/* Allocate temporary buffers for decoding */ int s5p_mfc_alloc_dec_temp_buffers(struct s5p_mfc_ctx *ctx) { void *desc_virt; struct s5p_mfc_dev *dev = ctx->dev; ctx->desc_buf = vb2_dma_contig_memops.alloc( dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], DESC_BUF_SIZE); if (IS_ERR_VALUE((int)ctx->desc_buf)) { ctx->desc_buf = NULL; mfc_err("Allocating DESC buffer failed\n"); return -ENOMEM; } ctx->desc_phys = s5p_mfc_mem_cookie( dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], ctx->desc_buf); BUG_ON(ctx->desc_phys & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); desc_virt = vb2_dma_contig_memops.vaddr(ctx->desc_buf); if (desc_virt == NULL) { vb2_dma_contig_memops.put(ctx->desc_buf); ctx->desc_phys = 0; ctx->desc_buf = NULL; mfc_err("Remapping DESC buffer failed\n"); return -ENOMEM; } memset(desc_virt, 0, DESC_BUF_SIZE); wmb(); return 0; }
int s5p_mfc_init_shm(struct s5p_mfc_ctx *ctx) { struct s5p_mfc_dev *dev = ctx->dev; void *shm_alloc_ctx = dev->alloc_ctx[MFC_BANK1_ALLOC_CTX]; ctx->shm_alloc = vb2_dma_contig_memops.alloc(shm_alloc_ctx, SHARED_BUF_SIZE); if (IS_ERR(ctx->shm_alloc)) { mfc_err("failed to allocate shared memory\n"); return PTR_ERR(ctx->shm_alloc); } /* */ ctx->shm_ofs = s5p_mfc_mem_cookie(shm_alloc_ctx, ctx->shm_alloc) - dev->bank1; BUG_ON(ctx->shm_ofs & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); ctx->shm = vb2_dma_contig_memops.vaddr(ctx->shm_alloc); if (!ctx->shm) { vb2_dma_contig_memops.put(ctx->shm_alloc); ctx->shm_ofs = 0; ctx->shm_alloc = NULL; mfc_err("failed to virt addr of shared memory\n"); return -ENOMEM; } memset((void *)ctx->shm, 0, SHARED_BUF_SIZE); wmb(); return 0; }
/* Allocate firmware */ int s5p_mfc_alloc_firmware(struct s5p_mfc_dev *dev) { #if defined(CONFIG_S5P_MFC_VB2_CMA) int err; struct cma_info mem_info_f, mem_info_a, mem_info_b; #endif unsigned int base_align = dev->variant->buf_align->mfc_base_align; unsigned int firmware_size = dev->variant->buf_size->firmware_code; mfc_debug_enter(); #if !defined(CONFIG_S5P_MFC_VB2_ION) if (s5p_mfc_bitproc_buf) { mfc_err("Attempting to allocate firmware when it seems that it is already loaded.\n"); return -ENOMEM; } #else if (s5p_mfc_bitproc_buf) return 0; #endif /* Get memory region information and check if it is correct */ #if defined(CONFIG_S5P_MFC_VB2_CMA) err = cma_info(&mem_info_f, dev->v4l2_dev.dev, MFC_CMA_FW); mfc_debug(3, "Area \"%s\" is from %08x to %08x and has size %08x", "f", mem_info_f.lower_bound, mem_info_f.upper_bound, mem_info_f.total_size); if (err) { mfc_err("Couldn't get memory information from CMA.\n"); return -EINVAL; } err = cma_info(&mem_info_a, dev->v4l2_dev.dev, MFC_CMA_BANK1); mfc_debug(3, "Area \"%s\" is from %08x to %08x and has size %08x", "a", mem_info_a.lower_bound, mem_info_a.upper_bound, mem_info_a.total_size); if (err) { mfc_err("Couldn't get memory information from CMA.\n"); return -EINVAL; } if (mem_info_f.upper_bound > mem_info_a.lower_bound) { mfc_err("Firmware has to be " "allocated before memory for buffers (bank A).\n"); return -EINVAL; } mfc_debug(2, "Allocating memory for firmware.\n"); s5p_mfc_bitproc_buf = s5p_mfc_mem_alloc( dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], firmware_size); if (IS_ERR(s5p_mfc_bitproc_buf)) { s5p_mfc_bitproc_buf = 0; printk(KERN_ERR "Allocating bitprocessor buffer failed\n"); return -ENOMEM; } s5p_mfc_bitproc_phys = s5p_mfc_mem_cookie( dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); if (s5p_mfc_bitproc_phys & ((1 << base_align) - 1)) { mfc_err("The base memory is not aligned to %dBytes.\n", (1 << base_align)); s5p_mfc_mem_put(dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); s5p_mfc_bitproc_phys = 0; s5p_mfc_bitproc_buf = 0; return -EIO; } dev->port_a = s5p_mfc_bitproc_phys; s5p_mfc_bitproc_virt = s5p_mfc_mem_vaddr( dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); mfc_debug(2, "Virtual address for FW: %08lx\n", (long unsigned int)s5p_mfc_bitproc_virt); if (!s5p_mfc_bitproc_virt) { mfc_err("Bitprocessor memory remap failed\n"); s5p_mfc_mem_put(dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); s5p_mfc_bitproc_phys = 0; s5p_mfc_bitproc_buf = 0; return -EIO; } if (HAS_PORTNUM(dev) && IS_TWOPORT(dev)) { err = cma_info(&mem_info_b, dev->v4l2_dev.dev, MFC_CMA_BANK2); mfc_debug(3, "Area \"%s\" is from %08x to %08x and has size %08x", "b", mem_info_b.lower_bound, mem_info_b.upper_bound, mem_info_b.total_size); if (err) { mfc_err("Couldn't get memory information from CMA.\n"); return -EINVAL; } dev->port_b = mem_info_b.lower_bound; mfc_debug(2, "Port A: %08x Port B: %08x (FW: %08x size: %08x)\n", dev->port_a, dev->port_b, s5p_mfc_bitproc_phys, firmware_size); } else { mfc_debug(2, "Port : %08x (FW: %08x size: %08x)\n", dev->port_a, s5p_mfc_bitproc_phys, firmware_size); } #elif defined(CONFIG_S5P_MFC_VB2_SDVMM) mfc_debug(2, "Allocating memory for firmware.\n"); s5p_mfc_bitproc_buf = s5p_mfc_mem_alloc( dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], firmware_size); if (IS_ERR(s5p_mfc_bitproc_buf)) { s5p_mfc_bitproc_buf = 0; printk(KERN_ERR "Allocating bitprocessor buffer failed\n"); return -ENOMEM; } s5p_mfc_bitproc_phys = s5p_mfc_mem_cookie( dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); if (s5p_mfc_bitproc_phys & ((1 << base_align) - 1)) { mfc_err("The base memory is not aligned to %dBytes.\n", (1 << base_align)); s5p_mfc_mem_put(dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); s5p_mfc_bitproc_phys = 0; s5p_mfc_bitproc_buf = 0; return -EIO; } s5p_mfc_bitproc_virt = s5p_mfc_mem_vaddr( dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); mfc_debug(2, "Virtual address for FW: %08lx\n", (long unsigned int)s5p_mfc_bitproc_virt); if (!s5p_mfc_bitproc_virt) { mfc_err("Bitprocessor memory remap failed\n"); s5p_mfc_mem_put(dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); s5p_mfc_bitproc_phys = 0; s5p_mfc_bitproc_buf = 0; return -EIO; } dev->port_a = s5p_mfc_bitproc_phys; dev->port_b = s5p_mfc_bitproc_phys; mfc_debug(2, "Port A: %08x Port B: %08x (FW: %08x size: %08x)\n", dev->port_a, dev->port_b, s5p_mfc_bitproc_phys, firmware_size); #elif defined(CONFIG_S5P_MFC_VB2_ION) mfc_debug(2, "Allocating memory for firmware.\n"); s5p_mfc_bitproc_buf = s5p_mfc_mem_alloc( dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], firmware_size); if (IS_ERR(s5p_mfc_bitproc_buf)) { s5p_mfc_bitproc_buf = 0; printk(KERN_ERR "Allocating bitprocessor buffer failed\n"); return -ENOMEM; } s5p_mfc_bitproc_phys = s5p_mfc_mem_cookie( dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); if (s5p_mfc_bitproc_phys & ((1 << base_align) - 1)) { mfc_err("The base memory is not aligned to %dBytes.\n", (1 << base_align)); s5p_mfc_mem_put(dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); s5p_mfc_bitproc_phys = 0; s5p_mfc_bitproc_buf = 0; return -EIO; } s5p_mfc_bitproc_virt = s5p_mfc_mem_vaddr( dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); mfc_debug(2, "Virtual address for FW: %08lx\n", (long unsigned int)s5p_mfc_bitproc_virt); if (!s5p_mfc_bitproc_virt) { mfc_err("Bitprocessor memory remap failed\n"); s5p_mfc_mem_put(dev->alloc_ctx[MFC_CMA_FW_ALLOC_CTX], s5p_mfc_bitproc_buf); s5p_mfc_bitproc_phys = 0; s5p_mfc_bitproc_buf = 0; return -EIO; } dev->port_a = s5p_mfc_bitproc_phys; dev->port_b = s5p_mfc_bitproc_phys; mfc_debug(2, "Port A: %08x Port B: %08x (FW: %08x size: %08x)\n", dev->port_a, dev->port_b, s5p_mfc_bitproc_phys, firmware_size); #endif mfc_debug_leave(); return 0; }
int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev) { struct firmware *fw_blob; size_t bank2_base_phys; void *b_base; int err; mfc_debug_enter(); err = request_firmware((const struct firmware **)&fw_blob, "s5p-mfc.fw", dev->v4l2_dev.dev); if (err != 0) { mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); return -EINVAL; } dev->fw_size = ALIGN(fw_blob->size, FIRMWARE_ALIGN); if (s5p_mfc_bitproc_buf) { mfc_err("Attempting to allocate firmware when it seems that it is already loaded\n"); release_firmware(fw_blob); return -ENOMEM; } s5p_mfc_bitproc_buf = vb2_dma_contig_memops.alloc( dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], dev->fw_size); if (IS_ERR(s5p_mfc_bitproc_buf)) { s5p_mfc_bitproc_buf = 0; mfc_err("Allocating bitprocessor buffer failed\n"); release_firmware(fw_blob); return -ENOMEM; } s5p_mfc_bitproc_phys = s5p_mfc_mem_cookie( dev->alloc_ctx[MFC_BANK1_ALLOC_CTX], s5p_mfc_bitproc_buf); if (s5p_mfc_bitproc_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) { mfc_err("The base memory for bank 1 is not aligned to 128KB\n"); vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf); s5p_mfc_bitproc_phys = 0; s5p_mfc_bitproc_buf = 0; release_firmware(fw_blob); return -EIO; } s5p_mfc_bitproc_virt = vb2_dma_contig_memops.vaddr(s5p_mfc_bitproc_buf); if (!s5p_mfc_bitproc_virt) { mfc_err("Bitprocessor memory remap failed\n"); vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf); s5p_mfc_bitproc_phys = 0; s5p_mfc_bitproc_buf = 0; release_firmware(fw_blob); return -EIO; } dev->bank1 = s5p_mfc_bitproc_phys; b_base = vb2_dma_contig_memops.alloc( dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], 1 << MFC_BANK2_ALIGN_ORDER); if (IS_ERR(b_base)) { vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf); s5p_mfc_bitproc_phys = 0; s5p_mfc_bitproc_buf = 0; mfc_err("Allocating bank2 base failed\n"); release_firmware(fw_blob); return -ENOMEM; } bank2_base_phys = s5p_mfc_mem_cookie( dev->alloc_ctx[MFC_BANK2_ALLOC_CTX], b_base); vb2_dma_contig_memops.put(b_base); if (bank2_base_phys & ((1 << MFC_BASE_ALIGN_ORDER) - 1)) { mfc_err("The base memory for bank 2 is not aligned to 128KB\n"); vb2_dma_contig_memops.put(s5p_mfc_bitproc_buf); s5p_mfc_bitproc_phys = 0; s5p_mfc_bitproc_buf = 0; release_firmware(fw_blob); return -EIO; } dev->bank2 = bank2_base_phys; memcpy(s5p_mfc_bitproc_virt, fw_blob->data, fw_blob->size); wmb(); release_firmware(fw_blob); mfc_debug_leave(); return 0; }