static void fthd_buffer_cleanup(struct vb2_buffer *vb) { struct fthd_private *dev_priv = vb2_get_drv_priv(vb->vb2_queue); struct h2t_buf_ctx *ctx = NULL; int i; pr_debug("%p\n", vb); for(i = 0; i < FTHD_BUFFERS; i++) { if (dev_priv->h2t_bufs[i].vb == vb) { ctx = dev_priv->h2t_bufs + i; break; }; } if (!ctx || ctx->state == BUF_FREE) return; ctx->state = BUF_FREE; ctx->vb = NULL; isp_mem_destroy(ctx->dma_desc_obj); for(i = 0; i < dev_priv->fmt.planes; i++) { iommu_free(dev_priv, ctx->plane[i]); ctx->plane[i] = NULL; } ctx->dma_desc_obj = NULL; }
int isp_uninit(struct fthd_private *dev_priv) { FTHD_ISP_REG_WRITE(0x00000000, 0x40004); FTHD_ISP_REG_WRITE(0x00000000, ISP_IRQ_ENABLE); FTHD_ISP_REG_WRITE(0xffffffff, 0xc0008); FTHD_ISP_REG_WRITE(0xffffffff, 0xc000c); FTHD_ISP_REG_WRITE(0xffffffff, 0xc0010); FTHD_ISP_REG_WRITE(0x00000000, 0xc1004); FTHD_ISP_REG_WRITE(0xffffffff, 0xc100c); FTHD_ISP_REG_WRITE(0xffffffff, 0xc1014); FTHD_ISP_REG_WRITE(0xffffffff, 0xc101c); FTHD_ISP_REG_WRITE(0xffffffff, 0xc1024); mdelay(1); FTHD_ISP_REG_WRITE(0, 0xc0000); FTHD_ISP_REG_WRITE(0, 0xc0004); FTHD_ISP_REG_WRITE(0, 0xc0008); FTHD_ISP_REG_WRITE(0, 0xc000c); FTHD_ISP_REG_WRITE(0, 0xc0010); FTHD_ISP_REG_WRITE(0, 0xc0014); FTHD_ISP_REG_WRITE(0, 0xc0018); FTHD_ISP_REG_WRITE(0, 0xc001c); FTHD_ISP_REG_WRITE(0, 0xc0020); FTHD_ISP_REG_WRITE(0, 0xc0024); FTHD_ISP_REG_WRITE(0xffffffff, ISP_IRQ_CLEAR); isp_free_channel_info(dev_priv); isp_free_set_file(dev_priv); isp_mem_destroy(dev_priv->firmware); kfree(dev_priv->mem); return 0; }
static int isp_load_firmware(struct fthd_private *dev_priv) { const struct firmware *fw; int ret = 0; ret = request_firmware(&fw, "facetimehd/firmware.bin", &dev_priv->pdev->dev); if (ret) return ret; /* Firmware memory is preallocated at init time */ if (!dev_priv->firmware) return -ENOMEM; if (dev_priv->firmware->base.start != dev_priv->mem->start) { dev_err(&dev_priv->pdev->dev, "Misaligned firmware memory object (offset: %lu)\n", dev_priv->firmware->offset); isp_mem_destroy(dev_priv->firmware); dev_priv->firmware = NULL; return -EBUSY; } FTHD_S2_MEMCPY_TOIO(dev_priv->firmware->offset, fw->data, fw->size); /* Might need a flush here if we map ISP memory cached */ dev_info(&dev_priv->pdev->dev, "Loaded firmware, size: %lukb\n", fw->size / 1024); release_firmware(fw); return ret; }
static void isp_free_set_file(struct fthd_private *dev_priv) { if (dev_priv->set_file) isp_mem_destroy(dev_priv->set_file); }
int fthd_isp_debug_cmd(struct fthd_private *dev_priv, enum fthd_isp_cmds command, void *buf, int request_len, int *response_len) { struct isp_mem_obj *request; struct isp_cmd_hdr cmd; u32 address, request_size, response_size; u32 entry; int len, ret; memset(&cmd, 0, sizeof(cmd)); if (response_len) { len = max(request_len, *response_len); } else { len = request_len; } len += sizeof(struct isp_cmd_hdr); pr_debug("sending debug cmd %d to firmware\n", command); request = isp_mem_create(dev_priv, FTHD_MEM_CMD, len); if (!request) { dev_err(&dev_priv->pdev->dev, "failed to allocate cmd memory object\n"); return -ENOMEM; } cmd.opcode = command; FTHD_S2_MEMCPY_TOIO(request->offset, &cmd, sizeof(struct isp_cmd_hdr)); if (request_len) FTHD_S2_MEMCPY_TOIO(request->offset + sizeof(struct isp_cmd_hdr), buf, request_len); ret = fthd_channel_ringbuf_send(dev_priv, dev_priv->channel_debug, request->offset, request_len + 8, (response_len ? *response_len : 0) + 8, &entry); if (ret) goto out; if (entry == (u32)-1) { ret = -EIO; goto out; } ret = fthd_channel_wait_ready(dev_priv, dev_priv->channel_debug, entry, 20000); if (ret) { if (response_len) *response_len = 0; goto out; } FTHD_S2_MEMCPY_FROMIO(&cmd, request->offset, sizeof(struct isp_cmd_hdr)); address = FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_ADDRESS_FLAGS); request_size = FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_REQUEST_SIZE); response_size = FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_RESPONSE_SIZE); /* XXX: response size in the ringbuf is zero after command completion, how is buffer size verification done? */ if (response_len && *response_len) FTHD_S2_MEMCPY_FROMIO(buf, (address & ~3) + sizeof(struct isp_cmd_hdr), *response_len); pr_info("status %04x, request_len %d response len %d address_flags %x\n", cmd.status, request_size, response_size, address); ret = 0; out: isp_mem_destroy(request); return ret; }