bc388414b71f818151e43b852c38d5f68e2b9406
[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                         camsys_trace
409                         (
410                         2,
411                         "exist mapped buf, release it before map: attach %p,"
412                         "dma_buf %p,sgt %p,fd %d,index %d",
413                         attach,
414                         dma_buf,
415                         sgt,
416                         iommu->map_fd,
417                         index);
418                         dma_buf_unmap_attachment
419                                 (attach,
420                                 sgt,
421                                 DMA_BIDIRECTIONAL);
422                         dma_buf_detach(dma_buf, attach);
423                         dma_buf_put(dma_buf);
424                         if (camsys_dev->dma_buf_cnt == 1)
425                                 camsys_drm_dma_detach_device(camsys_dev);
426                         camsys_dev->dma_buf_cnt--;
427                         camsys_dev->dma_buf[index].fd = -1;
428                 }
429                 /*get a free slot*/
430                 for (index = 0; index < CAMSYS_DMA_BUF_MAX_NUM; index++)
431                         if (camsys_dev->dma_buf[index].fd == -1)
432                                 break;
433
434                 if (index == CAMSYS_DMA_BUF_MAX_NUM)
435                         return -ENOMEM;
436
437                 if (camsys_dev->dma_buf_cnt == 0) {
438                         ret = camsys_drm_dma_attach_device(camsys_dev);
439                         if (ret)
440                                 return ret;
441                 }
442
443                 dma_buf = dma_buf_get(iommu->map_fd);
444                 if (IS_ERR(dma_buf))
445                         return PTR_ERR(dma_buf);
446                 attach = dma_buf_attach(dma_buf, dev);
447                 if (IS_ERR(attach)) {
448                         dma_buf_put(dma_buf);
449                         return PTR_ERR(attach);
450                 }
451                 sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
452                 if (IS_ERR(sgt)) {
453                         dma_buf_detach(dma_buf, attach);
454                         dma_buf_put(dma_buf);
455                         return PTR_ERR(sgt);
456                 }
457                 dma_addr = sg_dma_address(sgt->sgl);
458                 camsys_dev->dma_buf[index].dma_addr = dma_addr;
459                 camsys_dev->dma_buf[index].attach       = attach;
460                 camsys_dev->dma_buf[index].dma_buf = dma_buf;
461                 camsys_dev->dma_buf[index].sgt = sgt;
462                 camsys_dev->dma_buf[index].fd = iommu->map_fd;
463                 iommu->linear_addr = dma_addr;
464                 iommu->len = sg_dma_len(sgt->sgl);
465                 camsys_dev->dma_buf_cnt++;
466                 camsys_trace
467                         (
468                         2,
469                         "dma buf map: dma_addr 0x%lx,attach %p,"
470                         "dma_buf %p,sgt %p,fd %d,buf_cnt %d",
471                         (unsigned long)dma_addr,
472                         attach,
473                         dma_buf,
474                         sgt,
475                         iommu->map_fd,
476                         camsys_dev->dma_buf_cnt);
477         } else {
478                 if (
479                         (camsys_dev->dma_buf_cnt == 0) ||
480                         (index < 0) ||
481                         (index >= CAMSYS_DMA_BUF_MAX_NUM))
482                         return -EINVAL;
483
484                 for (index = 0; index < camsys_dev->dma_buf_cnt; index++) {
485                         if (camsys_dev->dma_buf[index].fd == iommu->map_fd)
486                                 break;
487                 }
488                 if (index == camsys_dev->dma_buf_cnt) {
489                         camsys_warn("can't find map fd %d", iommu->map_fd);
490                         return -EINVAL;
491                 }
492                 attach = camsys_dev->dma_buf[index].attach;
493                 dma_buf = camsys_dev->dma_buf[index].dma_buf;
494                 sgt = camsys_dev->dma_buf[index].sgt;
495                 dma_addr = sg_dma_address(sgt->sgl);
496                 camsys_trace
497                                 (
498                                 2,
499                                 "dma buf unmap: dma_addr 0x%lx,attach %p,"
500                                 "dma_buf %p,sgt %p,index %d",
501                                 (unsigned long)dma_addr,
502                                 attach,
503                                 dma_buf,
504                                 sgt,
505                                 index);
506                 dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
507                 dma_buf_detach(dma_buf, attach);
508                 dma_buf_put(dma_buf);
509                 if (camsys_dev->dma_buf_cnt == 1)
510                         camsys_drm_dma_detach_device(camsys_dev);
511
512                 camsys_dev->dma_buf_cnt--;
513                 camsys_dev->dma_buf[index].fd = -1;
514         }
515
516         return ret;
517 }
518
519 static int camsys_mrv_reset_cb(void *ptr, unsigned int on)
520 {
521         camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
522         camsys_soc_priv_t *soc;
523
524         if (camsys_dev->soc) {
525                 soc = (camsys_soc_priv_t *)camsys_dev->soc;
526                 if (soc->soc_cfg) {
527                         (soc->soc_cfg)
528                                 (camsys_dev, Isp_SoftRst,
529                                 (void *)(unsigned long)on);
530                 } else {
531                         camsys_err("camsys_dev->soc->soc_cfg is NULL!");
532                 }
533         } else {
534                 camsys_err("camsys_dev->soc is NULL!");
535         }
536
537         return 0;
538 }
539
540 static int camsys_mrv_clkin_cb(void *ptr, unsigned int on)
541 {
542         camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
543         camsys_mrv_clk_t *clk = (camsys_mrv_clk_t *)camsys_dev->clk;
544         unsigned long isp_clk;
545
546         if (CHIP_TYPE == 3399) {
547                 if (on && !clk->in_on) {
548                         /* rockchip_set_system_status(SYS_STATUS_ISP); */
549                         if (on == 1)
550                                 isp_clk = 210000000;
551                         else
552                                 isp_clk = 420000000;
553
554                         if (strstr(camsys_dev->miscdev.name,
555                                 "camsys_marvin1")) {
556                                 clk_set_rate(clk->clk_isp1, isp_clk);
557                                 clk_prepare_enable(clk->hclk_isp1_noc);
558                                 clk_prepare_enable(clk->hclk_isp1_wrapper);
559                                 clk_prepare_enable(clk->aclk_isp1_noc);
560                                 clk_prepare_enable(clk->aclk_isp1_wrapper);
561                                 clk_prepare_enable(clk->clk_isp1);
562
563                                 clk_prepare_enable(clk->cif_clk_out);
564                                 clk_prepare_enable(clk->pclk_dphy_ref);
565                                 clk_prepare_enable(clk->pclk_dphytxrx);
566
567                                 clk_prepare_enable(clk->pclkin_isp);
568                                 clk_prepare_enable(clk->cif_clk_out);
569                         } else {
570                                 clk_set_rate(clk->clk_isp0, isp_clk);
571                                 clk_prepare_enable(clk->hclk_isp0_noc);
572                                 clk_prepare_enable(clk->hclk_isp0_wrapper);
573                                 clk_prepare_enable(clk->aclk_isp0_noc);
574                                 clk_prepare_enable(clk->aclk_isp0_wrapper);
575                                 clk_prepare_enable(clk->clk_isp0);
576                                 clk_prepare_enable(clk->cif_clk_out);
577                                 clk_prepare_enable(clk->pclk_dphyrx);
578                                 clk_prepare_enable(clk->pclk_dphy_ref);
579                         }
580
581                         clk->in_on = true;
582
583                         camsys_trace(1, "%s clock(f: %ld Hz) in turn on",
584                                      dev_name(camsys_dev->miscdev.this_device),
585                                      isp_clk);
586                         camsys_mrv_reset_cb(ptr, 1);
587                         udelay(100);
588                         camsys_mrv_reset_cb(ptr, 0);
589                 } else if (!on && clk->in_on) {
590                         if (strstr(camsys_dev->miscdev.name,
591                                 "camsys_marvin1")) {
592                                 clk_disable_unprepare(clk->hclk_isp1_noc);
593                                 clk_disable_unprepare(clk->hclk_isp1_wrapper);
594                                 clk_disable_unprepare(clk->aclk_isp1_noc);
595                                 clk_disable_unprepare(clk->aclk_isp1_wrapper);
596                                 clk_disable_unprepare(clk->clk_isp1);
597
598                                 clk_disable_unprepare(clk->cif_clk_out);
599                                 clk_disable_unprepare(clk->pclk_dphytxrx);
600                                 clk_disable_unprepare(clk->pclk_dphy_ref);
601
602                                 clk_disable_unprepare(clk->pclkin_isp);
603                         } else {
604                                 clk_disable_unprepare(clk->hclk_isp0_noc);
605                                 clk_disable_unprepare(clk->hclk_isp0_wrapper);
606                                 clk_disable_unprepare(clk->aclk_isp0_noc);
607                                 clk_disable_unprepare(clk->aclk_isp0_wrapper);
608                                 clk_disable_unprepare(clk->clk_isp0);
609
610                                 clk_disable_unprepare(clk->cif_clk_out);
611                                 clk_disable_unprepare(clk->pclk_dphyrx);
612                                 clk_disable_unprepare(clk->pclk_dphy_ref);
613                         }
614
615                         /* rockchip_clear_system_status(SYS_STATUS_ISP); */
616                         clk->in_on = false;
617                         camsys_trace(1, "%s clock in turn off",
618                                      dev_name(camsys_dev->miscdev.this_device));
619                         }
620         } else{
621                 if (on && !clk->in_on) {
622                         /* rockchip_set_system_status(SYS_STATUS_ISP); */
623
624                 if (on == 1)
625                         isp_clk = 210000000;
626                 else
627                         isp_clk = 420000000;
628
629                 clk_set_rate(clk->isp, isp_clk);
630                 clk_set_rate(clk->isp_jpe, isp_clk);
631
632                 /* clk_prepare_enable(clk->pd_isp); */
633                 clk_prepare_enable(clk->aclk_isp);
634                 clk_prepare_enable(clk->hclk_isp);
635                 clk_prepare_enable(clk->isp);
636                 clk_prepare_enable(clk->isp_jpe);
637                 clk_prepare_enable(clk->pclkin_isp);
638                 if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) {
639                         clk_prepare_enable(clk->cif_clk_out);
640                         clk_prepare_enable(clk->pclk_dphyrx);
641                 } else {
642                         clk_prepare_enable(clk->clk_mipi_24m);
643                 }
644                 clk->in_on = true;
645
646                 camsys_trace(1, "%s clock(f: %ld Hz) in turn on",
647                         dev_name(camsys_dev->miscdev.this_device), isp_clk);
648                 camsys_mrv_reset_cb(ptr, 1);
649                 udelay(100);
650                 camsys_mrv_reset_cb(ptr, 0);
651                 } else if (!on && clk->in_on) {
652                 clk_disable_unprepare(clk->aclk_isp);
653                 clk_disable_unprepare(clk->hclk_isp);
654                 clk_disable_unprepare(clk->isp);
655                 clk_disable_unprepare(clk->isp_jpe);
656                 clk_disable_unprepare(clk->pclkin_isp);
657                 if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) {
658                         clk_disable_unprepare(clk->cif_clk_out);
659                         clk_disable_unprepare(clk->pclk_dphyrx);
660                 } else {
661                         clk_disable_unprepare(clk->clk_mipi_24m);
662                 }
663                 /* clk_disable_unprepare(clk->pd_isp); */
664
665                 /* rockchip_clear_system_status(SYS_STATUS_ISP); */
666                 clk->in_on = false;
667                 camsys_trace(1, "%s clock in turn off",
668                         dev_name(camsys_dev->miscdev.this_device));
669                 }
670         }
671
672         return 0;
673 }
674
675 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on, unsigned int inclk)
676 {
677         camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
678         camsys_mrv_clk_t *clk = (camsys_mrv_clk_t *)camsys_dev->clk;
679
680         mutex_lock(&clk->lock);
681         if (on && (clk->out_on != on)) {
682
683                 pm_runtime_get_sync(&camsys_dev->pdev->dev);
684
685                 clk_set_rate(clk->cif_clk_out, inclk);
686                 clk_prepare_enable(clk->cif_clk_out);
687                 clk->out_on = on;
688                 camsys_trace(1, "%s clock out(rate: %dHz) turn on",
689                         dev_name(camsys_dev->miscdev.this_device),
690                                         inclk);
691         } else if (!on && clk->out_on) {
692                 if (!IS_ERR_OR_NULL(clk->cif_clk_pll)) {
693                         clk_set_parent(clk->cif_clk_out,
694                                 clk->cif_clk_pll);
695                 } else {
696                         camsys_warn("%s clock out may be not off!",
697                                 dev_name(camsys_dev->miscdev.this_device));
698                 }
699
700                 clk_disable_unprepare(clk->cif_clk_out);
701
702                 pm_runtime_disable(&camsys_dev->pdev->dev);
703                 clk->out_on = 0;
704
705                 camsys_trace(1, "%s clock out turn off",
706                         dev_name(camsys_dev->miscdev.this_device));
707         }
708         mutex_unlock(&clk->lock);
709
710         return 0;
711 }
712 static irqreturn_t camsys_mrv_irq(int irq, void *data)
713 {
714         camsys_dev_t *camsys_dev = (camsys_dev_t *)data;
715         camsys_irqstas_t *irqsta;
716         camsys_irqpool_t *irqpool;
717         unsigned int isp_mis, mipi_mis, mi_mis, *mis, jpg_mis, jpg_err_mis;
718         unsigned int mi_ris, mi_imis;
719
720         isp_mis = __raw_readl((void volatile *)
721                                 (camsys_dev->devmems.registermem->vir_base +
722                                 MRV_ISP_MIS));
723         mipi_mis = __raw_readl((void volatile *)
724                                 (camsys_dev->devmems.registermem->vir_base +
725                                 MRV_MIPI_MIS));
726         jpg_mis = __raw_readl((void volatile *)
727                                 (camsys_dev->devmems.registermem->vir_base +
728                                 MRV_JPG_MIS));
729         jpg_err_mis = __raw_readl((void volatile *)
730                                 (camsys_dev->devmems.registermem->vir_base +
731                                 MRV_JPG_ERR_MIS));
732         mi_mis = __raw_readl((void volatile *)
733                                 (camsys_dev->devmems.registermem->vir_base +
734                                 MRV_MI_MIS));
735
736         mi_ris =  __raw_readl((void volatile *)
737                                 (camsys_dev->devmems.registermem->vir_base +
738                                 MRV_MI_RIS));
739         mi_imis = __raw_readl((void volatile *)
740                                 (camsys_dev->devmems.registermem->vir_base +
741                                 MRV_MI_IMIS));
742         while ((mi_ris & mi_imis) != mi_mis) {
743         camsys_trace(2, "mi_mis status erro,mi_mis 0x%x,"
744                                 "mi_ris 0x%x,imis 0x%x\n",
745                                 mi_mis, mi_ris, mi_imis);
746         mi_mis = __raw_readl((void volatile *)
747                                 (camsys_dev->devmems.registermem->vir_base +
748                                 MRV_MI_MIS));
749         mi_ris =  __raw_readl((void volatile *)
750                                 (camsys_dev->devmems.registermem->vir_base +
751                                 MRV_MI_RIS));
752         mi_imis = __raw_readl((void volatile *)
753                                 (camsys_dev->devmems.registermem->vir_base +
754                                 MRV_MI_IMIS));
755         }
756
757         __raw_writel(isp_mis, (void volatile *)
758                                 (camsys_dev->devmems.registermem->vir_base +
759                                 MRV_ISP_ICR));
760         __raw_writel(mipi_mis, (void volatile *)
761                                 (camsys_dev->devmems.registermem->vir_base +
762                                 MRV_MIPI_ICR));
763         __raw_writel(jpg_mis, (void volatile *)
764                                 (camsys_dev->devmems.registermem->vir_base +
765                                 MRV_JPG_ICR));
766         __raw_writel(jpg_err_mis, (void volatile *)
767                                 (camsys_dev->devmems.registermem->vir_base +
768                                 MRV_JPG_ERR_ICR));
769         __raw_writel(mi_mis, (void volatile *)
770                                 (camsys_dev->devmems.registermem->vir_base +
771                                 MRV_MI_ICR));
772
773         spin_lock(&camsys_dev->irq.lock);
774         if (!list_empty(&camsys_dev->irq.irq_pool)) {
775                 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
776                         if (irqpool->pid != 0) {
777                                 switch (irqpool->mis) {
778                                 case MRV_ISP_MIS:
779                                 {
780                                         mis = &isp_mis;
781                                         break;
782                                 }
783
784                                 case MRV_MIPI_MIS:
785                                 {
786                                         mis = &mipi_mis;
787                                         break;
788                                 }
789                                 case MRV_MI_MIS:
790                                 {
791                                         mis = &mi_mis;
792                                         break;
793                                 }
794
795                                 case MRV_JPG_MIS:
796                                 {
797                                         mis = &jpg_mis;
798                                         break;
799                                 }
800
801                                 case MRV_JPG_ERR_MIS:
802                                 {
803                                         mis = &jpg_err_mis;
804                                         break;
805                                 }
806
807                                 default:
808                                 {
809                                         camsys_trace(2,
810                                                 "Thread(pid:%d) irqpool mis(%d) is invalidate",
811                                                 irqpool->pid, irqpool->mis);
812                                         goto end;
813                                 }
814                                 }
815
816                                 if (*mis != 0) {
817                                         spin_lock(&irqpool->lock);
818                                         if (!list_empty(&irqpool->deactive)) {
819                                                 irqsta =
820                                                         list_first_entry(
821                                                         &irqpool->deactive,
822                                                         camsys_irqstas_t,
823                                                         list);
824                                                 irqsta->sta.mis = *mis;
825                                                 list_del_init(&irqsta->list);
826                                                 list_add_tail(&irqsta->list,
827                                                         &irqpool->active);
828                                                 wake_up(&irqpool->done);
829                                         }
830                                         spin_unlock(&irqpool->lock);
831                                 }
832                         }
833                 }
834         }
835 end:
836         spin_unlock(&camsys_dev->irq.lock);
837
838         return IRQ_HANDLED;
839 }
840
841 static int camsys_mrv_remove_cb(struct platform_device *pdev)
842 {
843         camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
844         camsys_mrv_clk_t *mrv_clk = NULL;
845
846         if (camsys_dev->clk != NULL) {
847
848                 mrv_clk = (camsys_mrv_clk_t *)camsys_dev->clk;
849                 if (mrv_clk->out_on)
850                         camsys_mrv_clkout_cb(mrv_clk, 0, 0);
851                 if (mrv_clk->in_on)
852                         camsys_mrv_clkin_cb(mrv_clk, 0);
853
854                 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
855                         devm_clk_put(&pdev->dev, mrv_clk->pd_isp);
856                 }
857                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
858                         devm_clk_put(&pdev->dev, mrv_clk->aclk_isp);
859                 }
860                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
861                         devm_clk_put(&pdev->dev, mrv_clk->hclk_isp);
862                 }
863                 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
864                         devm_clk_put(&pdev->dev, mrv_clk->isp);
865                 }
866                 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
867                         devm_clk_put(&pdev->dev, mrv_clk->isp_jpe);
868                 }
869                 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
870                         devm_clk_put(&pdev->dev, mrv_clk->pclkin_isp);
871                 }
872                 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
873                         devm_clk_put(&pdev->dev, mrv_clk->cif_clk_out);
874                 }
875                 if (!IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) {
876                         devm_clk_put(&pdev->dev, mrv_clk->clk_vio0_noc);
877                 }
878
879                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp0_noc)) {
880                         devm_clk_put(&pdev->dev, mrv_clk->hclk_isp0_noc);
881                 }
882                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp0_wrapper)) {
883                         devm_clk_put(&pdev->dev, mrv_clk->hclk_isp0_wrapper);
884                 }
885                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp1_noc)) {
886                         devm_clk_put(&pdev->dev, mrv_clk->hclk_isp1_noc);
887                 }
888                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp1_wrapper)) {
889                         devm_clk_put(&pdev->dev, mrv_clk->hclk_isp1_wrapper);
890                 }
891                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp0_noc)) {
892                         devm_clk_put(&pdev->dev, mrv_clk->aclk_isp0_noc);
893                 }
894
895                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp0_wrapper)) {
896                         devm_clk_put(&pdev->dev, mrv_clk->aclk_isp0_wrapper);
897                 }
898                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp1_noc)) {
899                         devm_clk_put(&pdev->dev, mrv_clk->aclk_isp1_noc);
900                 }
901                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp1_wrapper)) {
902                         devm_clk_put(&pdev->dev, mrv_clk->aclk_isp1_wrapper);
903                 }
904                 if (!IS_ERR_OR_NULL(mrv_clk->clk_isp0)) {
905                         devm_clk_put(&pdev->dev, mrv_clk->clk_isp0);
906                 }
907                 if (!IS_ERR_OR_NULL(mrv_clk->clk_isp1)) {
908                         devm_clk_put(&pdev->dev, mrv_clk->clk_isp1);
909                 }
910                 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp1)) {
911                         devm_clk_put(&pdev->dev, mrv_clk->pclkin_isp1);
912                 }
913                 if (CHIP_TYPE == 3399)
914                         pm_runtime_disable(&pdev->dev);
915                 kfree(mrv_clk);
916                 mrv_clk = NULL;
917         }
918
919         camsys_drm_dma_detach_device(camsys_dev);
920         iommu_group_remove_device(&camsys_dev->pdev->dev);
921         iommu_put_dma_cookie(camsys_dev->domain);
922         iommu_domain_free(camsys_dev->domain);
923
924         return 0;
925 }
926 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
927 {
928         int err = 0;
929         camsys_mrv_clk_t *mrv_clk = NULL;
930         struct resource register_res;
931         struct iommu_domain *domain;
932         struct iommu_group *group;
933         struct device_node *np;
934
935         err = of_address_to_resource(pdev->dev.of_node, 0, &register_res);
936         if (err < 0) {
937                 camsys_err(
938                         "Get register resource from %s platform device failed!",
939                         pdev->name);
940         }
941
942         err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq,
943                                         IRQF_SHARED, CAMSYS_MARVIN_IRQNAME,
944                                         camsys_dev);
945         if (err) {
946                 camsys_err("request irq for %s failed", CAMSYS_MARVIN_IRQNAME);
947                 goto end;
948         }
949
950         /* Clk and Iomux init */
951         mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t), GFP_KERNEL);
952         if (mrv_clk == NULL) {
953                 camsys_err("Allocate camsys_mrv_clk_t failed!");
954                 err = -EINVAL;
955                 goto clk_failed;
956         }
957         if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) {
958                 /* mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp"); */
959                 mrv_clk->aclk_isp        = devm_clk_get(&pdev->dev, "aclk_isp");
960                 mrv_clk->hclk_isp        = devm_clk_get(&pdev->dev, "hclk_isp");
961                 mrv_clk->isp             = devm_clk_get(&pdev->dev, "clk_isp");
962                 mrv_clk->isp_jpe     = devm_clk_get(&pdev->dev, "clk_isp_jpe");
963                 mrv_clk->pclkin_isp  = devm_clk_get(&pdev->dev, "pclkin_isp");
964                 mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
965                 mrv_clk->cif_clk_pll = devm_clk_get(&pdev->dev, "clk_cif_pll");
966                 mrv_clk->pclk_dphyrx = devm_clk_get(&pdev->dev, "pclk_dphyrx");
967                 if (CHIP_TYPE == 3368) {
968                         mrv_clk->clk_vio0_noc =
969                                 devm_clk_get(&pdev->dev, "clk_vio0_noc");
970                         if (IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) {
971                                 camsys_err("Get %s clock resouce failed!\n",
972                                         miscdev_name);
973                                 err = -EINVAL;
974                                 goto clk_failed;
975                         }
976
977                 }
978
979                 if (IS_ERR_OR_NULL(mrv_clk->aclk_isp)    ||
980                         IS_ERR_OR_NULL(mrv_clk->hclk_isp)        ||
981                         IS_ERR_OR_NULL(mrv_clk->isp)             ||
982                         IS_ERR_OR_NULL(mrv_clk->isp_jpe)         ||
983                         IS_ERR_OR_NULL(mrv_clk->pclkin_isp)  ||
984                         IS_ERR_OR_NULL(mrv_clk->cif_clk_out) ||
985                         IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx)) {
986                         camsys_err("Get %s clock resouce failed!\n",
987                                 miscdev_name);
988                         err = -EINVAL;
989                         goto clk_failed;
990                 }
991
992                 clk_set_rate(mrv_clk->isp, 210000000);
993                 clk_set_rate(mrv_clk->isp_jpe, 210000000);
994
995         } else if (CHIP_TYPE == 3399) {
996
997                 pm_runtime_enable(&pdev->dev);
998                 if (register_res.start == 0xff920000) {
999                         mrv_clk->hclk_isp1_noc     =
1000                                 devm_clk_get(&pdev->dev, "hclk_isp1_noc");
1001                         mrv_clk->hclk_isp1_wrapper =
1002                                 devm_clk_get(&pdev->dev, "hclk_isp1_wrapper");
1003                         mrv_clk->aclk_isp1_noc     =
1004                                 devm_clk_get(&pdev->dev, "aclk_isp1_noc");
1005                         mrv_clk->aclk_isp1_wrapper =
1006                                 devm_clk_get(&pdev->dev, "aclk_isp1_wrapper");
1007                         mrv_clk->clk_isp1                  =
1008                                 devm_clk_get(&pdev->dev, "clk_isp1");
1009                         mrv_clk->pclkin_isp        =
1010                                 devm_clk_get(&pdev->dev, "pclk_isp1");
1011                         mrv_clk->pclk_dphytxrx     =
1012                                 devm_clk_get(&pdev->dev, "pclk_dphytxrx");
1013                 } else{
1014                         mrv_clk->hclk_isp0_noc     =
1015                                 devm_clk_get(&pdev->dev, "hclk_isp0_noc");
1016                         mrv_clk->hclk_isp0_wrapper =
1017                                 devm_clk_get(&pdev->dev, "hclk_isp0_wrapper");
1018                         mrv_clk->aclk_isp0_noc     =
1019                                 devm_clk_get(&pdev->dev, "aclk_isp0_noc");
1020                         mrv_clk->aclk_isp0_wrapper =
1021                                 devm_clk_get(&pdev->dev, "aclk_isp0_wrapper");
1022                         mrv_clk->clk_isp0                  =
1023                                 devm_clk_get(&pdev->dev, "clk_isp0");
1024                         mrv_clk->pclk_dphyrx       =
1025                                 devm_clk_get(&pdev->dev, "pclk_dphyrx");
1026                 }
1027                 mrv_clk->cif_clk_out       =
1028                         devm_clk_get(&pdev->dev, "clk_cif_out");
1029                 mrv_clk->cif_clk_pll       =
1030                         devm_clk_get(&pdev->dev, "clk_cif_pll");
1031                 mrv_clk->pclk_dphy_ref     =
1032                         devm_clk_get(&pdev->dev, "pclk_dphy_ref");
1033                 if (register_res.start == 0xff920000) {
1034                         if (IS_ERR_OR_NULL(mrv_clk->hclk_isp1_noc)       ||
1035                                 IS_ERR_OR_NULL(mrv_clk->hclk_isp1_wrapper)   ||
1036                                 IS_ERR_OR_NULL(mrv_clk->aclk_isp1_noc)       ||
1037                                 IS_ERR_OR_NULL(mrv_clk->aclk_isp1_wrapper)   ||
1038                                 IS_ERR_OR_NULL(mrv_clk->clk_isp1)            ||
1039                                 IS_ERR_OR_NULL(mrv_clk->cif_clk_out)         ||
1040                                 IS_ERR_OR_NULL(mrv_clk->cif_clk_pll)         ||
1041                                 IS_ERR_OR_NULL(mrv_clk->pclkin_isp)          ||
1042                                 IS_ERR_OR_NULL(mrv_clk->pclk_dphytxrx)) {
1043                                 camsys_err("Get %s clock resouce failed!\n",
1044                                         miscdev_name);
1045                                 err = -EINVAL;
1046                                 goto clk_failed;
1047                         }
1048                 } else{
1049                         if (IS_ERR_OR_NULL(mrv_clk->hclk_isp0_noc)       ||
1050                                 IS_ERR_OR_NULL(mrv_clk->hclk_isp0_wrapper)   ||
1051                                 IS_ERR_OR_NULL(mrv_clk->aclk_isp0_noc)       ||
1052                                 IS_ERR_OR_NULL(mrv_clk->aclk_isp0_wrapper)   ||
1053                                 IS_ERR_OR_NULL(mrv_clk->clk_isp0)            ||
1054                                 IS_ERR_OR_NULL(mrv_clk->cif_clk_out)         ||
1055                                 IS_ERR_OR_NULL(mrv_clk->cif_clk_pll)         ||
1056                                 IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx)) {
1057                                 camsys_err("Get %s clock resouce failed!\n",
1058                                         miscdev_name);
1059                                 err = -EINVAL;
1060                                 goto clk_failed;
1061                         }
1062                 }
1063         } else{
1064                 /*mrv_clk->pd_isp         =                */
1065                 /*      devm_clk_get(&pdev->dev, "pd_isp");*/
1066                 mrv_clk->aclk_isp         =
1067                         devm_clk_get(&pdev->dev, "aclk_isp");
1068                 mrv_clk->hclk_isp         =
1069                         devm_clk_get(&pdev->dev, "hclk_isp");
1070                 mrv_clk->isp              =
1071                         devm_clk_get(&pdev->dev, "clk_isp");
1072                 mrv_clk->isp_jpe          =
1073                         devm_clk_get(&pdev->dev, "clk_isp_jpe");
1074                 mrv_clk->pclkin_isp   =
1075                         devm_clk_get(&pdev->dev, "pclkin_isp");
1076                 mrv_clk->cif_clk_out  =
1077                         devm_clk_get(&pdev->dev, "clk_cif_out");
1078                 mrv_clk->cif_clk_pll  =
1079                         devm_clk_get(&pdev->dev, "clk_cif_pll");
1080                 mrv_clk->clk_mipi_24m =
1081                         devm_clk_get(&pdev->dev, "clk_mipi_24m");
1082
1083                 if (
1084                         /*IS_ERR_OR_NULL(mrv_clk->pd_isp)    ||*/
1085                         IS_ERR_OR_NULL(mrv_clk->aclk_isp)    ||
1086                         IS_ERR_OR_NULL(mrv_clk->hclk_isp)    ||
1087                         IS_ERR_OR_NULL(mrv_clk->isp)         ||
1088                         IS_ERR_OR_NULL(mrv_clk->isp_jpe)     ||
1089                         IS_ERR_OR_NULL(mrv_clk->pclkin_isp)  ||
1090                         IS_ERR_OR_NULL(mrv_clk->cif_clk_out) ||
1091                         IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) {
1092                         camsys_err("Get %s clock resouce failed!\n",
1093                                 miscdev_name);
1094                         err = -EINVAL;
1095                         goto clk_failed;
1096                 }
1097
1098                 clk_set_rate(mrv_clk->isp, 210000000);
1099                 clk_set_rate(mrv_clk->isp_jpe, 210000000);
1100         }
1101
1102
1103         mutex_init(&mrv_clk->lock);
1104
1105         mrv_clk->in_on = false;
1106         mrv_clk->out_on = 0;
1107
1108         np = of_find_node_by_name(NULL, "isp0_mmu");
1109         if (!np) {
1110                 int index = 0;
1111                 /* iommu domain */
1112                 domain = iommu_domain_alloc(&platform_bus_type);
1113                 if (!domain)
1114                         goto clk_failed;
1115
1116                 err = iommu_get_dma_cookie(domain);
1117                 if (err)
1118                         goto err_free_domain;
1119
1120                 group = iommu_group_get(&pdev->dev);
1121                 if (!group) {
1122                         group = iommu_group_alloc();
1123                         if (IS_ERR(group)) {
1124                                 dev_err(&pdev->dev, "Failed to allocate IOMMU group\n");
1125                                 goto err_put_cookie;
1126                         }
1127
1128                         err = iommu_group_add_device(group, &pdev->dev);
1129                         iommu_group_put(group);
1130                         if (err) {
1131                                 dev_err(&pdev->dev, "failed to add device to IOMMU group\n");
1132                                 goto err_put_cookie;
1133                         }
1134                 }
1135                 camsys_dev->domain = domain;
1136                 camsys_dev->dma_buf_cnt = 0;
1137                 camsys_dev->iommu_cb = camsys_mrv_drm_iommu_cb;
1138                 for (index = 0; index < CAMSYS_DMA_BUF_MAX_NUM; index++)
1139                         camsys_dev->dma_buf[index].fd = -1;
1140         } else {
1141                 camsys_dev->iommu_cb = camsys_mrv_iommu_cb;
1142         }
1143
1144         camsys_dev->clk = (void *)mrv_clk;
1145         camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
1146         camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
1147         camsys_dev->reset_cb = camsys_mrv_reset_cb;
1148         camsys_dev->iomux = camsys_mrv_iomux_cb;
1149         camsys_dev->flash_trigger_cb = camsys_mrv_flash_trigger_cb;
1150
1151         camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
1152         camsys_dev->miscdev.name = miscdev_name;
1153         camsys_dev->miscdev.nodename = miscdev_name;
1154         camsys_dev->miscdev.fops = &camsys_fops;
1155
1156         if (CHIP_TYPE == 3399) {
1157                 if (register_res.start == 0xff920000) {
1158                         camsys_dev->miscdev.name = "camsys_marvin1";
1159                         camsys_dev->miscdev.nodename = "camsys_marvin1";
1160                 }
1161         }
1162
1163         err = misc_register(&camsys_dev->miscdev);
1164         if (err < 0) {
1165                 camsys_err("misc register %s failed!", miscdev_name);
1166                 goto misc_register_failed;
1167         }
1168         /* Variable init */
1169         camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
1170         camsys_dev->platform_remove = camsys_mrv_remove_cb;
1171
1172         return 0;
1173 misc_register_failed:
1174         if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device))
1175                 misc_deregister(&camsys_dev->miscdev);
1176 err_put_cookie:
1177         iommu_put_dma_cookie(domain);
1178 err_free_domain:
1179         iommu_domain_free(domain);
1180 clk_failed:
1181         if (mrv_clk != NULL) {
1182                 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp))
1183                         clk_put(mrv_clk->pd_isp);
1184
1185                 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp))
1186                         clk_put(mrv_clk->aclk_isp);
1187
1188                 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp))
1189                         clk_put(mrv_clk->hclk_isp);
1190
1191                 if (!IS_ERR_OR_NULL(mrv_clk->isp))
1192                         clk_put(mrv_clk->isp);
1193
1194                 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe))
1195                         clk_put(mrv_clk->isp_jpe);
1196
1197                 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp))
1198                         clk_put(mrv_clk->pclkin_isp);
1199
1200                 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out))
1201                         clk_put(mrv_clk->cif_clk_out);
1202
1203                 if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) {
1204                         if (!IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx))
1205                                 clk_put(mrv_clk->pclk_dphyrx);
1206
1207                         if (!IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc))
1208                                 clk_put(mrv_clk->clk_vio0_noc);
1209                 }
1210
1211                 kfree(mrv_clk);
1212                 mrv_clk = NULL;
1213         }
1214
1215 end:
1216         return err;
1217 }
1218 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);
1219