i.MX53QSB booting failed as OALMc34708PmicInit

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

i.MX53QSB booting failed as OALMc34708PmicInit

1,019 次查看
PramodKumar
Contributor IV

Hi Friends,

I am working i.MX53QSB with Adeno WinCe image that load in SD card but failed to boot. On RS232 the messages shown is given below

 

INFO:OALLogSetZones: dpCurSettings.ulZoneMask: 0xb

BSP Clock Configuration:

OSC = 24000000 Hz

PLL1 = 800000000 Hz

PLL2 = 600000000 Hz

PLL3 = 400000000 Hz

PLL4 = 595000000 Hz

LP_APM = 24000000 Hz

ARM = 800000000 Hz

AXI_A = 300000000 Hz

AXI_B = 200000000 Hz

EMI_SLOW = 120000000 Hz

AHB = 120000000 Hz

IPG = 60000000 Hz

PERCLK = 8000000 Hz

CKIL_SYNC = 32768 Hz

DDR = 300000000 Hz

ARM_AXI = 200000000 Hz

IPU_HSP = 200000000 Hz

VPU_AXI = 200000000 Hz

GPU = 200000000 Hz

GPU2D = 200000000 Hz

DEBUG_APB = 200000000 Hz

ENFC = 30000000 Hz

USBOH3 = 66666666 Hz

ESDHC1 = 100000000 Hz

ESDHC2 = 100000000 Hz

ESDHC3 = 100000000 Hz

ESDHC4 = 100000000 Hz

UART = 24000000 Hz

SSI1 = 6000000 Hz

SSI2 = 6000000 Hz

SSI3 = 6000000 Hz

SSI_EXT1 = 24000000 Hz

SSI_EXT2 = 19047619 Hz

USB_PHY = 24000000 Hz

TVE_216_54 = 297500000 Hz

DI0 = 50000000 Hz

DI1 = 297500000 Hz

VPU_RCLK = 24000000 Hz

SSI_LP_APM = 24000000 Hz

SPDIF_XTAL = 24000000 Hz

LDB_DIO = 595000000 Hz

LDB_DI1 = 595000000 Hz

SPDIF0 = 1142857 Hz

ESAI = 3000000 Hz

ESAI_HCKR = 0 Hz

ESAI_HCKT = 0 Hz

CAN = 60000000 Hz

FIRI = 24000000 Hz

CSI_MCLK1 = 25000000 Hz

CSI_MCLK2 = 25000000 Hz

ECSPI = 66666666 Hz

LPSR = 0 Hz

PGC = 7500000 Hz

ASRC = 59500000 Hz

IEEE_CEMX = 40000000 Hz

CKIH = 22579200 Hz

CKIH2 = 0 Hz

Microsoft Windows CE Bootloader Common Library Version 1.4 Built May 11 2012 10:43:27

OALMc34708PmicI2cInit: Trying to init PMIC I2C Interface

OALPmicInit: Trying to init I2C Interface

OALI2CReadOneByte: OALI2cWriteData Set Reg Error!

OALMc34708PmicInit: Read of PMIC hardware rev failed!

OEMPlatformInit: OALPmicInit failed!

 

Is there is any change in PMIC of I.MX53QSB. I am using SCH-265665 REV E/700-265665 REV F board

 

How to remove the problem shown above

标记 (2)
0 项奖励
回复
1 回复

515 次查看
qiang_li-mpu_se
NXP Employee
NXP Employee

From your log, it seems the code failed to access the MC34708 with I2C interface.

There is an I2C access failure issue.

 /* Random reboot cause i2c SDA low issue:
  * the i2c bus busy because some device pull down the I2C SDA
  * line. This happens when Host is reading some byte from slave, and
  * then host is reset/reboot. Since in this case, device is
  * controlling i2c SDA line, the only thing host can do this give the
  * clock on SCL and sending NAK, and STOP to finish this
  * transaction.
  *
  * How to fix this issue:
  * detect if the SDA was low on bus send 8 dummy clock, and 1
  * clock + NAK, and STOP to finish i2c transaction the pending
  * transfer.
  */ 

 

The followed is the Linux code to fix this issue, it can be found in Linux Uboot file "board\freescale\mx53_loco\mx53_loco.c"

 

#ifdef CONFIG_I2C_MXC
/* Note: udelay() is not accurate for i2c timing */
static void __udelay(int time)
{
       int i, j;

       for (i = 0; i < time; i++) {
        for (j = 0; j < 200; j++) {
         asm("nop");
         asm("nop");
        }
       }
}
#define I2C1_SDA_GPIO5_26_BIT_MASK  (1 << 26)
#define I2C1_SCL_GPIO5_27_BIT_MASK  (1 << 27)
#define I2C2_SCL_GPIO4_12_BIT_MASK  (1 << 12)
#define I2C2_SDA_GPIO4_13_BIT_MASK  (1 << 13)
#define I2C3_SCL_GPIO1_3_BIT_MASK   (1 << 3)
#define I2C3_SDA_GPIO1_6_BIT_MASK   (1 << 6)
static void mx53_i2c_gpio_scl_direction(int bus, int output)
{
 u32 reg;

 switch (bus) {
 case 1:
  mxc_request_iomux(MX53_PIN_CSI0_D9, IOMUX_CONFIG_ALT1);
  reg = readl(GPIO5_BASE_ADDR + GPIO_GDIR);
  if (output)
   reg |= I2C1_SCL_GPIO5_27_BIT_MASK;
  else
   reg &= ~I2C1_SCL_GPIO5_27_BIT_MASK;
  writel(reg, GPIO5_BASE_ADDR + GPIO_GDIR);
  break;
 case 2:
  mxc_request_iomux(MX53_PIN_KEY_COL3, IOMUX_CONFIG_ALT1);
  reg = readl(GPIO4_BASE_ADDR + GPIO_GDIR);
  if (output)
   reg |= I2C2_SCL_GPIO4_12_BIT_MASK;
  else
   reg &= ~I2C2_SCL_GPIO4_12_BIT_MASK;
  writel(reg, GPIO4_BASE_ADDR + GPIO_GDIR);
  break;
 case 3:
  mxc_request_iomux(MX53_PIN_GPIO_3, IOMUX_CONFIG_ALT1);
  reg = readl(GPIO1_BASE_ADDR + GPIO_GDIR);
  if (output)
   reg |= I2C3_SCL_GPIO1_3_BIT_MASK;
  else
   reg &= I2C3_SCL_GPIO1_3_BIT_MASK;
  writel(reg, GPIO1_BASE_ADDR + GPIO_GDIR);
  break;
 }
}

/* set 1 to output, sent 0 to input */
static void mx53_i2c_gpio_sda_direction(int bus, int output)
{
 u32 reg;

 switch (bus) {
 case 1:
  mxc_request_iomux(MX53_PIN_CSI0_D8, IOMUX_CONFIG_ALT1);

  reg = readl(GPIO5_BASE_ADDR + GPIO_GDIR);
  if (output) {
   mxc_iomux_set_pad(MX53_PIN_CSI0_D8,
       PAD_CTL_ODE_OPENDRAIN_ENABLE |
       PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU);
   reg |= I2C1_SDA_GPIO5_26_BIT_MASK;
  } else
   reg &= ~I2C1_SDA_GPIO5_26_BIT_MASK;
  writel(reg, GPIO5_BASE_ADDR + GPIO_GDIR);
  break;
 case 2:
  mxc_request_iomux(MX53_PIN_KEY_ROW3, IOMUX_CONFIG_ALT1);

  mxc_iomux_set_pad(MX53_PIN_KEY_ROW3,
      PAD_CTL_SRE_FAST |
      PAD_CTL_ODE_OPENDRAIN_ENABLE |
      PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU |
      PAD_CTL_HYS_ENABLE);

  reg = readl(GPIO4_BASE_ADDR + GPIO_GDIR);
  if (output)
   reg |= I2C2_SDA_GPIO4_13_BIT_MASK;
  else
   reg &= ~I2C2_SDA_GPIO4_13_BIT_MASK;
  writel(reg, GPIO4_BASE_ADDR + GPIO_GDIR);
 case 3:
  mxc_request_iomux(MX53_PIN_GPIO_6, IOMUX_CONFIG_ALT1);
  mxc_iomux_set_pad(MX53_PIN_GPIO_6,
      PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE |
      PAD_CTL_DRV_HIGH | PAD_CTL_360K_PD |
      PAD_CTL_HYS_ENABLE);
  reg = readl(GPIO1_BASE_ADDR + GPIO_GDIR);
  if (output)
   reg |= I2C3_SDA_GPIO1_6_BIT_MASK;
  else
   reg &= ~I2C3_SDA_GPIO1_6_BIT_MASK;
  writel(reg, GPIO1_BASE_ADDR + GPIO_GDIR);
 default:
  break;
 }
}

/* set 1 to high 0 to low */
static void mx53_i2c_gpio_scl_set_level(int bus, int high)
{
 u32 reg;
 switch (bus) {
 case 1:
  reg = readl(GPIO5_BASE_ADDR + GPIO_DR);
  if (high)
   reg |= I2C1_SCL_GPIO5_27_BIT_MASK;
  else
   reg &= ~I2C1_SCL_GPIO5_27_BIT_MASK;
  writel(reg, GPIO5_BASE_ADDR + GPIO_DR);
  break;
 case 2:
  reg = readl(GPIO4_BASE_ADDR + GPIO_DR);
  if (high)
   reg |= I2C2_SCL_GPIO4_12_BIT_MASK;
  else
   reg &= ~I2C2_SCL_GPIO4_12_BIT_MASK;
  writel(reg, GPIO4_BASE_ADDR + GPIO_DR);
  break;
 case 3:
  reg = readl(GPIO1_BASE_ADDR + GPIO_DR);
  if (high)
   reg |= I2C3_SCL_GPIO1_3_BIT_MASK;
  else
   reg &= ~I2C3_SCL_GPIO1_3_BIT_MASK;
  writel(reg, GPIO1_BASE_ADDR + GPIO_DR);
  break;
 }
}

/* set 1 to high 0 to low */
static void mx53_i2c_gpio_sda_set_level(int bus, int high)
{
 u32 reg;

 switch (bus) {
 case 1:
  reg = readl(GPIO5_BASE_ADDR + GPIO_DR);
  if (high)
   reg |= I2C1_SDA_GPIO5_26_BIT_MASK;
  else
   reg &= ~I2C1_SDA_GPIO5_26_BIT_MASK;
  writel(reg, GPIO5_BASE_ADDR + GPIO_DR);
  break;
 case 2:
  reg = readl(GPIO4_BASE_ADDR + GPIO_DR);
  if (high)
   reg |= I2C2_SDA_GPIO4_13_BIT_MASK;
  else
   reg &= ~I2C2_SDA_GPIO4_13_BIT_MASK;
  writel(reg, GPIO4_BASE_ADDR + GPIO_DR);
  break;
 case 3:
  reg = readl(GPIO1_BASE_ADDR + GPIO_DR);
  if (high)
   reg |= I2C3_SDA_GPIO1_6_BIT_MASK;
  else
   reg &= ~I2C3_SDA_GPIO1_6_BIT_MASK;
  writel(reg, GPIO1_BASE_ADDR + GPIO_DR);
  break;
 }
}

static int mx53_i2c_gpio_check_sda(int bus)
{
 u32 reg;
 int result = 0;

 switch (bus) {
 case 1:
  reg = readl(GPIO5_BASE_ADDR + GPIO_PSR);
  result = !!(reg & I2C1_SDA_GPIO5_26_BIT_MASK);
  break;
 case 2:
  reg = readl(GPIO4_BASE_ADDR + GPIO_PSR);
  result = !!(reg & I2C2_SDA_GPIO4_13_BIT_MASK);
  break;
 case 3:
  reg = readl(GPIO1_BASE_ADDR + GPIO_PSR);
  result = !!(reg & I2C3_SDA_GPIO1_6_BIT_MASK);
  break;
 }

 return result;
}


 /* Random reboot cause i2c SDA low issue:
  * the i2c bus busy because some device pull down the I2C SDA
  * line. This happens when Host is reading some byte from slave, and
  * then host is reset/reboot. Since in this case, device is
  * controlling i2c SDA line, the only thing host can do this give the
  * clock on SCL and sending NAK, and STOP to finish this
  * transaction.
  *
  * How to fix this issue:
  * detect if the SDA was low on bus send 8 dummy clock, and 1
  * clock + NAK, and STOP to finish i2c transaction the pending
  * transfer.
  */
int i2c_bus_recovery(void)
{
 int i, bus, result = 0;

 for (bus = 1; bus <= 3; bus++) {
  mx53_i2c_gpio_sda_direction(bus, 0);

  if (mx53_i2c_gpio_check_sda(bus) == 0) {
   printf("i2c: I2C%d SDA is low, start i2c recovery...\n", bus);
   mx53_i2c_gpio_scl_direction(bus, 1);
   mx53_i2c_gpio_scl_set_level(bus, 1);
   __udelay(10000);

   for (i = 0; i < 9; i++) {
    mx53_i2c_gpio_scl_set_level(bus, 1);
    __udelay(5);
    mx53_i2c_gpio_scl_set_level(bus, 0);
    __udelay(5);
   }

   /* 9th clock here, the slave should already
      release the SDA, we can set SDA as high to
      a NAK.*/
   mx53_i2c_gpio_sda_direction(bus, 1);
   mx53_i2c_gpio_sda_set_level(bus, 1);
   __udelay(1); /* Pull up SDA first */
   mx53_i2c_gpio_scl_set_level(bus, 1);
   __udelay(5); /* plus pervious 1 us */
   mx53_i2c_gpio_scl_set_level(bus, 0);
   __udelay(5);
   mx53_i2c_gpio_sda_set_level(bus, 0);
   __udelay(5);
   mx53_i2c_gpio_scl_set_level(bus, 1);
   __udelay(5);
   /* Here: SCL is high, and SDA from low to high, it's a
    * stop condition */
   mx53_i2c_gpio_sda_set_level(bus, 1);
   __udelay(5);

   mx53_i2c_gpio_sda_direction(bus, 0);
   if (mx53_i2c_gpio_check_sda(bus) == 1)
    printf("I2C%d Recovery success\n", bus);
   else {
    printf("I2C%d Recovery failed, I2C1 SDA still low!!!\n", bus);
    result |= 1 << bus;
   }
  }

  /* configure back to i2c */
  switch (bus) {
  case 1:
   setup_i2c(I2C1_BASE_ADDR);
   break;
  case 2:
   setup_i2c(I2C2_BASE_ADDR);
   break;
  case 3:
   setup_i2c(I2C3_BASE_ADDR);
   break;
  }
 }

 return result;
}
#endif

0 项奖励
回复