Merge tag 'v4.4-rc4'
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_mipicsi_phy.c
index 407ada10c4655ae31738d21c17e41aefc118301a..8094b7e654beedaf7c22656627e3fb286974ebf8 100755 (executable)
+#include "camsys_soc_priv.h"
 #include "camsys_mipicsi_phy.h"
 
-#if defined(CONFIG_ARCH_ROCKCHIP)
-//GRF_SOC_CON14
-//bit 0     dphy_rx0_testclr
-//bit 1     dphy_rx0_testclk
-//bit 2     dphy_rx0_testen
-//bit 3:10 dphy_rx0_testdin
-#define GRF_SOC_CON14_OFFSET    (0x027c)
-#define DPHY_RX0_TESTCLR_MASK   (0x1<<16)
-#define DPHY_RX0_TESTCLK_MASK   (0x1<<17)
-#define DPHY_RX0_TESTEN_MASK    (0x1<<18)
-#define DPHY_RX0_TESTDIN_MASK   (0xff<<19)
+unsigned int CHIP_TYPE;
+unsigned long rk_grf_base;
+unsigned long rk_cru_base;
+unsigned long rk_isp_base;
 
-#define DPHY_RX0_TESTCLR    (1<<0)
-#define DPHY_RX0_TESTCLK    (1<<1)
-#define DPHY_RX0_TESTEN     (1<<2)
-#define DPHY_RX0_TESTDIN_OFFSET    (3)
-
-#define DPHY_TX1RX1_ENABLECLK_MASK   (0x1<<28)
-#define DPHY_RX1_SRC_SEL_MASK        (0x1<<29)
-#define DPHY_TX1RX1_MASTERSLAVEZ_MASK (0x1<<30)
-#define DPHY_TX1RX1_BASEDIR_OFFSET  (0x1<<31)
-
-#define DPHY_TX1RX1_ENABLECLK           (0x1<<12)
-#define DPHY_TX1RX1_DISABLECLK          (0x0<<12)
-#define DPHY_RX1_SRC_SEL_ISP          (0x1<<13)
-#define DPHY_TX1RX1_SLAVEZ            (0x0<<14)
-#define DPHY_TX1RX1_BASEDIR_REC       (0x1<<15)
-
-
-
-//GRF_SOC_CON6
-//bit 0 grf_con_disable_isp
-//bit 1 grf_con_isp_dphy_sel  1'b0 mipi phy rx0
-#define GRF_SOC_CON6_OFFSET    (0x025c)
-#define MIPI_PHY_DISABLE_ISP_MASK       (0x1<<16)
-#define MIPI_PHY_DISABLE_ISP            (0x0<<0)
-
-#define DSI_CSI_TESTBUS_SEL_MASK        (0x1<<30)
-#define DSI_CSI_TESTBUS_SEL_OFFSET_BIT  (14)
-
-
-#define MIPI_PHY_DPHYSEL_OFFSET_MASK (0x1<<17)
-#define MIPI_PHY_DPHYSEL_OFFSET_BIT (0x1)
-
-//GRF_SOC_CON10
-//bit12:15 grf_dphy_rx0_enable
-//bit 0:3 turn disable
-#define GRF_SOC_CON10_OFFSET                (0x026c)
-#define DPHY_RX0_TURN_DISABLE_MASK          (0xf<<16)
-#define DPHY_RX0_TURN_DISABLE_OFFSET_BITS   (0x0)
-#define DPHY_RX0_ENABLE_MASK                (0xf<<28)
-#define DPHY_RX0_ENABLE_OFFSET_BITS         (12)
-
-//GRF_SOC_CON9
-//bit12:15 grf_dphy_rx0_enable
-//bit 0:3 turn disable
-#define GRF_SOC_CON9_OFFSET                (0x0268)
-#define DPHY_TX1RX1_TURN_DISABLE_MASK          (0xf<<16)
-#define DPHY_TX1RX1_TURN_DISABLE_OFFSET_BITS   (0x0)
-#define DPHY_TX1RX1_ENABLE_MASK                (0xf<<28)
-#define DPHY_TX1RX1_ENABLE_OFFSET_BITS         (12)
-
-//GRF_SOC_CON15
-//bit 0:3   turn request
-#define GRF_SOC_CON15_OFFSET                (0x03a4) 
-#define DPHY_RX0_TURN_REQUEST_MASK          (0xf<<16)
-#define DPHY_RX0_TURN_REQUEST_OFFSET_BITS   (0x0)
-
-#define DPHY_TX1RX1_TURN_REQUEST_MASK          (0xf<<20)
-#define DPHY_TX1RX1_TURN_REQUEST_OFFSET_BITS   (0x0)
-
-
-#endif
-
-
-static void phy_select(uint8_t index)
+static int camsys_mipiphy_clkin_cb(void *ptr, unsigned int on)
 {
-    if((index == 0) || (index == 1)){
-        write_grf_reg(GRF_SOC_CON6_OFFSET, MIPI_PHY_DPHYSEL_OFFSET_MASK | (index<<MIPI_PHY_DPHYSEL_OFFSET_BIT)); 
-        if(index == 1){
-            write_grf_reg(GRF_SOC_CON6_OFFSET, DSI_CSI_TESTBUS_SEL_MASK | (1<<DSI_CSI_TESTBUS_SEL_OFFSET_BIT)); 
-
-            write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX1_SRC_SEL_ISP | DPHY_RX1_SRC_SEL_MASK); 
-            write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_TX1RX1_SLAVEZ | DPHY_TX1RX1_MASTERSLAVEZ_MASK); 
-            write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_TX1RX1_BASEDIR_REC | DPHY_TX1RX1_BASEDIR_OFFSET); 
+    camsys_mipiphy_clk_t *clk;
+    camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
+    unsigned int i,phycnt;
+    
+    if (camsys_dev->mipiphy != NULL) {
+        phycnt = camsys_dev->mipiphy[0].phycnt;
+         
+        for (i=0; i<phycnt; i++) {
+            if (camsys_dev->mipiphy[i].clk != NULL) {
+                clk = (camsys_mipiphy_clk_t*)camsys_dev->mipiphy[i].clk;
+                if (on && !clk->on) {
+                    if (!IS_ERR_OR_NULL(clk->hclk))
+                        clk_prepare_enable(clk->hclk);  
+                    clk->on = on;
+                } else if (!on && clk->on) {
+                    if (!IS_ERR_OR_NULL(clk->hclk))
+                        clk_disable_unprepare(clk->hclk);                    
+                    clk->on = on;
+                }
+            }
         }
-
-    }else{
-        camsys_err("phy index is erro!");
-        
     }
+    if (on)
+        camsys_trace(1, "%s mipi phy clk in turn on",dev_name(camsys_dev->miscdev.this_device));
+    else 
+        camsys_trace(1, "%s mipi phy clk in turn off",dev_name(camsys_dev->miscdev.this_device));
+    
+    return 0;
 }
 
-
-static void phy0_WriteReg(uint8_t addr, uint8_t data)
+static int camsys_mipiphy_ops (void * ptr, camsys_mipiphy_t *phy)
 {
-   // uint8_t test_data = 0;
-    //TESTEN =1,TESTDIN=addr
-    write_grf_reg(GRF_SOC_CON14_OFFSET,(( addr << DPHY_RX0_TESTDIN_OFFSET) |DPHY_RX0_TESTDIN_MASK | DPHY_RX0_TESTEN| DPHY_RX0_TESTEN_MASK)); 
-//     //TESTCLK=1
-    write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK |DPHY_RX0_TESTCLK);
+    camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
+    camsys_mipiphy_soc_para_t para;
+    camsys_soc_priv_t *soc;
     
-    //TESTCLK=0
-        write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK); 
-  
-    if(data != -1){ //write data ?
-        //TESTEN =0,TESTDIN=data
-        write_grf_reg(GRF_SOC_CON14_OFFSET, (( data << DPHY_RX0_TESTDIN_OFFSET)|DPHY_RX0_TESTDIN_MASK |DPHY_RX0_TESTEN)); 
-
-        //TESTCLK=1
-        write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK |DPHY_RX0_TESTCLK); 
+    if (camsys_dev->soc) {
+        soc = (camsys_soc_priv_t*)camsys_dev->soc;
+        if (soc->soc_cfg) { 
+            para.camsys_dev = camsys_dev;
+            para.phy = phy;
+            (soc->soc_cfg)(Mipi_Phy_Cfg,(void*)&para);
+        } else {
+            camsys_err("camsys_dev->soc->soc_cfg is NULL!");
+        }
+    } else {
+        camsys_err("camsys_dev->soc is NULL!");
     }
+    
+    return 0;
 }
 
-static uint8_t phy0_ReadReg(uint8_t addr)  
+static int camsys_mipiphy_remove_cb(struct platform_device *pdev)
 {
-    uint8_t data = 0;
+    camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
+    camsys_mipiphy_clk_t *phyclk;
+    unsigned int i;
     
-    //TESTEN =1,TESTDIN=addr
-    write_grf_reg(GRF_SOC_CON14_OFFSET,(( addr << DPHY_RX0_TESTDIN_OFFSET) |DPHY_RX0_TESTDIN_MASK | DPHY_RX0_TESTEN| DPHY_RX0_TESTEN_MASK)); 
-
-    //TESTCLK=0
-    write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK); 
-
-    return data ;
+    if (camsys_dev->mipiphy != NULL) {
+        for (i=0; i<camsys_dev->mipiphy[0].phycnt; i++) {
+            if (camsys_dev->mipiphy[i].reg != NULL) {
+                if (camsys_dev->mipiphy[i].reg->vir_base != 0) {
+                    iounmap((void __iomem *)camsys_dev->mipiphy[i].reg->vir_base);
+                    camsys_dev->mipiphy[i].reg->vir_base = 0;
+                }
+                kfree(camsys_dev->mipiphy[i].reg);
+                camsys_dev->mipiphy[i].reg = NULL;
+            }
+
+            if (camsys_dev->mipiphy[i].clk != NULL) {
+                phyclk = (camsys_mipiphy_clk_t*)camsys_dev->mipiphy[i].clk;
+                devm_clk_put(&pdev->dev,phyclk->hclk);
+
+                kfree(camsys_dev->mipiphy[i].clk);
+                camsys_dev->mipiphy[i].clk = NULL;
+            }
+        }
+    }
+       if(CHIP_TYPE == 3368){
+               if(camsys_dev->csiphy_reg != NULL){
+                       kfree(camsys_dev->csiphy_reg);
+                       camsys_dev->csiphy_reg = NULL;
+               }
+       }
 
-    
+    return 0;
 }
-
-static void phy_config_num_lane(uint8_t index,int numLane)
+int camsys_mipiphy_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
 {
-    uint8_t lane_mask =0;
-    int i = 0;
-
-    for(i=0;i<numLane;i++){
-        lane_mask |= 1<<i;
+    struct device *dev = &pdev->dev;
+    camsys_meminfo_t *meminfo;
+    camsys_phyinfo_t *mipiphy;
+    unsigned int mipiphy_cnt,phyreg[2];
+    char str[31];
+    struct clk* clk;
+    camsys_mipiphy_clk_t *phyclk;
+    int err,i;
+       struct device_node *node;
+       const char *compatible = NULL;
+
+       err = of_property_read_string(dev->of_node->parent,"compatible",&compatible);   
+    if (err < 0) {
+        camsys_err("get compatible failed!");
+    } else {
+        camsys_trace(1, "compatible is %s\n",compatible);
     }
-    camsys_trace(1,"lane num = 0x%d\n",lane_mask);
-    if(index == 0){
-    //  set lane num
-        write_grf_reg(GRF_SOC_CON10_OFFSET, DPHY_RX0_ENABLE_MASK | (lane_mask << DPHY_RX0_ENABLE_OFFSET_BITS)); 
-    //  set lan turndisab as 1
-        write_grf_reg(GRF_SOC_CON10_OFFSET, DPHY_RX0_TURN_DISABLE_MASK | (0xf << DPHY_RX0_TURN_DISABLE_OFFSET_BITS));
-
-        write_grf_reg(GRF_SOC_CON10_OFFSET, (0xc<<4)|(0xf<<20));
-
-    //  set lan turnrequest as 0   
-        write_grf_reg(GRF_SOC_CON15_OFFSET, DPHY_RX0_TURN_REQUEST_MASK | (0x0 << DPHY_RX0_TURN_REQUEST_OFFSET_BITS));
-    }else if(index == 1){
-    //  set lane num
-        write_grf_reg(GRF_SOC_CON9_OFFSET, DPHY_TX1RX1_ENABLE_MASK | (lane_mask << DPHY_TX1RX1_ENABLE_OFFSET_BITS)); 
-    //  set lan turndisab as 1
-        write_grf_reg(GRF_SOC_CON9_OFFSET, DPHY_TX1RX1_TURN_DISABLE_MASK | (0xf << DPHY_TX1RX1_TURN_DISABLE_OFFSET_BITS));
-    //  set lan turnrequest as 0   
-        write_grf_reg(GRF_SOC_CON15_OFFSET, DPHY_TX1RX1_TURN_REQUEST_MASK | (0x0 << DPHY_TX1RX1_TURN_REQUEST_OFFSET_BITS));
+       if(strstr(compatible, "rk3368"))
+               CHIP_TYPE = 3368;
+       else if(strstr(compatible, "rk3288"))
+               CHIP_TYPE = 3288;
+       
+    err = of_property_read_u32(dev->of_node,"rockchip,isp,mipiphy",&mipiphy_cnt);
+    if (err < 0) {
+        camsys_err("get property(rockchip,isp,mipiphy) failed!");
+        goto fail;
+    } else {
+        camsys_trace(2, "%s have %d mipi phy\n",dev_name(&pdev->dev),mipiphy_cnt);
     }
-}
-
-static void phy0_start(int freq,int numLane)
-{
-//TESTCLK=1
-    write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK |DPHY_RX0_TESTCLK); 
-//TESTCLR=1    
-    write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLR_MASK |DPHY_RX0_TESTCLR);   
-//TESTCLR=0  zyc
-//    write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLR_MASK); 
-    udelay(1000);
-
-//**********************************************************************//
-
-#if 1
-//set clock lane
-    phy0_WriteReg(0x34,0x14);
-
-//set lane 0
- /********************
-    500-550M 0x0E
-    600-650M 0x10
-    720M     0x12
-    360M     0x2A
-    *******************/
-    phy0_WriteReg(0x44,0x10);
-    if(numLane > 1)
-        phy0_WriteReg(0x54,0x10);
-#endif
- //**********************************************************************//
-
-//Normal operation
-    phy0_WriteReg(0x0,-1);
-    //TESTCLK=1
-    write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK |DPHY_RX0_TESTCLK); 
-
-    //TESTEN =0
-    write_grf_reg(GRF_SOC_CON14_OFFSET, (DPHY_RX0_TESTEN_MASK)); 
-
-}
-
-
-
-static int camsys_mipiphy_ops (void *phy, void *phyinfo, unsigned int on)
-{
-#if 0
-    camsys_phyinfo_t* phyinfo_s = (camsys_phyinfo_t*)phyinfo;
-    struct camsys_mipiphy_s* phy_s = (struct camsys_mipiphy_s*)phy;
-    if(phy_s->phy_index == 0){
-        phy_select(phy_s->phy_index);
-        phy_config_num_lane(phy_s->data_en_bit);
-        phy0_start(0,phy_s->data_en_bit);
-
-    }else if(phy_s->phy_index == 1){
-
-    }else{
-
-        camsys_err("phy index is erro!");
+    
+    mipiphy = kzalloc(sizeof(camsys_phyinfo_t)*mipiphy_cnt,GFP_KERNEL);
+    if (mipiphy == NULL) {
+        err = -ENOMEM;
+        camsys_err("malloc camsys_phyinfo_t failed!");
+        goto fail;
     }
-#else
-#if 0
-    if(on == 1){
-    //disable isp
-        write_grf_reg(GRF_SOC_CON6_OFFSET, MIPI_PHY_DISABLE_ISP_MASK | 1); 
-        phy_select(0);
-    //    phy_config_num_lane(0,2);
-        phy0_start(0,2);
 
-        phy_config_num_lane(0,2);
-        udelay(200);
-    //enable isp
-        write_grf_reg(GRF_SOC_CON6_OFFSET, MIPI_PHY_DISABLE_ISP_MASK | 0); 
-    }else
-#endif
-    {
-    //disable isp
-        write_grf_reg(GRF_SOC_CON6_OFFSET, MIPI_PHY_DISABLE_ISP_MASK | 1); 
-        phy_select(0);
-        phy_config_num_lane(0,1);
-        phy0_start(0,1);
+    camsys_dev->mipiphy = mipiphy;
+
+    memset(str,0x00,sizeof(str));
+    for (i=0; i<mipiphy_cnt; i++) {
+        meminfo = NULL;
+        sprintf(str,"rockchip,isp,mipiphy%d,reg",i);
+        if (of_property_read_u32_array(dev->of_node,str,phyreg,2) == 0) {
+            meminfo = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
+            if (meminfo == NULL) {                
+                camsys_err("malloc camsys_meminfo_t for mipiphy%d failed!",i);                
+            } else {
+                meminfo->vir_base = (unsigned long)ioremap(phyreg[0],phyreg[1]);
+                if (!meminfo->vir_base){
+                    camsys_err("%s ioremap %s failed",dev_name(&pdev->dev), str);                    
+                } else {
+                    strlcpy(meminfo->name, CAMSYS_MIPIPHY_MEM_NAME,sizeof(meminfo->name));
+                    meminfo->phy_base = phyreg[0];
+                    meminfo->size = phyreg[1];
+                }
+               
+                camsys_dev->mipiphy[i].reg = meminfo;
+            }
+        }
 
-        udelay(200);
-    //enable isp
-        write_grf_reg(GRF_SOC_CON6_OFFSET, MIPI_PHY_DISABLE_ISP_MASK | 0); 
-    }
+        memset(str,sizeof(str),0x00);
+        sprintf(str,"hclk_mipiphy%d",i);
 
-#endif   
-    return 0;
-}
+        clk = devm_clk_get(&pdev->dev, str);
+        if (!IS_ERR_OR_NULL(clk)) {
+            phyclk = kzalloc(sizeof(camsys_mipiphy_clk_t),GFP_KERNEL);
+            if (phyclk == NULL) {
+                camsys_err("malloc camsys_mipiphy_clk_t for %s failed!",str);
+            } else {
+                phyclk->hclk = clk;
+            }
 
-static int camsys_mipiphy_clkin_cb(void *ptr, unsigned int on)
-{
-    return 0;
-}
+            camsys_dev->mipiphy[i].clk = (void*)phyclk;
+        }
 
-static int camsys_mipiphy_remove_cb(struct platform_device *pdev)
-{
+        camsys_dev->mipiphy[i].phycnt = mipiphy_cnt;
+        camsys_dev->mipiphy[i].clkin_cb = camsys_mipiphy_clkin_cb;
+        camsys_dev->mipiphy[i].ops = camsys_mipiphy_ops;
+        camsys_dev->mipiphy[i].remove = camsys_mipiphy_remove_cb;
+
+        if (meminfo != NULL) {
+            camsys_trace(1,"%s mipi phy%d probe success(reg_phy: 0x%lx  reg_vir: 0x%lx  size: 0x%x)",
+                dev_name(&pdev->dev), i,meminfo->phy_base,meminfo->vir_base, meminfo->size);
+        } else {
+            camsys_trace(1,"%s mipi phy%d probe success(reg_phy: 0x%x  reg_vir: 0x%x  size: 0x%x)",
+                dev_name(&pdev->dev), i,0,0,0);
+        }
+
+    }   
+
+       if(CHIP_TYPE == 3368){
+               camsys_dev->csiphy_reg = kzalloc(sizeof(camsys_meminfo_t),GFP_KERNEL);
+           if (camsys_dev->csiphy_reg == NULL) {                
+                   camsys_err("malloc camsys_meminfo_t for csiphy_reg failed!"); 
+               }
+               if (of_property_read_u32_array(dev->of_node,"rockchip,isp,csiphy,reg",phyreg,2) == 0) {
+                       camsys_dev->csiphy_reg->vir_base = (unsigned long)ioremap(phyreg[0],phyreg[1]);
+               if (!camsys_dev->csiphy_reg->vir_base){
+                       camsys_err("%s ioremap %s failed",dev_name(&pdev->dev), "rockchip,isp,csiphy,reg");                    
+               } else {
+               camsys_trace(1,"csiphy vir addr=0x%lx",camsys_dev->csiphy_reg->vir_base);
+                       strlcpy(camsys_dev->csiphy_reg->name, "Csi-DPHY",sizeof(camsys_dev->csiphy_reg->name));
+                       camsys_dev->csiphy_reg->phy_base = phyreg[0];
+                       camsys_dev->csiphy_reg->size = phyreg[1];
+               }
+               }
+               //get cru base
+           node = of_parse_phandle(dev->of_node, "rockchip,cru", 0);
+           rk_cru_base = (unsigned long)of_iomap(node, 0);
+               camsys_trace(1,"rk_cru_base=0x%lx",rk_cru_base);
+               //get grf base
+           node = of_parse_phandle(dev->of_node, "rockchip,grf", 0);
+           rk_grf_base = (unsigned long)of_iomap(node, 0);
+               camsys_trace(1,"rk_grf_base=0x%lx",rk_grf_base);
+       }
+       
     return 0;
-}
-int camsys_mipiphy_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
-{
-    camsys_dev->mipiphy.clkin_cb = camsys_mipiphy_clkin_cb;
-    camsys_dev->mipiphy.ops = camsys_mipiphy_ops;
-    camsys_dev->mipiphy.remove = camsys_mipiphy_remove_cb;
 
+fail:
 
-    return 0;
-  
+    return err;
 }