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_get_sync(rga->dev); 83 if (ret < 0) { 84 pm_runtime_put_noidle(rga->dev); 85 rga_buf_return_buffers(q, VB2_BUF_STATE_QUEUED); 86 return ret; 87 } 88 89 return 0; 90 } 91 92 static void rga_buf_stop_streaming(struct vb2_queue *q) 93 { 94 struct rga_ctx *ctx = vb2_get_drv_priv(q); 95 struct rockchip_rga *rga = ctx->rga; 96 97 rga_buf_return_buffers(q, VB2_BUF_STATE_ERROR); 98 pm_runtime_put(rga->dev); 99 } 100 101 const struct vb2_ops rga_qops = { 102 .queue_setup = rga_queue_setup, 103 .buf_prepare = rga_buf_prepare, 104 .buf_queue = rga_buf_queue, 105 .wait_prepare = vb2_ops_wait_prepare, 106 .wait_finish = vb2_ops_wait_finish, 107 .start_streaming = rga_buf_start_streaming, 108 .stop_streaming = rga_buf_stop_streaming, 109 }; 110 111 /* RGA MMU is a 1-Level MMU, so it can't be used through the IOMMU API. 112 * We use it more like a scatter-gather list. 113 */ 114 void rga_buf_map(struct vb2_buffer *vb) 115 { 116 struct rga_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); 117 struct rockchip_rga *rga = ctx->rga; 118 struct sg_table *sgt; 119 struct scatterlist *sgl; 120 unsigned int *pages; 121 unsigned int address, len, i, p; 122 unsigned int mapped_size = 0; 123 124 if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 125 pages = rga->src_mmu_pages; 126 else 127 pages = rga->dst_mmu_pages; 128 129 /* Create local MMU table for RGA */ 130 sgt = vb2_plane_cookie(vb, 0); 131 132 for_each_sg(sgt->sgl, sgl, sgt->nents, i) { 133 len = sg_dma_len(sgl) >> PAGE_SHIFT; 134 address = sg_phys(sgl); 135 136 for (p = 0; p < len; p++) { 137 dma_addr_t phys = address + 138 ((dma_addr_t)p << PAGE_SHIFT); 139 140 pages[mapped_size + p] = phys; 141 } 142 143 mapped_size += len; 144 } 145 146 /* sync local MMU table for RGA */ 147 dma_sync_single_for_device(rga->dev, virt_to_phys(pages), 148 8 * PAGE_SIZE, DMA_BIDIRECTIONAL); 149 } 150