+#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*)¶);
+ } 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;
}