Merge branch develop-3.10-next
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_soc_rk3288.c
1 #ifdef CONFIG_ARM
2 #include "camsys_soc_priv.h"
3 #include "camsys_soc_rk3288.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,90,0x00},
14     {90,100,0x10},
15     {100,110,0x20},
16     {110,130,0x01},
17     {130,140,0x11},
18     {140,150,0x21},
19     {150,170,0x02},
20     {170,180,0x12},
21     {180,200,0x22},
22     {200,220,0x03},
23     {220,240,0x13},
24     {240,250,0x23},
25     {250,270,0x4},
26     {270,300,0x14},
27     {300,330,0x5},
28     {330,360,0x15},
29     {360,400,0x25},
30     {400,450,0x06},
31     {450,500,0x16},
32     {500,550,0x07},
33     {550,600,0x17},
34     {600,650,0x08},
35     {650,700,0x18},
36     {700,750,0x09},
37     {750,800,0x19},
38     {800,850,0x29},
39     {850,900,0x39},
40     {900,950,0x0a},
41     {950,1000,0x1a}
42     
43 };
44
45
46 static int camsys_rk3288_mipiphy0_wr_reg(unsigned char addr, unsigned char data)
47 {
48     //TESTCLK=1
49     write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK |DPHY_RX0_TESTCLK);
50     //TESTEN =1,TESTDIN=addr
51     write_grf_reg(GRF_SOC_CON14_OFFSET,(( addr << DPHY_RX0_TESTDIN_OFFSET) |DPHY_RX0_TESTDIN_MASK | DPHY_RX0_TESTEN| DPHY_RX0_TESTEN_MASK)); 
52     //TESTCLK=0
53         write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK); 
54   
55     if(data != 0xff){ //write data ?
56         //TESTEN =0,TESTDIN=data
57         write_grf_reg(GRF_SOC_CON14_OFFSET, (( data << DPHY_RX0_TESTDIN_OFFSET)|DPHY_RX0_TESTDIN_MASK |DPHY_RX0_TESTEN_MASK)); 
58
59         //TESTCLK=1
60         write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK |DPHY_RX0_TESTCLK); 
61     }
62     return 0;
63 }
64 #if 0
65 static int camsys_rk3288_mipiphy0_rd_reg(unsigned char addr)
66 {
67     return read_grf_reg(GRF_SOC_STATUS21);
68 }
69 #endif
70 static int camsys_rk3288_mipiphy1_wr_reg(unsigned int phy_virt,unsigned char addr, unsigned char data)
71 {
72     
73     write_csihost_reg(CSIHOST_PHY_TEST_CTRL1,(0x00010000|addr));    //TESTEN =1,TESTDIN=addr
74     write_csihost_reg(CSIHOST_PHY_TEST_CTRL0,0x00000000);         //TESTCLK=0
75     write_csihost_reg(CSIHOST_PHY_TEST_CTRL1,(0x00000000|data));    //TESTEN =0,TESTDIN=data
76     write_csihost_reg(CSIHOST_PHY_TEST_CTRL0,0x00000002);         //TESTCLK=1 
77
78     return 0;
79 }
80
81 static int camsys_rk3288_mipiphy1_rd_reg(unsigned int phy_virt,unsigned char addr)
82 {
83     return (read_csihost_reg(((CSIHOST_PHY_TEST_CTRL1)&0xff00))>>8);
84 }
85
86 static int camsys_rk3288_mipihpy_cfg (camsys_mipiphy_soc_para_t *para)
87 {    
88     unsigned char hsfreqrange=0xff,i;
89     struct mipiphy_hsfreqrange_s *hsfreqrange_p;
90     unsigned int phy_virt, phy_index;
91     unsigned int *base;
92
93     phy_index = para->phy->phy_index;
94     if (para->camsys_dev->mipiphy[phy_index].reg!=NULL) {
95         phy_virt  = para->camsys_dev->mipiphy[phy_index].reg->vir_base;
96     } else {
97         phy_virt = 0x00;
98     }
99     
100     if ((para->phy->bit_rate == 0) || (para->phy->data_en_bit == 0)) {
101         if (para->phy->phy_index == 0) {
102             base = (unsigned int *)para->camsys_dev->devmems.registermem->vir_base;
103             *(base + (MRV_MIPI_BASE+MRV_MIPI_CTRL)/4) &= ~(0x0f<<8);
104             camsys_trace(1, "mipi phy 0 standby!");
105         } else if (para->phy->phy_index == 1) {
106             write_csihost_reg(CSIHOST_PHY_SHUTDOWNZ,0x00000000);           //SHUTDOWNZ=0
107             write_csihost_reg(CSIHOST_DPHY_RSTZ,0x00000000);               //RSTZ=0
108
109             camsys_trace(1, "mipi phy 1 standby!");
110         }
111
112         return 0;
113     }
114     
115     
116     hsfreqrange_p = mipiphy_hsfreqrange;
117     for (i=0; i<(sizeof(mipiphy_hsfreqrange)/sizeof(struct mipiphy_hsfreqrange_s)); i++) {
118
119         if ((para->phy->bit_rate > hsfreqrange_p->range_l) && (para->phy->bit_rate <= hsfreqrange_p->range_h)) {
120             hsfreqrange = hsfreqrange_p->cfg_bit;
121             break;
122         }
123         hsfreqrange_p++;
124     }
125
126     if (hsfreqrange == 0xff) {
127         camsys_err("mipi phy config bitrate %d Mbps isn't supported!",para->phy->bit_rate);
128         hsfreqrange = 0x00;
129     }
130     hsfreqrange <<= 1;
131     
132     if (para->phy->phy_index == 0) {
133         write_grf_reg(GRF_SOC_CON6_OFFSET, MIPI_PHY_DPHYSEL_OFFSET_MASK | (para->phy->phy_index<<MIPI_PHY_DPHYSEL_OFFSET_BIT)); 
134
135         //  set lane num
136         write_grf_reg(GRF_SOC_CON10_OFFSET, DPHY_RX0_ENABLE_MASK | (para->phy->data_en_bit << DPHY_RX0_ENABLE_OFFSET_BITS)); 
137         //  set lan turndisab as 1
138         write_grf_reg(GRF_SOC_CON10_OFFSET, DPHY_RX0_TURN_DISABLE_MASK | (0xf << DPHY_RX0_TURN_DISABLE_OFFSET_BITS));
139         write_grf_reg(GRF_SOC_CON10_OFFSET, (0x0<<4)|(0xf<<20));
140         //  set lan turnrequest as 0   
141         write_grf_reg(GRF_SOC_CON15_OFFSET, DPHY_RX0_TURN_REQUEST_MASK | (0x0 << DPHY_RX0_TURN_REQUEST_OFFSET_BITS));
142
143         //phy start
144         {
145             write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK |DPHY_RX0_TESTCLK); //TESTCLK=1              
146             write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLR_MASK |DPHY_RX0_TESTCLR);   //TESTCLR=1
147             udelay(100);
148             write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLR_MASK); //TESTCLR=0  zyc
149             udelay(100);
150
151             //set clock lane
152             camsys_rk3288_mipiphy0_wr_reg(0x34,0x15);
153             if (para->phy->data_en_bit >= 0x00)  
154                 camsys_rk3288_mipiphy0_wr_reg(0x44,hsfreqrange);         
155             if (para->phy->data_en_bit >= 0x01) 
156                 camsys_rk3288_mipiphy0_wr_reg(0x54,hsfreqrange);
157             if (para->phy->data_en_bit >= 0x04) { 
158                 camsys_rk3288_mipiphy0_wr_reg(0x84,hsfreqrange);
159                 camsys_rk3288_mipiphy0_wr_reg(0x94,hsfreqrange);
160             }
161
162             //Normal operation
163             camsys_rk3288_mipiphy0_wr_reg(0x0,-1);        
164             write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX0_TESTCLK_MASK |DPHY_RX0_TESTCLK);    //TESTCLK=1     
165             write_grf_reg(GRF_SOC_CON14_OFFSET, (DPHY_RX0_TESTEN_MASK));                     //TESTEN =0 
166         }
167
168         base = (unsigned int *)para->camsys_dev->devmems.registermem->vir_base;
169         *(base + (MRV_MIPI_BASE+MRV_MIPI_CTRL)/4) |= (0x0f<<8);
170         
171     } else if (para->phy->phy_index == 1){
172         
173         write_grf_reg(GRF_SOC_CON6_OFFSET, MIPI_PHY_DPHYSEL_OFFSET_MASK | (para->phy->phy_index<<MIPI_PHY_DPHYSEL_OFFSET_BIT));         
174         write_grf_reg(GRF_SOC_CON6_OFFSET, DSI_CSI_TESTBUS_SEL_MASK | (1<<DSI_CSI_TESTBUS_SEL_OFFSET_BIT)); 
175
176         write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_RX1_SRC_SEL_ISP | DPHY_RX1_SRC_SEL_MASK); 
177         write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_TX1RX1_SLAVEZ | DPHY_TX1RX1_MASTERSLAVEZ_MASK); 
178         write_grf_reg(GRF_SOC_CON14_OFFSET, DPHY_TX1RX1_BASEDIR_REC | DPHY_TX1RX1_BASEDIR_OFFSET); 
179
180         //  set lane num
181         write_grf_reg(GRF_SOC_CON9_OFFSET, DPHY_TX1RX1_ENABLE_MASK | (para->phy->data_en_bit << DPHY_TX1RX1_ENABLE_OFFSET_BITS)); 
182         //  set lan turndisab as 1
183         write_grf_reg(GRF_SOC_CON9_OFFSET, DPHY_TX1RX1_TURN_DISABLE_MASK | (0xf << DPHY_TX1RX1_TURN_DISABLE_OFFSET_BITS));
184         //  set lan turnrequest as 0   
185         write_grf_reg(GRF_SOC_CON15_OFFSET, DPHY_TX1RX1_TURN_REQUEST_MASK | (0x0 << DPHY_TX1RX1_TURN_REQUEST_OFFSET_BITS));
186
187         //phy1 start
188         {
189             write_csihost_reg(CSIHOST_PHY_SHUTDOWNZ,0x00000000);           //SHUTDOWNZ=0
190             write_csihost_reg(CSIHOST_DPHY_RSTZ,0x00000000);               //RSTZ=0
191             write_csihost_reg(CSIHOST_PHY_TEST_CTRL0,0x00000002);          //TESTCLK=1
192             write_csihost_reg(CSIHOST_PHY_TEST_CTRL0,0x00000003);          //TESTCLR=1 TESTCLK=1  
193             udelay(100);
194             write_csihost_reg(CSIHOST_PHY_TEST_CTRL0,0x00000002);          //TESTCLR=0 TESTCLK=1
195             udelay(100);
196    
197             //set clock lane
198             camsys_rk3288_mipiphy1_wr_reg(phy_virt,0x34,0x15);
199             if (para->phy->data_en_bit >= 0x00)  
200                 camsys_rk3288_mipiphy1_wr_reg(phy_virt,0x44,hsfreqrange);         
201             if (para->phy->data_en_bit >= 0x01) 
202                 camsys_rk3288_mipiphy1_wr_reg(phy_virt,0x54,hsfreqrange);
203             if (para->phy->data_en_bit >= 0x04) { 
204                 camsys_rk3288_mipiphy1_wr_reg(phy_virt,0x84,hsfreqrange);
205                 camsys_rk3288_mipiphy1_wr_reg(phy_virt,0x94,hsfreqrange);
206             }
207
208             camsys_rk3288_mipiphy1_rd_reg(phy_virt,0x0);
209             write_csihost_reg(CSIHOST_PHY_TEST_CTRL0,0x00000002);       //TESTCLK=1
210             write_csihost_reg(CSIHOST_PHY_TEST_CTRL1,0x00000000);       //TESTEN =0
211             write_csihost_reg(CSIHOST_PHY_SHUTDOWNZ,0x00000001);        //SHUTDOWNZ=1
212             write_csihost_reg(CSIHOST_DPHY_RSTZ,0x00000001);            //RSTZ=1
213         }
214     } else {
215         camsys_err("mipi phy index %d is invalidate!",para->phy->phy_index);
216         goto fail;
217     }
218
219     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);
220
221
222     return 0;
223
224 fail:
225     return -1;
226 }
227
228 int camsys_rk3288_cfg (camsys_soc_cfg_t cfg_cmd, void* cfg_para)
229 {
230     unsigned int *para_int;
231     
232     switch (cfg_cmd)
233     {
234         case Clk_DriverStrength_Cfg:
235         {
236             para_int = (unsigned int*)cfg_para;
237             __raw_writel((((*para_int)&0x03)<<3)|(0x03<<3), RK_GRF_VIRT+0x01d4);
238             break;
239         }
240
241         case Cif_IoDomain_Cfg:
242         {
243             para_int = (unsigned int*)cfg_para;
244             if (*para_int < 28000000) {
245                 __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);    // 1.8v IO
246             } else {
247                 __raw_writel(((0<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);    // 3.3v IO
248             }
249             break;
250         }
251
252         case Mipi_Phy_Cfg:
253         {
254             camsys_rk3288_mipihpy_cfg((camsys_mipiphy_soc_para_t*)cfg_para);
255             break;
256         }
257
258         case Isp_SoftRst:         /* ddl@rock-chips.com: v0.d.0 */
259         {
260             unsigned int reset;
261             reset = (unsigned int)cfg_para;
262
263             if (reset == 1)
264                 cru_writel(0x40004000,0x1d0);
265             else 
266                 cru_writel(0x40000000,0x1d0);
267             camsys_trace(1, "Isp_SoftRst: %d",reset);
268             break;
269         }
270
271         default:
272         {
273             camsys_warn("cfg_cmd: 0x%x isn't support",cfg_cmd);
274             break;
275         }
276
277     }
278
279     return 0;
280
281
282 }
283 #endif /* CONFIG_ARM */