rk3368 camera: hold vio0 noc clock during the camera work, fixed isp iommu stall...
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_soc_rk3368.c
1 #ifdef CONFIG_ARM64
2 #include "camsys_soc_priv.h"
3 #include "camsys_soc_rk3368.h"
4
5
6 struct mipiphy_hsfreqrange_s {
7     unsigned int range_l;
8     unsigned int range_h;
9     unsigned char cfg_bit;
10 };
11
12 static struct mipiphy_hsfreqrange_s mipiphy_hsfreqrange[] = {
13     {80,110,0x00},
14     {110,150,0x01},
15     {150,200,0x02},
16     {200,250,0x03},
17     {250,300,0x04},
18     {300,400,0x05},
19     {400,500,0x06},
20     {500,600,0x07},
21     {600,700,0x08},
22     {700,800,0x09},
23     {800,1000,0x10},
24     {1000,1200,0x11},
25     {1200,1400,0x12},
26     {1400,1600,0x13},
27     {1600,1800,0x14}
28     
29 };
30
31 #if 0
32 static int camsys_rk3368_mipiphy_wr_reg(unsigned long phy_virt, unsigned char addr, unsigned char data)
33 {
34         /*TESTEN =1,TESTDIN=addr */
35         write_csihost_reg(CSIHOST_PHY_TEST_CTRL1, (0x00010000 | addr));
36         /*TESTCLK=0 */
37         write_csihost_reg(CSIHOST_PHY_TEST_CTRL0, 0x00000000);
38         udelay(10);
39         /*TESTEN =0,TESTDIN=data */
40         write_csihost_reg(CSIHOST_PHY_TEST_CTRL1, (0x00000000 | data));
41         /*TESTCLK=1 */
42         write_csihost_reg(CSIHOST_PHY_TEST_CTRL0, 0x00000002);
43         udelay(10);
44
45         return 0;
46 }
47
48 static int camsys_rk3368_mipiphy_rd_reg(unsigned long phy_virt,unsigned char addr)
49 {
50     return (read_csihost_reg(((CSIHOST_PHY_TEST_CTRL1)&0xff00))>>8);
51 }
52
53 static int camsys_rk3368_csiphy_wr_reg(unsigned long csiphy_virt, unsigned char addr, unsigned char data)
54 {
55         write_csiphy_reg(addr,data);
56         return 0;
57 }
58
59 static int camsys_rk3368_csiphy_rd_reg(unsigned long csiphy_virt,unsigned char addr)
60 {
61         return read_csiphy_reg(addr);
62 }
63 #endif
64 static int camsys_rk3368_mipihpy_cfg (camsys_mipiphy_soc_para_t *para)
65
66     unsigned char hsfreqrange=0xff,i;
67     struct mipiphy_hsfreqrange_s *hsfreqrange_p;
68     unsigned long phy_virt, phy_index;
69     unsigned long base;
70         unsigned long csiphy_virt;
71
72     phy_index = para->phy->phy_index;
73     if (para->camsys_dev->mipiphy[phy_index].reg!=NULL) {
74         phy_virt  = para->camsys_dev->mipiphy[phy_index].reg->vir_base;
75     } else {
76         phy_virt = 0x00;
77     }
78     if(para->camsys_dev->csiphy_reg!=NULL){
79                 csiphy_virt = (unsigned long)para->camsys_dev->csiphy_reg->vir_base;
80         }else {
81                 csiphy_virt = 0x00;
82         }
83     if ((para->phy->bit_rate == 0) || (para->phy->data_en_bit == 0)) {
84         if (para->phy->phy_index == 0) {
85                         camsys_trace(1, ">>>>>>>>>>>>>>>>para->phy->phy_index==0");     
86             base = (unsigned long)para->camsys_dev->devmems.registermem->vir_base;
87             *((unsigned int*)(base + (MRV_MIPI_BASE+MRV_MIPI_CTRL))) &= ~(0x0f<<8);
88             camsys_trace(1, "mipi phy 0 standby!");             
89         } else if (para->phy->phy_index == 1) {
90                         /*TODO*/
91         }
92
93         return 0;
94     }
95     
96     hsfreqrange_p = mipiphy_hsfreqrange;
97     for (i=0; i<(sizeof(mipiphy_hsfreqrange)/sizeof(struct mipiphy_hsfreqrange_s)); i++) {
98
99         if ((para->phy->bit_rate > hsfreqrange_p->range_l) && (para->phy->bit_rate <= hsfreqrange_p->range_h)) {
100             hsfreqrange = hsfreqrange_p->cfg_bit;
101             break;
102         }
103         hsfreqrange_p++;
104     }
105
106     if (hsfreqrange == 0xff) {
107         camsys_err("mipi phy config bitrate %d Mbps isn't supported!",para->phy->bit_rate);
108         hsfreqrange = 0x00;
109     }
110         /* hsfreqrange <<= 1; */
111
112     if (para->phy->phy_index == 0) {
113
114                 /*isp select */
115         write_grf_reg(GRF_SOC_CON6_OFFSET, ISP_MIPI_CSI_HOST_SEL_OFFSET_MASK | (1<<ISP_MIPI_CSI_HOST_SEL_OFFSET_BIT)); 
116
117                 /*phy start */
118         {
119                         /*set clock lane */
120                         /*write_csiphy_reg(0x34,0x00); */
121                         
122             write_csiphy_reg((MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x100),hsfreqrange|(read_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x100)&(~0xf)));
123
124                         if(para->phy->data_en_bit > 0x00){
125                                 write_csiphy_reg((MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x180),hsfreqrange|(read_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x180)&(~0xf)));//lane0                       
126                         }
127                         if(para->phy->data_en_bit > 0x02){
128                                 write_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x200,hsfreqrange|(read_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x200)&(~0xf)));//lane1                 
129                         }
130                         if(para->phy->data_en_bit > 0x04){
131                                 write_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x280,hsfreqrange|(read_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x280)&(~0xf)));//lane2                 
132                                 write_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x300,hsfreqrange|(read_csiphy_reg(MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x300)&(~0xf)));        //lane3                         
133                         }
134
135                         /*set data lane num and enable clock lane */
136                         write_csiphy_reg( 0x00, ((para->phy->data_en_bit << 2)|(0x1<<6)|0x1));
137                         //base = (unsigned long)para->camsys_dev->devmems.registermem->vir_base;
138                         //*((unsigned int*)(base + (MRV_MIPI_BASE+MRV_MIPI_CTRL))) =( 0x1|((/*para->phy->data_en_bit*/0x0)<<12)|0x1<<18);
139
140         }
141                 camsys_trace(1,"vir_base=0x%lx",(unsigned long)para->camsys_dev->devmems.registermem->vir_base);                
142
143         base = (unsigned long)para->camsys_dev->devmems.registermem->vir_base;
144         *((unsigned int*)(base + (MRV_MIPI_BASE+MRV_MIPI_CTRL))) &= ~(0x0f<<8);
145         camsys_trace(1,"val:0x%x",*((unsigned int*)(base + (MRV_MIPI_BASE+MRV_MIPI_CTRL))));
146     }
147 #if 0   
148         else if (para->phy->phy_index == 1){
149                 
150                 //csihost select
151         write_grf_reg(GRF_SOC_CON6_OFFSET, ISP_MIPI_CSI_HOST_SEL_OFFSET_MASK | (0<<ISP_MIPI_CSI_HOST_SEL_OFFSET_BIT)); 
152                   
153                 write_csihost_reg(CSIHOST_PHY_TEST_CTRL0,0x00000002);            //TESTCLK=1
154                 write_csihost_reg(CSIHOST_PHY_TEST_CTRL0,0x00000003);            //TESTCLR=1 TESTCLK=1  
155                 udelay(100);
156                 write_csihost_reg(CSIHOST_PHY_TEST_CTRL0,0x00000002);            //TESTCLR=0 TESTCLK=1
157                 udelay(100);
158
159                 //set lane num, csi phy
160                 camsys_rk3368_mipiphy_wr_reg(phy_virt, MIPI_CSI_DPHY_CTRL_LANE_ENABLE_OFFSET<<2, para->phy->data_en_bit << MIPI_CSI_DPHY_CTRL_LANE_ENABLE_OFFSET_BIT);
161
162                 //set clock lane
163                 camsys_rk3368_mipiphy_wr_reg(phy_virt, (MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x100)<<2,0x00);
164                 //MSB enable
165                 //camsys_rk3368_mipiphy_wr_reg(phy_virt, (MIPI_CSI_DPHY_LANEX_MSB_EN_OFFSET+0x100)<<2,0x40);            
166                 if(para->phy->data_en_bit > 0x00){
167                         camsys_rk3368_mipiphy_wr_reg(phy_virt, (MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x180)<<2,hsfreqrange);//lane0
168                         //MSB enable
169                         //camsys_rk3368_mipiphy_wr_reg(phy_virt, (MIPI_CSI_DPHY_LANEX_MSB_EN_OFFSET+0x180)<<2,0x40);
170                 }
171                 if(para->phy->data_en_bit > 0x02){
172                         camsys_rk3368_mipiphy_wr_reg(phy_virt, (MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x200)<<2,hsfreqrange);//lane1
173                         //MSB enable
174                         //camsys_rk3368_mipiphy_wr_reg(phy_virt, (MIPI_CSI_DPHY_LANEX_MSB_EN_OFFSET+0x200)<<2,0x40);
175                 }
176                 if(para->phy->data_en_bit > 0x04){
177                         camsys_rk3368_mipiphy_wr_reg(phy_virt, (MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x280)<<2,hsfreqrange);//lane2
178                         //MSB enable
179                         //camsys_rk3368_mipiphy_wr_reg(phy_virt, (MIPI_CSI_DPHY_LANEX_MSB_EN_OFFSET+0x280)<<2,0x40);
180                         camsys_rk3368_mipiphy_wr_reg(phy_virt, (MIPI_CSI_DPHY_LANEX_THS_SETTLE_OFFSET+0x300)<<2,hsfreqrange); //lane3 
181                         //MSB enable
182                         //camsys_rk3368_mipiphy_wr_reg(phy_virt, (MIPI_CSI_DPHY_LANEX_MSB_EN_OFFSET+0x300)<<2,0x40);
183                 }
184
185                 
186                 //set active lane num, csi host
187                 if(para->phy->data_en_bit > 0x00){
188                         write_csihost_reg(CSIHOST_N_LANES_OFFSET, 0x00);//one lane active
189                 }else if(para->phy->data_en_bit > 0x01){
190                         write_csihost_reg(CSIHOST_N_LANES_OFFSET, 0x01);//two lane active
191                 }else if(para->phy->data_en_bit > 0x04){
192                         write_csihost_reg(CSIHOST_N_LANES_OFFSET, 0x02);// three lane active
193                 }else if(para->phy->data_en_bit > 0x08){
194                         write_csihost_reg(CSIHOST_N_LANES_OFFSET, 0x03);//foure lane active
195                 }
196                 camsys_rk3368_mipiphy_rd_reg(phy_virt,0x0);
197                 write_csihost_reg(CSIHOST_PHY_TEST_CTRL0,0x00000002);  //TESTCLK=1                      
198                 write_csihost_reg(CSIHOST_PHY_TEST_CTRL1,0x00000000); //TESTCLR=0       
199         write_csihost_reg(CSIHOST_PHY_SHUTDOWNZ,0x00000001);  //SHUTDOWNZ=1
200         write_csihost_reg(CSIHOST_DPHY_RSTZ,0x00000001);  //RSTZ=1      
201         write_csihost_reg(CSIHOST_CSI2_RESETN,0x00000001);  //RESETN=1         
202     }
203 #endif
204     else {
205         camsys_err("mipi phy index %d is invalidate!",para->phy->phy_index);
206         goto fail;
207     }
208
209     camsys_trace(1, "mipi phy(%d) turn on(lane: 0x%x  bit_rate: %dMbps)",para->phy->phy_index,para->phy->data_en_bit, para->phy->bit_rate);
210
211     return 0;
212
213 fail:
214     return -1;
215 }
216
217 #define MRV_AFM_BASE            0x0000
218 #define VI_IRCL                         0x0014
219 int camsys_rk3368_cfg (camsys_soc_cfg_t cfg_cmd, void* cfg_para)
220 {
221     unsigned int *para_int;
222     
223     switch (cfg_cmd)
224     {
225         case Clk_DriverStrength_Cfg:
226         {
227             para_int = (unsigned int*)cfg_para;
228                         __raw_writel((((*para_int)&0x03)<<3)|(0x03<<3), (void*)(rk_grf_base+0x204));
229             //__raw_writel(0xffffffff, rk_grf_base+0x204);
230             break;
231         }
232
233         case Cif_IoDomain_Cfg:
234         {
235             para_int = (unsigned int*)cfg_para;
236             if (*para_int < 28000000) {
237                 __raw_writel(((1<<1)|(1<<(1+16))),(void*)(rk_grf_base+0x0900));    // 1.8v IO
238             } else {
239                 __raw_writel(((0<<1)|(1<<(1+16))),(void*)(rk_grf_base+0x0900));    // 3.3v IO
240             }
241             break;
242         }
243
244         case Mipi_Phy_Cfg:
245         {
246             camsys_rk3368_mipihpy_cfg((camsys_mipiphy_soc_para_t*)cfg_para);
247             break;
248         }
249
250         case Isp_SoftRst:         /* ddl@rock-chips.com: v0.d.0 */
251         {
252             unsigned long reset;
253             reset = (unsigned long)cfg_para;
254                         #if 0
255             if (reset == 1)
256                 write_cru_reg(0x318,0x40004000);
257             else 
258                 write_cru_reg(0x318,0x40000000);
259             camsys_trace(1, "Isp_SoftRst: %d",reset);
260                         #endif
261                         if (reset == 1)
262                                 __raw_writel(0x80,
263                                              (void*)(rk_isp_base + MRV_AFM_BASE +
264                                              VI_IRCL));
265                         else
266                                 __raw_writel(0x00,
267                                              (void*)(rk_isp_base + MRV_AFM_BASE +
268                                              VI_IRCL));
269                         camsys_trace(1, "Isp self soft rst: %ld", reset);
270             break;
271         }
272
273         default:
274         {
275             camsys_warn("cfg_cmd: 0x%x isn't support",cfg_cmd);
276             break;
277         }
278
279     }
280
281     return 0;
282 }
283 #endif /* CONFIG_ARM64 */