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