Merge tag 'lsk-v4.4-16.07-android'
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_marvin.c
1 #include "camsys_marvin.h"
2 #include "camsys_soc_priv.h"
3 #include "camsys_gpio.h"
4
5 #include <linux/rockchip/common.h>
6 #include <dt-bindings/clock/rk_system_status.h>
7 #include <linux/rockchip_ion.h>
8 #include <linux/file.h>
9 #include <linux/pm_runtime.h>
10
11 extern int rockchip_set_system_status(unsigned long status);
12 extern int rockchip_clear_system_status(unsigned long status);
13
14 static const char miscdev_name[] = CAMSYS_MARVIN_DEVNAME;
15
16 static int camsys_mrv_iomux_cb(camsys_extdev_t *extdev, void *ptr)
17 {
18         struct pinctrl          *pinctrl;
19         struct pinctrl_state    *state;
20         int retval = 0;
21         char state_str[20] = {0};
22         camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
23         struct device *dev = &(extdev->pdev->dev);
24         camsys_soc_priv_t *soc;
25
26         /* DVP IO Config */
27
28         if (extdev->phy.type == CamSys_Phy_Cif) {
29                 switch (extdev->phy.info.cif.fmt) {
30                 case CamSys_Fmt_Raw_8b:
31                 case CamSys_Fmt_Yuv420_8b:
32                 case CamSys_Fmt_Yuv422_8b:{
33                         if (extdev->phy.info.cif.cifio ==
34                                 CamSys_SensorBit0_CifBit0) {
35                                 strcpy(state_str, "isp_dvp8bit0");
36                         } else if (extdev->phy.info.cif.cifio ==
37                         CamSys_SensorBit0_CifBit2) {
38                                 strcpy(state_str, "isp_dvp8bit2");
39                         } else if (extdev->phy.info.cif.cifio ==
40                         CamSys_SensorBit0_CifBit4) {
41                                 strcpy(state_str, "isp_dvp8bit4");
42                         } else {
43                                 camsys_err("extdev->phy.info.cif.cifio:0x%x is invalidate!",
44                                         extdev->phy.info.cif.cifio);
45                                 goto fail;
46                         }
47
48                         break;
49                 }
50
51                 case CamSys_Fmt_Raw_10b:{
52                         strcpy(state_str, "isp_dvp10bit");
53                         break;
54                 }
55
56                 case CamSys_Fmt_Raw_12b:{
57                         strcpy(state_str, "isp_dvp12bit");
58                         break;
59                 }
60
61                 default:{
62                         camsys_err("extdev->phy.info.cif.fmt: 0x%x is invalidate!",
63                                 extdev->phy.info.cif.fmt);
64                         goto fail;
65                 }
66                 }
67         } else {
68                 if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) {
69                         if (extdev->dev_cfg & CAMSYS_DEVCFG_PREFLASHLIGHT) {
70                                 strcpy(state_str, "isp_mipi_fl_prefl");
71                         } else {
72                                 strcpy(state_str, "isp_mipi_fl");
73                         }
74                         {
75                                 /*mux triggerout as gpio*/
76                                 /*get gpio index*/
77                                 int flash_trigger_io;
78                                 enum of_gpio_flags flags;
79
80                                 flash_trigger_io =
81                                         of_get_named_gpio_flags(
82                                         camsys_dev->pdev->dev.of_node,
83                                         "rockchip,gpios", 0, &flags);
84                                 if (gpio_is_valid(flash_trigger_io)) {
85                                         flash_trigger_io =
86                                                 of_get_named_gpio_flags(
87                                                 camsys_dev->pdev->dev.of_node,
88                                                 "rockchip,gpios", 0, &flags);
89                                         gpio_request(flash_trigger_io,
90                                                 "camsys_gpio");
91                                         gpio_direction_output(
92                                                 flash_trigger_io,
93                                                 (~(extdev->fl.fl.active) &
94                                                 0x1));
95                                 }
96                         }
97                 } else {
98                         if (CHIP_TYPE == 3399) {
99                                 strcpy(state_str, "cif_clkout");
100                         } else {
101                                 strcpy(state_str, "default");
102                         }
103                 }
104         }
105
106         camsys_trace(1, "marvin pinctrl select: %s", state_str);
107
108         pinctrl = devm_pinctrl_get(dev);
109         if (IS_ERR(pinctrl)) {
110                 camsys_err("devm_pinctrl_get failed!");
111                 goto fail;
112         }
113         state = pinctrl_lookup_state(pinctrl,
114                                                         state_str);
115         if (IS_ERR(state)) {
116                 camsys_err("pinctrl_lookup_state failed!");
117                 goto fail;
118         }
119
120         if (!IS_ERR(state)) {
121                 retval = pinctrl_select_state(pinctrl, state);
122                 if (retval) {
123                         camsys_err("pinctrl_select_state failed!");
124                         goto fail;
125                 }
126         }
127
128         if (camsys_dev->soc) {
129                 soc = (camsys_soc_priv_t *)camsys_dev->soc;
130                 if (soc->soc_cfg) {
131                         (soc->soc_cfg)(camsys_dev, Cif_IoDomain_Cfg,
132                                 (void *)&extdev->dovdd.min_uv);
133                         (soc->soc_cfg)(camsys_dev, Clk_DriverStrength_Cfg,
134                                 (void *)&extdev->clk.driver_strength);
135                 } else {
136                         camsys_err("camsys_dev->soc->soc_cfg is NULL!");
137                 }
138         } else {
139                 camsys_err("camsys_dev->soc is NULL!");
140         }
141
142         return 0;
143 fail:
144         return -1;
145 }
146
147 static int camsys_mrv_flash_trigger_cb(void *ptr, int mode, unsigned int on)
148 {
149         camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
150         struct device *dev = &(camsys_dev->pdev->dev);
151         int flash_trigger_io;
152         struct pinctrl          *pinctrl;
153         struct pinctrl_state    *state;
154         char state_str[20] = {0};
155         int retval = 0;
156         enum of_gpio_flags flags;
157         camsys_extdev_t *extdev = NULL;
158
159         if (!on) {
160                 strcpy(state_str, "isp_flash_as_gpio");
161                 pinctrl = devm_pinctrl_get(dev);
162                 if (IS_ERR(pinctrl)) {
163                         camsys_err("devm_pinctrl_get failed!");
164                 }
165                 state = pinctrl_lookup_state(pinctrl, state_str);
166                 if (IS_ERR(state)) {
167                         camsys_err("pinctrl_lookup_state failed!");
168                 }
169
170                 if (!IS_ERR(state)) {
171                         retval = pinctrl_select_state(pinctrl, state);
172                         if (retval) {
173                                 camsys_err("pinctrl_select_state failed!");
174                         }
175                 }
176
177                 /*get gpio index*/
178                 flash_trigger_io = of_get_named_gpio_flags(
179                         camsys_dev->pdev->dev.of_node,
180                                 "rockchip,gpios", 0, &flags);
181                 if (gpio_is_valid(flash_trigger_io)) {
182                         flash_trigger_io = of_get_named_gpio_flags(
183                                 camsys_dev->pdev->dev.of_node,
184                                 "rockchip,gpios", 0, &flags);
185                         gpio_request(flash_trigger_io, "camsys_gpio");
186                         /*get flash io active pol*/
187                         if (!list_empty(&camsys_dev->extdevs.list)) {
188                                 list_for_each_entry(
189                                         extdev, &camsys_dev->extdevs.list,
190                                         list) {
191                                         if (extdev->dev_cfg &
192                                                 CAMSYS_DEVCFG_FLASHLIGHT) {
193                                                 gpio_direction_output(
194                                                         flash_trigger_io,
195                                                         (~(extdev->fl.fl.active)
196                                                         & 0x1));
197                                         }
198                                 }
199                         }
200                 }
201         } else{
202                 strcpy(state_str, "isp_flash_as_trigger_out");
203                 pinctrl = devm_pinctrl_get(dev);
204                 if (IS_ERR(pinctrl)) {
205                         camsys_err("devm_pinctrl_get failed!");
206                 }
207                 state = pinctrl_lookup_state(pinctrl,
208                                                                 state_str);
209                 if (IS_ERR(state)) {
210                         camsys_err("pinctrl_lookup_state failed!");
211                 }
212
213                 if (!IS_ERR(state)) {
214                         retval = pinctrl_select_state(pinctrl, state);
215                         if (retval) {
216                                 camsys_err("pinctrl_select_state failed!");
217                         }
218
219                 }
220         }
221         return retval;
222 }
223 static struct device *rockchip_get_sysmmu_device_by_compatible(
224 const char *compt)
225 {
226         struct device_node *dn = NULL;
227         struct platform_device *pd = NULL;
228         struct device *ret = NULL;
229
230         dn = of_find_compatible_node(NULL, NULL, compt);
231         if (!dn) {
232                 camsys_err("can't find device node %s \r\n", compt);
233                 return NULL;
234         }
235
236         pd = of_find_device_by_node(dn);
237         if (!pd) {
238                 camsys_err(
239                         "can't find platform device in device node %s \r\n",
240                         compt);
241                 return  NULL;
242         }
243         ret = &pd->dev;
244
245         return ret;
246
247 }
248 #ifdef CONFIG_IOMMU_API
249 static inline void platform_set_sysmmu(
250 struct device *iommu, struct device *dev)
251 {
252         dev->archdata.iommu = iommu;
253 }
254 #else
255 static inline void platform_set_sysmmu(
256 struct device *iommu, struct device *dev)
257 {
258 }
259 #endif
260
261
262 static int camsys_mrv_iommu_cb(void *ptr, camsys_sysctrl_t *devctl)
263 {
264         struct device *iommu_dev = NULL, *dev = NULL;
265         struct file *file = NULL;
266         struct ion_client *client = NULL;
267         struct ion_handle *handle = NULL;
268         camsys_iommu_t *iommu = NULL;
269         int ret = 0, iommu_enabled = 0;
270         camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
271
272         of_property_read_u32(camsys_dev->pdev->dev.of_node,
273                 "rockchip,isp,iommu-enable", &iommu_enabled);
274         if (iommu_enabled != 1) {
275                 camsys_err("isp iommu have not been enabled!\n");
276                 ret = -1;
277                 goto iommu_end;
278         }
279
280         if (strstr(camsys_dev->miscdev.name, "camsys_marvin1")) {
281                 iommu_dev =
282                         rockchip_get_sysmmu_device_by_compatible
283                                 (ISP1_IOMMU_COMPATIBLE_NAME);
284         } else{
285                 if (CHIP_TYPE == 3399) {
286                         iommu_dev =
287                                 rockchip_get_sysmmu_device_by_compatible
288                                         (ISP0_IOMMU_COMPATIBLE_NAME);
289                 } else{
290                         iommu_dev =
291                                 rockchip_get_sysmmu_device_by_compatible
292                                         (ISP_IOMMU_COMPATIBLE_NAME);
293                 }
294         }
295
296         if (!iommu_dev) {
297                 camsys_err("get iommu device erro!\n");
298                 ret = -1;
299                 goto iommu_end;
300         }
301         dev = &(camsys_dev->pdev->dev);
302         iommu = (camsys_iommu_t *)(devctl->rev);
303         file = fget(iommu->client_fd);
304         if (!file) {
305                 camsys_err("get client_fd file erro!\n");
306                 ret = -1;
307                 goto iommu_end;
308         }
309
310         client = file->private_data;
311
312         if (!client) {
313                 camsys_err("get ion_client erro!\n");
314                 ret = -1;
315                 goto iommu_end;
316         }
317
318         fput(file);
319
320         handle = ion_import_dma_buf(client, iommu->map_fd);
321
322         camsys_trace(1, "map fd %d ,client fd %d\n",
323                 iommu->map_fd, iommu->client_fd);
324         if (!handle) {
325                 camsys_err("get ion_handle erro!\n");
326                 ret = -1;
327                 goto iommu_end;
328         }
329         if (devctl->on) {
330                 platform_set_sysmmu(iommu_dev, dev);
331                 ret = rockchip_iovmm_activate(dev);
332                 ret = ion_map_iommu(dev, client, handle,
333                         &(iommu->linear_addr), &(iommu->len));
334         } else{
335                 ion_unmap_iommu(dev, client, handle);
336                 platform_set_sysmmu(iommu_dev, dev);
337                 rockchip_iovmm_deactivate(dev);
338         }
339 iommu_end:
340         return ret;
341 }
342 static int camsys_mrv_reset_cb(void *ptr, unsigned int on)
343 {
344         camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
345         camsys_soc_priv_t *soc;
346
347         if (camsys_dev->soc) {
348                 soc = (camsys_soc_priv_t *)camsys_dev->soc;
349                 if (soc->soc_cfg) {
350                         (soc->soc_cfg)
351                                 (camsys_dev, Isp_SoftRst,
352                                 (void *)(unsigned long)on);
353                 } else {
354                         camsys_err("camsys_dev->soc->soc_cfg is NULL!");
355                 }
356         } else {
357                 camsys_err("camsys_dev->soc is NULL!");
358         }
359
360         return 0;
361 }
362
363 static int camsys_mrv_clkin_cb(void *ptr, unsigned int on)
364 {
365         camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
366         camsys_mrv_clk_t *clk = (camsys_mrv_clk_t *)camsys_dev->clk;
367         unsigned long isp_clk;
368
369         if (CHIP_TYPE == 3399) {
370                 if (on && !clk->in_on) {
371                         /* rockchip_set_system_status(SYS_STATUS_ISP); */
372                         if (on == 1)
373                                 isp_clk = 210000000;
374                         else
375                                 isp_clk = 210000000;
376
377                         if (strstr(camsys_dev->miscdev.name,
378                                 "camsys_marvin1")) {
379                                 clk_set_rate(clk->clk_isp1, isp_clk);
380                                 clk_prepare_enable(clk->hclk_isp1_noc);
381                                 clk_prepare_enable(clk->hclk_isp1_wrapper);
382                                 clk_prepare_enable(clk->aclk_isp1_noc);
383                                 clk_prepare_enable(clk->aclk_isp1_wrapper);
384                                 clk_prepare_enable(clk->clk_isp1);
385
386                                 clk_prepare_enable(clk->cif_clk_out);
387                                 clk_prepare_enable(clk->pclk_dphy_ref);
388                                 clk_prepare_enable(clk->pclk_dphytxrx);
389
390                                 clk_prepare_enable(clk->pclkin_isp);
391                                 clk_prepare_enable(clk->cif_clk_out);
392                         } else{
393                                 clk_set_rate(clk->clk_isp0, isp_clk);
394                                 clk_prepare_enable(clk->hclk_isp0_noc);
395                                 clk_prepare_enable(clk->hclk_isp0_wrapper);
396                                 clk_prepare_enable(clk->aclk_isp0_noc);
397                                 clk_prepare_enable(clk->aclk_isp0_wrapper);
398                                 clk_prepare_enable(clk->clk_isp0);
399                                 clk_prepare_enable(clk->cif_clk_out);
400                                 clk_prepare_enable(clk->pclk_dphyrx);
401                                 clk_prepare_enable(clk->pclk_dphy_ref);
402                         }
403
404                 clk_set_rate(clk->clk_isp0, isp_clk);
405                 clk_set_rate(clk->clk_isp1, isp_clk);
406
407                 clk->in_on = true;
408
409                 camsys_trace(1, "%s clock(f: %ld Hz) in turn on",
410                         dev_name(camsys_dev->miscdev.this_device), isp_clk);
411                 camsys_mrv_reset_cb(ptr, 1);
412                 udelay(100);
413                 camsys_mrv_reset_cb(ptr, 0);
414                 } else if (!on && clk->in_on) {
415                         if (strstr(camsys_dev->miscdev.name,
416                                 "camsys_marvin1")) {
417                                 clk_disable_unprepare(clk->hclk_isp1_noc);
418                                 clk_disable_unprepare(clk->hclk_isp1_wrapper);
419                                 clk_disable_unprepare(clk->aclk_isp1_noc);
420                                 clk_disable_unprepare(clk->aclk_isp1_wrapper);
421                                 clk_disable_unprepare(clk->clk_isp1);
422
423                                 clk_disable_unprepare(clk->cif_clk_out);
424                                 clk_disable_unprepare(clk->pclk_dphytxrx);
425                                 clk_disable_unprepare(clk->pclk_dphy_ref);
426
427                                 clk_disable_unprepare(clk->pclkin_isp);
428                         } else{
429                                 clk_disable_unprepare(clk->hclk_isp0_noc);
430                                 clk_disable_unprepare(clk->hclk_isp0_wrapper);
431                                 clk_disable_unprepare(clk->aclk_isp0_noc);
432                                 clk_disable_unprepare(clk->aclk_isp0_wrapper);
433                                 clk_disable_unprepare(clk->clk_isp0);
434
435                                 clk_disable_unprepare(clk->cif_clk_out);
436                                 clk_disable_unprepare(clk->pclk_dphyrx);
437                                 clk_disable_unprepare(clk->pclk_dphy_ref);
438                         }
439
440                 /* rockchip_clear_system_status(SYS_STATUS_ISP); */
441                 clk->in_on = false;
442                 camsys_trace(1, "%s clock in turn off",
443                         dev_name(camsys_dev->miscdev.this_device));
444                 }
445         } else{
446                 if (on && !clk->in_on) {
447                         /* rockchip_set_system_status(SYS_STATUS_ISP); */
448
449                 if (on == 1)
450                         isp_clk = 210000000;
451                 else
452                         isp_clk = 420000000;
453
454                 clk_set_rate(clk->isp, isp_clk);
455                 clk_set_rate(clk->isp_jpe, isp_clk);
456
457                 /* clk_prepare_enable(clk->pd_isp); */
458                 clk_prepare_enable(clk->aclk_isp);
459                 clk_prepare_enable(clk->hclk_isp);
460                 clk_prepare_enable(clk->isp);
461                 clk_prepare_enable(clk->isp_jpe);
462                 clk_prepare_enable(clk->pclkin_isp);
463                 if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) {
464                         clk_prepare_enable(clk->cif_clk_out);
465                         clk_prepare_enable(clk->pclk_dphyrx);
466                         if (CHIP_TYPE == 3368)
467                                 clk_prepare_enable(clk->clk_vio0_noc);
468                 } else{
469                         clk_prepare_enable(clk->clk_mipi_24m);
470                 }
471                         clk->in_on = true;
472
473                 camsys_trace(1, "%s clock(f: %ld Hz) in turn on",
474                         dev_name(camsys_dev->miscdev.this_device), isp_clk);
475                 camsys_mrv_reset_cb(ptr, 1);
476                 udelay(100);
477                 camsys_mrv_reset_cb(ptr, 0);
478                 } else if (!on && clk->in_on) {
479                 clk_disable_unprepare(clk->aclk_isp);
480                 clk_disable_unprepare(clk->hclk_isp);
481                 clk_disable_unprepare(clk->isp);
482                 clk_disable_unprepare(clk->isp_jpe);
483                 clk_disable_unprepare(clk->pclkin_isp);
484                 if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) {
485                         clk_disable_unprepare(clk->cif_clk_out);
486                         clk_disable_unprepare(clk->pclk_dphyrx);
487                         if (CHIP_TYPE == 3368)
488                                 clk_disable_unprepare(clk->clk_vio0_noc);
489                 } else{
490                         clk_disable_unprepare(clk->clk_mipi_24m);
491                 }
492                 /* clk_disable_unprepare(clk->pd_isp); */
493
494                 /* rockchip_clear_system_status(SYS_STATUS_ISP); */
495                 clk->in_on = false;
496                 camsys_trace(1, "%s clock in turn off",
497                         dev_name(camsys_dev->miscdev.this_device));
498                 }
499         }
500
501         return 0;
502 }
503
504 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on, unsigned int inclk)
505 {
506         camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
507         camsys_mrv_clk_t *clk = (camsys_mrv_clk_t *)camsys_dev->clk;
508
509         mutex_lock(&clk->lock);
510         if (on && (clk->out_on != on)) {
511
512                 pm_runtime_get_sync(&camsys_dev->pdev->dev);
513
514                 clk_set_rate(clk->cif_clk_out, inclk);
515                 clk_prepare_enable(clk->cif_clk_out);
516                 clk->out_on = on;
517                 camsys_trace(1, "camsys %s clock out(rate: %dHz) turn on",
518                         dev_name(camsys_dev->miscdev.this_device),
519                                         inclk);
520         } else if (!on && clk->out_on) {
521                 if (!IS_ERR_OR_NULL(clk->cif_clk_pll)) {
522                         clk_set_parent(clk->cif_clk_out,
523                                 clk->cif_clk_pll);
524                 } else {
525                         camsys_warn("%s clock out may be not off!",
526                                 dev_name(camsys_dev->miscdev.this_device));
527                 }
528
529                 clk_disable_unprepare(clk->cif_clk_out);
530
531                 pm_runtime_disable(&camsys_dev->pdev->dev);
532                 clk->out_on = 0;
533
534                 camsys_trace(1, "%s clock out turn off",
535                         dev_name(camsys_dev->miscdev.this_device));
536         }
537         mutex_unlock(&clk->lock);
538
539         return 0;
540 }
541 static irqreturn_t camsys_mrv_irq(int irq, void *data)
542 {
543         camsys_dev_t *camsys_dev = (camsys_dev_t *)data;
544         camsys_irqstas_t *irqsta;
545         camsys_irqpool_t *irqpool;
546         unsigned int isp_mis, mipi_mis, mi_mis, *mis, jpg_mis, jpg_err_mis;
547         unsigned int mi_ris, mi_imis;
548
549         isp_mis = __raw_readl((void volatile *)
550                                 (camsys_dev->devmems.registermem->vir_base +
551                                 MRV_ISP_MIS));
552         mipi_mis = __raw_readl((void volatile *)
553                                 (camsys_dev->devmems.registermem->vir_base +
554                                 MRV_MIPI_MIS));
555         jpg_mis = __raw_readl((void volatile *)
556                                 (camsys_dev->devmems.registermem->vir_base +
557                                 MRV_JPG_MIS));
558         jpg_err_mis = __raw_readl((void volatile *)
559                                 (camsys_dev->devmems.registermem->vir_base +
560                                 MRV_JPG_ERR_MIS));
561         mi_mis = __raw_readl((void volatile *)
562                                 (camsys_dev->devmems.registermem->vir_base +
563                                 MRV_MI_MIS));
564
565         mi_ris =  __raw_readl((void volatile *)
566                                 (camsys_dev->devmems.registermem->vir_base +
567                                 MRV_MI_RIS));
568         mi_imis = __raw_readl((void volatile *)
569                                 (camsys_dev->devmems.registermem->vir_base +
570                                 MRV_MI_IMIS));
571         while ((mi_ris & mi_imis) != mi_mis) {
572         camsys_trace(2, "mi_mis status erro,mi_mis 0x%x,"
573                                 "mi_ris 0x%x,imis 0x%x\n",
574                                 mi_mis, mi_ris, mi_imis);
575         mi_mis = __raw_readl((void volatile *)
576                                 (camsys_dev->devmems.registermem->vir_base +
577                                 MRV_MI_MIS));
578         mi_ris =  __raw_readl((void volatile *)
579                                 (camsys_dev->devmems.registermem->vir_base +
580                                 MRV_MI_RIS));
581         mi_imis = __raw_readl((void volatile *)
582                                 (camsys_dev->devmems.registermem->vir_base +
583                                 MRV_MI_IMIS));
584         }
585
586         __raw_writel(isp_mis, (void volatile *)
587                                 (camsys_dev->devmems.registermem->vir_base +
588                                 MRV_ISP_ICR));
589         __raw_writel(mipi_mis, (void volatile *)
590                                 (camsys_dev->devmems.registermem->vir_base +
591                                 MRV_MIPI_ICR));
592         __raw_writel(jpg_mis, (void volatile *)
593                                 (camsys_dev->devmems.registermem->vir_base +
594                                 MRV_JPG_ICR));
595         __raw_writel(jpg_err_mis, (void volatile *)
596                                 (camsys_dev->devmems.registermem->vir_base +
597                                 MRV_JPG_ERR_ICR));
598         __raw_writel(mi_mis, (void volatile *)
599                                 (camsys_dev->devmems.registermem->vir_base +
600                                 MRV_MI_ICR));
601
602         spin_lock(&camsys_dev->irq.lock);
603         if (!list_empty(&camsys_dev->irq.irq_pool)) {
604                 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
605                         if (irqpool->pid != 0) {
606                                 switch (irqpool->mis) {
607                                 case MRV_ISP_MIS:
608                                 {
609                                         mis = &isp_mis;
610                                         break;
611                                 }
612
613                                 case MRV_MIPI_MIS:
614                                 {
615                                         mis = &mipi_mis;
616                                         break;
617                                 }
618                                 case MRV_MI_MIS:
619                                 {
620                                         mis = &mi_mis;
621                                         break;
622                                 }
623
624                                 case MRV_JPG_MIS:
625                                 {
626                                         mis = &jpg_mis;
627                                         break;
628                                 }
629
630                                 case MRV_JPG_ERR_MIS:
631                                 {
632                                         mis = &jpg_err_mis;
633                                         break;
634                                 }
635
636                                 default:
637                                 {
638                                         camsys_trace(2,
639                                                 "Thread(pid:%d) irqpool mis(%d) is invalidate",
640                                                 irqpool->pid, irqpool->mis);
641                                         goto end;
642                                 }
643                                 }
644
645                                 if (*mis != 0) {
646                                         spin_lock(&irqpool->lock);
647                                         if (!list_empty(&irqpool->deactive)) {
648                                                 irqsta =
649                                                         list_first_entry(
650                                                         &irqpool->deactive,
651                                                         camsys_irqstas_t,
652                                                         list);
653                                                 irqsta->sta.mis = *mis;
654                                                 list_del_init(&irqsta->list);
655                                                 list_add_tail(&irqsta->list,
656                                                         &irqpool->active);
657                                                 wake_up(&irqpool->done);
658                                         }
659                                         spin_unlock(&irqpool->lock);
660                                 }
661                         }
662                 }
663         }
664 end:
665         spin_unlock(&camsys_dev->irq.lock);
666
667         return IRQ_HANDLED;
668 }
669
670 static int camsys_mrv_remove_cb(struct platform_device *pdev)
671 {
672         camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
673         camsys_mrv_clk_t *mrv_clk = NULL;
674
675         if (camsys_dev->clk != NULL) {
676
677                 mrv_clk = (camsys_mrv_clk_t *)camsys_dev->clk;
678                 if (mrv_clk->out_on)
679                         camsys_mrv_clkout_cb(mrv_clk, 0, 0);
680                 if (mrv_clk->in_on)
681                         camsys_mrv_clkin_cb(mrv_clk, 0);
682
683                 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
684                         devm_clk_put(&pdev->dev, mrv_clk->pd_isp);
685                 }
686                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
687                         devm_clk_put(&pdev->dev, mrv_clk->aclk_isp);
688                 }
689                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
690                         devm_clk_put(&pdev->dev, mrv_clk->hclk_isp);
691                 }
692                 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
693                         devm_clk_put(&pdev->dev, mrv_clk->isp);
694                 }
695                 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
696                         devm_clk_put(&pdev->dev, mrv_clk->isp_jpe);
697                 }
698                 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
699                         devm_clk_put(&pdev->dev, mrv_clk->pclkin_isp);
700                 }
701                 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
702                         devm_clk_put(&pdev->dev, mrv_clk->cif_clk_out);
703                 }
704                 if (!IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) {
705                         devm_clk_put(&pdev->dev, mrv_clk->clk_vio0_noc);
706                 }
707
708                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp0_noc)) {
709                         devm_clk_put(&pdev->dev, mrv_clk->hclk_isp0_noc);
710                 }
711                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp0_wrapper)) {
712                         devm_clk_put(&pdev->dev, mrv_clk->hclk_isp0_wrapper);
713                 }
714                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp1_noc)) {
715                         devm_clk_put(&pdev->dev, mrv_clk->hclk_isp1_noc);
716                 }
717                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp1_wrapper)) {
718                         devm_clk_put(&pdev->dev, mrv_clk->hclk_isp1_wrapper);
719                 }
720                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp0_noc)) {
721                         devm_clk_put(&pdev->dev, mrv_clk->aclk_isp0_noc);
722                 }
723
724                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp0_wrapper)) {
725                         devm_clk_put(&pdev->dev, mrv_clk->aclk_isp0_wrapper);
726                 }
727                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp1_noc)) {
728                         devm_clk_put(&pdev->dev, mrv_clk->aclk_isp1_noc);
729                 }
730                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp1_wrapper)) {
731                         devm_clk_put(&pdev->dev, mrv_clk->aclk_isp1_wrapper);
732                 }
733                 if (!IS_ERR_OR_NULL(mrv_clk->clk_isp0)) {
734                         devm_clk_put(&pdev->dev, mrv_clk->clk_isp0);
735                 }
736                 if (!IS_ERR_OR_NULL(mrv_clk->clk_isp1)) {
737                         devm_clk_put(&pdev->dev, mrv_clk->clk_isp1);
738                 }
739                 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp1)) {
740                         devm_clk_put(&pdev->dev, mrv_clk->pclkin_isp1);
741                 }
742                 if (CHIP_TYPE == 3399)
743                         pm_runtime_disable(&pdev->dev);
744                 kfree(mrv_clk);
745                 mrv_clk = NULL;
746         }
747
748         return 0;
749 }
750 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
751 {
752         int err = 0;
753         camsys_mrv_clk_t *mrv_clk = NULL;
754         struct resource register_res;
755
756         err = of_address_to_resource(pdev->dev.of_node, 0, &register_res);
757         if (err < 0) {
758                 camsys_err(
759                         "Get register resource from %s platform device failed!",
760                         pdev->name);
761         }
762
763         err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq,
764                                         IRQF_SHARED, CAMSYS_MARVIN_IRQNAME,
765                                         camsys_dev);
766         if (err) {
767                 camsys_err("request irq for %s failed", CAMSYS_MARVIN_IRQNAME);
768                 goto end;
769         }
770
771         /* Clk and Iomux init */
772         mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t), GFP_KERNEL);
773         if (mrv_clk == NULL) {
774                 camsys_err("Allocate camsys_mrv_clk_t failed!");
775                 err = -EINVAL;
776                 goto clk_failed;
777         }
778         if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) {
779                 /* mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp"); */
780                 mrv_clk->aclk_isp        = devm_clk_get(&pdev->dev, "aclk_isp");
781                 mrv_clk->hclk_isp        = devm_clk_get(&pdev->dev, "hclk_isp");
782                 mrv_clk->isp             = devm_clk_get(&pdev->dev, "clk_isp");
783                 mrv_clk->isp_jpe     = devm_clk_get(&pdev->dev, "clk_isp_jpe");
784                 mrv_clk->pclkin_isp  = devm_clk_get(&pdev->dev, "pclkin_isp");
785                 mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
786                 mrv_clk->cif_clk_pll = devm_clk_get(&pdev->dev, "clk_cif_pll");
787                 mrv_clk->pclk_dphyrx = devm_clk_get(&pdev->dev, "pclk_dphyrx");
788                 if (CHIP_TYPE == 3368) {
789                         mrv_clk->clk_vio0_noc =
790                                 devm_clk_get(&pdev->dev, "clk_vio0_noc");
791                         if (IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) {
792                                 camsys_err("Get %s clock resouce failed!\n",
793                                         miscdev_name);
794                                 err = -EINVAL;
795                                 goto clk_failed;
796                         }
797
798                 }
799
800                 if (IS_ERR_OR_NULL(mrv_clk->aclk_isp)    ||
801                         IS_ERR_OR_NULL(mrv_clk->hclk_isp)        ||
802                         IS_ERR_OR_NULL(mrv_clk->isp)             ||
803                         IS_ERR_OR_NULL(mrv_clk->isp_jpe)         ||
804                         IS_ERR_OR_NULL(mrv_clk->pclkin_isp)  ||
805                         IS_ERR_OR_NULL(mrv_clk->cif_clk_out) ||
806                         IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx)) {
807                         camsys_err("Get %s clock resouce failed!\n",
808                                 miscdev_name);
809                         err = -EINVAL;
810                         goto clk_failed;
811                 }
812
813                 clk_set_rate(mrv_clk->isp, 210000000);
814                 clk_set_rate(mrv_clk->isp_jpe, 210000000);
815
816         } else if (CHIP_TYPE == 3399) {
817
818                 pm_runtime_enable(&pdev->dev);
819                 if (register_res.start == 0xff920000) {
820                         mrv_clk->hclk_isp1_noc     =
821                                 devm_clk_get(&pdev->dev, "hclk_isp1_noc");
822                         mrv_clk->hclk_isp1_wrapper =
823                                 devm_clk_get(&pdev->dev, "hclk_isp1_wrapper");
824                         mrv_clk->aclk_isp1_noc     =
825                                 devm_clk_get(&pdev->dev, "aclk_isp1_noc");
826                         mrv_clk->aclk_isp1_wrapper =
827                                 devm_clk_get(&pdev->dev, "aclk_isp1_wrapper");
828                         mrv_clk->clk_isp1                  =
829                                 devm_clk_get(&pdev->dev, "clk_isp1");
830                         mrv_clk->pclkin_isp        =
831                                 devm_clk_get(&pdev->dev, "pclk_isp1");
832                         mrv_clk->pclk_dphytxrx     =
833                                 devm_clk_get(&pdev->dev, "pclk_dphytxrx");
834                 }
835                 else
836                 {
837                         mrv_clk->hclk_isp0_noc     =
838                                 devm_clk_get(&pdev->dev, "hclk_isp0_noc");
839                         mrv_clk->hclk_isp0_wrapper =
840                                 devm_clk_get(&pdev->dev, "hclk_isp0_wrapper");
841                         mrv_clk->aclk_isp0_noc     =
842                                 devm_clk_get(&pdev->dev, "aclk_isp0_noc");
843                         mrv_clk->aclk_isp0_wrapper =
844                                 devm_clk_get(&pdev->dev, "aclk_isp0_wrapper");
845                         mrv_clk->clk_isp0                  =
846                                 devm_clk_get(&pdev->dev, "clk_isp0");
847                         mrv_clk->pclk_dphyrx       =
848                                 devm_clk_get(&pdev->dev, "pclk_dphyrx");
849                 }
850                 mrv_clk->cif_clk_out       =
851                         devm_clk_get(&pdev->dev, "clk_cif_out");
852                 mrv_clk->cif_clk_pll       =
853                         devm_clk_get(&pdev->dev, "clk_cif_pll");
854                 mrv_clk->pclk_dphy_ref     =
855                         devm_clk_get(&pdev->dev, "pclk_dphy_ref");
856                 if (register_res.start == 0xff920000) {
857                         if (IS_ERR_OR_NULL(mrv_clk->hclk_isp1_noc)       ||
858                                 IS_ERR_OR_NULL(mrv_clk->hclk_isp1_wrapper)   ||
859                                 IS_ERR_OR_NULL(mrv_clk->aclk_isp1_noc)       ||
860                                 IS_ERR_OR_NULL(mrv_clk->aclk_isp1_wrapper)   ||
861                                 IS_ERR_OR_NULL(mrv_clk->clk_isp1)            ||
862                                 IS_ERR_OR_NULL(mrv_clk->cif_clk_out)         ||
863                                 IS_ERR_OR_NULL(mrv_clk->cif_clk_pll)         ||
864                                 IS_ERR_OR_NULL(mrv_clk->pclkin_isp)          ||
865                                 IS_ERR_OR_NULL(mrv_clk->pclk_dphytxrx)) {
866                                 camsys_err("Get %s clock resouce failed!\n",
867                                         miscdev_name);
868                                 err = -EINVAL;
869                                 goto clk_failed;
870                         }
871                 }
872                 else
873                 {
874                         if (IS_ERR_OR_NULL(mrv_clk->hclk_isp0_noc)       ||
875                                 IS_ERR_OR_NULL(mrv_clk->hclk_isp0_wrapper)   ||
876                                 IS_ERR_OR_NULL(mrv_clk->aclk_isp0_noc)       ||
877                                 IS_ERR_OR_NULL(mrv_clk->aclk_isp0_wrapper)   ||
878                                 IS_ERR_OR_NULL(mrv_clk->clk_isp0)            ||
879                                 IS_ERR_OR_NULL(mrv_clk->cif_clk_out)         ||
880                                 IS_ERR_OR_NULL(mrv_clk->cif_clk_pll)         ||
881                                 IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx)) {
882                                 camsys_err("Get %s clock resouce failed!\n",
883                                         miscdev_name);
884                                 err = -EINVAL;
885                                 goto clk_failed;
886                         }
887                 }
888         clk_set_rate(mrv_clk->clk_isp0, 210000000);
889         } else{
890                 mrv_clk->pd_isp           =
891                         devm_clk_get(&pdev->dev, "pd_isp");
892                 mrv_clk->aclk_isp         =
893                         devm_clk_get(&pdev->dev, "aclk_isp");
894                 mrv_clk->hclk_isp         =
895                         devm_clk_get(&pdev->dev, "hclk_isp");
896                 mrv_clk->isp              =
897                         devm_clk_get(&pdev->dev, "clk_isp");
898                 mrv_clk->isp_jpe          =
899                         devm_clk_get(&pdev->dev, "clk_isp_jpe");
900                 mrv_clk->pclkin_isp   =
901                         devm_clk_get(&pdev->dev, "pclkin_isp");
902                 mrv_clk->cif_clk_out  =
903                         devm_clk_get(&pdev->dev, "clk_cif_out");
904                 mrv_clk->cif_clk_pll  =
905                         devm_clk_get(&pdev->dev, "clk_cif_pll");
906                 mrv_clk->clk_mipi_24m =
907                         devm_clk_get(&pdev->dev, "clk_mipi_24m");
908
909                 if (IS_ERR_OR_NULL(mrv_clk->pd_isp)      ||
910                         IS_ERR_OR_NULL(mrv_clk->aclk_isp)    ||
911                         IS_ERR_OR_NULL(mrv_clk->hclk_isp)    ||
912                         IS_ERR_OR_NULL(mrv_clk->isp)         ||
913                         IS_ERR_OR_NULL(mrv_clk->isp_jpe)     ||
914                         IS_ERR_OR_NULL(mrv_clk->pclkin_isp)  ||
915                         IS_ERR_OR_NULL(mrv_clk->cif_clk_out) ||
916                         IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) {
917                         camsys_err("Get %s clock resouce failed!\n",
918                                 miscdev_name);
919                         err = -EINVAL;
920                         goto clk_failed;
921                 }
922
923                 clk_set_rate(mrv_clk->isp, 210000000);
924                 clk_set_rate(mrv_clk->isp_jpe, 210000000);
925         }
926
927
928         mutex_init(&mrv_clk->lock);
929
930         mrv_clk->in_on = false;
931         mrv_clk->out_on = 0;
932
933         camsys_dev->clk = (void *)mrv_clk;
934         camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
935         camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
936         camsys_dev->reset_cb = camsys_mrv_reset_cb;
937         camsys_dev->iomux = camsys_mrv_iomux_cb;
938         camsys_dev->flash_trigger_cb = camsys_mrv_flash_trigger_cb;
939         camsys_dev->iommu_cb = camsys_mrv_iommu_cb;
940
941         camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
942         camsys_dev->miscdev.name = miscdev_name;
943         camsys_dev->miscdev.nodename = miscdev_name;
944         camsys_dev->miscdev.fops = &camsys_fops;
945
946         if (CHIP_TYPE == 3399) {
947                 if (register_res.start == 0xff920000) {
948                         camsys_dev->miscdev.name = "camsys_marvin1";
949                         camsys_dev->miscdev.nodename = "camsys_marvin1";
950                 }
951         }
952
953         err = misc_register(&camsys_dev->miscdev);
954         if (err < 0) {
955                 camsys_err("misc register %s failed!", miscdev_name);
956                 goto misc_register_failed;
957         }
958         /* Variable init */
959         camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
960         camsys_dev->platform_remove = camsys_mrv_remove_cb;
961
962         return 0;
963 misc_register_failed:
964         if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device))
965                 misc_deregister(&camsys_dev->miscdev);
966
967 clk_failed:
968         if (mrv_clk != NULL) {
969                 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp))
970                         clk_put(mrv_clk->pd_isp);
971
972                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp))
973                         clk_put(mrv_clk->aclk_isp);
974
975                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp))
976                         clk_put(mrv_clk->hclk_isp);
977
978                 if (!IS_ERR_OR_NULL(mrv_clk->isp))
979                         clk_put(mrv_clk->isp);
980
981                 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe))
982                         clk_put(mrv_clk->isp_jpe);
983
984                 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp))
985                         clk_put(mrv_clk->pclkin_isp);
986
987                 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out))
988                         clk_put(mrv_clk->cif_clk_out);
989
990         if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) {
991                 if (!IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx))
992                         clk_put(mrv_clk->pclk_dphyrx);
993
994                 if (!IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc))
995                 clk_put(mrv_clk->clk_vio0_noc);
996         }
997
998                 kfree(mrv_clk);
999                 mrv_clk = NULL;
1000         }
1001
1002 end:
1003         return err;
1004 }
1005 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);
1006