1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co.Ltd 4 * Author: Jacob Chen <jacob-chen@iotwrt.com> 5 */ 6 7 #include <linux/pm_runtime.h> 8 9 #include <media/v4l2-device.h> 10 #include <media/v4l2-ioctl.h> 11 #include <media/v4l2-mem2mem.h> 12 #include <media/videobuf2-dma-sg.h> 13 #include <media/videobuf2-v4l2.h> 14 15 #include "rga-hw.h" 16 #include "rga.h" 17 18 static int 19 rga_queue_setup(struct vb2_queue *vq, 20 unsigned int *nbuffers, unsigned int *nplanes, 21 unsigned int sizes[], struct device *alloc_devs[]) 22 { 23 struct rga_ctx *ctx = vb2_get_drv_priv(vq); 24 struct rga_frame *f = rga_get_frame(ctx, vq->type); 25 26 if (IS_ERR(f)) 27 return PTR_ERR(f); 28 29 if (*nplanes) 30 return sizes[0] < f->size ? -EINVAL : 0; 31 32 sizes[0] = f->size; 33 *nplanes = 1; 34 35 return 0; 36 } 37 38 static int rga_buf_prepare(struct vb2_buffer *vb) 39 { 40 struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 41 struct rga_frame *f = rga_get_frame(ctx, vb->vb2_queue->type); 42 43 if (IS_ERR(f)) 44 return PTR_ERR(f); 45 46 vb2_set_plane_payload(vb, 0, f->size); 47 48 return 0; 49 } 50 51 static void rga_buf_queue(struct vb2_buffer *vb) 52 { 53 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 54 struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 55 56 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); 57 } 58 59 static void rga_buf_return_buffers(struct vb2_queue *q, 60 enum vb2_buffer_state state) 61 { 62 struct rga_ctx *ctx = vb2_get_drv_priv(q); 63 struct vb2_v4l2_buffer *vbuf; 64 65 for (;;) { 66 if (V4L2_TYPE_IS_OUTPUT(q->type)) 67 vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 68 else 69 vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); 70 if (!vbuf) 71 break; 72 v4l2_m2m_buf_done(vbuf, state); 73 } 74 } 75 76 static int rga_buf_start_streaming(struct vb2_queue *q, unsigned int count) 77 { 78 struct rga_ctx *ctx = vb2_get_drv_priv(q); 79 struct rockchip_rga *rga = ctx->rga; 80 int ret; 81 82 ret = pm_runtime_resume_and_get(rga->dev); 83 if (ret < 0) { 84 rga_buf_return_buffers(q, VB2_BUF_STATE_QUEUED); 85 return ret; 86 } 87 88 return 0; 89 } 90 91 static void rga_buf_stop_streaming(struct vb2_queue *q) 92 { 93 struct rga_ctx *ctx = vb2_get_drv_priv(q); 94 struct rockchip_rga *rga = ctx->rga; 95 96 rga_buf_return_buffers(q, VB2_BUF_STATE_ERROR); 97 pm_runtime_put(rga->dev); 98 } 99 100 const struct vb2_ops rga_qops = { 101 .queue_setup = rga_queue_setup, 102 .buf_prepare = rga_buf_prepare, 103 .buf_queue = rga_buf_queue, 104 .wait_prepare = vb2_ops_wait_prepare, 105 .wait_finish = vb2_ops_wait_finish, 106 .start_streaming = rga_buf_start_streaming, 107 .stop_streaming = rga_buf_stop_streaming, 108 }; 109 110 /* RGA MMU is a 1-Level MMU, so it can't be used through the IOMMU API. 111 * We use it more like a scatter-gather list. 112 */ 113 void rga_buf_map(struct vb2_buffer *vb) 114 { 115 struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 116 struct rockchip_rga *rga = ctx->rga; 117 struct sg_table *sgt; 118 struct scatterlist *sgl; 119 unsigned int *pages; 120 unsigned int address, len, i, p; 121 unsigned int mapped_size = 0; 122 123 if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 124 pages = rga->src_mmu_pages; 125 else 126 pages = rga->dst_mmu_pages; 127 128 /* Create local MMU table for RGA */ 129 sgt = vb2_plane_cookie(vb, 0); 130 131 for_each_sg(sgt->sgl, sgl, sgt->nents, i) { 132 len = sg_dma_len(sgl) >> PAGE_SHIFT; 133 address = sg_phys(sgl); 134 135 for (p = 0; p < len; p++) { 136 dma_addr_t phys = address + 137 ((dma_addr_t)p << PAGE_SHIFT); 138 139 pages[mapped_size + p] = phys; 140 } 141 142 mapped_size += len; 143 } 144 145 /* sync local MMU table for RGA */ 146 dma_sync_single_for_device(rga->dev, virt_to_phys(pages), 147 8 * PAGE_SIZE, DMA_BIDIRECTIONAL); 148 } 149