uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file_p, struct ion_handle **ionhandle) { unsigned long paddr; unsigned long size; int rc; *ionhandle = ion_import_dma_buf(gemini_client, fd); if (IS_ERR_OR_NULL(*ionhandle)) return 0; rc = ion_map_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL, SZ_4K, 0, &paddr, (unsigned long *)&size, 0, 0); if (rc < 0) { GMN_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd, rc); goto error1; } /* validate user input */ if (len > size) { GMN_PR_ERR("%s: invalid offset + len\n", __func__); goto error1; } return paddr; error1: ion_free(gemini_client, *ionhandle); return 0; }
uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file_p) { unsigned long paddr; unsigned long size; int rc; #ifdef CONFIG_ANDROID_PMEM unsigned long kvstart; rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p); #else rc = 0; paddr = 0; size = 0; #endif if (rc < 0) { GMN_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd, rc); return 0; } /* validate user input */ if (len > size) { GMN_PR_ERR("%s: invalid offset + len\n", __func__); return 0; } return paddr; }
int msm_gemini_hw_exec_cmds(struct msm_gemini_hw_cmd *hw_cmd_p, uint32_t m_cmds) { int is_copy_to_user = -1; uint32_t data; while (m_cmds--) { if (hw_cmd_p->offset > gemini_region_size) { GMN_PR_ERR("%s:%d] %d exceed hw region %d\n", __func__, __LINE__, hw_cmd_p->offset, gemini_region_size); return -EFAULT; } switch (hw_cmd_p->type) { case MSM_GEMINI_HW_CMD_TYPE_READ: hw_cmd_p->data = msm_gemini_hw_read(hw_cmd_p); is_copy_to_user = 1; break; case MSM_GEMINI_HW_CMD_TYPE_WRITE: msm_gemini_hw_write(hw_cmd_p); break; case MSM_GEMINI_HW_CMD_TYPE_WRITE_OR: data = msm_gemini_hw_read(hw_cmd_p); hw_cmd_p->data = (hw_cmd_p->data & hw_cmd_p->mask) | data; msm_gemini_hw_write(hw_cmd_p); break; case MSM_GEMINI_HW_CMD_TYPE_UWAIT: msm_gemini_hw_wait(hw_cmd_p, 1); break; case MSM_GEMINI_HW_CMD_TYPE_MWAIT: msm_gemini_hw_wait(hw_cmd_p, 1000); break; case MSM_GEMINI_HW_CMD_TYPE_UDELAY: msm_gemini_hw_delay(hw_cmd_p, 1); break; case MSM_GEMINI_HW_CMD_TYPE_MDELAY: msm_gemini_hw_delay(hw_cmd_p, 1000); break; default: GMN_PR_ERR("wrong hw command type\n"); break; } hw_cmd_p++; } return is_copy_to_user; }
int msm_gemini_hw_pingpong_update(struct msm_gemini_hw_pingpong *pingpong_hw, struct msm_gemini_hw_buf *buf) { int buf_free_index = -1; if (!pingpong_hw->buf_status[0]) { buf_free_index = 0; } else if (!pingpong_hw->buf_status[1]) { buf_free_index = 1; } else { GMN_PR_ERR("%s:%d: pingpong buffer busy\n", __func__, __LINE__); return -1; } pingpong_hw->buf[buf_free_index] = *buf; pingpong_hw->buf_status[buf_free_index] = 1; if (pingpong_hw->is_fe) { /* it is fe */ msm_gemini_hw_fe_buffer_update( &pingpong_hw->buf[buf_free_index], buf_free_index); } else { /* it is we */ msm_gemini_hw_we_buffer_update( &pingpong_hw->buf[buf_free_index], buf_free_index); } return 0; }
void msm_gemini_hw_region_dump(uint32_t size) { uint32_t *p; uint8_t *p8; if (size > gemini_region_size) { GMN_PR_ERR("%s:%d] wrong region dump size\n", __func__, __LINE__); return; } if (!gemini_region_base) { GMN_PR_ERR("%s:%d] gemini region not setup yet\n", __func__, __LINE__); return; } p = (uint32_t *) gemini_region_base; while (size >= 16) { GMN_DBG("0x%08X] %08X %08X %08X %08X\n", gemini_region_size - size, readl(p), readl(p+1), readl(p+2), readl(p+3)); p += 4; size -= 16; } if (size > 0) { uint32_t d; GMN_DBG("0x%08X] ", gemini_region_size - size); while (size >= 4) { GMN_DBG("%08X ", readl(p++)); size -= 4; } d = readl(p); p8 = (uint8_t *) &d; while (size) { GMN_DBG("%02X", *p8++); size--; } GMN_DBG("\n"); } }
uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file_p, struct ion_handle **ionhandle) { unsigned long paddr; unsigned long size; int rc; #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION *ionhandle = ion_import_dma_buf(gemini_client, fd); if (IS_ERR_OR_NULL(*ionhandle)) return 0; rc = ion_map_iommu(gemini_client, *ionhandle, CAMERA_DOMAIN, GEN_POOL, SZ_4K, 0, &paddr, (unsigned long *)&size, 0, 0); #elif CONFIG_ANDROID_PMEM unsigned long kvstart; rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p); #else rc = 0; paddr = 0; size = 0; #endif if (rc < 0) { GMN_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd, rc); goto error1; } /* validate user input */ if (len > size) { GMN_PR_ERR("%s: invalid offset + len\n", __func__); goto error1; } return paddr; error1: #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION ion_free(gemini_client, *ionhandle); #endif return 0; }
uint32_t msm_gemini_platform_v2p(int fd, uint32_t len, struct file **file_p, struct msm_mapped_buffer **msm_buffer, int *subsys_id) { unsigned long paddr; unsigned long size; int rc; int flags; #ifdef CONFIG_ANDROID_PMEM unsigned long kvstart; rc = get_pmem_file(fd, &paddr, &kvstart, &size, file_p); #else rc = 0; paddr = 0; size = 0; #endif if (rc < 0) { GMN_PR_ERR("%s: get_pmem_file fd %d error %d\n", __func__, fd, rc); return 0; } /* validate user input */ if (len > size) { GMN_PR_ERR("%s: invalid offset + len\n", __func__); return 0; } flags = MSM_SUBSYSTEM_MAP_IOVA; *subsys_id = MSM_SUBSYSTEM_CAMERA; *msm_buffer = msm_subsystem_map_buffer(paddr, size, flags, subsys_id, 1); if (IS_ERR((void *)*msm_buffer)) { pr_err("%s: msm_subsystem_map_buffer failed\n", __func__); return 0; } paddr = ((struct msm_mapped_buffer *)*msm_buffer)->iova[0]; return paddr; }
int msm_gemini_platform_clk_enable(void) { /* MP*fps*(1 + %blanking) 2MP: 24MHz ------ 2 x 10 x 1.2 3MP: 36MHz ------ 3 x 10 x 1.2 5MP: 60MHz ------ 5 x 10 x 1.2 8MP: 96MHz ------ 8 x 10 x 1.2 12MP: 144MHz ------12 x 10 x 1.2 */ int rc = -1; u32 rate = 144000000; if (jpeg_clk == NULL) { jpeg_clk = clk_get(NULL, "jpeg_clk"); if (jpeg_clk == NULL) { GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); goto fail; } } rc = clk_set_min_rate(jpeg_clk, rate); if (rc) { GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); goto fail; } rc = clk_enable(jpeg_clk); if (rc) { GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); goto fail; } if (jpeg_pclk == NULL) { jpeg_pclk = clk_get(NULL, "jpeg_pclk"); if (jpeg_pclk == NULL) { GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); goto fail; } } rc = clk_enable(jpeg_pclk); if (rc) { GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); goto fail; } /* Need to add PM QOS bus requirement once updated */ GMN_DBG("%s:%d]\n", __func__, __LINE__); return rc; fail: GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); return rc; }
int msm_gemini_platform_init(struct platform_device *pdev, struct resource **mem, void **base, int *irq, irqreturn_t (*handler) (int, void *), void *context) { int rc = -1; int gemini_irq; struct resource *gemini_mem, *gemini_io, *gemini_irq_res; void *gemini_base; gemini_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!gemini_mem) { GMN_PR_ERR("%s: no mem resource?\n", __func__); return -ENODEV; } gemini_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!gemini_irq_res) { GMN_PR_ERR("no irq resource?\n"); return -ENODEV; } gemini_irq = gemini_irq_res->start; gemini_io = request_mem_region(gemini_mem->start, resource_size(gemini_mem), pdev->name); if (!gemini_io) { GMN_PR_ERR("%s: region already claimed\n", __func__); return -EBUSY; } gemini_base = ioremap(gemini_mem->start, resource_size(gemini_mem)); if (!gemini_base) { rc = -ENOMEM; GMN_PR_ERR("%s: ioremap failed\n", __func__); goto fail1; } rc = msm_camio_jpeg_clk_enable(); if (rc) { GMN_PR_ERR("%s: clk failed rc = %d\n", __func__, rc); goto fail2; } msm_gemini_hw_init(gemini_base, resource_size(gemini_mem)); rc = request_irq(gemini_irq, handler, IRQF_TRIGGER_RISING, "gemini", context); if (rc) { GMN_PR_ERR("%s: request_irq failed, %d, JPEG = %d\n", __func__, gemini_irq, INT_JPEG); goto fail3; } *mem = gemini_mem; *base = gemini_base; *irq = gemini_irq; GMN_DBG("%s:%d] success\n", __func__, __LINE__); return rc; fail3: msm_camio_jpeg_clk_disable(); fail2: iounmap(gemini_base); fail1: release_mem_region(gemini_mem->start, resource_size(gemini_mem)); GMN_DBG("%s:%d] fail\n", __func__, __LINE__); return rc; }
static int msm_gemini_init(struct platform_device *pdev) { int rc = -1; struct device *dev; GMN_DBG("%s:%d]\n", __func__, __LINE__); msm_gemini_device_p = __msm_gemini_init(pdev); if (msm_gemini_device_p == NULL) { GMN_PR_ERR("%s: initialization failed\n", __func__); goto fail; } rc = alloc_chrdev_region(&msm_gemini_devno, 0, 1, MSM_GEMINI_NAME); if (rc < 0) { GMN_PR_ERR("%s: failed to allocate chrdev\n", __func__); goto fail_1; } if (!msm_gemini_class) { msm_gemini_class = class_create(THIS_MODULE, MSM_GEMINI_NAME); if (IS_ERR(msm_gemini_class)) { rc = PTR_ERR(msm_gemini_class); GMN_PR_ERR("%s: create device class failed\n", __func__); goto fail_2; } } dev = device_create(msm_gemini_class, NULL, MKDEV(MAJOR(msm_gemini_devno), MINOR(msm_gemini_devno)), NULL, "%s%d", MSM_GEMINI_NAME, 0); if (IS_ERR(dev)) { GMN_PR_ERR("%s: error creating device\n", __func__); rc = -ENODEV; goto fail_3; } cdev_init(&msm_gemini_device_p->cdev, &msm_gemini_fops); msm_gemini_device_p->cdev.owner = THIS_MODULE; msm_gemini_device_p->cdev.ops = (const struct file_operations *) &msm_gemini_fops; rc = cdev_add(&msm_gemini_device_p->cdev, msm_gemini_devno, 1); if (rc < 0) { GMN_PR_ERR("%s: error adding cdev\n", __func__); rc = -ENODEV; goto fail_4; } pr_info("[CAM] %s %s: success\n", __func__, MSM_GEMINI_NAME); return rc; fail_4: device_destroy(msm_gemini_class, msm_gemini_devno); fail_3: class_destroy(msm_gemini_class); fail_2: unregister_chrdev_region(msm_gemini_devno, 1); fail_1: __msm_gemini_exit(msm_gemini_device_p); fail: return rc; }
int msm_gemini_platform_init(struct platform_device *pdev, struct resource **mem, void **base, int *irq, irqreturn_t (*handler) (int, void *), void *context) { int rc = -1; int gemini_irq; struct resource *gemini_mem, *gemini_io, *gemini_irq_res; void *gemini_base; struct msm_gemini_device *pgmn_dev = (struct msm_gemini_device *) context; gemini_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!gemini_mem) { GMN_PR_ERR("%s: no mem resource?\n", __func__); return -ENODEV; } gemini_irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!gemini_irq_res) { GMN_PR_ERR("no irq resource?\n"); return -ENODEV; } gemini_irq = gemini_irq_res->start; gemini_io = request_mem_region(gemini_mem->start, resource_size(gemini_mem), pdev->name); if (!gemini_io) { GMN_PR_ERR("%s: region already claimed\n", __func__); return -EBUSY; } gemini_base = ioremap(gemini_mem->start, resource_size(gemini_mem)); if (!gemini_base) { rc = -ENOMEM; GMN_PR_ERR("%s: ioremap failed\n", __func__); goto fail1; } pgmn_dev->hw_version = GEMINI_8X60; rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_8x_clk_info, pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_8x_clk_info), 1); if (rc < 0) { pgmn_dev->hw_version = GEMINI_7X; rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_7x_clk_info, pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_7x_clk_info), 1); if (rc < 0) { GMN_PR_ERR("%s: clk failed rc = %d\n", __func__, rc); goto fail2; } } else { rc = msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_imem_clk_info, &pgmn_dev->gemini_clk[2], ARRAY_SIZE(gemini_imem_clk_info), 1); if (!rc) pgmn_dev->hw_version = GEMINI_8960; } if (pgmn_dev->hw_version != GEMINI_7X) { if (pgmn_dev->gemini_fs == NULL) { pgmn_dev->gemini_fs = regulator_get(&pgmn_dev->pdev->dev, "vdd"); if (IS_ERR(pgmn_dev->gemini_fs)) { pr_err("%s: Regulator FS_ijpeg get failed %ld\n", __func__, PTR_ERR(pgmn_dev->gemini_fs)); pgmn_dev->gemini_fs = NULL; goto gemini_fs_failed; } else if (regulator_enable(pgmn_dev->gemini_fs)) { pr_err("%s: Regulator FS_ijpeg enable failed\n", __func__); regulator_put(pgmn_dev->gemini_fs); pgmn_dev->gemini_fs = NULL; goto gemini_fs_failed; } } } msm_gemini_hw_init(gemini_base, resource_size(gemini_mem)); rc = request_irq(gemini_irq, handler, IRQF_TRIGGER_RISING, "gemini", context); if (rc) { GMN_PR_ERR("%s: request_irq failed, %d\n", __func__, gemini_irq); goto fail3; } *mem = gemini_mem; *base = gemini_base; *irq = gemini_irq; #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION gemini_client = msm_ion_client_create(-1, "camera/gemini"); #endif GMN_DBG("%s:%d] success\n", __func__, __LINE__); return rc; fail3: if (pgmn_dev->hw_version != GEMINI_7X) { regulator_disable(pgmn_dev->gemini_fs); regulator_put(pgmn_dev->gemini_fs); pgmn_dev->gemini_fs = NULL; } gemini_fs_failed: if (pgmn_dev->hw_version == GEMINI_8960) msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_imem_clk_info, &pgmn_dev->gemini_clk[2], ARRAY_SIZE(gemini_imem_clk_info), 0); if (pgmn_dev->hw_version != GEMINI_7X) msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_8x_clk_info, pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_8x_clk_info), 0); else msm_cam_clk_enable(&pgmn_dev->pdev->dev, gemini_7x_clk_info, pgmn_dev->gemini_clk, ARRAY_SIZE(gemini_7x_clk_info), 0); fail2: iounmap(gemini_base); fail1: release_mem_region(gemini_mem->start, resource_size(gemini_mem)); GMN_DBG("%s:%d] fail\n", __func__, __LINE__); return rc; }
void *msm_gemini_core_err_irq(int gemini_irq_status, void *context) { GMN_PR_ERR("%s:%d]\n", __func__, gemini_irq_status); return NULL; }
int msm_gemini_platform_clk_enable(void) { /* MP*fps*(1 + %blanking) 2MP: 24MHz ------ 2 x 10 x 1.2 3MP: 36MHz ------ 3 x 10 x 1.2 5MP: 60MHz ------ 5 x 10 x 1.2 8MP: 96MHz ------ 8 x 10 x 1.2 12MP: 144MHz ------12 x 10 x 1.2 */ int rc = -1; u32 rate = 144000000; if (jpeg_clk == NULL) { jpeg_clk = clk_get(NULL, "jpeg_clk"); if (jpeg_clk == NULL) { GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); goto fail; } } rc = clk_set_min_rate(jpeg_clk, rate); if (rc) { GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); goto fail; } rc = clk_enable(jpeg_clk); if (rc) { GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); goto fail; } if (jpeg_pclk == NULL) { jpeg_pclk = clk_get(NULL, "jpeg_pclk"); if (jpeg_pclk == NULL) { GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); goto fail; } } rc = clk_enable(jpeg_pclk); if (rc) { GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); goto fail; } rc = pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ, "msm_gemini", MSM_SYSTEM_BUS_RATE); if (rc) { GMN_PR_ERR("request AXI bus QOS fails. rc = %d\n", rc); goto fail; } GMN_DBG("%s:%d]\n", __func__, __LINE__); return rc; fail: GMN_PR_ERR("%s:%d] fail rc = %d\n", __func__, __LINE__, rc); return rc; }