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
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