rk3288: enable camera isp clocks
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_marvin.c
1 #include "camsys_marvin.h"
2
3 static const char miscdev_name[] = CAMSYS_MARVIN_DEVNAME;
4
5 static int camsys_mrv_iomux_cb(camsys_extdev_t *extdev,void *ptr)
6 {  
7     unsigned int cif_vol_sel;
8 #if 0    
9     if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) {
10         iomux_set(ISP_FLASH_TRIG);  
11         if (extdev->fl.fl.io != 0xffffffff) {
12             iomux_set(ISP_FL_TRIG);
13         }
14     } 
15
16     if (extdev->dev_cfg & CAMSYS_DEVCFG_PREFLASHLIGHT) {
17         iomux_set(ISP_PRELIGHT_TRIG);
18     }
19     
20     if (extdev->dev_cfg & CAMSYS_DEVCFG_SHUTTER) {
21         iomux_set(ISP_SHUTTER_OPEN);
22         iomux_set(ISP_SHUTTER_TRIG);
23     }
24
25     iomux_set(CIF0_CLKOUT);
26 #endif
27
28     struct pinctrl      *pinctrl;
29     struct pinctrl_state    *state;
30     int retval = 0;
31     char state_str[20] = {0};
32
33     struct device *dev = &(extdev->pdev->dev);
34     
35     if (extdev->phy.type == CamSys_Phy_Cif) {
36         if ((extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_8b)&& (extdev->phy.info.cif.fmt <= CamSys_Fmt_Raw_12b)) {
37
38            strcpy(state_str,"isp_dvp8bit");
39
40         }
41
42         if ((extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_10b)&& (extdev->phy.info.cif.fmt <= CamSys_Fmt_Raw_12b)) {
43            strcpy(state_str,"isp_dvp10bit");
44         }
45
46         if (extdev->phy.info.cif.fmt == CamSys_Fmt_Raw_12b) {
47            strcpy(state_str,"isp_dvp12bit");
48
49         }
50     }else{
51            strcpy(state_str,"default");
52     }
53
54     //mux CIF0_CLKOUT
55
56     pinctrl = devm_pinctrl_get(dev);
57     if (IS_ERR(pinctrl)) {
58         camsys_err("%s:Get pinctrl failed!\n",__func__);
59         return -1;
60     }
61     state = pinctrl_lookup_state(pinctrl,
62                          state_str);
63     if (IS_ERR(state)){
64         dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
65         return -1;
66         }
67
68     if (!IS_ERR(state)) {
69         retval = pinctrl_select_state(pinctrl, state);
70         if (retval){
71             dev_err(dev,
72                 "%s:could not set %s pins\n",__func__,state_str);
73                 return -1;
74
75                 }
76     }
77
78     //set 1.8v vol domain for rk32
79     __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
80    __raw_writel(0xffffffff, RK_GRF_VIRT+0x01d4);   
81
82     //set cif vol domain
83     if (extdev->phy.type == CamSys_Phy_Cif) {
84
85         #if 0
86         if (!IS_ERR_OR_NULL(extdev->dovdd.ldo)) {
87             if (extdev->dovdd.max_uv >= 25000000) {
88                 __raw_writel(((1<<1)|(1<<(1+16))),RK30_GRF_BASE+0x018c);
89             } else {
90                 __raw_writel((1<<(1+16)),RK30_GRF_BASE+0x018c);
91             }
92         } else {
93             __raw_writel(((1<<1)|(1<<(1+16))),RK30_GRF_BASE+0x018c);
94         }
95         #else
96
97         //set 1.8v vol domain
98         __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
99         #endif
100         
101         //set driver strength
102       //  __raw_writel(0xffffffff, RK_GRF_VIRT+0x01dc);   
103     }
104     
105     return 0;
106 }
107
108 static int camsys_mrv_reset_cb(void *ptr)
109 {
110     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
111     #if 0 //do nothing ,zyc
112     cru_set_soft_reset(SOFT_RST_ISP,true);
113     udelay(100);
114     cru_set_soft_reset(SOFT_RST_ISP,false);
115     #endif
116     camsys_trace(1, "%s soft reset\n",dev_name(camsys_dev->miscdev.this_device));
117     return 0;
118 }
119
120 static int camsys_mrv_clkin_cb(void *ptr, unsigned int on)
121 {
122     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
123     camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
124     
125   //  spin_lock(&clk->lock);
126     if (on && !clk->in_on) {
127         clk_set_rate(clk->isp,180000000);
128         clk_set_rate(clk->isp_jpe, 180000000);
129    //     clk_set_rate(clk->aclk_isp,24000000);
130    //     clk_set_rate(clk->hclk_isp,24000000);
131
132
133         clk_prepare_enable(clk->aclk_isp);
134         clk_prepare_enable(clk->hclk_isp);
135         clk_prepare_enable(clk->isp);
136         clk_prepare_enable(clk->isp_jpe);
137         clk_prepare_enable(clk->clk_mipi_24m); 
138
139  //       clk_enable(clk->pd_isp);
140   //      clk_enable(clk->aclk_isp);
141   //    clk_enable(clk->hclk_isp);      
142   //    clk_enable(clk->isp);
143  //     clk_enable(clk->isp_jpe);
144  //     clk_enable(clk->pclkin_isp);
145         
146         clk->in_on = true;
147
148         camsys_trace(1, "%s clock in turn on",dev_name(camsys_dev->miscdev.this_device));
149         camsys_mrv_reset_cb(ptr);       
150         
151     } else if (!on && clk->in_on) {
152
153
154         clk_disable_unprepare(clk->aclk_isp);
155         clk_disable_unprepare(clk->hclk_isp);
156         clk_disable_unprepare(clk->isp);
157         clk_disable_unprepare(clk->isp_jpe);
158         clk_disable_unprepare(clk->clk_mipi_24m); 
159
160   //      clk_disable(clk->pd_isp);
161   //      clk_disable(clk->aclk_isp);
162    //   clk_disable(clk->hclk_isp);
163   //    clk_disable(clk->isp);
164   //    clk_disable(clk->isp_jpe);
165  //     clk_disable(clk->pclkin_isp);
166
167         clk->in_on = false;
168         camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
169     }
170   //  spin_unlock(&clk->lock);
171     return 0;
172 }
173
174 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on)
175 {
176     camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
177     camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
178     struct clk *cif_clk_out_div;
179     
180     spin_lock(&clk->lock);
181     if (on && (clk->out_on != on)) {  
182         clk_prepare_enable(clk->cif_clk_out);
183
184 //        clk_enable(clk->cif_clk_out);
185         clk_set_rate(clk->cif_clk_out,on);
186         
187         clk->out_on = on;
188         camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
189                     clk->out_on);
190     } else if (!on && clk->out_on) {
191         cif_clk_out_div =  clk_get(NULL, "cif0_out_div");
192         if(IS_ERR_OR_NULL(cif_clk_out_div)) {
193             cif_clk_out_div =  clk_get(NULL, "cif_out_div");
194         }
195
196         if(!IS_ERR_OR_NULL(cif_clk_out_div)) {
197             clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
198             clk_put(cif_clk_out_div);
199         } else {
200             camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
201         }
202
203         clk_disable_unprepare( clk->cif_clk_out);
204 //        clk_disable(clk->cif_clk_out);
205
206         clk->out_on = 0;
207
208         camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
209     }
210     spin_unlock(&clk->lock);    
211
212     return 0;
213 }
214 static irqreturn_t camsys_mrv_irq(int irq, void *data)
215 {
216     camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
217     camsys_irqstas_t *irqsta;
218     camsys_irqpool_t *irqpool;
219     unsigned int isp_mis,mipi_mis,mi_mis,*mis;
220
221     isp_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_MIS));
222     mipi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_MIS));
223     mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));    
224
225     __raw_writel(isp_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_ICR)); 
226     __raw_writel(mipi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_ICR)); 
227     __raw_writel(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_ICR)); 
228
229     spin_lock(&camsys_dev->irq.lock);
230     if (!list_empty(&camsys_dev->irq.irq_pool)) {
231         list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
232             if (irqpool->pid != 0) {
233                 switch(irqpool->mis)
234                 {
235                     case MRV_ISP_MIS:
236                     {
237                         mis = &isp_mis;
238                         break;
239                     }
240
241                     case MRV_MIPI_MIS:
242                     {
243                         mis = &mipi_mis;
244                         break;
245                     }
246                     case MRV_MI_MIS:
247                     {
248                         mis = &mi_mis;
249                         break;
250                     }
251
252                     default:     
253                     {
254                         camsys_trace(2,"Thread(pid:%d) irqpool mis(%d) is invalidate",irqpool->pid,irqpool->mis);
255                         goto end;
256                     }
257                 }
258
259                 if (*mis != 0) {
260                     spin_lock(&irqpool->lock);
261                     if (!list_empty(&irqpool->deactive)) {
262                         irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
263                         irqsta->sta.mis = *mis;                                                 
264                         list_del_init(&irqsta->list);            
265                         list_add_tail(&irqsta->list,&irqpool->active);                        
266                         wake_up(&irqpool->done);
267                     }
268                     spin_unlock(&irqpool->lock);
269                 }
270             }
271         }
272     }
273 end:    
274     spin_unlock(&camsys_dev->irq.lock);
275
276     return IRQ_HANDLED;
277 }
278 static int camsys_mrv_remove_cb(struct platform_device *pdev)
279 {
280     camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
281     camsys_mrv_clk_t *mrv_clk=NULL;
282
283     if (camsys_dev->clk != NULL) {
284
285         mrv_clk = (camsys_mrv_clk_t*)camsys_dev->clk;
286         if (mrv_clk->out_on)
287             camsys_mrv_clkout_cb(mrv_clk,0);
288         if (mrv_clk->in_on)
289             camsys_mrv_clkin_cb(mrv_clk,0);
290     
291         if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
292             clk_put(mrv_clk->pd_isp);
293         }
294         if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
295             clk_put(mrv_clk->aclk_isp);
296         }
297         if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
298             clk_put(mrv_clk->hclk_isp);
299         }
300         if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
301             clk_put(mrv_clk->isp);
302         }
303         if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
304             clk_put(mrv_clk->isp_jpe);
305         }
306         if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
307             clk_put(mrv_clk->pclkin_isp);
308         }
309         if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
310             clk_put(mrv_clk->cif_clk_out);
311         }
312
313         kfree(mrv_clk);
314         mrv_clk = NULL;
315     }
316
317     return 0;
318 }
319 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
320 {
321     int err = 0;   
322     camsys_mrv_clk_t *mrv_clk=NULL;
323     //struct clk *clk_parent;
324     
325     err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, 0, CAMSYS_MARVIN_IRQNAME,camsys_dev);
326     if (err) {
327         camsys_err("request irq for %s failed",CAMSYS_MARVIN_IRQNAME);
328         goto end;
329     }
330
331     //Clk and Iomux init
332     mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t),GFP_KERNEL);
333     if (mrv_clk == NULL) {
334         camsys_err("Allocate camsys_mrv_clk_t failed!");
335         err = -EINVAL;
336         goto clk_failed;
337     }
338      
339    // mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp");
340     mrv_clk->pd_isp = NULL;
341     mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp");
342     mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp");
343     mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp");
344     mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe");
345     mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp");
346     mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_vipout");
347     mrv_clk->clk_mipi_24m = devm_clk_get(&pdev->dev,"clk_mipi_24m"); 
348     if (/*IS_ERR_OR_NULL(mrv_clk->pd_isp) ||*/ IS_ERR_OR_NULL(mrv_clk->aclk_isp) || IS_ERR_OR_NULL(mrv_clk->hclk_isp) ||
349         IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) /*|| IS_ERR_OR_NULL(mrv_clk->pclkin_isp)*/ || 
350         IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) {
351         camsys_err("Get %s clock resouce failed!\n",miscdev_name);
352         err = -EINVAL;
353         goto clk_failed;
354     }
355
356     
357 //    clk_set_rate(mrv_clk->isp,1800000000);
358 //    clk_set_rate(mrv_clk->isp_jpe,180000000);
359     
360     spin_lock_init(&mrv_clk->lock);
361     
362     mrv_clk->in_on = false;
363     mrv_clk->out_on = 0;
364         
365     camsys_dev->clk = (void*)mrv_clk;
366     camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
367     camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
368     camsys_dev->reset_cb = camsys_mrv_reset_cb;
369     camsys_dev->iomux = camsys_mrv_iomux_cb;
370     
371     camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
372     camsys_dev->miscdev.name = miscdev_name;
373     camsys_dev->miscdev.nodename = miscdev_name;
374     camsys_dev->miscdev.fops = &camsys_fops;
375
376     err = misc_register(&camsys_dev->miscdev);
377     if (err < 0) {
378         camsys_err("misc register %s failed!",miscdev_name);
379         goto misc_register_failed;
380     }   
381
382     //Variable init
383     camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
384     camsys_dev->platform_remove = camsys_mrv_remove_cb;
385     
386     return 0;
387 misc_register_failed:
388     if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) {
389         misc_deregister(&camsys_dev->miscdev);
390     }
391
392 clk_failed:
393     if (mrv_clk != NULL) {
394         if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
395             clk_put(mrv_clk->pd_isp);
396         }
397         if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
398             clk_put(mrv_clk->aclk_isp);
399         }
400         if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
401             clk_put(mrv_clk->hclk_isp);
402         }
403         if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
404             clk_put(mrv_clk->isp);
405         }
406         if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
407             clk_put(mrv_clk->isp_jpe);
408         }
409         if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
410             clk_put(mrv_clk->pclkin_isp);
411         }
412         if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
413             clk_put(mrv_clk->cif_clk_out);
414         }
415
416         kfree(mrv_clk);
417         mrv_clk = NULL;
418     }
419     
420 end:
421     return err;
422 }
423 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);
424