diff mbox

[U-Boot,05/11,v2] snowball: Moving to ux500.v2 addess scheme for PRCMU access

Message ID 1341514426-31033-3-git-send-email-mathieu.poirier@linaro.org
State Accepted
Commit 101a769d75ffd06b7316d7bd4e896b95af7cb6d4
Delegated to: Tom Rini
Headers show

Commit Message

Mathieu Poirier July 5, 2012, 6:53 p.m. UTC
From: "Mathieu J. Poirier" <mathieu.poirier@linaro.org>

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>
---
Changes for v2:
   - Refactored to apply cleanly over previous v2 changes.
---
 arch/arm/cpu/armv7/u8500/prcmu.c           |   91 +++++++++++++++++++---------
 arch/arm/include/asm/arch-u8500/hardware.h |    2 +-
 arch/arm/include/asm/arch-u8500/prcmu.h    |   10 ++-
 3 files changed, 71 insertions(+), 32 deletions(-)
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/u8500/prcmu.c b/arch/arm/cpu/armv7/u8500/prcmu.c
index 4918bbc..934428f 100644
--- a/arch/arm/cpu/armv7/u8500/prcmu.c
+++ b/arch/arm/cpu/armv7/u8500/prcmu.c
@@ -36,9 +36,10 @@ 
 #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)
diff --git a/arch/arm/include/asm/arch-u8500/hardware.h b/arch/arm/include/asm/arch-u8500/hardware.h
index 6bb95ec..9208880 100644
--- a/arch/arm/include/asm/arch-u8500/hardware.h
+++ b/arch/arm/include/asm/arch-u8500/hardware.h
@@ -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)
diff --git a/arch/arm/include/asm/arch-u8500/prcmu.h b/arch/arm/include/asm/arch-u8500/prcmu.h
index 1fd4d2a..9862eb3 100644
--- a/arch/arm/include/asm/arch-u8500/prcmu.h
+++ b/arch/arm/include/asm/arch-u8500/prcmu.h
@@ -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)
@@ -38,12 +39,15 @@ 
 #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)