X-Git-Url: http://plrg.eecs.uci.edu/git/?p=firefly-linux-kernel-4.4.55.git;a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Frk_camsys%2Fcamsys_marvin.c;h=d4799695e486baa2e346dea73853d2914ffa10bf;hp=abad592f54af7a9b0d8565441d486971d49b30d9;hb=df804a00a9448cb6b8f7e387555d4660ad029dfb;hpb=91c0b3f7a5bdcd21dd014852bd3cf4e48c84e6cb diff --git a/drivers/media/video/rk_camsys/camsys_marvin.c b/drivers/media/video/rk_camsys/camsys_marvin.c old mode 100755 new mode 100644 index abad592f54af..d4799695e486 --- a/drivers/media/video/rk_camsys/camsys_marvin.c +++ b/drivers/media/video/rk_camsys/camsys_marvin.c @@ -2,683 +2,1206 @@ #include "camsys_soc_priv.h" #include "camsys_gpio.h" -#include +#include #include #include #include +#include + +#include +#include +#include +#include extern int rockchip_set_system_status(unsigned long status); extern int rockchip_clear_system_status(unsigned long status); static const char miscdev_name[] = CAMSYS_MARVIN_DEVNAME; - -static int camsys_mrv_iomux_cb(camsys_extdev_t *extdev,void *ptr) +static int camsys_mrv_iomux_cb(camsys_extdev_t *extdev, void *ptr) { - struct pinctrl *pinctrl; - struct pinctrl_state *state; - int retval = 0; - char state_str[20] = {0}; - camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr; - struct device *dev = &(extdev->pdev->dev); - camsys_soc_priv_t *soc; - - // DVP IO Config - - if (extdev->phy.type == CamSys_Phy_Cif) { - - switch (extdev->phy.info.cif.fmt) - { - case CamSys_Fmt_Raw_8b: - case CamSys_Fmt_Yuv420_8b: - case CamSys_Fmt_Yuv422_8b: - { - if (extdev->phy.info.cif.cifio == CamSys_SensorBit0_CifBit0) { - strcpy(state_str,"isp_dvp8bit0"); - } else if (extdev->phy.info.cif.cifio == CamSys_SensorBit0_CifBit2) { - strcpy(state_str,"isp_dvp8bit2"); - } else if (extdev->phy.info.cif.cifio == CamSys_SensorBit0_CifBit4) { - strcpy(state_str,"isp_dvp8bit4"); - }else { - camsys_err("extdev->phy.info.cif.cifio: 0x%x is invalidate!", extdev->phy.info.cif.cifio); - goto fail; - } - - break; - } - - case CamSys_Fmt_Raw_10b: - { - strcpy(state_str,"isp_dvp10bit"); - break; - } - - case CamSys_Fmt_Raw_12b: - { - strcpy(state_str,"isp_dvp12bit"); - break; - } - - default: - { - camsys_err("extdev->phy.info.cif.fmt: 0x%x is invalidate!",extdev->phy.info.cif.fmt); - goto fail; - } - } - } else { - if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) { - if (extdev->dev_cfg & CAMSYS_DEVCFG_PREFLASHLIGHT) { - strcpy(state_str,"isp_mipi_fl_prefl"); - } else { - strcpy(state_str,"isp_mipi_fl"); - } - { - //mux triggerout as gpio - //get gpio index - int flash_trigger_io ; - enum of_gpio_flags flags; - flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags); - if(gpio_is_valid(flash_trigger_io)){ - flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags); - gpio_request(flash_trigger_io,"camsys_gpio"); - gpio_direction_output(flash_trigger_io, (~(extdev->fl.fl.active) & 0x1)); - } - } - } else { - strcpy(state_str,"default"); - } - } - - camsys_trace(1,"marvin pinctrl select: %s", state_str); - - pinctrl = devm_pinctrl_get(dev); - if (IS_ERR(pinctrl)) { - camsys_err("devm_pinctrl_get failed!"); - goto fail; - } - state = pinctrl_lookup_state(pinctrl, - state_str); - if (IS_ERR(state)){ - camsys_err("pinctrl_lookup_state failed!"); - goto fail; - } - - if (!IS_ERR(state)) { - retval = pinctrl_select_state(pinctrl, state); - if (retval){ - camsys_err("pinctrl_select_state failed!"); - goto fail; - } - } - - if (camsys_dev->soc) { - soc = (camsys_soc_priv_t*)camsys_dev->soc; - if (soc->soc_cfg) { - (soc->soc_cfg)(Cif_IoDomain_Cfg,(void*)&extdev->dovdd.min_uv); - (soc->soc_cfg)(Clk_DriverStrength_Cfg,(void*)&extdev->clk.driver_strength); - } else { - camsys_err("camsys_dev->soc->soc_cfg is NULL!"); - } - } else { - camsys_err("camsys_dev->soc is NULL!"); - } - - return 0; + struct pinctrl *pinctrl; + struct pinctrl_state *state; + int retval = 0; + char state_str[64] = {0}; + camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr; + struct device *dev = &(extdev->pdev->dev); + camsys_soc_priv_t *soc; + + /* DVP IO Config */ + + if (extdev->phy.type == CamSys_Phy_Cif) { + switch (extdev->phy.info.cif.fmt) { + case CamSys_Fmt_Raw_8b: + case CamSys_Fmt_Yuv420_8b: + case CamSys_Fmt_Yuv422_8b:{ + if (extdev->phy.info.cif.cifio == + CamSys_SensorBit0_CifBit0) { + strcpy(state_str, "isp_dvp8bit0"); + } else if (extdev->phy.info.cif.cifio == + CamSys_SensorBit0_CifBit2) { + strcpy(state_str, "isp_dvp8bit2"); + } else if (extdev->phy.info.cif.cifio == + CamSys_SensorBit0_CifBit4) { + strcpy(state_str, "isp_dvp8bit4"); + } else { + camsys_err("extdev->phy.info.cif.cifio:0x%x is invalidate!", + extdev->phy.info.cif.cifio); + goto fail; + } + + break; + } + + case CamSys_Fmt_Raw_10b:{ + strcpy(state_str, "isp_dvp10bit"); + break; + } + + case CamSys_Fmt_Raw_12b:{ + strcpy(state_str, "isp_dvp12bit"); + break; + } + + default:{ + camsys_err("extdev->phy.info.cif.fmt: 0x%x is invalidate!", + extdev->phy.info.cif.fmt); + goto fail; + } + } + } else { + if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) { + if (extdev->dev_cfg & CAMSYS_DEVCFG_PREFLASHLIGHT) { + strcpy(state_str, "isp_mipi_fl_prefl"); + } else { + strcpy(state_str, "isp_mipi_fl"); + } + { + /*mux triggerout as gpio*/ + /*get gpio index*/ + int flash_trigger_io; + enum of_gpio_flags flags; + + flash_trigger_io = + of_get_named_gpio_flags( + camsys_dev->pdev->dev.of_node, + "rockchip,gpios", 0, &flags); + if (gpio_is_valid(flash_trigger_io)) { + flash_trigger_io = + of_get_named_gpio_flags( + camsys_dev->pdev->dev.of_node, + "rockchip,gpios", 0, &flags); + gpio_request(flash_trigger_io, + "camsys_gpio"); + gpio_direction_output( + flash_trigger_io, + (~(extdev->fl.fl.active) & + 0x1)); + } + } + } else { + if (CHIP_TYPE == 3399) { + strcpy(state_str, "cif_clkout"); + } else { + strcpy(state_str, "default"); + } + } + } + + camsys_trace(1, "marvin pinctrl select: %s", state_str); + + pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(pinctrl)) { + camsys_err("devm_pinctrl_get failed!"); + goto fail; + } + state = pinctrl_lookup_state(pinctrl, + state_str); + if (IS_ERR(state)) { + camsys_err("pinctrl_lookup_state failed!"); + goto fail; + } + + if (!IS_ERR(state)) { + retval = pinctrl_select_state(pinctrl, state); + if (retval) { + camsys_err("pinctrl_select_state failed!"); + goto fail; + } + } + + if (camsys_dev->soc) { + soc = (camsys_soc_priv_t *)camsys_dev->soc; + if (soc->soc_cfg) { + (soc->soc_cfg)(camsys_dev, Cif_IoDomain_Cfg, + (void *)&extdev->dovdd.min_uv); + (soc->soc_cfg)(camsys_dev, Clk_DriverStrength_Cfg, + (void *)&extdev->clk.driver_strength); + } else { + camsys_err("camsys_dev->soc->soc_cfg is NULL!"); + } + } else { + camsys_err("camsys_dev->soc is NULL!"); + } + + return 0; fail: - return -1; + return -1; } -static int camsys_mrv_flash_trigger_cb(void *ptr,int mode,unsigned int on) +static int camsys_mrv_flash_trigger_cb(void *ptr, int mode, unsigned int on) { - camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr; - struct device *dev = &(camsys_dev->pdev->dev); - int flash_trigger_io ; - struct pinctrl *pinctrl; - struct pinctrl_state *state; - char state_str[20] = {0}; - int retval = 0; - enum of_gpio_flags flags; - camsys_extdev_t *extdev = NULL; - - if(!on){ - strcpy(state_str,"isp_flash_as_gpio"); - pinctrl = devm_pinctrl_get(dev); - if (IS_ERR(pinctrl)) { - camsys_err("devm_pinctrl_get failed!"); - } - state = pinctrl_lookup_state(pinctrl, - state_str); - if (IS_ERR(state)){ - camsys_err("pinctrl_lookup_state failed!"); - } - - if (!IS_ERR(state)) { - retval = pinctrl_select_state(pinctrl, state); - if (retval){ - camsys_err("pinctrl_select_state failed!"); - } - - } - - //get gpio index - flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags); - if(gpio_is_valid(flash_trigger_io)){ - flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags); - gpio_request(flash_trigger_io,"camsys_gpio"); - //get flash io active pol - if (!list_empty(&camsys_dev->extdevs.list)) { - list_for_each_entry(extdev, &camsys_dev->extdevs.list, list) { - if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) { - gpio_direction_output(flash_trigger_io, (~(extdev->fl.fl.active) & 0x1)); - } - } - } - } - }else{ - strcpy(state_str,"isp_flash_as_trigger_out"); - pinctrl = devm_pinctrl_get(dev); - if (IS_ERR(pinctrl)) { - camsys_err("devm_pinctrl_get failed!"); - } - state = pinctrl_lookup_state(pinctrl, - state_str); - if (IS_ERR(state)){ - camsys_err("pinctrl_lookup_state failed!"); - } - - if (!IS_ERR(state)) { - retval = pinctrl_select_state(pinctrl, state); - if (retval){ - camsys_err("pinctrl_select_state failed!"); - } - - } - } - return retval; + camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr; + struct device *dev = &(camsys_dev->pdev->dev); + int flash_trigger_io; + struct pinctrl *pinctrl; + struct pinctrl_state *state; + char state_str[63] = {0}; + int retval = 0; + enum of_gpio_flags flags; + camsys_extdev_t *extdev = NULL; + + if (!on) { + strcpy(state_str, "isp_flash_as_gpio"); + pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(pinctrl)) { + camsys_err("devm_pinctrl_get failed!"); + } + state = pinctrl_lookup_state(pinctrl, state_str); + if (IS_ERR(state)) { + camsys_err("pinctrl_lookup_state failed!"); + } + + if (!IS_ERR(state)) { + retval = pinctrl_select_state(pinctrl, state); + if (retval) { + camsys_err("pinctrl_select_state failed!"); + } + } + + /*get gpio index*/ + flash_trigger_io = of_get_named_gpio_flags( + camsys_dev->pdev->dev.of_node, + "rockchip,gpios", 0, &flags); + if (gpio_is_valid(flash_trigger_io)) { + flash_trigger_io = of_get_named_gpio_flags( + camsys_dev->pdev->dev.of_node, + "rockchip,gpios", 0, &flags); + gpio_request(flash_trigger_io, "camsys_gpio"); + /*get flash io active pol*/ + if (!list_empty(&camsys_dev->extdevs.list)) { + list_for_each_entry( + extdev, &camsys_dev->extdevs.list, + list) { + if (extdev->dev_cfg & + CAMSYS_DEVCFG_FLASHLIGHT) { + gpio_direction_output( + flash_trigger_io, + (~(extdev->fl.fl.active) + & 0x1)); + } + } + } + } + } else { + strcpy(state_str, "isp_flash_as_trigger_out"); + pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(pinctrl)) { + camsys_err("devm_pinctrl_get failed!"); + } + state = pinctrl_lookup_state(pinctrl, + state_str); + if (IS_ERR(state)) { + camsys_err("pinctrl_lookup_state failed!"); + } + + if (!IS_ERR(state)) { + retval = pinctrl_select_state(pinctrl, state); + if (retval) { + camsys_err("pinctrl_select_state failed!"); + } + + } + } + return retval; } -static struct device *rockchip_get_sysmmu_device_by_compatible(const char *compt) +static struct device *rockchip_get_sysmmu_device_by_compatible( +const char *compt) { struct device_node *dn = NULL; struct platform_device *pd = NULL; - struct device *ret = NULL ; + struct device *ret = NULL; - dn = of_find_compatible_node(NULL,NULL,compt); - if(!dn) - { - printk("can't find device node %s \r\n",compt); + dn = of_find_compatible_node(NULL, NULL, compt); + if (!dn) { + camsys_err("can't find device node %s \r\n", compt); return NULL; } - + pd = of_find_device_by_node(dn); - if(!pd) - { - printk("can't find platform device in device node %s \r\n",compt); - return NULL; + if (!pd) { + camsys_err( + "can't find platform device in device node %s \r\n", + compt); + return NULL; } ret = &pd->dev; - + return ret; } #ifdef CONFIG_IOMMU_API -static inline void platform_set_sysmmu(struct device *iommu, struct device *dev) +static inline void platform_set_sysmmu( +struct device *iommu, struct device *dev) { dev->archdata.iommu = iommu; } #else -static inline void platform_set_sysmmu(struct device *iommu, struct device *dev) +static inline void platform_set_sysmmu( +struct device *iommu, struct device *dev) { } #endif -static int camsys_mrv_iommu_cb(void *ptr,camsys_sysctrl_t *devctl) +static int camsys_mrv_iommu_cb(void *ptr, camsys_sysctrl_t *devctl) { - struct device *iommu_dev = NULL,*dev = NULL; - struct file *file = NULL; - struct ion_client *client = NULL; - struct ion_handle *handle = NULL; - camsys_iommu_t *iommu = NULL; - int ret = 0,iommu_enabled = 0; - camsys_dev_t * camsys_dev = (camsys_dev_t *)ptr; - - of_property_read_u32(camsys_dev->pdev->dev.of_node, "rockchip,isp,iommu_enable", &iommu_enabled); - if(iommu_enabled != 1){ - camsys_err("isp iommu have not been enabled!\n"); - ret = -1; - goto iommu_end; - } - iommu_dev = rockchip_get_sysmmu_device_by_compatible(ISP_IOMMU_COMPATIBLE_NAME); - if(!iommu_dev){ - camsys_err("get iommu device erro!\n"); - ret = -1; - goto iommu_end; - } - dev = &(camsys_dev->pdev->dev); - iommu = (camsys_iommu_t *)(devctl->rev); - file = fget(iommu->client_fd); - if(!file){ - camsys_err("get client_fd file erro!\n"); - ret = -1; - goto iommu_end; - } - - client = file->private_data; - - if(!client){ - camsys_err("get ion_client erro!\n"); - ret = -1; - goto iommu_end; - } - - fput(file); - - handle = ion_import_dma_buf(client,iommu->map_fd); - - camsys_trace(1,"map fd %d ,client fd %d\n",iommu->map_fd,iommu->client_fd); - if(!handle){ - camsys_err("get ion_handle erro!\n"); - ret = -1; - goto iommu_end; - } - if(devctl->on){ - platform_set_sysmmu(iommu_dev,dev); - ret = rockchip_iovmm_activate(dev); - - ret = ion_map_iommu(dev,client,handle,&(iommu->linear_addr),&(iommu->len)); - - }else{ - ion_unmap_iommu(dev,client,handle); - platform_set_sysmmu(iommu_dev,dev); - rockchip_iovmm_deactivate(dev); - } + struct device *iommu_dev = NULL, *dev = NULL; + struct file *file = NULL; + struct ion_client *client = NULL; + struct ion_handle *handle = NULL; + camsys_iommu_t *iommu = NULL; + int ret = 0, iommu_enabled = 0; + camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr; + + of_property_read_u32(camsys_dev->pdev->dev.of_node, + "rockchip,isp,iommu-enable", &iommu_enabled); + if (iommu_enabled != 1) { + camsys_err("isp iommu have not been enabled!\n"); + ret = -1; + goto iommu_end; + } + + if (strstr(camsys_dev->miscdev.name, "camsys_marvin1")) { + iommu_dev = + rockchip_get_sysmmu_device_by_compatible + (ISP1_IOMMU_COMPATIBLE_NAME); + } else { + if (CHIP_TYPE == 3399) { + iommu_dev = + rockchip_get_sysmmu_device_by_compatible + (ISP0_IOMMU_COMPATIBLE_NAME); + } else{ + iommu_dev = + rockchip_get_sysmmu_device_by_compatible + (ISP_IOMMU_COMPATIBLE_NAME); + } + } + + if (!iommu_dev) { + camsys_err("get iommu device erro!\n"); + ret = -1; + goto iommu_end; + } + dev = &(camsys_dev->pdev->dev); + iommu = (camsys_iommu_t *)(devctl->rev); + file = fget(iommu->client_fd); + if (!file) { + camsys_err("get client_fd file erro!\n"); + ret = -1; + goto iommu_end; + } + + client = file->private_data; + + if (!client) { + camsys_err("get ion_client erro!\n"); + ret = -1; + goto iommu_end; + } + + fput(file); + + handle = ion_import_dma_buf(client, iommu->map_fd); + + camsys_trace(1, "map fd %d ,client fd %d\n", + iommu->map_fd, iommu->client_fd); + if (!handle) { + camsys_err("get ion_handle erro!\n"); + ret = -1; + goto iommu_end; + } + if (devctl->on) { + platform_set_sysmmu(iommu_dev, dev); + ret = rockchip_iovmm_activate(dev); + ret = ion_map_iommu(dev, client, handle, + &(iommu->linear_addr), &(iommu->len)); + } else { + ion_unmap_iommu(dev, client, handle); + platform_set_sysmmu(iommu_dev, dev); + rockchip_iovmm_deactivate(dev); + } iommu_end: - return ret; + return ret; } -static int camsys_mrv_reset_cb(void *ptr,unsigned int on) + +static int camsys_drm_dma_attach_device(camsys_dev_t *camsys_dev) { - camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr; - camsys_soc_priv_t *soc; - - - if (camsys_dev->soc) { - soc = (camsys_soc_priv_t*)camsys_dev->soc; - if (soc->soc_cfg) { - (soc->soc_cfg)(Isp_SoftRst,(void*)(unsigned long)on); - } else { - camsys_err("camsys_dev->soc->soc_cfg is NULL!"); - } - } else { - camsys_err("camsys_dev->soc is NULL!"); - } - - return 0; + struct iommu_domain *domain = camsys_dev->domain; + struct device *dev = &camsys_dev->pdev->dev; + int ret; + + ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + if (ret) + return ret; + + dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); + ret = iommu_attach_device(domain, dev); + if (ret) { + dev_err(dev, "Failed to attach iommu device\n"); + return ret; + } + + if (!common_iommu_setup_dma_ops(dev, 0x10000000, SZ_2G, domain->ops)) { + dev_err(dev, "Failed to set dma_ops\n"); + iommu_detach_device(domain, dev); + ret = -ENODEV; + } + + return ret; } -static int camsys_mrv_clkin_cb(void *ptr, unsigned int on) +static void camsys_drm_dma_detach_device(camsys_dev_t *camsys_dev) { - camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr; - camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk; - unsigned long isp_clk; - - if (on && !clk->in_on) { - rockchip_set_system_status(SYS_STATUS_ISP); - - if (on == 1) { - isp_clk = 210000000; - } else { - isp_clk = 420000000; + struct iommu_domain *domain = camsys_dev->domain; + struct device *dev = &camsys_dev->pdev->dev; + + iommu_detach_device(domain, dev); +} + +static int camsys_mrv_drm_iommu_cb(void *ptr, camsys_sysctrl_t *devctl) +{ + struct device *dev = NULL; + camsys_iommu_t *iommu = NULL; + struct dma_buf *dma_buf; + struct dma_buf_attachment *attach; + struct sg_table *sgt; + dma_addr_t dma_addr; + int index = 0; + int ret = 0; + camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr; + + dev = &camsys_dev->pdev->dev; + iommu = (camsys_iommu_t *)(devctl->rev); + if (devctl->on) { + /*ummap mapped fd first*/ + int cur_mapped_cnt = camsys_dev->dma_buf_cnt; + + for (index = 0; index < cur_mapped_cnt; index++) { + if (camsys_dev->dma_buf[index].fd == iommu->map_fd) + break; + } + if (index != cur_mapped_cnt) { + attach = camsys_dev->dma_buf[index].attach; + dma_buf = camsys_dev->dma_buf[index].dma_buf; + sgt = camsys_dev->dma_buf[index].sgt; + dma_buf_unmap_attachment + (attach, + sgt, + DMA_BIDIRECTIONAL); + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); + if (camsys_dev->dma_buf_cnt == 1) + camsys_drm_dma_detach_device(camsys_dev); + camsys_dev->dma_buf_cnt--; + camsys_dev->dma_buf[index].fd = -1; + } + /*get a free slot*/ + for (index = 0; index < CAMSYS_DMA_BUF_MAX_NUM; index++) + if (camsys_dev->dma_buf[index].fd == -1) + break; + + if (index == CAMSYS_DMA_BUF_MAX_NUM) + return -ENOMEM; + + if (camsys_dev->dma_buf_cnt == 0) { + ret = camsys_drm_dma_attach_device(camsys_dev); + if (ret) + return ret; } - clk_set_rate(clk->isp,isp_clk); - clk_set_rate(clk->isp_jpe, isp_clk); + dma_buf = dma_buf_get(iommu->map_fd); + if (IS_ERR(dma_buf)) + return PTR_ERR(dma_buf); + attach = dma_buf_attach(dma_buf, dev); + if (IS_ERR(attach)) { + dma_buf_put(dma_buf); + return PTR_ERR(attach); + } + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) { + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); + return PTR_ERR(sgt); + } + dma_addr = sg_dma_address(sgt->sgl); + camsys_dev->dma_buf[index].dma_addr = dma_addr; + camsys_dev->dma_buf[index].attach = attach; + camsys_dev->dma_buf[index].dma_buf = dma_buf; + camsys_dev->dma_buf[index].sgt = sgt; + camsys_dev->dma_buf[index].fd = iommu->map_fd; + iommu->linear_addr = dma_addr; + iommu->len = sg_dma_len(sgt->sgl); + camsys_dev->dma_buf_cnt++; + camsys_trace + ( + 1, + "%s:iommu map dma_addr 0x%lx,attach %p," + "dma_buf %p,sgt %p,fd %d,buf_cnt %d", + __func__, + (unsigned long)dma_addr, + attach, + dma_buf, + sgt, + iommu->map_fd, + camsys_dev->dma_buf_cnt); + } else { + if ( + (camsys_dev->dma_buf_cnt == 0) || + (index < 0) || + (index >= CAMSYS_DMA_BUF_MAX_NUM)) + return -EINVAL; + + for (index = 0; index < camsys_dev->dma_buf_cnt; index++) { + if (camsys_dev->dma_buf[index].fd == iommu->map_fd) + break; + } + if (index == camsys_dev->dma_buf_cnt) { + camsys_warn("can't find map fd %d", iommu->map_fd); + return 0; + } + attach = camsys_dev->dma_buf[index].attach; + dma_buf = camsys_dev->dma_buf[index].dma_buf; + sgt = camsys_dev->dma_buf[index].sgt; + camsys_trace + ( + 1, + "%s:iommu map ,attach %p," + "dma_buf %p,sgt %p,index %d", + __func__, + attach, + dma_buf, + sgt, + index); + dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); + if (camsys_dev->dma_buf_cnt == 1) + camsys_drm_dma_detach_device(camsys_dev); + + camsys_dev->dma_buf_cnt--; + camsys_dev->dma_buf[index].fd = -1; + } - clk_prepare_enable(clk->pd_isp); - clk_prepare_enable(clk->aclk_isp); - clk_prepare_enable(clk->hclk_isp); - clk_prepare_enable(clk->isp); - clk_prepare_enable(clk->isp_jpe); - clk_prepare_enable(clk->pclkin_isp); - if(CHIP_TYPE == 3368){ + return ret; +} + +static int camsys_mrv_reset_cb(void *ptr, unsigned int on) +{ + camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr; + camsys_soc_priv_t *soc; + + if (camsys_dev->soc) { + soc = (camsys_soc_priv_t *)camsys_dev->soc; + if (soc->soc_cfg) { + (soc->soc_cfg) + (camsys_dev, Isp_SoftRst, + (void *)(unsigned long)on); + } else { + camsys_err("camsys_dev->soc->soc_cfg is NULL!"); + } + } else { + camsys_err("camsys_dev->soc is NULL!"); + } + + return 0; +} +static int camsys_mrv_clkin_cb(void *ptr, unsigned int on) +{ + camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr; + camsys_mrv_clk_t *clk = (camsys_mrv_clk_t *)camsys_dev->clk; + unsigned long isp_clk; + + if (CHIP_TYPE == 3399) { + if (on && !clk->in_on) { + /* rockchip_set_system_status(SYS_STATUS_ISP); */ + if (on == 1) + isp_clk = 210000000; + else + isp_clk = 420000000; + + if (strstr(camsys_dev->miscdev.name, + "camsys_marvin1")) { + clk_set_rate(clk->clk_isp1, isp_clk); + clk_prepare_enable(clk->hclk_isp1_noc); + clk_prepare_enable(clk->hclk_isp1_wrapper); + clk_prepare_enable(clk->aclk_isp1_noc); + clk_prepare_enable(clk->aclk_isp1_wrapper); + clk_prepare_enable(clk->clk_isp1); + + clk_prepare_enable(clk->cif_clk_out); + clk_prepare_enable(clk->pclk_dphy_ref); + clk_prepare_enable(clk->pclk_dphytxrx); + + clk_prepare_enable(clk->pclkin_isp); + clk_prepare_enable(clk->cif_clk_out); + } else { + clk_set_rate(clk->clk_isp0, isp_clk); + clk_prepare_enable(clk->hclk_isp0_noc); + clk_prepare_enable(clk->hclk_isp0_wrapper); + clk_prepare_enable(clk->aclk_isp0_noc); + clk_prepare_enable(clk->aclk_isp0_wrapper); + clk_prepare_enable(clk->clk_isp0); + clk_prepare_enable(clk->cif_clk_out); + clk_prepare_enable(clk->pclk_dphyrx); + clk_prepare_enable(clk->pclk_dphy_ref); + } + + clk->in_on = true; + + camsys_trace(1, "%s clock(f: %ld Hz) in turn on", + dev_name(camsys_dev->miscdev.this_device), isp_clk); + camsys_mrv_reset_cb(ptr, 1); + udelay(100); + camsys_mrv_reset_cb(ptr, 0); + } else if (!on && clk->in_on) { + if (strstr(camsys_dev->miscdev.name, + "camsys_marvin1")) { + clk_disable_unprepare(clk->hclk_isp1_noc); + clk_disable_unprepare(clk->hclk_isp1_wrapper); + clk_disable_unprepare(clk->aclk_isp1_noc); + clk_disable_unprepare(clk->aclk_isp1_wrapper); + clk_disable_unprepare(clk->clk_isp1); + + clk_disable_unprepare(clk->cif_clk_out); + clk_disable_unprepare(clk->pclk_dphytxrx); + clk_disable_unprepare(clk->pclk_dphy_ref); + + clk_disable_unprepare(clk->pclkin_isp); + } else { + clk_disable_unprepare(clk->hclk_isp0_noc); + clk_disable_unprepare(clk->hclk_isp0_wrapper); + clk_disable_unprepare(clk->aclk_isp0_noc); + clk_disable_unprepare(clk->aclk_isp0_wrapper); + clk_disable_unprepare(clk->clk_isp0); + + clk_disable_unprepare(clk->cif_clk_out); + clk_disable_unprepare(clk->pclk_dphyrx); + clk_disable_unprepare(clk->pclk_dphy_ref); + } + + /* rockchip_clear_system_status(SYS_STATUS_ISP); */ + clk->in_on = false; + camsys_trace(1, "%s clock in turn off", + dev_name(camsys_dev->miscdev.this_device)); + } + } else{ + if (on && !clk->in_on) { + /* rockchip_set_system_status(SYS_STATUS_ISP); */ + + if (on == 1) + isp_clk = 210000000; + else + isp_clk = 420000000; + + clk_set_rate(clk->isp, isp_clk); + clk_set_rate(clk->isp_jpe, isp_clk); + + /* clk_prepare_enable(clk->pd_isp); */ + clk_prepare_enable(clk->aclk_isp); + clk_prepare_enable(clk->hclk_isp); + clk_prepare_enable(clk->isp); + clk_prepare_enable(clk->isp_jpe); + clk_prepare_enable(clk->pclkin_isp); + if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) { clk_prepare_enable(clk->cif_clk_out); clk_prepare_enable(clk->pclk_dphyrx); - clk_prepare_enable(clk->clk_vio0_noc); - }else{ - clk_prepare_enable(clk->clk_mipi_24m); - } - clk->in_on = true; - - camsys_trace(1, "%s clock(f: %ld Hz) in turn on",dev_name(camsys_dev->miscdev.this_device),isp_clk); - camsys_mrv_reset_cb(ptr,1); - udelay(100); - camsys_mrv_reset_cb(ptr,0); - - } else if (!on && clk->in_on) { - - clk_disable_unprepare(clk->aclk_isp); - clk_disable_unprepare(clk->hclk_isp); - clk_disable_unprepare(clk->isp); - clk_disable_unprepare(clk->isp_jpe); - clk_disable_unprepare(clk->pclkin_isp); - if(CHIP_TYPE == 3368){ - clk_disable_unprepare(clk->cif_clk_out); + } else { + clk_prepare_enable(clk->clk_mipi_24m); + } + clk->in_on = true; + + camsys_trace(1, "%s clock(f: %ld Hz) in turn on", + dev_name(camsys_dev->miscdev.this_device), isp_clk); + camsys_mrv_reset_cb(ptr, 1); + udelay(100); + camsys_mrv_reset_cb(ptr, 0); + } else if (!on && clk->in_on) { + clk_disable_unprepare(clk->aclk_isp); + clk_disable_unprepare(clk->hclk_isp); + clk_disable_unprepare(clk->isp); + clk_disable_unprepare(clk->isp_jpe); + clk_disable_unprepare(clk->pclkin_isp); + if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) { + clk_disable_unprepare(clk->cif_clk_out); clk_disable_unprepare(clk->pclk_dphyrx); - clk_disable_unprepare(clk->clk_vio0_noc); + } else { + clk_disable_unprepare(clk->clk_mipi_24m); + } + /* clk_disable_unprepare(clk->pd_isp); */ - }else{ - clk_disable_unprepare(clk->clk_mipi_24m); + /* rockchip_clear_system_status(SYS_STATUS_ISP); */ + clk->in_on = false; + camsys_trace(1, "%s clock in turn off", + dev_name(camsys_dev->miscdev.this_device)); } - clk_disable_unprepare(clk->pd_isp); + } - rockchip_clear_system_status(SYS_STATUS_ISP); - clk->in_on = false; - camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device)); - } - - return 0; + return 0; } -static int camsys_mrv_clkout_cb(void *ptr, unsigned int on,unsigned int inclk) + +static int camsys_mrv_clkout_cb(void *ptr, unsigned int on, unsigned int inclk) { - camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr; - camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk; - - mutex_lock(&clk->lock); - if (on && (clk->out_on != on)) { - - clk_set_rate(clk->cif_clk_out,inclk); - clk_prepare_enable(clk->cif_clk_out); - + camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr; + camsys_mrv_clk_t *clk = (camsys_mrv_clk_t *)camsys_dev->clk; + + mutex_lock(&clk->lock); + if (on && (clk->out_on != on)) { + + pm_runtime_get_sync(&camsys_dev->pdev->dev); + + clk_set_rate(clk->cif_clk_out, inclk); + clk_prepare_enable(clk->cif_clk_out); clk->out_on = on; - camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device), - inclk); - } else if (!on && clk->out_on) { - if(!IS_ERR_OR_NULL(clk->cif_clk_pll)) { - clk_set_parent(clk->cif_clk_out, clk->cif_clk_pll); - } else { - camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device)); - } + camsys_trace(1, "camsys %s clock out(rate: %dHz) turn on", + dev_name(camsys_dev->miscdev.this_device), + inclk); + } else if (!on && clk->out_on) { + if (!IS_ERR_OR_NULL(clk->cif_clk_pll)) { + clk_set_parent(clk->cif_clk_out, + clk->cif_clk_pll); + } else { + camsys_warn("%s clock out may be not off!", + dev_name(camsys_dev->miscdev.this_device)); + } - clk_disable_unprepare( clk->cif_clk_out); + clk_disable_unprepare(clk->cif_clk_out); - clk->out_on = 0; + pm_runtime_disable(&camsys_dev->pdev->dev); + clk->out_on = 0; - camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device)); - } - mutex_unlock(&clk->lock); + camsys_trace(1, "%s clock out turn off", + dev_name(camsys_dev->miscdev.this_device)); + } + mutex_unlock(&clk->lock); - return 0; + return 0; } static irqreturn_t camsys_mrv_irq(int irq, void *data) { - camsys_dev_t *camsys_dev = (camsys_dev_t*)data; - camsys_irqstas_t *irqsta; - camsys_irqpool_t *irqpool; - unsigned int isp_mis,mipi_mis,mi_mis,*mis,jpg_mis,jpg_err_mis; - - unsigned int mi_ris,mi_imis; - - isp_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_MIS)); - mipi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_MIS)); - jpg_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_JPG_MIS)); - jpg_err_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_JPG_ERR_MIS)); - mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS)); -#if 1 - mi_ris = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_RIS)); - mi_imis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_IMIS)); - while((mi_ris & mi_imis) != mi_mis){ - camsys_trace(2,"mi_mis status erro,mi_mis 0x%x,mi_ris 0x%x,imis 0x%x\n",mi_mis,mi_ris,mi_imis); - mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS)); - mi_ris = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_RIS)); - mi_imis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_IMIS)); + camsys_dev_t *camsys_dev = (camsys_dev_t *)data; + camsys_irqstas_t *irqsta; + camsys_irqpool_t *irqpool; + unsigned int isp_mis, mipi_mis, mi_mis, *mis, jpg_mis, jpg_err_mis; + unsigned int mi_ris, mi_imis; + + isp_mis = __raw_readl((void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_ISP_MIS)); + mipi_mis = __raw_readl((void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_MIPI_MIS)); + jpg_mis = __raw_readl((void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_JPG_MIS)); + jpg_err_mis = __raw_readl((void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_JPG_ERR_MIS)); + mi_mis = __raw_readl((void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_MI_MIS)); + + mi_ris = __raw_readl((void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_MI_RIS)); + mi_imis = __raw_readl((void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_MI_IMIS)); + while ((mi_ris & mi_imis) != mi_mis) { + camsys_trace(2, "mi_mis status erro,mi_mis 0x%x," + "mi_ris 0x%x,imis 0x%x\n", + mi_mis, mi_ris, mi_imis); + mi_mis = __raw_readl((void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_MI_MIS)); + mi_ris = __raw_readl((void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_MI_RIS)); + mi_imis = __raw_readl((void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_MI_IMIS)); } -#endif + __raw_writel(isp_mis, (void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_ISP_ICR)); + __raw_writel(mipi_mis, (void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_MIPI_ICR)); + __raw_writel(jpg_mis, (void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_JPG_ICR)); + __raw_writel(jpg_err_mis, (void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_JPG_ERR_ICR)); + __raw_writel(mi_mis, (void volatile *) + (camsys_dev->devmems.registermem->vir_base + + MRV_MI_ICR)); + + spin_lock(&camsys_dev->irq.lock); + if (!list_empty(&camsys_dev->irq.irq_pool)) { + list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) { + if (irqpool->pid != 0) { + switch (irqpool->mis) { + case MRV_ISP_MIS: + { + mis = &isp_mis; + break; + } + + case MRV_MIPI_MIS: + { + mis = &mipi_mis; + break; + } + case MRV_MI_MIS: + { + mis = &mi_mis; + break; + } + + case MRV_JPG_MIS: + { + mis = &jpg_mis; + break; + } + + case MRV_JPG_ERR_MIS: + { + mis = &jpg_err_mis; + break; + } + + default: + { + camsys_trace(2, + "Thread(pid:%d) irqpool mis(%d) is invalidate", + irqpool->pid, irqpool->mis); + goto end; + } + } + + if (*mis != 0) { + spin_lock(&irqpool->lock); + if (!list_empty(&irqpool->deactive)) { + irqsta = + list_first_entry( + &irqpool->deactive, + camsys_irqstas_t, + list); + irqsta->sta.mis = *mis; + list_del_init(&irqsta->list); + list_add_tail(&irqsta->list, + &irqpool->active); + wake_up(&irqpool->done); + } + spin_unlock(&irqpool->lock); + } + } + } + } +end: + spin_unlock(&camsys_dev->irq.lock); - __raw_writel(isp_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_ICR)); - __raw_writel(mipi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_ICR)); - __raw_writel(jpg_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_JPG_ICR)); - __raw_writel(jpg_err_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_JPG_ERR_ICR)); - __raw_writel(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_ICR)); - - spin_lock(&camsys_dev->irq.lock); - if (!list_empty(&camsys_dev->irq.irq_pool)) { - list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) { - if (irqpool->pid != 0) { - switch(irqpool->mis) - { - case MRV_ISP_MIS: - { - mis = &isp_mis; - break; - } - - case MRV_MIPI_MIS: - { - mis = &mipi_mis; - break; - } - case MRV_MI_MIS: - { - mis = &mi_mis; - break; - } - - case MRV_JPG_MIS: - { - mis = &jpg_mis; - break; - } - - case MRV_JPG_ERR_MIS: - { - mis = &jpg_err_mis; - break; - } - - default: - { - camsys_trace(2,"Thread(pid:%d) irqpool mis(%d) is invalidate",irqpool->pid,irqpool->mis); - goto end; - } - } - - if (*mis != 0) { - spin_lock(&irqpool->lock); - if (!list_empty(&irqpool->deactive)) { - irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list); - irqsta->sta.mis = *mis; - list_del_init(&irqsta->list); - list_add_tail(&irqsta->list,&irqpool->active); - wake_up(&irqpool->done); - } - spin_unlock(&irqpool->lock); - } - } - } - } -end: - spin_unlock(&camsys_dev->irq.lock); - - return IRQ_HANDLED; + return IRQ_HANDLED; } + static int camsys_mrv_remove_cb(struct platform_device *pdev) { - camsys_dev_t *camsys_dev = platform_get_drvdata(pdev); - camsys_mrv_clk_t *mrv_clk=NULL; - - if (camsys_dev->clk != NULL) { - - mrv_clk = (camsys_mrv_clk_t*)camsys_dev->clk; - if (mrv_clk->out_on) - camsys_mrv_clkout_cb(mrv_clk,0,0); - if (mrv_clk->in_on) - camsys_mrv_clkin_cb(mrv_clk,0); - - if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) { - devm_clk_put(&pdev->dev,mrv_clk->pd_isp); - } - if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) { - devm_clk_put(&pdev->dev,mrv_clk->aclk_isp); - } - if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) { - devm_clk_put(&pdev->dev,mrv_clk->hclk_isp); - } - if (!IS_ERR_OR_NULL(mrv_clk->isp)) { - devm_clk_put(&pdev->dev,mrv_clk->isp); - } - if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) { - devm_clk_put(&pdev->dev,mrv_clk->isp_jpe); - } - if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) { - devm_clk_put(&pdev->dev,mrv_clk->pclkin_isp); - } - if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) { - devm_clk_put(&pdev->dev,mrv_clk->cif_clk_out); - } - if (!IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) { - devm_clk_put(&pdev->dev,mrv_clk->clk_vio0_noc); - } - - kfree(mrv_clk); - mrv_clk = NULL; - } - - return 0; + camsys_dev_t *camsys_dev = platform_get_drvdata(pdev); + camsys_mrv_clk_t *mrv_clk = NULL; + + if (camsys_dev->clk != NULL) { + + mrv_clk = (camsys_mrv_clk_t *)camsys_dev->clk; + if (mrv_clk->out_on) + camsys_mrv_clkout_cb(mrv_clk, 0, 0); + if (mrv_clk->in_on) + camsys_mrv_clkin_cb(mrv_clk, 0); + + if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) { + devm_clk_put(&pdev->dev, mrv_clk->pd_isp); + } + if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) { + devm_clk_put(&pdev->dev, mrv_clk->aclk_isp); + } + if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) { + devm_clk_put(&pdev->dev, mrv_clk->hclk_isp); + } + if (!IS_ERR_OR_NULL(mrv_clk->isp)) { + devm_clk_put(&pdev->dev, mrv_clk->isp); + } + if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) { + devm_clk_put(&pdev->dev, mrv_clk->isp_jpe); + } + if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) { + devm_clk_put(&pdev->dev, mrv_clk->pclkin_isp); + } + if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) { + devm_clk_put(&pdev->dev, mrv_clk->cif_clk_out); + } + if (!IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) { + devm_clk_put(&pdev->dev, mrv_clk->clk_vio0_noc); + } + + if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp0_noc)) { + devm_clk_put(&pdev->dev, mrv_clk->hclk_isp0_noc); + } + if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp0_wrapper)) { + devm_clk_put(&pdev->dev, mrv_clk->hclk_isp0_wrapper); + } + if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp1_noc)) { + devm_clk_put(&pdev->dev, mrv_clk->hclk_isp1_noc); + } + if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp1_wrapper)) { + devm_clk_put(&pdev->dev, mrv_clk->hclk_isp1_wrapper); + } + if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp0_noc)) { + devm_clk_put(&pdev->dev, mrv_clk->aclk_isp0_noc); + } + + if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp0_wrapper)) { + devm_clk_put(&pdev->dev, mrv_clk->aclk_isp0_wrapper); + } + if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp1_noc)) { + devm_clk_put(&pdev->dev, mrv_clk->aclk_isp1_noc); + } + if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp1_wrapper)) { + devm_clk_put(&pdev->dev, mrv_clk->aclk_isp1_wrapper); + } + if (!IS_ERR_OR_NULL(mrv_clk->clk_isp0)) { + devm_clk_put(&pdev->dev, mrv_clk->clk_isp0); + } + if (!IS_ERR_OR_NULL(mrv_clk->clk_isp1)) { + devm_clk_put(&pdev->dev, mrv_clk->clk_isp1); + } + if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp1)) { + devm_clk_put(&pdev->dev, mrv_clk->pclkin_isp1); + } + if (CHIP_TYPE == 3399) + pm_runtime_disable(&pdev->dev); + kfree(mrv_clk); + mrv_clk = NULL; + } + + camsys_drm_dma_detach_device(camsys_dev); + iommu_group_remove_device(&camsys_dev->pdev->dev); + iommu_put_dma_cookie(camsys_dev->domain); + iommu_domain_free(camsys_dev->domain); + + return 0; } int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev) { - int err = 0; - camsys_mrv_clk_t *mrv_clk=NULL; - - err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, IRQF_SHARED, CAMSYS_MARVIN_IRQNAME,camsys_dev); - if (err) { - camsys_err("request irq for %s failed",CAMSYS_MARVIN_IRQNAME); - goto end; - } - - //Clk and Iomux init - mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t),GFP_KERNEL); - if (mrv_clk == NULL) { - camsys_err("Allocate camsys_mrv_clk_t failed!"); - err = -EINVAL; - goto clk_failed; - } - if(CHIP_TYPE == 3368){ - mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp"); - mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp"); - mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp"); - mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp"); - mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe"); - mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp"); - mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out"); - mrv_clk->cif_clk_pll = devm_clk_get(&pdev->dev, "clk_cif_pll"); - mrv_clk->pclk_dphyrx = devm_clk_get(&pdev->dev, "pclk_dphyrx"); - mrv_clk->clk_vio0_noc = devm_clk_get(&pdev->dev, "clk_vio0_noc"); - - if (IS_ERR_OR_NULL(mrv_clk->aclk_isp) || IS_ERR_OR_NULL(mrv_clk->hclk_isp) || - IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) || IS_ERR_OR_NULL(mrv_clk->pclkin_isp) || - IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx)|| - IS_ERR_OR_NULL(mrv_clk->pd_isp) || IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) { - camsys_err("Get %s clock resouce failed!\n",miscdev_name); - err = -EINVAL; - goto clk_failed; - } - }else{ - mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp"); - mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp"); - mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp"); - mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp"); - mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe"); - mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp"); - mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out"); - mrv_clk->cif_clk_pll = devm_clk_get(&pdev->dev, "clk_cif_pll"); - mrv_clk->clk_mipi_24m = devm_clk_get(&pdev->dev,"clk_mipi_24m"); - - if (IS_ERR_OR_NULL(mrv_clk->pd_isp) || IS_ERR_OR_NULL(mrv_clk->aclk_isp) || IS_ERR_OR_NULL(mrv_clk->hclk_isp) || - IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) || IS_ERR_OR_NULL(mrv_clk->pclkin_isp) || - IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) { - camsys_err("Get %s clock resouce failed!\n",miscdev_name); - err = -EINVAL; - goto clk_failed; - } - } - clk_set_rate(mrv_clk->isp,210000000); - clk_set_rate(mrv_clk->isp_jpe, 210000000); - - mutex_init(&mrv_clk->lock); - - mrv_clk->in_on = false; - mrv_clk->out_on = 0; - - camsys_dev->clk = (void*)mrv_clk; - camsys_dev->clkin_cb = camsys_mrv_clkin_cb; - camsys_dev->clkout_cb = camsys_mrv_clkout_cb; - camsys_dev->reset_cb = camsys_mrv_reset_cb; - camsys_dev->iomux = camsys_mrv_iomux_cb; - camsys_dev->flash_trigger_cb = camsys_mrv_flash_trigger_cb; - camsys_dev->iommu_cb = camsys_mrv_iommu_cb; - - camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR; - camsys_dev->miscdev.name = miscdev_name; - camsys_dev->miscdev.nodename = miscdev_name; - camsys_dev->miscdev.fops = &camsys_fops; - - err = misc_register(&camsys_dev->miscdev); - if (err < 0) { - camsys_err("misc register %s failed!",miscdev_name); - goto misc_register_failed; - } - - //Variable init - camsys_dev->dev_id = CAMSYS_DEVID_MARVIN; - camsys_dev->platform_remove = camsys_mrv_remove_cb; - - - return 0; -misc_register_failed: - if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) { - misc_deregister(&camsys_dev->miscdev); - } + int err = 0; + camsys_mrv_clk_t *mrv_clk = NULL; + struct resource register_res; + struct iommu_domain *domain; + struct iommu_group *group; + struct device_node *np; + + err = of_address_to_resource(pdev->dev.of_node, 0, ®ister_res); + if (err < 0) { + camsys_err( + "Get register resource from %s platform device failed!", + pdev->name); + } -clk_failed: - if (mrv_clk != NULL) { - if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) { - clk_put(mrv_clk->pd_isp); - } - if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) { - clk_put(mrv_clk->aclk_isp); - } - if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) { - clk_put(mrv_clk->hclk_isp); - } - if (!IS_ERR_OR_NULL(mrv_clk->isp)) { - clk_put(mrv_clk->isp); - } - if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) { - clk_put(mrv_clk->isp_jpe); - } - if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) { - clk_put(mrv_clk->pclkin_isp); - } - if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) { - clk_put(mrv_clk->cif_clk_out); - } - if(CHIP_TYPE == 3368){ - if (!IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx)) { - clk_put(mrv_clk->pclk_dphyrx); - } - if (!IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) { - clk_put(mrv_clk->clk_vio0_noc); + err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, + IRQF_SHARED, CAMSYS_MARVIN_IRQNAME, + camsys_dev); + if (err) { + camsys_err("request irq for %s failed", CAMSYS_MARVIN_IRQNAME); + goto end; + } + + /* Clk and Iomux init */ + mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t), GFP_KERNEL); + if (mrv_clk == NULL) { + camsys_err("Allocate camsys_mrv_clk_t failed!"); + err = -EINVAL; + goto clk_failed; + } + if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) { + /* mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp"); */ + mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp"); + mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp"); + mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp"); + mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe"); + mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp"); + mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out"); + mrv_clk->cif_clk_pll = devm_clk_get(&pdev->dev, "clk_cif_pll"); + mrv_clk->pclk_dphyrx = devm_clk_get(&pdev->dev, "pclk_dphyrx"); + if (CHIP_TYPE == 3368) { + mrv_clk->clk_vio0_noc = + devm_clk_get(&pdev->dev, "clk_vio0_noc"); + if (IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) { + camsys_err("Get %s clock resouce failed!\n", + miscdev_name); + err = -EINVAL; + goto clk_failed; + } + + } + + if (IS_ERR_OR_NULL(mrv_clk->aclk_isp) || + IS_ERR_OR_NULL(mrv_clk->hclk_isp) || + IS_ERR_OR_NULL(mrv_clk->isp) || + IS_ERR_OR_NULL(mrv_clk->isp_jpe) || + IS_ERR_OR_NULL(mrv_clk->pclkin_isp) || + IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || + IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx)) { + camsys_err("Get %s clock resouce failed!\n", + miscdev_name); + err = -EINVAL; + goto clk_failed; + } + + clk_set_rate(mrv_clk->isp, 210000000); + clk_set_rate(mrv_clk->isp_jpe, 210000000); + + } else if (CHIP_TYPE == 3399) { + + pm_runtime_enable(&pdev->dev); + if (register_res.start == 0xff920000) { + mrv_clk->hclk_isp1_noc = + devm_clk_get(&pdev->dev, "hclk_isp1_noc"); + mrv_clk->hclk_isp1_wrapper = + devm_clk_get(&pdev->dev, "hclk_isp1_wrapper"); + mrv_clk->aclk_isp1_noc = + devm_clk_get(&pdev->dev, "aclk_isp1_noc"); + mrv_clk->aclk_isp1_wrapper = + devm_clk_get(&pdev->dev, "aclk_isp1_wrapper"); + mrv_clk->clk_isp1 = + devm_clk_get(&pdev->dev, "clk_isp1"); + mrv_clk->pclkin_isp = + devm_clk_get(&pdev->dev, "pclk_isp1"); + mrv_clk->pclk_dphytxrx = + devm_clk_get(&pdev->dev, "pclk_dphytxrx"); + } else{ + mrv_clk->hclk_isp0_noc = + devm_clk_get(&pdev->dev, "hclk_isp0_noc"); + mrv_clk->hclk_isp0_wrapper = + devm_clk_get(&pdev->dev, "hclk_isp0_wrapper"); + mrv_clk->aclk_isp0_noc = + devm_clk_get(&pdev->dev, "aclk_isp0_noc"); + mrv_clk->aclk_isp0_wrapper = + devm_clk_get(&pdev->dev, "aclk_isp0_wrapper"); + mrv_clk->clk_isp0 = + devm_clk_get(&pdev->dev, "clk_isp0"); + mrv_clk->pclk_dphyrx = + devm_clk_get(&pdev->dev, "pclk_dphyrx"); + } + mrv_clk->cif_clk_out = + devm_clk_get(&pdev->dev, "clk_cif_out"); + mrv_clk->cif_clk_pll = + devm_clk_get(&pdev->dev, "clk_cif_pll"); + mrv_clk->pclk_dphy_ref = + devm_clk_get(&pdev->dev, "pclk_dphy_ref"); + if (register_res.start == 0xff920000) { + if (IS_ERR_OR_NULL(mrv_clk->hclk_isp1_noc) || + IS_ERR_OR_NULL(mrv_clk->hclk_isp1_wrapper) || + IS_ERR_OR_NULL(mrv_clk->aclk_isp1_noc) || + IS_ERR_OR_NULL(mrv_clk->aclk_isp1_wrapper) || + IS_ERR_OR_NULL(mrv_clk->clk_isp1) || + IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || + IS_ERR_OR_NULL(mrv_clk->cif_clk_pll) || + IS_ERR_OR_NULL(mrv_clk->pclkin_isp) || + IS_ERR_OR_NULL(mrv_clk->pclk_dphytxrx)) { + camsys_err("Get %s clock resouce failed!\n", + miscdev_name); + err = -EINVAL; + goto clk_failed; + } + } else{ + if (IS_ERR_OR_NULL(mrv_clk->hclk_isp0_noc) || + IS_ERR_OR_NULL(mrv_clk->hclk_isp0_wrapper) || + IS_ERR_OR_NULL(mrv_clk->aclk_isp0_noc) || + IS_ERR_OR_NULL(mrv_clk->aclk_isp0_wrapper) || + IS_ERR_OR_NULL(mrv_clk->clk_isp0) || + IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || + IS_ERR_OR_NULL(mrv_clk->cif_clk_pll) || + IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx)) { + camsys_err("Get %s clock resouce failed!\n", + miscdev_name); + err = -EINVAL; + goto clk_failed; + } + } + } else{ + mrv_clk->pd_isp = + devm_clk_get(&pdev->dev, "pd_isp"); + mrv_clk->aclk_isp = + devm_clk_get(&pdev->dev, "aclk_isp"); + mrv_clk->hclk_isp = + devm_clk_get(&pdev->dev, "hclk_isp"); + mrv_clk->isp = + devm_clk_get(&pdev->dev, "clk_isp"); + mrv_clk->isp_jpe = + devm_clk_get(&pdev->dev, "clk_isp_jpe"); + mrv_clk->pclkin_isp = + devm_clk_get(&pdev->dev, "pclkin_isp"); + mrv_clk->cif_clk_out = + devm_clk_get(&pdev->dev, "clk_cif_out"); + mrv_clk->cif_clk_pll = + devm_clk_get(&pdev->dev, "clk_cif_pll"); + mrv_clk->clk_mipi_24m = + devm_clk_get(&pdev->dev, "clk_mipi_24m"); + + if (IS_ERR_OR_NULL(mrv_clk->pd_isp) || + IS_ERR_OR_NULL(mrv_clk->aclk_isp) || + IS_ERR_OR_NULL(mrv_clk->hclk_isp) || + IS_ERR_OR_NULL(mrv_clk->isp) || + IS_ERR_OR_NULL(mrv_clk->isp_jpe) || + IS_ERR_OR_NULL(mrv_clk->pclkin_isp) || + IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || + IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) { + camsys_err("Get %s clock resouce failed!\n", + miscdev_name); + err = -EINVAL; + goto clk_failed; + } + + clk_set_rate(mrv_clk->isp, 210000000); + clk_set_rate(mrv_clk->isp_jpe, 210000000); + } + + + mutex_init(&mrv_clk->lock); + + mrv_clk->in_on = false; + mrv_clk->out_on = 0; + + np = of_find_node_by_name(NULL, "isp0_mmu"); + if (!np) { + int index = 0; + /* iommu domain */ + domain = iommu_domain_alloc(&platform_bus_type); + if (!domain) + goto clk_failed; + + err = iommu_get_dma_cookie(domain); + if (err) + goto err_free_domain; + + group = iommu_group_get(&pdev->dev); + if (!group) { + group = iommu_group_alloc(); + if (IS_ERR(group)) { + dev_err(&pdev->dev, "Failed to allocate IOMMU group\n"); + goto err_put_cookie; + } + + err = iommu_group_add_device(group, &pdev->dev); + iommu_group_put(group); + if (err) { + dev_err(&pdev->dev, "failed to add device to IOMMU group\n"); + goto err_put_cookie; + } } + camsys_dev->domain = domain; + camsys_dev->dma_buf_cnt = 0; + camsys_dev->iommu_cb = camsys_mrv_drm_iommu_cb; + for (index = 0; index < CAMSYS_DMA_BUF_MAX_NUM; index++) + camsys_dev->dma_buf[index].fd = -1; + } else { + camsys_dev->iommu_cb = camsys_mrv_iommu_cb; + } + + camsys_dev->clk = (void *)mrv_clk; + camsys_dev->clkin_cb = camsys_mrv_clkin_cb; + camsys_dev->clkout_cb = camsys_mrv_clkout_cb; + camsys_dev->reset_cb = camsys_mrv_reset_cb; + camsys_dev->iomux = camsys_mrv_iomux_cb; + camsys_dev->flash_trigger_cb = camsys_mrv_flash_trigger_cb; + + camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR; + camsys_dev->miscdev.name = miscdev_name; + camsys_dev->miscdev.nodename = miscdev_name; + camsys_dev->miscdev.fops = &camsys_fops; + + if (CHIP_TYPE == 3399) { + if (register_res.start == 0xff920000) { + camsys_dev->miscdev.name = "camsys_marvin1"; + camsys_dev->miscdev.nodename = "camsys_marvin1"; } + } + + err = misc_register(&camsys_dev->miscdev); + if (err < 0) { + camsys_err("misc register %s failed!", miscdev_name); + goto misc_register_failed; + } + /* Variable init */ + camsys_dev->dev_id = CAMSYS_DEVID_MARVIN; + camsys_dev->platform_remove = camsys_mrv_remove_cb; + + return 0; +misc_register_failed: + if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) + misc_deregister(&camsys_dev->miscdev); +err_put_cookie: + iommu_put_dma_cookie(domain); +err_free_domain: + iommu_domain_free(domain); +clk_failed: + if (mrv_clk != NULL) { + if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) + clk_put(mrv_clk->pd_isp); + + if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) + clk_put(mrv_clk->aclk_isp); + + if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) + clk_put(mrv_clk->hclk_isp); + + if (!IS_ERR_OR_NULL(mrv_clk->isp)) + clk_put(mrv_clk->isp); + + if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) + clk_put(mrv_clk->isp_jpe); + + if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) + clk_put(mrv_clk->pclkin_isp); + + if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) + clk_put(mrv_clk->cif_clk_out); + + if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366) { + if (!IS_ERR_OR_NULL(mrv_clk->pclk_dphyrx)) + clk_put(mrv_clk->pclk_dphyrx); + + if (!IS_ERR_OR_NULL(mrv_clk->clk_vio0_noc)) + clk_put(mrv_clk->clk_vio0_noc); + } + + kfree(mrv_clk); + mrv_clk = NULL; + } - kfree(mrv_clk); - mrv_clk = NULL; - } - end: - return err; + return err; } EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);