snowball: Moving to ux500.v2 addess scheme for PRCMU access
authorMathieu J. Poirier <mathieu.poirier@linaro.org>
Tue, 31 Jul 2012 08:59:27 +0000 (08:59 +0000)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Sat, 1 Sep 2012 12:58:20 +0000 (14:58 +0200)
Addresses between ux500.v1 and ux500.v2 have changed slightly,
hence mandating a review of the PRCMU access methods.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: John Rigby <john.rigby@linaro.org>
arch/arm/cpu/armv7/u8500/prcmu.c
arch/arm/include/asm/arch-u8500/hardware.h
arch/arm/include/asm/arch-u8500/prcmu.h

index 4918bbc1cadd7bed99a14e5287bfc348b1d97803..934428fb89f738345ab46c44a025eb0c243e3cb3 100644 (file)
 #include <asm/arch/prcmu.h>
 
 /* CPU mailbox registers */
-#define PRCM_MBOX_CPU_VAL (U8500_PRCMU_BASE + 0x0fc)
-#define PRCM_MBOX_CPU_SET (U8500_PRCMU_BASE + 0x100)
-#define PRCM_MBOX_CPU_CLR (U8500_PRCMU_BASE + 0x104)
+#define PRCMU_I2C_WRITE(slave)  \
+       (((slave) << 1) | I2CWRITE | (1 << 6))
+#define PRCMU_I2C_READ(slave) \
+       (((slave) << 1) | I2CREAD | (1 << 6))
 
 #define I2C_MBOX_BIT    (1 << 5)
 
@@ -50,26 +51,39 @@ static int prcmu_is_ready(void)
        return ready;
 }
 
-static int _wait_for_req_complete(int num)
+static int wait_for_i2c_mbx_rdy(void)
 {
-       int timeout = 1000;
+       int timeout = 10000;
 
-       /* checking any already on-going transaction */
-       while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout)
+       if (readl(PRCM_ARM_IT1_VAL) & I2C_MBOX_BIT) {
+               printf("prcmu: warning i2c mailbox was not acked\n");
+               /* clear mailbox 5 ack irq */
+               writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR);
+       }
+
+       /* check any already on-going transaction */
+       while ((readl(PRCM_MBOX_CPU_VAL) & I2C_MBOX_BIT) && timeout)
                timeout--;
 
-       timeout = 1000;
+       if (timeout == 0)
+               return -1;
+
+       return 0;
+}
+
+static int wait_for_i2c_req_done(void)
+{
+       int timeout = 10000;
 
        /* Set an interrupt to XP70 */
-       writel(1 << num, PRCM_MBOX_CPU_SET);
+       writel(I2C_MBOX_BIT, PRCM_MBOX_CPU_SET);
 
-       while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout)
+       /* wait for mailbox 5 (i2c) ack */
+       while (!(readl(PRCM_ARM_IT1_VAL) & I2C_MBOX_BIT) && timeout)
                timeout--;
 
-       if (!timeout) {
-               printf("PRCMU operation timed out\n");
+       if (timeout == 0)
                return -1;
-       }
 
        return 0;
 }
@@ -84,6 +98,7 @@ int prcmu_i2c_read(u8 reg, u16 slave)
 {
        uint8_t i2c_status;
        uint8_t i2c_val;
+       int ret;
 
        if (!prcmu_is_ready())
                return -1;
@@ -91,13 +106,23 @@ int prcmu_i2c_read(u8 reg, u16 slave)
        debug("\nprcmu_4500_i2c_read:bank=%x;reg=%x;\n",
                        reg, slave);
 
+       ret = wait_for_i2c_mbx_rdy();
+       if (ret) {
+               printf("prcmu_i2c_read: mailbox became not ready\n");
+               return ret;
+       }
+
        /* prepare the data for mailbox 5 */
-       writeb((reg << 1) | I2CREAD, PRCM_REQ_MB5_I2COPTYPE_REG);
+       writeb(PRCMU_I2C_READ(reg), PRCM_REQ_MB5_I2COPTYPE_REG);
        writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
        writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
        writeb(0, PRCM_REQ_MB5_I2CVAL);
 
-       _wait_for_req_complete(REQ_MB5);
+       ret = wait_for_i2c_req_done();
+       if (ret) {
+               printf("prcmu_i2c_read: mailbox request timed out\n");
+               return ret;
+       }
 
        /* retrieve values */
        debug("ack-mb5:transfer status = %x\n",
@@ -109,16 +134,14 @@ int prcmu_i2c_read(u8 reg, u16 slave)
 
        i2c_status = readb(PRCM_ACK_MB5_STATUS);
        i2c_val = readb(PRCM_ACK_MB5_VAL);
+       /* clear mailbox 5 ack irq */
+       writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR);
 
        if (i2c_status == I2C_RD_OK)
                return i2c_val;
-       else {
-
-               printf("prcmu_i2c_read:read return status= %d\n",
-                               i2c_status);
-               return -1;
-       }
 
+       printf("prcmu_i2c_read:read return status= %d\n", i2c_status);
+       return -1;
 }
 
 /**
@@ -131,6 +154,7 @@ int prcmu_i2c_read(u8 reg, u16 slave)
 int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
 {
        uint8_t i2c_status;
+       int ret;
 
        if (!prcmu_is_ready())
                return -1;
@@ -138,14 +162,23 @@ int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
        debug("\nprcmu_4500_i2c_write:bank=%x;reg=%x;\n",
                        reg, slave);
 
+       ret = wait_for_i2c_mbx_rdy();
+       if (ret) {
+               printf("prcmu_i2c_write: mailbox became not ready\n");
+               return ret;
+       }
+
        /* prepare the data for mailbox 5 */
-       writeb((reg << 1) | I2CWRITE, PRCM_REQ_MB5_I2COPTYPE_REG);
+       writeb(PRCMU_I2C_WRITE(reg), PRCM_REQ_MB5_I2COPTYPE_REG);
        writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
        writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
        writeb(reg_data, PRCM_REQ_MB5_I2CVAL);
 
-       debug("\ncpu_is_u8500v11\n");
-       _wait_for_req_complete(REQ_MB5);
+       ret = wait_for_i2c_req_done();
+       if (ret) {
+               printf("prcmu_i2c_write: mailbox request timed out\n");
+               return ret;
+       }
 
        /* retrieve values */
        debug("ack-mb5:transfer status = %x\n",
@@ -157,12 +190,14 @@ int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
 
        i2c_status = readb(PRCM_ACK_MB5_STATUS);
        debug("\ni2c_status = %x\n", i2c_status);
+       /* clear mailbox 5 ack irq */
+       writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR);
+
        if (i2c_status == I2C_WR_OK)
                return 0;
-       else {
-               printf("ape-i2c: i2c_status : 0x%x\n", i2c_status);
-               return -1;
-       }
+
+       printf("%s: i2c_status : 0x%x\n", __func__, i2c_status);
+       return -1;
 }
 
 void u8500_prcmu_enable(u32 *reg)
index 6bb95ec07074f52712c2cb9ab56753235efd5e6f..920888052b91ac2b9c9e4927dab2d919b3d21a3b 100644 (file)
@@ -62,7 +62,7 @@
 
 /* Per4 */
 #define U8500_PRCMU_BASE       (U8500_PER4_BASE + 0x07000)
-#define U8500_PRCMU_TCDM_BASE   (U8500_PER4_BASE + 0x0f000)
+#define U8500_PRCMU_TCDM_BASE   (U8500_PER4_BASE + 0x06800)
 
 /* Per3 */
 #define U8500_UART2_BASE       (U8500_PER3_BASE + 0x7000)
index 1fd4d2a5642b54e9eec690ac66443f014d77a52e..9862eb3dd952ecb2d7ca2d801c7fe74820e27b2c 100644 (file)
@@ -28,6 +28,7 @@
 #define I2CWRITE       0
 
 #define PRCMU_BASE                     U8500_PRCMU_BASE
+#define PRCMU_BASE_TCDM                        U8500_PRCMU_TCDM_BASE
 #define PRCM_UARTCLK_MGT_REG           (PRCMU_BASE + 0x018)
 #define PRCM_MSPCLK_MGT_REG            (PRCMU_BASE + 0x01C)
 #define PRCM_I2CCLK_MGT_REG            (PRCMU_BASE + 0x020)
 #define PRCM_PER5CLK_MGT_REG           (PRCMU_BASE + 0x038)
 #define PRCM_PER6CLK_MGT_REG           (PRCMU_BASE + 0x03C)
 #define PRCM_PER7CLK_MGT_REG           (PRCMU_BASE + 0x040)
+#define PRCM_MBOX_CPU_VAL              (PRCMU_BASE + 0x0FC)
+#define PRCM_MBOX_CPU_SET              (PRCMU_BASE + 0x100)
 
 #define PRCM_ARM_IT1_CLEAR             (PRCMU_BASE + 0x48C)
+#define PRCM_ARM_IT1_VAL               (PRCMU_BASE + 0x494)
 #define PRCM_TCR                       (PRCMU_BASE + 0x1C8)
-#define PRCM_REQ_MB5                   (PRCMU_BASE + 0xE44)
-#define PRCM_ACK_MB5                   (PRCMU_BASE + 0xDF4)
-#define PRCM_XP70_CUR_PWR_STATE                (PRCMU_BASE + 0xFFC)
+#define PRCM_REQ_MB5                   (PRCMU_BASE_TCDM + 0xE44)
+#define PRCM_ACK_MB5                   (PRCMU_BASE_TCDM + 0xDF4)
+#define PRCM_XP70_CUR_PWR_STATE                (PRCMU_BASE_TCDM + 0xFFC)
 /* Mailbox 5 Requests */
 #define PRCM_REQ_MB5_I2COPTYPE_REG     (PRCM_REQ_MB5 + 0x0)
 #define PRCM_REQ_MB5_BIT_FIELDS                (PRCM_REQ_MB5 + 0x1)