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