| .. | .. |
|---|
| 5 | 5 | #include <linux/delay.h> |
|---|
| 6 | 6 | #include <media/v4l2-device.h> |
|---|
| 7 | 7 | #include <media/v4l2-fh.h> |
|---|
| 8 | | -#include <media/v4l2-mem2mem.h> |
|---|
| 9 | 8 | #include <media/v4l2-ioctl.h> |
|---|
| 10 | 9 | #include <media/videobuf2-dma-contig.h> |
|---|
| 11 | 10 | #include <media/videobuf2-v4l2.h> |
|---|
| 12 | 11 | #include <linux/pm_runtime.h> |
|---|
| 13 | | -#include <linux/rkispp-config.h> |
|---|
| 12 | +#include <linux/rk-ispp-config.h> |
|---|
| 13 | +#include <uapi/linux/rk-video-format.h> |
|---|
| 14 | 14 | |
|---|
| 15 | 15 | #include "hw.h" |
|---|
| 16 | 16 | #include "ispp.h" |
|---|
| .. | .. |
|---|
| 18 | 18 | #include "stream.h" |
|---|
| 19 | 19 | #include "common.h" |
|---|
| 20 | 20 | |
|---|
| 21 | +struct rkispp_fec_buf { |
|---|
| 22 | + struct list_head list; |
|---|
| 23 | + struct file *file; |
|---|
| 24 | + int fd; |
|---|
| 25 | + struct dma_buf *dbuf; |
|---|
| 26 | + void *mem; |
|---|
| 27 | +}; |
|---|
| 28 | + |
|---|
| 21 | 29 | static const struct vb2_mem_ops *g_ops = &vb2_dma_contig_memops; |
|---|
| 22 | 30 | |
|---|
| 23 | | -static int fec_running(struct rkispp_fec_dev *fec, |
|---|
| 24 | | - struct rkispp_fec_in_out *buf) |
|---|
| 31 | +static void *fec_buf_add(struct file *file, int fd, int size) |
|---|
| 25 | 32 | { |
|---|
| 33 | + struct rkispp_fec_dev *fec = video_drvdata(file); |
|---|
| 34 | + struct rkispp_fec_buf *buf = NULL; |
|---|
| 35 | + struct dma_buf *dbuf; |
|---|
| 36 | + void *mem = NULL; |
|---|
| 37 | + bool is_add = true; |
|---|
| 38 | + |
|---|
| 39 | + dbuf = dma_buf_get(fd); |
|---|
| 40 | + v4l2_dbg(4, rkispp_debug, &fec->v4l2_dev, |
|---|
| 41 | + "%s file:%p fd:%d dbuf:%p\n", __func__, file, fd, dbuf); |
|---|
| 42 | + if (IS_ERR_OR_NULL(dbuf)) { |
|---|
| 43 | + v4l2_err(&fec->v4l2_dev, "invalid dmabuf fd:%d for in picture", fd); |
|---|
| 44 | + return mem; |
|---|
| 45 | + } |
|---|
| 46 | + if (size && dbuf->size < size) { |
|---|
| 47 | + v4l2_err(&fec->v4l2_dev, |
|---|
| 48 | + "input fd:%d size error:%zu < %u\n", fd, dbuf->size, size); |
|---|
| 49 | + dma_buf_put(dbuf); |
|---|
| 50 | + return mem; |
|---|
| 51 | + } |
|---|
| 52 | + |
|---|
| 53 | + mutex_lock(&fec->hw->dev_lock); |
|---|
| 54 | + list_for_each_entry(buf, &fec->list, list) { |
|---|
| 55 | + if (buf->file == file && buf->fd == fd && buf->dbuf == dbuf) { |
|---|
| 56 | + is_add = false; |
|---|
| 57 | + break; |
|---|
| 58 | + } |
|---|
| 59 | + } |
|---|
| 60 | + |
|---|
| 61 | + if (is_add) { |
|---|
| 62 | + mem = g_ops->attach_dmabuf(fec->hw->dev, dbuf, dbuf->size, DMA_BIDIRECTIONAL); |
|---|
| 63 | + if (IS_ERR(mem)) { |
|---|
| 64 | + v4l2_err(&fec->v4l2_dev, "failed to attach dmabuf, fd:%d\n", fd); |
|---|
| 65 | + dma_buf_put(dbuf); |
|---|
| 66 | + goto end; |
|---|
| 67 | + } |
|---|
| 68 | + if (g_ops->map_dmabuf(mem)) { |
|---|
| 69 | + v4l2_err(&fec->v4l2_dev, "failed to map, fd:%d\n", fd); |
|---|
| 70 | + g_ops->detach_dmabuf(mem); |
|---|
| 71 | + dma_buf_put(dbuf); |
|---|
| 72 | + mem = NULL; |
|---|
| 73 | + goto end; |
|---|
| 74 | + } |
|---|
| 75 | + buf = kzalloc(sizeof(struct rkispp_fec_buf), GFP_KERNEL); |
|---|
| 76 | + if (!buf) { |
|---|
| 77 | + g_ops->unmap_dmabuf(mem); |
|---|
| 78 | + g_ops->detach_dmabuf(mem); |
|---|
| 79 | + dma_buf_put(dbuf); |
|---|
| 80 | + mem = NULL; |
|---|
| 81 | + goto end; |
|---|
| 82 | + } |
|---|
| 83 | + buf->fd = fd; |
|---|
| 84 | + buf->file = file; |
|---|
| 85 | + buf->dbuf = dbuf; |
|---|
| 86 | + buf->mem = mem; |
|---|
| 87 | + list_add_tail(&buf->list, &fec->list); |
|---|
| 88 | + } else { |
|---|
| 89 | + dma_buf_put(dbuf); |
|---|
| 90 | + mem = buf->mem; |
|---|
| 91 | + } |
|---|
| 92 | +end: |
|---|
| 93 | + mutex_unlock(&fec->hw->dev_lock); |
|---|
| 94 | + return mem; |
|---|
| 95 | +} |
|---|
| 96 | + |
|---|
| 97 | +static void fec_buf_del(struct file *file, int fd, bool is_all) |
|---|
| 98 | +{ |
|---|
| 99 | + struct rkispp_fec_dev *fec = video_drvdata(file); |
|---|
| 100 | + struct rkispp_fec_buf *buf, *next; |
|---|
| 101 | + |
|---|
| 102 | + mutex_lock(&fec->hw->dev_lock); |
|---|
| 103 | + list_for_each_entry_safe(buf, next, &fec->list, list) { |
|---|
| 104 | + if (buf->file == file && (is_all || buf->fd == fd)) { |
|---|
| 105 | + v4l2_dbg(4, rkispp_debug, &fec->v4l2_dev, |
|---|
| 106 | + "%s file:%p fd:%d dbuf:%p\n", |
|---|
| 107 | + __func__, file, buf->fd, buf->dbuf); |
|---|
| 108 | + g_ops->unmap_dmabuf(buf->mem); |
|---|
| 109 | + g_ops->detach_dmabuf(buf->mem); |
|---|
| 110 | + dma_buf_put(buf->dbuf); |
|---|
| 111 | + buf->file = NULL; |
|---|
| 112 | + buf->mem = NULL; |
|---|
| 113 | + buf->dbuf = NULL; |
|---|
| 114 | + buf->fd = -1; |
|---|
| 115 | + list_del(&buf->list); |
|---|
| 116 | + kfree(buf); |
|---|
| 117 | + } |
|---|
| 118 | + } |
|---|
| 119 | + mutex_unlock(&fec->hw->dev_lock); |
|---|
| 120 | +} |
|---|
| 121 | + |
|---|
| 122 | +static int fec_running(struct file *file, struct rkispp_fec_in_out *buf) |
|---|
| 123 | +{ |
|---|
| 124 | + struct rkispp_fec_dev *fec = video_drvdata(file); |
|---|
| 26 | 125 | u32 in_fmt, out_fmt, in_mult = 1, out_mult = 1; |
|---|
| 27 | 126 | u32 in_size, in_offs, out_size, out_offs, val; |
|---|
| 28 | | - u32 w = buf->width, h = buf->height, density, mesh_size; |
|---|
| 29 | | - struct dma_buf *in_dbuf, *out_dbuf; |
|---|
| 30 | | - struct dma_buf *xint_dbuf, *xfra_dbuf, *yint_dbuf, *yfra_dbuf; |
|---|
| 31 | | - void *in_mem, *out_mem; |
|---|
| 32 | | - void *xint_mem, *xfra_mem, *yint_mem, *yfra_mem; |
|---|
| 127 | + u32 in_w = buf->in_width, in_h = buf->in_height; |
|---|
| 128 | + u32 out_w = buf->out_width, out_h = buf->out_height; |
|---|
| 129 | + u32 density, mesh_size; |
|---|
| 33 | 130 | void __iomem *base = fec->hw->base_addr; |
|---|
| 131 | + void *mem; |
|---|
| 34 | 132 | int ret = -EINVAL; |
|---|
| 133 | + ktime_t t = 0; |
|---|
| 134 | + s64 us = 0; |
|---|
| 35 | 135 | |
|---|
| 136 | + if (rkispp_debug) |
|---|
| 137 | + t = ktime_get(); |
|---|
| 36 | 138 | v4l2_dbg(3, rkispp_debug, &fec->v4l2_dev, |
|---|
| 37 | | - "%s enter %dx%d format(in:%c%c%c%c out:%c%c%c%c)\n", |
|---|
| 38 | | - __func__, w, h, |
|---|
| 139 | + "%s enter %dx%d->%dx%d format(in:%c%c%c%c out:%c%c%c%c)\n", |
|---|
| 140 | + __func__, in_w, in_h, out_w, out_h, |
|---|
| 39 | 141 | buf->in_fourcc, buf->in_fourcc >> 8, |
|---|
| 40 | 142 | buf->in_fourcc >> 16, buf->in_fourcc >> 24, |
|---|
| 41 | 143 | buf->out_fourcc, buf->out_fourcc >> 8, |
|---|
| .. | .. |
|---|
| 45 | 147 | rkispp_set_clk_rate(fec->hw->clks[0], fec->hw->core_clk_max); |
|---|
| 46 | 148 | |
|---|
| 47 | 149 | init_completion(&fec->cmpl); |
|---|
| 48 | | - density = w > 1920 ? SW_MESH_DENSITY : 0; |
|---|
| 49 | | - mesh_size = cal_fec_mesh(w, h, !!density); |
|---|
| 150 | + density = out_w > 1920 ? SW_MESH_DENSITY : 0; |
|---|
| 151 | + mesh_size = cal_fec_mesh(out_w, out_h, !!density); |
|---|
| 50 | 152 | |
|---|
| 51 | 153 | switch (buf->in_fourcc) { |
|---|
| 52 | 154 | case V4L2_PIX_FMT_YUYV: |
|---|
| .. | .. |
|---|
| 68 | 170 | "no support in format:%c%c%c%c\n", |
|---|
| 69 | 171 | buf->in_fourcc, buf->in_fourcc >> 8, |
|---|
| 70 | 172 | buf->in_fourcc >> 16, buf->in_fourcc >> 24); |
|---|
| 71 | | - ret = -EINVAL; |
|---|
| 72 | | - goto end; |
|---|
| 173 | + return -EINVAL; |
|---|
| 73 | 174 | } |
|---|
| 74 | | - in_offs = w * h; |
|---|
| 175 | + in_offs = in_w * in_h; |
|---|
| 75 | 176 | in_size = (in_fmt & FMT_YUV422) ? |
|---|
| 76 | | - w * h * 2 : w * h * 3 / 2; |
|---|
| 177 | + in_w * in_h * 2 : in_w * in_h * 3 / 2; |
|---|
| 77 | 178 | |
|---|
| 78 | 179 | switch (buf->out_fourcc) { |
|---|
| 79 | 180 | case V4L2_PIX_FMT_YUYV: |
|---|
| .. | .. |
|---|
| 100 | 201 | v4l2_err(&fec->v4l2_dev, "no support out format:%c%c%c%c\n", |
|---|
| 101 | 202 | buf->out_fourcc, buf->out_fourcc >> 8, |
|---|
| 102 | 203 | buf->out_fourcc >> 16, buf->out_fourcc >> 24); |
|---|
| 103 | | - ret = -EINVAL; |
|---|
| 104 | | - goto end; |
|---|
| 204 | + return -EINVAL; |
|---|
| 105 | 205 | } |
|---|
| 106 | 206 | out_size = 0; |
|---|
| 107 | | - out_offs = w * h; |
|---|
| 207 | + out_offs = out_w * out_h; |
|---|
| 108 | 208 | if (out_fmt & FMT_FBC) { |
|---|
| 109 | | - w = ALIGN(w, 16); |
|---|
| 110 | | - h = ALIGN(h, 16); |
|---|
| 111 | | - out_offs = w * h >> 4; |
|---|
| 209 | + out_w = ALIGN(out_w, 16); |
|---|
| 210 | + out_h = ALIGN(out_h, 16); |
|---|
| 211 | + out_offs = out_w * out_h >> 4; |
|---|
| 112 | 212 | out_size = out_offs; |
|---|
| 113 | 213 | } |
|---|
| 114 | 214 | out_size += (out_fmt & FMT_YUV422) ? |
|---|
| 115 | | - w * h * 2 : w * h * 3 / 2; |
|---|
| 215 | + out_w * out_h * 2 : out_w * out_h * 3 / 2; |
|---|
| 116 | 216 | |
|---|
| 117 | 217 | /* input picture buf */ |
|---|
| 118 | | - in_dbuf = dma_buf_get(buf->in_pic_fd); |
|---|
| 119 | | - if (IS_ERR_OR_NULL(in_dbuf)) { |
|---|
| 120 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 121 | | - "invalid dmabuf fd:%d for in picture", buf->in_pic_fd); |
|---|
| 122 | | - ret = -EINVAL; |
|---|
| 123 | | - goto end; |
|---|
| 124 | | - } |
|---|
| 125 | | - if (in_dbuf->size < in_size) { |
|---|
| 126 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 127 | | - "in picture size error:%zu < %u\n", in_dbuf->size, in_size); |
|---|
| 128 | | - goto put_in_dbuf; |
|---|
| 129 | | - } |
|---|
| 130 | | - in_mem = g_ops->attach_dmabuf(fec->hw->dev, in_dbuf, |
|---|
| 131 | | - in_dbuf->size, DMA_BIDIRECTIONAL); |
|---|
| 132 | | - if (IS_ERR(in_mem)) { |
|---|
| 133 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 134 | | - "failed to attach in dmabuf\n"); |
|---|
| 135 | | - goto put_in_dbuf; |
|---|
| 136 | | - } |
|---|
| 137 | | - if (g_ops->map_dmabuf(in_mem)) |
|---|
| 138 | | - goto detach_in_dbuf; |
|---|
| 139 | | - val = *((dma_addr_t *)g_ops->cookie(in_mem)); |
|---|
| 218 | + mem = fec_buf_add(file, buf->in_pic_fd, in_size); |
|---|
| 219 | + if (!mem) |
|---|
| 220 | + goto free_buf; |
|---|
| 221 | + val = *((dma_addr_t *)g_ops->cookie(mem)); |
|---|
| 140 | 222 | writel(val, base + RKISPP_FEC_RD_Y_BASE); |
|---|
| 141 | 223 | val += in_offs; |
|---|
| 142 | 224 | writel(val, base + RKISPP_FEC_RD_UV_BASE); |
|---|
| 143 | 225 | |
|---|
| 144 | 226 | /* output picture buf */ |
|---|
| 145 | | - out_dbuf = dma_buf_get(buf->out_pic_fd); |
|---|
| 146 | | - if (IS_ERR_OR_NULL(out_dbuf)) { |
|---|
| 147 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 148 | | - "invalid dmabuf fd:%d for out picture", buf->out_pic_fd); |
|---|
| 149 | | - goto unmap_in_dbuf; |
|---|
| 150 | | - } |
|---|
| 151 | | - if (out_dbuf->size < out_size) { |
|---|
| 152 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 153 | | - "out picture size error:%zu < %u\n", out_dbuf->size, out_size); |
|---|
| 154 | | - goto put_out_dbuf; |
|---|
| 155 | | - } |
|---|
| 156 | | - out_mem = g_ops->attach_dmabuf(fec->hw->dev, out_dbuf, |
|---|
| 157 | | - out_dbuf->size, DMA_BIDIRECTIONAL); |
|---|
| 158 | | - if (IS_ERR(out_mem)) { |
|---|
| 159 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 160 | | - "failed to attach out dmabuf\n"); |
|---|
| 161 | | - goto put_out_dbuf; |
|---|
| 162 | | - } |
|---|
| 163 | | - if (g_ops->map_dmabuf(out_mem)) |
|---|
| 164 | | - goto detach_out_dbuf; |
|---|
| 165 | | - val = *((dma_addr_t *)g_ops->cookie(out_mem)); |
|---|
| 227 | + mem = fec_buf_add(file, buf->out_pic_fd, out_size); |
|---|
| 228 | + if (!mem) |
|---|
| 229 | + goto free_buf; |
|---|
| 230 | + val = *((dma_addr_t *)g_ops->cookie(mem)); |
|---|
| 166 | 231 | writel(val, base + RKISPP_FEC_WR_Y_BASE); |
|---|
| 167 | 232 | val += out_offs; |
|---|
| 168 | 233 | writel(val, base + RKISPP_FEC_WR_UV_BASE); |
|---|
| 169 | 234 | |
|---|
| 170 | 235 | /* mesh xint buf */ |
|---|
| 171 | | - xint_dbuf = dma_buf_get(buf->mesh_xint_fd); |
|---|
| 172 | | - if (IS_ERR_OR_NULL(xint_dbuf)) { |
|---|
| 173 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 174 | | - "invalid dmabuf fd for xint picture"); |
|---|
| 175 | | - goto unmap_out_dbuf; |
|---|
| 176 | | - } |
|---|
| 177 | | - if (xint_dbuf->size < mesh_size * 2) { |
|---|
| 178 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 179 | | - "mesh xint size error:%zu < %u\n", xint_dbuf->size, mesh_size * 2); |
|---|
| 180 | | - goto put_xint_dbuf; |
|---|
| 181 | | - } |
|---|
| 182 | | - xint_mem = g_ops->attach_dmabuf(fec->hw->dev, xint_dbuf, |
|---|
| 183 | | - xint_dbuf->size, DMA_BIDIRECTIONAL); |
|---|
| 184 | | - if (IS_ERR(xint_mem)) { |
|---|
| 185 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 186 | | - "failed to attach xint dmabuf\n"); |
|---|
| 187 | | - goto put_xint_dbuf; |
|---|
| 188 | | - } |
|---|
| 189 | | - if (g_ops->map_dmabuf(xint_mem)) |
|---|
| 190 | | - goto detach_xint_dbuf; |
|---|
| 191 | | - val = *((dma_addr_t *)g_ops->cookie(xint_mem)); |
|---|
| 236 | + mem = fec_buf_add(file, buf->mesh_xint_fd, mesh_size * 2); |
|---|
| 237 | + if (!mem) |
|---|
| 238 | + goto free_buf; |
|---|
| 239 | + val = *((dma_addr_t *)g_ops->cookie(mem)); |
|---|
| 192 | 240 | writel(val, base + RKISPP_FEC_MESH_XINT_BASE); |
|---|
| 193 | 241 | |
|---|
| 194 | 242 | /* mesh xfra buf */ |
|---|
| 195 | | - xfra_dbuf = dma_buf_get(buf->mesh_xfra_fd); |
|---|
| 196 | | - if (IS_ERR_OR_NULL(xfra_dbuf)) { |
|---|
| 197 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 198 | | - "invalid dmabuf fd for xfra picture"); |
|---|
| 199 | | - goto unmap_xint_dbuf; |
|---|
| 200 | | - } |
|---|
| 201 | | - if (xfra_dbuf->size < mesh_size) { |
|---|
| 202 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 203 | | - "mesh xfra size error:%zu < %u\n", xfra_dbuf->size, mesh_size); |
|---|
| 204 | | - goto put_xfra_dbuf; |
|---|
| 205 | | - } |
|---|
| 206 | | - xfra_mem = g_ops->attach_dmabuf(fec->hw->dev, xfra_dbuf, |
|---|
| 207 | | - xfra_dbuf->size, DMA_BIDIRECTIONAL); |
|---|
| 208 | | - if (IS_ERR(xfra_mem)) { |
|---|
| 209 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 210 | | - "failed to attach xfra dmabuf\n"); |
|---|
| 211 | | - goto put_xfra_dbuf; |
|---|
| 212 | | - } |
|---|
| 213 | | - if (g_ops->map_dmabuf(xfra_mem)) |
|---|
| 214 | | - goto detach_xfra_dbuf; |
|---|
| 215 | | - val = *((dma_addr_t *)g_ops->cookie(xfra_mem)); |
|---|
| 243 | + mem = fec_buf_add(file, buf->mesh_xfra_fd, mesh_size); |
|---|
| 244 | + if (!mem) |
|---|
| 245 | + goto free_buf; |
|---|
| 246 | + val = *((dma_addr_t *)g_ops->cookie(mem)); |
|---|
| 216 | 247 | writel(val, base + RKISPP_FEC_MESH_XFRA_BASE); |
|---|
| 217 | 248 | |
|---|
| 218 | 249 | /* mesh yint buf */ |
|---|
| 219 | | - yint_dbuf = dma_buf_get(buf->mesh_yint_fd); |
|---|
| 220 | | - if (IS_ERR_OR_NULL(yint_dbuf)) { |
|---|
| 221 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 222 | | - "invalid dmabuf fd for yint picture"); |
|---|
| 223 | | - goto unmap_xfra_dbuf; |
|---|
| 224 | | - } |
|---|
| 225 | | - if (yint_dbuf->size < mesh_size * 2) { |
|---|
| 226 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 227 | | - "mesh yint size error:%zu < %u\n", yint_dbuf->size, mesh_size * 2); |
|---|
| 228 | | - goto put_yint_dbuf; |
|---|
| 229 | | - } |
|---|
| 230 | | - yint_mem = g_ops->attach_dmabuf(fec->hw->dev, yint_dbuf, |
|---|
| 231 | | - yint_dbuf->size, DMA_BIDIRECTIONAL); |
|---|
| 232 | | - if (IS_ERR(yint_mem)) { |
|---|
| 233 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 234 | | - "failed to attach yint dmabuf\n"); |
|---|
| 235 | | - goto put_yint_dbuf; |
|---|
| 236 | | - } |
|---|
| 237 | | - if (g_ops->map_dmabuf(yint_mem)) |
|---|
| 238 | | - goto detach_yint_dbuf; |
|---|
| 239 | | - val = *((dma_addr_t *)g_ops->cookie(yint_mem)); |
|---|
| 250 | + mem = fec_buf_add(file, buf->mesh_yint_fd, mesh_size * 2); |
|---|
| 251 | + if (!mem) |
|---|
| 252 | + goto free_buf; |
|---|
| 253 | + val = *((dma_addr_t *)g_ops->cookie(mem)); |
|---|
| 240 | 254 | writel(val, base + RKISPP_FEC_MESH_YINT_BASE); |
|---|
| 241 | 255 | |
|---|
| 242 | 256 | /* mesh yfra buf */ |
|---|
| 243 | | - yfra_dbuf = dma_buf_get(buf->mesh_yfra_fd); |
|---|
| 244 | | - if (IS_ERR_OR_NULL(yfra_dbuf)) { |
|---|
| 245 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 246 | | - "invalid dmabuf fd for yfra picture"); |
|---|
| 247 | | - goto unmap_yint_dbuf; |
|---|
| 248 | | - } |
|---|
| 249 | | - if (yfra_dbuf->size < mesh_size) { |
|---|
| 250 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 251 | | - "mesh yfra size error:%zu < %u\n", yfra_dbuf->size, mesh_size); |
|---|
| 252 | | - goto put_yfra_dbuf; |
|---|
| 253 | | - } |
|---|
| 254 | | - yfra_mem = g_ops->attach_dmabuf(fec->hw->dev, yfra_dbuf, |
|---|
| 255 | | - yfra_dbuf->size, DMA_BIDIRECTIONAL); |
|---|
| 256 | | - if (IS_ERR(yfra_mem)) { |
|---|
| 257 | | - v4l2_err(&fec->v4l2_dev, |
|---|
| 258 | | - "failed to attach yfra dmabuf\n"); |
|---|
| 259 | | - goto put_yfra_dbuf; |
|---|
| 260 | | - } |
|---|
| 261 | | - if (g_ops->map_dmabuf(yfra_mem)) |
|---|
| 262 | | - goto detach_yfra_dbuf; |
|---|
| 263 | | - val = *((dma_addr_t *)g_ops->cookie(yfra_mem)); |
|---|
| 257 | + mem = fec_buf_add(file, buf->mesh_yfra_fd, mesh_size); |
|---|
| 258 | + if (!mem) |
|---|
| 259 | + goto free_buf; |
|---|
| 260 | + val = *((dma_addr_t *)g_ops->cookie(mem)); |
|---|
| 264 | 261 | writel(val, base + RKISPP_FEC_MESH_YFRA_BASE); |
|---|
| 265 | 262 | |
|---|
| 266 | 263 | val = out_fmt << 4 | in_fmt; |
|---|
| 267 | 264 | writel(val, base + RKISPP_FEC_CTRL); |
|---|
| 268 | | - val = ALIGN(buf->width * in_mult, 16) >> 2; |
|---|
| 265 | + val = ALIGN(in_w * in_mult, 16) >> 2; |
|---|
| 269 | 266 | writel(val, base + RKISPP_FEC_RD_VIR_STRIDE); |
|---|
| 270 | | - val = ALIGN(buf->width * out_mult, 16) >> 2; |
|---|
| 267 | + val = ALIGN(out_w * out_mult, 16) >> 2; |
|---|
| 271 | 268 | writel(val, base + RKISPP_FEC_WR_VIR_STRIDE); |
|---|
| 272 | | - val = buf->height << 16 | buf->width; |
|---|
| 273 | | - writel(val, base + RKISPP_FEC_PIC_SIZE); |
|---|
| 269 | + val = out_h << 16 | out_w; |
|---|
| 270 | + writel(val, base + RKISPP_FEC_DST_SIZE); |
|---|
| 271 | + val = in_h << 16 | in_w; |
|---|
| 272 | + writel(val, base + RKISPP_FEC_SRC_SIZE); |
|---|
| 274 | 273 | writel(mesh_size, base + RKISPP_FEC_MESH_SIZE); |
|---|
| 275 | 274 | val = SW_FEC_EN | density; |
|---|
| 276 | 275 | writel(val, base + RKISPP_FEC_CORE_CTRL); |
|---|
| .. | .. |
|---|
| 279 | 278 | v4l2_dbg(3, rkispp_debug, &fec->v4l2_dev, |
|---|
| 280 | 279 | "0x%x:0x%x 0x%x:0x%x 0x%x:0x%x 0x%x:0x%x 0x%x:0x%x\n" |
|---|
| 281 | 280 | "0x%x:0x%x 0x%x:0x%x 0x%x:0x%x 0x%x:0x%x 0x%x:0x%x\n" |
|---|
| 282 | | - "0x%x:0x%x 0x%x:0x%x 0x%x:0x%x 0x%x:0x%x 0x%x:0x%x\n", |
|---|
| 281 | + "0x%x:0x%x 0x%x:0x%x 0x%x:0x%x 0x%x:0x%x 0x%x:0x%x 0x%x:0x%x\n", |
|---|
| 283 | 282 | RKISPP_CTRL_SYS_STATUS, readl(base + RKISPP_CTRL_SYS_STATUS), |
|---|
| 284 | 283 | RKISPP_FEC_CTRL, readl(base + RKISPP_FEC_CTRL), |
|---|
| 285 | 284 | RKISPP_FEC_RD_VIR_STRIDE, readl(base + RKISPP_FEC_RD_VIR_STRIDE), |
|---|
| .. | .. |
|---|
| 293 | 292 | RKISPP_FEC_WR_Y_BASE_SHD, readl(base + RKISPP_FEC_WR_Y_BASE_SHD), |
|---|
| 294 | 293 | RKISPP_FEC_WR_UV_BASE_SHD, readl(base + RKISPP_FEC_WR_UV_BASE_SHD), |
|---|
| 295 | 294 | RKISPP_FEC_CORE_CTRL, readl(base + RKISPP_FEC_CORE_CTRL), |
|---|
| 296 | | - RKISPP_FEC_PIC_SIZE, readl(base + RKISPP_FEC_PIC_SIZE), |
|---|
| 295 | + RKISPP_FEC_DST_SIZE, readl(base + RKISPP_FEC_DST_SIZE), |
|---|
| 296 | + RKISPP_FEC_SRC_SIZE, readl(base + RKISPP_FEC_SRC_SIZE), |
|---|
| 297 | 297 | RKISPP_FEC_MESH_SIZE, readl(base + RKISPP_FEC_MESH_SIZE)); |
|---|
| 298 | 298 | if (!fec->hw->is_shutdown) |
|---|
| 299 | 299 | writel(FEC_ST, base + RKISPP_CTRL_STRT); |
|---|
| .. | .. |
|---|
| 307 | 307 | } |
|---|
| 308 | 308 | writel(SW_FEC2DDR_DIS, base + RKISPP_FEC_CORE_CTRL); |
|---|
| 309 | 309 | |
|---|
| 310 | | - g_ops->unmap_dmabuf(yfra_mem); |
|---|
| 311 | | -detach_yfra_dbuf: |
|---|
| 312 | | - g_ops->detach_dmabuf(yfra_mem); |
|---|
| 313 | | -put_yfra_dbuf: |
|---|
| 314 | | - dma_buf_put(yfra_dbuf); |
|---|
| 315 | | -unmap_yint_dbuf: |
|---|
| 316 | | - g_ops->unmap_dmabuf(yint_mem); |
|---|
| 317 | | -detach_yint_dbuf: |
|---|
| 318 | | - g_ops->detach_dmabuf(yint_mem); |
|---|
| 319 | | -put_yint_dbuf: |
|---|
| 320 | | - dma_buf_put(yint_dbuf); |
|---|
| 321 | | -unmap_xfra_dbuf: |
|---|
| 322 | | - g_ops->unmap_dmabuf(xfra_mem); |
|---|
| 323 | | -detach_xfra_dbuf: |
|---|
| 324 | | - g_ops->detach_dmabuf(xfra_mem); |
|---|
| 325 | | -put_xfra_dbuf: |
|---|
| 326 | | - dma_buf_put(xfra_dbuf); |
|---|
| 327 | | -unmap_xint_dbuf: |
|---|
| 328 | | - g_ops->unmap_dmabuf(xint_mem); |
|---|
| 329 | | -detach_xint_dbuf: |
|---|
| 330 | | - g_ops->detach_dmabuf(xint_mem); |
|---|
| 331 | | -put_xint_dbuf: |
|---|
| 332 | | - dma_buf_put(xint_dbuf); |
|---|
| 333 | | -unmap_out_dbuf: |
|---|
| 334 | | - g_ops->unmap_dmabuf(out_mem); |
|---|
| 335 | | -detach_out_dbuf: |
|---|
| 336 | | - g_ops->detach_dmabuf(out_mem); |
|---|
| 337 | | -put_out_dbuf: |
|---|
| 338 | | - dma_buf_put(out_dbuf); |
|---|
| 339 | | -unmap_in_dbuf: |
|---|
| 340 | | - g_ops->unmap_dmabuf(in_mem); |
|---|
| 341 | | -detach_in_dbuf: |
|---|
| 342 | | - g_ops->detach_dmabuf(in_mem); |
|---|
| 343 | | -put_in_dbuf: |
|---|
| 344 | | - dma_buf_put(in_dbuf); |
|---|
| 345 | | -end: |
|---|
| 310 | + if (rkispp_debug) |
|---|
| 311 | + us = ktime_us_delta(ktime_get(), t); |
|---|
| 346 | 312 | v4l2_dbg(3, rkispp_debug, &fec->v4l2_dev, |
|---|
| 347 | | - "%s exit ret:%d\n", __func__, ret); |
|---|
| 313 | + "%s exit ret:%d, time:%lldus\n", __func__, ret, us); |
|---|
| 314 | + return ret; |
|---|
| 315 | +free_buf: |
|---|
| 316 | + fec_buf_del(file, 0, true); |
|---|
| 348 | 317 | return ret; |
|---|
| 349 | 318 | } |
|---|
| 350 | 319 | |
|---|
| 351 | 320 | static long fec_ioctl_default(struct file *file, void *fh, |
|---|
| 352 | 321 | bool valid_prio, unsigned int cmd, void *arg) |
|---|
| 353 | 322 | { |
|---|
| 354 | | - struct rkispp_fec_dev *fec = video_drvdata(file); |
|---|
| 355 | 323 | long ret = 0; |
|---|
| 356 | 324 | |
|---|
| 357 | 325 | if (!arg) |
|---|
| .. | .. |
|---|
| 359 | 327 | |
|---|
| 360 | 328 | switch (cmd) { |
|---|
| 361 | 329 | case RKISPP_CMD_FEC_IN_OUT: |
|---|
| 362 | | - ret = fec_running(fec, arg); |
|---|
| 330 | + ret = fec_running(file, arg); |
|---|
| 331 | + break; |
|---|
| 332 | + case RKISPP_CMD_FEC_BUF_ADD: |
|---|
| 333 | + if (!fec_buf_add(file, *(int *)arg, 0)) |
|---|
| 334 | + ret = -ENOMEM; |
|---|
| 335 | + break; |
|---|
| 336 | + case RKISPP_CMD_FEC_BUF_DEL: |
|---|
| 337 | + fec_buf_del(file, *(int *)arg, false); |
|---|
| 363 | 338 | break; |
|---|
| 364 | 339 | default: |
|---|
| 365 | 340 | ret = -EFAULT; |
|---|
| .. | .. |
|---|
| 368 | 343 | return ret; |
|---|
| 369 | 344 | } |
|---|
| 370 | 345 | |
|---|
| 371 | | -static const struct v4l2_ioctl_ops m2m_ioctl_ops = { |
|---|
| 346 | +static const struct v4l2_ioctl_ops fec_ioctl_ops = { |
|---|
| 372 | 347 | .vidioc_default = fec_ioctl_default, |
|---|
| 373 | 348 | }; |
|---|
| 374 | 349 | |
|---|
| .. | .. |
|---|
| 399 | 374 | v4l2_dbg(1, rkispp_debug, &fec->v4l2_dev, "%s\n", __func__); |
|---|
| 400 | 375 | |
|---|
| 401 | 376 | v4l2_fh_release(file); |
|---|
| 377 | + fec_buf_del(file, 0, true); |
|---|
| 402 | 378 | mutex_lock(&fec->hw->dev_lock); |
|---|
| 403 | 379 | pm_runtime_put_sync(fec->hw->dev); |
|---|
| 404 | 380 | mutex_unlock(&fec->hw->dev_lock); |
|---|
| .. | .. |
|---|
| 409 | 385 | .owner = THIS_MODULE, |
|---|
| 410 | 386 | .open = fec_open, |
|---|
| 411 | 387 | .release = fec_release, |
|---|
| 412 | | - .poll = v4l2_m2m_fop_poll, |
|---|
| 413 | 388 | .unlocked_ioctl = video_ioctl2, |
|---|
| 414 | | - .mmap = v4l2_m2m_fop_mmap, |
|---|
| 389 | +#ifdef CONFIG_COMPAT |
|---|
| 390 | + .compat_ioctl32 = video_ioctl2, |
|---|
| 391 | +#endif |
|---|
| 415 | 392 | }; |
|---|
| 416 | 393 | |
|---|
| 417 | 394 | static const struct video_device fec_videodev = { |
|---|
| 418 | 395 | .name = "rkispp_fec", |
|---|
| 419 | | - .vfl_dir = VFL_DIR_M2M, |
|---|
| 396 | + .vfl_dir = VFL_DIR_RX, |
|---|
| 420 | 397 | .fops = &fec_fops, |
|---|
| 421 | | - .ioctl_ops = &m2m_ioctl_ops, |
|---|
| 398 | + .ioctl_ops = &fec_ioctl_ops, |
|---|
| 422 | 399 | .minor = -1, |
|---|
| 423 | 400 | .release = video_device_release_empty, |
|---|
| 424 | 401 | }; |
|---|
| .. | .. |
|---|
| 450 | 427 | if (ret) |
|---|
| 451 | 428 | return ret; |
|---|
| 452 | 429 | |
|---|
| 430 | + mutex_init(&fec->apilock); |
|---|
| 453 | 431 | fec->vfd = fec_videodev; |
|---|
| 454 | 432 | vfd = &fec->vfd; |
|---|
| 433 | + vfd->device_caps = V4L2_CAP_STREAMING; |
|---|
| 455 | 434 | vfd->lock = &fec->apilock; |
|---|
| 456 | 435 | vfd->v4l2_dev = v4l2_dev; |
|---|
| 457 | | - ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); |
|---|
| 436 | + ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0); |
|---|
| 458 | 437 | if (ret) { |
|---|
| 459 | 438 | v4l2_err(v4l2_dev, "Failed to register video device\n"); |
|---|
| 460 | 439 | goto unreg_v4l2; |
|---|
| 461 | 440 | } |
|---|
| 462 | 441 | video_set_drvdata(vfd, fec); |
|---|
| 442 | + INIT_LIST_HEAD(&fec->list); |
|---|
| 463 | 443 | return 0; |
|---|
| 464 | 444 | unreg_v4l2: |
|---|
| 445 | + mutex_destroy(&fec->apilock); |
|---|
| 465 | 446 | v4l2_device_unregister(v4l2_dev); |
|---|
| 466 | 447 | return ret; |
|---|
| 467 | 448 | } |
|---|
| .. | .. |
|---|
| 471 | 452 | if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISPP_FEC)) |
|---|
| 472 | 453 | return; |
|---|
| 473 | 454 | |
|---|
| 455 | + mutex_destroy(&hw->fec_dev.apilock); |
|---|
| 474 | 456 | video_unregister_device(&hw->fec_dev.vfd); |
|---|
| 475 | 457 | v4l2_device_unregister(&hw->fec_dev.v4l2_dev); |
|---|
| 476 | 458 | } |
|---|