Merge "msm: camera: ISPIF changes for V2" into msm-3.0
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 0d1da49..1b6497d 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -543,7 +543,10 @@
 
 	CAMIO_CSI1_SRC_CLK,
 	CAMIO_CSI_PIX_CLK,
+	CAMIO_CSI_PIX1_CLK,
 	CAMIO_CSI_RDI_CLK,
+	CAMIO_CSI_RDI1_CLK,
+	CAMIO_CSI_RDI2_CLK,
 	CAMIO_CSIPHY0_TIMER_CLK,
 	CAMIO_CSIPHY1_TIMER_CLK,
 
diff --git a/drivers/media/video/msm/msm_io_8960.c b/drivers/media/video/msm/msm_io_8960.c
index 43f893b..45871bc 100644
--- a/drivers/media/video/msm/msm_io_8960.c
+++ b/drivers/media/video/msm/msm_io_8960.c
@@ -60,6 +60,7 @@
 #define MIPI_CSIPHY_INTERRUPT_CLEAR4_ADDR       0x01D0
 
 /* MIPI	CSID registers */
+#define CSID_HW_VERSION_ADDR                    0x0
 #define CSID_CORE_CTRL_ADDR                     0x4
 #define CSID_RST_CMD_ADDR                       0x8
 #define CSID_CID_LUT_VC_0_ADDR                  0xc
@@ -105,6 +106,9 @@
 #define CAM_VANA_LOAD_UA                  85600
 #define CAM_CSI_LOAD_UA                    20000
 
+#define CSID_VERSION_V2              0x2000011
+
+static uint32_t csid_hw_version;
 static struct clk *camio_cam_clk;
 static struct clk *camio_vfe_clk;
 static struct clk *camio_csi_src_clk;
@@ -113,7 +117,10 @@
 static struct clk *camio_csi0_clk;
 static struct clk *camio_csi0_pclk;
 static struct clk *camio_csi_pix_clk;
+static struct clk *camio_csi_pix1_clk;
 static struct clk *camio_csi_rdi_clk;
+static struct clk *camio_csi_rdi1_clk;
+static struct clk *camio_csi_rdi2_clk;
 static struct clk *camio_csiphy0_timer_clk;
 static struct clk *camio_csiphy1_timer_clk;
 static struct clk *camio_vfe_pclk;
@@ -497,6 +504,13 @@
 		msm_camio_clk_rate_set_2(clk, csid_core);
 		break;
 
+	case CAMIO_CSI_PIX1_CLK:
+		camio_csi_pix1_clk =
+		clk = clk_get(NULL, "csi_pix1_clk");
+		/* mux to select between csid0 and csid1 */
+		msm_camio_clk_rate_set_2(clk, csid_core);
+		break;
+
 	case CAMIO_CSI_RDI_CLK:
 		camio_csi_rdi_clk =
 		clk = clk_get(NULL, "csi_rdi_clk");
@@ -504,6 +518,20 @@
 		msm_camio_clk_rate_set_2(clk, csid_core);
 		break;
 
+	case CAMIO_CSI_RDI1_CLK:
+		camio_csi_rdi1_clk =
+		clk = clk_get(NULL, "csi_rdi1_clk");
+		/* mux to select between csid0 and csid1 */
+		msm_camio_clk_rate_set_2(clk, csid_core);
+		break;
+
+	case CAMIO_CSI_RDI2_CLK:
+		camio_csi_rdi2_clk =
+		clk = clk_get(NULL, "csi_rdi2_clk");
+		/* mux to select between csid0 and csid1 */
+		msm_camio_clk_rate_set_2(clk, csid_core);
+		break;
+
 	case CAMIO_CSIPHY0_TIMER_CLK:
 		camio_csiphy0_timer_clk =
 		clk = clk_get(NULL, "csi0phy_timer_clk");
@@ -596,10 +624,22 @@
 		clk = camio_csi0_phy_clk;
 		break;
 
+	case CAMIO_CSI_PIX1_CLK:
+		clk = camio_csi_pix1_clk;
+		break;
+
 	case CAMIO_CSI_PIX_CLK:
 		clk = camio_csi_pix_clk;
 		break;
 
+	case CAMIO_CSI_RDI1_CLK:
+		clk = camio_csi_rdi1_clk;
+		break;
+
+	case CAMIO_CSI_RDI2_CLK:
+		clk = camio_csi_rdi2_clk;
+		break;
+
 	case CAMIO_CSI_RDI_CLK:
 		clk = camio_csi_rdi_clk;
 		break;
@@ -744,6 +784,40 @@
 	return IRQ_HANDLED;
 }
 #endif
+
+static int msm_camio_enable_v2_clks(void)
+{
+	int rc = 0;
+	csid_hw_version = msm_io_r(csidbase +
+				CSID_HW_VERSION_ADDR);
+	CDBG("%s csid_hw_version %d\n",
+		__func__,
+		csid_hw_version);
+
+	if (csid_hw_version == CSID_VERSION_V2) {
+		rc = msm_camio_clk_enable(CAMIO_CSI_PIX1_CLK);
+		if (rc < 0)
+			goto csi_pix1_fail;
+
+		rc = msm_camio_clk_enable(CAMIO_CSI_RDI1_CLK);
+		if (rc < 0)
+			goto csi_rdi1_fail;
+
+		rc = msm_camio_clk_enable(CAMIO_CSI_RDI2_CLK);
+		if (rc < 0)
+			goto csi_rdi2_fail;
+	}
+
+	return rc;
+
+csi_rdi2_fail:
+	msm_camio_clk_disable(CAMIO_CSI_RDI1_CLK);
+csi_rdi1_fail:
+	msm_camio_clk_disable(CAMIO_CSI_PIX1_CLK);
+csi_pix1_fail:
+	return rc;
+}
+
 static int msm_camio_enable_all_clks(uint8_t csid_core)
 {
 	int rc = 0;
@@ -824,8 +898,18 @@
 	return rc;
 }
 
+static void msm_camio_disable_v2_clks(void)
+{
+	if (csid_hw_version == CSID_VERSION_V2) {
+		msm_camio_clk_disable(CAMIO_CSI_RDI2_CLK);
+		msm_camio_clk_disable(CAMIO_CSI_RDI1_CLK);
+		msm_camio_clk_disable(CAMIO_CSI_PIX1_CLK);
+	}
+}
+
 static void msm_camio_disable_all_clks(uint8_t csid_core)
 {
+	msm_camio_disable_v2_clks();
 	msm_camio_clk_disable(CAMIO_CSI_RDI_CLK);
 	msm_camio_clk_disable(CAMIO_CSI_PIX_CLK);
 	msm_camio_clk_disable(CAMIO_CSI0_VFE_CLK);
@@ -1034,6 +1118,7 @@
 	if (rc < 0)
 		goto csiphy_irq_fail;
 #endif
+	msm_camio_enable_v2_clks();
 	CDBG("camio enable done\n");
 	return 0;
 #if DBG_CSIPHY
diff --git a/drivers/media/video/msm/msm_ispif.c b/drivers/media/video/msm/msm_ispif.c
index c5e38ef..8797d38 100644
--- a/drivers/media/video/msm/msm_ispif.c
+++ b/drivers/media/video/msm/msm_ispif.c
@@ -47,6 +47,7 @@
 #define ISPIF_IRQ_MASK_1_ADDR                   0X010C
 #define ISPIF_IRQ_CLEAR_1_ADDR                  0X0110
 #define ISPIF_IRQ_STATUS_1_ADDR                 0X0114
+#define ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR         0x0124
 
 /*ISPIF RESET BITS*/
 
@@ -73,9 +74,11 @@
 #define ISPIF_IRQ_STATUS_MASK        0xA493000
 #define ISPIF_IRQ_1_STATUS_MASK      0xA493000
 #define ISPIF_IRQ_STATUS_RDI_SOF_MASK	0x492000
+#define ISPIF_IRQ_GLOBAL_CLEAR_CMD     0x1
 
 #define MAX_CID 15
 
+
 static struct ispif_device *ispif;
 
 static uint32_t global_intf_cmd_mask = 0xFFFFFFFF;
@@ -207,6 +210,8 @@
 					ISPIF_IRQ_MASK_ADDR);
 	msm_io_w(ISPIF_IRQ_STATUS_MASK, ispif->base +
 					ISPIF_IRQ_CLEAR_ADDR);
+	msm_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
+		 ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
 	return rc;
 }
 
@@ -410,6 +415,8 @@
 	}
 	msm_io_w(out->ispifIrqStatus0,
 			ispif->base + ISPIF_IRQ_CLEAR_ADDR);
+	msm_io_w(ISPIF_IRQ_GLOBAL_CLEAR_CMD, ispif->base +
+		 ISPIF_IRQ_GLOBAL_CLEAR_CMD_ADDR);
 }
 
 static irqreturn_t msm_io_ispif_irq(int irq_num, void *data)