Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1 | /* |
| 2 | * drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c |
| 3 | * |
| 4 | * Samsung MFC (Multi Function Codec - FIMV) driver |
| 5 | * This file contains hw related functions. |
| 6 | * |
| 7 | * Copyright (c) 2012 Samsung Electronics Co., Ltd. |
| 8 | * http://www.samsung.com/ |
| 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify |
| 11 | * it under the terms of the GNU General Public License version 2 as |
| 12 | * published by the Free Software Foundation. |
| 13 | */ |
| 14 | |
| 15 | #undef DEBUG |
| 16 | |
| 17 | #include <linux/delay.h> |
| 18 | #include <linux/mm.h> |
| 19 | #include <linux/io.h> |
| 20 | #include <linux/jiffies.h> |
| 21 | #include <linux/firmware.h> |
| 22 | #include <linux/err.h> |
| 23 | #include <linux/sched.h> |
| 24 | #include <linux/dma-mapping.h> |
| 25 | |
| 26 | #include <asm/cacheflush.h> |
| 27 | |
| 28 | #include "s5p_mfc_common.h" |
| 29 | #include "s5p_mfc_cmd.h" |
| 30 | #include "s5p_mfc_intr.h" |
| 31 | #include "s5p_mfc_pm.h" |
| 32 | #include "s5p_mfc_debug.h" |
| 33 | #include "s5p_mfc_opr.h" |
| 34 | #include "s5p_mfc_opr_v6.h" |
| 35 | |
| 36 | /* #define S5P_MFC_DEBUG_REGWRITE */ |
| 37 | #ifdef S5P_MFC_DEBUG_REGWRITE |
| 38 | #undef writel |
| 39 | #define writel(v, r) \ |
| 40 | do { \ |
| 41 | pr_err("MFCWRITE(%p): %08x\n", r, (unsigned int)v); \ |
| 42 | __raw_writel(v, r); \ |
| 43 | } while (0) |
| 44 | #endif /* S5P_MFC_DEBUG_REGWRITE */ |
| 45 | |
Arun Kumar K | 9ab10e4 | 2014-05-21 06:29:31 -0300 | [diff] [blame] | 46 | #define IS_MFCV6_V2(dev) (!IS_MFCV7_PLUS(dev) && dev->fw_ver == MFC_FW_V2) |
| 47 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 48 | /* Allocate temporary buffers for decoding */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 49 | static int s5p_mfc_alloc_dec_temp_buffers_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 50 | { |
| 51 | /* NOP */ |
| 52 | |
| 53 | return 0; |
| 54 | } |
| 55 | |
| 56 | /* Release temproary buffers for decoding */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 57 | static void s5p_mfc_release_dec_desc_buffer_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 58 | { |
| 59 | /* NOP */ |
| 60 | } |
| 61 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 62 | /* Allocate codec buffers */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 63 | static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 64 | { |
| 65 | struct s5p_mfc_dev *dev = ctx->dev; |
| 66 | unsigned int mb_width, mb_height; |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 67 | int ret; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 68 | |
| 69 | mb_width = MB_WIDTH(ctx->img_width); |
| 70 | mb_height = MB_HEIGHT(ctx->img_height); |
| 71 | |
| 72 | if (ctx->type == MFCINST_DECODER) { |
| 73 | mfc_debug(2, "Luma size:%d Chroma size:%d MV size:%d\n", |
| 74 | ctx->luma_size, ctx->chroma_size, ctx->mv_size); |
| 75 | mfc_debug(2, "Totals bufs: %d\n", ctx->total_dpb_count); |
| 76 | } else if (ctx->type == MFCINST_ENCODER) { |
Kiran AVND | 3e594ce7 | 2014-05-19 09:50:02 -0300 | [diff] [blame] | 77 | if (IS_MFCV8(dev)) |
| 78 | ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 * |
| 79 | ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V8(mb_width, mb_height), |
| 80 | S5P_FIMV_TMV_BUFFER_ALIGN_V6); |
| 81 | else |
| 82 | ctx->tmv_buffer_size = S5P_FIMV_NUM_TMV_BUFFERS_V6 * |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 83 | ALIGN(S5P_FIMV_TMV_BUFFER_SIZE_V6(mb_width, mb_height), |
| 84 | S5P_FIMV_TMV_BUFFER_ALIGN_V6); |
Arun Kumar K | debe626 | 2013-07-09 01:24:39 -0300 | [diff] [blame] | 85 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 86 | ctx->luma_dpb_size = ALIGN((mb_width * mb_height) * |
| 87 | S5P_FIMV_LUMA_MB_TO_PIXEL_V6, |
| 88 | S5P_FIMV_LUMA_DPB_BUFFER_ALIGN_V6); |
| 89 | ctx->chroma_dpb_size = ALIGN((mb_width * mb_height) * |
| 90 | S5P_FIMV_CHROMA_MB_TO_PIXEL_V6, |
| 91 | S5P_FIMV_CHROMA_DPB_BUFFER_ALIGN_V6); |
Kiran AVND | 3e594ce7 | 2014-05-19 09:50:02 -0300 | [diff] [blame] | 92 | if (IS_MFCV8(dev)) |
| 93 | ctx->me_buffer_size = ALIGN(S5P_FIMV_ME_BUFFER_SIZE_V8( |
| 94 | ctx->img_width, ctx->img_height, |
| 95 | mb_width, mb_height), |
| 96 | S5P_FIMV_ME_BUFFER_ALIGN_V6); |
| 97 | else |
| 98 | ctx->me_buffer_size = ALIGN(S5P_FIMV_ME_BUFFER_SIZE_V6( |
| 99 | ctx->img_width, ctx->img_height, |
| 100 | mb_width, mb_height), |
| 101 | S5P_FIMV_ME_BUFFER_ALIGN_V6); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 102 | |
Mauro Carvalho Chehab | 03ce781 | 2014-09-24 19:07:36 -0300 | [diff] [blame] | 103 | mfc_debug(2, "recon luma size: %zu chroma size: %zu\n", |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 104 | ctx->luma_dpb_size, ctx->chroma_dpb_size); |
| 105 | } else { |
| 106 | return -EINVAL; |
| 107 | } |
| 108 | |
| 109 | /* Codecs have different memory requirements */ |
| 110 | switch (ctx->codec_mode) { |
| 111 | case S5P_MFC_CODEC_H264_DEC: |
| 112 | case S5P_MFC_CODEC_H264_MVC_DEC: |
Kiran AVND | e2b9deb | 2014-05-19 09:50:01 -0300 | [diff] [blame] | 113 | if (IS_MFCV8(dev)) |
| 114 | ctx->scratch_buf_size = |
| 115 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V8( |
| 116 | mb_width, |
| 117 | mb_height); |
| 118 | else |
| 119 | ctx->scratch_buf_size = |
| 120 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_DEC_V6( |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 121 | mb_width, |
| 122 | mb_height); |
| 123 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| 124 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 125 | ctx->bank1.size = |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 126 | ctx->scratch_buf_size + |
| 127 | (ctx->mv_count * ctx->mv_size); |
| 128 | break; |
| 129 | case S5P_MFC_CODEC_MPEG4_DEC: |
Arun Kumar K | 109b794 | 2014-05-19 09:33:06 -0300 | [diff] [blame] | 130 | if (IS_MFCV7_PLUS(dev)) { |
Arun Kumar K | debe626 | 2013-07-09 01:24:39 -0300 | [diff] [blame] | 131 | ctx->scratch_buf_size = |
| 132 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V7( |
| 133 | mb_width, |
| 134 | mb_height); |
| 135 | } else { |
| 136 | ctx->scratch_buf_size = |
| 137 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_DEC_V6( |
| 138 | mb_width, |
| 139 | mb_height); |
| 140 | } |
| 141 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 142 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| 143 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 144 | ctx->bank1.size = ctx->scratch_buf_size; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 145 | break; |
| 146 | case S5P_MFC_CODEC_VC1RCV_DEC: |
| 147 | case S5P_MFC_CODEC_VC1_DEC: |
| 148 | ctx->scratch_buf_size = |
| 149 | S5P_FIMV_SCRATCH_BUF_SIZE_VC1_DEC_V6( |
| 150 | mb_width, |
| 151 | mb_height); |
| 152 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| 153 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 154 | ctx->bank1.size = ctx->scratch_buf_size; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 155 | break; |
| 156 | case S5P_MFC_CODEC_MPEG2_DEC: |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 157 | ctx->bank1.size = 0; |
| 158 | ctx->bank2.size = 0; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 159 | break; |
| 160 | case S5P_MFC_CODEC_H263_DEC: |
| 161 | ctx->scratch_buf_size = |
| 162 | S5P_FIMV_SCRATCH_BUF_SIZE_H263_DEC_V6( |
| 163 | mb_width, |
| 164 | mb_height); |
| 165 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| 166 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 167 | ctx->bank1.size = ctx->scratch_buf_size; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 168 | break; |
| 169 | case S5P_MFC_CODEC_VP8_DEC: |
Kiran AVND | e2b9deb | 2014-05-19 09:50:01 -0300 | [diff] [blame] | 170 | if (IS_MFCV8(dev)) |
| 171 | ctx->scratch_buf_size = |
| 172 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V8( |
| 173 | mb_width, |
| 174 | mb_height); |
| 175 | else |
| 176 | ctx->scratch_buf_size = |
| 177 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_DEC_V6( |
| 178 | mb_width, |
| 179 | mb_height); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 180 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| 181 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 182 | ctx->bank1.size = ctx->scratch_buf_size; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 183 | break; |
| 184 | case S5P_MFC_CODEC_H264_ENC: |
Kiran AVND | 3e594ce7 | 2014-05-19 09:50:02 -0300 | [diff] [blame] | 185 | if (IS_MFCV8(dev)) |
| 186 | ctx->scratch_buf_size = |
| 187 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V8( |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 188 | mb_width, |
| 189 | mb_height); |
Kiran AVND | 3e594ce7 | 2014-05-19 09:50:02 -0300 | [diff] [blame] | 190 | else |
| 191 | ctx->scratch_buf_size = |
| 192 | S5P_FIMV_SCRATCH_BUF_SIZE_H264_ENC_V6( |
| 193 | mb_width, |
| 194 | mb_height); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 195 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| 196 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 197 | ctx->bank1.size = |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 198 | ctx->scratch_buf_size + ctx->tmv_buffer_size + |
Arun Kumar K | e9d98dd | 2013-04-24 09:41:53 -0300 | [diff] [blame] | 199 | (ctx->pb_count * (ctx->luma_dpb_size + |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 200 | ctx->chroma_dpb_size + ctx->me_buffer_size)); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 201 | ctx->bank2.size = 0; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 202 | break; |
| 203 | case S5P_MFC_CODEC_MPEG4_ENC: |
| 204 | case S5P_MFC_CODEC_H263_ENC: |
| 205 | ctx->scratch_buf_size = |
| 206 | S5P_FIMV_SCRATCH_BUF_SIZE_MPEG4_ENC_V6( |
| 207 | mb_width, |
| 208 | mb_height); |
| 209 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| 210 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 211 | ctx->bank1.size = |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 212 | ctx->scratch_buf_size + ctx->tmv_buffer_size + |
Arun Kumar K | e9d98dd | 2013-04-24 09:41:53 -0300 | [diff] [blame] | 213 | (ctx->pb_count * (ctx->luma_dpb_size + |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 214 | ctx->chroma_dpb_size + ctx->me_buffer_size)); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 215 | ctx->bank2.size = 0; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 216 | break; |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 217 | case S5P_MFC_CODEC_VP8_ENC: |
Kiran AVND | 3e594ce7 | 2014-05-19 09:50:02 -0300 | [diff] [blame] | 218 | if (IS_MFCV8(dev)) |
| 219 | ctx->scratch_buf_size = |
| 220 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_ENC_V8( |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 221 | mb_width, |
| 222 | mb_height); |
Kiran AVND | 3e594ce7 | 2014-05-19 09:50:02 -0300 | [diff] [blame] | 223 | else |
| 224 | ctx->scratch_buf_size = |
| 225 | S5P_FIMV_SCRATCH_BUF_SIZE_VP8_ENC_V7( |
| 226 | mb_width, |
| 227 | mb_height); |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 228 | ctx->scratch_buf_size = ALIGN(ctx->scratch_buf_size, |
| 229 | S5P_FIMV_SCRATCH_BUFFER_ALIGN_V6); |
| 230 | ctx->bank1.size = |
| 231 | ctx->scratch_buf_size + ctx->tmv_buffer_size + |
| 232 | (ctx->pb_count * (ctx->luma_dpb_size + |
| 233 | ctx->chroma_dpb_size + ctx->me_buffer_size)); |
| 234 | ctx->bank2.size = 0; |
| 235 | break; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 236 | default: |
| 237 | break; |
| 238 | } |
| 239 | |
| 240 | /* Allocate only if memory from bank 1 is necessary */ |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 241 | if (ctx->bank1.size > 0) { |
Marek Szyprowski | 1af2198 | 2015-06-03 07:36:23 -0300 | [diff] [blame] | 242 | ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, |
| 243 | &ctx->bank1); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 244 | if (ret) { |
| 245 | mfc_err("Failed to allocate Bank1 memory\n"); |
| 246 | return ret; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 247 | } |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 248 | BUG_ON(ctx->bank1.dma & ((1 << MFC_BANK1_ALIGN_ORDER) - 1)); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 249 | } |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 250 | return 0; |
| 251 | } |
| 252 | |
| 253 | /* Release buffers allocated for codec */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 254 | static void s5p_mfc_release_codec_buffers_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 255 | { |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 256 | s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->bank1); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 257 | } |
| 258 | |
| 259 | /* Allocate memory for instance data buffer */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 260 | static int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 261 | { |
| 262 | struct s5p_mfc_dev *dev = ctx->dev; |
| 263 | struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 264 | int ret; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 265 | |
| 266 | mfc_debug_enter(); |
| 267 | |
| 268 | switch (ctx->codec_mode) { |
| 269 | case S5P_MFC_CODEC_H264_DEC: |
| 270 | case S5P_MFC_CODEC_H264_MVC_DEC: |
| 271 | ctx->ctx.size = buf_size->h264_dec_ctx; |
| 272 | break; |
| 273 | case S5P_MFC_CODEC_MPEG4_DEC: |
| 274 | case S5P_MFC_CODEC_H263_DEC: |
| 275 | case S5P_MFC_CODEC_VC1RCV_DEC: |
| 276 | case S5P_MFC_CODEC_VC1_DEC: |
| 277 | case S5P_MFC_CODEC_MPEG2_DEC: |
| 278 | case S5P_MFC_CODEC_VP8_DEC: |
| 279 | ctx->ctx.size = buf_size->other_dec_ctx; |
| 280 | break; |
| 281 | case S5P_MFC_CODEC_H264_ENC: |
| 282 | ctx->ctx.size = buf_size->h264_enc_ctx; |
| 283 | break; |
| 284 | case S5P_MFC_CODEC_MPEG4_ENC: |
| 285 | case S5P_MFC_CODEC_H263_ENC: |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 286 | case S5P_MFC_CODEC_VP8_ENC: |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 287 | ctx->ctx.size = buf_size->other_enc_ctx; |
| 288 | break; |
| 289 | default: |
| 290 | ctx->ctx.size = 0; |
| 291 | mfc_err("Codec type(%d) should be checked!\n", ctx->codec_mode); |
| 292 | break; |
| 293 | } |
| 294 | |
Marek Szyprowski | 1af2198 | 2015-06-03 07:36:23 -0300 | [diff] [blame] | 295 | ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, &ctx->ctx); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 296 | if (ret) { |
| 297 | mfc_err("Failed to allocate instance buffer\n"); |
| 298 | return ret; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 299 | } |
| 300 | |
| 301 | memset(ctx->ctx.virt, 0, ctx->ctx.size); |
| 302 | wmb(); |
| 303 | |
| 304 | mfc_debug_leave(); |
| 305 | |
| 306 | return 0; |
| 307 | } |
| 308 | |
| 309 | /* Release instance buffer */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 310 | static void s5p_mfc_release_instance_buffer_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 311 | { |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 312 | s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->ctx); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 313 | } |
| 314 | |
| 315 | /* Allocate context buffers for SYS_INIT */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 316 | static int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 317 | { |
| 318 | struct s5p_mfc_buf_size_v6 *buf_size = dev->variant->buf_size->priv; |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 319 | int ret; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 320 | |
| 321 | mfc_debug_enter(); |
| 322 | |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 323 | dev->ctx_buf.size = buf_size->dev_ctx; |
Marek Szyprowski | 1af2198 | 2015-06-03 07:36:23 -0300 | [diff] [blame] | 324 | ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, |
| 325 | &dev->ctx_buf); |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 326 | if (ret) { |
| 327 | mfc_err("Failed to allocate device context buffer\n"); |
| 328 | return ret; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 329 | } |
| 330 | |
| 331 | memset(dev->ctx_buf.virt, 0, buf_size->dev_ctx); |
| 332 | wmb(); |
| 333 | |
| 334 | mfc_debug_leave(); |
| 335 | |
| 336 | return 0; |
| 337 | } |
| 338 | |
| 339 | /* Release context buffers for SYS_INIT */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 340 | static void s5p_mfc_release_dev_context_buffer_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 341 | { |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 342 | s5p_mfc_release_priv_buf(dev->mem_dev_l, &dev->ctx_buf); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 343 | } |
| 344 | |
| 345 | static int calc_plane(int width, int height) |
| 346 | { |
| 347 | int mbX, mbY; |
| 348 | |
| 349 | mbX = DIV_ROUND_UP(width, S5P_FIMV_NUM_PIXELS_IN_MB_ROW_V6); |
| 350 | mbY = DIV_ROUND_UP(height, S5P_FIMV_NUM_PIXELS_IN_MB_COL_V6); |
| 351 | |
| 352 | if (width * height < S5P_FIMV_MAX_FRAME_SIZE_V6) |
| 353 | mbY = (mbY + 1) / 2 * 2; |
| 354 | |
| 355 | return (mbX * S5P_FIMV_NUM_PIXELS_IN_MB_COL_V6) * |
| 356 | (mbY * S5P_FIMV_NUM_PIXELS_IN_MB_ROW_V6); |
| 357 | } |
| 358 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 359 | static void s5p_mfc_dec_calc_dpb_size_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 360 | { |
| 361 | ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12MT_HALIGN_V6); |
| 362 | ctx->buf_height = ALIGN(ctx->img_height, S5P_FIMV_NV12MT_VALIGN_V6); |
| 363 | mfc_debug(2, "SEQ Done: Movie dimensions %dx%d,\n" |
| 364 | "buffer dimensions: %dx%d\n", ctx->img_width, |
| 365 | ctx->img_height, ctx->buf_width, ctx->buf_height); |
| 366 | |
| 367 | ctx->luma_size = calc_plane(ctx->img_width, ctx->img_height); |
| 368 | ctx->chroma_size = calc_plane(ctx->img_width, (ctx->img_height >> 1)); |
Kiran AVND | e2b9deb | 2014-05-19 09:50:01 -0300 | [diff] [blame] | 369 | if (IS_MFCV8(ctx->dev)) { |
| 370 | /* MFCv8 needs additional 64 bytes for luma,chroma dpb*/ |
| 371 | ctx->luma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8; |
| 372 | ctx->chroma_size += S5P_FIMV_D_ALIGN_PLANE_SIZE_V8; |
| 373 | } |
| 374 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 375 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || |
| 376 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) { |
| 377 | ctx->mv_size = S5P_MFC_DEC_MV_SIZE_V6(ctx->img_width, |
| 378 | ctx->img_height); |
| 379 | ctx->mv_size = ALIGN(ctx->mv_size, 16); |
| 380 | } else { |
| 381 | ctx->mv_size = 0; |
| 382 | } |
| 383 | } |
| 384 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 385 | static void s5p_mfc_enc_calc_src_size_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 386 | { |
| 387 | unsigned int mb_width, mb_height; |
| 388 | |
| 389 | mb_width = MB_WIDTH(ctx->img_width); |
| 390 | mb_height = MB_HEIGHT(ctx->img_height); |
| 391 | |
| 392 | ctx->buf_width = ALIGN(ctx->img_width, S5P_FIMV_NV12M_HALIGN_V6); |
| 393 | ctx->luma_size = ALIGN((mb_width * mb_height) * 256, 256); |
| 394 | ctx->chroma_size = ALIGN((mb_width * mb_height) * 128, 256); |
Arun Kumar K | debe626 | 2013-07-09 01:24:39 -0300 | [diff] [blame] | 395 | |
| 396 | /* MFCv7 needs pad bytes for Luma and Chroma */ |
Arun Kumar K | 109b794 | 2014-05-19 09:33:06 -0300 | [diff] [blame] | 397 | if (IS_MFCV7_PLUS(ctx->dev)) { |
Arun Kumar K | debe626 | 2013-07-09 01:24:39 -0300 | [diff] [blame] | 398 | ctx->luma_size += MFC_LUMA_PAD_BYTES_V7; |
| 399 | ctx->chroma_size += MFC_CHROMA_PAD_BYTES_V7; |
| 400 | } |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 401 | } |
| 402 | |
| 403 | /* Set registers for decoding stream buffer */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 404 | static int s5p_mfc_set_dec_stream_buffer_v6(struct s5p_mfc_ctx *ctx, |
| 405 | int buf_addr, unsigned int start_num_byte, |
| 406 | unsigned int strm_size) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 407 | { |
| 408 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 409 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 410 | struct s5p_mfc_buf_size *buf_size = dev->variant->buf_size; |
| 411 | |
| 412 | mfc_debug_enter(); |
| 413 | mfc_debug(2, "inst_no: %d, buf_addr: 0x%08x,\n" |
| 414 | "buf_size: 0x%08x (%d)\n", |
| 415 | ctx->inst_no, buf_addr, strm_size, strm_size); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 416 | writel(strm_size, mfc_regs->d_stream_data_size); |
| 417 | writel(buf_addr, mfc_regs->d_cpb_buffer_addr); |
| 418 | writel(buf_size->cpb, mfc_regs->d_cpb_buffer_size); |
| 419 | writel(start_num_byte, mfc_regs->d_cpb_buffer_offset); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 420 | |
| 421 | mfc_debug_leave(); |
| 422 | return 0; |
| 423 | } |
| 424 | |
| 425 | /* Set decoding frame buffer */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 426 | static int s5p_mfc_set_dec_frame_buffer_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 427 | { |
| 428 | unsigned int frame_size, i; |
| 429 | unsigned int frame_size_ch, frame_size_mv; |
| 430 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 431 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 432 | size_t buf_addr1; |
| 433 | int buf_size1; |
| 434 | int align_gap; |
| 435 | |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 436 | buf_addr1 = ctx->bank1.dma; |
| 437 | buf_size1 = ctx->bank1.size; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 438 | |
| 439 | mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); |
| 440 | mfc_debug(2, "Total DPB COUNT: %d\n", ctx->total_dpb_count); |
| 441 | mfc_debug(2, "Setting display delay to %d\n", ctx->display_delay); |
| 442 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 443 | writel(ctx->total_dpb_count, mfc_regs->d_num_dpb); |
| 444 | writel(ctx->luma_size, mfc_regs->d_first_plane_dpb_size); |
| 445 | writel(ctx->chroma_size, mfc_regs->d_second_plane_dpb_size); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 446 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 447 | writel(buf_addr1, mfc_regs->d_scratch_buffer_addr); |
| 448 | writel(ctx->scratch_buf_size, mfc_regs->d_scratch_buffer_size); |
Kiran AVND | e2b9deb | 2014-05-19 09:50:01 -0300 | [diff] [blame] | 449 | |
| 450 | if (IS_MFCV8(dev)) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 451 | writel(ctx->img_width, |
Kiran AVND | e2b9deb | 2014-05-19 09:50:01 -0300 | [diff] [blame] | 452 | mfc_regs->d_first_plane_dpb_stride_size); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 453 | writel(ctx->img_width, |
Kiran AVND | e2b9deb | 2014-05-19 09:50:01 -0300 | [diff] [blame] | 454 | mfc_regs->d_second_plane_dpb_stride_size); |
| 455 | } |
| 456 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 457 | buf_addr1 += ctx->scratch_buf_size; |
| 458 | buf_size1 -= ctx->scratch_buf_size; |
| 459 | |
| 460 | if (ctx->codec_mode == S5P_FIMV_CODEC_H264_DEC || |
| 461 | ctx->codec_mode == S5P_FIMV_CODEC_H264_MVC_DEC){ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 462 | writel(ctx->mv_size, mfc_regs->d_mv_buffer_size); |
| 463 | writel(ctx->mv_count, mfc_regs->d_num_mv); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 464 | } |
| 465 | |
| 466 | frame_size = ctx->luma_size; |
| 467 | frame_size_ch = ctx->chroma_size; |
| 468 | frame_size_mv = ctx->mv_size; |
| 469 | mfc_debug(2, "Frame size: %d ch: %d mv: %d\n", |
| 470 | frame_size, frame_size_ch, frame_size_mv); |
| 471 | |
| 472 | for (i = 0; i < ctx->total_dpb_count; i++) { |
| 473 | /* Bank2 */ |
Mauro Carvalho Chehab | 4966bac | 2014-09-24 18:43:59 -0300 | [diff] [blame] | 474 | mfc_debug(2, "Luma %d: %zx\n", i, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 475 | ctx->dst_bufs[i].cookie.raw.luma); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 476 | writel(ctx->dst_bufs[i].cookie.raw.luma, |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 477 | mfc_regs->d_first_plane_dpb + i * 4); |
Mauro Carvalho Chehab | 4966bac | 2014-09-24 18:43:59 -0300 | [diff] [blame] | 478 | mfc_debug(2, "\tChroma %d: %zx\n", i, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 479 | ctx->dst_bufs[i].cookie.raw.chroma); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 480 | writel(ctx->dst_bufs[i].cookie.raw.chroma, |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 481 | mfc_regs->d_second_plane_dpb + i * 4); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 482 | } |
| 483 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_DEC || |
| 484 | ctx->codec_mode == S5P_MFC_CODEC_H264_MVC_DEC) { |
| 485 | for (i = 0; i < ctx->mv_count; i++) { |
| 486 | /* To test alignment */ |
| 487 | align_gap = buf_addr1; |
| 488 | buf_addr1 = ALIGN(buf_addr1, 16); |
| 489 | align_gap = buf_addr1 - align_gap; |
| 490 | buf_size1 -= align_gap; |
| 491 | |
Mauro Carvalho Chehab | 4966bac | 2014-09-24 18:43:59 -0300 | [diff] [blame] | 492 | mfc_debug(2, "\tBuf1: %zx, size: %d\n", |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 493 | buf_addr1, buf_size1); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 494 | writel(buf_addr1, mfc_regs->d_mv_buffer + i * 4); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 495 | buf_addr1 += frame_size_mv; |
| 496 | buf_size1 -= frame_size_mv; |
| 497 | } |
| 498 | } |
| 499 | |
Mauro Carvalho Chehab | 4966bac | 2014-09-24 18:43:59 -0300 | [diff] [blame] | 500 | mfc_debug(2, "Buf1: %zu, buf_size1: %d (frames %d)\n", |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 501 | buf_addr1, buf_size1, ctx->total_dpb_count); |
| 502 | if (buf_size1 < 0) { |
| 503 | mfc_debug(2, "Not enough memory has been allocated.\n"); |
| 504 | return -ENOMEM; |
| 505 | } |
| 506 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 507 | writel(ctx->inst_no, mfc_regs->instance_id); |
| 508 | s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 509 | S5P_FIMV_CH_INIT_BUFS_V6, NULL); |
| 510 | |
| 511 | mfc_debug(2, "After setting buffers.\n"); |
| 512 | return 0; |
| 513 | } |
| 514 | |
| 515 | /* Set registers for encoding stream buffer */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 516 | static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 517 | unsigned long addr, unsigned int size) |
| 518 | { |
| 519 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 520 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 521 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 522 | writel(addr, mfc_regs->e_stream_buffer_addr); /* 16B align */ |
| 523 | writel(size, mfc_regs->e_stream_buffer_size); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 524 | |
Joe Perches | f5b5fbd | 2015-08-02 17:30:53 -0300 | [diff] [blame] | 525 | mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%x\n", |
Andrzej Hajda | 4130eab | 2013-05-28 03:26:16 -0300 | [diff] [blame] | 526 | addr, size); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 527 | |
| 528 | return 0; |
| 529 | } |
| 530 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 531 | static void s5p_mfc_set_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 532 | unsigned long y_addr, unsigned long c_addr) |
| 533 | { |
| 534 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 535 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 536 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 537 | writel(y_addr, mfc_regs->e_source_first_plane_addr); |
| 538 | writel(c_addr, mfc_regs->e_source_second_plane_addr); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 539 | |
Andrzej Hajda | 4130eab | 2013-05-28 03:26:16 -0300 | [diff] [blame] | 540 | mfc_debug(2, "enc src y buf addr: 0x%08lx\n", y_addr); |
| 541 | mfc_debug(2, "enc src c buf addr: 0x%08lx\n", c_addr); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 542 | } |
| 543 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 544 | static void s5p_mfc_get_enc_frame_buffer_v6(struct s5p_mfc_ctx *ctx, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 545 | unsigned long *y_addr, unsigned long *c_addr) |
| 546 | { |
| 547 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 548 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 549 | unsigned long enc_recon_y_addr, enc_recon_c_addr; |
| 550 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 551 | *y_addr = readl(mfc_regs->e_encoded_source_first_plane_addr); |
| 552 | *c_addr = readl(mfc_regs->e_encoded_source_second_plane_addr); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 553 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 554 | enc_recon_y_addr = readl(mfc_regs->e_recon_luma_dpb_addr); |
| 555 | enc_recon_c_addr = readl(mfc_regs->e_recon_chroma_dpb_addr); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 556 | |
Andrzej Hajda | 96c5777 | 2015-10-07 07:15:31 -0300 | [diff] [blame] | 557 | mfc_debug(2, "recon y addr: 0x%08lx y_addr: 0x%08lx\n", enc_recon_y_addr, *y_addr); |
Andrzej Hajda | 4130eab | 2013-05-28 03:26:16 -0300 | [diff] [blame] | 558 | mfc_debug(2, "recon c addr: 0x%08lx\n", enc_recon_c_addr); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 559 | } |
| 560 | |
| 561 | /* Set encoding ref & codec buffer */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 562 | static int s5p_mfc_set_enc_ref_buffer_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 563 | { |
| 564 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 565 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Sachin Kamat | 4a9c85a | 2013-01-02 06:45:49 -0300 | [diff] [blame] | 566 | size_t buf_addr1; |
| 567 | int i, buf_size1; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 568 | |
| 569 | mfc_debug_enter(); |
| 570 | |
Kamil Debski | 317b4ca | 2013-01-03 07:06:04 -0300 | [diff] [blame] | 571 | buf_addr1 = ctx->bank1.dma; |
| 572 | buf_size1 = ctx->bank1.size; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 573 | |
| 574 | mfc_debug(2, "Buf1: %p (%d)\n", (void *)buf_addr1, buf_size1); |
| 575 | |
Arun Kumar K | e9d98dd | 2013-04-24 09:41:53 -0300 | [diff] [blame] | 576 | for (i = 0; i < ctx->pb_count; i++) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 577 | writel(buf_addr1, mfc_regs->e_luma_dpb + (4 * i)); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 578 | buf_addr1 += ctx->luma_dpb_size; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 579 | writel(buf_addr1, mfc_regs->e_chroma_dpb + (4 * i)); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 580 | buf_addr1 += ctx->chroma_dpb_size; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 581 | writel(buf_addr1, mfc_regs->e_me_buffer + (4 * i)); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 582 | buf_addr1 += ctx->me_buffer_size; |
| 583 | buf_size1 -= (ctx->luma_dpb_size + ctx->chroma_dpb_size + |
| 584 | ctx->me_buffer_size); |
| 585 | } |
| 586 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 587 | writel(buf_addr1, mfc_regs->e_scratch_buffer_addr); |
| 588 | writel(ctx->scratch_buf_size, mfc_regs->e_scratch_buffer_size); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 589 | buf_addr1 += ctx->scratch_buf_size; |
| 590 | buf_size1 -= ctx->scratch_buf_size; |
| 591 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 592 | writel(buf_addr1, mfc_regs->e_tmv_buffer0); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 593 | buf_addr1 += ctx->tmv_buffer_size >> 1; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 594 | writel(buf_addr1, mfc_regs->e_tmv_buffer1); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 595 | buf_addr1 += ctx->tmv_buffer_size >> 1; |
| 596 | buf_size1 -= ctx->tmv_buffer_size; |
| 597 | |
Mauro Carvalho Chehab | 4966bac | 2014-09-24 18:43:59 -0300 | [diff] [blame] | 598 | mfc_debug(2, "Buf1: %zu, buf_size1: %d (ref frames %d)\n", |
Arun Kumar K | e9d98dd | 2013-04-24 09:41:53 -0300 | [diff] [blame] | 599 | buf_addr1, buf_size1, ctx->pb_count); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 600 | if (buf_size1 < 0) { |
| 601 | mfc_debug(2, "Not enough memory has been allocated.\n"); |
| 602 | return -ENOMEM; |
| 603 | } |
| 604 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 605 | writel(ctx->inst_no, mfc_regs->instance_id); |
| 606 | s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 607 | S5P_FIMV_CH_INIT_BUFS_V6, NULL); |
| 608 | |
| 609 | mfc_debug_leave(); |
| 610 | |
| 611 | return 0; |
| 612 | } |
| 613 | |
| 614 | static int s5p_mfc_set_slice_mode(struct s5p_mfc_ctx *ctx) |
| 615 | { |
| 616 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 617 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 618 | |
| 619 | /* multi-slice control */ |
| 620 | /* multi-slice MB number or bit size */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 621 | writel(ctx->slice_mode, mfc_regs->e_mslice_mode); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 622 | if (ctx->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 623 | writel(ctx->slice_size.mb, mfc_regs->e_mslice_size_mb); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 624 | } else if (ctx->slice_mode == |
| 625 | V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 626 | writel(ctx->slice_size.bits, mfc_regs->e_mslice_size_bits); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 627 | } else { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 628 | writel(0x0, mfc_regs->e_mslice_size_mb); |
| 629 | writel(0x0, mfc_regs->e_mslice_size_bits); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 630 | } |
| 631 | |
| 632 | return 0; |
| 633 | } |
| 634 | |
| 635 | static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) |
| 636 | { |
| 637 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 638 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 639 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 640 | unsigned int reg = 0; |
| 641 | |
| 642 | mfc_debug_enter(); |
| 643 | |
| 644 | /* width */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 645 | writel(ctx->img_width, mfc_regs->e_frame_width); /* 16 align */ |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 646 | /* height */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 647 | writel(ctx->img_height, mfc_regs->e_frame_height); /* 16 align */ |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 648 | |
| 649 | /* cropped width */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 650 | writel(ctx->img_width, mfc_regs->e_cropped_frame_width); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 651 | /* cropped height */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 652 | writel(ctx->img_height, mfc_regs->e_cropped_frame_height); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 653 | /* cropped offset */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 654 | writel(0x0, mfc_regs->e_frame_crop_offset); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 655 | |
| 656 | /* pictype : IDR period */ |
| 657 | reg = 0; |
| 658 | reg |= p->gop_size & 0xFFFF; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 659 | writel(reg, mfc_regs->e_gop_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 660 | |
| 661 | /* multi-slice control */ |
| 662 | /* multi-slice MB number or bit size */ |
| 663 | ctx->slice_mode = p->slice_mode; |
| 664 | reg = 0; |
| 665 | if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { |
| 666 | reg |= (0x1 << 3); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 667 | writel(reg, mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 668 | ctx->slice_size.mb = p->slice_mb; |
| 669 | } else if (p->slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { |
| 670 | reg |= (0x1 << 3); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 671 | writel(reg, mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 672 | ctx->slice_size.bits = p->slice_bit; |
| 673 | } else { |
| 674 | reg &= ~(0x1 << 3); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 675 | writel(reg, mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 676 | } |
| 677 | |
| 678 | s5p_mfc_set_slice_mode(ctx); |
| 679 | |
| 680 | /* cyclic intra refresh */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 681 | writel(p->intra_refresh_mb, mfc_regs->e_ir_size); |
| 682 | reg = readl(mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 683 | if (p->intra_refresh_mb == 0) |
| 684 | reg &= ~(0x1 << 4); |
| 685 | else |
| 686 | reg |= (0x1 << 4); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 687 | writel(reg, mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 688 | |
| 689 | /* 'NON_REFERENCE_STORE_ENABLE' for debugging */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 690 | reg = readl(mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 691 | reg &= ~(0x1 << 9); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 692 | writel(reg, mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 693 | |
| 694 | /* memory structure cur. frame */ |
| 695 | if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12M) { |
| 696 | /* 0: Linear, 1: 2D tiled*/ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 697 | reg = readl(mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 698 | reg &= ~(0x1 << 7); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 699 | writel(reg, mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 700 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 701 | writel(0x0, mfc_regs->pixel_format); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 702 | } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV21M) { |
| 703 | /* 0: Linear, 1: 2D tiled*/ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 704 | reg = readl(mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 705 | reg &= ~(0x1 << 7); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 706 | writel(reg, mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 707 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 708 | writel(0x1, mfc_regs->pixel_format); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 709 | } else if (ctx->src_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) { |
| 710 | /* 0: Linear, 1: 2D tiled*/ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 711 | reg = readl(mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 712 | reg |= (0x1 << 7); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 713 | writel(reg, mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 714 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 715 | writel(0x0, mfc_regs->pixel_format); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 716 | } |
| 717 | |
| 718 | /* memory structure recon. frame */ |
| 719 | /* 0: Linear, 1: 2D tiled */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 720 | reg = readl(mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 721 | reg |= (0x1 << 8); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 722 | writel(reg, mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 723 | |
| 724 | /* padding control & value */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 725 | writel(0x0, mfc_regs->e_padding_ctrl); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 726 | if (p->pad) { |
| 727 | reg = 0; |
| 728 | /** enable */ |
| 729 | reg |= (1 << 31); |
| 730 | /** cr value */ |
| 731 | reg |= ((p->pad_cr & 0xFF) << 16); |
| 732 | /** cb value */ |
| 733 | reg |= ((p->pad_cb & 0xFF) << 8); |
| 734 | /** y value */ |
| 735 | reg |= p->pad_luma & 0xFF; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 736 | writel(reg, mfc_regs->e_padding_ctrl); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 737 | } |
| 738 | |
| 739 | /* rate control config. */ |
| 740 | reg = 0; |
| 741 | /* frame-level rate control */ |
| 742 | reg |= ((p->rc_frame & 0x1) << 9); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 743 | writel(reg, mfc_regs->e_rc_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 744 | |
| 745 | /* bit rate */ |
| 746 | if (p->rc_frame) |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 747 | writel(p->rc_bitrate, |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 748 | mfc_regs->e_rc_bit_rate); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 749 | else |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 750 | writel(1, mfc_regs->e_rc_bit_rate); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 751 | |
| 752 | /* reaction coefficient */ |
| 753 | if (p->rc_frame) { |
| 754 | if (p->rc_reaction_coeff < TIGHT_CBR_MAX) /* tight CBR */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 755 | writel(1, mfc_regs->e_rc_mode); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 756 | else /* loose CBR */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 757 | writel(2, mfc_regs->e_rc_mode); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 758 | } |
| 759 | |
| 760 | /* seq header ctrl */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 761 | reg = readl(mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 762 | reg &= ~(0x1 << 2); |
| 763 | reg |= ((p->seq_hdr_mode & 0x1) << 2); |
| 764 | |
| 765 | /* frame skip mode */ |
| 766 | reg &= ~(0x3); |
| 767 | reg |= (p->frame_skip_mode & 0x3); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 768 | writel(reg, mfc_regs->e_enc_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 769 | |
| 770 | /* 'DROP_CONTROL_ENABLE', disable */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 771 | reg = readl(mfc_regs->e_rc_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 772 | reg &= ~(0x1 << 10); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 773 | writel(reg, mfc_regs->e_rc_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 774 | |
| 775 | /* setting for MV range [16, 256] */ |
Amit Grover | a378a32 | 2014-02-04 06:59:59 -0300 | [diff] [blame] | 776 | reg = (p->mv_h_range & S5P_FIMV_E_MV_RANGE_V6_MASK); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 777 | writel(reg, mfc_regs->e_mv_hor_range); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 778 | |
Amit Grover | a378a32 | 2014-02-04 06:59:59 -0300 | [diff] [blame] | 779 | reg = (p->mv_v_range & S5P_FIMV_E_MV_RANGE_V6_MASK); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 780 | writel(reg, mfc_regs->e_mv_ver_range); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 781 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 782 | writel(0x0, mfc_regs->e_frame_insertion); |
| 783 | writel(0x0, mfc_regs->e_roi_buffer_addr); |
| 784 | writel(0x0, mfc_regs->e_param_change); |
| 785 | writel(0x0, mfc_regs->e_rc_roi_ctrl); |
| 786 | writel(0x0, mfc_regs->e_picture_tag); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 787 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 788 | writel(0x0, mfc_regs->e_bit_count_enable); |
| 789 | writel(0x0, mfc_regs->e_max_bit_count); |
| 790 | writel(0x0, mfc_regs->e_min_bit_count); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 791 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 792 | writel(0x0, mfc_regs->e_metadata_buffer_addr); |
| 793 | writel(0x0, mfc_regs->e_metadata_buffer_size); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 794 | |
| 795 | mfc_debug_leave(); |
| 796 | |
| 797 | return 0; |
| 798 | } |
| 799 | |
| 800 | static int s5p_mfc_set_enc_params_h264(struct s5p_mfc_ctx *ctx) |
| 801 | { |
| 802 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 803 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 804 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 805 | struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264; |
| 806 | unsigned int reg = 0; |
| 807 | int i; |
| 808 | |
| 809 | mfc_debug_enter(); |
| 810 | |
| 811 | s5p_mfc_set_enc_params(ctx); |
| 812 | |
| 813 | /* pictype : number of B */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 814 | reg = readl(mfc_regs->e_gop_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 815 | reg &= ~(0x3 << 16); |
| 816 | reg |= ((p->num_b_frame & 0x3) << 16); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 817 | writel(reg, mfc_regs->e_gop_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 818 | |
| 819 | /* profile & level */ |
| 820 | reg = 0; |
| 821 | /** level */ |
| 822 | reg |= ((p_h264->level & 0xFF) << 8); |
| 823 | /** profile - 0 ~ 3 */ |
| 824 | reg |= p_h264->profile & 0x3F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 825 | writel(reg, mfc_regs->e_picture_profile); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 826 | |
| 827 | /* rate control config. */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 828 | reg = readl(mfc_regs->e_rc_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 829 | /** macroblock level rate control */ |
| 830 | reg &= ~(0x1 << 8); |
| 831 | reg |= ((p->rc_mb & 0x1) << 8); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 832 | writel(reg, mfc_regs->e_rc_config); |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 833 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 834 | /** frame QP */ |
| 835 | reg &= ~(0x3F); |
| 836 | reg |= p_h264->rc_frame_qp & 0x3F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 837 | writel(reg, mfc_regs->e_rc_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 838 | |
| 839 | /* max & min value of QP */ |
| 840 | reg = 0; |
| 841 | /** max QP */ |
| 842 | reg |= ((p_h264->rc_max_qp & 0x3F) << 8); |
| 843 | /** min QP */ |
| 844 | reg |= p_h264->rc_min_qp & 0x3F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 845 | writel(reg, mfc_regs->e_rc_qp_bound); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 846 | |
| 847 | /* other QPs */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 848 | writel(0x0, mfc_regs->e_fixed_picture_qp); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 849 | if (!p->rc_frame && !p->rc_mb) { |
| 850 | reg = 0; |
| 851 | reg |= ((p_h264->rc_b_frame_qp & 0x3F) << 16); |
| 852 | reg |= ((p_h264->rc_p_frame_qp & 0x3F) << 8); |
| 853 | reg |= p_h264->rc_frame_qp & 0x3F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 854 | writel(reg, mfc_regs->e_fixed_picture_qp); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 855 | } |
| 856 | |
| 857 | /* frame rate */ |
| 858 | if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) { |
| 859 | reg = 0; |
| 860 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); |
| 861 | reg |= p->rc_framerate_denom & 0xFFFF; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 862 | writel(reg, mfc_regs->e_rc_frame_rate); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 863 | } |
| 864 | |
| 865 | /* vbv buffer size */ |
| 866 | if (p->frame_skip_mode == |
| 867 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 868 | writel(p_h264->cpb_size & 0xFFFF, |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 869 | mfc_regs->e_vbv_buffer_size); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 870 | |
| 871 | if (p->rc_frame) |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 872 | writel(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 873 | } |
| 874 | |
| 875 | /* interlace */ |
| 876 | reg = 0; |
| 877 | reg |= ((p_h264->interlace & 0x1) << 3); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 878 | writel(reg, mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 879 | |
| 880 | /* height */ |
| 881 | if (p_h264->interlace) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 882 | writel(ctx->img_height >> 1, |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 883 | mfc_regs->e_frame_height); /* 32 align */ |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 884 | /* cropped height */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 885 | writel(ctx->img_height >> 1, |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 886 | mfc_regs->e_cropped_frame_height); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 887 | } |
| 888 | |
| 889 | /* loop filter ctrl */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 890 | reg = readl(mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 891 | reg &= ~(0x3 << 1); |
| 892 | reg |= ((p_h264->loop_filter_mode & 0x3) << 1); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 893 | writel(reg, mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 894 | |
| 895 | /* loopfilter alpha offset */ |
| 896 | if (p_h264->loop_filter_alpha < 0) { |
| 897 | reg = 0x10; |
| 898 | reg |= (0xFF - p_h264->loop_filter_alpha) + 1; |
| 899 | } else { |
| 900 | reg = 0x00; |
| 901 | reg |= (p_h264->loop_filter_alpha & 0xF); |
| 902 | } |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 903 | writel(reg, mfc_regs->e_h264_lf_alpha_offset); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 904 | |
| 905 | /* loopfilter beta offset */ |
| 906 | if (p_h264->loop_filter_beta < 0) { |
| 907 | reg = 0x10; |
| 908 | reg |= (0xFF - p_h264->loop_filter_beta) + 1; |
| 909 | } else { |
| 910 | reg = 0x00; |
| 911 | reg |= (p_h264->loop_filter_beta & 0xF); |
| 912 | } |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 913 | writel(reg, mfc_regs->e_h264_lf_beta_offset); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 914 | |
| 915 | /* entropy coding mode */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 916 | reg = readl(mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 917 | reg &= ~(0x1); |
| 918 | reg |= p_h264->entropy_mode & 0x1; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 919 | writel(reg, mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 920 | |
| 921 | /* number of ref. picture */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 922 | reg = readl(mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 923 | reg &= ~(0x1 << 7); |
| 924 | reg |= (((p_h264->num_ref_pic_4p - 1) & 0x1) << 7); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 925 | writel(reg, mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 926 | |
| 927 | /* 8x8 transform enable */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 928 | reg = readl(mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 929 | reg &= ~(0x3 << 12); |
| 930 | reg |= ((p_h264->_8x8_transform & 0x3) << 12); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 931 | writel(reg, mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 932 | |
| 933 | /* macroblock adaptive scaling features */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 934 | writel(0x0, mfc_regs->e_mb_rc_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 935 | if (p->rc_mb) { |
| 936 | reg = 0; |
| 937 | /** dark region */ |
| 938 | reg |= ((p_h264->rc_mb_dark & 0x1) << 3); |
| 939 | /** smooth region */ |
| 940 | reg |= ((p_h264->rc_mb_smooth & 0x1) << 2); |
| 941 | /** static region */ |
| 942 | reg |= ((p_h264->rc_mb_static & 0x1) << 1); |
| 943 | /** high activity region */ |
| 944 | reg |= p_h264->rc_mb_activity & 0x1; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 945 | writel(reg, mfc_regs->e_mb_rc_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 946 | } |
| 947 | |
| 948 | /* aspect ratio VUI */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 949 | readl(mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 950 | reg &= ~(0x1 << 5); |
| 951 | reg |= ((p_h264->vui_sar & 0x1) << 5); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 952 | writel(reg, mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 953 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 954 | writel(0x0, mfc_regs->e_aspect_ratio); |
| 955 | writel(0x0, mfc_regs->e_extended_sar); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 956 | if (p_h264->vui_sar) { |
| 957 | /* aspect ration IDC */ |
| 958 | reg = 0; |
| 959 | reg |= p_h264->vui_sar_idc & 0xFF; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 960 | writel(reg, mfc_regs->e_aspect_ratio); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 961 | if (p_h264->vui_sar_idc == 0xFF) { |
| 962 | /* extended SAR */ |
| 963 | reg = 0; |
| 964 | reg |= (p_h264->vui_ext_sar_width & 0xFFFF) << 16; |
| 965 | reg |= p_h264->vui_ext_sar_height & 0xFFFF; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 966 | writel(reg, mfc_regs->e_extended_sar); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 967 | } |
| 968 | } |
| 969 | |
| 970 | /* intra picture period for H.264 open GOP */ |
| 971 | /* control */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 972 | readl(mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 973 | reg &= ~(0x1 << 4); |
| 974 | reg |= ((p_h264->open_gop & 0x1) << 4); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 975 | writel(reg, mfc_regs->e_h264_options); |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 976 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 977 | /* value */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 978 | writel(0x0, mfc_regs->e_h264_i_period); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 979 | if (p_h264->open_gop) { |
| 980 | reg = 0; |
| 981 | reg |= p_h264->open_gop_size & 0xFFFF; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 982 | writel(reg, mfc_regs->e_h264_i_period); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 983 | } |
| 984 | |
| 985 | /* 'WEIGHTED_BI_PREDICTION' for B is disable */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 986 | readl(mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 987 | reg &= ~(0x3 << 9); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 988 | writel(reg, mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 989 | |
| 990 | /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 991 | readl(mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 992 | reg &= ~(0x1 << 14); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 993 | writel(reg, mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 994 | |
| 995 | /* ASO */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 996 | readl(mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 997 | reg &= ~(0x1 << 6); |
| 998 | reg |= ((p_h264->aso & 0x1) << 6); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 999 | writel(reg, mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1000 | |
| 1001 | /* hier qp enable */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1002 | readl(mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1003 | reg &= ~(0x1 << 8); |
| 1004 | reg |= ((p_h264->open_gop & 0x1) << 8); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1005 | writel(reg, mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1006 | reg = 0; |
| 1007 | if (p_h264->hier_qp && p_h264->hier_qp_layer) { |
| 1008 | reg |= (p_h264->hier_qp_type & 0x1) << 0x3; |
| 1009 | reg |= p_h264->hier_qp_layer & 0x7; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1010 | writel(reg, mfc_regs->e_h264_num_t_layer); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1011 | /* QP value for each layer */ |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1012 | for (i = 0; i < p_h264->hier_qp_layer && |
| 1013 | i < ARRAY_SIZE(p_h264->hier_qp_layer_qp); i++) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1014 | writel(p_h264->hier_qp_layer_qp[i], |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1015 | mfc_regs->e_h264_hierarchical_qp_layer0 |
| 1016 | + i * 4); |
| 1017 | } |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1018 | } |
| 1019 | /* number of coding layer should be zero when hierarchical is disable */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1020 | writel(reg, mfc_regs->e_h264_num_t_layer); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1021 | |
| 1022 | /* frame packing SEI generation */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1023 | readl(mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1024 | reg &= ~(0x1 << 25); |
| 1025 | reg |= ((p_h264->sei_frame_packing & 0x1) << 25); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1026 | writel(reg, mfc_regs->e_h264_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1027 | if (p_h264->sei_frame_packing) { |
| 1028 | reg = 0; |
| 1029 | /** current frame0 flag */ |
| 1030 | reg |= ((p_h264->sei_fp_curr_frame_0 & 0x1) << 2); |
| 1031 | /** arrangement type */ |
| 1032 | reg |= p_h264->sei_fp_arrangement_type & 0x3; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1033 | writel(reg, mfc_regs->e_h264_frame_packing_sei_info); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1034 | } |
| 1035 | |
| 1036 | if (p_h264->fmo) { |
| 1037 | switch (p_h264->fmo_map_type) { |
| 1038 | case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES: |
| 1039 | if (p_h264->fmo_slice_grp > 4) |
| 1040 | p_h264->fmo_slice_grp = 4; |
| 1041 | for (i = 0; i < (p_h264->fmo_slice_grp & 0xF); i++) |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1042 | writel(p_h264->fmo_run_len[i] - 1, |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1043 | mfc_regs->e_h264_fmo_run_length_minus1_0 |
| 1044 | + i * 4); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1045 | break; |
| 1046 | case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES: |
| 1047 | if (p_h264->fmo_slice_grp > 4) |
| 1048 | p_h264->fmo_slice_grp = 4; |
| 1049 | break; |
| 1050 | case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN: |
| 1051 | case V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN: |
| 1052 | if (p_h264->fmo_slice_grp > 2) |
| 1053 | p_h264->fmo_slice_grp = 2; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1054 | writel(p_h264->fmo_chg_dir & 0x1, |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1055 | mfc_regs->e_h264_fmo_slice_grp_change_dir); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1056 | /* the valid range is 0 ~ number of macroblocks -1 */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1057 | writel(p_h264->fmo_chg_rate, |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1058 | mfc_regs->e_h264_fmo_slice_grp_change_rate_minus1); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1059 | break; |
| 1060 | default: |
| 1061 | mfc_err("Unsupported map type for FMO: %d\n", |
| 1062 | p_h264->fmo_map_type); |
| 1063 | p_h264->fmo_map_type = 0; |
| 1064 | p_h264->fmo_slice_grp = 1; |
| 1065 | break; |
| 1066 | } |
| 1067 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1068 | writel(p_h264->fmo_map_type, |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1069 | mfc_regs->e_h264_fmo_slice_grp_map_type); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1070 | writel(p_h264->fmo_slice_grp - 1, |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1071 | mfc_regs->e_h264_fmo_num_slice_grp_minus1); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1072 | } else { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1073 | writel(0, mfc_regs->e_h264_fmo_num_slice_grp_minus1); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1074 | } |
| 1075 | |
| 1076 | mfc_debug_leave(); |
| 1077 | |
| 1078 | return 0; |
| 1079 | } |
| 1080 | |
| 1081 | static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) |
| 1082 | { |
| 1083 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1084 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1085 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 1086 | struct s5p_mfc_mpeg4_enc_params *p_mpeg4 = &p->codec.mpeg4; |
| 1087 | unsigned int reg = 0; |
| 1088 | |
| 1089 | mfc_debug_enter(); |
| 1090 | |
| 1091 | s5p_mfc_set_enc_params(ctx); |
| 1092 | |
| 1093 | /* pictype : number of B */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1094 | reg = readl(mfc_regs->e_gop_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1095 | reg &= ~(0x3 << 16); |
| 1096 | reg |= ((p->num_b_frame & 0x3) << 16); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1097 | writel(reg, mfc_regs->e_gop_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1098 | |
| 1099 | /* profile & level */ |
| 1100 | reg = 0; |
| 1101 | /** level */ |
| 1102 | reg |= ((p_mpeg4->level & 0xFF) << 8); |
| 1103 | /** profile - 0 ~ 1 */ |
| 1104 | reg |= p_mpeg4->profile & 0x3F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1105 | writel(reg, mfc_regs->e_picture_profile); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1106 | |
| 1107 | /* rate control config. */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1108 | reg = readl(mfc_regs->e_rc_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1109 | /** macroblock level rate control */ |
| 1110 | reg &= ~(0x1 << 8); |
| 1111 | reg |= ((p->rc_mb & 0x1) << 8); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1112 | writel(reg, mfc_regs->e_rc_config); |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1113 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1114 | /** frame QP */ |
| 1115 | reg &= ~(0x3F); |
| 1116 | reg |= p_mpeg4->rc_frame_qp & 0x3F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1117 | writel(reg, mfc_regs->e_rc_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1118 | |
| 1119 | /* max & min value of QP */ |
| 1120 | reg = 0; |
| 1121 | /** max QP */ |
| 1122 | reg |= ((p_mpeg4->rc_max_qp & 0x3F) << 8); |
| 1123 | /** min QP */ |
| 1124 | reg |= p_mpeg4->rc_min_qp & 0x3F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1125 | writel(reg, mfc_regs->e_rc_qp_bound); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1126 | |
| 1127 | /* other QPs */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1128 | writel(0x0, mfc_regs->e_fixed_picture_qp); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1129 | if (!p->rc_frame && !p->rc_mb) { |
| 1130 | reg = 0; |
| 1131 | reg |= ((p_mpeg4->rc_b_frame_qp & 0x3F) << 16); |
| 1132 | reg |= ((p_mpeg4->rc_p_frame_qp & 0x3F) << 8); |
| 1133 | reg |= p_mpeg4->rc_frame_qp & 0x3F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1134 | writel(reg, mfc_regs->e_fixed_picture_qp); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1135 | } |
| 1136 | |
| 1137 | /* frame rate */ |
| 1138 | if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) { |
| 1139 | reg = 0; |
| 1140 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); |
| 1141 | reg |= p->rc_framerate_denom & 0xFFFF; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1142 | writel(reg, mfc_regs->e_rc_frame_rate); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1143 | } |
| 1144 | |
| 1145 | /* vbv buffer size */ |
| 1146 | if (p->frame_skip_mode == |
| 1147 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1148 | writel(p->vbv_size & 0xFFFF, mfc_regs->e_vbv_buffer_size); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1149 | |
| 1150 | if (p->rc_frame) |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1151 | writel(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1152 | } |
| 1153 | |
| 1154 | /* Disable HEC */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1155 | writel(0x0, mfc_regs->e_mpeg4_options); |
| 1156 | writel(0x0, mfc_regs->e_mpeg4_hec_period); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1157 | |
| 1158 | mfc_debug_leave(); |
| 1159 | |
| 1160 | return 0; |
| 1161 | } |
| 1162 | |
| 1163 | static int s5p_mfc_set_enc_params_h263(struct s5p_mfc_ctx *ctx) |
| 1164 | { |
| 1165 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1166 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1167 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 1168 | struct s5p_mfc_mpeg4_enc_params *p_h263 = &p->codec.mpeg4; |
| 1169 | unsigned int reg = 0; |
| 1170 | |
| 1171 | mfc_debug_enter(); |
| 1172 | |
| 1173 | s5p_mfc_set_enc_params(ctx); |
| 1174 | |
| 1175 | /* profile & level */ |
| 1176 | reg = 0; |
| 1177 | /** profile */ |
| 1178 | reg |= (0x1 << 4); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1179 | writel(reg, mfc_regs->e_picture_profile); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1180 | |
| 1181 | /* rate control config. */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1182 | reg = readl(mfc_regs->e_rc_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1183 | /** macroblock level rate control */ |
| 1184 | reg &= ~(0x1 << 8); |
| 1185 | reg |= ((p->rc_mb & 0x1) << 8); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1186 | writel(reg, mfc_regs->e_rc_config); |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1187 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1188 | /** frame QP */ |
| 1189 | reg &= ~(0x3F); |
| 1190 | reg |= p_h263->rc_frame_qp & 0x3F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1191 | writel(reg, mfc_regs->e_rc_config); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1192 | |
| 1193 | /* max & min value of QP */ |
| 1194 | reg = 0; |
| 1195 | /** max QP */ |
| 1196 | reg |= ((p_h263->rc_max_qp & 0x3F) << 8); |
| 1197 | /** min QP */ |
| 1198 | reg |= p_h263->rc_min_qp & 0x3F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1199 | writel(reg, mfc_regs->e_rc_qp_bound); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1200 | |
| 1201 | /* other QPs */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1202 | writel(0x0, mfc_regs->e_fixed_picture_qp); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1203 | if (!p->rc_frame && !p->rc_mb) { |
| 1204 | reg = 0; |
| 1205 | reg |= ((p_h263->rc_b_frame_qp & 0x3F) << 16); |
| 1206 | reg |= ((p_h263->rc_p_frame_qp & 0x3F) << 8); |
| 1207 | reg |= p_h263->rc_frame_qp & 0x3F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1208 | writel(reg, mfc_regs->e_fixed_picture_qp); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1209 | } |
| 1210 | |
| 1211 | /* frame rate */ |
| 1212 | if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) { |
| 1213 | reg = 0; |
| 1214 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); |
| 1215 | reg |= p->rc_framerate_denom & 0xFFFF; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1216 | writel(reg, mfc_regs->e_rc_frame_rate); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1217 | } |
| 1218 | |
| 1219 | /* vbv buffer size */ |
| 1220 | if (p->frame_skip_mode == |
| 1221 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1222 | writel(p->vbv_size & 0xFFFF, mfc_regs->e_vbv_buffer_size); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1223 | |
| 1224 | if (p->rc_frame) |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1225 | writel(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1226 | } |
| 1227 | |
| 1228 | mfc_debug_leave(); |
| 1229 | |
| 1230 | return 0; |
| 1231 | } |
| 1232 | |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1233 | static int s5p_mfc_set_enc_params_vp8(struct s5p_mfc_ctx *ctx) |
| 1234 | { |
| 1235 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1236 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1237 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 1238 | struct s5p_mfc_vp8_enc_params *p_vp8 = &p->codec.vp8; |
| 1239 | unsigned int reg = 0; |
| 1240 | unsigned int val = 0; |
| 1241 | |
| 1242 | mfc_debug_enter(); |
| 1243 | |
| 1244 | s5p_mfc_set_enc_params(ctx); |
| 1245 | |
| 1246 | /* pictype : number of B */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1247 | reg = readl(mfc_regs->e_gop_config); |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1248 | reg &= ~(0x3 << 16); |
| 1249 | reg |= ((p->num_b_frame & 0x3) << 16); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1250 | writel(reg, mfc_regs->e_gop_config); |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1251 | |
Kiran AVND | bbd8f3f | 2013-12-16 06:40:42 -0300 | [diff] [blame] | 1252 | /* profile - 0 ~ 3 */ |
| 1253 | reg = p_vp8->profile & 0x3; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1254 | writel(reg, mfc_regs->e_picture_profile); |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1255 | |
| 1256 | /* rate control config. */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1257 | reg = readl(mfc_regs->e_rc_config); |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1258 | /** macroblock level rate control */ |
| 1259 | reg &= ~(0x1 << 8); |
| 1260 | reg |= ((p->rc_mb & 0x1) << 8); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1261 | writel(reg, mfc_regs->e_rc_config); |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1262 | |
| 1263 | /* frame rate */ |
| 1264 | if (p->rc_frame && p->rc_framerate_num && p->rc_framerate_denom) { |
| 1265 | reg = 0; |
| 1266 | reg |= ((p->rc_framerate_num & 0xFFFF) << 16); |
| 1267 | reg |= p->rc_framerate_denom & 0xFFFF; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1268 | writel(reg, mfc_regs->e_rc_frame_rate); |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1269 | } |
| 1270 | |
Arun Kumar K | 4773ab9 | 2013-11-15 02:29:22 -0300 | [diff] [blame] | 1271 | /* frame QP */ |
| 1272 | reg &= ~(0x7F); |
| 1273 | reg |= p_vp8->rc_frame_qp & 0x7F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1274 | writel(reg, mfc_regs->e_rc_config); |
Arun Kumar K | 4773ab9 | 2013-11-15 02:29:22 -0300 | [diff] [blame] | 1275 | |
| 1276 | /* other QPs */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1277 | writel(0x0, mfc_regs->e_fixed_picture_qp); |
Arun Kumar K | 4773ab9 | 2013-11-15 02:29:22 -0300 | [diff] [blame] | 1278 | if (!p->rc_frame && !p->rc_mb) { |
| 1279 | reg = 0; |
| 1280 | reg |= ((p_vp8->rc_p_frame_qp & 0x7F) << 8); |
| 1281 | reg |= p_vp8->rc_frame_qp & 0x7F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1282 | writel(reg, mfc_regs->e_fixed_picture_qp); |
Arun Kumar K | 4773ab9 | 2013-11-15 02:29:22 -0300 | [diff] [blame] | 1283 | } |
| 1284 | |
| 1285 | /* max QP */ |
| 1286 | reg = ((p_vp8->rc_max_qp & 0x7F) << 8); |
| 1287 | /* min QP */ |
| 1288 | reg |= p_vp8->rc_min_qp & 0x7F; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1289 | writel(reg, mfc_regs->e_rc_qp_bound); |
Arun Kumar K | 4773ab9 | 2013-11-15 02:29:22 -0300 | [diff] [blame] | 1290 | |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1291 | /* vbv buffer size */ |
| 1292 | if (p->frame_skip_mode == |
| 1293 | V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1294 | writel(p->vbv_size & 0xFFFF, mfc_regs->e_vbv_buffer_size); |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1295 | |
| 1296 | if (p->rc_frame) |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1297 | writel(p->vbv_delay, mfc_regs->e_vbv_init_delay); |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1298 | } |
| 1299 | |
| 1300 | /* VP8 specific params */ |
| 1301 | reg = 0; |
| 1302 | reg |= (p_vp8->imd_4x4 & 0x1) << 10; |
| 1303 | switch (p_vp8->num_partitions) { |
| 1304 | case V4L2_CID_MPEG_VIDEO_VPX_1_PARTITION: |
| 1305 | val = 0; |
| 1306 | break; |
| 1307 | case V4L2_CID_MPEG_VIDEO_VPX_2_PARTITIONS: |
| 1308 | val = 2; |
| 1309 | break; |
| 1310 | case V4L2_CID_MPEG_VIDEO_VPX_4_PARTITIONS: |
| 1311 | val = 4; |
| 1312 | break; |
| 1313 | case V4L2_CID_MPEG_VIDEO_VPX_8_PARTITIONS: |
| 1314 | val = 8; |
| 1315 | break; |
| 1316 | } |
| 1317 | reg |= (val & 0xF) << 3; |
| 1318 | reg |= (p_vp8->num_ref & 0x2); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1319 | writel(reg, mfc_regs->e_vp8_options); |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1320 | |
| 1321 | mfc_debug_leave(); |
| 1322 | |
| 1323 | return 0; |
| 1324 | } |
| 1325 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1326 | /* Initialize decoding */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1327 | static int s5p_mfc_init_decode_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1328 | { |
| 1329 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1330 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1331 | unsigned int reg = 0; |
| 1332 | int fmo_aso_ctrl = 0; |
| 1333 | |
| 1334 | mfc_debug_enter(); |
| 1335 | mfc_debug(2, "InstNo: %d/%d\n", ctx->inst_no, |
| 1336 | S5P_FIMV_CH_SEQ_HEADER_V6); |
| 1337 | mfc_debug(2, "BUFs: %08x %08x %08x\n", |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1338 | readl(mfc_regs->d_cpb_buffer_addr), |
| 1339 | readl(mfc_regs->d_cpb_buffer_addr), |
| 1340 | readl(mfc_regs->d_cpb_buffer_addr)); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1341 | |
| 1342 | /* FMO_ASO_CTRL - 0: Enable, 1: Disable */ |
| 1343 | reg |= (fmo_aso_ctrl << S5P_FIMV_D_OPT_FMO_ASO_CTRL_MASK_V6); |
| 1344 | |
Nicolas Dufresne | 1b880ef | 2014-12-15 18:10:57 -0300 | [diff] [blame] | 1345 | if (ctx->display_delay_enable) { |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1346 | reg |= (0x1 << S5P_FIMV_D_OPT_DDELAY_EN_SHIFT_V6); |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1347 | writel(ctx->display_delay, mfc_regs->d_display_delay); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1348 | } |
Arun Kumar K | debe626 | 2013-07-09 01:24:39 -0300 | [diff] [blame] | 1349 | |
Arun Kumar K | 9ab10e4 | 2014-05-21 06:29:31 -0300 | [diff] [blame] | 1350 | if (IS_MFCV7_PLUS(dev) || IS_MFCV6_V2(dev)) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1351 | writel(reg, mfc_regs->d_dec_options); |
Arun Kumar K | debe626 | 2013-07-09 01:24:39 -0300 | [diff] [blame] | 1352 | reg = 0; |
| 1353 | } |
| 1354 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1355 | /* Setup loop filter, for decoding this is only valid for MPEG4 */ |
| 1356 | if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_DEC) { |
| 1357 | mfc_debug(2, "Set loop filter to: %d\n", |
| 1358 | ctx->loop_filter_mpeg4); |
| 1359 | reg |= (ctx->loop_filter_mpeg4 << |
| 1360 | S5P_FIMV_D_OPT_LF_CTRL_SHIFT_V6); |
| 1361 | } |
| 1362 | if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV12MT_16X16) |
| 1363 | reg |= (0x1 << S5P_FIMV_D_OPT_TILE_MODE_SHIFT_V6); |
| 1364 | |
Arun Kumar K | 9ab10e4 | 2014-05-21 06:29:31 -0300 | [diff] [blame] | 1365 | if (IS_MFCV7_PLUS(dev) || IS_MFCV6_V2(dev)) |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1366 | writel(reg, mfc_regs->d_init_buffer_options); |
Arun Kumar K | debe626 | 2013-07-09 01:24:39 -0300 | [diff] [blame] | 1367 | else |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1368 | writel(reg, mfc_regs->d_dec_options); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1369 | |
| 1370 | /* 0: NV12(CbCr), 1: NV21(CrCb) */ |
| 1371 | if (ctx->dst_fmt->fourcc == V4L2_PIX_FMT_NV21M) |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1372 | writel(0x1, mfc_regs->pixel_format); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1373 | else |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1374 | writel(0x0, mfc_regs->pixel_format); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1375 | |
Arun Kumar K | debe626 | 2013-07-09 01:24:39 -0300 | [diff] [blame] | 1376 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1377 | /* sei parse */ |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1378 | writel(ctx->sei_fp_parse & 0x1, mfc_regs->d_sei_enable); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1379 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1380 | writel(ctx->inst_no, mfc_regs->instance_id); |
| 1381 | s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1382 | S5P_FIMV_CH_SEQ_HEADER_V6, NULL); |
| 1383 | |
| 1384 | mfc_debug_leave(); |
| 1385 | return 0; |
| 1386 | } |
| 1387 | |
| 1388 | static inline void s5p_mfc_set_flush(struct s5p_mfc_ctx *ctx, int flush) |
| 1389 | { |
| 1390 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1391 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Arun Kumar K | 8f23cc0 | 2012-11-22 06:15:55 -0300 | [diff] [blame] | 1392 | |
| 1393 | if (flush) { |
| 1394 | dev->curr_ctx = ctx->num; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1395 | writel(ctx->inst_no, mfc_regs->instance_id); |
| 1396 | s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, |
Arun Kumar K | 8f23cc0 | 2012-11-22 06:15:55 -0300 | [diff] [blame] | 1397 | S5P_FIMV_H2R_CMD_FLUSH_V6, NULL); |
| 1398 | } |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1399 | } |
| 1400 | |
| 1401 | /* Decode a single frame */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1402 | static int s5p_mfc_decode_one_frame_v6(struct s5p_mfc_ctx *ctx, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1403 | enum s5p_mfc_decode_arg last_frame) |
| 1404 | { |
| 1405 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1406 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1407 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1408 | writel(ctx->dec_dst_flag, mfc_regs->d_available_dpb_flag_lower); |
| 1409 | writel(ctx->slice_interface & 0x1, mfc_regs->d_slice_if_enable); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1410 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1411 | writel(ctx->inst_no, mfc_regs->instance_id); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1412 | /* Issue different commands to instance basing on whether it |
| 1413 | * is the last frame or not. */ |
| 1414 | switch (last_frame) { |
| 1415 | case 0: |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1416 | s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1417 | S5P_FIMV_CH_FRAME_START_V6, NULL); |
| 1418 | break; |
| 1419 | case 1: |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1420 | s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1421 | S5P_FIMV_CH_LAST_FRAME_V6, NULL); |
| 1422 | break; |
| 1423 | default: |
| 1424 | mfc_err("Unsupported last frame arg.\n"); |
| 1425 | return -EINVAL; |
| 1426 | } |
| 1427 | |
| 1428 | mfc_debug(2, "Decoding a usual frame.\n"); |
| 1429 | return 0; |
| 1430 | } |
| 1431 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1432 | static int s5p_mfc_init_encode_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1433 | { |
| 1434 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1435 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1436 | |
| 1437 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) |
| 1438 | s5p_mfc_set_enc_params_h264(ctx); |
| 1439 | else if (ctx->codec_mode == S5P_MFC_CODEC_MPEG4_ENC) |
| 1440 | s5p_mfc_set_enc_params_mpeg4(ctx); |
| 1441 | else if (ctx->codec_mode == S5P_MFC_CODEC_H263_ENC) |
| 1442 | s5p_mfc_set_enc_params_h263(ctx); |
Arun Kumar K | 3a96770 | 2013-07-09 01:24:42 -0300 | [diff] [blame] | 1443 | else if (ctx->codec_mode == S5P_MFC_CODEC_VP8_ENC) |
| 1444 | s5p_mfc_set_enc_params_vp8(ctx); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1445 | else { |
| 1446 | mfc_err("Unknown codec for encoding (%x).\n", |
| 1447 | ctx->codec_mode); |
| 1448 | return -EINVAL; |
| 1449 | } |
| 1450 | |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1451 | /* Set stride lengths for v7 & above */ |
Arun Kumar K | 109b794 | 2014-05-19 09:33:06 -0300 | [diff] [blame] | 1452 | if (IS_MFCV7_PLUS(dev)) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1453 | writel(ctx->img_width, mfc_regs->e_source_first_plane_stride); |
| 1454 | writel(ctx->img_width, mfc_regs->e_source_second_plane_stride); |
Arun Kumar K | debe626 | 2013-07-09 01:24:39 -0300 | [diff] [blame] | 1455 | } |
| 1456 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1457 | writel(ctx->inst_no, mfc_regs->instance_id); |
| 1458 | s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1459 | S5P_FIMV_CH_SEQ_HEADER_V6, NULL); |
| 1460 | |
| 1461 | return 0; |
| 1462 | } |
| 1463 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1464 | static int s5p_mfc_h264_set_aso_slice_order_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1465 | { |
| 1466 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1467 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1468 | struct s5p_mfc_enc_params *p = &ctx->enc_params; |
| 1469 | struct s5p_mfc_h264_enc_params *p_h264 = &p->codec.h264; |
| 1470 | int i; |
| 1471 | |
| 1472 | if (p_h264->aso) { |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1473 | for (i = 0; i < ARRAY_SIZE(p_h264->aso_slice_order); i++) { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1474 | writel(p_h264->aso_slice_order[i], |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1475 | mfc_regs->e_h264_aso_slice_order_0 + i * 4); |
| 1476 | } |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1477 | } |
| 1478 | return 0; |
| 1479 | } |
| 1480 | |
| 1481 | /* Encode a single frame */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1482 | static int s5p_mfc_encode_one_frame_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1483 | { |
| 1484 | struct s5p_mfc_dev *dev = ctx->dev; |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1485 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Andrzej Hajda | 96c5777 | 2015-10-07 07:15:31 -0300 | [diff] [blame] | 1486 | int cmd; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1487 | |
| 1488 | mfc_debug(2, "++\n"); |
| 1489 | |
| 1490 | /* memory structure cur. frame */ |
| 1491 | |
| 1492 | if (ctx->codec_mode == S5P_MFC_CODEC_H264_ENC) |
| 1493 | s5p_mfc_h264_set_aso_slice_order_v6(ctx); |
| 1494 | |
| 1495 | s5p_mfc_set_slice_mode(ctx); |
| 1496 | |
Andrzej Hajda | 96c5777 | 2015-10-07 07:15:31 -0300 | [diff] [blame] | 1497 | if (ctx->state != MFCINST_FINISHING) |
| 1498 | cmd = S5P_FIMV_CH_FRAME_START_V6; |
| 1499 | else |
| 1500 | cmd = S5P_FIMV_CH_LAST_FRAME_V6; |
| 1501 | |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1502 | writel(ctx->inst_no, mfc_regs->instance_id); |
Andrzej Hajda | 96c5777 | 2015-10-07 07:15:31 -0300 | [diff] [blame] | 1503 | s5p_mfc_hw_call_void(dev->mfc_cmds, cmd_host2risc, dev, cmd, NULL); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1504 | |
| 1505 | mfc_debug(2, "--\n"); |
| 1506 | |
| 1507 | return 0; |
| 1508 | } |
| 1509 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1510 | static inline void s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx) |
| 1511 | { |
| 1512 | struct s5p_mfc_dev *dev = ctx->dev; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1513 | |
Kiran AVND | 1625864 | 2014-10-21 08:07:04 -0300 | [diff] [blame] | 1514 | s5p_mfc_set_dec_stream_buffer_v6(ctx, 0, 0, 0); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1515 | dev->curr_ctx = ctx->num; |
Kiran AVND | 1625864 | 2014-10-21 08:07:04 -0300 | [diff] [blame] | 1516 | s5p_mfc_decode_one_frame_v6(ctx, MFC_DEC_LAST_FRAME); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1517 | } |
| 1518 | |
| 1519 | static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx) |
| 1520 | { |
| 1521 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1522 | struct s5p_mfc_buf *temp_vb; |
| 1523 | unsigned long flags; |
| 1524 | int last_frame = 0; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1525 | |
Kamil Debski | a34026e | 2013-01-11 12:29:33 -0300 | [diff] [blame] | 1526 | if (ctx->state == MFCINST_FINISHING) { |
| 1527 | last_frame = MFC_DEC_LAST_FRAME; |
| 1528 | s5p_mfc_set_dec_stream_buffer_v6(ctx, 0, 0, 0); |
| 1529 | dev->curr_ctx = ctx->num; |
| 1530 | s5p_mfc_clean_ctx_int_flags(ctx); |
| 1531 | s5p_mfc_decode_one_frame_v6(ctx, last_frame); |
| 1532 | return 0; |
| 1533 | } |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1534 | |
Kamil Debski | a34026e | 2013-01-11 12:29:33 -0300 | [diff] [blame] | 1535 | spin_lock_irqsave(&dev->irqlock, flags); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1536 | /* Frames are being decoded */ |
| 1537 | if (list_empty(&ctx->src_queue)) { |
| 1538 | mfc_debug(2, "No src buffers.\n"); |
| 1539 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 1540 | return -EAGAIN; |
| 1541 | } |
| 1542 | /* Get the next source buffer */ |
| 1543 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); |
| 1544 | temp_vb->flags |= MFC_BUF_FLAG_USED; |
| 1545 | s5p_mfc_set_dec_stream_buffer_v6(ctx, |
Junghak Sung | 2d70071 | 2015-09-22 10:30:30 -0300 | [diff] [blame] | 1546 | vb2_dma_contig_plane_dma_addr(&temp_vb->b->vb2_buf, 0), |
Andrzej Hajda | 96c5777 | 2015-10-07 07:15:31 -0300 | [diff] [blame] | 1547 | ctx->consumed_stream, |
| 1548 | temp_vb->b->vb2_buf.planes[0].bytesused); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1549 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 1550 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1551 | dev->curr_ctx = ctx->num; |
Junghak Sung | 2d70071 | 2015-09-22 10:30:30 -0300 | [diff] [blame] | 1552 | if (temp_vb->b->vb2_buf.planes[0].bytesused == 0) { |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1553 | last_frame = 1; |
| 1554 | mfc_debug(2, "Setting ctx->state to FINISHING\n"); |
| 1555 | ctx->state = MFCINST_FINISHING; |
| 1556 | } |
| 1557 | s5p_mfc_decode_one_frame_v6(ctx, last_frame); |
| 1558 | |
| 1559 | return 0; |
| 1560 | } |
| 1561 | |
| 1562 | static inline int s5p_mfc_run_enc_frame(struct s5p_mfc_ctx *ctx) |
| 1563 | { |
| 1564 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1565 | unsigned long flags; |
| 1566 | struct s5p_mfc_buf *dst_mb; |
| 1567 | struct s5p_mfc_buf *src_mb; |
| 1568 | unsigned long src_y_addr, src_c_addr, dst_addr; |
| 1569 | /* |
| 1570 | unsigned int src_y_size, src_c_size; |
| 1571 | */ |
| 1572 | unsigned int dst_size; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1573 | |
| 1574 | spin_lock_irqsave(&dev->irqlock, flags); |
| 1575 | |
Andrzej Hajda | 96c5777 | 2015-10-07 07:15:31 -0300 | [diff] [blame] | 1576 | if (list_empty(&ctx->src_queue) && ctx->state != MFCINST_FINISHING) { |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1577 | mfc_debug(2, "no src buffers.\n"); |
| 1578 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 1579 | return -EAGAIN; |
| 1580 | } |
| 1581 | |
| 1582 | if (list_empty(&ctx->dst_queue)) { |
| 1583 | mfc_debug(2, "no dst buffers.\n"); |
| 1584 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 1585 | return -EAGAIN; |
| 1586 | } |
| 1587 | |
Andrzej Hajda | 96c5777 | 2015-10-07 07:15:31 -0300 | [diff] [blame] | 1588 | if (list_empty(&ctx->src_queue)) { |
| 1589 | /* send null frame */ |
| 1590 | s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0); |
| 1591 | src_mb = NULL; |
| 1592 | } else { |
| 1593 | src_mb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); |
| 1594 | src_mb->flags |= MFC_BUF_FLAG_USED; |
| 1595 | if (src_mb->b->vb2_buf.planes[0].bytesused == 0) { |
| 1596 | s5p_mfc_set_enc_frame_buffer_v6(ctx, 0, 0); |
| 1597 | ctx->state = MFCINST_FINISHING; |
| 1598 | } else { |
| 1599 | src_y_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 0); |
| 1600 | src_c_addr = vb2_dma_contig_plane_dma_addr(&src_mb->b->vb2_buf, 1); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1601 | |
Andrzej Hajda | 96c5777 | 2015-10-07 07:15:31 -0300 | [diff] [blame] | 1602 | mfc_debug(2, "enc src y addr: 0x%08lx\n", src_y_addr); |
| 1603 | mfc_debug(2, "enc src c addr: 0x%08lx\n", src_c_addr); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1604 | |
Andrzej Hajda | 96c5777 | 2015-10-07 07:15:31 -0300 | [diff] [blame] | 1605 | s5p_mfc_set_enc_frame_buffer_v6(ctx, src_y_addr, src_c_addr); |
| 1606 | if (src_mb->flags & MFC_BUF_FLAG_EOS) |
| 1607 | ctx->state = MFCINST_FINISHING; |
| 1608 | } |
| 1609 | } |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1610 | |
| 1611 | dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); |
| 1612 | dst_mb->flags |= MFC_BUF_FLAG_USED; |
Junghak Sung | 2d70071 | 2015-09-22 10:30:30 -0300 | [diff] [blame] | 1613 | dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0); |
| 1614 | dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1615 | |
| 1616 | s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size); |
| 1617 | |
| 1618 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 1619 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1620 | dev->curr_ctx = ctx->num; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1621 | s5p_mfc_encode_one_frame_v6(ctx); |
| 1622 | |
| 1623 | return 0; |
| 1624 | } |
| 1625 | |
| 1626 | static inline void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx) |
| 1627 | { |
| 1628 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1629 | unsigned long flags; |
| 1630 | struct s5p_mfc_buf *temp_vb; |
| 1631 | |
| 1632 | /* Initializing decoding - parsing header */ |
| 1633 | spin_lock_irqsave(&dev->irqlock, flags); |
| 1634 | mfc_debug(2, "Preparing to init decoding.\n"); |
| 1635 | temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); |
Andrzej Hajda | 96c5777 | 2015-10-07 07:15:31 -0300 | [diff] [blame] | 1636 | mfc_debug(2, "Header size: %d\n", temp_vb->b->vb2_buf.planes[0].bytesused); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1637 | s5p_mfc_set_dec_stream_buffer_v6(ctx, |
Junghak Sung | 2d70071 | 2015-09-22 10:30:30 -0300 | [diff] [blame] | 1638 | vb2_dma_contig_plane_dma_addr(&temp_vb->b->vb2_buf, 0), 0, |
Andrzej Hajda | 96c5777 | 2015-10-07 07:15:31 -0300 | [diff] [blame] | 1639 | temp_vb->b->vb2_buf.planes[0].bytesused); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1640 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 1641 | dev->curr_ctx = ctx->num; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1642 | s5p_mfc_init_decode_v6(ctx); |
| 1643 | } |
| 1644 | |
| 1645 | static inline void s5p_mfc_run_init_enc(struct s5p_mfc_ctx *ctx) |
| 1646 | { |
| 1647 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1648 | unsigned long flags; |
| 1649 | struct s5p_mfc_buf *dst_mb; |
| 1650 | unsigned long dst_addr; |
| 1651 | unsigned int dst_size; |
| 1652 | |
| 1653 | spin_lock_irqsave(&dev->irqlock, flags); |
| 1654 | |
| 1655 | dst_mb = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, list); |
Junghak Sung | 2d70071 | 2015-09-22 10:30:30 -0300 | [diff] [blame] | 1656 | dst_addr = vb2_dma_contig_plane_dma_addr(&dst_mb->b->vb2_buf, 0); |
| 1657 | dst_size = vb2_plane_size(&dst_mb->b->vb2_buf, 0); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1658 | s5p_mfc_set_enc_stream_buffer_v6(ctx, dst_addr, dst_size); |
| 1659 | spin_unlock_irqrestore(&dev->irqlock, flags); |
| 1660 | dev->curr_ctx = ctx->num; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1661 | s5p_mfc_init_encode_v6(ctx); |
| 1662 | } |
| 1663 | |
| 1664 | static inline int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx) |
| 1665 | { |
| 1666 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1667 | int ret; |
| 1668 | /* Header was parsed now start processing |
| 1669 | * First set the output frame buffers |
| 1670 | * s5p_mfc_alloc_dec_buffers(ctx); */ |
| 1671 | |
| 1672 | if (ctx->capture_state != QUEUE_BUFS_MMAPED) { |
| 1673 | mfc_err("It seems that not all destionation buffers were\n" |
| 1674 | "mmaped.MFC requires that all destination are mmaped\n" |
| 1675 | "before starting processing.\n"); |
| 1676 | return -EAGAIN; |
| 1677 | } |
| 1678 | |
| 1679 | dev->curr_ctx = ctx->num; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1680 | ret = s5p_mfc_set_dec_frame_buffer_v6(ctx); |
| 1681 | if (ret) { |
| 1682 | mfc_err("Failed to alloc frame mem.\n"); |
| 1683 | ctx->state = MFCINST_ERROR; |
| 1684 | } |
| 1685 | return ret; |
| 1686 | } |
| 1687 | |
| 1688 | static inline int s5p_mfc_run_init_enc_buffers(struct s5p_mfc_ctx *ctx) |
| 1689 | { |
| 1690 | struct s5p_mfc_dev *dev = ctx->dev; |
| 1691 | int ret; |
| 1692 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1693 | dev->curr_ctx = ctx->num; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1694 | ret = s5p_mfc_set_enc_ref_buffer_v6(ctx); |
| 1695 | if (ret) { |
| 1696 | mfc_err("Failed to alloc frame mem.\n"); |
| 1697 | ctx->state = MFCINST_ERROR; |
| 1698 | } |
| 1699 | return ret; |
| 1700 | } |
| 1701 | |
| 1702 | /* Try running an operation on hardware */ |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1703 | static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1704 | { |
| 1705 | struct s5p_mfc_ctx *ctx; |
| 1706 | int new_ctx; |
| 1707 | unsigned int ret = 0; |
| 1708 | |
| 1709 | mfc_debug(1, "Try run dev: %p\n", dev); |
| 1710 | |
| 1711 | /* Check whether hardware is not running */ |
| 1712 | if (test_and_set_bit(0, &dev->hw_lock) != 0) { |
| 1713 | /* This is perfectly ok, the scheduled ctx should wait */ |
| 1714 | mfc_debug(1, "Couldn't lock HW.\n"); |
| 1715 | return; |
| 1716 | } |
| 1717 | |
| 1718 | /* Choose the context to run */ |
| 1719 | new_ctx = s5p_mfc_get_new_ctx(dev); |
| 1720 | if (new_ctx < 0) { |
| 1721 | /* No contexts to run */ |
| 1722 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) { |
| 1723 | mfc_err("Failed to unlock hardware.\n"); |
| 1724 | return; |
| 1725 | } |
| 1726 | |
| 1727 | mfc_debug(1, "No ctx is scheduled to be run.\n"); |
| 1728 | return; |
| 1729 | } |
| 1730 | |
| 1731 | mfc_debug(1, "New context: %d\n", new_ctx); |
| 1732 | ctx = dev->ctx[new_ctx]; |
Masanari Iida | 971bd8f | 2015-05-20 23:54:02 +0900 | [diff] [blame] | 1733 | mfc_debug(1, "Setting new context to %p\n", ctx); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1734 | /* Got context to run in ctx */ |
| 1735 | mfc_debug(1, "ctx->dst_queue_cnt=%d ctx->dpb_count=%d ctx->src_queue_cnt=%d\n", |
Arun Kumar K | e9d98dd | 2013-04-24 09:41:53 -0300 | [diff] [blame] | 1736 | ctx->dst_queue_cnt, ctx->pb_count, ctx->src_queue_cnt); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1737 | mfc_debug(1, "ctx->state=%d\n", ctx->state); |
| 1738 | /* Last frame has already been sent to MFC |
| 1739 | * Now obtaining frames from MFC buffer */ |
| 1740 | |
| 1741 | s5p_mfc_clock_on(); |
Pawel Osciak | f203536 | 2014-10-21 08:07:07 -0300 | [diff] [blame] | 1742 | s5p_mfc_clean_ctx_int_flags(ctx); |
| 1743 | |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1744 | if (ctx->type == MFCINST_DECODER) { |
| 1745 | switch (ctx->state) { |
| 1746 | case MFCINST_FINISHING: |
| 1747 | s5p_mfc_run_dec_last_frames(ctx); |
| 1748 | break; |
| 1749 | case MFCINST_RUNNING: |
| 1750 | ret = s5p_mfc_run_dec_frame(ctx); |
| 1751 | break; |
| 1752 | case MFCINST_INIT: |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1753 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, |
| 1754 | ctx); |
| 1755 | break; |
| 1756 | case MFCINST_RETURN_INST: |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1757 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, |
| 1758 | ctx); |
| 1759 | break; |
| 1760 | case MFCINST_GOT_INST: |
| 1761 | s5p_mfc_run_init_dec(ctx); |
| 1762 | break; |
| 1763 | case MFCINST_HEAD_PARSED: |
| 1764 | ret = s5p_mfc_run_init_dec_buffers(ctx); |
| 1765 | break; |
Arun Kumar K | 8f23cc0 | 2012-11-22 06:15:55 -0300 | [diff] [blame] | 1766 | case MFCINST_FLUSH: |
| 1767 | s5p_mfc_set_flush(ctx, ctx->dpb_flush_flag); |
| 1768 | break; |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1769 | case MFCINST_RES_CHANGE_INIT: |
| 1770 | s5p_mfc_run_dec_last_frames(ctx); |
| 1771 | break; |
| 1772 | case MFCINST_RES_CHANGE_FLUSH: |
| 1773 | s5p_mfc_run_dec_last_frames(ctx); |
| 1774 | break; |
| 1775 | case MFCINST_RES_CHANGE_END: |
| 1776 | mfc_debug(2, "Finished remaining frames after resolution change.\n"); |
| 1777 | ctx->capture_state = QUEUE_FREE; |
| 1778 | mfc_debug(2, "Will re-init the codec`.\n"); |
| 1779 | s5p_mfc_run_init_dec(ctx); |
| 1780 | break; |
| 1781 | default: |
| 1782 | ret = -EAGAIN; |
| 1783 | } |
| 1784 | } else if (ctx->type == MFCINST_ENCODER) { |
| 1785 | switch (ctx->state) { |
| 1786 | case MFCINST_FINISHING: |
| 1787 | case MFCINST_RUNNING: |
| 1788 | ret = s5p_mfc_run_enc_frame(ctx); |
| 1789 | break; |
| 1790 | case MFCINST_INIT: |
| 1791 | ret = s5p_mfc_hw_call(dev->mfc_cmds, open_inst_cmd, |
| 1792 | ctx); |
| 1793 | break; |
| 1794 | case MFCINST_RETURN_INST: |
| 1795 | ret = s5p_mfc_hw_call(dev->mfc_cmds, close_inst_cmd, |
| 1796 | ctx); |
| 1797 | break; |
| 1798 | case MFCINST_GOT_INST: |
| 1799 | s5p_mfc_run_init_enc(ctx); |
| 1800 | break; |
Arun Kumar K | e9d98dd | 2013-04-24 09:41:53 -0300 | [diff] [blame] | 1801 | case MFCINST_HEAD_PRODUCED: |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1802 | ret = s5p_mfc_run_init_enc_buffers(ctx); |
| 1803 | break; |
| 1804 | default: |
| 1805 | ret = -EAGAIN; |
| 1806 | } |
| 1807 | } else { |
| 1808 | mfc_err("invalid context type: %d\n", ctx->type); |
| 1809 | ret = -EAGAIN; |
| 1810 | } |
| 1811 | |
| 1812 | if (ret) { |
| 1813 | /* Free hardware lock */ |
| 1814 | if (test_and_clear_bit(0, &dev->hw_lock) == 0) |
| 1815 | mfc_err("Failed to unlock hardware.\n"); |
| 1816 | |
| 1817 | /* This is in deed imporant, as no operation has been |
| 1818 | * scheduled, reduce the clock count as no one will |
| 1819 | * ever do this, because no interrupt related to this try_run |
| 1820 | * will ever come from hardware. */ |
| 1821 | s5p_mfc_clock_off(); |
| 1822 | } |
| 1823 | } |
| 1824 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1825 | static void s5p_mfc_clear_int_flags_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1826 | { |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1827 | const struct s5p_mfc_regs *mfc_regs = dev->mfc_regs; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1828 | writel(0, mfc_regs->risc2host_command); |
| 1829 | writel(0, mfc_regs->risc2host_int); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1830 | } |
| 1831 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1832 | static void s5p_mfc_write_info_v6(struct s5p_mfc_ctx *ctx, unsigned int data, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1833 | unsigned int ofs) |
| 1834 | { |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1835 | s5p_mfc_clock_on(); |
Marek Szyprowski | 1d03def | 2015-05-28 08:11:47 -0300 | [diff] [blame] | 1836 | writel(data, (void __iomem *)((unsigned long)ofs)); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1837 | s5p_mfc_clock_off(); |
| 1838 | } |
| 1839 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1840 | static unsigned int |
Marek Szyprowski | 6c9fe76 | 2015-03-04 10:55:22 -0300 | [diff] [blame] | 1841 | s5p_mfc_read_info_v6(struct s5p_mfc_ctx *ctx, unsigned long ofs) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1842 | { |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1843 | int ret; |
| 1844 | |
| 1845 | s5p_mfc_clock_on(); |
Marek Szyprowski | 1d03def | 2015-05-28 08:11:47 -0300 | [diff] [blame] | 1846 | ret = readl((void __iomem *)ofs); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1847 | s5p_mfc_clock_off(); |
| 1848 | |
| 1849 | return ret; |
| 1850 | } |
| 1851 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1852 | static int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1853 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1854 | return readl(dev->mfc_regs->d_display_first_plane_addr); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1855 | } |
| 1856 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1857 | static int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1858 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1859 | return readl(dev->mfc_regs->d_decoded_first_plane_addr); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1860 | } |
| 1861 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1862 | static int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1863 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1864 | return readl(dev->mfc_regs->d_display_status); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1865 | } |
| 1866 | |
Sylwester Nawrocki | 644469a | 2013-05-25 07:25:55 -0300 | [diff] [blame] | 1867 | static int s5p_mfc_get_dec_status_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1868 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1869 | return readl(dev->mfc_regs->d_decoded_status); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1870 | } |
| 1871 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1872 | static int s5p_mfc_get_dec_frame_type_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1873 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1874 | return readl(dev->mfc_regs->d_decoded_frame_type) & |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1875 | S5P_FIMV_DECODE_FRAME_MASK_V6; |
| 1876 | } |
| 1877 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1878 | static int s5p_mfc_get_disp_frame_type_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1879 | { |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1880 | struct s5p_mfc_dev *dev = ctx->dev; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1881 | return readl(dev->mfc_regs->d_display_frame_type) & |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1882 | S5P_FIMV_DECODE_FRAME_MASK_V6; |
| 1883 | } |
| 1884 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1885 | static int s5p_mfc_get_consumed_stream_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1886 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1887 | return readl(dev->mfc_regs->d_decoded_nal_size); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1888 | } |
| 1889 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1890 | static int s5p_mfc_get_int_reason_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1891 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1892 | return readl(dev->mfc_regs->risc2host_command) & |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1893 | S5P_FIMV_RISC2HOST_CMD_MASK; |
| 1894 | } |
| 1895 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1896 | static int s5p_mfc_get_int_err_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1897 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1898 | return readl(dev->mfc_regs->error_code); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1899 | } |
| 1900 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1901 | static int s5p_mfc_err_dec_v6(unsigned int err) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1902 | { |
| 1903 | return (err & S5P_FIMV_ERR_DEC_MASK_V6) >> S5P_FIMV_ERR_DEC_SHIFT_V6; |
| 1904 | } |
| 1905 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1906 | static int s5p_mfc_err_dspl_v6(unsigned int err) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1907 | { |
| 1908 | return (err & S5P_FIMV_ERR_DSPL_MASK_V6) >> S5P_FIMV_ERR_DSPL_SHIFT_V6; |
| 1909 | } |
| 1910 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1911 | static int s5p_mfc_get_img_width_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1912 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1913 | return readl(dev->mfc_regs->d_display_frame_width); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1914 | } |
| 1915 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1916 | static int s5p_mfc_get_img_height_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1917 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1918 | return readl(dev->mfc_regs->d_display_frame_height); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1919 | } |
| 1920 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1921 | static int s5p_mfc_get_dpb_count_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1922 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1923 | return readl(dev->mfc_regs->d_min_num_dpb); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1924 | } |
| 1925 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1926 | static int s5p_mfc_get_mv_count_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1927 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1928 | return readl(dev->mfc_regs->d_min_num_mv); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1929 | } |
| 1930 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1931 | static int s5p_mfc_get_inst_no_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1932 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1933 | return readl(dev->mfc_regs->ret_instance_id); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1934 | } |
| 1935 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1936 | static int s5p_mfc_get_enc_dpb_count_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1937 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1938 | return readl(dev->mfc_regs->e_num_dpb); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1939 | } |
| 1940 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1941 | static int s5p_mfc_get_enc_strm_size_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1942 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1943 | return readl(dev->mfc_regs->e_stream_size); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1944 | } |
| 1945 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1946 | static int s5p_mfc_get_enc_slice_type_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1947 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1948 | return readl(dev->mfc_regs->e_slice_type); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1949 | } |
| 1950 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1951 | static int s5p_mfc_get_enc_pic_count_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1952 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1953 | return readl(dev->mfc_regs->e_picture_count); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1954 | } |
| 1955 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1956 | static int s5p_mfc_get_sei_avail_status_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1957 | { |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1958 | struct s5p_mfc_dev *dev = ctx->dev; |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1959 | return readl(dev->mfc_regs->d_frame_pack_sei_avail); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1960 | } |
| 1961 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1962 | static int s5p_mfc_get_mvc_num_views_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1963 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1964 | return readl(dev->mfc_regs->d_mvc_num_views); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1965 | } |
| 1966 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1967 | static int s5p_mfc_get_mvc_view_id_v6(struct s5p_mfc_dev *dev) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1968 | { |
Kamil Debski | e2c3be2 | 2014-09-11 10:27:20 -0300 | [diff] [blame] | 1969 | return readl(dev->mfc_regs->d_mvc_view_id); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1970 | } |
| 1971 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1972 | static unsigned int s5p_mfc_get_pic_type_top_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1973 | { |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1974 | return s5p_mfc_read_info_v6(ctx, |
Mauro Carvalho Chehab | 4966bac | 2014-09-24 18:43:59 -0300 | [diff] [blame] | 1975 | (__force unsigned long) ctx->dev->mfc_regs->d_ret_picture_tag_top); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1976 | } |
| 1977 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1978 | static unsigned int s5p_mfc_get_pic_type_bot_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1979 | { |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1980 | return s5p_mfc_read_info_v6(ctx, |
Mauro Carvalho Chehab | 4966bac | 2014-09-24 18:43:59 -0300 | [diff] [blame] | 1981 | (__force unsigned long) ctx->dev->mfc_regs->d_ret_picture_tag_bot); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1982 | } |
| 1983 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1984 | static unsigned int s5p_mfc_get_crop_info_h_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1985 | { |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1986 | return s5p_mfc_read_info_v6(ctx, |
Mauro Carvalho Chehab | 4966bac | 2014-09-24 18:43:59 -0300 | [diff] [blame] | 1987 | (__force unsigned long) ctx->dev->mfc_regs->d_display_crop_info1); |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1988 | } |
| 1989 | |
Sachin Kamat | b9571a5 | 2013-03-02 07:50:13 -0300 | [diff] [blame] | 1990 | static unsigned int s5p_mfc_get_crop_info_v_v6(struct s5p_mfc_ctx *ctx) |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 1991 | { |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1992 | return s5p_mfc_read_info_v6(ctx, |
Mauro Carvalho Chehab | 4966bac | 2014-09-24 18:43:59 -0300 | [diff] [blame] | 1993 | (__force unsigned long) ctx->dev->mfc_regs->d_display_crop_info2); |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 1994 | } |
| 1995 | |
| 1996 | static struct s5p_mfc_regs mfc_regs; |
| 1997 | |
| 1998 | /* Initialize registers for MFC v6 onwards */ |
| 1999 | const struct s5p_mfc_regs *s5p_mfc_init_regs_v6_plus(struct s5p_mfc_dev *dev) |
| 2000 | { |
| 2001 | memset(&mfc_regs, 0, sizeof(mfc_regs)); |
| 2002 | |
| 2003 | #define S5P_MFC_REG_ADDR(dev, reg) ((dev)->regs_base + (reg)) |
| 2004 | #define R(m, r) mfc_regs.m = S5P_MFC_REG_ADDR(dev, r) |
| 2005 | /* codec common registers */ |
| 2006 | R(risc_on, S5P_FIMV_RISC_ON_V6); |
| 2007 | R(risc2host_int, S5P_FIMV_RISC2HOST_INT_V6); |
| 2008 | R(host2risc_int, S5P_FIMV_HOST2RISC_INT_V6); |
| 2009 | R(risc_base_address, S5P_FIMV_RISC_BASE_ADDRESS_V6); |
| 2010 | R(mfc_reset, S5P_FIMV_MFC_RESET_V6); |
| 2011 | R(host2risc_command, S5P_FIMV_HOST2RISC_CMD_V6); |
| 2012 | R(risc2host_command, S5P_FIMV_RISC2HOST_CMD_V6); |
| 2013 | R(firmware_version, S5P_FIMV_FW_VERSION_V6); |
| 2014 | R(instance_id, S5P_FIMV_INSTANCE_ID_V6); |
| 2015 | R(codec_type, S5P_FIMV_CODEC_TYPE_V6); |
| 2016 | R(context_mem_addr, S5P_FIMV_CONTEXT_MEM_ADDR_V6); |
| 2017 | R(context_mem_size, S5P_FIMV_CONTEXT_MEM_SIZE_V6); |
| 2018 | R(pixel_format, S5P_FIMV_PIXEL_FORMAT_V6); |
| 2019 | R(ret_instance_id, S5P_FIMV_RET_INSTANCE_ID_V6); |
| 2020 | R(error_code, S5P_FIMV_ERROR_CODE_V6); |
| 2021 | |
| 2022 | /* decoder registers */ |
| 2023 | R(d_crc_ctrl, S5P_FIMV_D_CRC_CTRL_V6); |
| 2024 | R(d_dec_options, S5P_FIMV_D_DEC_OPTIONS_V6); |
| 2025 | R(d_display_delay, S5P_FIMV_D_DISPLAY_DELAY_V6); |
| 2026 | R(d_sei_enable, S5P_FIMV_D_SEI_ENABLE_V6); |
| 2027 | R(d_min_num_dpb, S5P_FIMV_D_MIN_NUM_DPB_V6); |
| 2028 | R(d_min_num_mv, S5P_FIMV_D_MIN_NUM_MV_V6); |
| 2029 | R(d_mvc_num_views, S5P_FIMV_D_MVC_NUM_VIEWS_V6); |
| 2030 | R(d_num_dpb, S5P_FIMV_D_NUM_DPB_V6); |
| 2031 | R(d_num_mv, S5P_FIMV_D_NUM_MV_V6); |
| 2032 | R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V6); |
| 2033 | R(d_first_plane_dpb_size, S5P_FIMV_D_LUMA_DPB_SIZE_V6); |
| 2034 | R(d_second_plane_dpb_size, S5P_FIMV_D_CHROMA_DPB_SIZE_V6); |
| 2035 | R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V6); |
| 2036 | R(d_first_plane_dpb, S5P_FIMV_D_LUMA_DPB_V6); |
| 2037 | R(d_second_plane_dpb, S5P_FIMV_D_CHROMA_DPB_V6); |
| 2038 | R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V6); |
| 2039 | R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V6); |
| 2040 | R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V6); |
| 2041 | R(d_cpb_buffer_addr, S5P_FIMV_D_CPB_BUFFER_ADDR_V6); |
| 2042 | R(d_cpb_buffer_size, S5P_FIMV_D_CPB_BUFFER_SIZE_V6); |
| 2043 | R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V6); |
| 2044 | R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V6); |
| 2045 | R(d_slice_if_enable, S5P_FIMV_D_SLICE_IF_ENABLE_V6); |
| 2046 | R(d_stream_data_size, S5P_FIMV_D_STREAM_DATA_SIZE_V6); |
| 2047 | R(d_display_frame_width, S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V6); |
| 2048 | R(d_display_frame_height, S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V6); |
| 2049 | R(d_display_status, S5P_FIMV_D_DISPLAY_STATUS_V6); |
| 2050 | R(d_display_first_plane_addr, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6); |
| 2051 | R(d_display_second_plane_addr, S5P_FIMV_D_DISPLAY_CHROMA_ADDR_V6); |
| 2052 | R(d_display_frame_type, S5P_FIMV_D_DISPLAY_FRAME_TYPE_V6); |
| 2053 | R(d_display_crop_info1, S5P_FIMV_D_DISPLAY_CROP_INFO1_V6); |
| 2054 | R(d_display_crop_info2, S5P_FIMV_D_DISPLAY_CROP_INFO2_V6); |
| 2055 | R(d_display_aspect_ratio, S5P_FIMV_D_DISPLAY_ASPECT_RATIO_V6); |
| 2056 | R(d_display_extended_ar, S5P_FIMV_D_DISPLAY_EXTENDED_AR_V6); |
| 2057 | R(d_decoded_status, S5P_FIMV_D_DECODED_STATUS_V6); |
| 2058 | R(d_decoded_first_plane_addr, S5P_FIMV_D_DECODED_LUMA_ADDR_V6); |
| 2059 | R(d_decoded_second_plane_addr, S5P_FIMV_D_DECODED_CHROMA_ADDR_V6); |
| 2060 | R(d_decoded_frame_type, S5P_FIMV_D_DECODED_FRAME_TYPE_V6); |
| 2061 | R(d_decoded_nal_size, S5P_FIMV_D_DECODED_NAL_SIZE_V6); |
| 2062 | R(d_ret_picture_tag_top, S5P_FIMV_D_RET_PICTURE_TAG_TOP_V6); |
| 2063 | R(d_ret_picture_tag_bot, S5P_FIMV_D_RET_PICTURE_TAG_BOT_V6); |
| 2064 | R(d_h264_info, S5P_FIMV_D_H264_INFO_V6); |
| 2065 | R(d_mvc_view_id, S5P_FIMV_D_MVC_VIEW_ID_V6); |
| 2066 | R(d_frame_pack_sei_avail, S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V6); |
| 2067 | |
| 2068 | /* encoder registers */ |
| 2069 | R(e_frame_width, S5P_FIMV_E_FRAME_WIDTH_V6); |
| 2070 | R(e_frame_height, S5P_FIMV_E_FRAME_HEIGHT_V6); |
| 2071 | R(e_cropped_frame_width, S5P_FIMV_E_CROPPED_FRAME_WIDTH_V6); |
| 2072 | R(e_cropped_frame_height, S5P_FIMV_E_CROPPED_FRAME_HEIGHT_V6); |
| 2073 | R(e_frame_crop_offset, S5P_FIMV_E_FRAME_CROP_OFFSET_V6); |
| 2074 | R(e_enc_options, S5P_FIMV_E_ENC_OPTIONS_V6); |
| 2075 | R(e_picture_profile, S5P_FIMV_E_PICTURE_PROFILE_V6); |
| 2076 | R(e_vbv_buffer_size, S5P_FIMV_E_VBV_BUFFER_SIZE_V6); |
| 2077 | R(e_vbv_init_delay, S5P_FIMV_E_VBV_INIT_DELAY_V6); |
| 2078 | R(e_fixed_picture_qp, S5P_FIMV_E_FIXED_PICTURE_QP_V6); |
| 2079 | R(e_rc_config, S5P_FIMV_E_RC_CONFIG_V6); |
| 2080 | R(e_rc_qp_bound, S5P_FIMV_E_RC_QP_BOUND_V6); |
| 2081 | R(e_rc_mode, S5P_FIMV_E_RC_RPARAM_V6); |
| 2082 | R(e_mb_rc_config, S5P_FIMV_E_MB_RC_CONFIG_V6); |
| 2083 | R(e_padding_ctrl, S5P_FIMV_E_PADDING_CTRL_V6); |
| 2084 | R(e_mv_hor_range, S5P_FIMV_E_MV_HOR_RANGE_V6); |
| 2085 | R(e_mv_ver_range, S5P_FIMV_E_MV_VER_RANGE_V6); |
| 2086 | R(e_num_dpb, S5P_FIMV_E_NUM_DPB_V6); |
| 2087 | R(e_luma_dpb, S5P_FIMV_E_LUMA_DPB_V6); |
| 2088 | R(e_chroma_dpb, S5P_FIMV_E_CHROMA_DPB_V6); |
| 2089 | R(e_me_buffer, S5P_FIMV_E_ME_BUFFER_V6); |
| 2090 | R(e_scratch_buffer_addr, S5P_FIMV_E_SCRATCH_BUFFER_ADDR_V6); |
| 2091 | R(e_scratch_buffer_size, S5P_FIMV_E_SCRATCH_BUFFER_SIZE_V6); |
| 2092 | R(e_tmv_buffer0, S5P_FIMV_E_TMV_BUFFER0_V6); |
| 2093 | R(e_tmv_buffer1, S5P_FIMV_E_TMV_BUFFER1_V6); |
| 2094 | R(e_source_first_plane_addr, S5P_FIMV_E_SOURCE_LUMA_ADDR_V6); |
| 2095 | R(e_source_second_plane_addr, S5P_FIMV_E_SOURCE_CHROMA_ADDR_V6); |
| 2096 | R(e_stream_buffer_addr, S5P_FIMV_E_STREAM_BUFFER_ADDR_V6); |
| 2097 | R(e_stream_buffer_size, S5P_FIMV_E_STREAM_BUFFER_SIZE_V6); |
| 2098 | R(e_roi_buffer_addr, S5P_FIMV_E_ROI_BUFFER_ADDR_V6); |
| 2099 | R(e_param_change, S5P_FIMV_E_PARAM_CHANGE_V6); |
| 2100 | R(e_ir_size, S5P_FIMV_E_IR_SIZE_V6); |
| 2101 | R(e_gop_config, S5P_FIMV_E_GOP_CONFIG_V6); |
| 2102 | R(e_mslice_mode, S5P_FIMV_E_MSLICE_MODE_V6); |
| 2103 | R(e_mslice_size_mb, S5P_FIMV_E_MSLICE_SIZE_MB_V6); |
| 2104 | R(e_mslice_size_bits, S5P_FIMV_E_MSLICE_SIZE_BITS_V6); |
| 2105 | R(e_frame_insertion, S5P_FIMV_E_FRAME_INSERTION_V6); |
| 2106 | R(e_rc_frame_rate, S5P_FIMV_E_RC_FRAME_RATE_V6); |
| 2107 | R(e_rc_bit_rate, S5P_FIMV_E_RC_BIT_RATE_V6); |
| 2108 | R(e_rc_roi_ctrl, S5P_FIMV_E_RC_ROI_CTRL_V6); |
| 2109 | R(e_picture_tag, S5P_FIMV_E_PICTURE_TAG_V6); |
| 2110 | R(e_bit_count_enable, S5P_FIMV_E_BIT_COUNT_ENABLE_V6); |
| 2111 | R(e_max_bit_count, S5P_FIMV_E_MAX_BIT_COUNT_V6); |
| 2112 | R(e_min_bit_count, S5P_FIMV_E_MIN_BIT_COUNT_V6); |
| 2113 | R(e_metadata_buffer_addr, S5P_FIMV_E_METADATA_BUFFER_ADDR_V6); |
| 2114 | R(e_metadata_buffer_size, S5P_FIMV_E_METADATA_BUFFER_SIZE_V6); |
| 2115 | R(e_encoded_source_first_plane_addr, |
| 2116 | S5P_FIMV_E_ENCODED_SOURCE_LUMA_ADDR_V6); |
| 2117 | R(e_encoded_source_second_plane_addr, |
| 2118 | S5P_FIMV_E_ENCODED_SOURCE_CHROMA_ADDR_V6); |
| 2119 | R(e_stream_size, S5P_FIMV_E_STREAM_SIZE_V6); |
| 2120 | R(e_slice_type, S5P_FIMV_E_SLICE_TYPE_V6); |
| 2121 | R(e_picture_count, S5P_FIMV_E_PICTURE_COUNT_V6); |
| 2122 | R(e_ret_picture_tag, S5P_FIMV_E_RET_PICTURE_TAG_V6); |
| 2123 | R(e_recon_luma_dpb_addr, S5P_FIMV_E_RECON_LUMA_DPB_ADDR_V6); |
| 2124 | R(e_recon_chroma_dpb_addr, S5P_FIMV_E_RECON_CHROMA_DPB_ADDR_V6); |
| 2125 | R(e_mpeg4_options, S5P_FIMV_E_MPEG4_OPTIONS_V6); |
| 2126 | R(e_mpeg4_hec_period, S5P_FIMV_E_MPEG4_HEC_PERIOD_V6); |
| 2127 | R(e_aspect_ratio, S5P_FIMV_E_ASPECT_RATIO_V6); |
| 2128 | R(e_extended_sar, S5P_FIMV_E_EXTENDED_SAR_V6); |
| 2129 | R(e_h264_options, S5P_FIMV_E_H264_OPTIONS_V6); |
| 2130 | R(e_h264_lf_alpha_offset, S5P_FIMV_E_H264_LF_ALPHA_OFFSET_V6); |
| 2131 | R(e_h264_lf_beta_offset, S5P_FIMV_E_H264_LF_BETA_OFFSET_V6); |
| 2132 | R(e_h264_i_period, S5P_FIMV_E_H264_I_PERIOD_V6); |
| 2133 | R(e_h264_fmo_slice_grp_map_type, |
| 2134 | S5P_FIMV_E_H264_FMO_SLICE_GRP_MAP_TYPE_V6); |
| 2135 | R(e_h264_fmo_num_slice_grp_minus1, |
| 2136 | S5P_FIMV_E_H264_FMO_NUM_SLICE_GRP_MINUS1_V6); |
| 2137 | R(e_h264_fmo_slice_grp_change_dir, |
| 2138 | S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_DIR_V6); |
| 2139 | R(e_h264_fmo_slice_grp_change_rate_minus1, |
| 2140 | S5P_FIMV_E_H264_FMO_SLICE_GRP_CHANGE_RATE_MINUS1_V6); |
| 2141 | R(e_h264_fmo_run_length_minus1_0, |
| 2142 | S5P_FIMV_E_H264_FMO_RUN_LENGTH_MINUS1_0_V6); |
| 2143 | R(e_h264_aso_slice_order_0, S5P_FIMV_E_H264_ASO_SLICE_ORDER_0_V6); |
| 2144 | R(e_h264_num_t_layer, S5P_FIMV_E_H264_NUM_T_LAYER_V6); |
| 2145 | R(e_h264_hierarchical_qp_layer0, |
| 2146 | S5P_FIMV_E_H264_HIERARCHICAL_QP_LAYER0_V6); |
| 2147 | R(e_h264_frame_packing_sei_info, |
| 2148 | S5P_FIMV_E_H264_FRAME_PACKING_SEI_INFO_V6); |
| 2149 | |
Arun Kumar K | 109b794 | 2014-05-19 09:33:06 -0300 | [diff] [blame] | 2150 | if (!IS_MFCV7_PLUS(dev)) |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 2151 | goto done; |
| 2152 | |
Kiran AVND | e2b9deb | 2014-05-19 09:50:01 -0300 | [diff] [blame] | 2153 | /* Initialize registers used in MFC v7+ */ |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 2154 | R(e_source_first_plane_addr, S5P_FIMV_E_SOURCE_FIRST_ADDR_V7); |
| 2155 | R(e_source_second_plane_addr, S5P_FIMV_E_SOURCE_SECOND_ADDR_V7); |
| 2156 | R(e_source_third_plane_addr, S5P_FIMV_E_SOURCE_THIRD_ADDR_V7); |
| 2157 | R(e_source_first_plane_stride, S5P_FIMV_E_SOURCE_FIRST_STRIDE_V7); |
| 2158 | R(e_source_second_plane_stride, S5P_FIMV_E_SOURCE_SECOND_STRIDE_V7); |
| 2159 | R(e_source_third_plane_stride, S5P_FIMV_E_SOURCE_THIRD_STRIDE_V7); |
| 2160 | R(e_encoded_source_first_plane_addr, |
| 2161 | S5P_FIMV_E_ENCODED_SOURCE_FIRST_ADDR_V7); |
| 2162 | R(e_encoded_source_second_plane_addr, |
| 2163 | S5P_FIMV_E_ENCODED_SOURCE_SECOND_ADDR_V7); |
| 2164 | R(e_vp8_options, S5P_FIMV_E_VP8_OPTIONS_V7); |
| 2165 | |
Kiran AVND | e2b9deb | 2014-05-19 09:50:01 -0300 | [diff] [blame] | 2166 | if (!IS_MFCV8(dev)) |
| 2167 | goto done; |
| 2168 | |
| 2169 | /* Initialize registers used in MFC v8 only. |
| 2170 | * Also, over-write the registers which have |
| 2171 | * a different offset for MFC v8. */ |
| 2172 | R(d_stream_data_size, S5P_FIMV_D_STREAM_DATA_SIZE_V8); |
| 2173 | R(d_cpb_buffer_addr, S5P_FIMV_D_CPB_BUFFER_ADDR_V8); |
| 2174 | R(d_cpb_buffer_size, S5P_FIMV_D_CPB_BUFFER_SIZE_V8); |
| 2175 | R(d_cpb_buffer_offset, S5P_FIMV_D_CPB_BUFFER_OFFSET_V8); |
| 2176 | R(d_first_plane_dpb_size, S5P_FIMV_D_FIRST_PLANE_DPB_SIZE_V8); |
| 2177 | R(d_second_plane_dpb_size, S5P_FIMV_D_SECOND_PLANE_DPB_SIZE_V8); |
| 2178 | R(d_scratch_buffer_addr, S5P_FIMV_D_SCRATCH_BUFFER_ADDR_V8); |
| 2179 | R(d_scratch_buffer_size, S5P_FIMV_D_SCRATCH_BUFFER_SIZE_V8); |
| 2180 | R(d_first_plane_dpb_stride_size, |
| 2181 | S5P_FIMV_D_FIRST_PLANE_DPB_STRIDE_SIZE_V8); |
| 2182 | R(d_second_plane_dpb_stride_size, |
| 2183 | S5P_FIMV_D_SECOND_PLANE_DPB_STRIDE_SIZE_V8); |
| 2184 | R(d_mv_buffer_size, S5P_FIMV_D_MV_BUFFER_SIZE_V8); |
| 2185 | R(d_num_mv, S5P_FIMV_D_NUM_MV_V8); |
| 2186 | R(d_first_plane_dpb, S5P_FIMV_D_FIRST_PLANE_DPB_V8); |
| 2187 | R(d_second_plane_dpb, S5P_FIMV_D_SECOND_PLANE_DPB_V8); |
| 2188 | R(d_mv_buffer, S5P_FIMV_D_MV_BUFFER_V8); |
| 2189 | R(d_init_buffer_options, S5P_FIMV_D_INIT_BUFFER_OPTIONS_V8); |
| 2190 | R(d_available_dpb_flag_lower, S5P_FIMV_D_AVAILABLE_DPB_FLAG_LOWER_V8); |
| 2191 | R(d_slice_if_enable, S5P_FIMV_D_SLICE_IF_ENABLE_V8); |
| 2192 | R(d_display_first_plane_addr, S5P_FIMV_D_DISPLAY_FIRST_PLANE_ADDR_V8); |
| 2193 | R(d_display_second_plane_addr, S5P_FIMV_D_DISPLAY_SECOND_PLANE_ADDR_V8); |
| 2194 | R(d_decoded_first_plane_addr, S5P_FIMV_D_DECODED_FIRST_PLANE_ADDR_V8); |
| 2195 | R(d_decoded_second_plane_addr, S5P_FIMV_D_DECODED_SECOND_PLANE_ADDR_V8); |
| 2196 | R(d_display_status, S5P_FIMV_D_DISPLAY_STATUS_V8); |
| 2197 | R(d_decoded_status, S5P_FIMV_D_DECODED_STATUS_V8); |
| 2198 | R(d_decoded_frame_type, S5P_FIMV_D_DECODED_FRAME_TYPE_V8); |
| 2199 | R(d_display_frame_type, S5P_FIMV_D_DISPLAY_FRAME_TYPE_V8); |
| 2200 | R(d_decoded_nal_size, S5P_FIMV_D_DECODED_NAL_SIZE_V8); |
| 2201 | R(d_display_frame_width, S5P_FIMV_D_DISPLAY_FRAME_WIDTH_V8); |
| 2202 | R(d_display_frame_height, S5P_FIMV_D_DISPLAY_FRAME_HEIGHT_V8); |
| 2203 | R(d_frame_pack_sei_avail, S5P_FIMV_D_FRAME_PACK_SEI_AVAIL_V8); |
| 2204 | R(d_mvc_num_views, S5P_FIMV_D_MVC_NUM_VIEWS_V8); |
| 2205 | R(d_mvc_view_id, S5P_FIMV_D_MVC_VIEW_ID_V8); |
| 2206 | R(d_ret_picture_tag_top, S5P_FIMV_D_RET_PICTURE_TAG_TOP_V8); |
| 2207 | R(d_ret_picture_tag_bot, S5P_FIMV_D_RET_PICTURE_TAG_BOT_V8); |
| 2208 | R(d_display_crop_info1, S5P_FIMV_D_DISPLAY_CROP_INFO1_V8); |
| 2209 | R(d_display_crop_info2, S5P_FIMV_D_DISPLAY_CROP_INFO2_V8); |
| 2210 | |
Kiran AVND | 3e594ce7 | 2014-05-19 09:50:02 -0300 | [diff] [blame] | 2211 | /* encoder registers */ |
| 2212 | R(e_padding_ctrl, S5P_FIMV_E_PADDING_CTRL_V8); |
| 2213 | R(e_rc_config, S5P_FIMV_E_RC_CONFIG_V8); |
| 2214 | R(e_rc_mode, S5P_FIMV_E_RC_RPARAM_V8); |
| 2215 | R(e_mv_hor_range, S5P_FIMV_E_MV_HOR_RANGE_V8); |
| 2216 | R(e_mv_ver_range, S5P_FIMV_E_MV_VER_RANGE_V8); |
| 2217 | R(e_rc_qp_bound, S5P_FIMV_E_RC_QP_BOUND_V8); |
| 2218 | R(e_fixed_picture_qp, S5P_FIMV_E_FIXED_PICTURE_QP_V8); |
| 2219 | R(e_vbv_buffer_size, S5P_FIMV_E_VBV_BUFFER_SIZE_V8); |
| 2220 | R(e_vbv_init_delay, S5P_FIMV_E_VBV_INIT_DELAY_V8); |
| 2221 | R(e_mb_rc_config, S5P_FIMV_E_MB_RC_CONFIG_V8); |
| 2222 | R(e_aspect_ratio, S5P_FIMV_E_ASPECT_RATIO_V8); |
| 2223 | R(e_extended_sar, S5P_FIMV_E_EXTENDED_SAR_V8); |
| 2224 | R(e_h264_options, S5P_FIMV_E_H264_OPTIONS_V8); |
| 2225 | |
Kiran AVND | 6a9c6f68 | 2014-05-19 09:33:05 -0300 | [diff] [blame] | 2226 | done: |
| 2227 | return &mfc_regs; |
| 2228 | #undef S5P_MFC_REG_ADDR |
| 2229 | #undef R |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 2230 | } |
| 2231 | |
| 2232 | /* Initialize opr function pointers for MFC v6 */ |
| 2233 | static struct s5p_mfc_hw_ops s5p_mfc_ops_v6 = { |
| 2234 | .alloc_dec_temp_buffers = s5p_mfc_alloc_dec_temp_buffers_v6, |
| 2235 | .release_dec_desc_buffer = s5p_mfc_release_dec_desc_buffer_v6, |
| 2236 | .alloc_codec_buffers = s5p_mfc_alloc_codec_buffers_v6, |
| 2237 | .release_codec_buffers = s5p_mfc_release_codec_buffers_v6, |
| 2238 | .alloc_instance_buffer = s5p_mfc_alloc_instance_buffer_v6, |
| 2239 | .release_instance_buffer = s5p_mfc_release_instance_buffer_v6, |
| 2240 | .alloc_dev_context_buffer = |
| 2241 | s5p_mfc_alloc_dev_context_buffer_v6, |
| 2242 | .release_dev_context_buffer = |
| 2243 | s5p_mfc_release_dev_context_buffer_v6, |
| 2244 | .dec_calc_dpb_size = s5p_mfc_dec_calc_dpb_size_v6, |
| 2245 | .enc_calc_src_size = s5p_mfc_enc_calc_src_size_v6, |
| 2246 | .set_dec_stream_buffer = s5p_mfc_set_dec_stream_buffer_v6, |
| 2247 | .set_dec_frame_buffer = s5p_mfc_set_dec_frame_buffer_v6, |
| 2248 | .set_enc_stream_buffer = s5p_mfc_set_enc_stream_buffer_v6, |
| 2249 | .set_enc_frame_buffer = s5p_mfc_set_enc_frame_buffer_v6, |
| 2250 | .get_enc_frame_buffer = s5p_mfc_get_enc_frame_buffer_v6, |
| 2251 | .set_enc_ref_buffer = s5p_mfc_set_enc_ref_buffer_v6, |
| 2252 | .init_decode = s5p_mfc_init_decode_v6, |
| 2253 | .init_encode = s5p_mfc_init_encode_v6, |
| 2254 | .encode_one_frame = s5p_mfc_encode_one_frame_v6, |
| 2255 | .try_run = s5p_mfc_try_run_v6, |
Jeongtae Park | f96f3cf | 2012-10-03 22:19:11 -0300 | [diff] [blame] | 2256 | .clear_int_flags = s5p_mfc_clear_int_flags_v6, |
| 2257 | .write_info = s5p_mfc_write_info_v6, |
| 2258 | .read_info = s5p_mfc_read_info_v6, |
| 2259 | .get_dspl_y_adr = s5p_mfc_get_dspl_y_adr_v6, |
| 2260 | .get_dec_y_adr = s5p_mfc_get_dec_y_adr_v6, |
| 2261 | .get_dspl_status = s5p_mfc_get_dspl_status_v6, |
| 2262 | .get_dec_status = s5p_mfc_get_dec_status_v6, |
| 2263 | .get_dec_frame_type = s5p_mfc_get_dec_frame_type_v6, |
| 2264 | .get_disp_frame_type = s5p_mfc_get_disp_frame_type_v6, |
| 2265 | .get_consumed_stream = s5p_mfc_get_consumed_stream_v6, |
| 2266 | .get_int_reason = s5p_mfc_get_int_reason_v6, |
| 2267 | .get_int_err = s5p_mfc_get_int_err_v6, |
| 2268 | .err_dec = s5p_mfc_err_dec_v6, |
| 2269 | .err_dspl = s5p_mfc_err_dspl_v6, |
| 2270 | .get_img_width = s5p_mfc_get_img_width_v6, |
| 2271 | .get_img_height = s5p_mfc_get_img_height_v6, |
| 2272 | .get_dpb_count = s5p_mfc_get_dpb_count_v6, |
| 2273 | .get_mv_count = s5p_mfc_get_mv_count_v6, |
| 2274 | .get_inst_no = s5p_mfc_get_inst_no_v6, |
| 2275 | .get_enc_strm_size = s5p_mfc_get_enc_strm_size_v6, |
| 2276 | .get_enc_slice_type = s5p_mfc_get_enc_slice_type_v6, |
| 2277 | .get_enc_dpb_count = s5p_mfc_get_enc_dpb_count_v6, |
| 2278 | .get_enc_pic_count = s5p_mfc_get_enc_pic_count_v6, |
| 2279 | .get_sei_avail_status = s5p_mfc_get_sei_avail_status_v6, |
| 2280 | .get_mvc_num_views = s5p_mfc_get_mvc_num_views_v6, |
| 2281 | .get_mvc_view_id = s5p_mfc_get_mvc_view_id_v6, |
| 2282 | .get_pic_type_top = s5p_mfc_get_pic_type_top_v6, |
| 2283 | .get_pic_type_bot = s5p_mfc_get_pic_type_bot_v6, |
| 2284 | .get_crop_info_h = s5p_mfc_get_crop_info_h_v6, |
| 2285 | .get_crop_info_v = s5p_mfc_get_crop_info_v_v6, |
| 2286 | }; |
| 2287 | |
| 2288 | struct s5p_mfc_hw_ops *s5p_mfc_init_hw_ops_v6(void) |
| 2289 | { |
| 2290 | return &s5p_mfc_ops_v6; |
| 2291 | } |