camera: rockchip: camsys version 0.0x21.0xb
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_mipicsi_phy.c
index 62335ad55ec7095fd800a3619def21586c51d7f2..fb5d83baf6f2b0e4e7ae998925850f68c9db14ef 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)
-
-#define DPHY_RX0_TESTCLR    (1<<0)
-#define DPHY_RX0_TESTCLK    (1<<1)
-#define DPHY_RX0_TESTEN     (1<<2)
-#define DPHY_RX0_TESTDIN_OFFSET    (3)
-
-
-//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_RX0_MASK       (0x1<<16)
-#define MIPI_PHY_RX0            (0x1<<0)
-
-#endif
-
-static void phy0_WriteReg(uint8_t addr, uint8_t data)
+unsigned int CHIP_TYPE;
+unsigned long rk_grf_base;
+unsigned long rk_cru_base;
+unsigned long rk_isp_base;
+
+static int camsys_mipiphy_clkin_cb(void *ptr, unsigned int on)
 {
+       camsys_mipiphy_clk_t *clk;
+       camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
+       unsigned int i, phycnt;
 
-    //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); 
-    //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->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;
+                               }
+                       }
+               }
+       }
+       if (on)
+               camsys_trace(2, "%s mipiphy clk turn on",
+               dev_name(camsys_dev->miscdev.this_device));
+       else
+               camsys_trace(2, "%s mipiphy clk turn off",
+               dev_name(camsys_dev->miscdev.this_device));
+
+       return 0;
 }
 
-static uint8_t phy0_ReadReg(uint8_t addr)  //read 0xff968034 bit8~15
+static int camsys_mipiphy_ops(void *ptr, camsys_mipiphy_t *phy)
 {
-    uint8_t 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=0
-    write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK); 
-
-    data = ((read_grf_reg(GRF_SOC_CON14_OFFSET) >> DPHY_RX0_TESTDIN_OFFSET) & (0xff));
+       camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
+       camsys_mipiphy_soc_para_t para;
+       camsys_soc_priv_t *soc;
 
-    camsys_err("%s phy addr = 0x%x,value = 0x%x\n",__func__,addr,data);
-    return data ;
+       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)(camsys_dev, 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 int camsys_mipiphy_remove_cb(struct platform_device *pdev)
+{
+       camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
+       camsys_mipiphy_clk_t *phyclk;
+       unsigned int i = 0;
+       unsigned long vir_base = camsys_dev->mipiphy[i].reg->vir_base;
+
+       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 *)vir_base);
+                                       vir_base = 0;
+                               }
+                               kfree(camsys_dev->mipiphy[i].reg);
+                               camsys_dev->mipiphy[i].reg = NULL;
+                       }
 
-static void PHY0_Init(int numLane,int clkfreq)
+                       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 || CHIP_TYPE == 3366 || CHIP_TYPE == 3399) {
+               if (camsys_dev->csiphy_reg != NULL) {
+                       kfree(camsys_dev->csiphy_reg);
+                       camsys_dev->csiphy_reg = NULL;
+               }
+
+               if (camsys_dev->dsiphy_reg != NULL) {
+                       kfree(camsys_dev->dsiphy_reg);
+                       camsys_dev->dsiphy_reg = NULL;
+               }
+       }
+
+       return 0;
+}
+
+int camsys_mipiphy_probe_cb(
+struct platform_device *pdev, camsys_dev_t *camsys_dev)
 {
-    
-//  select phy rx0
-    write_grf_reg(GRF_SOC_CON6_OFFSET, MIPI_PHY_RX0_MASK | MIPI_PHY_RX0); 
+       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;
 
-//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_TESTCLK_MASK |DPHY_RX0_TESTCLK | DPHY_RX0_TESTCLR_MASK |DPHY_RX0_TESTCLR);   
-//TESTCLR=0  zyc
-    write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK |DPHY_RX0_TESTCLK); 
+       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);
+       }
 
-//**********************************************************************//
+       mipiphy = kzalloc(sizeof(camsys_phyinfo_t)*mipiphy_cnt, GFP_KERNEL);
+       if (mipiphy == NULL) {
+               err = -ENOMEM;
+               camsys_err("malloc camsys_phyinfo_t failed!");
+               goto fail;
+       }
 
-//set clock lane
-    phy0_WriteReg(0x34,0x14);
+       camsys_dev->mipiphy = mipiphy;
 
-//set lane 0
- /********************
-    500-550M 0x0E
-    600-650M 0x10
-    720M     0x12
-    360M     0x2A
-    *******************/
-    phy0_WriteReg(0x44,0x10);
- //**********************************************************************//
+       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;
+                       }
+               }
 
-//Normal operation
-    phy0_ReadReg(0x00);                           
-    //TESTCLK=1
-    write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK |DPHY_RX0_TESTCLK); 
+               sprintf(str, "hclk_mipiphy%d", i);
 
-    //TESTEN =0
-    write_grf_reg(GRF_SOC_CON14_OFFSET, (DPHY_RX0_TESTEN)); 
+               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;
+                       }
 
- }
+                       camsys_dev->mipiphy[i].clk = (void *)phyclk;
+               }
 
+               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;
 
-static int camsys_mipiphy_ops (void *phy, void *phyinfo, unsigned int on)
-{
-    PHY0_Init(1,0);
-    return 0;
-}
+               if (meminfo != NULL) {
+                       camsys_trace(1, "%s mipi phy%d probe success "
+                               "(reg_phy: 0x%lx  reg_vir: 0x%lx  size: 0x%x)\n",
+                               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)\n",
+                               dev_name(&pdev->dev), i, 0, 0, 0);
+               }
 
-static int camsys_mipiphy_clkin_cb(void *ptr, unsigned int on)
-{
-    return 0;
-}
+       }
 
-static int camsys_mipiphy_remove_cb(struct platform_device *pdev)
-{
-    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;
+       if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366 || CHIP_TYPE == 3399) {
+
+               if (CHIP_TYPE == 3399) {
+                       camsys_dev->dsiphy_reg =
+                               kzalloc(sizeof(camsys_meminfo_t), GFP_KERNEL);
+                       if (camsys_dev->dsiphy_reg == NULL) {
+                               camsys_err("malloc camsys_meminfo_t for dsiphy_reg failed!");
+                       }
+
+                       if (of_property_read_u32_array(
+                                       dev->of_node,
+                                       "rockchip,isp,dsiphy,reg", phyreg, 2
+                                       ) == 0
+                               ) {
+                                       camsys_dev->dsiphy_reg->vir_base =
+                                               (unsigned long)
+                                               ioremap(phyreg[0], phyreg[1]);
+                               if (!camsys_dev->dsiphy_reg->vir_base) {
+                                       camsys_err("%s ioremap %s failed",
+                                               dev_name(&pdev->dev),
+                                               "rockchip,isp,dsiphy,reg");
+                               } else {
+                               strlcpy(camsys_dev->dsiphy_reg->name,
+                                       "Dsi-DPHY",
+                                       sizeof(camsys_dev->dsiphy_reg->name));
+                               camsys_dev->dsiphy_reg->phy_base = phyreg[0];
+                               camsys_dev->dsiphy_reg->size = phyreg[1];
+                               }
+                       }
+
+       } else {
+                       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 {
+                                       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);
+               camsys_dev->rk_cru_base = (unsigned long)of_iomap(node, 0);
+               camsys_trace(2, "rk_cru_base=0x%lx", camsys_dev->rk_cru_base);
+               /* get grf base */
+               node = of_parse_phandle(dev->of_node, "rockchip,grf", 0);
+               camsys_dev->rk_grf_base = (unsigned long)of_iomap(node, 0);
+               camsys_trace(2, "rk_grf_base=0x%lx", camsys_dev->rk_grf_base);
+       }
+
+       return 0;
+
+fail:
 
-    return 0;
-  
+       return err;
 }