platform: msm_shared: Fix spmi driver

Clean up spmi driver to use pmic arb version from hardware
instead of compile time option to differentiate the v2 h/w.
Also avoid finding channel number everytime the spmi read/write
is called by creating one time look up table at the driver init.

CRs-Fixed: 630065
Change-Id: Ib568a8569cf215708affc5cdfe64a8f7cefeac77
diff --git a/platform/msm_shared/spmi.c b/platform/msm_shared/spmi.c
index 07fb941..4655eaa 100644
--- a/platform/msm_shared/spmi.c
+++ b/platform/msm_shared/spmi.c
@@ -28,28 +28,64 @@
 
 #include <debug.h>
 #include <reg.h>
-#if SPMI_CORE_V2
-#include <spmi_v2.h>
-#else
 #include <spmi.h>
-#endif
+#include <bits.h>
 #include <platform/iomap.h>
 #include <platform/irqs.h>
 #include <platform/interrupts.h>
 
+#define PMIC_ARB_V2 0x20010000
+#define CHNL_IDX(sid, pid) ((sid << 8) | pid)
+
 static uint32_t pmic_arb_chnl_num;
 static uint32_t pmic_arb_owner_id;
 static uint8_t pmic_irq_perph_id;
 static spmi_callback callback;
+static uint32_t pmic_arb_ver;
+static uint8_t *chnl_tbl;
+
+static void spmi_lookup_chnl_number()
+{
+	int i;
+	uint8_t slave_id;
+	uint8_t ppid_address;
+	/* We need a max of sid (4 bits) + pid (8bits) of uint8_t's */
+	uint32_t chnl_tbl_sz = BIT(12) * sizeof(uint8_t);
+
+	/* Allocate the channel table */
+	chnl_tbl = (uint8_t *) malloc(chnl_tbl_sz);
+	ASSERT(chnl_tbl);
+
+	for(i = 0; i < MAX_PERIPH ; i++)
+	{
+#if SPMI_CORE_V2
+		slave_id = (readl(PMIC_ARB_REG_CHLN(i)) & 0xf0000) >> 16;
+		ppid_address = (readl(PMIC_ARB_REG_CHLN(i)) & 0xff00) >> 8;
+#endif
+		chnl_tbl[CHNL_IDX(slave_id, ppid_address)] = i;
+	}
+}
 
 /* Function to initialize SPMI controller.
  * chnl_num : Channel number to be used by this EE.
  */
 void spmi_init(uint32_t chnl_num, uint32_t owner_id)
 {
-	/* Initialize PMIC Arbiter Channel Number */
-	pmic_arb_chnl_num = chnl_num;
-	pmic_arb_owner_id = owner_id;
+	/* Read the version numver */
+	pmic_arb_ver = readl(PMIC_ARB_SPMI_HW_VERSION);
+
+	if (pmic_arb_ver < PMIC_ARB_V2)
+	{
+		/* Initialize PMIC Arbiter Channel Number to
+		 * 0 by default of V1 HW
+		 */
+		pmic_arb_chnl_num = chnl_num;
+		pmic_arb_owner_id = owner_id;
+	}
+	else
+	{
+		spmi_lookup_chnl_number();
+	}
 }
 
 static void write_wdata_from_array(uint8_t *array,
@@ -72,7 +108,6 @@
 	writel(val, PMIC_ARB_CHNLn_WDATA(pmic_arb_chnl_num, reg_num));
 }
 
-
 /* Initiate a write cmd by writing to cmd register.
  * Commands are written according to cmd parameters
  * cmd->opcode   : SPMI opcode for the command
@@ -95,30 +130,16 @@
 	uint32_t bytes_written = 0;
 	uint32_t error;
 	uint32_t val = 0;
-#ifdef SPMI_CORE_V2
-	uint32_t slave_id;
-	uint32_t ppid_address;
-	int i;
-	int channel_not_found = 1;
 
-	for(i = 0; i < MAX_PERIPH ; i++)
+	/* Look up for pmic channel only for V2 hardware
+	 * For V1-HW we dont care for channel number & always
+	 * use '0'
+	 */
+	if (pmic_arb_ver >= PMIC_ARB_V2)
 	{
-		slave_id = (readl(PMIC_ARB_REG_CHLN(i)) & 0xf0000) >> 16;
-		ppid_address = (readl(PMIC_ARB_REG_CHLN(i)) & 0xff00) >> 8;
-		if((cmd->slave_id == slave_id) && (cmd->address == ppid_address)) {
-			pmic_arb_chnl_num = i;
-			channel_not_found = 0;
-			dprintf(INFO, "pmic_arb_write_cmd: \
-				channel found for slave %x, ppid %x\n", cmd->slave_id, cmd->address);
-			break;
-		}
+		pmic_arb_chnl_num = chnl_tbl[CHNL_IDX(cmd->slave_id, cmd->address)];
 	}
-	if(channel_not_found) {
-		dprintf(CRITICAL, "pmic_arb_write_cmd: \
-			channel not found for slave %x, ppid %x\n", cmd->slave_id, cmd->address);
-		return channel_not_found;
-	}
-#endif
+
 	/* Disable IRQ mode for the current channel*/
 	writel(0x0, PMIC_ARB_CHNLn_CONFIG(pmic_arb_chnl_num));
 	/* Write parameters for the cmd */
@@ -219,31 +240,17 @@
 	uint32_t error;
 	uint32_t addr;
 	uint8_t bytes_read = 0;
-#ifdef SPMI_CORE_V2
-	int channel_not_found = 1;
-	int i;
-	uint32_t slave_id;
-	uint32_t ppid_address;
 
-	for(i = 0; i < MAX_PERIPH ; i++)
+	/* Look up for pmic channel only for V2 hardware
+	 * For V1-HW we dont care for channel number & always
+	 * use '0'
+	 */
+	if (pmic_arb_ver >= PMIC_ARB_V2)
 	{
-		slave_id = (readl(PMIC_ARB_REG_CHLN(i)) & 0xf0000) >> 16;
-		ppid_address = (readl(PMIC_ARB_REG_CHLN(i)) & 0xff00) >> 8;
-		if((cmd->slave_id == slave_id) && (cmd->address == ppid_address)) {
-			pmic_arb_chnl_num = i;
-			channel_not_found = 0;
-			dprintf(INFO, "pmic_arb_read_cmd: \
-				channel found for slave %x, ppid %x\n", cmd->slave_id, cmd->address);
-			break;
-		}
+		pmic_arb_chnl_num = chnl_tbl[CHNL_IDX(cmd->slave_id, cmd->address)];
 	}
-	if(channel_not_found) {
-		dprintf(CRITICAL, "pmic_arb_read_cmd: \
-			channel not found for slave %x, ppid %x\n", cmd->slave_id, cmd->address);
-		return channel_not_found;
-	}
-#endif
-	 /* Disable IRQ mode for the current channel*/
+
+	/* Disable IRQ mode for the current channel*/
 	writel(0x0, PMIC_ARB_CHNLn_CONFIG(pmic_arb_chnl_num));
 
 	/* Fill in the byte count for the command