X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Frk_camsys%2Fcamsys_marvin.c;h=c6a61d8b7317e048aa638fc52e55f08a34a4f932;hb=651397146e4137ab694eb74d6852b97a69fda3cf;hp=74493356fb4706c3476c9af7aaf232c42a205ee6;hpb=ee25a425b912bea6f9a14e566a7ab9b90ea95d08;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/media/video/rk_camsys/camsys_marvin.c b/drivers/media/video/rk_camsys/camsys_marvin.c index 74493356fb47..c6a61d8b7317 100755 --- a/drivers/media/video/rk_camsys/camsys_marvin.c +++ b/drivers/media/video/rk_camsys/camsys_marvin.c @@ -4,6 +4,8 @@ #include #include +#include +#include extern int rockchip_set_system_status(unsigned long status); extern int rockchip_clear_system_status(unsigned long status); @@ -68,6 +70,18 @@ static int camsys_mrv_iomux_cb(camsys_extdev_t *extdev,void *ptr) } 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"); } @@ -122,7 +136,8 @@ static int camsys_mrv_flash_trigger_cb(void *ptr,unsigned int on) 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); @@ -148,9 +163,15 @@ static int camsys_mrv_flash_trigger_cb(void *ptr,unsigned int on) 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, 1); - } - + //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); @@ -173,8 +194,105 @@ static int camsys_mrv_flash_trigger_cb(void *ptr,unsigned int on) } return retval; } +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 ; + + dn = of_find_compatible_node(NULL,NULL,compt); + if(!dn) + { + printk("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; + } + ret = &pd->dev; + + return ret; + +} +#ifdef CONFIG_IOMMU_API +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) +{ +} +#endif + + +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); + } +iommu_end: + return ret; +} static int camsys_mrv_reset_cb(void *ptr,unsigned int on) { camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr; @@ -199,10 +317,20 @@ 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 (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->aclk_isp); clk_prepare_enable(clk->hclk_isp); clk_prepare_enable(clk->isp); @@ -213,7 +341,7 @@ static int camsys_mrv_clkin_cb(void *ptr, unsigned int on) clk->in_on = true; - camsys_trace(1, "%s clock in turn on",dev_name(camsys_dev->miscdev.this_device)); + 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); @@ -235,7 +363,6 @@ static int camsys_mrv_clkin_cb(void *ptr, unsigned int on) return 0; } - static int camsys_mrv_clkout_cb(void *ptr, unsigned int on,unsigned int inclk) { camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr; @@ -272,15 +399,32 @@ 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; + 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)); - mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_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)); + } + +#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(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_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)) { @@ -305,6 +449,18 @@ static irqreturn_t camsys_mrv_irq(int irq, void *data) 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); @@ -377,7 +533,7 @@ 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, 0, CAMSYS_MARVIN_IRQNAME,camsys_dev); + 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; @@ -423,6 +579,7 @@ int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev) 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;