From 4460dc75e20124959a5bea8c0cb9444d2e1a5481 Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Fri, 6 Aug 2021 19:01:54 +0800 Subject: [PATCH] media: remove unused rockchip-vpu driver Signed-off-by: Tao Huang Change-Id: I7eeb6052fd42e49e07410ce97c5b183d7463bd90 --- drivers/media/platform/rockchip-vpu/Makefile | 13 - .../platform/rockchip-vpu/rk3288_vpu_hw.c | 74 - .../rockchip-vpu/rk3288_vpu_hw_h264d.c | 558 ------ .../rockchip-vpu/rk3288_vpu_hw_h264e.c | 1369 --------------- .../rockchip-vpu/rk3288_vpu_hw_vp8d.c | 767 --------- .../rockchip-vpu/rk3288_vpu_hw_vp8e.c | 478 ----- .../platform/rockchip-vpu/rk3288_vpu_regs.h | 445 ----- .../platform/rockchip-vpu/rockchip_vpu.c | 951 ---------- .../rockchip-vpu/rockchip_vpu_common.h | 595 ------- .../platform/rockchip-vpu/rockchip_vpu_dec.c | 1164 ------------- .../platform/rockchip-vpu/rockchip_vpu_dec.h | 33 - .../platform/rockchip-vpu/rockchip_vpu_enc.c | 1534 ----------------- .../platform/rockchip-vpu/rockchip_vpu_enc.h | 36 - .../platform/rockchip-vpu/rockchip_vpu_hw.c | 463 ----- .../platform/rockchip-vpu/rockchip_vpu_hw.h | 258 --- 15 files changed, 8738 deletions(-) delete mode 100644 drivers/media/platform/rockchip-vpu/Makefile delete mode 100644 drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c delete mode 100644 drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_h264d.c delete mode 100644 drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_h264e.c delete mode 100644 drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_vp8d.c delete mode 100644 drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_vp8e.c delete mode 100644 drivers/media/platform/rockchip-vpu/rk3288_vpu_regs.h delete mode 100644 drivers/media/platform/rockchip-vpu/rockchip_vpu.c delete mode 100644 drivers/media/platform/rockchip-vpu/rockchip_vpu_common.h delete mode 100644 drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.c delete mode 100644 drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.h delete mode 100644 drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.c delete mode 100644 drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.h delete mode 100644 drivers/media/platform/rockchip-vpu/rockchip_vpu_hw.c delete mode 100644 drivers/media/platform/rockchip-vpu/rockchip_vpu_hw.h diff --git a/drivers/media/platform/rockchip-vpu/Makefile b/drivers/media/platform/rockchip-vpu/Makefile deleted file mode 100644 index b0429e660d36..000000000000 --- a/drivers/media/platform/rockchip-vpu/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -obj-$(CONFIG_VIDEO_ROCKCHIP_VPU) += rockchip-vpu.o - -rockchip-vpu-y += rockchip_vpu.o \ - rockchip_vpu_dec.o \ - rockchip_vpu_enc.o \ - rockchip_vpu_hw.o \ - rk3288_vpu_hw.o \ - rk3288_vpu_hw_h264d.o \ - rk3288_vpu_hw_h264e.o \ - rk3288_vpu_hw_vp8d.o \ - rk3288_vpu_hw_vp8e.o \ diff --git a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c b/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c deleted file mode 100644 index a810f9133a23..000000000000 --- a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Rockchip VPU codec driver - * - * Copyright (C) 2016 Rockchip Electronics Co., Ltd. - * Jeffy Chen - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "rockchip_vpu_common.h" - -#include "rk3288_vpu_regs.h" - -/* - * Interrupt handlers. - */ - -int rk3288_vpu_enc_irq(int irq, struct rockchip_vpu_dev *vpu) -{ - u32 status = vepu_read(vpu, VEPU_REG_INTERRUPT); - - vepu_write(vpu, 0, VEPU_REG_INTERRUPT); - - if (status & VEPU_REG_INTERRUPT_BIT) { - vepu_write(vpu, 0, VEPU_REG_AXI_CTRL); - return 0; - } - - return -1; -} - -int rk3288_vpu_dec_irq(int irq, struct rockchip_vpu_dev *vpu) -{ - u32 status = vdpu_read(vpu, VDPU_REG_INTERRUPT); - - vdpu_write(vpu, 0, VDPU_REG_INTERRUPT); - - vpu_debug(3, "vdpu_irq status: %08x\n", status); - - if (status & VDPU_REG_INTERRUPT_DEC_IRQ) { - vdpu_write(vpu, 0, VDPU_REG_CONFIG); - return 0; - } - - return -1; -} - -/* - * Initialization/clean-up. - */ - -void rk3288_vpu_enc_reset(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - - vepu_write(vpu, VEPU_REG_INTERRUPT_DIS_BIT, VEPU_REG_INTERRUPT); - vepu_write(vpu, 0, VEPU_REG_ENC_CTRL); - vepu_write(vpu, 0, VEPU_REG_AXI_CTRL); -} - -void rk3288_vpu_dec_reset(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - - vdpu_write(vpu, VDPU_REG_INTERRUPT_DEC_IRQ_DIS, VDPU_REG_INTERRUPT); - vdpu_write(vpu, 0, VDPU_REG_CONFIG); -} diff --git a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_h264d.c b/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_h264d.c deleted file mode 100644 index 48bf44da48d8..000000000000 --- a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_h264d.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - * Rockchip RK3288 VPU codec driver - * - * Copyright (c) 2014 Rockchip Electronics Co., Ltd. - * Hertz Wong - * Herman Chen - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "rockchip_vpu_common.h" - -#include -#include - -#include "rockchip_vpu_hw.h" -#include "rk3288_vpu_regs.h" - -/* Max. number of DPB pictures supported by hardware. */ -#define RK3288_VPU_H264_NUM_DPB 16 - -/* Size with u32 units. */ -#define CABAC_INIT_BUFFER_SIZE (460 * 2) -#define POC_BUFFER_SIZE 34 -#define SCALING_LIST_SIZE ((6 * 16 + 6 * 64) / 4) - -/* Data structure describing auxilliary buffer format. */ -struct rk3288_vpu_h264d_priv_tbl { - u32 cabac_table[CABAC_INIT_BUFFER_SIZE]; - u32 poc[POC_BUFFER_SIZE]; - u32 scaling_list[SCALING_LIST_SIZE]; -}; - -/* Constant CABAC table. */ -static const u32 h264_cabac_table[] = { - 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07330000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x000b0137, - 0x0045ef7f, 0xf3660052, 0xf94aeb6b, 0xe57fe17f, 0xe87fee5f, 0xe57feb72, - 0xe27fef7b, 0xf473f07a, 0xf573f43f, 0xfe44f154, 0xf368fd46, 0xf85df65a, - 0xe27fff4a, 0xfa61f95b, 0xec7ffc38, 0xfb52f94c, 0xea7df95d, 0xf557fd4d, - 0xfb47fc3f, 0xfc44f454, 0xf93ef941, 0x083d0538, 0xfe420140, 0x003dfe4e, - 0x01320734, 0x0a23002c, 0x0b26012d, 0x002e052c, 0x1f110133, 0x07321c13, - 0x10210e3e, 0xf36cf164, 0xf365f35b, 0xf45ef658, 0xf054f656, 0xf953f357, - 0xed5e0146, 0x0048fb4a, 0x123bf866, 0xf164005f, 0xfc4b0248, 0xf54bfd47, - 0x0f2ef345, 0x003e0041, 0x1525f148, 0x09391036, 0x003e0c48, 0x18000f09, - 0x08190d12, 0x0f090d13, 0x0a250c12, 0x061d1421, 0x0f1e042d, 0x013a003e, - 0x073d0c26, 0x0b2d0f27, 0x0b2a0d2c, 0x102d0c29, 0x0a311e22, 0x122a0a37, - 0x1133112e, 0x00591aed, 0x16ef1aef, 0x1ee71cec, 0x21e925e5, 0x21e928e4, - 0x26ef21f5, 0x28f129fa, 0x26012911, 0x1efa1b03, 0x1a1625f0, 0x23fc26f8, - 0x26fd2503, 0x26052a00, 0x23102716, 0x0e301b25, 0x153c0c44, 0x0261fd47, - 0xfa2afb32, 0xfd36fe3e, 0x003a013f, 0xfe48ff4a, 0xf75bfb43, 0xfb1bfd27, - 0xfe2c002e, 0xf040f844, 0xf64efa4d, 0xf656f45c, 0xf137f63c, 0xfa3efc41, - 0xf449f84c, 0xf950f758, 0xef6ef561, 0xec54f54f, 0xfa49fc4a, 0xf356f360, - 0xf561ed75, 0xf84efb21, 0xfc30fe35, 0xfd3ef347, 0xf64ff456, 0xf35af261, - 0x0000fa5d, 0xfa54f84f, 0x0042ff47, 0x003efe3c, 0xfe3bfb4b, 0xfd3efc3a, - 0xf742ff4f, 0x00470344, 0x0a2cf93e, 0x0f240e28, 0x101b0c1d, 0x012c1424, - 0x1220052a, 0x01300a3e, 0x112e0940, 0xf468f561, 0xf060f958, 0xf855f955, - 0xf755f358, 0x0442fd4d, 0xfd4cfa4c, 0x0a3aff4c, 0xff53f963, 0xf25f025f, - 0x004cfb4a, 0x0046f54b, 0x01440041, 0xf249033e, 0x043eff44, 0xf34b0b37, - 0x05400c46, 0x0f060613, 0x07100c0e, 0x120d0d0b, 0x0d0f0f10, 0x0c170d17, - 0x0f140e1a, 0x0e2c1128, 0x112f1811, 0x15151916, 0x1f1b161d, 0x13230e32, - 0x0a39073f, 0xfe4dfc52, 0xfd5e0945, 0xf46d24dd, 0x24de20e6, 0x25e22ce0, - 0x22ee22f1, 0x28f121f9, 0x23fb2100, 0x2602210d, 0x17230d3a, 0x1dfd1a00, - 0x161e1ff9, 0x23f122fd, 0x220324ff, 0x2205200b, 0x2305220c, 0x270b1e1d, - 0x221a1d27, 0x13421f15, 0x1f1f1932, 0xef78ec70, 0xee72f555, 0xf15cf259, - 0xe647f151, 0xf2500044, 0xf246e838, 0xe944e832, 0xf54a17f3, 0x1af328f1, - 0x31f22c03, 0x2d062c22, 0x21361352, 0xfd4bff17, 0x0122012b, 0x0036fe37, - 0x003d0140, 0x0044f75c, 0xf26af361, 0xf15af45a, 0xee58f649, 0xf74ff256, - 0xf649f646, 0xf645fb42, 0xf740fb3a, 0x023b15f6, 0x18f51cf8, 0x1cff1d03, - 0x1d092314, 0x1d240e43, 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, - 0xfa35ff36, 0x07331721, 0x17021500, 0x01090031, 0xdb760539, 0xf34ef541, - 0x013e0c31, 0xfc491132, 0x1240092b, 0x1d001a43, 0x105a0968, 0xd27fec68, - 0x0143f34e, 0xf541013e, 0xfa56ef5f, 0xfa3d092d, 0xfd45fa51, 0xf5600637, - 0x0743fb56, 0x0258003a, 0xfd4cf65e, 0x05360445, 0xfd510058, 0xf943fb4a, - 0xfc4afb50, 0xf948013a, 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, - 0x0d29033e, 0x002dfc4e, 0xfd60e57e, 0xe462e765, 0xe943e452, 0xec5ef053, - 0xea6eeb5b, 0xee66f35d, 0xe37ff95c, 0xfb59f960, 0xf36cfd2e, 0xff41ff39, - 0xf75dfd4a, 0xf75cf857, 0xe97e0536, 0x063c063b, 0x0645ff30, 0x0044fc45, - 0xf858fe55, 0xfa4eff4b, 0xf94d0236, 0x0532fd44, 0x0132062a, 0xfc51013f, - 0xfc460043, 0x0239fe4c, 0x0b230440, 0x013d0b23, 0x12190c18, 0x0d1d0d24, - 0xf65df949, 0xfe490d2e, 0x0931f964, 0x09350235, 0x0535fe3d, 0x00380038, - 0xf33ffb3c, 0xff3e0439, 0xfa450439, 0x0e270433, 0x0d440340, 0x013d093f, - 0x07321027, 0x052c0434, 0x0b30fb3c, 0xff3b003b, 0x1621052c, 0x0e2bff4e, - 0x003c0945, 0x0b1c0228, 0x032c0031, 0x002e022c, 0x0233002f, 0x0427023e, - 0x062e0036, 0x0336023a, 0x043f0633, 0x06390735, 0x06340637, 0x0b2d0e24, - 0x0835ff52, 0x0737fd4e, 0x0f2e161f, 0xff541907, 0x1ef91c03, 0x1c042000, - 0x22ff1e06, 0x1e062009, 0x1f131a1b, 0x1a1e2514, 0x1c221146, 0x0143053b, - 0x0943101e, 0x12201223, 0x161d181f, 0x1726122b, 0x14290b3f, 0x093b0940, - 0xff5efe59, 0xf76cfa4c, 0xfe2c002d, 0x0034fd40, 0xfe3bfc46, 0xfc4bf852, - 0xef66f74d, 0x0318002a, 0x00300037, 0xfa3bf947, 0xf453f557, 0xe277013a, - 0xfd1dff24, 0x0126022b, 0xfa37003a, 0x0040fd4a, 0xf65a0046, 0xfc1d051f, - 0x072a013b, 0xfe3afd48, 0xfd51f561, 0x003a0805, 0x0a0e0e12, 0x0d1b0228, - 0x003afd46, 0xfa4ff855, 0x0000f36a, 0xf06af657, 0xeb72ee6e, 0xf262ea6e, - 0xeb6aee67, 0xeb6be96c, 0xe670f660, 0xf45ffb5b, 0xf75dea5e, 0xfb560943, - 0xfc50f655, 0xff46073c, 0x093a053d, 0x0c320f32, 0x12311136, 0x0a29072e, - 0xff330731, 0x08340929, 0x062f0237, 0x0d290a2c, 0x06320535, 0x0d31043f, - 0x0640fe45, 0xfe3b0646, 0x0a2c091f, 0x0c2b0335, 0x0e220a26, 0xfd340d28, - 0x1120072c, 0x07260d32, 0x0a391a2b, 0x0e0b0b0e, 0x090b120b, 0x150917fe, - 0x20f120f1, 0x22eb27e9, 0x2adf29e1, 0x2ee426f4, 0x151d2de8, 0x35d330e6, - 0x41d52bed, 0x27f61e09, 0x121a141b, 0x0039f252, 0xfb4bed61, 0xdd7d1b00, - 0x1c001ffc, 0x1b062208, 0x1e0a1816, 0x21131620, 0x1a1f1529, 0x1a2c172f, - 0x10410e47, 0x083c063f, 0x11411518, 0x17141a17, 0x1b201c17, 0x1c181728, - 0x18201c1d, 0x172a1339, 0x1635163d, 0x0b560c28, 0x0b330e3b, 0xfc4ff947, - 0xfb45f746, 0xf842f644, 0xed49f445, 0xf046f143, 0xec3eed46, 0xf042ea41, - 0xec3f09fe, 0x1af721f7, 0x27f929fe, 0x2d033109, 0x2d1b243b, 0xfa42f923, - 0xf92af82d, 0xfb30f438, 0xfa3cfb3e, 0xf842f84c, 0xfb55fa51, 0xf64df951, - 0xef50ee49, 0xfc4af653, 0xf747f743, 0xff3df842, 0xf242003b, 0x023b15f3, - 0x21f227f9, 0x2efe3302, 0x3c063d11, 0x37222a3e, 0x14f10236, 0x034a14f1, - 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331619, 0x22001000, 0xfe090429, - 0xe3760241, 0xfa47f34f, 0x05340932, 0xfd460a36, 0x1a221316, 0x28003902, - 0x29241a45, 0xd37ff165, 0xfc4cfa47, 0xf34f0534, 0x0645f35a, 0x0034082b, - 0xfe45fb52, 0xf660023b, 0x024bfd57, 0xfd640138, 0xfd4afa55, 0x003bfd51, - 0xf956fb5f, 0xff42ff4d, 0x0146fe56, 0xfb48003d, 0x0029003f, 0x003f003f, - 0xf7530456, 0x0061f948, 0x0d29033e, 0x0d0f0733, 0x0250d97f, 0xee5bef60, - 0xe651dd62, 0xe866e961, 0xe577e863, 0xeb6eee66, 0xdc7f0050, 0xfb59f95e, - 0xfc5c0027, 0x0041f154, 0xdd7ffe49, 0xf468f75b, 0xe17f0337, 0x07380737, - 0x083dfd35, 0x0044f94a, 0xf758f367, 0xf35bf759, 0xf25cf84c, 0xf457e96e, - 0xe869f64e, 0xec70ef63, 0xb27fba7f, 0xce7fd27f, 0xfc42fb4e, 0xfc47f848, - 0x023bff37, 0xf946fa4b, 0xf859de77, 0xfd4b2014, 0x1e16d47f, 0x0036fb3d, - 0x003aff3c, 0xfd3df843, 0xe754f24a, 0xfb410534, 0x0239003d, 0xf745f546, - 0x1237fc47, 0x003a073d, 0x09291219, 0x0920052b, 0x092f002c, 0x0033022e, - 0x1326fc42, 0x0f260c2a, 0x09220059, 0x042d0a1c, 0x0a1f21f5, 0x34d5120f, - 0x1c0023ea, 0x26e72200, 0x27ee20f4, 0x66a20000, 0x38f121fc, 0x1d0a25fb, - 0x33e327f7, 0x34de45c6, 0x43c12cfb, 0x200737e3, 0x20010000, 0x1b2421e7, - 0x22e224e4, 0x26e426e5, 0x22ee23f0, 0x22f220f8, 0x25fa2300, 0x1e0a1c12, - 0x1a191d29, 0x004b0248, 0x084d0e23, 0x121f1123, 0x151e112d, 0x142a122d, - 0x1b1a1036, 0x07421038, 0x0b490a43, 0xf674e970, 0xf147f93d, 0x0035fb42, - 0xf54df750, 0xf754f657, 0xde7feb65, 0xfd27fb35, 0xf93df54b, 0xf14def5b, - 0xe76be76f, 0xe47af54c, 0xf62cf634, 0xf639f73a, 0xf048f945, 0xfc45fb4a, - 0xf7560242, 0xf7220120, 0x0b1f0534, 0xfe37fe43, 0x0049f859, 0x03340704, - 0x0a081108, 0x10130325, 0xff3dfb49, 0xff46fc4e, 0x0000eb7e, 0xe97cec6e, - 0xe67ee77c, 0xef69e579, 0xe575ef66, 0xe675e574, 0xdf7af65f, 0xf264f85f, - 0xef6fe472, 0xfa59fe50, 0xfc52f755, 0xf851ff48, 0x05400143, 0x09380045, - 0x01450745, 0xf945fa43, 0xf04dfe40, 0x023dfa43, 0xfd400239, 0xfd41fd42, - 0x003e0933, 0xff42fe47, 0xfe4bff46, 0xf7480e3c, 0x1025002f, 0x12230b25, - 0x0c290a29, 0x02300c29, 0x0d29003b, 0x03321328, 0x03421232, 0x13fa12fa, - 0x0e001af4, 0x1ff021e7, 0x21ea25e4, 0x27e22ae2, 0x2fd62ddc, 0x31de29ef, - 0x200945b9, 0x3fc142c0, 0x4db636d9, 0x34dd29f6, 0x240028ff, 0x1e0e1c1a, - 0x17250c37, 0x0b4125df, 0x27dc28db, 0x26e22edf, 0x2ae228e8, 0x31e326f4, - 0x28f626fd, 0x2efb1f14, 0x1d1e192c, 0x0c300b31, 0x1a2d1616, 0x17161b15, - 0x21141a1c, 0x1e181b22, 0x122a1927, 0x12320c46, 0x15360e47, 0x0b531920, - 0x15311536, 0xfb55fa51, 0xf64df951, 0xef50ee49, 0xfc4af653, 0xf747f743, - 0xff3df842, 0xf242003b, 0x023b11f6, 0x20f32af7, 0x31fb3500, 0x4003440a, - 0x421b2f39, 0xfb470018, 0xff24fe2a, 0xfe34f739, 0xfa3ffc41, 0xfc43f952, - 0xfd51fd4c, 0xf948fa4e, 0xf448f244, 0xfd46fa4c, 0xfb42fb3e, 0x0039fc3d, - 0xf73c0136, 0x023a11f6, 0x20f32af7, 0x31fb3500, 0x4003440a, 0x421b2f39, - 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331d10, - 0x19000e00, 0xf633fd3e, 0xe5631a10, 0xfc55e866, 0x05390639, 0xef490e39, - 0x1428140a, 0x1d003600, 0x252a0c61, 0xe07fea75, 0xfe4afc55, 0xe8660539, - 0xfa5df258, 0xfa2c0437, 0xf559f167, 0xeb741339, 0x143a0454, 0x0660013f, - 0xfb55f36a, 0x053f064b, 0xfd5aff65, 0x0337fc4f, 0xfe4bf461, 0xf932013c, - 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x0722f758, - 0xec7fdc7f, 0xef5bf25f, 0xe754e756, 0xf459ef5b, 0xe17ff24c, 0xee67f35a, - 0xdb7f0b50, 0x054c0254, 0x054efa37, 0x043df253, 0xdb7ffb4f, 0xf568f55b, - 0xe27f0041, 0xfe4f0048, 0xfc5cfa38, 0x0344f847, 0xf362fc56, 0xf458fb52, - 0xfd48fc43, 0xf848f059, 0xf745ff3b, 0x05420439, 0xfc47fe47, 0x023aff4a, - 0xfc2cff45, 0x003ef933, 0xfc2ffa2a, 0xfd29fa35, 0x084cf74e, 0xf5530934, - 0x0043fb5a, 0x0143f148, 0xfb4bf850, 0xeb53eb40, 0xf31fe740, 0xe35e094b, - 0x113ff84a, 0xfb23fe1b, 0x0d5b0341, 0xf945084d, 0xf642033e, 0xfd44ec51, - 0x001e0107, 0xfd17eb4a, 0x1042e97c, 0x11252cee, 0x32deea7f, 0x0427002a, - 0x07220b1d, 0x081f0625, 0x072a0328, 0x08210d2b, 0x0d24042f, 0x0337023a, - 0x063c082c, 0x0b2c0e2a, 0x07300438, 0x04340d25, 0x0931133a, 0x0a300c2d, - 0x00451421, 0x083f23ee, 0x21e71cfd, 0x180a1b00, 0x22f234d4, 0x27e81311, - 0x1f19241d, 0x1821220f, 0x1e141649, 0x1422131f, 0x1b2c1310, 0x0f240f24, - 0x151c1915, 0x1e141f0c, 0x1b10182a, 0x005d0e38, 0x0f391a26, 0xe87fe873, - 0xea52f73e, 0x0035003b, 0xf255f359, 0xf35ef55c, 0xe37feb64, 0xf239f443, - 0xf547f64d, 0xeb55f058, 0xe968f162, 0xdb7ff652, 0xf830f83d, 0xf842f946, - 0xf24bf64f, 0xf753f45c, 0xee6cfc4f, 0xea45f04b, 0xfe3a013a, 0xf34ef753, - 0xfc51f363, 0xf351fa26, 0xf33efa3a, 0xfe3bf049, 0xf64cf356, 0xf753f657, - 0x0000ea7f, 0xe77fe778, 0xe57fed72, 0xe975e776, 0xe675e871, 0xe476e178, - 0xdb7cf65e, 0xf166f663, 0xf36ace7f, 0xfb5c1139, 0xfb56f35e, 0xf45bfe4d, - 0x0047ff49, 0x0440f951, 0x05400f39, 0x01430044, 0xf6430144, 0x004d0240, - 0x0044fb4e, 0x0737053b, 0x02410e36, 0x0f2c053c, 0x0246fe4c, 0xee560c46, - 0x0540f446, 0x0b370538, 0x00450241, 0xfa4a0536, 0x0736fa4c, 0xf552fe4d, - 0xfe4d192a, 0x11f310f7, 0x11f41beb, 0x25e229d8, 0x2ad730d1, 0x27e02ed8, - 0x34cd2ed7, 0x34d92bed, 0x200b3dc9, 0x38d23ece, 0x51bd2dec, 0x23fe1c0f, - 0x22012701, 0x1e111426, 0x122d0f36, 0x004f24f0, 0x25f225ef, 0x2001220f, - 0x1d0f1819, 0x22161f10, 0x23121f1c, 0x2129241c, 0x1b2f153e, 0x121f131a, - 0x24181817, 0x1b10181e, 0x1f1d1629, 0x162a103c, 0x0f340e3c, 0x034ef07b, - 0x15351638, 0x193d1521, 0x1332113d, 0xfd4ef84a, 0xf748f648, 0xee4bf447, - 0xf53ffb46, 0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc, - 0x21ff2107, 0x1f0c2517, 0x1f261440, 0xf747f925, 0xf82cf531, 0xf638f43b, - 0xf83ff743, 0xfa44f64f, 0xfd4ef84a, 0xf748f648, 0xee4bf447, 0xf53ffb46, - 0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc, 0x21ff2107, - 0x1f0c2517, 0x1f261440 -}; - -int rk3288_vpu_h264d_init(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - int ret; - - ret = rockchip_vpu_aux_buf_alloc(vpu, &ctx->hw.h264d.priv_tbl, - sizeof(struct rk3288_vpu_h264d_priv_tbl)); - if (ret) { - vpu_err("allocate h264 priv_tbl failed\n"); - return ret; - } - - return 0; -} - -void rk3288_vpu_h264d_exit(struct rockchip_vpu_ctx *ctx) -{ - rockchip_vpu_aux_buf_free(ctx->dev, &ctx->hw.h264d.priv_tbl); -} - -static void rk3288_vpu_h264d_prepare_table(struct rockchip_vpu_ctx *ctx) -{ - struct rk3288_vpu_h264d_priv_tbl *tbl = ctx->hw.h264d.priv_tbl.cpu; - const struct v4l2_ctrl_h264_scaling_matrix *scaling = - ctx->run.h264d.scaling_matrix; - const struct v4l2_ctrl_h264_decode_param *dec_param = - ctx->run.h264d.decode_param; - const struct v4l2_h264_dpb_entry *dpb = ctx->run.h264d.dpb; - int i; - - /* - * Prepare auxiliary buffer. - * - * TODO: The CABAC table never changes, but maybe it would be better - * to have it as a control, which is set by userspace once? - */ - memcpy(tbl->cabac_table, h264_cabac_table, sizeof(tbl->cabac_table)); - - for (i = 0; i < RK3288_VPU_H264_NUM_DPB; ++i) { - tbl->poc[i * 2 + 0] = dpb[i].top_field_order_cnt; - tbl->poc[i * 2 + 1] = dpb[i].bottom_field_order_cnt; - - vpu_debug(2, "poc [%02d]: %08x %08x\n", i, - tbl->poc[i*2+0], tbl->poc[i*2+1]); - } - - tbl->poc[32] = dec_param->top_field_order_cnt; - tbl->poc[33] = dec_param->bottom_field_order_cnt; - - vpu_debug(2, "poc curr: %08x %08x\n", tbl->poc[32], tbl->poc[33]); - - memcpy(tbl->scaling_list, scaling, sizeof(tbl->scaling_list)); -} - -static void rk3288_vpu_h264d_set_params(struct rockchip_vpu_ctx *ctx) -{ - const struct v4l2_ctrl_h264_decode_param *dec_param = - ctx->run.h264d.decode_param; - const struct v4l2_ctrl_h264_slice_param *slice = - ctx->run.h264d.slice_param; - const struct v4l2_ctrl_h264_sps *sps = ctx->run.h264d.sps; - const struct v4l2_ctrl_h264_pps *pps = ctx->run.h264d.pps; - struct rockchip_vpu_dev *vpu = ctx->dev; - u32 reg; - - /* Decoder control register 0. */ - reg = VDPU_REG_DEC_CTRL0_DEC_AXI_WR_ID(0xff); - if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD) - reg |= VDPU_REG_DEC_CTRL0_SEQ_MBAFF_E; - if (sps->profile_idc > 66) - reg |= VDPU_REG_DEC_CTRL0_PICORD_COUNT_E - | VDPU_REG_DEC_CTRL0_WRITE_MVS_E; - if (!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY) && - (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD || - slice->flags & V4L2_SLICE_FLAG_FIELD_PIC)) - reg |= VDPU_REG_DEC_CTRL0_PIC_INTERLACE_E; - if (slice->flags & V4L2_SLICE_FLAG_FIELD_PIC) - reg |= VDPU_REG_DEC_CTRL0_PIC_FIELDMODE_E; - if (!(slice->flags & V4L2_SLICE_FLAG_BOTTOM_FIELD)) - reg |= VDPU_REG_DEC_CTRL0_PIC_TOPFIELD_E; - vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_CTRL0); - - /* Decoder control register 1. */ - reg = VDPU_REG_DEC_CTRL1_PIC_MB_WIDTH(sps->pic_width_in_mbs_minus1 + 1) - | VDPU_REG_DEC_CTRL1_PIC_MB_HEIGHT_P( - sps->pic_height_in_map_units_minus1 + 1) - | VDPU_REG_DEC_CTRL1_REF_FRAMES(sps->max_num_ref_frames); - vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_CTRL1); - - /* Decoder control register 2. */ - reg = VDPU_REG_DEC_CTRL2_CH_QP_OFFSET(pps->chroma_qp_index_offset) - | VDPU_REG_DEC_CTRL2_CH_QP_OFFSET2( - pps->second_chroma_qp_index_offset); - if (pps->flags & V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT) - reg |= VDPU_REG_DEC_CTRL2_TYPE1_QUANT_E; - if (slice->flags & V4L2_SLICE_FLAG_FIELD_PIC) - reg |= VDPU_REG_DEC_CTRL2_FIELDPIC_FLAG_E; - vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_CTRL2); - - /* Decoder control register 3. */ - reg = VDPU_REG_DEC_CTRL3_START_CODE_E - | VDPU_REG_DEC_CTRL3_INIT_QP(pps->pic_init_qp_minus26 + 26) - | VDPU_REG_DEC_CTRL3_STREAM_LEN( - vb2_get_plane_payload(&ctx->run.src->vb.vb2_buf, 0)); - vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_CTRL3); - - /* Decoder control register 4. */ - reg = VDPU_REG_DEC_CTRL4_FRAMENUM_LEN( - sps->log2_max_frame_num_minus4 + 4) - | VDPU_REG_DEC_CTRL4_FRAMENUM(slice->frame_num) - | VDPU_REG_DEC_CTRL4_WEIGHT_BIPR_IDC(pps->weighted_bipred_idc); - if (pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE) - reg |= VDPU_REG_DEC_CTRL4_CABAC_E; - if (sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE) - reg |= VDPU_REG_DEC_CTRL4_DIR_8X8_INFER_E; - if (sps->profile_idc >= 0 && sps->chroma_format_idc == 0) - reg |= VDPU_REG_DEC_CTRL4_BLACKWHITE_E; - if (pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) - reg |= VDPU_REG_DEC_CTRL4_WEIGHT_PRED_E; - vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_CTRL4); - - /* Decoder control register 5. */ - reg = VDPU_REG_DEC_CTRL5_REFPIC_MK_LEN( - slice->dec_ref_pic_marking_bit_size) - | VDPU_REG_DEC_CTRL5_IDR_PIC_ID(slice->idr_pic_id); - if (pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED) - reg |= VDPU_REG_DEC_CTRL5_CONST_INTRA_E; - if (pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT) - reg |= VDPU_REG_DEC_CTRL5_FILT_CTRL_PRES; - if (pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT) - reg |= VDPU_REG_DEC_CTRL5_RDPIC_CNT_PRES; - if (pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE) - reg |= VDPU_REG_DEC_CTRL5_8X8TRANS_FLAG_E; - if (dec_param->idr_pic_flag) - reg |= VDPU_REG_DEC_CTRL5_IDR_PIC_E; - vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_CTRL5); - - /* Decoder control register 6. */ - reg = VDPU_REG_DEC_CTRL6_PPS_ID(slice->pic_parameter_set_id) - | VDPU_REG_DEC_CTRL6_REFIDX0_ACTIVE( - pps->num_ref_idx_l0_default_active_minus1 + 1) - | VDPU_REG_DEC_CTRL6_REFIDX1_ACTIVE( - pps->num_ref_idx_l1_default_active_minus1 + 1) - | VDPU_REG_DEC_CTRL6_POC_LENGTH(slice->pic_order_cnt_bit_size); - vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_CTRL6); - - /* Error concealment register. */ - vdpu_write_relaxed(vpu, 0, VDPU_REG_ERR_CONC); - - /* Prediction filter tap register. */ - vdpu_write_relaxed(vpu, VDPU_REG_PRED_FLT_PRED_BC_TAP_0_0(1) - | VDPU_REG_PRED_FLT_PRED_BC_TAP_0_1(-5 & 0x3ff) - | VDPU_REG_PRED_FLT_PRED_BC_TAP_0_2(20), - VDPU_REG_PRED_FLT); - - /* Reference picture buffer control register. */ - vdpu_write_relaxed(vpu, 0, VDPU_REG_REF_BUF_CTRL); - - /* Reference picture buffer control register 2. */ - vdpu_write_relaxed(vpu, VDPU_REG_REF_BUF_CTRL2_APF_THRESHOLD(8), - VDPU_REG_REF_BUF_CTRL2); -} - - -static void rk3288_vpu_h264d_set_ref(struct rockchip_vpu_ctx *ctx) -{ - const struct v4l2_ctrl_h264_decode_param *dec_param = - ctx->run.h264d.decode_param; - const struct v4l2_h264_dpb_entry *dpb = ctx->run.h264d.dpb; - const u8 *dpb_map = ctx->run.h264d.dpb_map; - struct rockchip_vpu_dev *vpu = ctx->dev; - u32 dpb_longterm = 0; - u32 dpb_valid = 0; - int reg_num; - u32 reg; - int i; - - /* - * Set up bit maps of valid and long term DPBs. - * NOTE: The bits are reversed, i.e. MSb is DPB 0. - */ - for (i = 0; i < RK3288_VPU_H264_NUM_DPB; ++i) { - if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE) - dpb_valid |= BIT(RK3288_VPU_H264_NUM_DPB - 1 - i); - - if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) - dpb_longterm |= BIT(RK3288_VPU_H264_NUM_DPB - 1 - i); - } - vdpu_write_relaxed(vpu, dpb_valid << 16, VDPU_REG_VALID_REF); - vdpu_write_relaxed(vpu, dpb_longterm << 16, VDPU_REG_LT_REF); - - /* - * Set up reference frame picture numbers. - * - * Each VDPU_REG_REF_PIC(x) register contains numbers of two - * subsequential reference pictures. - */ - for (i = 0; i < RK3288_VPU_H264_NUM_DPB; i += 2) { - reg = 0; - - if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) - reg |= VDPU_REG_REF_PIC_REFER0_NBR(dpb[i].pic_num); - else - reg |= VDPU_REG_REF_PIC_REFER0_NBR(dpb[i].frame_num); - - if (dpb[i + 1].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) - reg |= VDPU_REG_REF_PIC_REFER1_NBR(dpb[i + 1].pic_num); - else - reg |= VDPU_REG_REF_PIC_REFER1_NBR( - dpb[i + 1].frame_num); - - vdpu_write_relaxed(vpu, reg, VDPU_REG_REF_PIC(i / 2)); - } - - /* - * Each VDPU_REG_BD_REF_PIC(x) register contains three entries - * of each forward and backward picture list. - */ - reg_num = 0; - for (i = 0; i < 15; i += 3) { - reg = VDPU_REG_BD_REF_PIC_BINIT_RLIST_F0( - dpb_map[dec_param->ref_pic_list_b0[i + 0]]) - | VDPU_REG_BD_REF_PIC_BINIT_RLIST_F1( - dpb_map[dec_param->ref_pic_list_b0[i + 1]]) - | VDPU_REG_BD_REF_PIC_BINIT_RLIST_F2( - dpb_map[dec_param->ref_pic_list_b0[i + 2]]) - | VDPU_REG_BD_REF_PIC_BINIT_RLIST_B0( - dpb_map[dec_param->ref_pic_list_b1[i + 0]]) - | VDPU_REG_BD_REF_PIC_BINIT_RLIST_B1( - dpb_map[dec_param->ref_pic_list_b1[i + 1]]) - | VDPU_REG_BD_REF_PIC_BINIT_RLIST_B2( - dpb_map[dec_param->ref_pic_list_b1[i + 2]]); - vdpu_write_relaxed(vpu, reg, VDPU_REG_BD_REF_PIC(reg_num++)); - } - - /* - * VDPU_REG_BD_P_REF_PIC register contains last entries (index 15) - * of forward and backward reference picture lists and first 4 entries - * of P forward picture list. - */ - reg = VDPU_REG_BD_P_REF_PIC_BINIT_RLIST_F15( - dpb_map[dec_param->ref_pic_list_b0[15]]) - | VDPU_REG_BD_P_REF_PIC_BINIT_RLIST_B15( - dpb_map[dec_param->ref_pic_list_b1[15]]) - | VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F0( - dpb_map[dec_param->ref_pic_list_p0[0]]) - | VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F1( - dpb_map[dec_param->ref_pic_list_p0[1]]) - | VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F2( - dpb_map[dec_param->ref_pic_list_p0[2]]) - | VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F3( - dpb_map[dec_param->ref_pic_list_p0[3]]); - vdpu_write_relaxed(vpu, reg, VDPU_REG_BD_P_REF_PIC); - - /* - * Each VDPU_REG_FWD_PIC(x) register contains six consecutive - * entries of P forward picture list, starting from index 4. - */ - reg_num = 0; - for (i = 4; i < RK3288_VPU_H264_NUM_DPB; i += 6) { - reg = VDPU_REG_FWD_PIC_PINIT_RLIST_F0( - dpb_map[dec_param->ref_pic_list_p0[i + 0]]) - | VDPU_REG_FWD_PIC_PINIT_RLIST_F1( - dpb_map[dec_param->ref_pic_list_p0[i + 1]]) - | VDPU_REG_FWD_PIC_PINIT_RLIST_F2( - dpb_map[dec_param->ref_pic_list_p0[i + 2]]) - | VDPU_REG_FWD_PIC_PINIT_RLIST_F3( - dpb_map[dec_param->ref_pic_list_p0[i + 3]]) - | VDPU_REG_FWD_PIC_PINIT_RLIST_F4( - dpb_map[dec_param->ref_pic_list_p0[i + 4]]) - | VDPU_REG_FWD_PIC_PINIT_RLIST_F5( - dpb_map[dec_param->ref_pic_list_p0[i + 5]]); - vdpu_write_relaxed(vpu, reg, VDPU_REG_FWD_PIC(reg_num++)); - } - - /* - * Set up addresses of DPB buffers. - * - * If a DPB entry is unused, address of current destination buffer - * is used. - */ - for (i = 0; i < RK3288_VPU_H264_NUM_DPB; ++i) { - struct vb2_buffer *buf; - - if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE - && dpb[i].buf_index < ctx->vq_dst.num_buffers) - buf = ctx->dst_bufs[dpb[i].buf_index]; - else - buf = &ctx->run.dst->vb.vb2_buf; - - vdpu_write_relaxed(vpu, vb2_dma_contig_plane_dma_addr(buf, 0), - VDPU_REG_ADDR_REF(i)); - } -} - -static void rk3288_vpu_h264d_set_buffers(struct rockchip_vpu_ctx *ctx) -{ - const struct v4l2_ctrl_h264_sps *sps = ctx->run.h264d.sps; - const struct v4l2_ctrl_h264_slice_param *slice = - ctx->run.h264d.slice_param; - struct rockchip_vpu_dev *vpu = ctx->dev; - dma_addr_t src_dma, dst_dma; - - /* Source (stream) buffer. */ - src_dma = vb2_dma_contig_plane_dma_addr(&ctx->run.src->vb.vb2_buf, 0); - vdpu_write_relaxed(vpu, src_dma, VDPU_REG_ADDR_STR); - - /* Destination (decoded frame) buffer. */ - dst_dma = vb2_dma_contig_plane_dma_addr(&ctx->run.dst->vb.vb2_buf, 0); - vdpu_write_relaxed(vpu, dst_dma, VDPU_REG_ADDR_DST); - - /* Higher profiles require DMV buffer appended to reference frames. */ - if (sps->profile_idc > 66) { - size_t sizeimage = ctx->dst_fmt.plane_fmt[0].sizeimage; - size_t mv_offset = round_up(sizeimage, 8); - - if (slice->flags & V4L2_SLICE_FLAG_BOTTOM_FIELD) - mv_offset += 32 * MB_WIDTH(ctx->dst_fmt.width); - - vdpu_write_relaxed(vpu, dst_dma + mv_offset, - VDPU_REG_ADDR_DIR_MV); - } - - /* Auxiliary buffer prepared in rk3288_vpu_h264d_prepare_table(). */ - vdpu_write_relaxed(vpu, ctx->hw.h264d.priv_tbl.dma, - VDPU_REG_ADDR_QTABLE); -} - -void rk3288_vpu_h264d_run(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - - /* Prepare data in memory. */ - rk3288_vpu_h264d_prepare_table(ctx); - - rockchip_vpu_power_on(vpu); - - /* Configure hardware registers. */ - rk3288_vpu_h264d_set_params(ctx); - rk3288_vpu_h264d_set_ref(ctx); - rk3288_vpu_h264d_set_buffers(ctx); - - schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000)); - - /* Start decoding! */ - vdpu_write_relaxed(vpu, VDPU_REG_CONFIG_DEC_AXI_RD_ID(0xffu) - | VDPU_REG_CONFIG_DEC_TIMEOUT_E - | VDPU_REG_CONFIG_DEC_OUT_ENDIAN - | VDPU_REG_CONFIG_DEC_STRENDIAN_E - | VDPU_REG_CONFIG_DEC_MAX_BURST(16) - | VDPU_REG_CONFIG_DEC_OUTSWAP32_E - | VDPU_REG_CONFIG_DEC_INSWAP32_E - | VDPU_REG_CONFIG_DEC_STRSWAP32_E - | VDPU_REG_CONFIG_DEC_CLK_GATE_E, - VDPU_REG_CONFIG); - vdpu_write(vpu, VDPU_REG_INTERRUPT_DEC_E, VDPU_REG_INTERRUPT); -} diff --git a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_h264e.c b/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_h264e.c deleted file mode 100644 index 5cf22b17b24b..000000000000 --- a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_h264e.c +++ /dev/null @@ -1,1369 +0,0 @@ -/* - * Rockchip rk3288 VPU codec driver - * - * Copyright (C) 2014 Rockchip Electronics Co., Ltd. - * Alpha Lin - * Jung Zhao - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "rockchip_vpu_common.h" - -#include -#include - -#include "rk3288_vpu_regs.h" -#include "rockchip_vpu_hw.h" - -/* H.264 motion estimation parameters */ -static const u32 h264_prev_mode_favor[52] = { - 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 24, 25, 27, 29, 30, 32, 34, 36, 38, 41, 43, 46, - 49, 51, 55, 58, 61, 65, 69, 73, 78, 82, 87, 93, 98, 104, 110, - 117, 124, 132, 140 -}; - -/* sqrt(2^((qp-12)/3))*8 */ -static const u32 h264_diff_mv_penalty[52] = { - 2, 2, 3, 3, 3, 4, 4, 4, 5, 6, - 6, 7, 8, 9, 10, 11, 13, 14, 16, 18, - 20, 23, 26, 29, 32, 36, 40, 45, 51, 57, - 64, 72, 81, 91, 102, 114, 128, 144, 161, 181, - 203, 228, 256, 287, 323, 362, 406, 456, 512, 575, - 645, 724 -}; - -/* 31*sqrt(2^((qp-12)/3))/4 */ -static const u32 h264_diff_mv_penalty4p[52] = { - 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, - 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, - 20, 22, 25, 28, 31, 35, 39, 44, 49, 55, - 62, 70, 78, 88, 98, 110, 124, 139, 156, 175, - 197, 221, 248, 278, 312, 351, 394, 442, 496, 557, - 625, 701 -}; - -static const u32 h264_intra16_favor[52] = { - 24, 24, 24, 26, 27, 30, 32, 35, 39, 43, 48, 53, 58, 64, 71, 78, - 85, 93, 102, 111, 121, 131, 142, 154, 167, 180, 195, 211, 229, - 248, 271, 296, 326, 361, 404, 457, 523, 607, 714, 852, 1034, - 1272, 1588, 2008, 2568, 3318, 4323, 5672, 7486, 9928, 13216, - 17648 -}; - -static const u32 h264_inter_favor[52] = { - 40, 40, 41, 42, 43, 44, 45, 48, 51, 53, 55, 60, 62, 67, 69, 72, - 78, 84, 90, 96, 110, 120, 135, 152, 170, 189, 210, 235, 265, - 297, 335, 376, 420, 470, 522, 572, 620, 670, 724, 770, 820, - 867, 915, 970, 1020, 1076, 1132, 1180, 1230, 1275, 1320, 1370 -}; - -static u32 h264_skip_sad_penalty[52] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 233, 205, 182, 163, - 146, 132, 120, 109, 100, 92, 84, 78, 71, 66, 61, 56, 52, 48, - 44, 41, 38, 35, 32, 30, 27, 25, 23, 21, 19, 17, 15, 14, - 12, 11, 9, 8, 7, 5, 4, 3, 2, 1 -}; - -static const s32 h264_context_init_intra[460][2] = { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 unsused for I */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, - - /* 24 -> 39 */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - /* 40 -> 53 */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, - - /* 54 -> 59 */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 87 */ - { 0, 11 }, { 1, 55 }, { 0, 69 }, { -17, 127 }, - { -13, 102 }, { 0, 82 }, { -7, 74 }, { -21, 107 }, - { -27, 127 }, { -31, 127 }, { -24, 127 }, { -18, 95 }, - { -27, 127 }, { -21, 114 }, { -30, 127 }, { -17, 123 }, - { -12, 115 }, { -16, 122 }, - - /* 88 -> 104 */ - { -11, 115 }, { -12, 63 }, { -2, 68 }, { -15, 84 }, - { -13, 104 }, { -3, 70 }, { -8, 93 }, { -10, 90 }, - { -30, 127 }, { -1, 74 }, { -6, 97 }, { -7, 91 }, - { -20, 127 }, { -4, 56 }, { -5, 82 }, { -7, 76 }, - { -22, 125 }, - - /* 105 -> 135 */ - { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 }, - { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 }, - { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 }, - { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 }, - { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 }, - { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 }, - { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 }, - { 14, 62 }, { -13, 108 }, { -15, 100 }, - - /* 136 -> 165 */ - { -13, 101 }, { -13, 91 }, { -12, 94 }, { -10, 88 }, - { -16, 84 }, { -10, 86 }, { -7, 83 }, { -13, 87 }, - { -19, 94 }, { 1, 70 }, { 0, 72 }, { -5, 74 }, - { 18, 59 }, { -8, 102 }, { -15, 100 }, { 0, 95 }, - { -4, 75 }, { 2, 72 }, { -11, 75 }, { -3, 71 }, - { 15, 46 }, { -13, 69 }, { 0, 62 }, { 0, 65 }, - { 21, 37 }, { -15, 72 }, { 9, 57 }, { 16, 54 }, - { 0, 62 }, { 12, 72 }, - - /* 166 -> 196 */ - { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 }, - { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 }, - { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 }, - { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 }, - { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 }, - { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 }, - { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 }, - { 0, 89 }, { 26, -19 }, { 22, -17 }, - - /* 197 -> 226 */ - { 26, -17 }, { 30, -25 }, { 28, -20 }, { 33, -23 }, - { 37, -27 }, { 33, -23 }, { 40, -28 }, { 38, -17 }, - { 33, -11 }, { 40, -15 }, { 41, -6 }, { 38, 1 }, - { 41, 17 }, { 30, -6 }, { 27, 3 }, { 26, 22 }, - { 37, -16 }, { 35, -4 }, { 38, -8 }, { 38, -3 }, - { 37, 3 }, { 38, 5 }, { 42, 0 }, { 35, 16 }, - { 39, 22 }, { 14, 48 }, { 27, 37 }, { 21, 60 }, - { 12, 68 }, { 2, 97 }, - - /* 227 -> 251 */ - { -3, 71 }, { -6, 42 }, { -5, 50 }, { -3, 54 }, - { -2, 62 }, { 0, 58 }, { 1, 63 }, { -2, 72 }, - { -1, 74 }, { -9, 91 }, { -5, 67 }, { -5, 27 }, - { -3, 39 }, { -2, 44 }, { 0, 46 }, { -16, 64 }, - { -8, 68 }, { -10, 78 }, { -6, 77 }, { -10, 86 }, - { -12, 92 }, { -15, 55 }, { -10, 60 }, { -6, 62 }, - { -4, 65 }, - - /* 252 -> 275 */ - { -12, 73 }, { -8, 76 }, { -7, 80 }, { -9, 88 }, - { -17, 110 }, { -11, 97 }, { -20, 84 }, { -11, 79 }, - { -6, 73 }, { -4, 74 }, { -13, 86 }, { -13, 96 }, - { -11, 97 }, { -19, 117 }, { -8, 78 }, { -5, 33 }, - { -4, 48 }, { -2, 53 }, { -3, 62 }, { -13, 71 }, - { -10, 79 }, { -12, 86 }, { -13, 90 }, { -14, 97 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 307 */ - { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 }, - { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 }, - { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 }, - { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 }, - { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 }, - { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 }, - { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 }, - { 9, 64 }, { -12, 104 }, { -11, 97 }, - - /* 308 -> 337 */ - { -16, 96 }, { -7, 88 }, { -8, 85 }, { -7, 85 }, - { -9, 85 }, { -13, 88 }, { 4, 66 }, { -3, 77 }, - { -3, 76 }, { -6, 76 }, { 10, 58 }, { -1, 76 }, - { -1, 83 }, { -7, 99 }, { -14, 95 }, { 2, 95 }, - { 0, 76 }, { -5, 74 }, { 0, 70 }, { -11, 75 }, - { 1, 68 }, { 0, 65 }, { -14, 73 }, { 3, 62 }, - { 4, 62 }, { -1, 68 }, { -13, 75 }, { 11, 55 }, - { 5, 64 }, { 12, 70 }, - - /* 338 -> 368 */ - { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 }, - { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 }, - { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 }, - { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 }, - { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 }, - { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 }, - { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 }, - { -12, 109 }, { 36, -35 }, { 36, -34 }, - - /* 369 -> 398 */ - { 32, -26 }, { 37, -30 }, { 44, -32 }, { 34, -18 }, - { 34, -15 }, { 40, -15 }, { 33, -7 }, { 35, -5 }, - { 33, 0 }, { 38, 2 }, { 33, 13 }, { 23, 35 }, - { 13, 58 }, { 29, -3 }, { 26, 0 }, { 22, 30 }, - { 31, -7 }, { 35, -15 }, { 34, -3 }, { 34, 3 }, - { 36, -1 }, { 34, 5 }, { 32, 11 }, { 35, 5 }, - { 34, 12 }, { 39, 11 }, { 30, 29 }, { 34, 26 }, - { 29, 39 }, { 19, 66 }, - - /* 399 -> 435 */ - { 31, 21 }, { 31, 31 }, { 25, 50 }, - { -17, 120 }, { -20, 112 }, { -18, 114 }, { -11, 85 }, - { -15, 92 }, { -14, 89 }, { -26, 71 }, { -15, 81 }, - { -14, 80 }, { 0, 68 }, { -14, 70 }, { -24, 56 }, - { -23, 68 }, { -24, 50 }, { -11, 74 }, { 23, -13 }, - { 26, -13 }, { 40, -15 }, { 49, -14 }, { 44, 3 }, - { 45, 6 }, { 44, 34 }, { 33, 54 }, { 19, 82 }, - { -3, 75 }, { -1, 23 }, { 1, 34 }, { 1, 43 }, - { 0, 54 }, { -2, 55 }, { 0, 61 }, { 1, 64 }, - { 0, 68 }, { -9, 92 }, - - /* 436 -> 459 */ - { -14, 106 }, { -13, 97 }, { -15, 90 }, { -12, 90 }, - { -18, 88 }, { -10, 73 }, { -9, 79 }, { -14, 86 }, - { -10, 73 }, { -10, 70 }, { -10, 69 }, { -5, 66 }, - { -9, 64 }, { -5, 58 }, { 2, 59 }, { 21, -10 }, - { 24, -11 }, { 28, -8 }, { 28, -1 }, { 29, 3 }, - { 29, 9 }, { 35, 20 }, { 29, 36 }, { 14, 67 } -}; - -#define H264E_CABAC_IDC_NUM 3 -static const s32 h264_context_init[H264E_CABAC_IDC_NUM][460][2] = { - /* cabac_init_idc == 0 */ - { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 */ - { 23, 33 }, { 23, 2 }, { 21, 0 }, { 1, 9 }, - { 0, 49 }, { -37, 118 }, { 5, 57 }, { -13, 78 }, - { -11, 65 }, { 1, 62 }, { 12, 49 }, { -4, 73 }, - { 17, 50 }, - - /* 24 -> 39 */ - { 18, 64 }, { 9, 43 }, { 29, 0 }, { 26, 67 }, - { 16, 90 }, { 9, 104 }, { -46, 127 }, { -20, 104 }, - { 1, 67 }, { -13, 78 }, { -11, 65 }, { 1, 62 }, - { -6, 86 }, { -17, 95 }, { -6, 61 }, { 9, 45 }, - - /* 40 -> 53 */ - { -3, 69 }, { -6, 81 }, { -11, 96 }, { 6, 55 }, - { 7, 67 }, { -5, 86 }, { 2, 88 }, { 0, 58 }, - { -3, 76 }, { -10, 94 }, { 5, 54 }, { 4, 69 }, - { -3, 81 }, { 0, 88 }, - - /* 54 -> 59 */ - { -7, 67 }, { -5, 74 }, { -4, 74 }, { -5, 80 }, - { -7, 72 }, { 1, 58 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 87 */ - { 0, 45 }, { -4, 78 }, { -3, 96 }, { -27, 126 }, - { -28, 98 }, { -25, 101 }, { -23, 67 }, { -28, 82 }, - { -20, 94 }, { -16, 83 }, { -22, 110 }, { -21, 91 }, - { -18, 102 }, { -13, 93 }, { -29, 127 }, { -7, 92 }, - { -5, 89 }, { -7, 96 }, { -13, 108 }, { -3, 46 }, - { -1, 65 }, { -1, 57 }, { -9, 93 }, { -3, 74 }, - { -9, 92 }, { -8, 87 }, { -23, 126 }, { 5, 54 }, - { 6, 60 }, { 6, 59 }, { 6, 69 }, { -1, 48 }, - { 0, 68 }, { -4, 69 }, { -8, 88 }, - - /* 105 -> 165 */ - { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 }, - { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 }, - { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 }, - { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 }, - { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 }, - { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 }, - { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 }, - { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 }, - { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 }, - { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 }, - { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 }, - { 3, 64 }, { 1, 61 }, { 9, 63 }, { 7, 50 }, - { 16, 39 }, { 5, 44 }, { 4, 52 }, { 11, 48 }, - { -5, 60 }, { -1, 59 }, { 0, 59 }, { 22, 33 }, - { 5, 44 }, { 14, 43 }, { -1, 78 }, { 0, 60 }, - { 9, 69 }, - - /* 166 -> 226 */ - { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 }, - { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 }, - { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 }, - { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 }, - { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 }, - { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 }, - { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 }, - { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 }, - { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 }, - { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 }, - { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 }, - { 1, 67 }, { 5, 59 }, { 9, 67 }, { 16, 30 }, - { 18, 32 }, { 18, 35 }, { 22, 29 }, { 24, 31 }, - { 23, 38 }, { 18, 43 }, { 20, 41 }, { 11, 63 }, - { 9, 59 }, { 9, 64 }, { -1, 94 }, { -2, 89 }, - { -9, 108 }, - - /* 227 -> 275 */ - { -6, 76 }, { -2, 44 }, { 0, 45 }, { 0, 52 }, - { -3, 64 }, { -2, 59 }, { -4, 70 }, { -4, 75 }, - { -8, 82 }, { -17, 102 }, { -9, 77 }, { 3, 24 }, - { 0, 42 }, { 0, 48 }, { 0, 55 }, { -6, 59 }, - { -7, 71 }, { -12, 83 }, { -11, 87 }, { -30, 119 }, - { 1, 58 }, { -3, 29 }, { -1, 36 }, { 1, 38 }, - { 2, 43 }, { -6, 55 }, { 0, 58 }, { 0, 64 }, - { -3, 74 }, { -10, 90 }, { 0, 70 }, { -4, 29 }, - { 5, 31 }, { 7, 42 }, { 1, 59 }, { -2, 58 }, - { -3, 72 }, { -3, 81 }, { -11, 97 }, { 0, 58 }, - { 8, 5 }, { 10, 14 }, { 14, 18 }, { 13, 27 }, - { 2, 40 }, { 0, 58 }, { -3, 70 }, { -6, 79 }, - { -8, 85 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 337 */ - { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 }, - { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 }, - { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 }, - { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 }, - { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 }, - { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 }, - { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 }, - { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 }, - { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 }, - { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 }, - { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 }, - { -2, 69 }, { -2, 59 }, { 6, 70 }, { 10, 44 }, - { 9, 31 }, { 12, 43 }, { 3, 53 }, { 14, 34 }, - { 10, 38 }, { -3, 52 }, { 13, 40 }, { 17, 32 }, - { 7, 44 }, { 7, 38 }, { 13, 50 }, { 10, 57 }, - { 26, 43 }, - - /* 338 -> 398 */ - { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 }, - { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 }, - { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 }, - { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 }, - { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 }, - { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 }, - { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 }, - { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 }, - { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 }, - { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 }, - { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 }, - { 8, 60 }, { 6, 63 }, { 17, 65 }, { 21, 24 }, - { 23, 20 }, { 26, 23 }, { 27, 32 }, { 28, 23 }, - { 28, 24 }, { 23, 40 }, { 24, 32 }, { 28, 29 }, - { 23, 42 }, { 19, 57 }, { 22, 53 }, { 22, 61 }, - { 11, 86 }, - - /* 399 -> 435 */ - { 12, 40 }, { 11, 51 }, { 14, 59 }, - { -4, 79 }, { -7, 71 }, { -5, 69 }, { -9, 70 }, - { -8, 66 }, { -10, 68 }, { -19, 73 }, { -12, 69 }, - { -16, 70 }, { -15, 67 }, { -20, 62 }, { -19, 70 }, - { -16, 66 }, { -22, 65 }, { -20, 63 }, { 9, -2 }, - { 26, -9 }, { 33, -9 }, { 39, -7 }, { 41, -2 }, - { 45, 3 }, { 49, 9 }, { 45, 27 }, { 36, 59 }, - { -6, 66 }, { -7, 35 }, { -7, 42 }, { -8, 45 }, - { -5, 48 }, { -12, 56 }, { -6, 60 }, { -5, 62 }, - { -8, 66 }, { -8, 76 }, - - /* 436 -> 459 */ - { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, - { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, - { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, - { -14, 66 }, { 0, 59 }, { 2, 59 }, { 21, -13 }, - { 33, -14 }, { 39, -7 }, { 46, -2 }, { 51, 2 }, - { 60, 6 }, { 61, 17 }, { 55, 34 }, { 42, 62 }, - }, - - /* cabac_init_idc == 1 */ - { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 */ - { 22, 25 }, { 34, 0 }, { 16, 0 }, { -2, 9 }, - { 4, 41 }, { -29, 118 }, { 2, 65 }, { -6, 71 }, - { -13, 79 }, { 5, 52 }, { 9, 50 }, { -3, 70 }, - { 10, 54 }, - - /* 24 -> 39 */ - { 26, 34 }, { 19, 22 }, { 40, 0 }, { 57, 2 }, - { 41, 36 }, { 26, 69 }, { -45, 127 }, { -15, 101 }, - { -4, 76 }, { -6, 71 }, { -13, 79 }, { 5, 52 }, - { 6, 69 }, { -13, 90 }, { 0, 52 }, { 8, 43 }, - - /* 40 -> 53 */ - { -2, 69 }, { -5, 82 }, { -10, 96 }, { 2, 59 }, - { 2, 75 }, { -3, 87 }, { -3, 100 }, { 1, 56 }, - { -3, 74 }, { -6, 85 }, { 0, 59 }, { -3, 81 }, - { -7, 86 }, { -5, 95 }, - - /* 54 -> 59 */ - { -1, 66 }, { -1, 77 }, { 1, 70 }, { -2, 86 }, - { -5, 72 }, { 0, 61 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 104 */ - { 13, 15 }, { 7, 51 }, { 2, 80 }, { -39, 127 }, - { -18, 91 }, { -17, 96 }, { -26, 81 }, { -35, 98 }, - { -24, 102 }, { -23, 97 }, { -27, 119 }, { -24, 99 }, - { -21, 110 }, { -18, 102 }, { -36, 127 }, { 0, 80 }, - { -5, 89 }, { -7, 94 }, { -4, 92 }, { 0, 39 }, - { 0, 65 }, { -15, 84 }, { -35, 127 }, { -2, 73 }, - { -12, 104 }, { -9, 91 }, { -31, 127 }, { 3, 55 }, - { 7, 56 }, { 7, 55 }, { 8, 61 }, { -3, 53 }, - { 0, 68 }, { -7, 74 }, { -9, 88 }, - - /* 105 -> 165 */ - { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 }, - { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 }, - { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 }, - { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 }, - { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 }, - { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 }, - { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 }, - { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 }, - { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 }, - { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 }, - { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 }, - { -4, 71 }, { 0, 58 }, { 7, 61 }, { 9, 41 }, - { 18, 25 }, { 9, 32 }, { 5, 43 }, { 9, 47 }, - { 0, 44 }, { 0, 51 }, { 2, 46 }, { 19, 38 }, - { -4, 66 }, { 15, 38 }, { 12, 42 }, { 9, 34 }, - { 0, 89 }, - - /* 166 -> 226 */ - { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 }, - { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 }, - { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 }, - { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 }, - { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 }, - { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 }, - { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 }, - { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 }, - { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 }, - { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 }, - { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 }, - { 0, 75 }, { 2, 72 }, { 8, 77 }, { 14, 35 }, - { 18, 31 }, { 17, 35 }, { 21, 30 }, { 17, 45 }, - { 20, 42 }, { 18, 45 }, { 27, 26 }, { 16, 54 }, - { 7, 66 }, { 16, 56 }, { 11, 73 }, { 10, 67 }, - { -10, 116 }, - - /* 227 -> 275 */ - { -23, 112 }, { -15, 71 }, { -7, 61 }, { 0, 53 }, - { -5, 66 }, { -11, 77 }, { -9, 80 }, { -9, 84 }, - { -10, 87 }, { -34, 127 }, { -21, 101 }, { -3, 39 }, - { -5, 53 }, { -7, 61 }, { -11, 75 }, { -15, 77 }, - { -17, 91 }, { -25, 107 }, { -25, 111 }, { -28, 122 }, - { -11, 76 }, { -10, 44 }, { -10, 52 }, { -10, 57 }, - { -9, 58 }, { -16, 72 }, { -7, 69 }, { -4, 69 }, - { -5, 74 }, { -9, 86 }, { 2, 66 }, { -9, 34 }, - { 1, 32 }, { 11, 31 }, { 5, 52 }, { -2, 55 }, - { -2, 67 }, { 0, 73 }, { -8, 89 }, { 3, 52 }, - { 7, 4 }, { 10, 8 }, { 17, 8 }, { 16, 19 }, - { 3, 37 }, { -1, 61 }, { -5, 73 }, { -1, 70 }, - { -4, 78 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 337 */ - { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 }, - { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 }, - { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 }, - { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 }, - { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 }, - { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 }, - { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 }, - { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 }, - { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 }, - { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 }, - { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 }, - { -1, 70 }, { -9, 72 }, { 14, 60 }, { 16, 37 }, - { 0, 47 }, { 18, 35 }, { 11, 37 }, { 12, 41 }, - { 10, 41 }, { 2, 48 }, { 12, 41 }, { 13, 41 }, - { 0, 59 }, { 3, 50 }, { 19, 40 }, { 3, 66 }, - { 18, 50 }, - - /* 338 -> 398 */ - { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 }, - { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 }, - { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 }, - { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 }, - { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 }, - { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 }, - { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 }, - { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 }, - { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 }, - { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 }, - { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 }, - { 12, 48 }, { 11, 49 }, { 26, 45 }, { 22, 22 }, - { 23, 22 }, { 27, 21 }, { 33, 20 }, { 26, 28 }, - { 30, 24 }, { 27, 34 }, { 18, 42 }, { 25, 39 }, - { 18, 50 }, { 12, 70 }, { 21, 54 }, { 14, 71 }, - { 11, 83 }, - - /* 399 -> 435 */ - { 25, 32 }, { 21, 49 }, { 21, 54 }, - { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, - { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, - { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, - { -14, 66 }, { 0, 59 }, { 2, 59 }, { 17, -10 }, - { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, - { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, - { -5, 71 }, { 0, 24 }, { -1, 36 }, { -2, 42 }, - { -2, 52 }, { -9, 57 }, { -6, 63 }, { -4, 65 }, - { -4, 67 }, { -7, 82 }, - - /* 436 -> 459 */ - { -3, 81 }, { -3, 76 }, { -7, 72 }, { -6, 78 }, - { -12, 72 }, { -14, 68 }, { -3, 70 }, { -6, 76 }, - { -5, 66 }, { -5, 62 }, { 0, 57 }, { -4, 61 }, - { -9, 60 }, { 1, 54 }, { 2, 58 }, { 17, -10 }, - { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, - { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, - }, - - /* cabac_init_idc == 2 */ - { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 */ - { 29, 16 }, { 25, 0 }, { 14, 0 }, { -10, 51 }, - { -3, 62 }, { -27, 99 }, { 26, 16 }, { -4, 85 }, - { -24, 102 }, { 5, 57 }, { 6, 57 }, { -17, 73 }, - { 14, 57 }, - - /* 24 -> 39 */ - { 20, 40 }, { 20, 10 }, { 29, 0 }, { 54, 0 }, - { 37, 42 }, { 12, 97 }, { -32, 127 }, { -22, 117 }, - { -2, 74 }, { -4, 85 }, { -24, 102 }, { 5, 57 }, - { -6, 93 }, { -14, 88 }, { -6, 44 }, { 4, 55 }, - - /* 40 -> 53 */ - { -11, 89 }, { -15, 103 }, { -21, 116 }, { 19, 57 }, - { 20, 58 }, { 4, 84 }, { 6, 96 }, { 1, 63 }, - { -5, 85 }, { -13, 106 }, { 5, 63 }, { 6, 75 }, - { -3, 90 }, { -1, 101 }, - - /* 54 -> 59 */ - { 3, 55 }, { -4, 79 }, { -2, 75 }, { -12, 97 }, - { -7, 50 }, { 1, 60 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 104 */ - { 7, 34 }, { -9, 88 }, { -20, 127 }, { -36, 127 }, - { -17, 91 }, { -14, 95 }, { -25, 84 }, { -25, 86 }, - { -12, 89 }, { -17, 91 }, { -31, 127 }, { -14, 76 }, - { -18, 103 }, { -13, 90 }, { -37, 127 }, { 11, 80 }, - { 5, 76 }, { 2, 84 }, { 5, 78 }, { -6, 55 }, - { 4, 61 }, { -14, 83 }, { -37, 127 }, { -5, 79 }, - { -11, 104 }, { -11, 91 }, { -30, 127 }, { 0, 65 }, - { -2, 79 }, { 0, 72 }, { -4, 92 }, { -6, 56 }, - { 3, 68 }, { -8, 71 }, { -13, 98 }, - - /* 105 -> 165 */ - { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 }, - { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 }, - { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 }, - { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 }, - { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 }, - { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 }, - { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 }, - { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 }, - { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 }, - { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 }, - { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 }, - { 3, 65 }, { -7, 69 }, { 8, 77 }, { -10, 66 }, - { 3, 62 }, { -3, 68 }, { -20, 81 }, { 0, 30 }, - { 1, 7 }, { -3, 23 }, { -21, 74 }, { 16, 66 }, - { -23, 124 }, { 17, 37 }, { 44, -18 }, { 50, -34 }, - { -22, 127 }, - - /* 166 -> 226 */ - { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 }, - { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 }, - { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 }, - { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 }, - { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 }, - { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 }, - { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 }, - { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 }, - { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 }, - { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 }, - { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 }, - { 20, 34 }, { 19, 31 }, { 27, 44 }, { 19, 16 }, - { 15, 36 }, { 15, 36 }, { 21, 28 }, { 25, 21 }, - { 30, 20 }, { 31, 12 }, { 27, 16 }, { 24, 42 }, - { 0, 93 }, { 14, 56 }, { 15, 57 }, { 26, 38 }, - { -24, 127 }, - - /* 227 -> 275 */ - { -24, 115 }, { -22, 82 }, { -9, 62 }, { 0, 53 }, - { 0, 59 }, { -14, 85 }, { -13, 89 }, { -13, 94 }, - { -11, 92 }, { -29, 127 }, { -21, 100 }, { -14, 57 }, - { -12, 67 }, { -11, 71 }, { -10, 77 }, { -21, 85 }, - { -16, 88 }, { -23, 104 }, { -15, 98 }, { -37, 127 }, - { -10, 82 }, { -8, 48 }, { -8, 61 }, { -8, 66 }, - { -7, 70 }, { -14, 75 }, { -10, 79 }, { -9, 83 }, - { -12, 92 }, { -18, 108 }, { -4, 79 }, { -22, 69 }, - { -16, 75 }, { -2, 58 }, { 1, 58 }, { -13, 78 }, - { -9, 83 }, { -4, 81 }, { -13, 99 }, { -13, 81 }, - { -6, 38 }, { -13, 62 }, { -6, 58 }, { -2, 59 }, - { -16, 73 }, { -10, 76 }, { -13, 86 }, { -9, 83 }, - { -10, 87 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 337 */ - { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 }, - { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 }, - { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 }, - { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 }, - { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 }, - { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 }, - { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 }, - { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 }, - { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 }, - { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 }, - { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 }, - { -2, 76 }, { -18, 86 }, { 12, 70 }, { 5, 64 }, - { -12, 70 }, { 11, 55 }, { 5, 56 }, { 0, 69 }, - { 2, 65 }, { -6, 74 }, { 5, 54 }, { 7, 54 }, - { -6, 76 }, { -11, 82 }, { -2, 77 }, { -2, 77 }, - { 25, 42 }, - - /* 338 -> 398 */ - { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 }, - { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 }, - { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 }, - { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 }, - { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 }, - { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 }, - { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 }, - { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 }, - { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 }, - { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 }, - { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 }, - { 18, 31 }, { 19, 26 }, { 36, 24 }, { 24, 23 }, - { 27, 16 }, { 24, 30 }, { 31, 29 }, { 22, 41 }, - { 22, 42 }, { 16, 60 }, { 15, 52 }, { 14, 60 }, - { 3, 78 }, { -16, 123 }, { 21, 53 }, { 22, 56 }, - { 25, 61 }, - - /* 399 -> 435 */ - { 21, 33 }, { 19, 50 }, { 17, 61 }, - { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, - { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, - { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, - { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, - { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, - { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, - { -9, 71 }, { -7, 37 }, { -8, 44 }, { -11, 49 }, - { -10, 56 }, { -12, 59 }, { -8, 63 }, { -9, 67 }, - { -6, 68 }, { -10, 79 }, - - /* 436 -> 459 */ - { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, - { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, - { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, - { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, - { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, - { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, - } -}; - -#define CLIP3(v, min, max) ((v) < (min) ? (min) : ((v) > (max) ? (max) : (v))) - -static void rk3288_vpu_h264e_init_cabac_table(struct rockchip_vpu_ctx *ctx) -{ - u8 *table; - - const s32(*context)[460][2]; - s32 i, j, k, qp; - - for (k = 0; k < H264E_CABAC_IDC_NUM; k ++) { - table = (u8 *)ctx->hw.h264e.cabac_tbl[k].cpu; - for (qp = 0; qp < 52; qp++) { /* All QP values */ - for (j = 0; j < 2; j++) { /* Intra/Inter */ - - context = (j == 0) ? - &h264_context_init_intra : - &h264_context_init[k]; - - for (i = 0; i < 460; i++) { - s32 m = (s32)(*context)[i][0]; - s32 n = (s32)(*context)[i][1]; - - s32 pre_ctx_st = - CLIP3(((m * qp) >> 4) + n, 1, 126); - int idx = qp * 464 * 2 + j * 464 + i; - - if (pre_ctx_st <= 63) - table[idx] = - (u8)((63 - pre_ctx_st) << 1); - else - table[idx] = - (u8)(((pre_ctx_st - 64) << - 1) | 1); - } - } - } - } -} - -static inline unsigned int ref_luma_size(unsigned int w, unsigned int h) -{ - return round_up(w, MB_DIM) * round_up(h, MB_DIM); -} - -static void write_ue(struct stream_s *fifo, u32 val, - const char *name) -{ - u32 num_bits = 0; - - val++; - while (val >> ++num_bits); - - if (num_bits > 12) { - u32 tmp; - - tmp = num_bits - 1; - - if (tmp > 24) { - tmp -= 24; - stream_put_bits(fifo, 0, 24, name); - } - - stream_put_bits(fifo, 0, tmp, name); - - if (num_bits > 24) { - num_bits -= 24; - stream_put_bits(fifo, val >> num_bits, 24, name); - val = val >> num_bits; - } - - stream_put_bits(fifo, val, num_bits, name); - } else { - stream_put_bits(fifo, val, 2 * num_bits - 1, name); - } -} - -static void write_se(struct stream_s *fifo, s32 val, const char *name) -{ - u32 tmp; - - if (val > 0) - tmp = (u32)(2 * val - 1); - else - tmp = (u32)(-2 * val); - - write_ue(fifo, tmp, name); -} - -static int rk3288_vpu_h264e_assumble_sps(struct rockchip_vpu_ctx *ctx) -{ - struct stream_s *sps = &ctx->run.h264e.sps; - - stream_buffer_reset(sps); - - stream_put_bits(sps, 0, 8, "start code"); - stream_put_bits(sps, 0, 8, "start code"); - stream_put_bits(sps, 0, 8, "start code"); - stream_put_bits(sps, 1, 8, "start code"); - - stream_put_bits(sps, 0, 1, "forbidden_zero_bit"); - stream_put_bits(sps, 1, 2, "nal_ref_idc"); - stream_put_bits(sps, 7, 5, "nal_unit_type"); - - stream_put_bits(sps, 77, 8, "profile_idc"); - stream_put_bits(sps, 0, 1, "constraint_set0_flag"); - stream_put_bits(sps, 0, 1, "constraint_set1_flag"); - stream_put_bits(sps, 0, 1, "constraint_set2_flag"); - stream_put_bits(sps, 1, 1, "constraint_set3_flag"); - - stream_put_bits(sps, 0, 4, "reserved_zero_4bits"); - stream_put_bits(sps, 30, 8, "level_idc"); - - write_ue(sps, 0, "seq_parameter_set_id"); - - write_ue(sps, 16 - 4, "log2_max_frame_num_minus4"); - - write_ue(sps, 2, "pic_order_cnt_type"); - - write_ue(sps, 1, "num_ref_frames"); - - stream_put_bits(sps, 0, 1, "gaps_in_frame_num_value_allowed_flag"); - - write_ue(sps, MB_WIDTH(ctx->src_fmt.width) - 1, - "pic_width_in_mbs_minus1"); - - write_ue(sps, MB_HEIGHT(ctx->src_fmt.height) - 1, - "pic_height_in_map_units_minus1"); - - stream_put_bits(sps, 1, 1, "frame_mbs_only_flag"); - - stream_put_bits(sps, 0, 1, "direct_8x8_inference_flag"); - - stream_put_bits(sps, 0, 1, "frame_cropping_flag"); - - stream_put_bits(sps, 0, 1, "vui_parameters_present_flag"); - - stream_put_bits(sps, 1, 1, "rbsp_stop_one_bit"); - if (sps->buffered_bits > 0) - stream_put_bits(sps, 0, 8 - sps->buffered_bits, - "bsp_alignment_zero_bits"); - - - return 0; -} - -static int rk3288_vpu_h264e_assumble_pps(struct rockchip_vpu_ctx *ctx) -{ - const struct rk3288_h264e_reg_params *params = - (struct rk3288_h264e_reg_params *)ctx->run.h264e.reg_params; - struct stream_s *pps = &ctx->run.h264e.pps; - - stream_buffer_reset(pps); - - stream_put_bits(pps, 0, 8, "start code"); - stream_put_bits(pps, 0, 8, "start code"); - stream_put_bits(pps, 0, 8, "start code"); - stream_put_bits(pps, 1, 8, "start code"); - - stream_put_bits(pps, 0, 1, "forbidden_zero_bit"); - stream_put_bits(pps, 1, 2, "nal_ref_idc"); - stream_put_bits(pps, 8, 5, "nal_unit_type"); - - write_ue(pps, 0, "pic_parameter_set_id"); - write_ue(pps, 0, "seq_parameter_set_id"); - - stream_put_bits(pps, params->enable_cabac, 1, - "entropy_coding_mode_flag"); - stream_put_bits(pps, 0, 1, "pic_order_present_flag"); - - write_ue(pps, 0, "num_slice_groups_minus1"); - write_ue(pps, 0, "num_ref_idx_l0_active_minus1"); - write_ue(pps, 0, "num_ref_idx_l1_active_minus1"); - - stream_put_bits(pps, 0, 1, "weighted_pred_flag"); - stream_put_bits(pps, 0, 2, "weighted_bipred_idc"); - - write_se(pps, params->pic_init_qp - 26, - "pic_init_qp_minus26"); - write_se(pps, 0, "pic_init_qs_minus26"); - write_se(pps, params->chroma_qp_index_offset, - "chroma_qp_index_offset"); - - stream_put_bits(pps, 1, 1, - "deblocking_filter_control_present_flag"); - stream_put_bits(pps, 0, 1, "constrained_intra_pred_flag"); - - stream_put_bits(pps, 0, 1, "redundant_pic_cnt_present_flag"); - - if (params->transform8x8_mode) { - stream_put_bits(pps, 1, 1, "transform_8x8_mode_flag"); - stream_put_bits(pps, 0, 1, "pic_scaling_matrix_present_flag"); - write_se(pps, params->chroma_qp_index_offset, - "chroma_qp_index_offset"); - } - stream_put_bits(pps, 1, 1, "rbsp_stop_one_bit"); - if (pps->buffered_bits > 0) - stream_put_bits(pps, 0, 8 - pps->buffered_bits, - "bsp_alignment_zero_bits"); - - return 0; -} - -int rk3288_vpu_h264e_init(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - size_t ref_buf_size; - size_t height = ctx->src_fmt.height; - size_t width = ctx->src_fmt.width; - int ret; - int i; - - vpu_debug_enter(); - - for (i = 0; i < H264E_CABAC_IDC_NUM; i++) { - ret = rockchip_vpu_aux_buf_alloc(vpu, &ctx->hw.h264e.cabac_tbl[i], - 52 * 2 * 464); - if (ret) { - vpu_err("allocate h264e cabac_tbl failed\n"); - goto err_cabac_tbl_alloc; - } - } - - ref_buf_size = ref_luma_size(width, height) * 3 / 2; - ret = rockchip_vpu_aux_buf_alloc(vpu, &ctx->hw.h264e.ext_buf, - 2 * ref_buf_size); - if (ret) { - vpu_err("allocate ext_buf failed\n"); - goto err_ext_buf_alloc; - } - - if (0 > stream_buffer_init(&ctx->run.h264e.sps, NULL, 128)) - goto err_init_sps_buffer; - - if (0 > stream_buffer_init(&ctx->run.h264e.pps, NULL, 128)) - goto err_init_pps_buffer; - - rk3288_vpu_h264e_init_cabac_table(ctx); - - return ret; - -err_init_pps_buffer: - kfree(&ctx->run.h264e.sps.buffer); -err_init_sps_buffer: - rockchip_vpu_aux_buf_free(vpu, &ctx->hw.h264e.ext_buf); -err_ext_buf_alloc: - for (i = 0; i < H264E_CABAC_IDC_NUM; i++) - if (ctx->hw.h264e.cabac_tbl[i].size != 0) - rockchip_vpu_aux_buf_free(vpu, - &ctx->hw.h264e.cabac_tbl[i]); - -err_cabac_tbl_alloc: - vpu_debug_leave(); - - return ret; -} - -void rk3288_vpu_h264e_exit(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - int i; - - vpu_debug_enter(); - - kfree(ctx->run.h264e.sps.buffer); - kfree(ctx->run.h264e.pps.buffer); - rockchip_vpu_aux_buf_free(vpu, &ctx->hw.h264e.ext_buf); - - for (i = 0; i < H264E_CABAC_IDC_NUM; i++) - rockchip_vpu_aux_buf_free(vpu, &ctx->hw.h264e.cabac_tbl[i]); - - vpu_debug_leave(); -} - -static void rk3288_vpu_h264e_set_buffers(struct rockchip_vpu_dev *vpu, - struct rockchip_vpu_ctx *ctx) -{ - const struct rk3288_h264e_reg_params *params = - (struct rk3288_h264e_reg_params *)ctx->run.h264e.reg_params; - dma_addr_t ref_buf_dma, rec_buf_dma; - size_t rounded_size; - dma_addr_t dst_dma; - - dma_addr_t cabac_dma = - ctx->hw.h264e.cabac_tbl[params->cabac_init_idc].dma; - - dst_dma = vb2_dma_contig_plane_dma_addr(&ctx->run.dst->vb.vb2_buf, 0) + - ctx->run.h264e.hw_write_offset; - - vepu_write_relaxed(vpu, cabac_dma, VEPU_REG_ADDR_CABAC_TBL); - - vepu_write_relaxed(vpu, dst_dma, VEPU_REG_ADDR_OUTPUT_STREAM); - - vepu_write_relaxed(vpu, 0, VEPU_REG_ADDR_OUTPUT_CTRL); - - rounded_size = ref_luma_size(ctx->src_fmt.width, - ctx->src_fmt.height); - ref_buf_dma = rec_buf_dma = ctx->hw.h264e.ext_buf.dma; - if (ctx->hw.h264e.ref_rec_ptr) - rec_buf_dma += rounded_size * 3 / 2; - else - ref_buf_dma += rounded_size * 3 / 2; - ctx->hw.h264e.ref_rec_ptr ^= 1; - - vepu_write_relaxed(vpu, ref_buf_dma, VEPU_REG_ADDR_REF_LUMA); - vepu_write_relaxed(vpu, ref_buf_dma + rounded_size, - VEPU_REG_ADDR_REF_CHROMA); - vepu_write_relaxed(vpu, rec_buf_dma, VEPU_REG_ADDR_REC_LUMA); - vepu_write_relaxed(vpu, rec_buf_dma + rounded_size, - VEPU_REG_ADDR_REC_CHROMA); - - vepu_write_relaxed(vpu, vb2_dma_contig_plane_dma_addr( - &ctx->run.src->vb.vb2_buf, PLANE_Y), - VEPU_REG_ADDR_IN_LUMA); - vepu_write_relaxed(vpu, vb2_dma_contig_plane_dma_addr( - &ctx->run.src->vb.vb2_buf, PLANE_CB), - VEPU_REG_ADDR_IN_CB); - vepu_write_relaxed(vpu, vb2_dma_contig_plane_dma_addr( - &ctx->run.src->vb.vb2_buf, PLANE_CR), - VEPU_REG_ADDR_IN_CR); - -} - -static s32 exp_golomb_signed(s32 val) -{ - s32 tmp = 0; - - if (val > 0) - val = 2 * val; - else - val = -2 * val + 1; - - while (val >> ++tmp) - ; - - return tmp * 2 - 1; -} - -static void rk3288_vpu_h264e_set_params(struct rockchip_vpu_dev *vpu, - struct rockchip_vpu_ctx *ctx) -{ - const struct rk3288_h264e_reg_params *params = - (struct rk3288_h264e_reg_params *)ctx->run.h264e.reg_params; - struct v4l2_pix_format_mplane *pix_fmt = &ctx->src_fmt; - s32 scaler, i; - u32 reg; - u32 prev_mode_favor = h264_prev_mode_favor[params->qp]; - - u32 mbs_in_row = MB_WIDTH(ctx->dst_fmt.width); - u32 mbs_in_col = MB_HEIGHT(ctx->dst_fmt.height); - struct v4l2_rect *crop = &ctx->src_crop; - u32 overfill_r, overfill_b, bytes_per_line; - u32 first_free_bit = 0; - u32 skip_penalty; - - u8 dmv_penalty[128]; - u8 dmv_qpel_penalty[128]; - u32 diff_mv_penalty[3]; - u32 split_penalty[4]; - - /* If frame encode type for current frame is intra, write sps pps to - the output buffer */ - ctx->run.h264e.hw_write_offset = 0; - if (params->frame_coding_type == 1) { - ctx->run.h264e.hw_write_offset = ctx->run.h264e.sps.byte_cnt + - ctx->run.h264e.pps.byte_cnt; - first_free_bit = (ctx->run.h264e.hw_write_offset & 0x7) * 8; - ctx->run.h264e.hw_write_offset &= ~0x7; - } - - /* - * The hardware needs only the value for luma plane, because - * values of other planes are calculated internally based on - * format setting. - */ - bytes_per_line = pix_fmt->plane_fmt[0].bytesperline; - overfill_r = (pix_fmt->width - crop->width) / 4; - overfill_b = pix_fmt->height - crop->height; - - reg = VEPU_REG_IN_IMG_CTRL_ROW_LEN(bytes_per_line) - | VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(overfill_r) - | VEPU_REG_IN_IMG_CTRL_OVRFLB_D4(overfill_b) - | VEPU_REG_IN_IMG_CTRL_FMT(ctx->vpu_src_fmt->enc_fmt); - vepu_write_relaxed(vpu, reg, VEPU_REG_IN_IMG_CTRL); - - reg = VEPU_REG_ENC_CTRL0_INIT_QP(params->pic_init_qp) | - VEPU_REG_ENC_CTRL0_SLICE_ALPHA(params->slice_alpha_offset) | - VEPU_REG_ENC_CTRL0_SLICE_BETA(params->slice_beta_offset) | - VEPU_REG_ENC_CTRL0_CHROMA_QP_OFFSET(params->chroma_qp_index_offset) | - VEPU_REG_ENC_CTRL0_FILTER_DIS(params->filter_disable) | - VEPU_REG_ENC_CTRL0_IDR_PICID(params->idr_pic_id); - vepu_write_relaxed(vpu, reg, VEPU_REG_ENC_CTRL0); - - reg = VEPU_REG_ENC_CTRL1_PPS_ID(params->pps_id) | - VEPU_REG_ENC_CTRL1_INTRA_PRED_MODE(prev_mode_favor) | - VEPU_REG_ENC_CTRL1_FRAME_NUM(params->frame_num); - - vepu_write_relaxed(vpu, reg, VEPU_REG_ENC_CTRL1); - - reg = VEPU_REG_ENC_CTRL2_H264_SLICE_SIZE(params->slice_size_mb_rows) | - VEPU_REG_ENC_CTRL2_CABAC_INIT_IDC(params->cabac_init_idc) | - VEPU_REG_ENC_CTRL2_INTRA16X16_MODE(h264_intra16_favor[params->qp]); - - if (params->h264_inter4x4_disabled) - reg |= VEPU_REG_ENC_CTRL2_H264_INTER4X4_MODE; - if (params->enable_cabac) - reg |= VEPU_REG_ENC_CTRL2_ENTROPY_CODING_MODE; - if (params->transform8x8_mode) - reg |= VEPU_REG_ENC_CTRL2_TRANS8X8_MODE_EN; - if (mbs_in_row * mbs_in_col > 3600) - reg |= VEPU_REG_ENC_CTRL2_DISABLE_QUARTER_PIXMV; - - vepu_write_relaxed(vpu, reg, VEPU_REG_ENC_CTRL2); - - scaler = max(1U, 200 / (mbs_in_row + mbs_in_col)); - skip_penalty = min(255U, h264_skip_sad_penalty[params->qp] * scaler); - - diff_mv_penalty[0] = h264_diff_mv_penalty4p[params->qp]; - diff_mv_penalty[1] = h264_diff_mv_penalty[params->qp]; - diff_mv_penalty[2] = h264_diff_mv_penalty[params->qp]; - split_penalty[0] = 0; - split_penalty[1] = 0; - split_penalty[2] = 0; - split_penalty[3] = 0; - - reg = VEPU_REG_ENC_CTRL3_MUTIMV_EN | - VEPU_REG_ENC_CTRL3_MV_PENALTY_1_4P(split_penalty[2]) | - VEPU_REG_ENC_CTRL3_MV_PENALTY_4P(diff_mv_penalty[0]) | - VEPU_REG_ENC_CTRL3_MV_PENALTY_1P(diff_mv_penalty[1]); - - vepu_write_relaxed(vpu, reg, VEPU_REG_ENC_CTRL3); - - reg = VEPU_REG_MVC_CTRL_MV16X16_FAVOR(10); - - vepu_write_relaxed(vpu, reg, VEPU_REG_MVC_CTRL); - - vepu_write_relaxed(vpu, 0, VEPU_REG_ENC_CTRL4); - - reg = VEPU_REG_ENC_CTRL5_MACROBLOCK_PENALTY(skip_penalty) | - VEPU_REG_ENC_CTRL5_INTER_MODE(h264_inter_favor[params->qp]); - vepu_write_relaxed(vpu, reg, VEPU_REG_ENC_CTRL5); - - vepu_write_relaxed(vpu, 0, VEPU_REG_STR_HDR_REM_MSB); - vepu_write_relaxed(vpu, 0, VEPU_REG_STR_HDR_REM_LSB); - vepu_write_relaxed(vpu, vb2_plane_size(&ctx->run.dst->vb.vb2_buf, 0) - - ctx->run.h264e.hw_write_offset, - VEPU_REG_STR_BUF_LIMIT); - - reg = VEPU_REG_MAD_CTRL_QP_ADJUST(params->mad_qp_delta) | - VEPU_REG_MAD_CTRL_MAD_THREDHOLD(params->mad_threshold); - - vepu_write_relaxed(vpu, reg, VEPU_REG_MAD_CTRL); - - reg = VEPU_REG_QP_VAL_LUM(params->qp) | - VEPU_REG_QP_VAL_MAX(params->qp_max) | - VEPU_REG_QP_VAL_MIN(params->qp_min) | - VEPU_REG_QP_VAL_CHECKPOINT_DISTAN(params->cp_distance_mbs); - - vepu_write_relaxed(vpu, reg, VEPU_REG_QP_VAL); - - reg = VEPU_REG_CHECKPOINT_CHECK1(params->cp_target[0]) - | VEPU_REG_CHECKPOINT_CHECK0(params->cp_target[1]); - vepu_write_relaxed(vpu, reg, VEPU_REG_CHECKPOINT(0)); - - reg = VEPU_REG_CHECKPOINT_CHECK1(params->cp_target[2]) - | VEPU_REG_CHECKPOINT_CHECK0(params->cp_target[3]); - vepu_write_relaxed(vpu, reg, VEPU_REG_CHECKPOINT(1)); - - reg = VEPU_REG_CHECKPOINT_CHECK1(params->cp_target[4]) - | VEPU_REG_CHECKPOINT_CHECK0(params->cp_target[5]); - vepu_write_relaxed(vpu, reg, VEPU_REG_CHECKPOINT(2)); - - reg = VEPU_REG_CHECKPOINT_CHECK1(params->cp_target[6]) - | VEPU_REG_CHECKPOINT_CHECK0(params->cp_target[7]); - vepu_write_relaxed(vpu, reg, VEPU_REG_CHECKPOINT(3)); - - reg = VEPU_REG_CHECKPOINT_CHECK1(params->cp_target[8]) - | VEPU_REG_CHECKPOINT_CHECK0(params->cp_target[9]); - vepu_write_relaxed(vpu, reg, VEPU_REG_CHECKPOINT(4)); - - reg = VEPU_REG_CHKPT_WORD_ERR_CHK1(params->target_error[0]) - | VEPU_REG_CHKPT_WORD_ERR_CHK0(params->target_error[1]); - vepu_write_relaxed(vpu, reg, VEPU_REG_CHKPT_WORD_ERR(0)); - - reg = VEPU_REG_CHKPT_WORD_ERR_CHK1(params->target_error[2]) - | VEPU_REG_CHKPT_WORD_ERR_CHK0(params->target_error[3]); - vepu_write_relaxed(vpu, reg, VEPU_REG_CHKPT_WORD_ERR(1)); - - reg = VEPU_REG_CHKPT_WORD_ERR_CHK1(params->target_error[4]) - | VEPU_REG_CHKPT_WORD_ERR_CHK0(params->target_error[5]); - vepu_write_relaxed(vpu, reg, VEPU_REG_CHKPT_WORD_ERR(2)); - - reg = VEPU_REG_CHKPT_DELTA_QP_CHK6(params->delta_qp[6]) - | VEPU_REG_CHKPT_DELTA_QP_CHK5(params->delta_qp[5]) - | VEPU_REG_CHKPT_DELTA_QP_CHK4(params->delta_qp[4]) - | VEPU_REG_CHKPT_DELTA_QP_CHK3(params->delta_qp[3]) - | VEPU_REG_CHKPT_DELTA_QP_CHK2(params->delta_qp[2]) - | VEPU_REG_CHKPT_DELTA_QP_CHK1(params->delta_qp[1]) - | VEPU_REG_CHKPT_DELTA_QP_CHK0(params->delta_qp[0]); - vepu_write_relaxed(vpu, reg, VEPU_REG_CHKPT_DELTA_QP); - - reg = first_free_bit << VEPU_REG_RLC_CTRL_STR_OFFS_SHIFT; - - vepu_write_relaxed(vpu, reg, VEPU_REG_RLC_CTRL); - - vepu_write_relaxed(vpu, 0, VEPU_REG_ADDR_NEXT_PIC); - vepu_write_relaxed(vpu, 0, VEPU_REG_STABLILIZATION_OUTPUT); - - vepu_write_relaxed(vpu, 0, VEPU_REG_ADDR_MV_OUT); - - vepu_write_relaxed(vpu, 0, VEPU_REG_RGB_YUV_COEFF(0)); - vepu_write_relaxed(vpu, 0, VEPU_REG_RGB_YUV_COEFF(1)); - //vepu_write_relaxed(vpu, 0, VEPU_REG_RGB_YUV_COEFF(2)); - vepu_write_relaxed(vpu, 0, VEPU_REG_RGB_MASK_MSB); - - vepu_write_relaxed(vpu, 0, VEPU_REG_INTRA_AREA_CTRL); - - vepu_write_relaxed(vpu, 0, VEPU_REG_FIRST_ROI_AREA); - vepu_write_relaxed(vpu, 0, VEPU_REG_SECOND_ROI_AREA); - - for (i = 0; i < 128; i++) { - dmv_penalty[i] = i; - dmv_qpel_penalty[i] = min(255, exp_golomb_signed(i)); - } - - for (i = 0; i < 128; i += 4) { - reg = VEPU_REG_DMV_4P_1P_PENALTY_BIT(dmv_penalty[i], 3); - reg |= VEPU_REG_DMV_4P_1P_PENALTY_BIT(dmv_penalty[i + 1], 2); - reg |= VEPU_REG_DMV_4P_1P_PENALTY_BIT(dmv_penalty[i + 2], 1); - reg |= VEPU_REG_DMV_4P_1P_PENALTY_BIT(dmv_penalty[i + 3], 0); - vepu_write_relaxed(vpu, reg, VEPU_REG_DMV_4P_1P_PENALTY(i / 4)); - - reg = VEPU_REG_DMV_QPEL_PENALTY_BIT( - dmv_qpel_penalty[i], 3); - reg |= VEPU_REG_DMV_QPEL_PENALTY_BIT( - dmv_qpel_penalty[i + 1], 2); - reg |= VEPU_REG_DMV_QPEL_PENALTY_BIT( - dmv_qpel_penalty[i + 2], 1); - reg |= VEPU_REG_DMV_QPEL_PENALTY_BIT( - dmv_qpel_penalty[i + 3], 0); - vepu_write_relaxed(vpu, reg, - VEPU_REG_DMV_QPEL_PENALTY(i / 4)); - } -} - -void rk3288_vpu_h264e_run(struct rockchip_vpu_ctx *ctx) -{ - const struct rk3288_h264e_reg_params *params = - (struct rk3288_h264e_reg_params *)ctx->run.h264e.reg_params; - struct rockchip_vpu_dev *vpu = ctx->dev; - u32 reg; - u32 mbs_in_row = (ctx->dst_fmt.width + 15) / 16; - u32 mbs_in_col = (ctx->dst_fmt.height + 15) / 16; - - vpu_debug_enter(); - - if (params->frame_coding_type == 1) { - rk3288_vpu_h264e_assumble_sps(ctx); - rk3288_vpu_h264e_assumble_pps(ctx); - } - - /* - * Program the hardware. - */ - rockchip_vpu_power_on(vpu); - - /* Select encode mode first. */ - vepu_write_relaxed(vpu, VEPU_REG_ENC_CTRL_ENC_MODE_H264, - VEPU_REG_ENC_CTRL); - - rk3288_vpu_h264e_set_params(vpu, ctx); - rk3288_vpu_h264e_set_buffers(vpu, ctx); - - /* Make sure that all registers are written at this point. */ - wmb(); - - /* Set the watchdog. */ - schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000)); - - /* Start the hardware. */ - reg = VEPU_REG_AXI_CTRL_OUTPUT_SWAP16 - | VEPU_REG_AXI_CTRL_INPUT_SWAP16 - | VEPU_REG_AXI_CTRL_BURST_LEN(16) - | VEPU_REG_AXI_CTRL_GATE_BIT - | VEPU_REG_AXI_CTRL_OUTPUT_SWAP32 - | VEPU_REG_AXI_CTRL_INPUT_SWAP32 - | VEPU_REG_AXI_CTRL_OUTPUT_SWAP8 - | VEPU_REG_AXI_CTRL_INPUT_SWAP8; - vepu_write(vpu, reg, VEPU_REG_AXI_CTRL); - - vepu_write(vpu, 0, VEPU_REG_INTERRUPT); - - reg = VEPU_REG_ENC_CTRL_WIDTH(mbs_in_row) - | VEPU_REG_ENC_CTRL_HEIGHT(mbs_in_col) - | VEPU_REG_ENC_CTRL_ENC_MODE_H264 - | VEPU_REG_PIC_TYPE(params->frame_coding_type) - | VEPU_REG_ENC_CTRL_EN_BIT; - - /*if (ctx->run.dst->b.v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) - reg |= VEPU_REG_ENC_CTRL_KEYFRAME_BIT;*/ - - vepu_write_relaxed(vpu, reg, VEPU_REG_ENC_CTRL); - - vpu_debug_leave(); -} - -void rk3288_vpu_h264e_done(struct rockchip_vpu_ctx *ctx, - enum vb2_buffer_state result) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - struct rockchip_vpu_h264e_feedback *feedback = - (struct rockchip_vpu_h264e_feedback *)ctx->run.priv_dst.cpu; - u32 i, reg = VEPU_REG_CHECKPOINT(0); - u32 cpt_prev = 0, overflow = 0; - - vpu_debug_enter(); - - feedback->qp_sum = - VEPU_REG_MAD_CTRL_QP_SUM_DIV2(vepu_read(vpu, VEPU_REG_MAD_CTRL)) * 2; - feedback->mad_count = - VEPU_REG_MB_CNT_OUT(vepu_read(vpu, VEPU_REG_MB_CTRL)); - feedback->rlc_count = - VEPU_REG_RLC_CTRL_RLC_SUM(vepu_read(vpu, VEPU_REG_RLC_CTRL)) * 4; - - for (i = 0; i < 10; i++) { - u32 cpt = VEPU_REG_CHECKPOINT_RESULT(vepu_read(vpu, reg)); - - if (cpt < cpt_prev) - overflow += (1 << 21); - feedback->cp[i] = cpt + overflow; - reg += (i & 1); - } - - if (ctx->run.h264e.hw_write_offset) { - ctx->run.dst->h264e.sps_size = - ctx->run.h264e.sps.byte_cnt; - ctx->run.dst->h264e.pps_size = - ctx->run.h264e.pps.byte_cnt; - vpu_debug(1, "sps %d, pps %d\n", - ctx->run.dst->h264e.sps_size, - ctx->run.dst->h264e.pps_size); - } else { - ctx->run.dst->h264e.sps_size = 0; - ctx->run.dst->h264e.pps_size = 0; - } - - ctx->run.dst->h264e.slices_size = - vepu_read(vpu, VEPU_REG_STR_BUF_LIMIT) / 8; - - rockchip_vpu_run_done(ctx, result); - - vpu_debug_leave(); -} diff --git a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_vp8d.c b/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_vp8d.c deleted file mode 100644 index 473605e9e577..000000000000 --- a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_vp8d.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Rockchip RK3288 VPU codec vp8 decode driver - * - * Copyright (C) 2014 Rockchip Electronics Co., Ltd. - * ZhiChao Yu - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "rockchip_vpu_hw.h" -#include "rk3288_vpu_regs.h" -#include "rockchip_vpu_common.h" - -#define DEC_8190_ALIGN_MASK 0x07U - -/* - * probs table with packed - */ -struct vp8_prob_tbl_packed { - u8 prob_mb_skip_false; - u8 prob_intra; - u8 prob_ref_last; - u8 prob_ref_golden; - u8 prob_segment[3]; - u8 packed0; - - u8 prob_luma_16x16_pred_mode[4]; - u8 prob_chroma_pred_mode[3]; - u8 packed1; - - /* mv prob */ - u8 prob_mv_context[2][19]; - u8 packed2[2]; - - /* coeff probs */ - u8 prob_coeffs[4][8][3][11]; - u8 packed3[96]; -}; - -struct vp8d_reg { - u32 base; - u32 shift; - u32 mask; -}; - -/* dct partiton base address regs */ -static const struct vp8d_reg vp8d_dct_base[8] = { - { VDPU_REG_ADDR_STR, 0, 0xffffffff }, - { VDPU_REG_ADDR_REF(8), 0, 0xffffffff }, - { VDPU_REG_ADDR_REF(9), 0, 0xffffffff }, - { VDPU_REG_ADDR_REF(10), 0, 0xffffffff }, - { VDPU_REG_ADDR_REF(11), 0, 0xffffffff }, - { VDPU_REG_ADDR_REF(12), 0, 0xffffffff }, - { VDPU_REG_ADDR_REF(14), 0, 0xffffffff }, - { VDPU_REG_ADDR_REF(15), 0, 0xffffffff }, -}; - -/* loop filter level regs */ -static const struct vp8d_reg vp8d_lf_level[4] = { - { VDPU_REG_REF_PIC(2), 18, 0x3f }, - { VDPU_REG_REF_PIC(2), 12, 0x3f }, - { VDPU_REG_REF_PIC(2), 6, 0x3f }, - { VDPU_REG_REF_PIC(2), 0, 0x3f }, -}; - -/* macroblock loop filter level adjustment regs */ -static const struct vp8d_reg vp8d_mb_adj[4] = { - { VDPU_REG_REF_PIC(0), 21, 0x7f }, - { VDPU_REG_REF_PIC(0), 14, 0x7f }, - { VDPU_REG_REF_PIC(0), 7, 0x7f }, - { VDPU_REG_REF_PIC(0), 0, 0x7f }, -}; - -/* reference frame adjustment regs */ -static const struct vp8d_reg vp8d_ref_adj[4] = { - { VDPU_REG_REF_PIC(1), 21, 0x7f }, - { VDPU_REG_REF_PIC(1), 14, 0x7f }, - { VDPU_REG_REF_PIC(1), 7, 0x7f }, - { VDPU_REG_REF_PIC(1), 0, 0x7f }, -}; - -/* quantizer regs */ -static const struct vp8d_reg vp8d_quant[4] = { - { VDPU_REG_REF_PIC(3), 11, 0x7ff }, - { VDPU_REG_REF_PIC(3), 0, 0x7ff }, - { VDPU_REG_BD_REF_PIC(4), 11, 0x7ff }, - { VDPU_REG_BD_REF_PIC(4), 0, 0x7ff }, -}; - -/* quantizer delta regs */ -static const struct vp8d_reg vp8d_quant_delta[5] = { - { VDPU_REG_REF_PIC(3), 27, 0x1f }, - { VDPU_REG_REF_PIC(3), 22, 0x1f }, - { VDPU_REG_BD_REF_PIC(4), 27, 0x1f }, - { VDPU_REG_BD_REF_PIC(4), 22, 0x1f }, - { VDPU_REG_BD_P_REF_PIC, 27, 0x1f }, -}; - -/* dct partition start bits regs */ -static const struct vp8d_reg vp8d_dct_start_bits[8] = { - { VDPU_REG_DEC_CTRL2, 26, 0x3f }, { VDPU_REG_DEC_CTRL4, 26, 0x3f }, - { VDPU_REG_DEC_CTRL4, 20, 0x3f }, { VDPU_REG_DEC_CTRL7, 24, 0x3f }, - { VDPU_REG_DEC_CTRL7, 18, 0x3f }, { VDPU_REG_DEC_CTRL7, 12, 0x3f }, - { VDPU_REG_DEC_CTRL7, 6, 0x3f }, { VDPU_REG_DEC_CTRL7, 0, 0x3f }, -}; - -/* precision filter tap regs */ -static const struct vp8d_reg vp8d_pred_bc_tap[8][4] = { - { - { VDPU_REG_PRED_FLT, 22, 0x3ff }, - { VDPU_REG_PRED_FLT, 12, 0x3ff }, - { VDPU_REG_PRED_FLT, 2, 0x3ff }, - { VDPU_REG_REF_PIC(4), 22, 0x3ff }, - }, - { - { VDPU_REG_REF_PIC(4), 12, 0x3ff }, - { VDPU_REG_REF_PIC(4), 2, 0x3ff }, - { VDPU_REG_REF_PIC(5), 22, 0x3ff }, - { VDPU_REG_REF_PIC(5), 12, 0x3ff }, - }, - { - { VDPU_REG_REF_PIC(5), 2, 0x3ff }, - { VDPU_REG_REF_PIC(6), 22, 0x3ff }, - { VDPU_REG_REF_PIC(6), 12, 0x3ff }, - { VDPU_REG_REF_PIC(6), 2, 0x3ff }, - }, - { - { VDPU_REG_REF_PIC(7), 22, 0x3ff }, - { VDPU_REG_REF_PIC(7), 12, 0x3ff }, - { VDPU_REG_REF_PIC(7), 2, 0x3ff }, - { VDPU_REG_LT_REF, 22, 0x3ff }, - }, - { - { VDPU_REG_LT_REF, 12, 0x3ff }, - { VDPU_REG_LT_REF, 2, 0x3ff }, - { VDPU_REG_VALID_REF, 22, 0x3ff }, - { VDPU_REG_VALID_REF, 12, 0x3ff }, - }, - { - { VDPU_REG_VALID_REF, 2, 0x3ff }, - { VDPU_REG_BD_REF_PIC(0), 22, 0x3ff }, - { VDPU_REG_BD_REF_PIC(0), 12, 0x3ff }, - { VDPU_REG_BD_REF_PIC(0), 2, 0x3ff }, - }, - { - { VDPU_REG_BD_REF_PIC(1), 22, 0x3ff }, - { VDPU_REG_BD_REF_PIC(1), 12, 0x3ff }, - { VDPU_REG_BD_REF_PIC(1), 2, 0x3ff }, - { VDPU_REG_BD_REF_PIC(2), 22, 0x3ff }, - }, - { - { VDPU_REG_BD_REF_PIC(2), 12, 0x3ff }, - { VDPU_REG_BD_REF_PIC(2), 2, 0x3ff }, - { VDPU_REG_BD_REF_PIC(3), 22, 0x3ff }, - { VDPU_REG_BD_REF_PIC(3), 12, 0x3ff }, - }, -}; - -/* - * filter taps taken to 7-bit precision, - * reference RFC6386#Page-16, filters[8][6] - */ -static const u32 vp8d_mc_filter[8][6] = { - { 0, 0, 128, 0, 0, 0 }, - { 0, -6, 123, 12, -1, 0 }, - { 2, -11, 108, 36, -8, 1 }, - { 0, -9, 93, 50, -6, 0 }, - { 3, -16, 77, 77, -16, 3 }, - { 0, -6, 50, 93, -9, 0 }, - { 1, -8, 36, 108, -11, 2 }, - { 0, -1, 12, 123, -6, 0 } -}; - -static inline void vp8d_reg_write(struct rockchip_vpu_dev *vpu, - const struct vp8d_reg *reg, u32 val) -{ - u32 v; - - v = vdpu_read(vpu, reg->base); - v &= ~(reg->mask << reg->shift); - v |= ((val & reg->mask) << reg->shift); - vdpu_write_relaxed(vpu, v, reg->base); -} - -/* dump hw params for debug */ -#ifdef DEBUG -static void rk3288_vp8d_dump_hdr(struct rockchip_vpu_ctx *ctx) -{ - const struct v4l2_ctrl_vp8_frame_hdr *hdr = ctx->run.vp8d.frame_hdr; - int dct_total_len = 0; - int i; - - vpu_debug(4, "Frame tag: key_frame=0x%02x, version=0x%02x\n", - !hdr->key_frame, hdr->version); - - vpu_debug(4, "Picture size: w=%d, h=%d\n", hdr->width, hdr->height); - - /* stream addresses */ - vpu_debug(4, "Addresses: segmap=0x%x, probs=0x%x\n", - (int)ctx->hw.vp8d.segment_map.dma, - (int)ctx->hw.vp8d.prob_tbl.dma); - - /* reference frame info */ - vpu_debug(4, "Ref frame: last=%d, golden=%d, alt=%d\n", - hdr->last_frame, hdr->golden_frame, hdr->alt_frame); - - /* bool decoder info */ - vpu_debug(4, "Bool decoder: range=0x%x, value=0x%x, count=0x%x\n", - hdr->bool_dec_range, hdr->bool_dec_value, - hdr->bool_dec_count); - - /* control partition info */ - vpu_debug(4, "Control Part: offset=0x%x, size=0x%x\n", - hdr->first_part_offset, hdr->first_part_size); - vpu_debug(2, "Macroblock Data: bits_offset=0x%x\n", - hdr->macroblock_bit_offset); - - /* dct partition info */ - for (i = 0; i < hdr->num_dct_parts; i++) { - dct_total_len += hdr->dct_part_sizes[i]; - vpu_debug(4, "Dct Part%d Size: 0x%x\n", - i, hdr->dct_part_sizes[i]); - } - - dct_total_len += (hdr->num_dct_parts - 1) * 3; - vpu_debug(4, "Dct Part Total Length: 0x%x\n", dct_total_len); -} -#else -static inline void rk3288_vp8d_dump_hdr(struct rockchip_vpu_ctx *ctx) {} -#endif - -static void rk3288_vp8d_prob_update(struct rockchip_vpu_ctx *ctx) -{ - const struct v4l2_ctrl_vp8_frame_hdr *hdr = ctx->run.vp8d.frame_hdr; - const struct v4l2_vp8_entropy_hdr *entropy_hdr = &hdr->entropy_hdr; - u32 i, j, k; - u8 *dst; - - /* first probs */ - dst = ctx->hw.vp8d.prob_tbl.cpu; - - dst[0] = hdr->prob_skip_false; - dst[1] = hdr->prob_intra; - dst[2] = hdr->prob_last; - dst[3] = hdr->prob_gf; - dst[4] = hdr->sgmnt_hdr.segment_probs[0]; - dst[5] = hdr->sgmnt_hdr.segment_probs[1]; - dst[6] = hdr->sgmnt_hdr.segment_probs[2]; - dst[7] = 0; - - dst += 8; - dst[0] = entropy_hdr->y_mode_probs[0]; - dst[1] = entropy_hdr->y_mode_probs[1]; - dst[2] = entropy_hdr->y_mode_probs[2]; - dst[3] = entropy_hdr->y_mode_probs[3]; - dst[4] = entropy_hdr->uv_mode_probs[0]; - dst[5] = entropy_hdr->uv_mode_probs[1]; - dst[6] = entropy_hdr->uv_mode_probs[2]; - dst[7] = 0; /*unused */ - - /* mv probs */ - dst += 8; - dst[0] = entropy_hdr->mv_probs[0][0]; /* is short */ - dst[1] = entropy_hdr->mv_probs[1][0]; - dst[2] = entropy_hdr->mv_probs[0][1]; /* sign */ - dst[3] = entropy_hdr->mv_probs[1][1]; - dst[4] = entropy_hdr->mv_probs[0][8 + 9]; - dst[5] = entropy_hdr->mv_probs[0][9 + 9]; - dst[6] = entropy_hdr->mv_probs[1][8 + 9]; - dst[7] = entropy_hdr->mv_probs[1][9 + 9]; - dst += 8; - for (i = 0; i < 2; ++i) { - for (j = 0; j < 8; j += 4) { - dst[0] = entropy_hdr->mv_probs[i][j + 9 + 0]; - dst[1] = entropy_hdr->mv_probs[i][j + 9 + 1]; - dst[2] = entropy_hdr->mv_probs[i][j + 9 + 2]; - dst[3] = entropy_hdr->mv_probs[i][j + 9 + 3]; - dst += 4; - } - } - for (i = 0; i < 2; ++i) { - dst[0] = entropy_hdr->mv_probs[i][0 + 2]; - dst[1] = entropy_hdr->mv_probs[i][1 + 2]; - dst[2] = entropy_hdr->mv_probs[i][2 + 2]; - dst[3] = entropy_hdr->mv_probs[i][3 + 2]; - dst[4] = entropy_hdr->mv_probs[i][4 + 2]; - dst[5] = entropy_hdr->mv_probs[i][5 + 2]; - dst[6] = entropy_hdr->mv_probs[i][6 + 2]; - dst[7] = 0; /*unused */ - dst += 8; - } - - /* coeff probs (header part) */ - dst = ctx->hw.vp8d.prob_tbl.cpu; - dst += (8 * 7); - for (i = 0; i < 4; ++i) { - for (j = 0; j < 8; ++j) { - for (k = 0; k < 3; ++k) { - dst[0] = entropy_hdr->coeff_probs[i][j][k][0]; - dst[1] = entropy_hdr->coeff_probs[i][j][k][1]; - dst[2] = entropy_hdr->coeff_probs[i][j][k][2]; - dst[3] = entropy_hdr->coeff_probs[i][j][k][3]; - dst += 4; - } - } - } - - /* coeff probs (footer part) */ - dst = ctx->hw.vp8d.prob_tbl.cpu; - dst += (8 * 55); - for (i = 0; i < 4; ++i) { - for (j = 0; j < 8; ++j) { - for (k = 0; k < 3; ++k) { - dst[0] = entropy_hdr->coeff_probs[i][j][k][4]; - dst[1] = entropy_hdr->coeff_probs[i][j][k][5]; - dst[2] = entropy_hdr->coeff_probs[i][j][k][6]; - dst[3] = entropy_hdr->coeff_probs[i][j][k][7]; - dst[4] = entropy_hdr->coeff_probs[i][j][k][8]; - dst[5] = entropy_hdr->coeff_probs[i][j][k][9]; - dst[6] = entropy_hdr->coeff_probs[i][j][k][10]; - dst[7] = 0; /*unused */ - dst += 8; - } - } - } -} - -/* - * set loop filters - */ -static void rk3288_vp8d_cfg_lf(struct rockchip_vpu_ctx *ctx) -{ - const struct v4l2_ctrl_vp8_frame_hdr *hdr = ctx->run.vp8d.frame_hdr; - struct rockchip_vpu_dev *vpu = ctx->dev; - u32 reg; - int i; - - if (!(hdr->sgmnt_hdr.flags & V4L2_VP8_SEGMNT_HDR_FLAG_ENABLED)) { - vp8d_reg_write(vpu, &vp8d_lf_level[0], hdr->lf_hdr.level); - } else if (hdr->sgmnt_hdr.segment_feature_mode) { - /* absolute mode */ - for (i = 0; i < 4; i++) - vp8d_reg_write(vpu, &vp8d_lf_level[i], - hdr->sgmnt_hdr.lf_update[i]); - } else { - /* delta mode */ - for (i = 0; i < 4; i++) - vp8d_reg_write(vpu, &vp8d_lf_level[i], - clamp(hdr->lf_hdr.level - + hdr->sgmnt_hdr.lf_update[i], 0, 63)); - } - - reg = VDPU_REG_REF_PIC_FILT_SHARPNESS(hdr->lf_hdr.sharpness_level); - if (hdr->lf_hdr.type) - reg |= VDPU_REG_REF_PIC_FILT_TYPE_E; - vdpu_write_relaxed(vpu, reg, VDPU_REG_REF_PIC(0)); - - if (hdr->lf_hdr.flags & V4L2_VP8_LF_HDR_ADJ_ENABLE) { - for (i = 0; i < 4; i++) { - vp8d_reg_write(vpu, &vp8d_mb_adj[i], - hdr->lf_hdr.mb_mode_delta_magnitude[i]); - vp8d_reg_write(vpu, &vp8d_ref_adj[i], - hdr->lf_hdr.ref_frm_delta_magnitude[i]); - } - } -} - -/* - * set quantization parameters - */ -static void rk3288_vp8d_cfg_qp(struct rockchip_vpu_ctx *ctx) -{ - const struct v4l2_ctrl_vp8_frame_hdr *hdr = ctx->run.vp8d.frame_hdr; - struct rockchip_vpu_dev *vpu = ctx->dev; - int i; - - if (!(hdr->sgmnt_hdr.flags & V4L2_VP8_SEGMNT_HDR_FLAG_ENABLED)) { - vp8d_reg_write(vpu, &vp8d_quant[0], hdr->quant_hdr.y_ac_qi); - } else if (hdr->sgmnt_hdr.segment_feature_mode) { - /* absolute mode */ - for (i = 0; i < 4; i++) - vp8d_reg_write(vpu, &vp8d_quant[i], - hdr->sgmnt_hdr.quant_update[i]); - } else { - /* delta mode */ - for (i = 0; i < 4; i++) - vp8d_reg_write(vpu, &vp8d_quant[i], - clamp(hdr->quant_hdr.y_ac_qi - + hdr->sgmnt_hdr.quant_update[i], - 0, 127)); - } - - vp8d_reg_write(vpu, &vp8d_quant_delta[0], hdr->quant_hdr.y_dc_delta); - vp8d_reg_write(vpu, &vp8d_quant_delta[1], hdr->quant_hdr.y2_dc_delta); - vp8d_reg_write(vpu, &vp8d_quant_delta[2], hdr->quant_hdr.y2_ac_delta); - vp8d_reg_write(vpu, &vp8d_quant_delta[3], hdr->quant_hdr.uv_dc_delta); - vp8d_reg_write(vpu, &vp8d_quant_delta[4], hdr->quant_hdr.uv_ac_delta); -} - -/* - * set control partition and dct partition regs - * - * VP8 frame stream data layout: - * - * first_part_size parttion_sizes[0] - * ^ ^ - * src_dma | | - * ^ +--------+------+ +-----+-----+ - * | | control part | | | - * +--------+----------------+------------------+-----------+-----+-----------+ - * | tag 3B | extra 7B | hdr | mb_data | dct sz | dct part0 | ... | dct partn | - * +--------+-----------------------------------+-----------+-----+-----------+ - * | | | | | - * | v +----+---+ v - * | mb_start | src_dma_end - * v v - * first_part_offset dct size part - * (num_dct-1)*3B - * Note: - * 1. only key frame has extra 7 bytes - * 2. all offsets are base on src_dma - * 3. number of dct parts is 1, 2, 4 or 8 - * 4. the addresses set to vpu must be 64bits alignment - */ -static void rk3288_vp8d_cfg_parts(struct rockchip_vpu_ctx *ctx) -{ - const struct v4l2_ctrl_vp8_frame_hdr *hdr = ctx->run.vp8d.frame_hdr; - struct rockchip_vpu_dev *vpu = ctx->dev; - u32 dct_part_total_len = 0; - u32 dct_size_part_size = 0; - u32 dct_part_offset = 0; - u32 mb_offset_bytes = 0; - u32 mb_offset_bits = 0; - u32 mb_start_bits = 0; - struct vp8d_reg reg; - dma_addr_t src_dma; - u32 mb_size = 0; - u32 count = 0; - u32 i; - - src_dma = vb2_dma_contig_plane_dma_addr(&ctx->run.src->vb.vb2_buf, 0); - - /* - * Calculate control partition mb data info - * @macroblock_bit_offset: bits offset of mb data from first - * part start pos - * @mb_offset_bits: bits offset of mb data from src_dma - * base addr - * @mb_offset_byte: bytes offset of mb data from src_dma - * base addr - * @mb_start_bits: bits offset of mb data from mb data - * 64bits alignment addr - */ - mb_offset_bits = hdr->first_part_offset * 8 - + hdr->macroblock_bit_offset + 8; - mb_offset_bytes = mb_offset_bits / 8; - mb_start_bits = mb_offset_bits - - (mb_offset_bytes & (~DEC_8190_ALIGN_MASK)) * 8; - mb_size = hdr->first_part_size - - (mb_offset_bytes - hdr->first_part_offset) - + (mb_offset_bytes & DEC_8190_ALIGN_MASK); - - /* mb data aligned base addr */ - vdpu_write_relaxed(vpu, (mb_offset_bytes & (~DEC_8190_ALIGN_MASK)) - + src_dma, VDPU_REG_ADDR_REF(13)); - - /* mb data start bits */ - reg.base = VDPU_REG_DEC_CTRL2; - reg.mask = 0x3f; - reg.shift = 18; - vp8d_reg_write(vpu, ®, mb_start_bits); - - /* mb aligned data length */ - reg.base = VDPU_REG_DEC_CTRL6; - reg.mask = 0x3fffff; - reg.shift = 0; - vp8d_reg_write(vpu, ®, mb_size); - - /* - * Calculate dct partition info - * @dct_size_part_size: Containing sizes of dct part, every dct part - * has 3 bytes to store its size, except the last - * dct part - * @dct_part_offset: bytes offset of dct parts from src_dma base addr - * @dct_part_total_len: total size of all dct parts - */ - dct_size_part_size = (hdr->num_dct_parts - 1) * 3; - dct_part_offset = hdr->first_part_offset + hdr->first_part_size; - for (i = 0; i < hdr->num_dct_parts; i++) - dct_part_total_len += hdr->dct_part_sizes[i]; - dct_part_total_len += dct_size_part_size; - dct_part_total_len += (dct_part_offset & DEC_8190_ALIGN_MASK); - - /* number of dct partitions */ - reg.base = VDPU_REG_DEC_CTRL6; - reg.mask = 0xf; - reg.shift = 24; - vp8d_reg_write(vpu, ®, hdr->num_dct_parts - 1); - - /* dct partition length */ - vdpu_write_relaxed(vpu, - VDPU_REG_DEC_CTRL3_STREAM_LEN(dct_part_total_len), - VDPU_REG_DEC_CTRL3); - - /* dct partitions base address */ - for (i = 0; i < hdr->num_dct_parts; i++) { - u32 byte_offset = dct_part_offset + dct_size_part_size + count; - u32 base_addr = byte_offset + src_dma; - - vp8d_reg_write(vpu, &vp8d_dct_base[i], - base_addr & (~DEC_8190_ALIGN_MASK)); - - vp8d_reg_write(vpu, &vp8d_dct_start_bits[i], - (byte_offset & DEC_8190_ALIGN_MASK) * 8); - - count += hdr->dct_part_sizes[i]; - } -} - -/* - * prediction filter taps - * normal 6-tap filters - */ -static void rk3288_vp8d_cfg_tap(struct rockchip_vpu_ctx *ctx) -{ - const struct v4l2_ctrl_vp8_frame_hdr *hdr = ctx->run.vp8d.frame_hdr; - struct rockchip_vpu_dev *vpu = ctx->dev; - struct vp8d_reg reg; - u32 val = 0; - int i, j; - - reg.base = VDPU_REG_BD_REF_PIC(3); - reg.mask = 0xf; - - if ((hdr->version & 0x03) != 0) - return; /* Tap filter not used. */ - - - for (i = 0; i < 8; i++) { - val = (vp8d_mc_filter[i][0] << 2) | vp8d_mc_filter[i][5]; - - for (j = 0; j < 4; j++) - vp8d_reg_write(vpu, &vp8d_pred_bc_tap[i][j], - vp8d_mc_filter[i][j + 1]); - - switch (i) { - case 2: - reg.shift = 8; - break; - case 4: - reg.shift = 4; - break; - case 6: - reg.shift = 0; - break; - default: - continue; - } - - vp8d_reg_write(vpu, ®, val); - } -} - -/* set reference frame */ -static void rk3288_vp8d_cfg_ref(struct rockchip_vpu_ctx *ctx) -{ - u32 reg; - struct vb2_buffer *buf; - struct rockchip_vpu_dev *vpu = ctx->dev; - const struct v4l2_ctrl_vp8_frame_hdr *hdr = ctx->run.vp8d.frame_hdr; - - /* set last frame address */ - if (hdr->last_frame >= ctx->vq_dst.num_buffers) - buf = &ctx->run.dst->vb.vb2_buf; - else - buf = ctx->dst_bufs[hdr->last_frame]; - - if (!hdr->key_frame) - vdpu_write_relaxed(vpu, - vb2_dma_contig_plane_dma_addr(&ctx->run.dst->vb.vb2_buf, 0), - VDPU_REG_ADDR_REF(0)); - else - vdpu_write_relaxed(vpu, vb2_dma_contig_plane_dma_addr(buf, 0), - VDPU_REG_ADDR_REF(0)); - - /* set golden reference frame buffer address */ - if (hdr->golden_frame >= ctx->vq_dst.num_buffers) - buf = &ctx->run.dst->vb.vb2_buf; - else - buf = ctx->dst_bufs[hdr->golden_frame]; - - reg = vb2_dma_contig_plane_dma_addr(buf, 0); - if (hdr->sign_bias_golden) - reg |= VDPU_REG_ADDR_REF_TOPC_E; - vdpu_write_relaxed(vpu, reg, VDPU_REG_ADDR_REF(4)); - - /* set alternate reference frame buffer address */ - if (hdr->alt_frame >= ctx->vq_dst.num_buffers) - buf = &ctx->run.dst->vb.vb2_buf; - else - buf = ctx->dst_bufs[hdr->alt_frame]; - - reg = vb2_dma_contig_plane_dma_addr(buf, 0); - if (hdr->sign_bias_alternate) - reg |= VDPU_REG_ADDR_REF_TOPC_E; - vdpu_write_relaxed(vpu, reg, VDPU_REG_ADDR_REF(5)); -} - -static void rk3288_vp8d_cfg_buffers(struct rockchip_vpu_ctx *ctx) -{ - const struct v4l2_ctrl_vp8_frame_hdr *hdr = ctx->run.vp8d.frame_hdr; - struct rockchip_vpu_dev *vpu = ctx->dev; - u32 reg; - - /* set probability table buffer address */ - vdpu_write_relaxed(vpu, ctx->hw.vp8d.prob_tbl.dma, - VDPU_REG_ADDR_QTABLE); - - /* set segment map address */ - reg = 0; - reg = VDPU_REG_FWD_PIC1_SEGMENT_BASE(ctx->hw.vp8d.segment_map.dma); - if (hdr->sgmnt_hdr.flags & V4L2_VP8_SEGMNT_HDR_FLAG_ENABLED) { - reg |= VDPU_REG_FWD_PIC1_SEGMENT_E; - if (hdr->sgmnt_hdr.flags & V4L2_VP8_SEGMNT_HDR_FLAG_UPDATE_MAP) - reg |= VDPU_REG_FWD_PIC1_SEGMENT_UPD_E; - } - vdpu_write_relaxed(vpu, reg, VDPU_REG_FWD_PIC(0)); - - /* set output frame buffer address */ - vdpu_write_relaxed(vpu, - vb2_dma_contig_plane_dma_addr(&ctx->run.dst->vb.vb2_buf, 0), - VDPU_REG_ADDR_DST); -} - -int rk3288_vpu_vp8d_init(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - unsigned int mb_width, mb_height; - size_t segment_map_size; - int ret; - - /* segment map table size calculation */ - mb_width = MB_WIDTH(ctx->dst_fmt.width); - mb_height = MB_HEIGHT(ctx->dst_fmt.height); - segment_map_size = round_up(DIV_ROUND_UP(mb_width * mb_height, 4), 64); - - /* - * In context init the dma buffer for segment map must be allocated. - * And the data in segment map buffer must be set to all zero. - */ - ret = rockchip_vpu_aux_buf_alloc(vpu, &ctx->hw.vp8d.segment_map, - segment_map_size); - if (ret) { - vpu_err("allocate segment map mem failed\n"); - return ret; - } - memset(ctx->hw.vp8d.segment_map.cpu, 0, ctx->hw.vp8d.segment_map.size); - - /* - * Allocate probability table buffer, - * total 1208 bytes, 4K page is far enough. - */ - ret = rockchip_vpu_aux_buf_alloc(vpu, &ctx->hw.vp8d.prob_tbl, - sizeof(struct vp8_prob_tbl_packed)); - if (ret) { - vpu_err("allocate prob table mem failed\n"); - goto prob_table_failed; - } - - return 0; - -prob_table_failed: - rockchip_vpu_aux_buf_free(vpu, &ctx->hw.vp8d.segment_map); - - return ret; -} - -void rk3288_vpu_vp8d_exit(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - - rockchip_vpu_aux_buf_free(vpu, &ctx->hw.vp8d.segment_map); - rockchip_vpu_aux_buf_free(vpu, &ctx->hw.vp8d.prob_tbl); -} - -void rk3288_vpu_vp8d_run(struct rockchip_vpu_ctx *ctx) -{ - const struct v4l2_ctrl_vp8_frame_hdr *hdr = ctx->run.vp8d.frame_hdr; - struct rockchip_vpu_dev *vpu = ctx->dev; - size_t height = ctx->dst_fmt.height; - size_t width = ctx->dst_fmt.width; - u32 mb_width, mb_height; - u32 reg; - - rk3288_vp8d_dump_hdr(ctx); - - /* reset segment_map buffer in keyframe */ - if (!hdr->key_frame && ctx->hw.vp8d.segment_map.cpu) - memset(ctx->hw.vp8d.segment_map.cpu, 0, - ctx->hw.vp8d.segment_map.size); - - rk3288_vp8d_prob_update(ctx); - - rockchip_vpu_power_on(vpu); - - reg = VDPU_REG_CONFIG_DEC_TIMEOUT_E - | VDPU_REG_CONFIG_DEC_STRENDIAN_E - | VDPU_REG_CONFIG_DEC_INSWAP32_E - | VDPU_REG_CONFIG_DEC_STRSWAP32_E - | VDPU_REG_CONFIG_DEC_OUTSWAP32_E - | VDPU_REG_CONFIG_DEC_CLK_GATE_E - | VDPU_REG_CONFIG_DEC_IN_ENDIAN - | VDPU_REG_CONFIG_DEC_OUT_ENDIAN - | VDPU_REG_CONFIG_DEC_MAX_BURST(16); - vdpu_write_relaxed(vpu, reg, VDPU_REG_CONFIG); - - reg = VDPU_REG_DEC_CTRL0_DEC_MODE(10); - if (hdr->key_frame) - reg |= VDPU_REG_DEC_CTRL0_PIC_INTER_E; - if (!(hdr->flags & V4L2_VP8_FRAME_HDR_FLAG_MB_NO_SKIP_COEFF)) - reg |= VDPU_REG_DEC_CTRL0_SKIP_MODE; - if (hdr->lf_hdr.level == 0) - reg |= VDPU_REG_DEC_CTRL0_FILTERING_DIS; - vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_CTRL0); - - /* frame dimensions */ - mb_width = MB_WIDTH(width); - mb_height = MB_HEIGHT(height); - reg = VDPU_REG_DEC_CTRL1_PIC_MB_WIDTH(mb_width) - | VDPU_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(mb_height) - | VDPU_REG_DEC_CTRL1_PIC_MB_W_EXT(mb_width >> 9) - | VDPU_REG_DEC_CTRL1_PIC_MB_H_EXT(mb_height >> 8); - vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_CTRL1); - - /* bool decode info */ - reg = VDPU_REG_DEC_CTRL2_BOOLEAN_RANGE(hdr->bool_dec_range) - | VDPU_REG_DEC_CTRL2_BOOLEAN_VALUE(hdr->bool_dec_value); - vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_CTRL2); - - reg = 0; - if (hdr->version != 3) - reg |= VDPU_REG_DEC_CTRL4_VC1_HEIGHT_EXT; - if (hdr->version & 0x3) - reg |= VDPU_REG_DEC_CTRL4_BILIN_MC_E; - vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_CTRL4); - - rk3288_vp8d_cfg_lf(ctx); - rk3288_vp8d_cfg_qp(ctx); - rk3288_vp8d_cfg_parts(ctx); - rk3288_vp8d_cfg_tap(ctx); - rk3288_vp8d_cfg_ref(ctx); - rk3288_vp8d_cfg_buffers(ctx); - - schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000)); - - vdpu_write(vpu, VDPU_REG_INTERRUPT_DEC_E, VDPU_REG_INTERRUPT); -} diff --git a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_vp8e.c b/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_vp8e.c deleted file mode 100644 index 0fc0bf91424e..000000000000 --- a/drivers/media/platform/rockchip-vpu/rk3288_vpu_hw_vp8e.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Rockchip RK3288 VPU codec driver - * - * Copyright (C) 2014 Rockchip Electronics Co., Ltd. - * Alpha Lin - * Jeffy Chen - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "rockchip_vpu_common.h" - -#include -#include - -#include "rk3288_vpu_regs.h" -#include "rockchip_vpu_hw.h" - -/* Various parameters specific to VP8 encoder. */ -#define VP8_CABAC_CTX_OFFSET 192 -#define VP8_CABAC_CTX_SIZE ((55 + 96) << 3) - -/** - * struct rk3288_vpu_vp8e_ctrl_buf - hardware control buffer layout - * @ext_hdr_size: Ext header size in bytes (written by hardware). - * @dct_size: DCT partition size (written by hardware). - * @rsvd: Reserved for hardware. - */ -struct rk3288_vpu_vp8e_ctrl_buf { - u32 ext_hdr_size; - u32 dct_size; - u8 rsvd[1016]; -}; - -static inline unsigned int ref_luma_size(unsigned int w, unsigned int h) -{ - return round_up(w, MB_DIM) * round_up(h, MB_DIM); -} - -int rk3288_vpu_vp8e_init(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - size_t height = ctx->src_fmt.height; - size_t width = ctx->src_fmt.width; - size_t ref_buf_size; - size_t mv_size; - int ret; - - ret = rockchip_vpu_aux_buf_alloc(vpu, &ctx->hw.vp8e.ctrl_buf, - sizeof(struct rk3288_vpu_vp8e_ctrl_buf)); - if (ret) { - vpu_err("failed to allocate ctrl buffer\n"); - return ret; - } - - mv_size = DIV_ROUND_UP(width, 16) * DIV_ROUND_UP(height, 16) / 4; - ret = rockchip_vpu_aux_buf_alloc(vpu, &ctx->hw.vp8e.mv_buf, mv_size); - if (ret) { - vpu_err("failed to allocate MV buffer\n"); - goto err_ctrl_buf; - } - - ref_buf_size = ref_luma_size(width, height) * 3 / 2; - ret = rockchip_vpu_aux_buf_alloc(vpu, &ctx->hw.vp8e.ext_buf, - 2 * ref_buf_size); - if (ret) { - vpu_err("failed to allocate ext buffer\n"); - goto err_mv_buf; - } - - return 0; - -err_mv_buf: - rockchip_vpu_aux_buf_free(vpu, &ctx->hw.vp8e.mv_buf); -err_ctrl_buf: - rockchip_vpu_aux_buf_free(vpu, &ctx->hw.vp8e.ctrl_buf); - - return ret; -} - -void rk3288_vpu_vp8e_exit(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - - rockchip_vpu_aux_buf_free(vpu, &ctx->hw.vp8e.ext_buf); - rockchip_vpu_aux_buf_free(vpu, &ctx->hw.vp8e.mv_buf); - rockchip_vpu_aux_buf_free(vpu, &ctx->hw.vp8e.ctrl_buf); -} - -static inline u32 enc_in_img_ctrl(struct rockchip_vpu_ctx *ctx) -{ - struct v4l2_pix_format_mplane *pix_fmt = &ctx->src_fmt; - struct v4l2_rect *crop = &ctx->src_crop; - unsigned bytes_per_line, overfill_r, overfill_b; - - /* - * The hardware needs only the value for luma plane, because - * values of other planes are calculated internally based on - * format setting. - */ - bytes_per_line = pix_fmt->plane_fmt[0].bytesperline; - overfill_r = (pix_fmt->width - crop->width) / 4; - overfill_b = pix_fmt->height - crop->height; - - return VEPU_REG_IN_IMG_CTRL_ROW_LEN(bytes_per_line) - | VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(overfill_r) - | VEPU_REG_IN_IMG_CTRL_OVRFLB_D4(overfill_b) - | VEPU_REG_IN_IMG_CTRL_FMT(ctx->vpu_src_fmt->enc_fmt); -} - -static void rk3288_vpu_vp8e_set_buffers(struct rockchip_vpu_dev *vpu, - struct rockchip_vpu_ctx *ctx) -{ - struct vb2_v4l2_buffer *vb2_dst = to_vb2_v4l2_buffer(&ctx->run.dst->vb.vb2_buf); - const struct rk3288_vp8e_reg_params *params = - (struct rk3288_vp8e_reg_params *)ctx->run.vp8e.reg_params; - dma_addr_t ref_buf_dma, rec_buf_dma; - dma_addr_t stream_dma; - size_t rounded_size; - dma_addr_t dst_dma; - u32 start_offset; - size_t dst_size; - - rounded_size = ref_luma_size(ctx->src_fmt.width, - ctx->src_fmt.height); - - ref_buf_dma = rec_buf_dma = ctx->hw.vp8e.ext_buf.dma; - if (ctx->hw.vp8e.ref_rec_ptr) - ref_buf_dma += rounded_size * 3 / 2; - else - rec_buf_dma += rounded_size * 3 / 2; - ctx->hw.vp8e.ref_rec_ptr ^= 1; - - if (rockchip_vpu_ctx_is_dummy_encode(ctx)) { - dst_dma = vpu->dummy_encode_dst.dma; - dst_size = vpu->dummy_encode_dst.size; - } else { - dst_dma = vb2_dma_contig_plane_dma_addr(&ctx->run.dst->vb.vb2_buf, 0); - dst_size = vb2_plane_size(&ctx->run.dst->vb.vb2_buf, 0); - } - - /* - * stream addr-->| - * align 64bits->|<-start offset->| - * |<---------header size-------->|<---dst buf--- - */ - start_offset = (params->rlc_ctrl & VEPU_REG_RLC_CTRL_STR_OFFS_MASK) - >> VEPU_REG_RLC_CTRL_STR_OFFS_SHIFT; - stream_dma = dst_dma + params->hdr_len; - - /** - * Userspace will pass 8 bytes aligned size(round_down) to us, - * so we need to plus start offset to get real header size. - * - * |<-aligned size->|<-start offset->| - * |<----------header size---------->| - */ - ctx->run.dst->vp8e.hdr_size = params->hdr_len + (start_offset >> 3); - - if (params->enc_ctrl & VEPU_REG_ENC_CTRL_KEYFRAME_BIT) - vb2_dst->flags |= V4L2_BUF_FLAG_KEYFRAME; - else - vb2_dst->flags &= ~V4L2_BUF_FLAG_KEYFRAME; - - /* - * We assume here that 1/10 of the buffer is enough for headers. - * DCT partition will be placed in remaining 9/10 of the buffer. - */ - ctx->run.dst->vp8e.dct_offset = round_up(dst_size / 10, 8); - - /* Destination buffer. */ - vepu_write_relaxed(vpu, stream_dma, VEPU_REG_ADDR_OUTPUT_STREAM); - vepu_write_relaxed(vpu, dst_dma + ctx->run.dst->vp8e.dct_offset, - VEPU_REG_ADDR_VP8_DCT_PART(0)); - vepu_write_relaxed(vpu, dst_size - ctx->run.dst->vp8e.dct_offset, - VEPU_REG_STR_BUF_LIMIT); - - /* Auxilliary buffers. */ - vepu_write_relaxed(vpu, ctx->hw.vp8e.ctrl_buf.dma, - VEPU_REG_ADDR_OUTPUT_CTRL); - vepu_write_relaxed(vpu, ctx->hw.vp8e.mv_buf.dma, - VEPU_REG_ADDR_MV_OUT); - vepu_write_relaxed(vpu, ctx->run.priv_dst.dma, - VEPU_REG_ADDR_VP8_PROB_CNT); - vepu_write_relaxed(vpu, ctx->run.priv_src.dma + VP8_CABAC_CTX_OFFSET, - VEPU_REG_ADDR_CABAC_TBL); - vepu_write_relaxed(vpu, ctx->run.priv_src.dma - + VP8_CABAC_CTX_OFFSET + VP8_CABAC_CTX_SIZE, - VEPU_REG_ADDR_VP8_SEG_MAP); - - /* Reference buffers. */ - vepu_write_relaxed(vpu, ref_buf_dma, - VEPU_REG_ADDR_REF_LUMA); - vepu_write_relaxed(vpu, ref_buf_dma + rounded_size, - VEPU_REG_ADDR_REF_CHROMA); - - /* Reconstruction buffers. */ - vepu_write_relaxed(vpu, rec_buf_dma, - VEPU_REG_ADDR_REC_LUMA); - vepu_write_relaxed(vpu, rec_buf_dma + rounded_size, - VEPU_REG_ADDR_REC_CHROMA); - - /* Source buffer. */ - if (rockchip_vpu_ctx_is_dummy_encode(ctx)) { - vepu_write_relaxed(vpu, vpu->dummy_encode_src[PLANE_Y].dma, - VEPU_REG_ADDR_IN_LUMA); - vepu_write_relaxed(vpu, vpu->dummy_encode_src[PLANE_CB].dma, - VEPU_REG_ADDR_IN_CB); - vepu_write_relaxed(vpu, vpu->dummy_encode_src[PLANE_CR].dma, - VEPU_REG_ADDR_IN_CR); - } else { - vepu_write_relaxed(vpu, vb2_dma_contig_plane_dma_addr( - &ctx->run.src->vb.vb2_buf, PLANE_Y), - VEPU_REG_ADDR_IN_LUMA); - vepu_write_relaxed(vpu, vb2_dma_contig_plane_dma_addr( - &ctx->run.src->vb.vb2_buf, PLANE_CB), - VEPU_REG_ADDR_IN_CB); - vepu_write_relaxed(vpu, vb2_dma_contig_plane_dma_addr( - &ctx->run.src->vb.vb2_buf, PLANE_CR), - VEPU_REG_ADDR_IN_CR); - } - - /* Source parameters. */ - vepu_write_relaxed(vpu, enc_in_img_ctrl(ctx), VEPU_REG_IN_IMG_CTRL); -} - -static void rk3288_vpu_vp8e_set_params(struct rockchip_vpu_dev *vpu, - struct rockchip_vpu_ctx *ctx) -{ - const struct rk3288_vp8e_reg_params *params = - (struct rk3288_vp8e_reg_params *)ctx->run.vp8e.reg_params; - int i; - - vepu_write_relaxed(vpu, params->enc_ctrl0, VEPU_REG_ENC_CTRL0); - vepu_write_relaxed(vpu, params->enc_ctrl1, VEPU_REG_ENC_CTRL1); - vepu_write_relaxed(vpu, params->enc_ctrl2, VEPU_REG_ENC_CTRL2); - vepu_write_relaxed(vpu, params->enc_ctrl3, VEPU_REG_ENC_CTRL3); - vepu_write_relaxed(vpu, params->enc_ctrl5, VEPU_REG_ENC_CTRL5); - vepu_write_relaxed(vpu, params->enc_ctrl4, VEPU_REG_ENC_CTRL4); - vepu_write_relaxed(vpu, params->str_hdr_rem_msb, - VEPU_REG_STR_HDR_REM_MSB); - vepu_write_relaxed(vpu, params->str_hdr_rem_lsb, - VEPU_REG_STR_HDR_REM_LSB); - vepu_write_relaxed(vpu, params->mad_ctrl, VEPU_REG_MAD_CTRL); - - for (i = 0; i < ARRAY_SIZE(params->qp_val); ++i) - vepu_write_relaxed(vpu, params->qp_val[i], - VEPU_REG_VP8_QP_VAL(i)); - - vepu_write_relaxed(vpu, params->bool_enc, VEPU_REG_VP8_BOOL_ENC); - vepu_write_relaxed(vpu, params->vp8_ctrl0, VEPU_REG_VP8_CTRL0); - vepu_write_relaxed(vpu, params->rlc_ctrl, VEPU_REG_RLC_CTRL); - vepu_write_relaxed(vpu, params->mb_ctrl, VEPU_REG_MB_CTRL); - - for (i = 0; i < ARRAY_SIZE(params->rgb_yuv_coeff); ++i) - vepu_write_relaxed(vpu, params->rgb_yuv_coeff[i], - VEPU_REG_RGB_YUV_COEFF(i)); - - vepu_write_relaxed(vpu, params->rgb_mask_msb, - VEPU_REG_RGB_MASK_MSB); - vepu_write_relaxed(vpu, params->intra_area_ctrl, - VEPU_REG_INTRA_AREA_CTRL); - vepu_write_relaxed(vpu, params->cir_intra_ctrl, - VEPU_REG_CIR_INTRA_CTRL); - vepu_write_relaxed(vpu, params->first_roi_area, - VEPU_REG_FIRST_ROI_AREA); - vepu_write_relaxed(vpu, params->second_roi_area, - VEPU_REG_SECOND_ROI_AREA); - vepu_write_relaxed(vpu, params->mvc_ctrl, - VEPU_REG_MVC_CTRL); - - for (i = 0; i < ARRAY_SIZE(params->intra_penalty); ++i) - vepu_write_relaxed(vpu, params->intra_penalty[i], - VEPU_REG_VP8_INTRA_PENALTY(i)); - - for (i = 0; i < ARRAY_SIZE(params->seg_qp); ++i) - vepu_write_relaxed(vpu, params->seg_qp[i], - VEPU_REG_VP8_SEG_QP(i)); - - for (i = 0; i < ARRAY_SIZE(params->dmv_4p_1p_penalty); ++i) - vepu_write_relaxed(vpu, params->dmv_4p_1p_penalty[i], - VEPU_REG_DMV_4P_1P_PENALTY(i)); - - for (i = 0; i < ARRAY_SIZE(params->dmv_qpel_penalty); ++i) - vepu_write_relaxed(vpu, params->dmv_qpel_penalty[i], - VEPU_REG_DMV_QPEL_PENALTY(i)); - - vepu_write_relaxed(vpu, params->vp8_ctrl1, VEPU_REG_VP8_CTRL1); - vepu_write_relaxed(vpu, params->bit_cost_golden, - VEPU_REG_VP8_BIT_COST_GOLDEN); - - for (i = 0; i < ARRAY_SIZE(params->loop_flt_delta); ++i) - vepu_write_relaxed(vpu, params->loop_flt_delta[i], - VEPU_REG_VP8_LOOP_FLT_DELTA(i)); -} - -void rk3288_vpu_vp8e_run(struct rockchip_vpu_ctx *ctx) -{ - struct vb2_v4l2_buffer *vb2_dst = to_vb2_v4l2_buffer(&ctx->run.dst->vb.vb2_buf); - struct rockchip_vpu_dev *vpu = ctx->dev; - u32 reg; - - /* The hardware expects the control buffer to be zeroed. */ - memset(ctx->hw.vp8e.ctrl_buf.cpu, 0, - sizeof(struct rk3288_vpu_vp8e_ctrl_buf)); - - /* - * Program the hardware. - */ - rockchip_vpu_power_on(vpu); - - vepu_write_relaxed(vpu, VEPU_REG_ENC_CTRL_ENC_MODE_VP8, - VEPU_REG_ENC_CTRL); - - rk3288_vpu_vp8e_set_params(vpu, ctx); - rk3288_vpu_vp8e_set_buffers(vpu, ctx); - - /* Make sure that all registers are written at this point. */ - wmb(); - - /* Set the watchdog. */ - schedule_delayed_work(&vpu->watchdog_work, msecs_to_jiffies(2000)); - - /* Start the hardware. */ - reg = VEPU_REG_AXI_CTRL_OUTPUT_SWAP16 - | VEPU_REG_AXI_CTRL_INPUT_SWAP16 - | VEPU_REG_AXI_CTRL_BURST_LEN(16) - | VEPU_REG_AXI_CTRL_GATE_BIT - | VEPU_REG_AXI_CTRL_OUTPUT_SWAP32 - | VEPU_REG_AXI_CTRL_INPUT_SWAP32 - | VEPU_REG_AXI_CTRL_OUTPUT_SWAP8 - | VEPU_REG_AXI_CTRL_INPUT_SWAP8; - vepu_write(vpu, reg, VEPU_REG_AXI_CTRL); - - vepu_write(vpu, 0, VEPU_REG_INTERRUPT); - - reg = VEPU_REG_ENC_CTRL_NAL_MODE_BIT - | VEPU_REG_ENC_CTRL_WIDTH(MB_WIDTH(ctx->src_fmt.width)) - | VEPU_REG_ENC_CTRL_HEIGHT(MB_HEIGHT(ctx->src_fmt.height)) - | VEPU_REG_ENC_CTRL_ENC_MODE_VP8 - | VEPU_REG_ENC_CTRL_EN_BIT; - - if (vb2_dst->flags & V4L2_BUF_FLAG_KEYFRAME) - reg |= VEPU_REG_ENC_CTRL_KEYFRAME_BIT; - - vepu_write(vpu, reg, VEPU_REG_ENC_CTRL); -} - -void rk3288_vpu_vp8e_done(struct rockchip_vpu_ctx *ctx, - enum vb2_buffer_state result) -{ - struct rk3288_vpu_vp8e_ctrl_buf *ctrl_buf = ctx->hw.vp8e.ctrl_buf.cpu; - - /* Read length information of this run from utility buffer. */ - ctx->run.dst->vp8e.ext_hdr_size = ctrl_buf->ext_hdr_size; - ctx->run.dst->vp8e.dct_size = ctrl_buf->dct_size; - - rockchip_vpu_run_done(ctx, result); -} - -/* - * WAR for encoder state corruption after decoding - */ - -static const struct rockchip_reg_params dummy_encode_reg_params = { - .rk3288_vp8e = { - /* 00000014 */ .hdr_len = 0x00000000, - /* 00000038 */ .enc_ctrl = VEPU_REG_ENC_CTRL_KEYFRAME_BIT, - /* 00000040 */ .enc_ctrl0 = 0x00000000, - /* 00000044 */ .enc_ctrl1 = 0x00000000, - /* 00000048 */ .enc_ctrl2 = 0x00040014, - /* 0000004c */ .enc_ctrl3 = 0x404083c0, - /* 00000050 */ .enc_ctrl5 = 0x01006bff, - /* 00000054 */ .enc_ctrl4 = 0x00000039, - /* 00000058 */ .str_hdr_rem_msb = 0x85848805, - /* 0000005c */ .str_hdr_rem_lsb = 0x02000000, - /* 00000064 */ .mad_ctrl = 0x00000000, - /* 0000006c */ .qp_val = { - /* 0000006c */ 0x020213b1, - /* 00000070 */ 0x02825249, - /* 00000074 */ 0x048409d8, - /* 00000078 */ 0x03834c30, - /* 0000007c */ 0x020213b1, - /* 00000080 */ 0x02825249, - /* 00000084 */ 0x00340e0d, - /* 00000088 */ 0x401c1a15, - }, - /* 0000008c */ .bool_enc = 0x00018140, - /* 00000090 */ .vp8_ctrl0 = 0x000695c0, - /* 00000094 */ .rlc_ctrl = 0x14000000, - /* 00000098 */ .mb_ctrl = 0x00000000, - /* 000000d4 */ .rgb_yuv_coeff = { - /* 000000d4 */ 0x962b4c85, - /* 000000d8 */ 0x90901d50, - }, - /* 000000dc */ .rgb_mask_msb = 0x0000b694, - /* 000000e0 */ .intra_area_ctrl = 0xffffffff, - /* 000000e4 */ .cir_intra_ctrl = 0x00000000, - /* 000000f0 */ .first_roi_area = 0xffffffff, - /* 000000f4 */ .second_roi_area = 0xffffffff, - /* 000000f8 */ .mvc_ctrl = 0x01780000, - /* 00000100 */ .intra_penalty = { - /* 00000100 */ 0x00010005, - /* 00000104 */ 0x00015011, - /* 00000108 */ 0x0000c005, - /* 0000010c */ 0x00016010, - /* 00000110 */ 0x0001a018, - /* 00000114 */ 0x00018015, - /* 00000118 */ 0x0001d01a, - }, - /* 00000120 */ .seg_qp = { - /* 00000120 */ 0x020213b1, - /* 00000124 */ 0x02825249, - /* 00000128 */ 0x048409d8, - /* 0000012c */ 0x03834c30, - /* 00000130 */ 0x020213b1, - /* 00000134 */ 0x02825249, - /* 00000138 */ 0x00340e0d, - /* 0000013c */ 0x341c1a15, - /* 00000140 */ 0x020213b1, - /* 00000144 */ 0x02825249, - /* 00000148 */ 0x048409d8, - /* 0000014c */ 0x03834c30, - /* 00000150 */ 0x020213b1, - /* 00000154 */ 0x02825249, - /* 00000158 */ 0x00340e0d, - /* 0000015c */ 0x341c1a15, - /* 00000160 */ 0x020213b1, - /* 00000164 */ 0x02825249, - /* 00000168 */ 0x048409d8, - /* 0000016c */ 0x03834c30, - /* 00000170 */ 0x020213b1, - /* 00000174 */ 0x02825249, - /* 00000178 */ 0x00340e0d, - /* 0000017c */ 0x341c1a15, - }, - /* 00000180 */ .dmv_4p_1p_penalty = { - /* 00000180 */ 0x00020406, - /* 00000184 */ 0x080a0c0e, - /* 00000188 */ 0x10121416, - /* 0000018c */ 0x181a1c1e, - /* 00000190 */ 0x20222426, - /* 00000194 */ 0x282a2c2e, - /* 00000198 */ 0x30323436, - /* 0000019c */ 0x383a3c3e, - /* 000001a0 */ 0x40424446, - /* 000001a4 */ 0x484a4c4e, - /* 000001a8 */ 0x50525456, - /* 000001ac */ 0x585a5c5e, - /* 000001b0 */ 0x60626466, - /* 000001b4 */ 0x686a6c6e, - /* 000001b8 */ 0x70727476, - /* NOTE: Further 17 registers set to 0. */ - }, - /* - * NOTE: Following registers all set to 0: - * - dmv_qpel_penalty, - * - vp8_ctrl1, - * - bit_cost_golden, - * - loop_flt_delta. - */ - }, -}; - -const struct rockchip_reg_params *rk3288_vpu_vp8e_get_dummy_params(void) -{ - return &dummy_encode_reg_params; -} diff --git a/drivers/media/platform/rockchip-vpu/rk3288_vpu_regs.h b/drivers/media/platform/rockchip-vpu/rk3288_vpu_regs.h deleted file mode 100644 index 782bf78a55c5..000000000000 --- a/drivers/media/platform/rockchip-vpu/rk3288_vpu_regs.h +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Rockchip RK3288 VPU codec driver - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef RK3288_VPU_REGS_H_ -#define RK3288_VPU_REGS_H_ - -/* Encoder registers. */ -#define VEPU_REG_INTERRUPT 0x004 -#define VEPU_REG_INTERRUPT_DIS_BIT BIT(1) -#define VEPU_REG_INTERRUPT_BIT BIT(0) -#define VEPU_REG_AXI_CTRL 0x008 -#define VEPU_REG_AXI_CTRL_OUTPUT_SWAP16 BIT(15) -#define VEPU_REG_AXI_CTRL_INPUT_SWAP16 BIT(14) -#define VEPU_REG_AXI_CTRL_BURST_LEN(x) ((x) << 8) -#define VEPU_REG_AXI_CTRL_GATE_BIT BIT(4) -#define VEPU_REG_AXI_CTRL_OUTPUT_SWAP32 BIT(3) -#define VEPU_REG_AXI_CTRL_INPUT_SWAP32 BIT(2) -#define VEPU_REG_AXI_CTRL_OUTPUT_SWAP8 BIT(1) -#define VEPU_REG_AXI_CTRL_INPUT_SWAP8 BIT(0) -#define VEPU_REG_ADDR_OUTPUT_STREAM 0x014 -#define VEPU_REG_ADDR_OUTPUT_CTRL 0x018 -#define VEPU_REG_ADDR_REF_LUMA 0x01c -#define VEPU_REG_ADDR_REF_CHROMA 0x020 -#define VEPU_REG_ADDR_REC_LUMA 0x024 -#define VEPU_REG_ADDR_REC_CHROMA 0x028 -#define VEPU_REG_ADDR_IN_LUMA 0x02c -#define VEPU_REG_ADDR_IN_CB 0x030 -#define VEPU_REG_ADDR_IN_CR 0x034 -#define VEPU_REG_ENC_CTRL 0x038 -#define VEPU_REG_ENC_CTRL_TIMEOUT_EN BIT(31) -#define VEPU_REG_ENC_CTRL_NAL_MODE_BIT BIT(29) -#define VEPU_REG_ENC_CTRL_WIDTH(w) ((w) << 19) -#define VEPU_REG_ENC_CTRL_HEIGHT(h) ((h) << 10) -#define VEPU_REG_PIC_TYPE(x) (((x) & 0x3) << 3) -#define VEPU_REG_ENC_CTRL_KEYFRAME_BIT BIT(3) -#define VEPU_REG_ENC_CTRL_ENC_MODE_H264 (0x3 << 1) -#define VEPU_REG_ENC_CTRL_ENC_MODE_VP8 (0x1 << 1) -#define VEPU_REG_ENC_CTRL_EN_BIT BIT(0) -#define VEPU_REG_IN_IMG_CTRL 0x03c -#define VEPU_REG_IN_IMG_CTRL_ROW_LEN(x) ((x) << 12) -#define VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(x) ((x) << 10) -#define VEPU_REG_IN_IMG_CTRL_OVRFLB_D4(x) ((x) << 6) -#define VEPU_REG_IN_IMG_CTRL_FMT(x) ((x) << 2) -#define VEPU_REG_ENC_CTRL0 0x040 -#define VEPU_REG_ENC_CTRL0_INIT_QP(x) ((x) << 26) -#define VEPU_REG_ENC_CTRL0_SLICE_ALPHA(x) ((x) << 22) -#define VEPU_REG_ENC_CTRL0_SLICE_BETA(x) ((x) << 18) -#define VEPU_REG_ENC_CTRL0_CHROMA_QP_OFFSET(x) ((x) << 13) -#define VEPU_REG_ENC_CTRL0_FILTER_DIS(x) ((x) << 5) -#define VEPU_REG_ENC_CTRL0_IDR_PICID(x) ((x) << 1) -#define VEPU_REG_ENC_CTRL0_CONSTR_INTRA_PRED BIT(0) -#define VEPU_REG_ENC_CTRL1 0x044 -#define VEPU_REG_ENC_CTRL1_PPS_ID(x) ((x) << 24) -#define VEPU_REG_ENC_CTRL1_INTRA_PRED_MODE(x) ((x) << 16) -#define VEPU_REG_ENC_CTRL1_FRAME_NUM(x) ((x)) -#define VEPU_REG_ENC_CTRL2 0x048 -#define VEPU_REG_ENC_CTRL2_DEBLOCKING_FILETER_MODE(x) ((x) << 30) -#define VEPU_REG_ENC_CTRL2_H264_SLICE_SIZE(x) ((x) << 23) -#define VEPU_REG_ENC_CTRL2_DISABLE_QUARTER_PIXMV BIT(22) -#define VEPU_REG_ENC_CTRL2_TRANS8X8_MODE_EN BIT(21) -#define VEPU_REG_ENC_CTRL2_CABAC_INIT_IDC(x) ((x) << 19) -#define VEPU_REG_ENC_CTRL2_ENTROPY_CODING_MODE BIT(18) -#define VEPU_REG_ENC_CTRL2_H264_INTER4X4_MODE BIT(17) -#define VEPU_REG_ENC_CTRL2_H264_STREAM_MODE BIT(16) -#define VEPU_REG_ENC_CTRL2_INTRA16X16_MODE(x) ((x)) -#define VEPU_REG_ENC_CTRL3 0x04c -#define VEPU_REG_ENC_CTRL3_MUTIMV_EN BIT(30) -#define VEPU_REG_ENC_CTRL3_MV_PENALTY_1_4P(x) ((x) << 20) -#define VEPU_REG_ENC_CTRL3_MV_PENALTY_4P(x) ((x) << 10) -#define VEPU_REG_ENC_CTRL3_MV_PENALTY_1P(x) ((x)) -#define VEPU_REG_ENC_CTRL4 0x050 -#define VEPU_REG_ENC_CTRL4_MV_PENALTY_16X8_8X16(x) ((x) << 20) -#define VEPU_REG_ENC_CTRL4_MV_PENALTY_8X8(x) ((x) << 10) -#define VEPU_REG_ENC_CTRL4_8X4_4X8(x) ((x)) -#define VEPU_REG_ENC_CTRL5 0x054 -#define VEPU_REG_ENC_CTRL5_MACROBLOCK_PENALTY(x) ((x) << 24) -#define VEPU_REG_ENC_CTRL5_COMPLETE_SLICES(x) ((x) << 16) -#define VEPU_REG_ENC_CTRL5_INTER_MODE(x) ((x)) -#define VEPU_REG_STR_HDR_REM_MSB 0x058 -#define VEPU_REG_STR_HDR_REM_LSB 0x05c -#define VEPU_REG_STR_BUF_LIMIT 0x060 -#define VEPU_REG_MAD_CTRL 0x064 -#define VEPU_REG_MAD_CTRL_QP_ADJUST(x) ((x) << 28) -#define VEPU_REG_MAD_CTRL_MAD_THREDHOLD(x) ((x) << 22) -#define VEPU_REG_MAD_CTRL_QP_SUM_DIV2(x) ((x)) -#define VEPU_REG_ADDR_VP8_PROB_CNT 0x068 -#define VEPU_REG_QP_VAL 0x06c -#define VEPU_REG_QP_VAL_LUM(x) ((x) << 26) -#define VEPU_REG_QP_VAL_MAX(x) ((x) << 20) -#define VEPU_REG_QP_VAL_MIN(x) ((x) << 14) -#define VEPU_REG_QP_VAL_CHECKPOINT_DISTAN(x) ((x)) -#define VEPU_REG_VP8_QP_VAL(i) (0x06c + ((i) * 0x4)) -#define VEPU_REG_CHECKPOINT(i) (0x070 + ((i) * 0x4)) -#define VEPU_REG_CHECKPOINT_CHECK0(x) (((x) & 0xffff)) -#define VEPU_REG_CHECKPOINT_CHECK1(x) (((x) & 0xffff) << 16) -#define VEPU_REG_CHECKPOINT_RESULT(x) ((((x) >> (16 - 16 \ - * (i & 1))) & 0xffff) \ - * 32) -#define VEPU_REG_CHKPT_WORD_ERR(i) (0x084 + ((i) * 0x4)) -#define VEPU_REG_CHKPT_WORD_ERR_CHK0(x) (((x) & 0xffff)) -#define VEPU_REG_CHKPT_WORD_ERR_CHK1(x) (((x) & 0xffff) << 16) -#define VEPU_REG_VP8_BOOL_ENC 0x08c -#define VEPU_REG_CHKPT_DELTA_QP 0x090 -#define VEPU_REG_CHKPT_DELTA_QP_CHK0(x) (((x) & 0x0f) << 0) -#define VEPU_REG_CHKPT_DELTA_QP_CHK1(x) (((x) & 0x0f) << 4) -#define VEPU_REG_CHKPT_DELTA_QP_CHK2(x) (((x) & 0x0f) << 8) -#define VEPU_REG_CHKPT_DELTA_QP_CHK3(x) (((x) & 0x0f) << 12) -#define VEPU_REG_CHKPT_DELTA_QP_CHK4(x) (((x) & 0x0f) << 16) -#define VEPU_REG_CHKPT_DELTA_QP_CHK5(x) (((x) & 0x0f) << 20) -#define VEPU_REG_CHKPT_DELTA_QP_CHK6(x) (((x) & 0x0f) << 24) -#define VEPU_REG_VP8_CTRL0 0x090 -#define VEPU_REG_RLC_CTRL 0x094 -#define VEPU_REG_RLC_CTRL_STR_OFFS_SHIFT 23 -#define VEPU_REG_RLC_CTRL_STR_OFFS_MASK (0x3f << 23) -#define VEPU_REG_RLC_CTRL_RLC_SUM(x) ((x)) -#define VEPU_REG_MB_CTRL 0x098 -#define VEPU_REG_MB_CNT_OUT(x) (((x) & 0xffff)) -#define VEPU_REG_MB_CNT_SET(x) (((x) & 0xffff) << 16) -#define VEPU_REG_ADDR_NEXT_PIC 0x09c -#define VEPU_REG_STABLILIZATION_OUTPUT 0x0A0 -#define VEPU_REG_ADDR_CABAC_TBL 0x0cc -#define VEPU_REG_ADDR_MV_OUT 0x0d0 -#define VEPU_REG_RGB_YUV_COEFF(i) (0x0d4 + ((i) * 0x4)) -#define VEPU_REG_RGB_MASK_MSB 0x0dc -#define VEPU_REG_INTRA_AREA_CTRL 0x0e0 -#define VEPU_REG_CIR_INTRA_CTRL 0x0e4 -#define VEPU_REG_INTRA_SLICE_BITMAP(i) (0x0e8 + ((i) * 0x4)) -#define VEPU_REG_ADDR_VP8_DCT_PART(i) (0x0e8 + ((i) * 0x4)) -#define VEPU_REG_FIRST_ROI_AREA 0x0f0 -#define VEPU_REG_SECOND_ROI_AREA 0x0f4 -#define VEPU_REG_MVC_CTRL 0x0f8 -#define VEPU_REG_MVC_CTRL_MV16X16_FAVOR(x) ((x) << 28) -#define VEPU_REG_VP8_INTRA_PENALTY(i) (0x100 + ((i) * 0x4)) -#define VEPU_REG_ADDR_VP8_SEG_MAP 0x11c -#define VEPU_REG_VP8_SEG_QP(i) (0x120 + ((i) * 0x4)) -#define VEPU_REG_DMV_4P_1P_PENALTY(i) (0x180 + ((i) * 0x4)) -#define VEPU_REG_DMV_4P_1P_PENALTY_BIT(x, i) (x << i * 8) -#define VEPU_REG_DMV_QPEL_PENALTY(i) (0x200 + ((i) * 0x4)) -#define VEPU_REG_DMV_QPEL_PENALTY_BIT(x, i) (x << i * 8) -#define VEPU_REG_VP8_CTRL1 0x280 -#define VEPU_REG_VP8_BIT_COST_GOLDEN 0x284 -#define VEPU_REG_VP8_LOOP_FLT_DELTA(i) (0x288 + ((i) * 0x4)) - -/* Decoder registers. */ -#define VDPU_REG_INTERRUPT 0x004 -#define VDPU_REG_INTERRUPT_DEC_PIC_INF BIT(24) -#define VDPU_REG_INTERRUPT_DEC_TIMEOUT BIT(18) -#define VDPU_REG_INTERRUPT_DEC_SLICE_INT BIT(17) -#define VDPU_REG_INTERRUPT_DEC_ERROR_INT BIT(16) -#define VDPU_REG_INTERRUPT_DEC_ASO_INT BIT(15) -#define VDPU_REG_INTERRUPT_DEC_BUFFER_INT BIT(14) -#define VDPU_REG_INTERRUPT_DEC_BUS_INT BIT(13) -#define VDPU_REG_INTERRUPT_DEC_RDY_INT BIT(12) -#define VDPU_REG_INTERRUPT_DEC_IRQ BIT(8) -#define VDPU_REG_INTERRUPT_DEC_IRQ_DIS BIT(4) -#define VDPU_REG_INTERRUPT_DEC_E BIT(0) -#define VDPU_REG_CONFIG 0x008 -#define VDPU_REG_CONFIG_DEC_AXI_RD_ID(x) (((x) & 0xff) << 24) -#define VDPU_REG_CONFIG_DEC_TIMEOUT_E BIT(23) -#define VDPU_REG_CONFIG_DEC_STRSWAP32_E BIT(22) -#define VDPU_REG_CONFIG_DEC_STRENDIAN_E BIT(21) -#define VDPU_REG_CONFIG_DEC_INSWAP32_E BIT(20) -#define VDPU_REG_CONFIG_DEC_OUTSWAP32_E BIT(19) -#define VDPU_REG_CONFIG_DEC_DATA_DISC_E BIT(18) -#define VDPU_REG_CONFIG_TILED_MODE_MSB BIT(17) -#define VDPU_REG_CONFIG_DEC_OUT_TILED_E BIT(17) -#define VDPU_REG_CONFIG_DEC_LATENCY(x) (((x) & 0x3f) << 11) -#define VDPU_REG_CONFIG_DEC_CLK_GATE_E BIT(10) -#define VDPU_REG_CONFIG_DEC_IN_ENDIAN BIT(9) -#define VDPU_REG_CONFIG_DEC_OUT_ENDIAN BIT(8) -#define VDPU_REG_CONFIG_PRIORITY_MODE(x) (((x) & 0x7) << 5) -#define VDPU_REG_CONFIG_TILED_MODE_LSB BIT(7) -#define VDPU_REG_CONFIG_DEC_ADV_PRE_DIS BIT(6) -#define VDPU_REG_CONFIG_DEC_SCMD_DIS BIT(5) -#define VDPU_REG_CONFIG_DEC_MAX_BURST(x) (((x) & 0x1f) << 0) -#define VDPU_REG_DEC_CTRL0 0x00c -#define VDPU_REG_DEC_CTRL0_DEC_MODE(x) (((x) & 0xf) << 28) -#define VDPU_REG_DEC_CTRL0_RLC_MODE_E BIT(27) -#define VDPU_REG_DEC_CTRL0_SKIP_MODE BIT(26) -#define VDPU_REG_DEC_CTRL0_DIVX3_E BIT(25) -#define VDPU_REG_DEC_CTRL0_PJPEG_E BIT(24) -#define VDPU_REG_DEC_CTRL0_PIC_INTERLACE_E BIT(23) -#define VDPU_REG_DEC_CTRL0_PIC_FIELDMODE_E BIT(22) -#define VDPU_REG_DEC_CTRL0_PIC_B_E BIT(21) -#define VDPU_REG_DEC_CTRL0_PIC_INTER_E BIT(20) -#define VDPU_REG_DEC_CTRL0_PIC_TOPFIELD_E BIT(19) -#define VDPU_REG_DEC_CTRL0_FWD_INTERLACE_E BIT(18) -#define VDPU_REG_DEC_CTRL0_SORENSON_E BIT(17) -#define VDPU_REG_DEC_CTRL0_REF_TOPFIELD_E BIT(16) -#define VDPU_REG_DEC_CTRL0_DEC_OUT_DIS BIT(15) -#define VDPU_REG_DEC_CTRL0_FILTERING_DIS BIT(14) -#define VDPU_REG_DEC_CTRL0_WEBP_E BIT(13) -#define VDPU_REG_DEC_CTRL0_MVC_E BIT(13) -#define VDPU_REG_DEC_CTRL0_PIC_FIXED_QUANT BIT(13) -#define VDPU_REG_DEC_CTRL0_WRITE_MVS_E BIT(12) -#define VDPU_REG_DEC_CTRL0_REFTOPFIRST_E BIT(11) -#define VDPU_REG_DEC_CTRL0_SEQ_MBAFF_E BIT(10) -#define VDPU_REG_DEC_CTRL0_PICORD_COUNT_E BIT(9) -#define VDPU_REG_DEC_CTRL0_DEC_AHB_HLOCK_E BIT(8) -#define VDPU_REG_DEC_CTRL0_DEC_AXI_WR_ID(x) (((x) & 0xff) << 0) -#define VDPU_REG_DEC_CTRL1 0x010 -#define VDPU_REG_DEC_CTRL1_PIC_MB_WIDTH(x) (((x) & 0x1ff) << 23) -#define VDPU_REG_DEC_CTRL1_MB_WIDTH_OFF(x) (((x) & 0xf) << 19) -#define VDPU_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(x) (((x) & 0xff) << 11) -#define VDPU_REG_DEC_CTRL1_MB_HEIGHT_OFF(x) (((x) & 0xf) << 7) -#define VDPU_REG_DEC_CTRL1_ALT_SCAN_E BIT(6) -#define VDPU_REG_DEC_CTRL1_TOPFIELDFIRST_E BIT(5) -#define VDPU_REG_DEC_CTRL1_REF_FRAMES(x) (((x) & 0x1f) << 0) -#define VDPU_REG_DEC_CTRL1_PIC_MB_W_EXT(x) (((x) & 0x7) << 3) -#define VDPU_REG_DEC_CTRL1_PIC_MB_H_EXT(x) (((x) & 0x7) << 0) -#define VDPU_REG_DEC_CTRL1_PIC_REFER_FLAG BIT(0) -#define VDPU_REG_DEC_CTRL2 0x014 -#define VDPU_REG_DEC_CTRL2_STRM_START_BIT(x) (((x) & 0x3f) << 26) -#define VDPU_REG_DEC_CTRL2_SYNC_MARKER_E BIT(25) -#define VDPU_REG_DEC_CTRL2_TYPE1_QUANT_E BIT(24) -#define VDPU_REG_DEC_CTRL2_CH_QP_OFFSET(x) (((x) & 0x1f) << 19) -#define VDPU_REG_DEC_CTRL2_CH_QP_OFFSET2(x) (((x) & 0x1f) << 14) -#define VDPU_REG_DEC_CTRL2_FIELDPIC_FLAG_E BIT(0) -#define VDPU_REG_DEC_CTRL2_INTRADC_VLC_THR(x) (((x) & 0x7) << 16) -#define VDPU_REG_DEC_CTRL2_VOP_TIME_INCR(x) (((x) & 0xffff) << 0) -#define VDPU_REG_DEC_CTRL2_DQ_PROFILE BIT(24) -#define VDPU_REG_DEC_CTRL2_DQBI_LEVEL BIT(23) -#define VDPU_REG_DEC_CTRL2_RANGE_RED_FRM_E BIT(22) -#define VDPU_REG_DEC_CTRL2_FAST_UVMC_E BIT(20) -#define VDPU_REG_DEC_CTRL2_TRANSDCTAB BIT(17) -#define VDPU_REG_DEC_CTRL2_TRANSACFRM(x) (((x) & 0x3) << 15) -#define VDPU_REG_DEC_CTRL2_TRANSACFRM2(x) (((x) & 0x3) << 13) -#define VDPU_REG_DEC_CTRL2_MB_MODE_TAB(x) (((x) & 0x7) << 10) -#define VDPU_REG_DEC_CTRL2_MVTAB(x) (((x) & 0x7) << 7) -#define VDPU_REG_DEC_CTRL2_CBPTAB(x) (((x) & 0x7) << 4) -#define VDPU_REG_DEC_CTRL2_2MV_BLK_PAT_TAB(x) (((x) & 0x3) << 2) -#define VDPU_REG_DEC_CTRL2_4MV_BLK_PAT_TAB(x) (((x) & 0x3) << 0) -#define VDPU_REG_DEC_CTRL2_QSCALE_TYPE BIT(24) -#define VDPU_REG_DEC_CTRL2_CON_MV_E BIT(4) -#define VDPU_REG_DEC_CTRL2_INTRA_DC_PREC(x) (((x) & 0x3) << 2) -#define VDPU_REG_DEC_CTRL2_INTRA_VLC_TAB BIT(1) -#define VDPU_REG_DEC_CTRL2_FRAME_PRED_DCT BIT(0) -#define VDPU_REG_DEC_CTRL2_JPEG_QTABLES(x) (((x) & 0x3) << 11) -#define VDPU_REG_DEC_CTRL2_JPEG_MODE(x) (((x) & 0x7) << 8) -#define VDPU_REG_DEC_CTRL2_JPEG_FILRIGHT_E BIT(7) -#define VDPU_REG_DEC_CTRL2_JPEG_STREAM_ALL BIT(6) -#define VDPU_REG_DEC_CTRL2_CR_AC_VLCTABLE BIT(5) -#define VDPU_REG_DEC_CTRL2_CB_AC_VLCTABLE BIT(4) -#define VDPU_REG_DEC_CTRL2_CR_DC_VLCTABLE BIT(3) -#define VDPU_REG_DEC_CTRL2_CB_DC_VLCTABLE BIT(2) -#define VDPU_REG_DEC_CTRL2_CR_DC_VLCTABLE3 BIT(1) -#define VDPU_REG_DEC_CTRL2_CB_DC_VLCTABLE3 BIT(0) -#define VDPU_REG_DEC_CTRL2_STRM1_START_BIT(x) (((x) & 0x3f) << 18) -#define VDPU_REG_DEC_CTRL2_HUFFMAN_E BIT(17) -#define VDPU_REG_DEC_CTRL2_MULTISTREAM_E BIT(16) -#define VDPU_REG_DEC_CTRL2_BOOLEAN_VALUE(x) (((x) & 0xff) << 8) -#define VDPU_REG_DEC_CTRL2_BOOLEAN_RANGE(x) (((x) & 0xff) << 0) -#define VDPU_REG_DEC_CTRL2_ALPHA_OFFSET(x) (((x) & 0x1f) << 5) -#define VDPU_REG_DEC_CTRL2_BETA_OFFSET(x) (((x) & 0x1f) << 0) -#define VDPU_REG_DEC_CTRL3 0x018 -#define VDPU_REG_DEC_CTRL3_START_CODE_E BIT(31) -#define VDPU_REG_DEC_CTRL3_INIT_QP(x) (((x) & 0x3f) << 25) -#define VDPU_REG_DEC_CTRL3_CH_8PIX_ILEAV_E BIT(24) -#define VDPU_REG_DEC_CTRL3_STREAM_LEN_EXT(x) (((x) & 0xff) << 24) -#define VDPU_REG_DEC_CTRL3_STREAM_LEN(x) (((x) & 0xffffff) << 0) -#define VDPU_REG_DEC_CTRL4 0x01c -#define VDPU_REG_DEC_CTRL4_CABAC_E BIT(31) -#define VDPU_REG_DEC_CTRL4_BLACKWHITE_E BIT(30) -#define VDPU_REG_DEC_CTRL4_DIR_8X8_INFER_E BIT(29) -#define VDPU_REG_DEC_CTRL4_WEIGHT_PRED_E BIT(28) -#define VDPU_REG_DEC_CTRL4_WEIGHT_BIPR_IDC(x) (((x) & 0x3) << 26) -#define VDPU_REG_DEC_CTRL4_AVS_H264_H_EXT BIT(25) -#define VDPU_REG_DEC_CTRL4_FRAMENUM_LEN(x) (((x) & 0x1f) << 16) -#define VDPU_REG_DEC_CTRL4_FRAMENUM(x) (((x) & 0xffff) << 0) -#define VDPU_REG_DEC_CTRL4_BITPLANE0_E BIT(31) -#define VDPU_REG_DEC_CTRL4_BITPLANE1_E BIT(30) -#define VDPU_REG_DEC_CTRL4_BITPLANE2_E BIT(29) -#define VDPU_REG_DEC_CTRL4_ALT_PQUANT(x) (((x) & 0x1f) << 24) -#define VDPU_REG_DEC_CTRL4_DQ_EDGES(x) (((x) & 0xf) << 20) -#define VDPU_REG_DEC_CTRL4_TTMBF BIT(19) -#define VDPU_REG_DEC_CTRL4_PQINDEX(x) (((x) & 0x1f) << 14) -#define VDPU_REG_DEC_CTRL4_VC1_HEIGHT_EXT BIT(13) -#define VDPU_REG_DEC_CTRL4_BILIN_MC_E BIT(12) -#define VDPU_REG_DEC_CTRL4_UNIQP_E BIT(11) -#define VDPU_REG_DEC_CTRL4_HALFQP_E BIT(10) -#define VDPU_REG_DEC_CTRL4_TTFRM(x) (((x) & 0x3) << 8) -#define VDPU_REG_DEC_CTRL4_2ND_BYTE_EMUL_E BIT(7) -#define VDPU_REG_DEC_CTRL4_DQUANT_E BIT(6) -#define VDPU_REG_DEC_CTRL4_VC1_ADV_E BIT(5) -#define VDPU_REG_DEC_CTRL4_PJPEG_FILDOWN_E BIT(26) -#define VDPU_REG_DEC_CTRL4_PJPEG_WDIV8 BIT(25) -#define VDPU_REG_DEC_CTRL4_PJPEG_HDIV8 BIT(24) -#define VDPU_REG_DEC_CTRL4_PJPEG_AH(x) (((x) & 0xf) << 20) -#define VDPU_REG_DEC_CTRL4_PJPEG_AL(x) (((x) & 0xf) << 16) -#define VDPU_REG_DEC_CTRL4_PJPEG_SS(x) (((x) & 0xff) << 8) -#define VDPU_REG_DEC_CTRL4_PJPEG_SE(x) (((x) & 0xff) << 0) -#define VDPU_REG_DEC_CTRL4_DCT1_START_BIT(x) (((x) & 0x3f) << 26) -#define VDPU_REG_DEC_CTRL4_DCT2_START_BIT(x) (((x) & 0x3f) << 20) -#define VDPU_REG_DEC_CTRL4_CH_MV_RES BIT(13) -#define VDPU_REG_DEC_CTRL4_INIT_DC_MATCH0(x) (((x) & 0x7) << 9) -#define VDPU_REG_DEC_CTRL4_INIT_DC_MATCH1(x) (((x) & 0x7) << 6) -#define VDPU_REG_DEC_CTRL4_VP7_VERSION BIT(5) -#define VDPU_REG_DEC_CTRL5 0x020 -#define VDPU_REG_DEC_CTRL5_CONST_INTRA_E BIT(31) -#define VDPU_REG_DEC_CTRL5_FILT_CTRL_PRES BIT(30) -#define VDPU_REG_DEC_CTRL5_RDPIC_CNT_PRES BIT(29) -#define VDPU_REG_DEC_CTRL5_8X8TRANS_FLAG_E BIT(28) -#define VDPU_REG_DEC_CTRL5_REFPIC_MK_LEN(x) (((x) & 0x7ff) << 17) -#define VDPU_REG_DEC_CTRL5_IDR_PIC_E BIT(16) -#define VDPU_REG_DEC_CTRL5_IDR_PIC_ID(x) (((x) & 0xffff) << 0) -#define VDPU_REG_DEC_CTRL5_MV_SCALEFACTOR(x) (((x) & 0xff) << 24) -#define VDPU_REG_DEC_CTRL5_REF_DIST_FWD(x) (((x) & 0x1f) << 19) -#define VDPU_REG_DEC_CTRL5_REF_DIST_BWD(x) (((x) & 0x1f) << 14) -#define VDPU_REG_DEC_CTRL5_LOOP_FILT_LIMIT(x) (((x) & 0xf) << 14) -#define VDPU_REG_DEC_CTRL5_VARIANCE_TEST_E BIT(13) -#define VDPU_REG_DEC_CTRL5_MV_THRESHOLD(x) (((x) & 0x7) << 10) -#define VDPU_REG_DEC_CTRL5_VAR_THRESHOLD(x) (((x) & 0x3ff) << 0) -#define VDPU_REG_DEC_CTRL5_DIVX_IDCT_E BIT(8) -#define VDPU_REG_DEC_CTRL5_DIVX3_SLICE_SIZE(x) (((x) & 0xff) << 0) -#define VDPU_REG_DEC_CTRL5_PJPEG_REST_FREQ(x) (((x) & 0xffff) << 0) -#define VDPU_REG_DEC_CTRL5_RV_PROFILE(x) (((x) & 0x3) << 30) -#define VDPU_REG_DEC_CTRL5_RV_OSV_QUANT(x) (((x) & 0x3) << 28) -#define VDPU_REG_DEC_CTRL5_RV_FWD_SCALE(x) (((x) & 0x3fff) << 14) -#define VDPU_REG_DEC_CTRL5_RV_BWD_SCALE(x) (((x) & 0x3fff) << 0) -#define VDPU_REG_DEC_CTRL5_INIT_DC_COMP0(x) (((x) & 0xffff) << 16) -#define VDPU_REG_DEC_CTRL5_INIT_DC_COMP1(x) (((x) & 0xffff) << 0) -#define VDPU_REG_DEC_CTRL6 0x024 -#define VDPU_REG_DEC_CTRL6_PPS_ID(x) (((x) & 0xff) << 24) -#define VDPU_REG_DEC_CTRL6_REFIDX1_ACTIVE(x) (((x) & 0x1f) << 19) -#define VDPU_REG_DEC_CTRL6_REFIDX0_ACTIVE(x) (((x) & 0x1f) << 14) -#define VDPU_REG_DEC_CTRL6_POC_LENGTH(x) (((x) & 0xff) << 0) -#define VDPU_REG_DEC_CTRL6_ICOMP0_E BIT(24) -#define VDPU_REG_DEC_CTRL6_ISCALE0(x) (((x) & 0xff) << 16) -#define VDPU_REG_DEC_CTRL6_ISHIFT0(x) (((x) & 0xffff) << 0) -#define VDPU_REG_DEC_CTRL6_STREAM1_LEN(x) (((x) & 0xffffff) << 0) -#define VDPU_REG_DEC_CTRL6_PIC_SLICE_AM(x) (((x) & 0x1fff) << 0) -#define VDPU_REG_DEC_CTRL6_COEFFS_PART_AM(x) (((x) & 0xf) << 24) -#define VDPU_REG_FWD_PIC(i) (0x028 + ((i) * 0x4)) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F5(x) (((x) & 0x1f) << 25) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F4(x) (((x) & 0x1f) << 20) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F3(x) (((x) & 0x1f) << 15) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F2(x) (((x) & 0x1f) << 10) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F1(x) (((x) & 0x1f) << 5) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F0(x) (((x) & 0x1f) << 0) -#define VDPU_REG_FWD_PIC1_ICOMP1_E BIT(24) -#define VDPU_REG_FWD_PIC1_ISCALE1(x) (((x) & 0xff) << 16) -#define VDPU_REG_FWD_PIC1_ISHIFT1(x) (((x) & 0xffff) << 0) -#define VDPU_REG_FWD_PIC1_SEGMENT_BASE(x) ((x) << 0) -#define VDPU_REG_FWD_PIC1_SEGMENT_UPD_E BIT(1) -#define VDPU_REG_FWD_PIC1_SEGMENT_E BIT(0) -#define VDPU_REG_DEC_CTRL7 0x02c -#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F15(x) (((x) & 0x1f) << 25) -#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F14(x) (((x) & 0x1f) << 20) -#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F13(x) (((x) & 0x1f) << 15) -#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F12(x) (((x) & 0x1f) << 10) -#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F11(x) (((x) & 0x1f) << 5) -#define VDPU_REG_DEC_CTRL7_PINIT_RLIST_F10(x) (((x) & 0x1f) << 0) -#define VDPU_REG_DEC_CTRL7_ICOMP2_E BIT(24) -#define VDPU_REG_DEC_CTRL7_ISCALE2(x) (((x) & 0xff) << 16) -#define VDPU_REG_DEC_CTRL7_ISHIFT2(x) (((x) & 0xffff) << 0) -#define VDPU_REG_DEC_CTRL7_DCT3_START_BIT(x) (((x) & 0x3f) << 24) -#define VDPU_REG_DEC_CTRL7_DCT4_START_BIT(x) (((x) & 0x3f) << 18) -#define VDPU_REG_DEC_CTRL7_DCT5_START_BIT(x) (((x) & 0x3f) << 12) -#define VDPU_REG_DEC_CTRL7_DCT6_START_BIT(x) (((x) & 0x3f) << 6) -#define VDPU_REG_DEC_CTRL7_DCT7_START_BIT(x) (((x) & 0x3f) << 0) -#define VDPU_REG_ADDR_STR 0x030 -#define VDPU_REG_ADDR_DST 0x034 -#define VDPU_REG_ADDR_REF(i) (0x038 + ((i) * 0x4)) -#define VDPU_REG_ADDR_REF_FIELD_E BIT(1) -#define VDPU_REG_ADDR_REF_TOPC_E BIT(0) -#define VDPU_REG_REF_PIC(i) (0x078 + ((i) * 0x4)) -#define VDPU_REG_REF_PIC_FILT_TYPE_E BIT(31) -#define VDPU_REG_REF_PIC_FILT_SHARPNESS(x) (((x) & 0x7) << 28) -#define VDPU_REG_REF_PIC_MB_ADJ_0(x) (((x) & 0x7f) << 21) -#define VDPU_REG_REF_PIC_MB_ADJ_1(x) (((x) & 0x7f) << 14) -#define VDPU_REG_REF_PIC_MB_ADJ_2(x) (((x) & 0x7f) << 7) -#define VDPU_REG_REF_PIC_MB_ADJ_3(x) (((x) & 0x7f) << 0) -#define VDPU_REG_REF_PIC_REFER1_NBR(x) (((x) & 0xffff) << 16) -#define VDPU_REG_REF_PIC_REFER0_NBR(x) (((x) & 0xffff) << 0) -#define VDPU_REG_REF_PIC_LF_LEVEL_0(x) (((x) & 0x3f) << 18) -#define VDPU_REG_REF_PIC_LF_LEVEL_1(x) (((x) & 0x3f) << 12) -#define VDPU_REG_REF_PIC_LF_LEVEL_2(x) (((x) & 0x3f) << 6) -#define VDPU_REG_REF_PIC_LF_LEVEL_3(x) (((x) & 0x3f) << 0) -#define VDPU_REG_REF_PIC_QUANT_DELTA_0(x) (((x) & 0x1f) << 27) -#define VDPU_REG_REF_PIC_QUANT_DELTA_1(x) (((x) & 0x1f) << 22) -#define VDPU_REG_REF_PIC_QUANT_0(x) (((x) & 0x7ff) << 11) -#define VDPU_REG_REF_PIC_QUANT_1(x) (((x) & 0x7ff) << 0) -#define VDPU_REG_LT_REF 0x098 -#define VDPU_REG_VALID_REF 0x09c -#define VDPU_REG_ADDR_QTABLE 0x0a0 -#define VDPU_REG_ADDR_DIR_MV 0x0a4 -#define VDPU_REG_BD_REF_PIC(i) (0x0a8 + ((i) * 0x4)) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B2(x) (((x) & 0x1f) << 25) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F2(x) (((x) & 0x1f) << 20) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B1(x) (((x) & 0x1f) << 15) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F1(x) (((x) & 0x1f) << 10) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B0(x) (((x) & 0x1f) << 5) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F0(x) (((x) & 0x1f) << 0) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_2_M1(x) (((x) & 0x3) << 10) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_2_4(x) (((x) & 0x3) << 8) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_4_M1(x) (((x) & 0x3) << 6) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_4_4(x) (((x) & 0x3) << 4) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_6_M1(x) (((x) & 0x3) << 2) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_6_4(x) (((x) & 0x3) << 0) -#define VDPU_REG_BD_REF_PIC_QUANT_DELTA_2(x) (((x) & 0x1f) << 27) -#define VDPU_REG_BD_REF_PIC_QUANT_DELTA_3(x) (((x) & 0x1f) << 22) -#define VDPU_REG_BD_REF_PIC_QUANT_2(x) (((x) & 0x7ff) << 11) -#define VDPU_REG_BD_REF_PIC_QUANT_3(x) (((x) & 0x7ff) << 0) -#define VDPU_REG_BD_P_REF_PIC 0x0bc -#define VDPU_REG_BD_P_REF_PIC_QUANT_DELTA_4(x) (((x) & 0x1f) << 27) -#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F3(x) (((x) & 0x1f) << 25) -#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F2(x) (((x) & 0x1f) << 20) -#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F1(x) (((x) & 0x1f) << 15) -#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F0(x) (((x) & 0x1f) << 10) -#define VDPU_REG_BD_P_REF_PIC_BINIT_RLIST_B15(x) (((x) & 0x1f) << 5) -#define VDPU_REG_BD_P_REF_PIC_BINIT_RLIST_F15(x) (((x) & 0x1f) << 0) -#define VDPU_REG_ERR_CONC 0x0c0 -#define VDPU_REG_ERR_CONC_STARTMB_X(x) (((x) & 0x1ff) << 23) -#define VDPU_REG_ERR_CONC_STARTMB_Y(x) (((x) & 0xff) << 15) -#define VDPU_REG_PRED_FLT 0x0c4 -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_0(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_1(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_2(x) (((x) & 0x3ff) << 2) -#define VDPU_REG_REF_BUF_CTRL 0x0cc -#define VDPU_REG_REF_BUF_CTRL_REFBU_E BIT(31) -#define VDPU_REG_REF_BUF_CTRL_REFBU_THR(x) (((x) & 0xfff) << 19) -#define VDPU_REG_REF_BUF_CTRL_REFBU_PICID(x) (((x) & 0x1f) << 14) -#define VDPU_REG_REF_BUF_CTRL_REFBU_EVAL_E BIT(13) -#define VDPU_REG_REF_BUF_CTRL_REFBU_FPARMOD_E BIT(12) -#define VDPU_REG_REF_BUF_CTRL_REFBU_Y_OFFSET(x) (((x) & 0x1ff) << 0) -#define VDPU_REG_REF_BUF_CTRL2 0x0dc -#define VDPU_REG_REF_BUF_CTRL2_REFBU2_BUF_E BIT(31) -#define VDPU_REG_REF_BUF_CTRL2_REFBU2_THR(x) (((x) & 0xfff) << 19) -#define VDPU_REG_REF_BUF_CTRL2_REFBU2_PICID(x) (((x) & 0x1f) << 14) -#define VDPU_REG_REF_BUF_CTRL2_APF_THRESHOLD(x) (((x) & 0x3fff) << 0) - -#endif /* RK3288_VPU_REGS_H_ */ diff --git a/drivers/media/platform/rockchip-vpu/rockchip_vpu.c b/drivers/media/platform/rockchip-vpu/rockchip_vpu.c deleted file mode 100644 index 95a201b40213..000000000000 --- a/drivers/media/platform/rockchip-vpu/rockchip_vpu.c +++ /dev/null @@ -1,951 +0,0 @@ -/* - * Rockchip VPU codec driver - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. - * - * Copyright (C) 2011 Samsung Electronics Co., Ltd. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "rockchip_vpu_common.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rockchip_vpu_dec.h" -#include "rockchip_vpu_enc.h" -#include "rockchip_vpu_hw.h" - -int debug; -module_param(debug, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, - "Debug level - higher value produces more verbose messages"); - -/* - * DMA coherent helpers. - */ - -int rockchip_vpu_aux_buf_alloc(struct rockchip_vpu_dev *vpu, - struct rockchip_vpu_aux_buf *buf, size_t size) -{ - buf->cpu = dma_alloc_coherent(vpu->dev, size, &buf->dma, GFP_KERNEL); - if (!buf->cpu) - return -ENOMEM; - - buf->size = size; - return 0; -} - -void rockchip_vpu_aux_buf_free(struct rockchip_vpu_dev *vpu, - struct rockchip_vpu_aux_buf *buf) -{ - dma_free_coherent(vpu->dev, buf->size, buf->cpu, buf->dma); - - buf->cpu = NULL; - buf->dma = 0; - buf->size = 0; -} - -/* - * Context scheduling. - */ - -static void rockchip_vpu_prepare_run(struct rockchip_vpu_ctx *ctx) -{ - if (ctx->run_ops->prepare_run) - ctx->run_ops->prepare_run(ctx); -} - -static void __rockchip_vpu_dequeue_run_locked(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_buf *src, *dst; - - /* - * Since ctx was dequeued from ready_ctxs list, we know that it has - * at least one buffer in each queue. - */ - src = list_first_entry(&ctx->src_queue, struct rockchip_vpu_buf, list); - dst = list_first_entry(&ctx->dst_queue, struct rockchip_vpu_buf, list); - - list_del(&src->list); - list_del(&dst->list); - - ctx->run.src = src; - ctx->run.dst = dst; -} - -static struct rockchip_vpu_ctx * -rockchip_vpu_encode_after_decode_war(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *dev = ctx->dev; - - if (dev->dummy_encode_ctx && - dev->was_decoding && rockchip_vpu_ctx_is_encoder(ctx)) - return dev->dummy_encode_ctx; - - return ctx; -} - -static void rockchip_vpu_try_run(struct rockchip_vpu_dev *dev) -{ - struct rockchip_vpu_ctx *ctx = NULL; - unsigned long flags; - - vpu_debug_enter(); - - spin_lock_irqsave(&dev->irqlock, flags); - - if (list_empty(&dev->ready_ctxs) || - test_bit(VPU_SUSPENDED, &dev->state)) - /* Nothing to do. */ - goto out; - - if (test_and_set_bit(VPU_RUNNING, &dev->state)) - /* - * The hardware is already running. We will pick another - * run after we get the notification in rockchip_vpu_run_done(). - */ - goto out; - - ctx = list_entry(dev->ready_ctxs.next, struct rockchip_vpu_ctx, list); - - /* - * WAR for corrupted hardware state when encoding directly after - * certain decoding runs. - * - * If previous context was decoding and currently picked one is - * encoding then we need to execute a dummy encode with proper - * settings to reinitialize certain internal hardware state. - */ - ctx = rockchip_vpu_encode_after_decode_war(ctx); - - if (!rockchip_vpu_ctx_is_dummy_encode(ctx)) { - list_del_init(&ctx->list); - __rockchip_vpu_dequeue_run_locked(ctx); - } - - dev->current_ctx = ctx; - dev->was_decoding = !rockchip_vpu_ctx_is_encoder(ctx); - -out: - spin_unlock_irqrestore(&dev->irqlock, flags); - - if (ctx) { - rockchip_vpu_prepare_run(ctx); - rockchip_vpu_run(ctx); - } - - vpu_debug_leave(); -} - -static void __rockchip_vpu_try_context_locked(struct rockchip_vpu_dev *dev, - struct rockchip_vpu_ctx *ctx) -{ - if (!list_empty(&ctx->list)) - /* Context already queued. */ - return; - - if (!list_empty(&ctx->dst_queue) && !list_empty(&ctx->src_queue)) - list_add_tail(&ctx->list, &dev->ready_ctxs); -} - -void rockchip_vpu_run_done(struct rockchip_vpu_ctx *ctx, - enum vb2_buffer_state result) -{ - struct rockchip_vpu_dev *dev = ctx->dev; - unsigned long flags; - - vpu_debug_enter(); - - if (ctx->run_ops->run_done) - ctx->run_ops->run_done(ctx, result); - - if (!rockchip_vpu_ctx_is_dummy_encode(ctx)) { - struct vb2_v4l2_buffer *src = - to_vb2_v4l2_buffer(&ctx->run.src->vb.vb2_buf); - struct vb2_v4l2_buffer *dst = - to_vb2_v4l2_buffer(&ctx->run.dst->vb.vb2_buf); - - dst->timestamp = src->timestamp; - vb2_buffer_done(&ctx->run.src->vb.vb2_buf, result); - vb2_buffer_done(&ctx->run.dst->vb.vb2_buf, result); - } - - dev->current_ctx = NULL; - wake_up_all(&dev->run_wq); - - spin_lock_irqsave(&dev->irqlock, flags); - - __rockchip_vpu_try_context_locked(dev, ctx); - clear_bit(VPU_RUNNING, &dev->state); - - spin_unlock_irqrestore(&dev->irqlock, flags); - - /* Try scheduling another run to see if we have anything left to do. */ - rockchip_vpu_try_run(dev); - - vpu_debug_leave(); -} - -void rockchip_vpu_try_context(struct rockchip_vpu_dev *dev, - struct rockchip_vpu_ctx *ctx) -{ - unsigned long flags; - - vpu_debug_enter(); - - spin_lock_irqsave(&dev->irqlock, flags); - - __rockchip_vpu_try_context_locked(dev, ctx); - - spin_unlock_irqrestore(&dev->irqlock, flags); - - rockchip_vpu_try_run(dev); - - vpu_debug_enter(); -} - -/* - * bit stream assembler - */ - -static int stream_buffer_status(struct stream_s *stream) -{ - if (stream->byte_cnt + 5 > stream->size) { - stream->overflow = 1; - return -1; - } - - return 0; -} - -void stream_put_bits(struct stream_s *buffer, s32 value, s32 number, - const char *name) -{ - s32 bits; - u32 byte_buffer = buffer->byte_buffer; - u8 *stream = buffer->stream; - - if (stream_buffer_status(buffer) != 0) - return; - - vpu_debug(0, "assemble %s value %x, bits %d\n", name, value, number); - - BUG_ON(value >= (1 << number)); - BUG_ON(number >= 25); - - bits = number + buffer->buffered_bits; - value <<= (32 - bits); - byte_buffer = byte_buffer | value; - - while (bits > 7) { - *stream = (u8)(byte_buffer >> 24); - - bits -= 8; - byte_buffer <<= 8; - stream++; - buffer->byte_cnt++; - } - - buffer->byte_buffer = byte_buffer; - buffer->buffered_bits = (u8)bits; - buffer->stream = stream; - - return; -} - -void stream_buffer_reset(struct stream_s *buffer) -{ - buffer->stream = buffer->buffer; - buffer->byte_cnt = 0; - buffer->overflow = 0; - buffer->byte_buffer = 0; - buffer->buffered_bits = 0; -} - -int stream_buffer_init(struct stream_s *buffer, u8 *stream, s32 size) -{ - if (stream == NULL) { - buffer->stream = kzalloc(size, GFP_KERNEL); - } - - if (buffer->stream == NULL) { - vpu_err("allocate stream buffer failed\n"); - return -1; - } - - buffer->buffer = buffer->stream; - buffer->size = size; - - stream_buffer_reset(buffer); - - if (stream_buffer_status(buffer) != 0) - return -1; - - return 0; -} - -/* - * Control registration. - */ - -#define IS_VPU_PRIV(x) ((V4L2_CTRL_ID2WHICH(x) == V4L2_CTRL_CLASS_MPEG) && \ - V4L2_CTRL_DRIVER_PRIV(x)) - -int rockchip_vpu_ctrls_setup(struct rockchip_vpu_ctx *ctx, - const struct v4l2_ctrl_ops *ctrl_ops, - struct rockchip_vpu_control *controls, - unsigned num_ctrls, - const char *const *(*get_menu)(u32)) -{ - struct v4l2_ctrl_config cfg; - int i; - - if (num_ctrls > ARRAY_SIZE(ctx->ctrls)) { - vpu_err("context control array not large enough\n"); - return -ENOSPC; - } - - v4l2_ctrl_handler_init(&ctx->ctrl_handler, num_ctrls); - if (ctx->ctrl_handler.error) { - vpu_err("v4l2_ctrl_handler_init failed\n"); - return ctx->ctrl_handler.error; - } - - for (i = 0; i < num_ctrls; i++) { - if (IS_VPU_PRIV(controls[i].id) - || controls[i].id >= V4L2_CID_CUSTOM_BASE - || controls[i].type == V4L2_CTRL_TYPE_PRIVATE) { - memset(&cfg, 0, sizeof(struct v4l2_ctrl_config)); - - cfg.ops = ctrl_ops; - cfg.id = controls[i].id; - cfg.min = controls[i].minimum; - cfg.max = controls[i].maximum; - cfg.max_stores = controls[i].max_stores; - cfg.def = controls[i].default_value; - cfg.name = controls[i].name; - cfg.type = controls[i].type; - cfg.elem_size = controls[i].elem_size; - memcpy(cfg.dims, controls[i].dims, sizeof(cfg.dims)); - - if (cfg.type == V4L2_CTRL_TYPE_MENU) { - cfg.menu_skip_mask = cfg.menu_skip_mask; - cfg.qmenu = get_menu(cfg.id); - } else { - cfg.step = controls[i].step; - } - - ctx->ctrls[i] = v4l2_ctrl_new_custom( - &ctx->ctrl_handler, &cfg, NULL); - } else { - if (controls[i].type == V4L2_CTRL_TYPE_MENU) { - ctx->ctrls[i] = - v4l2_ctrl_new_std_menu - (&ctx->ctrl_handler, - ctrl_ops, - controls[i].id, - controls[i].maximum, - 0, - controls[i]. - default_value); - } else { - ctx->ctrls[i] = - v4l2_ctrl_new_std(&ctx->ctrl_handler, - ctrl_ops, - controls[i].id, - controls[i].minimum, - controls[i].maximum, - controls[i].step, - controls[i]. - default_value); - } - } - - if (ctx->ctrl_handler.error) { - vpu_err("Adding control (%d) failed\n", i); - return ctx->ctrl_handler.error; - } - - if (controls[i].is_volatile && ctx->ctrls[i]) - ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_VOLATILE; - if (controls[i].is_read_only && ctx->ctrls[i]) - ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_READ_ONLY; - if (controls[i].can_store && ctx->ctrls[i]) - ctx->ctrls[i]->flags |= V4L2_CTRL_FLAG_CAN_STORE; - } - - v4l2_ctrl_handler_setup(&ctx->ctrl_handler); - ctx->num_ctrls = num_ctrls; - return 0; -} - -void rockchip_vpu_ctrls_delete(struct rockchip_vpu_ctx *ctx) -{ - int i; - - v4l2_ctrl_handler_free(&ctx->ctrl_handler); - for (i = 0; i < ctx->num_ctrls; i++) - ctx->ctrls[i] = NULL; -} - -/* - * V4L2 file operations. - */ - -static int rockchip_vpu_open(struct file *filp) -{ - struct video_device *vdev = video_devdata(filp); - struct rockchip_vpu_dev *dev = video_drvdata(filp); - struct rockchip_vpu_ctx *ctx = NULL; - struct vb2_queue *q; - int ret = 0; - - /* - * We do not need any extra locking here, because we operate only - * on local data here, except reading few fields from dev, which - * do not change through device's lifetime (which is guaranteed by - * reference on module from open()) and V4L2 internal objects (such - * as vdev and ctx->fh), which have proper locking done in respective - * helper functions used here. - */ - - vpu_debug_enter(); - - /* Allocate memory for context */ - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) { - ret = -ENOMEM; - goto err_leave; - } - - v4l2_fh_init(&ctx->fh, video_devdata(filp)); - filp->private_data = &ctx->fh; - v4l2_fh_add(&ctx->fh); - ctx->dev = dev; - INIT_LIST_HEAD(&ctx->src_queue); - INIT_LIST_HEAD(&ctx->dst_queue); - INIT_LIST_HEAD(&ctx->list); - - if (vdev == dev->vfd_enc) { - /* only for encoder */ - ret = rockchip_vpu_enc_init(ctx); - if (ret) { - vpu_err("Failed to initialize encoder context\n"); - goto err_fh_free; - } - } else if (vdev == dev->vfd_dec) { - /* only for decoder */ - ret = rockchip_vpu_dec_init(ctx); - if (ret) { - vpu_err("Failed to initialize decoder context\n"); - goto err_fh_free; - } - } else { - ret = -ENOENT; - goto err_fh_free; - } - ctx->fh.ctrl_handler = &ctx->ctrl_handler; - - /* Init videobuf2 queue for CAPTURE */ - q = &ctx->vq_dst; - q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - q->drv_priv = &ctx->fh; - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; - q->lock = &dev->vpu_mutex; - q->buf_struct_size = sizeof(struct rockchip_vpu_buf); - - if (vdev == dev->vfd_enc) { - q->ops = get_enc_queue_ops(); - } else if (vdev == dev->vfd_dec) { - q->ops = get_dec_queue_ops(); - q->use_dma_bidirectional = 1; - } - - q->mem_ops = &vb2_dma_contig_memops; - q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - - ret = vb2_queue_init(q); - if (ret) { - vpu_err("Failed to initialize videobuf2 queue(capture)\n"); - goto err_enc_dec_exit; - } - - /* Init videobuf2 queue for OUTPUT */ - q = &ctx->vq_src; - q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - q->drv_priv = &ctx->fh; - q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; - q->lock = &dev->vpu_mutex; - q->buf_struct_size = sizeof(struct rockchip_vpu_buf); - - if (vdev == dev->vfd_enc) - q->ops = get_enc_queue_ops(); - else if (vdev == dev->vfd_dec) - q->ops = get_dec_queue_ops(); - - q->mem_ops = &vb2_dma_contig_memops; - q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; - - ret = vb2_queue_init(q); - if (ret) { - vpu_err("Failed to initialize videobuf2 queue(output)\n"); - goto err_vq_dst_release; - } - - vpu_debug_leave(); - - return 0; - -err_vq_dst_release: - vb2_queue_release(&ctx->vq_dst); -err_enc_dec_exit: - if (vdev == dev->vfd_enc) - rockchip_vpu_enc_exit(ctx); - else if (vdev == dev->vfd_dec) - rockchip_vpu_dec_exit(ctx); -err_fh_free: - v4l2_fh_del(&ctx->fh); - v4l2_fh_exit(&ctx->fh); - kfree(ctx); -err_leave: - vpu_debug_leave(); - - return ret; -} - -static int rockchip_vpu_release(struct file *filp) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(filp->private_data); - struct video_device *vdev = video_devdata(filp); - struct rockchip_vpu_dev *dev = ctx->dev; - - /* - * No need for extra locking because this was the last reference - * to this file. - */ - - vpu_debug_enter(); - - /* - * vb2_queue_release() ensures that streaming is stopped, which - * in turn means that there are no frames still being processed - * by hardware. - */ - vb2_queue_release(&ctx->vq_src); - vb2_queue_release(&ctx->vq_dst); - - v4l2_fh_del(&ctx->fh); - v4l2_fh_exit(&ctx->fh); - - if (vdev == dev->vfd_enc) - rockchip_vpu_enc_exit(ctx); - else if (vdev == dev->vfd_dec) - rockchip_vpu_dec_exit(ctx); - - kfree(ctx); - - vpu_debug_leave(); - - return 0; -} - -static unsigned int rockchip_vpu_poll(struct file *filp, - struct poll_table_struct *wait) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(filp->private_data); - struct vb2_queue *src_q, *dst_q; - struct vb2_buffer *src_vb = NULL, *dst_vb = NULL; - unsigned int rc = 0; - unsigned long flags; - - vpu_debug_enter(); - - src_q = &ctx->vq_src; - dst_q = &ctx->vq_dst; - - /* - * There has to be at least one buffer queued on each queued_list, which - * means either in driver already or waiting for driver to claim it - * and start processing. - */ - if ((!vb2_is_streaming(src_q) || list_empty(&src_q->queued_list)) && - (!vb2_is_streaming(dst_q) || list_empty(&dst_q->queued_list))) { - vpu_debug(0, "src q streaming %d, dst q streaming %d, src list empty(%d), dst list empty(%d)\n", - src_q->streaming, dst_q->streaming, - list_empty(&src_q->queued_list), - list_empty(&dst_q->queued_list)); - return POLLERR; - } - - poll_wait(filp, &ctx->fh.wait, wait); - poll_wait(filp, &src_q->done_wq, wait); - poll_wait(filp, &dst_q->done_wq, wait); - - if (v4l2_event_pending(&ctx->fh)) - rc |= POLLPRI; - - spin_lock_irqsave(&src_q->done_lock, flags); - - if (!list_empty(&src_q->done_list)) - src_vb = list_first_entry(&src_q->done_list, struct vb2_buffer, - done_entry); - - if (src_vb && (src_vb->state == VB2_BUF_STATE_DONE || - src_vb->state == VB2_BUF_STATE_ERROR)) - rc |= POLLOUT | POLLWRNORM; - - spin_unlock_irqrestore(&src_q->done_lock, flags); - - spin_lock_irqsave(&dst_q->done_lock, flags); - - if (!list_empty(&dst_q->done_list)) - dst_vb = list_first_entry(&dst_q->done_list, struct vb2_buffer, - done_entry); - - if (dst_vb && (dst_vb->state == VB2_BUF_STATE_DONE || - dst_vb->state == VB2_BUF_STATE_ERROR)) - rc |= POLLIN | POLLRDNORM; - - spin_unlock_irqrestore(&dst_q->done_lock, flags); - - return rc; -} - -static int rockchip_vpu_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(filp->private_data); - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - int ret; - - vpu_debug_enter(); - - if (offset < DST_QUEUE_OFF_BASE) { - vpu_debug(4, "mmaping source\n"); - - ret = vb2_mmap(&ctx->vq_src, vma); - } else { /* capture */ - vpu_debug(4, "mmaping destination\n"); - - vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT); - ret = vb2_mmap(&ctx->vq_dst, vma); - } - - vpu_debug_leave(); - - return ret; -} - -static const struct v4l2_file_operations rockchip_vpu_fops = { - .owner = THIS_MODULE, - .open = rockchip_vpu_open, - .release = rockchip_vpu_release, - .poll = rockchip_vpu_poll, - .unlocked_ioctl = video_ioctl2, - .mmap = rockchip_vpu_mmap, -}; - -/* - * Platform driver. - */ - -static void* rockchip_get_drv_data(struct platform_device *pdev); - -static int rockchip_vpu_probe(struct platform_device *pdev) -{ - struct rockchip_vpu_dev *vpu = NULL; - DEFINE_DMA_ATTRS(attrs_novm); - DEFINE_DMA_ATTRS(attrs_nohugepage); - struct video_device *vfd; - int ret = 0; - - vpu_debug_enter(); - - vpu = devm_kzalloc(&pdev->dev, sizeof(*vpu), GFP_KERNEL); - if (!vpu) - return -ENOMEM; - - vpu->dev = &pdev->dev; - vpu->pdev = pdev; - mutex_init(&vpu->vpu_mutex); - spin_lock_init(&vpu->irqlock); - INIT_LIST_HEAD(&vpu->ready_ctxs); - init_waitqueue_head(&vpu->run_wq); - - vpu->variant = rockchip_get_drv_data(pdev); - - ret = rockchip_vpu_hw_probe(vpu); - if (ret) { - dev_err(&pdev->dev, "rockchip_vpu_hw_probe failed\n"); - goto err_hw_probe; - } - - /* - * We'll do mostly sequential access, so sacrifice TLB efficiency for - * faster allocation. - */ - dma_set_attr(DMA_ATTR_ALLOC_SINGLE_PAGES, &attrs_novm); - - dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs_novm); - vpu->alloc_ctx = vb2_dma_contig_init_ctx_attrs(&pdev->dev, - &attrs_novm); - if (IS_ERR(vpu->alloc_ctx)) { - ret = PTR_ERR(vpu->alloc_ctx); - goto err_dma_contig; - } - - dma_set_attr(DMA_ATTR_ALLOC_SINGLE_PAGES, &attrs_nohugepage); - vpu->alloc_ctx_vm = vb2_dma_contig_init_ctx_attrs(&pdev->dev, - &attrs_nohugepage); - if (IS_ERR(vpu->alloc_ctx_vm)) { - ret = PTR_ERR(vpu->alloc_ctx_vm); - goto err_dma_contig_vm; - } - - ret = v4l2_device_register(&pdev->dev, &vpu->v4l2_dev); - if (ret) { - dev_err(&pdev->dev, "Failed to register v4l2 device\n"); - goto err_v4l2_dev_reg; - } - - platform_set_drvdata(pdev, vpu); - - /* workaround for rk3288 codecs */ - if (vpu->variant->codecs == RK3288_CODECS) { - ret = rockchip_vpu_enc_init_dummy_ctx(vpu); - if (ret) { - dev_err(&pdev->dev, - "Failed to create dummy encode context\n"); - goto err_dummy_enc; - } - } - - /* encoder */ - if (!(vpu->variant->codecs & ROCKCHIP_VPU_ENCODERS)) - goto no_encoder; - - vfd = video_device_alloc(); - if (!vfd) { - v4l2_err(&vpu->v4l2_dev, "Failed to allocate video device\n"); - ret = -ENOMEM; - goto err_enc_alloc; - } - - vfd->fops = &rockchip_vpu_fops; - vfd->ioctl_ops = get_enc_v4l2_ioctl_ops(); - vfd->release = video_device_release; - vfd->lock = &vpu->vpu_mutex; - vfd->v4l2_dev = &vpu->v4l2_dev; - vfd->vfl_dir = VFL_DIR_M2M; - snprintf(vfd->name, sizeof(vfd->name), "%s", ROCKCHIP_VPU_ENC_NAME); - vpu->vfd_enc = vfd; - - video_set_drvdata(vfd, vpu); - - ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); - if (ret) { - v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n"); - video_device_release(vfd); - goto err_enc_reg; - } - - v4l2_info(&vpu->v4l2_dev, - "Rockchip VPU encoder registered as /vpu/video%d\n", - vfd->num); - -no_encoder: - /* decoder */ - if (!(vpu->variant->codecs & ROCKCHIP_VPU_DECODERS)) - goto no_decoder; - - vfd = video_device_alloc(); - if (!vfd) { - v4l2_err(&vpu->v4l2_dev, "Failed to allocate video device\n"); - ret = -ENOMEM; - goto err_dec_alloc; - } - - vfd->fops = &rockchip_vpu_fops; - vfd->ioctl_ops = get_dec_v4l2_ioctl_ops(); - vfd->release = video_device_release; - vfd->lock = &vpu->vpu_mutex; - vfd->v4l2_dev = &vpu->v4l2_dev; - vfd->vfl_dir = VFL_DIR_M2M; - snprintf(vfd->name, sizeof(vfd->name), "%s", ROCKCHIP_VPU_DEC_NAME); - vpu->vfd_dec = vfd; - - video_set_drvdata(vfd, vpu); - - ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); - if (ret) { - v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n"); - video_device_release(vfd); - goto err_dec_reg; - } - - v4l2_info(&vpu->v4l2_dev, - "Rockchip VPU decoder registered as /vpu/video%d\n", - vfd->num); - -no_decoder: - vpu_debug_leave(); - - return 0; - -err_dec_reg: - video_device_release(vpu->vfd_dec); -err_dec_alloc: - video_unregister_device(vpu->vfd_enc); -err_enc_reg: - video_device_release(vpu->vfd_enc); -err_enc_alloc: - rockchip_vpu_enc_free_dummy_ctx(vpu); -err_dummy_enc: - v4l2_device_unregister(&vpu->v4l2_dev); -err_v4l2_dev_reg: - vb2_dma_contig_cleanup_ctx(vpu->alloc_ctx_vm); -err_dma_contig_vm: - vb2_dma_contig_cleanup_ctx(vpu->alloc_ctx); -err_dma_contig: - rockchip_vpu_hw_remove(vpu); -err_hw_probe: - pr_debug("%s-- with error\n", __func__); - vpu_debug_leave(); - - return ret; -} - -static int rockchip_vpu_remove(struct platform_device *pdev) -{ - struct rockchip_vpu_dev *vpu = platform_get_drvdata(pdev); - - vpu_debug_enter(); - - v4l2_info(&vpu->v4l2_dev, "Removing %s\n", pdev->name); - - /* - * We are safe here assuming that .remove() got called as - * a result of module removal, which guarantees that all - * contexts have been released. - */ - - video_unregister_device(vpu->vfd_dec); - video_unregister_device(vpu->vfd_enc); - rockchip_vpu_enc_free_dummy_ctx(vpu); - v4l2_device_unregister(&vpu->v4l2_dev); - vb2_dma_contig_cleanup_ctx(vpu->alloc_ctx_vm); - vb2_dma_contig_cleanup_ctx(vpu->alloc_ctx); - rockchip_vpu_hw_remove(vpu); - - vpu_debug_leave(); - - return 0; -} - -/* Supported VPU variants. */ -static const struct rockchip_vpu_variant rk3288_vpu_variant = { - .name = "Rk3288 vpu", - .codecs = RK3288_CODECS, - .enc_offset = 0x0, - .enc_reg_num = 164, - .dec_offset = 0x400, - .dec_reg_num = 60 + 41, -}; - -static struct platform_device_id vpu_driver_ids[] = { - { - .name = "rk3288-vpu", - .driver_data = (unsigned long)&rk3288_vpu_variant, - }, - { /* sentinel */ } -}; - -MODULE_DEVICE_TABLE(platform, vpu_driver_ids); - -#ifdef CONFIG_OF -static const struct of_device_id of_rockchip_vpu_match[] = { - { .compatible = "rockchip,rk3288-vpu", .data = &rk3288_vpu_variant, }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, of_rockchip_vpu_match); -#endif - -static void* rockchip_get_drv_data(struct platform_device *pdev) -{ -#ifdef CONFIG_OF - if (pdev->dev.of_node) { - const struct of_device_id *match; - match = of_match_node(of_rockchip_vpu_match, - pdev->dev.of_node); - if (match) - return (void *)match->data; - } -#endif - - return (void *)platform_get_device_id(pdev)->driver_data; -} - -#ifdef CONFIG_PM_SLEEP -static int rockchip_vpu_suspend(struct device *dev) -{ - struct rockchip_vpu_dev *vpu = dev_get_drvdata(dev); - - set_bit(VPU_SUSPENDED, &vpu->state); - wait_event(vpu->run_wq, vpu->current_ctx == NULL); - - return 0; -} - -static int rockchip_vpu_resume(struct device *dev) -{ - struct rockchip_vpu_dev *vpu = dev_get_drvdata(dev); - - clear_bit(VPU_SUSPENDED, &vpu->state); - rockchip_vpu_try_run(vpu); - - return 0; -} -#endif - -static const struct dev_pm_ops rockchip_vpu_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(rockchip_vpu_suspend, rockchip_vpu_resume) -}; - -static struct platform_driver rockchip_vpu_driver = { - .probe = rockchip_vpu_probe, - .remove = rockchip_vpu_remove, - .id_table = vpu_driver_ids, - .driver = { - .name = ROCKCHIP_VPU_NAME, - .owner = THIS_MODULE, -#ifdef CONFIG_OF - .of_match_table = of_match_ptr(of_rockchip_vpu_match), -#endif - .pm = &rockchip_vpu_pm_ops, - }, -}; -module_platform_driver(rockchip_vpu_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Alpha Lin "); -MODULE_AUTHOR("Tomasz Figa "); -MODULE_DESCRIPTION("Rockchip VPU codec driver"); diff --git a/drivers/media/platform/rockchip-vpu/rockchip_vpu_common.h b/drivers/media/platform/rockchip-vpu/rockchip_vpu_common.h deleted file mode 100644 index 9a62d661cbad..000000000000 --- a/drivers/media/platform/rockchip-vpu/rockchip_vpu_common.h +++ /dev/null @@ -1,595 +0,0 @@ -/* - * Rockchip VPU codec driver - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. - * - * Copyright (C) 2011 Samsung Electronics Co., Ltd. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef ROCKCHIP_VPU_COMMON_H_ -#define ROCKCHIP_VPU_COMMON_H_ - -/* Enable debugging by default for now. */ -#define DEBUG - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "rockchip_vpu_hw.h" - -#define ROCKCHIP_VPU_NAME "rockchip-vpu" -#define ROCKCHIP_VPU_DEC_NAME "rockchip-vpu-dec" -#define ROCKCHIP_VPU_ENC_NAME "rockchip-vpu-enc" - -#define V4L2_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0x1000) - -#define DST_QUEUE_OFF_BASE (TASK_SIZE / 2) - -#define ROCKCHIP_VPU_MAX_CTRLS 32 - -#define MB_DIM 16 -#define MB_WIDTH(x_size) DIV_ROUND_UP(x_size, MB_DIM) -#define MB_HEIGHT(y_size) DIV_ROUND_UP(y_size, MB_DIM) - -struct rockchip_vpu_ctx; -struct rockchip_vpu_codec_ops; - -/** - * struct rockchip_vpu_variant - information about VPU hardware variant - * - * @hw_id: Top 16 bits (product ID) of hardware ID register. - * @name: Vpu name. - * @codecs: Supported codecs of this vpu. - * @enc_offset: Offset from VPU base to encoder registers. - * @enc_reg_num: Number of registers of encoder block. - * @dec_offset: Offset from VPU base to decoder registers. - * @dec_reg_num: Number of registers of decoder block. - */ -struct rockchip_vpu_variant { - char *name; - unsigned codecs; - unsigned enc_offset; - unsigned enc_reg_num; - unsigned dec_offset; - unsigned dec_reg_num; -}; - -/** - * enum rockchip_vpu_codec_mode - codec operating mode. - * @RK_VPU_CODEC_NONE: Used for RAW video formats. - * @RK3288_VPU_CODEC_H264D: Rk3288 H264 decoder. - * @RK3288_VPU_CODEC_H264E: Rk3288 H264 encoder. - * @RK3288_VPU_CODEC_VP8D: Rk3288 VP8 decoder. - * @RK3288_VPU_CODEC_VP8E: Rk3288 VP8 encoder. - */ -enum rockchip_vpu_codec_mode { - RK_VPU_CODEC_NONE = (1 << 0), - RK3288_VPU_CODEC_H264D = (1 << 1), - RK3288_VPU_CODEC_H264E = (1 << 2), - RK3288_VPU_CODEC_VP8D = (1 << 3), - RK3288_VPU_CODEC_VP8E = (1 << 4), -}; - -#define ROCKCHIP_VPU_DECODERS (RK3288_VPU_CODEC_H264D | RK3288_VPU_CODEC_VP8D) -#define ROCKCHIP_VPU_ENCODERS (RK3288_VPU_CODEC_H264E | RK3288_VPU_CODEC_VP8E) - -#define RK3288_CODECS (RK_VPU_CODEC_NONE | RK3288_VPU_CODEC_H264D | RK3288_VPU_CODEC_H264E | RK3288_VPU_CODEC_VP8D | RK3288_VPU_CODEC_VP8E) - -/** - * enum rockchip_vpu_plane - indices of planes inside a VB2 buffer. - * @PLANE_Y: Plane containing luminance data (also denoted as Y). - * @PLANE_CB_CR: Plane containing interleaved chrominance data (also - * denoted as CbCr). - * @PLANE_CB: Plane containing CB part of chrominance data. - * @PLANE_CR: Plane containing CR part of chrominance data. - */ -enum rockchip_vpu_plane { - PLANE_Y = 0, - PLANE_CB_CR = 1, - PLANE_CB = 1, - PLANE_CR = 2, -}; - -/** - * struct rockchip_vpu_vp8e_buf_data - mode-specific per-buffer data - * @dct_offset: Offset inside the buffer to DCT partition. - * @hdr_size: Size of header data in the buffer. - * @ext_hdr_size: Size of ext header data in the buffer. - * @dct_size: Size of DCT partition in the buffer. - * @header: Frame header to copy to destination buffer. - */ -struct rockchip_vpu_vp8e_buf_data { - size_t dct_offset; - size_t hdr_size; - size_t ext_hdr_size; - size_t dct_size; - u8 header[ROCKCHIP_HEADER_SIZE]; -}; - -/** - * struct rockchip_vpu_h264e_buf_data - mode-specific per-buffer data - * @sps_size: Size of sps data in the buffer. - * @pps_size: Size of pps data in the buffer. - * @slices_size: Size of slices data in the buffer. - */ -struct rockchip_vpu_h264e_buf_data { - size_t sps_size; - size_t pps_size; - size_t slices_size; -}; - -/** - * struct rockchip_vpu_buf - Private data related to each VB2 buffer. - * @vb: Pointer to related VB2 buffer. - * @list: List head for queuing in buffer queue. - */ -struct rockchip_vpu_buf { - struct vb2_v4l2_buffer vb; - struct list_head list; - - /* Mode-specific data. */ - union { - struct rockchip_vpu_h264e_buf_data h264e; - struct rockchip_vpu_vp8e_buf_data vp8e; - }; -}; - -/** - * enum rockchip_vpu_state - bitwise flags indicating hardware state. - * @VPU_RUNNING: The hardware has been programmed for operation - * and is running at the moment. - * @VPU_SUSPENDED: System is entering sleep state and no more runs - * should be executed on hardware. - */ -enum rockchip_vpu_state { - VPU_RUNNING = BIT(0), - VPU_SUSPENDED = BIT(1), -}; - -/** - * struct rockchip_vpu_dev - driver data - * @v4l2_dev: V4L2 device to register video devices for. - * @vfd_dec: Video device for decoder. - * @vfd_enc: Video device for encoder. - * @pdev: Pointer to VPU platform device. - * @dev: Pointer to device for convenient logging using - * dev_ macros. - * @alloc_ctx: VB2 allocator context - * (for allocations without kernel mapping). - * @alloc_ctx_vm: VB2 allocator context - * (for allocations with kernel mapping). - * @aclk: Handle of ACLK clock. - * @hclk: Handle of HCLK clock. - * @base: Mapped address of VPU registers. - * @enc_base: Mapped address of VPU encoder register for convenience. - * @dec_base: Mapped address of VPU decoder register for convenience. - * @mapping: DMA IOMMU mapping. - * @domain: DMA IOMMU domain. - * @vpu_mutex: Mutex to synchronize V4L2 calls. - * @irqlock: Spinlock to synchronize access to data structures - * shared with interrupt handlers. - * @state: Device state. - * @ready_ctxs: List of contexts ready to run. - * @variant: Hardware variant-specfic parameters. - * @current_ctx: Context being currently processed by hardware. - * @run_wq: Wait queue to wait for run completion. - * @watchdog_work: Delayed work for hardware timeout handling. - * @dummy_encode_ctx: Context used to run dummy frame encoding to initialize - * encoder hardware state. - * @dummy_encode_src: Source buffers used for dummy frame encoding. - * @dummy_encode_dst: Desintation buffer used for dummy frame encoding. - * @was_decoding: Indicates whether last run context was a decoder. - */ -struct rockchip_vpu_dev { - struct v4l2_device v4l2_dev; - struct video_device *vfd_dec; - struct video_device *vfd_enc; - struct platform_device *pdev; - struct device *dev; - void *alloc_ctx; - void *alloc_ctx_vm; - struct clk *aclk; - struct clk *hclk; - void __iomem *base; - void __iomem *enc_base; - void __iomem *dec_base; - struct dma_iommu_mapping *mapping; - struct iommu_domain *domain; - - struct mutex vpu_mutex; /* video_device lock */ - spinlock_t irqlock; - unsigned long state; - struct list_head ready_ctxs; - const struct rockchip_vpu_variant *variant; - struct rockchip_vpu_ctx *current_ctx; - wait_queue_head_t run_wq; - struct delayed_work watchdog_work; - struct rockchip_vpu_ctx *dummy_encode_ctx; - struct rockchip_vpu_aux_buf dummy_encode_src[VIDEO_MAX_PLANES]; - struct rockchip_vpu_aux_buf dummy_encode_dst; - bool was_decoding; -}; - -/** - * struct rockchip_vpu_run_ops - per context operations on run data. - * @prepare_run: Called when the context was selected for running - * to prepare operating mode specific data. - * @run_done: Called when hardware completed the run to collect - * operating mode specific data from hardware and - * finalize the processing. - */ -struct rockchip_vpu_run_ops { - void (*prepare_run)(struct rockchip_vpu_ctx *); - void (*run_done)(struct rockchip_vpu_ctx *, enum vb2_buffer_state); -}; - -/** - * struct rockchip_vpu_vp8e_run - per-run data specific to VP8 encoding. - * @reg_params: Pointer to a buffer containing register values prepared - * by user space. - */ -struct rockchip_vpu_vp8e_run { - const struct rockchip_reg_params *reg_params; -}; - -/** - * struct rockchip_vpu_vp8d_run - per-run data specific to VP8 decoding. - * @frame_hdr: Pointer to a buffer containing per-run frame data which - * is needed by setting vpu register. - */ -struct rockchip_vpu_vp8d_run { - const struct v4l2_ctrl_vp8_frame_hdr *frame_hdr; -}; - -/** - * struct rockchip_vpu_h264d_run - per-run data specific to H264 decoding. - * @sps: Pointer to a buffer containing H264 SPS. - * @pps: Pointer to a buffer containing H264 PPS. - * @scaling_matrix: Pointer to a buffer containing scaling matrix. - * @slice_param: Pointer to a buffer containing slice parameters array. - * @decode_param: Pointer to a buffer containing decode parameters. - * @dpb: Array of DPB entries reordered to keep POC order. - * @dpb_map: Map of indices used in ref_pic_list_* into indices to - * reordered DPB array. - */ -struct rockchip_vpu_h264d_run { - const struct v4l2_ctrl_h264_sps *sps; - const struct v4l2_ctrl_h264_pps *pps; - const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix; - const struct v4l2_ctrl_h264_slice_param *slice_param; - const struct v4l2_ctrl_h264_decode_param *decode_param; - struct v4l2_h264_dpb_entry dpb[16]; - u8 dpb_map[16]; -}; - -/* struct for assemble bitstream */ -struct stream_s { - u8 *buffer; /* point to first byte of stream */ - u8 *stream; /* Pointer to next byte of stream */ - u32 size; /* Byte size of stream buffer */ - u32 byte_cnt; /* Byte counter */ - u32 bit_cnt; /* Bit counter */ - u32 byte_buffer; /* Byte buffer */ - u32 buffered_bits; /* Amount of bits in byte buffer, [0-7] */ - s32 overflow; /* This will signal a buffer overflow */ -}; - -void stream_put_bits(struct stream_s *buffer, s32 value, s32 number, - const char *name); -void stream_buffer_reset(struct stream_s *buffer); -int stream_buffer_init(struct stream_s *buffer, u8 *stream, s32 size); - -/** - * struct rockchip_vpu_h264e_run - per-run data specific to H264 encoding. - */ -struct rockchip_vpu_h264e_run { - const struct rockchip_reg_params *reg_params; - struct stream_s sps; - struct stream_s pps; - u32 hw_write_offset; -}; - -/** - * struct rockchip_vpu_run - per-run data for hardware code. - * @src: Source buffer to be processed. - * @dst: Destination buffer to be processed. - * @priv_src: Hardware private source buffer. - * @priv_dst: Hardware private destination buffer. - */ -struct rockchip_vpu_run { - /* Generic for more than one operating mode. */ - struct rockchip_vpu_buf *src; - struct rockchip_vpu_buf *dst; - - struct rockchip_vpu_aux_buf priv_src; - struct rockchip_vpu_aux_buf priv_dst; - - /* Specific for particular operating modes. */ - union { - struct rockchip_vpu_vp8e_run vp8e; - struct rockchip_vpu_vp8d_run vp8d; - struct rockchip_vpu_h264d_run h264d; - struct rockchip_vpu_h264e_run h264e; - /* Other modes will need different data. */ - }; -}; - -/** - * struct rockchip_vpu_ctx - Context (instance) private data. - * - * @dev: VPU driver data to which the context belongs. - * @fh: V4L2 file handler. - * - * @vpu_src_fmt: Descriptor of active source format. - * @src_fmt: V4L2 pixel format of active source format. - * @vpu_dst_fmt: Descriptor of active destination format. - * @dst_fmt: V4L2 pixel format of active destination format. - * - * @vq_src: Videobuf2 source queue. - * @src_queue: Internal source buffer queue. - * @src_crop: Configured source crop rectangle (encoder-only). - * @vq_dst: Videobuf2 destination queue - * @dst_queue: Internal destination buffer queue. - * @dst_bufs: Private buffers wrapping VB2 buffers (destination). - * - * @ctrls: Array containing pointer to registered controls. - * @ctrl_handler: Control handler used to register controls. - * @num_ctrls: Number of registered controls. - * - * @list: List head for queue of ready contexts. - * - * @run: Structure containing data about currently scheduled - * processing run. - * @run_ops: Set of operations related to currently scheduled run. - * @hw: Structure containing hardware-related context. - */ -struct rockchip_vpu_ctx { - struct rockchip_vpu_dev *dev; - struct v4l2_fh fh; - - /* Format info */ - struct rockchip_vpu_fmt *vpu_src_fmt; - struct v4l2_pix_format_mplane src_fmt; - struct rockchip_vpu_fmt *vpu_dst_fmt; - struct v4l2_pix_format_mplane dst_fmt; - - /* VB2 queue data */ - struct vb2_queue vq_src; - struct list_head src_queue; - struct v4l2_rect src_crop; - struct vb2_queue vq_dst; - struct list_head dst_queue; - struct vb2_buffer *dst_bufs[VIDEO_MAX_FRAME]; - - /* Controls */ - struct v4l2_ctrl *ctrls[ROCKCHIP_VPU_MAX_CTRLS]; - struct v4l2_ctrl_handler ctrl_handler; - unsigned num_ctrls; - - /* Various runtime data */ - struct list_head list; - - struct rockchip_vpu_run run; - const struct rockchip_vpu_run_ops *run_ops; - struct rockchip_vpu_hw_ctx hw; -}; - -/** - * struct rockchip_vpu_fmt - information about supported video formats. - * @name: Human readable name of the format. - * @fourcc: FourCC code of the format. See V4L2_PIX_FMT_*. - * @codec_mode: Codec mode related to this format. See - * enum rockchip_vpu_codec_mode. - * @num_planes: Number of planes used by this format. - * @depth: Depth of each plane in bits per pixel. - * @enc_fmt: Format identifier for encoder registers. - */ -struct rockchip_vpu_fmt { - char *name; - u32 fourcc; - enum rockchip_vpu_codec_mode codec_mode; - int num_planes; - u8 depth[VIDEO_MAX_PLANES]; - enum rockchip_vpu_enc_fmt enc_fmt; -}; - -/** - * struct rockchip_vpu_control - information about controls to be registered. - * @id: Control ID. - * @type: Type of the control. - * @name: Human readable name of the control. - * @minimum: Minimum value of the control. - * @maximum: Maximum value of the control. - * @step: Control value increase step. - * @menu_skip_mask: Mask of invalid menu positions. - * @default_value: Initial value of the control. - * @max_stores: Maximum number of configration stores. - * @dims: Size of each dimension of compound control. - * @elem_size: Size of individual element of compound control. - * @is_volatile: Control is volatile. - * @is_read_only: Control is read-only. - * @can_store: Control uses configuration stores. - * - * See also struct v4l2_ctrl_config. - */ -struct rockchip_vpu_control { - u32 id; - - enum v4l2_ctrl_type type; - const char *name; - s32 minimum; - s32 maximum; - s32 step; - u32 menu_skip_mask; - s32 default_value; - s32 max_stores; - u32 dims[V4L2_CTRL_MAX_DIMS]; - u32 elem_size; - - bool is_volatile:1; - bool is_read_only:1; - bool can_store:1; -}; - -/* Logging helpers */ - -/** - * debug - Module parameter to control level of debugging messages. - * - * Level of debugging messages can be controlled by bits of module parameter - * called "debug". Meaning of particular bits is as follows: - * - * bit 0 - global information: mode, size, init, release - * bit 1 - each run start/result information - * bit 2 - contents of small controls from userspace - * bit 3 - contents of big controls from userspace - * bit 4 - detail fmt, ctrl, buffer q/dq information - * bit 5 - detail function enter/leave trace information - * bit 6 - register write/read information - */ -extern int debug; - -#define vpu_debug(level, fmt, args...) \ - do { \ - if (debug & BIT(level)) \ - pr_debug("%s:%d: " fmt, \ - __func__, __LINE__, ##args); \ - } while (0) - -#define vpu_debug_enter() vpu_debug(5, "enter\n") -#define vpu_debug_leave() vpu_debug(5, "leave\n") - -#define vpu_err(fmt, args...) \ - pr_err("%s:%d: " fmt, __func__, __LINE__, ##args) - -static inline char *fmt2str(u32 fmt, char *str) -{ - char a = fmt & 0xFF; - char b = (fmt >> 8) & 0xFF; - char c = (fmt >> 16) & 0xFF; - char d = (fmt >> 24) & 0xFF; - - sprintf(str, "%c%c%c%c", a, b, c, d); - - return str; -} - -/* Structure access helpers. */ -static inline struct rockchip_vpu_ctx *fh_to_ctx(struct v4l2_fh *fh) -{ - return container_of(fh, struct rockchip_vpu_ctx, fh); -} - -static inline struct rockchip_vpu_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl) -{ - return container_of(ctrl->handler, - struct rockchip_vpu_ctx, ctrl_handler); -} - -static inline struct rockchip_vpu_buf *vb_to_buf(struct vb2_buffer *vb) -{ - return container_of(to_vb2_v4l2_buffer(vb), - struct rockchip_vpu_buf, vb); -} - -static inline bool rockchip_vpu_ctx_is_encoder(struct rockchip_vpu_ctx *ctx) -{ - return ctx->vpu_dst_fmt->codec_mode != RK_VPU_CODEC_NONE; -} - -static inline bool -rockchip_vpu_ctx_is_dummy_encode(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *dev = ctx->dev; - - return ctx == dev->dummy_encode_ctx; -} - -static inline bool -rockchip_vpu_dev_codec_support(struct rockchip_vpu_dev *dev, - enum rockchip_vpu_codec_mode codec_mode) -{ - return !!(codec_mode & dev->variant->codecs); -} - -int rockchip_vpu_ctrls_setup(struct rockchip_vpu_ctx *ctx, - const struct v4l2_ctrl_ops *ctrl_ops, - struct rockchip_vpu_control *controls, - unsigned num_ctrls, - const char *const *(*get_menu)(u32)); -void rockchip_vpu_ctrls_delete(struct rockchip_vpu_ctx *ctx); - -void rockchip_vpu_try_context(struct rockchip_vpu_dev *dev, - struct rockchip_vpu_ctx *ctx); - -void rockchip_vpu_run_done(struct rockchip_vpu_ctx *ctx, - enum vb2_buffer_state result); - -int rockchip_vpu_aux_buf_alloc(struct rockchip_vpu_dev *vpu, - struct rockchip_vpu_aux_buf *buf, size_t size); -void rockchip_vpu_aux_buf_free(struct rockchip_vpu_dev *vpu, - struct rockchip_vpu_aux_buf *buf); - -/* Register accessors. */ -static inline void vepu_write_relaxed(struct rockchip_vpu_dev *vpu, - u32 val, u32 reg) -{ - vpu_debug(6, "MARK: set reg[%03d]: %08x\n", reg / 4, val); - writel_relaxed(val, vpu->enc_base + reg); -} - -static inline void vepu_write(struct rockchip_vpu_dev *vpu, u32 val, u32 reg) -{ - vpu_debug(6, "MARK: set reg[%03d]: %08x\n", reg / 4, val); - writel(val, vpu->enc_base + reg); -} - -static inline u32 vepu_read(struct rockchip_vpu_dev *vpu, u32 reg) -{ - u32 val = readl(vpu->enc_base + reg); - - vpu_debug(6, "MARK: get reg[%03d]: %08x\n", reg / 4, val); - return val; -} - -static inline void vdpu_write_relaxed(struct rockchip_vpu_dev *vpu, - u32 val, u32 reg) -{ - vpu_debug(6, "MARK: set reg[%03d]: %08x\n", reg / 4, val); - writel_relaxed(val, vpu->dec_base + reg); -} - -static inline void vdpu_write(struct rockchip_vpu_dev *vpu, u32 val, u32 reg) -{ - vpu_debug(6, "MARK: set reg[%03d]: %08x\n", reg / 4, val); - writel(val, vpu->dec_base + reg); -} - -static inline u32 vdpu_read(struct rockchip_vpu_dev *vpu, u32 reg) -{ - u32 val = readl(vpu->dec_base + reg); - - vpu_debug(6, "MARK: get reg[%03d]: %08x\n", reg / 4, val); - return val; -} - -#endif /* ROCKCHIP_VPU_COMMON_H_ */ diff --git a/drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.c b/drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.c deleted file mode 100644 index e1e1452de6f7..000000000000 --- a/drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.c +++ /dev/null @@ -1,1164 +0,0 @@ -/* - * Rockchip VPU codec driver - * - * Copyright (C) 2014 Rockchip Electronics Co., Ltd. - * Hertz Wong - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. - * - * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "rockchip_vpu_common.h" - -#include -#include -#include - -#include -#include -#include -#include - -#include "rockchip_vpu_dec.h" -#include "rockchip_vpu_hw.h" - -#define DEF_SRC_FMT_DEC V4L2_PIX_FMT_H264_SLICE -#define DEF_DST_FMT_DEC V4L2_PIX_FMT_NV12 - -#define ROCKCHIP_DEC_MIN_WIDTH 48U -#define ROCKCHIP_DEC_MAX_WIDTH 3840U -#define ROCKCHIP_DEC_MIN_HEIGHT 48U -#define ROCKCHIP_DEC_MAX_HEIGHT 2160U - -#define ROCKCHIP_H264_MAX_SLICES_PER_FRAME 16 - -static struct rockchip_vpu_fmt formats[] = { - { - .name = "4:2:0 1 plane Y/CbCr", - .fourcc = V4L2_PIX_FMT_NV12, - .codec_mode = RK_VPU_CODEC_NONE, - .num_planes = 1, - .depth = { 12 }, - }, - { - .name = "Slices of H264 Encoded Stream(RK3288)", - .fourcc = V4L2_PIX_FMT_H264_SLICE, - .codec_mode = RK3288_VPU_CODEC_H264D, - .num_planes = 1, - }, - { - .name = "Frames of VP8 Encoded Stream(RK3288)", - .fourcc = V4L2_PIX_FMT_VP8_FRAME, - .codec_mode = RK3288_VPU_CODEC_VP8D, - .num_planes = 1, - }, -}; - -static struct rockchip_vpu_fmt *find_format(struct rockchip_vpu_dev *dev, - u32 fourcc, bool bitstream) -{ - unsigned int i; - - vpu_debug_enter(); - - for (i = 0; i < ARRAY_SIZE(formats); i++) { - if (!rockchip_vpu_dev_codec_support(dev, formats[i].codec_mode)) - continue; - if (formats[i].fourcc == fourcc && - !!bitstream == (formats[i].codec_mode != RK_VPU_CODEC_NONE)) - return &formats[i]; - } - - return NULL; -} - -/* Indices of controls that need to be accessed directly. */ -enum { - ROCKCHIP_VPU_DEC_CTRL_H264_SPS, - ROCKCHIP_VPU_DEC_CTRL_H264_PPS, - ROCKCHIP_VPU_DEC_CTRL_H264_SCALING_MATRIX, - ROCKCHIP_VPU_DEC_CTRL_H264_SLICE_PARAM, - ROCKCHIP_VPU_DEC_CTRL_H264_DECODE_PARAM, - ROCKCHIP_VPU_DEC_CTRL_VP8_FRAME_HDR, -}; - -static struct rockchip_vpu_control controls[] = { - /* H264 slice-based interface. */ - [ROCKCHIP_VPU_DEC_CTRL_H264_SPS] = { - .id = V4L2_CID_MPEG_VIDEO_H264_SPS, - .type = V4L2_CTRL_TYPE_PRIVATE, - .name = "H264 SPS Parameters", - .elem_size = sizeof(struct v4l2_ctrl_h264_sps), - .max_stores = VIDEO_MAX_FRAME, - .can_store = true, - }, - [ROCKCHIP_VPU_DEC_CTRL_H264_PPS] = { - .id = V4L2_CID_MPEG_VIDEO_H264_PPS, - .type = V4L2_CTRL_TYPE_PRIVATE, - .name = "H264 PPS Parameters", - .elem_size = sizeof(struct v4l2_ctrl_h264_pps), - .max_stores = VIDEO_MAX_FRAME, - .can_store = true, - }, - [ROCKCHIP_VPU_DEC_CTRL_H264_SCALING_MATRIX] = { - .id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX, - .type = V4L2_CTRL_TYPE_PRIVATE, - .name = "H264 Scaling Matrix", - .elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix), - .max_stores = VIDEO_MAX_FRAME, - .can_store = true, - }, - [ROCKCHIP_VPU_DEC_CTRL_H264_SLICE_PARAM] = { - .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAM, - .type = V4L2_CTRL_TYPE_PRIVATE, - .name = "H264 Slice Parameters", - .max_stores = VIDEO_MAX_FRAME, - .elem_size = sizeof(struct v4l2_ctrl_h264_slice_param), - .dims = { ROCKCHIP_H264_MAX_SLICES_PER_FRAME, }, - .can_store = true, - }, - [ROCKCHIP_VPU_DEC_CTRL_H264_DECODE_PARAM] = { - .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAM, - .type = V4L2_CTRL_TYPE_PRIVATE, - .name = "H264 Decode Parameters", - .max_stores = VIDEO_MAX_FRAME, - .elem_size = sizeof(struct v4l2_ctrl_h264_decode_param), - .can_store = true, - }, - [ROCKCHIP_VPU_DEC_CTRL_VP8_FRAME_HDR] = { - .id = V4L2_CID_MPEG_VIDEO_VP8_FRAME_HDR, - .type = V4L2_CTRL_TYPE_PRIVATE, - .name = "VP8 Frame Header Parameters", - .max_stores = VIDEO_MAX_FRAME, - .elem_size = sizeof(struct v4l2_ctrl_vp8_frame_hdr), - .can_store = true, - }, -}; - -static inline const void *get_ctrl_ptr(struct rockchip_vpu_ctx *ctx, unsigned id) -{ - struct v4l2_ctrl *ctrl = ctx->ctrls[id]; - - return ctrl->p_cur.p; -} - -/* Query capabilities of the device */ -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct rockchip_vpu_dev *dev = video_drvdata(file); - - vpu_debug_enter(); - - strlcpy(cap->driver, ROCKCHIP_VPU_DEC_NAME, sizeof(cap->driver)); - strlcpy(cap->card, dev->pdev->name, sizeof(cap->card)); - strlcpy(cap->bus_info, "platform:" ROCKCHIP_VPU_NAME, - sizeof(cap->bus_info)); - - /* - * This is only a mem-to-mem video device. The capture and output - * device capability flags are left only for backward compatibility - * and are scheduled for removal. - */ - cap->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING | - V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - - vpu_debug_leave(); - - return 0; -} - -static int vidioc_enum_framesizes(struct file *file, void *prov, - struct v4l2_frmsizeenum *fsize) -{ - struct rockchip_vpu_dev *dev = video_drvdata(file); - struct v4l2_frmsize_stepwise *s = &fsize->stepwise; - struct rockchip_vpu_fmt *fmt; - - if (fsize->index != 0) { - vpu_debug(0, "invalid frame size index (expected 0, got %d)\n", - fsize->index); - return -EINVAL; - } - - fmt = find_format(dev, fsize->pixel_format, true); - if (!fmt) { - vpu_debug(0, "unsupported bitstream format (%08x)\n", - fsize->pixel_format); - return -EINVAL; - } - - fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; - - s->min_width = ROCKCHIP_DEC_MIN_WIDTH; - s->max_width = ROCKCHIP_DEC_MAX_WIDTH; - s->step_width = MB_DIM; - s->min_height = ROCKCHIP_DEC_MIN_HEIGHT; - s->max_height = ROCKCHIP_DEC_MAX_HEIGHT; - s->step_height = MB_DIM; - - return 0; -} - -static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, bool out) -{ - struct rockchip_vpu_dev *dev = video_drvdata(file); - struct rockchip_vpu_fmt *fmt; - int i, j = 0; - - vpu_debug_enter(); - - for (i = 0; i < ARRAY_SIZE(formats); ++i) { - if (!rockchip_vpu_dev_codec_support(dev, formats[i].codec_mode)) - continue; - if (out && formats[i].codec_mode == RK_VPU_CODEC_NONE) - continue; - else if (!out && (formats[i].codec_mode != RK_VPU_CODEC_NONE)) - continue; - - if (j == f->index) { - fmt = &formats[i]; - strlcpy(f->description, fmt->name, - sizeof(f->description)); - f->pixelformat = fmt->fourcc; - - f->flags = 0; - if (formats[i].codec_mode != RK_VPU_CODEC_NONE) - f->flags |= V4L2_FMT_FLAG_COMPRESSED; - - vpu_debug_leave(); - - return 0; - } - - ++j; - } - - vpu_debug_leave(); - - return -EINVAL; -} - -static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - return vidioc_enum_fmt(file, f, false); -} - -static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - return vidioc_enum_fmt(file, f, true); -} - -static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - - vpu_debug_enter(); - - vpu_debug(4, "f->type = %d\n", f->type); - - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - f->fmt.pix_mp = ctx->dst_fmt; - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - f->fmt.pix_mp = ctx->src_fmt; - break; - - default: - vpu_err("invalid buf type\n"); - return -EINVAL; - } - - vpu_debug_leave(); - - return 0; -} - -static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) -{ - struct rockchip_vpu_dev *dev = video_drvdata(file); - struct rockchip_vpu_fmt *fmt; - struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; - char str[5]; - - vpu_debug_enter(); - - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - vpu_debug(4, "%s\n", fmt2str(f->fmt.pix_mp.pixelformat, str)); - - fmt = find_format(dev, pix_fmt_mp->pixelformat, true); - if (!fmt) { - vpu_err("failed to try output format\n"); - return -EINVAL; - } - - if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { - vpu_err("sizeimage of output format must be given\n"); - return -EINVAL; - } - - pix_fmt_mp->plane_fmt[0].bytesperline = 0; - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - vpu_debug(4, "%s\n", fmt2str(f->fmt.pix_mp.pixelformat, str)); - - fmt = find_format(dev, pix_fmt_mp->pixelformat, false); - if (!fmt) { - vpu_err("failed to try capture format\n"); - return -EINVAL; - } - - if (fmt->num_planes != pix_fmt_mp->num_planes) { - vpu_err("plane number mismatches on capture format\n"); - return -EINVAL; - } - - /* Limit to hardware min/max. */ - pix_fmt_mp->width = clamp(pix_fmt_mp->width, - ROCKCHIP_DEC_MIN_WIDTH, ROCKCHIP_DEC_MAX_WIDTH); - pix_fmt_mp->height = clamp(pix_fmt_mp->height, - ROCKCHIP_DEC_MIN_HEIGHT, ROCKCHIP_DEC_MAX_HEIGHT); - - /* Round up to macroblocks. */ - pix_fmt_mp->width = round_up(pix_fmt_mp->width, MB_DIM); - pix_fmt_mp->height = round_up(pix_fmt_mp->height, MB_DIM); - break; - - default: - vpu_err("invalid buf type\n"); - return -EINVAL; - } - - vpu_debug_leave(); - - return 0; -} - -static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) -{ - struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - struct rockchip_vpu_dev *dev = ctx->dev; - unsigned int mb_width, mb_height; - struct rockchip_vpu_fmt *fmt; - int ret = 0; - int i; - - vpu_debug_enter(); - - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - /* Change not allowed if any queue is streaming. */ - if (vb2_is_streaming(&ctx->vq_src) - || vb2_is_streaming(&ctx->vq_dst)) { - ret = -EBUSY; - goto out; - } - /* - * Pixel format change is not allowed when the other queue has - * buffers allocated. - */ - if (vb2_is_busy(&ctx->vq_dst) - && pix_fmt_mp->pixelformat != ctx->src_fmt.pixelformat) { - ret = -EBUSY; - goto out; - } - - ret = vidioc_try_fmt(file, priv, f); - if (ret) - goto out; - - ctx->vpu_src_fmt = find_format(dev, pix_fmt_mp->pixelformat, true); - ctx->src_fmt = *pix_fmt_mp; - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - /* - * Change not allowed if this queue is streaming. - * - * NOTE: We allow changes with source queue streaming - * to support resolution change in decoded stream. - */ - if (vb2_is_streaming(&ctx->vq_dst)) { - ret = -EBUSY; - goto out; - } - /* - * Pixel format change is not allowed when the other queue has - * buffers allocated. - */ - if (vb2_is_busy(&ctx->vq_src) - && pix_fmt_mp->pixelformat != ctx->dst_fmt.pixelformat) { - ret = -EBUSY; - goto out; - } - - ret = vidioc_try_fmt(file, priv, f); - if (ret) - goto out; - - fmt = find_format(dev, pix_fmt_mp->pixelformat, false); - ctx->vpu_dst_fmt = fmt; - - mb_width = MB_WIDTH(pix_fmt_mp->width); - mb_height = MB_HEIGHT(pix_fmt_mp->height); - - vpu_debug(0, "CAPTURE codec mode: %d\n", fmt->codec_mode); - vpu_debug(0, "fmt - w: %d, h: %d, mb - w: %d, h: %d\n", - pix_fmt_mp->width, pix_fmt_mp->height, - mb_width, mb_height); - - for (i = 0; i < fmt->num_planes; ++i) { - pix_fmt_mp->plane_fmt[i].bytesperline = - mb_width * MB_DIM * fmt->depth[i] / 8; - pix_fmt_mp->plane_fmt[i].sizeimage = - pix_fmt_mp->plane_fmt[i].bytesperline - * mb_height * MB_DIM; - /* - * All of multiplanar formats we support have chroma - * planes subsampled by 2. - */ - if (i != 0) - pix_fmt_mp->plane_fmt[i].sizeimage /= 2; - } - - ctx->dst_fmt = *pix_fmt_mp; - break; - - default: - vpu_err("invalid buf type\n"); - return -EINVAL; - } - -out: - vpu_debug_leave(); - - return ret; -} - -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *reqbufs) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (reqbufs->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_reqbufs(&ctx->vq_src, reqbufs); - if (ret != 0) { - vpu_err("error in vb2_reqbufs() for E(S)\n"); - goto out; - } - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); - if (ret != 0) { - vpu_err("error in vb2_reqbufs() for E(D)\n"); - goto out; - } - break; - - default: - vpu_err("invalid buf type\n"); - ret = -EINVAL; - goto out; - } - -out: - vpu_debug_leave(); - - return ret; -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (buf->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_querybuf(&ctx->vq_dst, buf); - if (ret != 0) { - vpu_err("error in vb2_querybuf() for E(D)\n"); - goto out; - } - - buf->m.planes[0].m.mem_offset += DST_QUEUE_OFF_BASE; - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_querybuf(&ctx->vq_src, buf); - if (ret != 0) { - vpu_err("error in vb2_querybuf() for E(S)\n"); - goto out; - } - break; - - default: - vpu_err("invalid buf type\n"); - ret = -EINVAL; - goto out; - } - -out: - vpu_debug_leave(); - - return ret; -} - -/* Queue a buffer */ -static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - int i; - - vpu_debug_enter(); - - for (i = 0; i < buf->length; i++) - vpu_debug(4, "plane[%d]->length %d bytesused %d\n", - i, buf->m.planes[i].length, - buf->m.planes[i].bytesused); - - switch (buf->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_qbuf(&ctx->vq_src, buf); - vpu_debug(4, "OUTPUT_MPLANE : vb2_qbuf return %d\n", ret); - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_qbuf(&ctx->vq_dst, buf); - vpu_debug(4, "CAPTURE_MPLANE: vb2_qbuf return %d\n", ret); - break; - - default: - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -/* Dequeue a buffer */ -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (buf->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK); - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK); - break; - - default: - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -/* Export DMA buffer */ -static int vidioc_expbuf(struct file *file, void *priv, - struct v4l2_exportbuffer *eb) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (eb->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_expbuf(&ctx->vq_src, eb); - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_expbuf(&ctx->vq_dst, eb); - break; - - default: - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -/* Stream on */ -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_streamon(&ctx->vq_src, type); - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_streamon(&ctx->vq_dst, type); - break; - - default: - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -/* Stream off, which equals to a pause */ -static int vidioc_streamoff(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_streamoff(&ctx->vq_src, type); - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_streamoff(&ctx->vq_dst, type); - break; - - default: - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static void rockchip_vpu_dec_set_dpb(struct rockchip_vpu_ctx *ctx, - struct v4l2_ctrl *ctrl) -{ - struct v4l2_ctrl_h264_decode_param *dec_param = ctrl->p_new.p; - const struct v4l2_h264_dpb_entry *new_dpb_entry; - u8 *dpb_map = ctx->run.h264d.dpb_map; - struct v4l2_h264_dpb_entry *cur_dpb_entry; - DECLARE_BITMAP(used, ARRAY_SIZE(ctx->run.h264d.dpb)) = { 0, }; - DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, }; - int i, j; - - BUILD_BUG_ON(ARRAY_SIZE(ctx->run.h264d.dpb) != - ARRAY_SIZE(dec_param->dpb)); - - /* Disable all entries by default. */ - for (j = 0; j < ARRAY_SIZE(ctx->run.h264d.dpb); ++j) { - cur_dpb_entry = &ctx->run.h264d.dpb[j]; - - cur_dpb_entry->flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE; - } - - /* Try to match new DPB entries with existing ones by their POCs. */ - for (i = 0; i < ARRAY_SIZE(dec_param->dpb); ++i) { - new_dpb_entry = &dec_param->dpb[i]; - - if (!(new_dpb_entry->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) - continue; - - /* - * To cut off some comparisons, iterate only on target DPB - * entries which are not used yet. - */ - for_each_clear_bit(j, used, ARRAY_SIZE(ctx->run.h264d.dpb)) { - cur_dpb_entry = &ctx->run.h264d.dpb[j]; - - if (new_dpb_entry->top_field_order_cnt == - cur_dpb_entry->top_field_order_cnt && - new_dpb_entry->bottom_field_order_cnt == - cur_dpb_entry->bottom_field_order_cnt) { - memcpy(cur_dpb_entry, new_dpb_entry, - sizeof(*cur_dpb_entry)); - set_bit(j, used); - dpb_map[i] = j; - break; - } - } - - if (j == ARRAY_SIZE(ctx->run.h264d.dpb)) - set_bit(i, new); - } - - /* For entries that could not be matched, use remaining free slots. */ - for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) { - new_dpb_entry = &dec_param->dpb[i]; - - j = find_first_zero_bit(used, ARRAY_SIZE(ctx->run.h264d.dpb)); - /* - * Both arrays are of the same sizes, so there is no way - * we can end up with no space in target array, unless - * something is buggy. - */ - if (WARN_ON(j >= ARRAY_SIZE(ctx->run.h264d.dpb))) - return; - - cur_dpb_entry = &ctx->run.h264d.dpb[j]; - memcpy(cur_dpb_entry, new_dpb_entry, sizeof(*cur_dpb_entry)); - set_bit(j, used); - dpb_map[i] = j; - } - - /* - * Verify that reference picture lists are in range, since they - * will be indexing dpb_map[] when programming the hardware. - * - * Fallback to 0 should be safe, as we will get at most corrupt - * decoding result, without any serious side effects. Moreover, - * even if entry 0 is unused, the hardware programming code will - * handle this properly. - */ - for (i = 0; i < ARRAY_SIZE(dec_param->ref_pic_list_b0); ++i) - if (dec_param->ref_pic_list_b0[i] - >= ARRAY_SIZE(ctx->run.h264d.dpb_map)) - dec_param->ref_pic_list_b0[i] = 0; - for (i = 0; i < ARRAY_SIZE(dec_param->ref_pic_list_b1); ++i) - if (dec_param->ref_pic_list_b1[i] - >= ARRAY_SIZE(ctx->run.h264d.dpb_map)) - dec_param->ref_pic_list_b1[i] = 0; - for (i = 0; i < ARRAY_SIZE(dec_param->ref_pic_list_p0); ++i) - if (dec_param->ref_pic_list_p0[i] - >= ARRAY_SIZE(ctx->run.h264d.dpb_map)) - dec_param->ref_pic_list_p0[i] = 0; -} - -static int rockchip_vpu_dec_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct rockchip_vpu_ctx *ctx = ctrl_to_ctx(ctrl); - struct rockchip_vpu_dev *dev = ctx->dev; - int ret = 0; - - vpu_debug_enter(); - - vpu_debug(4, "ctrl id %d\n", ctrl->id); - - switch (ctrl->id) { - case V4L2_CID_MPEG_VIDEO_H264_SPS: - case V4L2_CID_MPEG_VIDEO_H264_PPS: - case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX: - case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAM: - case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HDR: - /* These controls are used directly. */ - break; - - case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAM: - if (ctrl->store) - break; - rockchip_vpu_dec_set_dpb(ctx, ctrl); - break; - - default: - v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n", - ctrl->id, ctrl->val); - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static const struct v4l2_ctrl_ops rockchip_vpu_dec_ctrl_ops = { - .s_ctrl = rockchip_vpu_dec_s_ctrl, -}; - -static const struct v4l2_ioctl_ops rockchip_vpu_dec_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_framesizes = vidioc_enum_framesizes, - .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane, - .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane, - .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt, - .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt, - .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt, - .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt, - .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt, - .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_expbuf = vidioc_expbuf, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, -}; - -static int rockchip_vpu_queue_setup(struct vb2_queue *vq, - const void *parg, - unsigned int *buf_count, - unsigned int *plane_count, - unsigned int psize[], void *allocators[]) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(vq->drv_priv); - int ret = 0; - - vpu_debug_enter(); - - switch (vq->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - *plane_count = ctx->vpu_src_fmt->num_planes; - - if (*buf_count < 1) - *buf_count = 1; - - if (*buf_count > VIDEO_MAX_FRAME) - *buf_count = VIDEO_MAX_FRAME; - - psize[0] = ctx->src_fmt.plane_fmt[0].sizeimage; - allocators[0] = ctx->dev->alloc_ctx; - vpu_debug(0, "output psize[%d]: %d\n", 0, psize[0]); - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - *plane_count = ctx->vpu_dst_fmt->num_planes; - - if (*buf_count < 1) - *buf_count = 1; - - if (*buf_count > VIDEO_MAX_FRAME) - *buf_count = VIDEO_MAX_FRAME; - - psize[0] = round_up(ctx->dst_fmt.plane_fmt[0].sizeimage, 8); - allocators[0] = ctx->dev->alloc_ctx; - - if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE) - /* Add space for appended motion vectors. */ - psize[0] += 64 * MB_WIDTH(ctx->dst_fmt.width) - * MB_HEIGHT(ctx->dst_fmt.height); - - vpu_debug(0, "capture psize[%d]: %d\n", 0, psize[0]); - break; - - default: - vpu_err("invalid queue type: %d\n", vq->type); - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static int rockchip_vpu_buf_init(struct vb2_buffer *vb) -{ - struct vb2_queue *vq = vb->vb2_queue; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(vq->drv_priv); - - vpu_debug_enter(); - - if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - ctx->dst_bufs[vb->index] = vb; - - vpu_debug_leave(); - - return 0; -} - -static void rockchip_vpu_buf_cleanup(struct vb2_buffer *vb) -{ - struct vb2_queue *vq = vb->vb2_queue; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(vq->drv_priv); - - vpu_debug_enter(); - - if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - ctx->dst_bufs[vb->index] = NULL; - - vpu_debug_leave(); -} - -static int rockchip_vpu_buf_prepare(struct vb2_buffer *vb) -{ - struct vb2_queue *vq = vb->vb2_queue; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(vq->drv_priv); - int ret = 0; - int i; - - vpu_debug_enter(); - - switch (vq->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - vpu_debug(4, "plane size: %ld, dst size: %d\n", - vb2_plane_size(vb, 0), - ctx->src_fmt.plane_fmt[0].sizeimage); - - if (vb2_plane_size(vb, 0) - < ctx->src_fmt.plane_fmt[0].sizeimage) { - vpu_err("plane size is too small for output\n"); - ret = -EINVAL; - } - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - for (i = 0; i < ctx->vpu_dst_fmt->num_planes; ++i) { - vpu_debug(4, "plane %d size: %ld, sizeimage: %u\n", i, - vb2_plane_size(vb, i), - ctx->dst_fmt.plane_fmt[i].sizeimage); - - if (vb2_plane_size(vb, i) - < ctx->dst_fmt.plane_fmt[i].sizeimage) { - vpu_err("size of plane %d is too small for capture\n", - i); - break; - } - } - - if (i != ctx->vpu_dst_fmt->num_planes) - ret = -EINVAL; - break; - - default: - vpu_err("invalid queue type: %d\n", vq->type); - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static int rockchip_vpu_start_streaming(struct vb2_queue *q, unsigned int count) -{ - int ret = 0; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(q->drv_priv); - struct rockchip_vpu_dev *dev = ctx->dev; - bool ready = false; - - vpu_debug_enter(); - - if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - ret = rockchip_vpu_init(ctx); - if (ret < 0) { - vpu_err("rockchip_vpu_init failed\n"); - return ret; - } - - ready = vb2_is_streaming(&ctx->vq_src); - } else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - ready = vb2_is_streaming(&ctx->vq_dst); - } - - if (ready) - rockchip_vpu_try_context(dev, ctx); - - vpu_debug_leave(); - - return 0; -} - -static void rockchip_vpu_stop_streaming(struct vb2_queue *q) -{ - unsigned long flags; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(q->drv_priv); - struct rockchip_vpu_dev *dev = ctx->dev; - struct rockchip_vpu_buf *b; - LIST_HEAD(queue); - int i; - - vpu_debug_enter(); - - spin_lock_irqsave(&dev->irqlock, flags); - - list_del_init(&ctx->list); - - switch (q->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - list_splice_init(&ctx->dst_queue, &queue); - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - list_splice_init(&ctx->src_queue, &queue); - break; - - default: - break; - } - - spin_unlock_irqrestore(&dev->irqlock, flags); - - wait_event(dev->run_wq, dev->current_ctx != ctx); - - while (!list_empty(&queue)) { - b = list_first_entry(&queue, struct rockchip_vpu_buf, list); - for (i = 0; i < b->vb.vb2_buf.num_planes; i++) - vb2_set_plane_payload(&b->vb.vb2_buf, i, 0); - vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR); - list_del(&b->list); - } - - if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - rockchip_vpu_deinit(ctx); - - vpu_debug_leave(); -} - -static void rockchip_vpu_buf_queue(struct vb2_buffer *vb) -{ - struct vb2_queue *vq = vb->vb2_queue; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(vq->drv_priv); - struct rockchip_vpu_dev *dev = ctx->dev; - struct rockchip_vpu_buf *vpu_buf; - unsigned long flags; - - vpu_debug_enter(); - - switch (vq->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - vpu_buf = vb_to_buf(vb); - - /* Mark destination as available for use by VPU */ - spin_lock_irqsave(&dev->irqlock, flags); - - list_add_tail(&vpu_buf->list, &ctx->dst_queue); - - spin_unlock_irqrestore(&dev->irqlock, flags); - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - vpu_buf = vb_to_buf(vb); - - spin_lock_irqsave(&dev->irqlock, flags); - - list_add_tail(&vpu_buf->list, &ctx->src_queue); - - spin_unlock_irqrestore(&dev->irqlock, flags); - break; - - default: - vpu_err("unsupported buffer type (%d)\n", vq->type); - } - - if (vb2_is_streaming(&ctx->vq_src) && vb2_is_streaming(&ctx->vq_dst)) - rockchip_vpu_try_context(dev, ctx); - - vpu_debug_leave(); -} - -static struct vb2_ops rockchip_vpu_dec_qops = { - .queue_setup = rockchip_vpu_queue_setup, - .wait_prepare = vb2_ops_wait_prepare, - .wait_finish = vb2_ops_wait_finish, - .buf_init = rockchip_vpu_buf_init, - .buf_prepare = rockchip_vpu_buf_prepare, - .buf_cleanup = rockchip_vpu_buf_cleanup, - .start_streaming = rockchip_vpu_start_streaming, - .stop_streaming = rockchip_vpu_stop_streaming, - .buf_queue = rockchip_vpu_buf_queue, -}; - -struct vb2_ops *get_dec_queue_ops(void) -{ - return &rockchip_vpu_dec_qops; -} - -const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void) -{ - return &rockchip_vpu_dec_ioctl_ops; -} - -static void rockchip_vpu_dec_prepare_run(struct rockchip_vpu_ctx *ctx) -{ - struct vb2_v4l2_buffer *src = to_vb2_v4l2_buffer(&ctx->run.src->vb.vb2_buf); - - v4l2_ctrl_apply_store(&ctx->ctrl_handler, src->config_store); - - if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE) { - ctx->run.h264d.sps = get_ctrl_ptr(ctx, - ROCKCHIP_VPU_DEC_CTRL_H264_SPS); - ctx->run.h264d.pps = get_ctrl_ptr(ctx, - ROCKCHIP_VPU_DEC_CTRL_H264_PPS); - ctx->run.h264d.scaling_matrix = get_ctrl_ptr(ctx, - ROCKCHIP_VPU_DEC_CTRL_H264_SCALING_MATRIX); - ctx->run.h264d.slice_param = get_ctrl_ptr(ctx, - ROCKCHIP_VPU_DEC_CTRL_H264_SLICE_PARAM); - ctx->run.h264d.decode_param = get_ctrl_ptr(ctx, - ROCKCHIP_VPU_DEC_CTRL_H264_DECODE_PARAM); - } else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP8_FRAME) { - ctx->run.vp8d.frame_hdr = get_ctrl_ptr(ctx, - ROCKCHIP_VPU_DEC_CTRL_VP8_FRAME_HDR); - } -} - -static void rockchip_vpu_dec_run_done(struct rockchip_vpu_ctx *ctx, - enum vb2_buffer_state result) -{ - struct v4l2_plane_pix_format *plane_fmts = ctx->dst_fmt.plane_fmt; - struct vb2_buffer *dst = &ctx->run.dst->vb.vb2_buf; - int i; - - if (result != VB2_BUF_STATE_DONE) { - /* Assume no payload after failed run. */ - for (i = 0; i < dst->num_planes; ++i) - vb2_set_plane_payload(dst, i, 0); - return; - } - - for (i = 0; i < dst->num_planes; ++i) - vb2_set_plane_payload(dst, i, plane_fmts[i].sizeimage); -} - -static const struct rockchip_vpu_run_ops rockchip_vpu_dec_run_ops = { - .prepare_run = rockchip_vpu_dec_prepare_run, - .run_done = rockchip_vpu_dec_run_done, -}; - -int rockchip_vpu_dec_init(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - - ctx->vpu_src_fmt = find_format(vpu, DEF_SRC_FMT_DEC, false); - ctx->vpu_dst_fmt = find_format(vpu, DEF_DST_FMT_DEC, true); - - ctx->run_ops = &rockchip_vpu_dec_run_ops; - - return rockchip_vpu_ctrls_setup(ctx, &rockchip_vpu_dec_ctrl_ops, - controls, ARRAY_SIZE(controls), NULL); -} - -void rockchip_vpu_dec_exit(struct rockchip_vpu_ctx *ctx) -{ - rockchip_vpu_ctrls_delete(ctx); -} diff --git a/drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.h b/drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.h deleted file mode 100644 index 267a0893907a..000000000000 --- a/drivers/media/platform/rockchip-vpu/rockchip_vpu_dec.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Rockchip VPU codec driver - * - * Copyright (C) 2014 Rockchip Electronics Co., Ltd. - * Hertz Wong - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. - * - * Copyright (C) 2011 Samsung Electronics Co., Ltd. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef ROCKCHIP_VPU_DEC_H_ -#define ROCKCHIP_VPU_DEC_H_ - -struct vb2_ops *get_dec_queue_ops(void); -const struct v4l2_ioctl_ops *get_dec_v4l2_ioctl_ops(void); -struct rockchip_vpu_fmt *get_dec_def_fmt(bool src); -int rockchip_vpu_dec_init(struct rockchip_vpu_ctx *ctx); -void rockchip_vpu_dec_exit(struct rockchip_vpu_ctx *ctx); - -#endif /* ROCKCHIP_VPU_DEC_H_ */ diff --git a/drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.c b/drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.c deleted file mode 100644 index 91a555ea3c10..000000000000 --- a/drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.c +++ /dev/null @@ -1,1534 +0,0 @@ -/* - * Rockchip VPU codec driver - * - * Copyright (C) 2014 Rockchip Electronics Co., Ltd. - * Alpha Lin - * Jeffy Chen - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. - * - * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "rockchip_vpu_common.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rockchip_vpu_enc.h" -#include "rockchip_vpu_hw.h" - -#define DEF_SRC_FMT_ENC V4L2_PIX_FMT_NV12 -#define DEF_DST_FMT_ENC V4L2_PIX_FMT_VP8 - -#define ROCKCHIP_ENC_MIN_WIDTH 96U -#define ROCKCHIP_ENC_MAX_WIDTH 1920U -#define ROCKCHIP_ENC_MIN_HEIGHT 96U -#define ROCKCHIP_ENC_MAX_HEIGHT 1088U - -#define V4L2_CID_PRIVATE_ROCKCHIP_HEADER (V4L2_CID_CUSTOM_BASE + 0) -#define V4L2_CID_PRIVATE_ROCKCHIP_REG_PARAMS (V4L2_CID_CUSTOM_BASE + 1) -#define V4L2_CID_PRIVATE_ROCKCHIP_HW_PARAMS (V4L2_CID_CUSTOM_BASE + 2) -#define V4L2_CID_PRIVATE_ROCKCHIP_RET_PARAMS (V4L2_CID_CUSTOM_BASE + 3) - -static struct rockchip_vpu_fmt formats[] = { - /* Source formats. */ - { - .name = "4:2:0 3 planes Y/Cb/Cr", - .fourcc = V4L2_PIX_FMT_YUV420M, - .codec_mode = RK_VPU_CODEC_NONE, - .num_planes = 3, - .depth = { 8, 4, 4 }, - .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420P, - }, - { - .name = "4:2:0 2 plane Y/CbCr", - .fourcc = V4L2_PIX_FMT_NV12M, - .codec_mode = RK_VPU_CODEC_NONE, - .num_planes = 2, - .depth = { 8, 8 }, - .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUV420SP, - }, - { - .name = "4:2:2 1 plane YUYV", - .fourcc = V4L2_PIX_FMT_YUYV, - .codec_mode = RK_VPU_CODEC_NONE, - .num_planes = 1, - .depth = { 16 }, - .enc_fmt = ROCKCHIP_VPU_ENC_FMT_YUYV422, - }, - { - .name = "4:2:2 1 plane UYVY", - .fourcc = V4L2_PIX_FMT_UYVY, - .codec_mode = RK_VPU_CODEC_NONE, - .num_planes = 1, - .depth = { 16 }, - .enc_fmt = ROCKCHIP_VPU_ENC_FMT_UYVY422, - }, - /* Destination formats. */ - { - .name = "VP8 Encoded Stream", - .fourcc = V4L2_PIX_FMT_VP8, - .codec_mode = RK3288_VPU_CODEC_VP8E, - .num_planes = 1, - }, - { - .name = "H264 Encoded Stream", - .fourcc = V4L2_PIX_FMT_H264, - .codec_mode = RK3288_VPU_CODEC_H264E, - .num_planes = 1, - }, -}; - -static struct rockchip_vpu_fmt *find_format(struct rockchip_vpu_dev *dev, u32 fourcc, bool bitstream) -{ - unsigned int i; - - vpu_debug_enter(); - - for (i = 0; i < ARRAY_SIZE(formats); i++) { - if (!rockchip_vpu_dev_codec_support(dev, formats[i].codec_mode)) - continue; - if (formats[i].fourcc != fourcc) - continue; - if (bitstream && formats[i].codec_mode != RK_VPU_CODEC_NONE) - return &formats[i]; - if (!bitstream && formats[i].codec_mode == RK_VPU_CODEC_NONE) - return &formats[i]; - } - - return NULL; -} - -/* - * Indices of controls that need to be accessed directly, i.e. through - * p_cur.p pointer of their v4l2_ctrl structs. - */ -enum { - ROCKCHIP_VPU_ENC_CTRL_HEADER, - ROCKCHIP_VPU_ENC_CTRL_REG_PARAMS, - ROCKCHIP_VPU_ENC_CTRL_HW_PARAMS, - ROCKCHIP_VPU_ENC_CTRL_RET_PARAMS, -}; - -static struct rockchip_vpu_control controls[] = { - /* Private, per-frame controls. */ - [ROCKCHIP_VPU_ENC_CTRL_HEADER] = { - .id = V4L2_CID_PRIVATE_ROCKCHIP_HEADER, - .type = V4L2_CTRL_TYPE_PRIVATE, - .name = "Rockchip Private Header", - .elem_size = ROCKCHIP_HEADER_SIZE, - .max_stores = VIDEO_MAX_FRAME, - .can_store = true, - }, - [ROCKCHIP_VPU_ENC_CTRL_REG_PARAMS] = { - .id = V4L2_CID_PRIVATE_ROCKCHIP_REG_PARAMS, - .type = V4L2_CTRL_TYPE_PRIVATE, - .name = "Rockchip Private Reg Params", - .elem_size = sizeof(struct rockchip_reg_params), - .max_stores = VIDEO_MAX_FRAME, - .can_store = true, - }, - [ROCKCHIP_VPU_ENC_CTRL_HW_PARAMS] = { - .id = V4L2_CID_PRIVATE_ROCKCHIP_HW_PARAMS, - .type = V4L2_CTRL_TYPE_PRIVATE, - .name = "Rockchip Private Hw Params", - .elem_size = ROCKCHIP_HW_PARAMS_SIZE, - .max_stores = VIDEO_MAX_FRAME, - .can_store = true, - }, - [ROCKCHIP_VPU_ENC_CTRL_RET_PARAMS] = { - .id = V4L2_CID_PRIVATE_ROCKCHIP_RET_PARAMS, - .type = V4L2_CTRL_TYPE_PRIVATE, - .name = "Rockchip Private Ret Params", - .is_volatile = true, - .is_read_only = true, - .max_stores = VIDEO_MAX_FRAME, - .elem_size = ROCKCHIP_RET_PARAMS_SIZE, - }, - /* Generic controls. (currently ignored) */ - { - .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 1, - .maximum = 150, - .step = 1, - .default_value = 30, - }, - { - .id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_BITRATE, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 10000, - .maximum = 288000000, - .step = 1, - .default_value = 2097152, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_PROFILE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, - .maximum = V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH, - .default_value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, - .menu_skip_mask = ~( - (1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | - (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | - (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) - ), - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_LEVEL, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_4_1, - .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 30, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 18, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 288000, - .step = 1, - .default_value = 30000, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, - .type = V4L2_CTRL_TYPE_BUTTON, - }, - /* - * This hardware does not support features provided by controls - * below, but they are required for compatibility with certain - * userspace software. - */ - { - .id = V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Rate Control Reaction Coeff.", - .minimum = 1, - .maximum = (1 << 16) - 1, - .step = 1, - .default_value = 1, - }, - { - .id = V4L2_CID_MPEG_VIDEO_HEADER_MODE, - .type = V4L2_CTRL_TYPE_MENU, - .minimum = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE, - .maximum = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, - .default_value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Fixed Target Bit Enable", - .minimum = 0, - .maximum = 1, - .default_value = 0, - .step = 1, - .menu_skip_mask = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_B_FRAMES, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 2, - .step = 1, - .default_value = 0, - }, - { - .id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, - .type = V4L2_CTRL_TYPE_INTEGER, - .minimum = 0, - .maximum = 51, - .step = 1, - .default_value = 1, - }, -}; - -static inline const void *get_ctrl_ptr(struct rockchip_vpu_ctx *ctx, unsigned id) -{ - struct v4l2_ctrl *ctrl = ctx->ctrls[id]; - - return ctrl->p_cur.p; -} - -static const char *const *rockchip_vpu_enc_get_menu(u32 id) -{ - static const char *const vpu_video_frame_skip[] = { - "Disabled", - "Level Limit", - "VBV/CPB Limit", - NULL, - }; - - switch (id) { - case V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE: - return vpu_video_frame_skip; - } - - return NULL; -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct rockchip_vpu_dev *dev = video_drvdata(file); - - vpu_debug_enter(); - - strlcpy(cap->driver, ROCKCHIP_VPU_ENC_NAME, sizeof(cap->driver)); - strlcpy(cap->card, dev->pdev->name, sizeof(cap->card)); - strlcpy(cap->bus_info, "platform:" ROCKCHIP_VPU_NAME, - sizeof(cap->bus_info)); - - /* - * This is only a mem-to-mem video device. The capture and output - * device capability flags are left only for backward compatibility - * and are scheduled for removal. - */ - cap->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING | - V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - - vpu_debug_leave(); - - return 0; -} - -static int vidioc_enum_framesizes(struct file *file, void *prov, - struct v4l2_frmsizeenum *fsize) -{ - struct rockchip_vpu_dev *dev = video_drvdata(file); - struct v4l2_frmsize_stepwise *s = &fsize->stepwise; - struct rockchip_vpu_fmt *fmt; - - if (fsize->index != 0) { - vpu_debug(0, "invalid frame size index (expected 0, got %d)\n", - fsize->index); - return -EINVAL; - } - - fmt = find_format(dev, fsize->pixel_format, true); - if (!fmt) { - vpu_debug(0, "unsupported bitstream format (%08x)\n", - fsize->pixel_format); - return -EINVAL; - } - - fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; - - s->min_width = ROCKCHIP_ENC_MIN_WIDTH; - s->max_width = ROCKCHIP_ENC_MAX_WIDTH; - s->step_width = MB_DIM; - s->min_height = ROCKCHIP_ENC_MIN_HEIGHT; - s->max_height = ROCKCHIP_ENC_MAX_HEIGHT; - s->step_height = MB_DIM; - - return 0; -} - -static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, bool out) -{ - struct rockchip_vpu_dev *dev = video_drvdata(file); - struct rockchip_vpu_fmt *fmt; - int i, j = 0; - - vpu_debug_enter(); - - for (i = 0; i < ARRAY_SIZE(formats); ++i) { - if (!rockchip_vpu_dev_codec_support(dev, formats[i].codec_mode)) - continue; - if (out && formats[i].codec_mode != RK_VPU_CODEC_NONE) - continue; - else if (!out && formats[i].codec_mode == RK_VPU_CODEC_NONE) - continue; - - if (j == f->index) { - fmt = &formats[i]; - strlcpy(f->description, fmt->name, - sizeof(f->description)); - f->pixelformat = fmt->fourcc; - - f->flags = 0; - if (formats[i].codec_mode != RK_VPU_CODEC_NONE) - f->flags |= V4L2_FMT_FLAG_COMPRESSED; - - vpu_debug_leave(); - - return 0; - } - - ++j; - } - - vpu_debug_leave(); - - return -EINVAL; -} - -static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - return vidioc_enum_fmt(file, f, false); -} - -static int vidioc_enum_fmt_vid_out_mplane(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - return vidioc_enum_fmt(file, f, true); -} - -static int vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - - vpu_debug_enter(); - - vpu_debug(4, "f->type = %d\n", f->type); - - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - f->fmt.pix_mp = ctx->dst_fmt; - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - f->fmt.pix_mp = ctx->src_fmt; - break; - - default: - vpu_err("invalid buf type\n"); - return -EINVAL; - } - - vpu_debug_leave(); - - return 0; -} - -static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) -{ - struct rockchip_vpu_dev *dev = video_drvdata(file); - struct rockchip_vpu_fmt *fmt; - struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; - char str[5]; - - vpu_debug_enter(); - - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - vpu_debug(4, "%s\n", fmt2str(f->fmt.pix_mp.pixelformat, str)); - - fmt = find_format(dev, pix_fmt_mp->pixelformat, true); - if (!fmt) { - vpu_err("failed to try capture format\n"); - return -EINVAL; - } - - if (pix_fmt_mp->plane_fmt[0].sizeimage == 0) { - vpu_err("must be set encoding output size\n"); - return -EINVAL; - } - - pix_fmt_mp->plane_fmt[0].bytesperline = 0; - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - vpu_debug(4, "%s\n", fmt2str(f->fmt.pix_mp.pixelformat, str)); - - fmt = find_format(dev, pix_fmt_mp->pixelformat, false); - if (!fmt) { - vpu_err("failed to try output format\n"); - return -EINVAL; - } - - if (fmt->num_planes != pix_fmt_mp->num_planes) { - vpu_err("plane number mismatches on output format\n"); - return -EINVAL; - } - - /* Limit to hardware min/max. */ - pix_fmt_mp->width = clamp(pix_fmt_mp->width, - ROCKCHIP_ENC_MIN_WIDTH, ROCKCHIP_ENC_MAX_WIDTH); - pix_fmt_mp->height = clamp(pix_fmt_mp->height, - ROCKCHIP_ENC_MIN_HEIGHT, ROCKCHIP_ENC_MAX_HEIGHT); - /* Round up to macroblocks. */ - pix_fmt_mp->width = round_up(pix_fmt_mp->width, MB_DIM); - pix_fmt_mp->height = round_up(pix_fmt_mp->height, MB_DIM); - break; - - default: - vpu_err("invalid buf type\n"); - return -EINVAL; - } - - vpu_debug_leave(); - - return 0; -} - -static void calculate_plane_sizes(struct rockchip_vpu_fmt *fmt, - unsigned int w, unsigned int h, - struct v4l2_pix_format_mplane *pix_fmt_mp) -{ - int i; - - for (i = 0; i < fmt->num_planes; ++i) { - pix_fmt_mp->plane_fmt[i].bytesperline = w * fmt->depth[i] / 8; - pix_fmt_mp->plane_fmt[i].sizeimage = h * - pix_fmt_mp->plane_fmt[i].bytesperline; - /* - * All of multiplanar formats we support have chroma - * planes subsampled by 2 vertically. - */ - if (i != 0) - pix_fmt_mp->plane_fmt[i].sizeimage /= 2; - } -} - -static int vidioc_s_fmt(struct file *file, void *priv, struct v4l2_format *f) -{ - struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - struct rockchip_vpu_dev *dev = ctx->dev; - unsigned int mb_width, mb_height; - struct rockchip_vpu_fmt *fmt; - int ret = 0; - - vpu_debug_enter(); - - /* Change not allowed if any queue is streaming. */ - if (vb2_is_streaming(&ctx->vq_src) || vb2_is_streaming(&ctx->vq_dst)) { - ret = -EBUSY; - goto out; - } - - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - /* - * Pixel format change is not allowed when the other queue has - * buffers allocated. - */ - if (vb2_is_busy(&ctx->vq_src) - && pix_fmt_mp->pixelformat != ctx->dst_fmt.pixelformat) { - ret = -EBUSY; - goto out; - } - - ret = vidioc_try_fmt(file, priv, f); - if (ret) - goto out; - - ctx->vpu_dst_fmt = find_format(dev, pix_fmt_mp->pixelformat, true); - ctx->dst_fmt = *pix_fmt_mp; - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - /* - * Pixel format change is not allowed when the other queue has - * buffers allocated. - */ - if (vb2_is_busy(&ctx->vq_dst) - && pix_fmt_mp->pixelformat != ctx->src_fmt.pixelformat) { - ret = -EBUSY; - goto out; - } - - ret = vidioc_try_fmt(file, priv, f); - if (ret) - goto out; - - fmt = find_format(dev, pix_fmt_mp->pixelformat, false); - ctx->vpu_src_fmt = fmt; - - mb_width = MB_WIDTH(pix_fmt_mp->width); - mb_height = MB_HEIGHT(pix_fmt_mp->height); - - vpu_debug(0, "OUTPUT codec mode: %d\n", fmt->codec_mode); - vpu_debug(0, "fmt - w: %d, h: %d, mb - w: %d, h: %d\n", - pix_fmt_mp->width, pix_fmt_mp->height, - mb_width, mb_height); - - calculate_plane_sizes(fmt, mb_width * MB_DIM, - mb_height * MB_DIM, pix_fmt_mp); - - /* Reset crop rectangle. */ - ctx->src_crop.width = pix_fmt_mp->width; - ctx->src_crop.height = pix_fmt_mp->height; - - ctx->src_fmt = *pix_fmt_mp; - break; - - default: - vpu_err("invalid buf type\n"); - return -EINVAL; - } - -out: - vpu_debug_leave(); - - return ret; -} - -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *reqbufs) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (reqbufs->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - vpu_debug(4, "\n"); - - ret = vb2_reqbufs(&ctx->vq_dst, reqbufs); - if (ret != 0) { - vpu_err("error in vb2_reqbufs() for E(D)\n"); - goto out; - } - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - vpu_debug(4, "memory type %d\n", reqbufs->memory); - - ret = vb2_reqbufs(&ctx->vq_src, reqbufs); - if (ret != 0) { - vpu_err("error in vb2_reqbufs() for E(S)\n"); - goto out; - } - break; - - default: - vpu_err("invalid buf type\n"); - ret = -EINVAL; - goto out; - } - -out: - vpu_debug_leave(); - - return ret; -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (buf->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_querybuf(&ctx->vq_dst, buf); - if (ret != 0) { - vpu_err("error in vb2_querybuf() for E(D)\n"); - goto out; - } - - buf->m.planes[0].m.mem_offset += DST_QUEUE_OFF_BASE; - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_querybuf(&ctx->vq_src, buf); - if (ret != 0) { - vpu_err("error in vb2_querybuf() for E(S)\n"); - goto out; - } - break; - - default: - vpu_err("invalid buf type\n"); - ret = -EINVAL; - goto out; - } - -out: - vpu_debug_leave(); - - return ret; -} - -static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - int i; - - vpu_debug_enter(); - - for (i = 0; i < buf->length; i++) { - vpu_debug(4, "plane[%d]->length %d bytesused %d\n", - i, buf->m.planes[i].length, - buf->m.planes[i].bytesused); - } - - switch (buf->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_qbuf(&ctx->vq_src, buf); - vpu_debug(4, "vb2_qbuf return %d\n", ret); - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_qbuf(&ctx->vq_dst, buf); - vpu_debug(4, "vb2_qbuf return %d\n", ret); - break; - - default: - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (buf->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_dqbuf(&ctx->vq_src, buf, file->f_flags & O_NONBLOCK); - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_dqbuf(&ctx->vq_dst, buf, file->f_flags & O_NONBLOCK); - break; - - default: - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static int vidioc_expbuf(struct file *file, void *priv, - struct v4l2_exportbuffer *eb) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (eb->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_expbuf(&ctx->vq_src, eb); - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_expbuf(&ctx->vq_dst, eb); - break; - - default: - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_streamon(&ctx->vq_src, type); - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_streamon(&ctx->vq_dst, type); - break; - - default: - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static int vidioc_streamoff(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret; - - vpu_debug_enter(); - - switch (type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - ret = vb2_streamoff(&ctx->vq_src, type); - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - ret = vb2_streamoff(&ctx->vq_dst, type); - break; - - default: - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static int rockchip_vpu_enc_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct rockchip_vpu_ctx *ctx = ctrl_to_ctx(ctrl); - struct rockchip_vpu_dev *dev = ctx->dev; - int ret = 0; - - vpu_debug_enter(); - - vpu_debug(4, "ctrl id %d\n", ctrl->id); - - switch (ctrl->id) { - case V4L2_CID_MPEG_VIDEO_GOP_SIZE: - case V4L2_CID_MPEG_VIDEO_BITRATE: - case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: - case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: - case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE: - case V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE: - case V4L2_CID_MPEG_VIDEO_H264_PROFILE: - case V4L2_CID_MPEG_VIDEO_H264_LEVEL: - case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: - case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: - case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING: - case V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF: - case V4L2_CID_MPEG_VIDEO_HEADER_MODE: - case V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT: - case V4L2_CID_MPEG_VIDEO_B_FRAMES: - case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP: - case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME: - /* Ignore these controls for now. (FIXME?) */ - break; - - case V4L2_CID_PRIVATE_ROCKCHIP_HEADER: - case V4L2_CID_PRIVATE_ROCKCHIP_REG_PARAMS: - case V4L2_CID_PRIVATE_ROCKCHIP_HW_PARAMS: - /* Nothing to do here. The control is used directly. */ - break; - - default: - v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n", - ctrl->id, ctrl->val); - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static int rockchip_vpu_enc_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct rockchip_vpu_ctx *ctx = ctrl_to_ctx(ctrl); - struct rockchip_vpu_dev *dev = ctx->dev; - int ret = 0; - - vpu_debug_enter(); - - vpu_debug(4, "ctrl id %d\n", ctrl->id); - - switch (ctrl->id) { - case V4L2_CID_PRIVATE_ROCKCHIP_RET_PARAMS: - memcpy(ctrl->p_new.p, ctx->run.priv_dst.cpu, - ROCKCHIP_RET_PARAMS_SIZE); - break; - - default: - v4l2_err(&dev->v4l2_dev, "Invalid control, id=%d, val=%d\n", - ctrl->id, ctrl->val); - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static const struct v4l2_ctrl_ops rockchip_vpu_enc_ctrl_ops = { - .s_ctrl = rockchip_vpu_enc_s_ctrl, - .g_volatile_ctrl = rockchip_vpu_enc_g_volatile_ctrl, -}; - -static int vidioc_cropcap(struct file *file, void *priv, - struct v4l2_cropcap *cap) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - struct v4l2_pix_format_mplane *fmt = &ctx->src_fmt; - int ret = 0; - - vpu_debug_enter(); - - /* Crop only supported on source. */ - if (cap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - ret = -EINVAL; - goto out; - } - - cap->bounds.left = 0; - cap->bounds.top = 0; - cap->bounds.width = fmt->width; - cap->bounds.height = fmt->height; - cap->defrect = cap->bounds; - cap->pixelaspect.numerator = 1; - cap->pixelaspect.denominator = 1; - -out: - vpu_debug_leave(); - - return ret; -} - -static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - int ret = 0; - - vpu_debug_enter(); - - /* Crop only supported on source. */ - if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - ret = -EINVAL; - goto out; - } - - crop->c = ctx->src_crop; - -out: - vpu_debug_leave(); - - return ret; -} - -static int vidioc_s_crop(struct file *file, void *priv, - const struct v4l2_crop *crop) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(priv); - struct v4l2_pix_format_mplane *fmt = &ctx->src_fmt; - const struct v4l2_rect *rect = &crop->c; - int ret = 0; - - vpu_debug_enter(); - - /* Crop only supported on source. */ - if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - ret = -EINVAL; - goto out; - } - - /* Change not allowed if the queue is streaming. */ - if (vb2_is_streaming(&ctx->vq_src)) { - ret = -EBUSY; - goto out; - } - - /* We do not support offsets. */ - if (rect->left != 0 || rect->top != 0) - goto fallback; - - /* We can crop only inside right- or bottom-most macroblocks. */ - if (round_up(rect->width, MB_DIM) != fmt->width - || round_up(rect->height, MB_DIM) != fmt->height) - goto fallback; - - /* We support widths aligned to 4 pixels and arbitrary heights. */ - ctx->src_crop.width = round_up(rect->width, 4); - ctx->src_crop.height = rect->height; - - vpu_debug_leave(); - - return 0; - -fallback: - /* Default to full frame for incorrect settings. */ - ctx->src_crop.width = fmt->width; - ctx->src_crop.height = fmt->height; - -out: - vpu_debug_leave(); - - return ret; -} - -static const struct v4l2_ioctl_ops rockchip_vpu_enc_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_framesizes = vidioc_enum_framesizes, - .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap_mplane, - .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out_mplane, - .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt, - .vidioc_g_fmt_vid_out_mplane = vidioc_g_fmt, - .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt, - .vidioc_try_fmt_vid_out_mplane = vidioc_try_fmt, - .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt, - .vidioc_s_fmt_vid_out_mplane = vidioc_s_fmt, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_expbuf = vidioc_expbuf, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_cropcap = vidioc_cropcap, - .vidioc_g_crop = vidioc_g_crop, - .vidioc_s_crop = vidioc_s_crop, -}; - -static int rockchip_vpu_queue_setup(struct vb2_queue *vq, - const void *parg, - unsigned int *buf_count, - unsigned int *plane_count, - unsigned int psize[], void *allocators[]) -{ - struct rockchip_vpu_ctx *ctx = fh_to_ctx(vq->drv_priv); - int ret = 0; - int i; - - vpu_debug_enter(); - - switch (vq->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - *plane_count = ctx->vpu_dst_fmt->num_planes; - - if (*buf_count < 1) - *buf_count = 1; - - if (*buf_count > VIDEO_MAX_FRAME) - *buf_count = VIDEO_MAX_FRAME; - - psize[0] = ctx->dst_fmt.plane_fmt[0].sizeimage; - /* Kernel mapping necessary for bitstream post processing. */ - allocators[0] = ctx->dev->alloc_ctx_vm; - vpu_debug(0, "capture psize[%d]: %d\n", 0, psize[0]); - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - *plane_count = ctx->vpu_src_fmt->num_planes; - - if (*buf_count < 1) - *buf_count = 1; - - if (*buf_count > VIDEO_MAX_FRAME) - *buf_count = VIDEO_MAX_FRAME; - - for (i = 0; i < ctx->vpu_src_fmt->num_planes; ++i) { - psize[i] = ctx->src_fmt.plane_fmt[i].sizeimage; - vpu_debug(0, "output psize[%d]: %d\n", i, psize[i]); - allocators[i] = ctx->dev->alloc_ctx; - } - break; - - default: - vpu_err("invalid queue type: %d\n", vq->type); - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static int rockchip_vpu_buf_prepare(struct vb2_buffer *vb) -{ - struct vb2_queue *vq = vb->vb2_queue; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(vq->drv_priv); - int ret = 0; - int i; - - vpu_debug_enter(); - - switch (vq->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - vpu_debug(4, "plane size: %ld, dst size: %d\n", - vb2_plane_size(vb, 0), - ctx->dst_fmt.plane_fmt[0].sizeimage); - - if (vb2_plane_size(vb, 0) - < ctx->dst_fmt.plane_fmt[0].sizeimage) { - vpu_err("plane size is too small for capture\n"); - ret = -EINVAL; - } - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - for (i = 0; i < ctx->vpu_src_fmt->num_planes; ++i) { - vpu_debug(4, "plane %d size: %ld, sizeimage: %u\n", i, - vb2_plane_size(vb, i), - ctx->src_fmt.plane_fmt[i].sizeimage); - - if (vb2_plane_size(vb, i) - < ctx->src_fmt.plane_fmt[i].sizeimage) { - vpu_err("size of plane %d is too small for output\n", - i); - break; - } - } - - if (i != ctx->vpu_src_fmt->num_planes) - ret = -EINVAL; - break; - - default: - vpu_err("invalid queue type: %d\n", vq->type); - ret = -EINVAL; - } - - vpu_debug_leave(); - - return ret; -} - -static void rockchip_vpu_buf_finish(struct vb2_buffer *vb) -{ - struct vb2_queue *vq = vb->vb2_queue; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(vq->drv_priv); - - vpu_debug_enter(); - - if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE - && vb->state == VB2_BUF_STATE_DONE - && ctx->vpu_dst_fmt->fourcc == V4L2_PIX_FMT_VP8) { - struct rockchip_vpu_buf *buf; - - buf = vb_to_buf(vb); - rockchip_vpu_vp8e_assemble_bitstream(ctx, buf); - } else if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE - && vb->state == VB2_BUF_STATE_DONE - && ctx->vpu_dst_fmt->fourcc == V4L2_PIX_FMT_H264) { - struct rockchip_vpu_buf *buf; - - buf = vb_to_buf(vb); - rockchip_vpu_h264e_assemble_bitstream(ctx, buf); - } - - vpu_debug_leave(); -} - -static int rockchip_vpu_start_streaming(struct vb2_queue *q, unsigned int count) -{ - int ret = 0; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(q->drv_priv); - struct rockchip_vpu_dev *dev = ctx->dev; - bool ready = false; - - vpu_debug_enter(); - - if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - ret = rockchip_vpu_init(ctx); - if (ret < 0) { - vpu_err("rockchip_vpu_init failed\n"); - return ret; - } - - ready = vb2_is_streaming(&ctx->vq_src); - } else if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { - ready = vb2_is_streaming(&ctx->vq_dst); - } - - if (ready) - rockchip_vpu_try_context(dev, ctx); - - vpu_debug_leave(); - - return 0; -} - -static void rockchip_vpu_stop_streaming(struct vb2_queue *q) -{ - unsigned long flags; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(q->drv_priv); - struct rockchip_vpu_dev *dev = ctx->dev; - struct rockchip_vpu_buf *b; - LIST_HEAD(queue); - int i; - - vpu_debug_enter(); - - spin_lock_irqsave(&dev->irqlock, flags); - - list_del_init(&ctx->list); - - switch (q->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - list_splice_init(&ctx->dst_queue, &queue); - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - list_splice_init(&ctx->src_queue, &queue); - break; - - default: - break; - } - - spin_unlock_irqrestore(&dev->irqlock, flags); - - wait_event(dev->run_wq, dev->current_ctx != ctx); - - while (!list_empty(&queue)) { - b = list_first_entry(&queue, struct rockchip_vpu_buf, list); - for (i = 0; i < b->vb.vb2_buf.num_planes; i++) - vb2_set_plane_payload(&b->vb.vb2_buf, i, 0); - vb2_buffer_done(&b->vb.vb2_buf, VB2_BUF_STATE_ERROR); - list_del(&b->list); - } - - if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - rockchip_vpu_deinit(ctx); - - vpu_debug_leave(); -} - -static void rockchip_vpu_buf_queue(struct vb2_buffer *vb) -{ - struct vb2_queue *vq = vb->vb2_queue; - struct rockchip_vpu_ctx *ctx = fh_to_ctx(vq->drv_priv); - struct rockchip_vpu_dev *dev = ctx->dev; - struct rockchip_vpu_buf *vpu_buf; - unsigned long flags; - - vpu_debug_enter(); - - switch (vq->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - vpu_buf = vb_to_buf(vb); - - /* Mark destination as available for use by VPU */ - spin_lock_irqsave(&dev->irqlock, flags); - - list_add_tail(&vpu_buf->list, &ctx->dst_queue); - - spin_unlock_irqrestore(&dev->irqlock, flags); - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - vpu_buf = vb_to_buf(vb); - - spin_lock_irqsave(&dev->irqlock, flags); - - list_add_tail(&vpu_buf->list, &ctx->src_queue); - - spin_unlock_irqrestore(&dev->irqlock, flags); - break; - - default: - vpu_err("unsupported buffer type (%d)\n", vq->type); - } - - if (vb2_is_streaming(&ctx->vq_src) && vb2_is_streaming(&ctx->vq_dst)) - rockchip_vpu_try_context(dev, ctx); - - vpu_debug_leave(); -} - -static struct vb2_ops rockchip_vpu_enc_qops = { - .queue_setup = rockchip_vpu_queue_setup, - .wait_prepare = vb2_ops_wait_prepare, - .wait_finish = vb2_ops_wait_finish, - .buf_prepare = rockchip_vpu_buf_prepare, - .buf_finish = rockchip_vpu_buf_finish, - .start_streaming = rockchip_vpu_start_streaming, - .stop_streaming = rockchip_vpu_stop_streaming, - .buf_queue = rockchip_vpu_buf_queue, -}; - -struct vb2_ops *get_enc_queue_ops(void) -{ - return &rockchip_vpu_enc_qops; -} - -const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void) -{ - return &rockchip_vpu_enc_ioctl_ops; -} - -static void rockchip_vpu_enc_prepare_run(struct rockchip_vpu_ctx *ctx) -{ - struct vb2_v4l2_buffer *vb2_src = to_vb2_v4l2_buffer(&ctx->run.src->vb.vb2_buf); - unsigned config_store = vb2_src->config_store; - - v4l2_ctrl_apply_store(&ctx->ctrl_handler, config_store); - - if (ctx->vpu_dst_fmt->fourcc == V4L2_PIX_FMT_VP8) { - memcpy(ctx->run.dst->vp8e.header, - get_ctrl_ptr(ctx, ROCKCHIP_VPU_ENC_CTRL_HEADER), - ROCKCHIP_HEADER_SIZE); - ctx->run.vp8e.reg_params = get_ctrl_ptr(ctx, - ROCKCHIP_VPU_ENC_CTRL_REG_PARAMS); - memcpy(ctx->run.priv_src.cpu, - get_ctrl_ptr(ctx, ROCKCHIP_VPU_ENC_CTRL_HW_PARAMS), - ROCKCHIP_HW_PARAMS_SIZE); - } else if (ctx->vpu_dst_fmt->fourcc == V4L2_PIX_FMT_H264) { - ctx->run.h264e.reg_params = get_ctrl_ptr(ctx, - ROCKCHIP_VPU_ENC_CTRL_REG_PARAMS); - } -} - -static const struct rockchip_vpu_run_ops rockchip_vpu_enc_run_ops = { - .prepare_run = rockchip_vpu_enc_prepare_run, -}; - -int rockchip_vpu_enc_init(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - int ret; - - ctx->vpu_src_fmt = find_format(vpu, DEF_SRC_FMT_ENC, false); - ctx->vpu_dst_fmt = find_format(vpu, DEF_DST_FMT_ENC, true); - - ret = rockchip_vpu_aux_buf_alloc(vpu, &ctx->run.priv_src, - ROCKCHIP_HW_PARAMS_SIZE); - if (ret) { - vpu_err("Failed to allocate private source buffer.\n"); - return ret; - } - - - ret = rockchip_vpu_aux_buf_alloc(vpu, &ctx->run.priv_dst, - ROCKCHIP_RET_PARAMS_SIZE); - if (ret) { - vpu_err("Failed to allocate private destination buffer.\n"); - goto err_priv_src; - } - - ret = rockchip_vpu_ctrls_setup(ctx, &rockchip_vpu_enc_ctrl_ops, - controls, ARRAY_SIZE(controls), - rockchip_vpu_enc_get_menu); - if (ret) { - vpu_err("Failed to set up controls\n"); - goto err_priv_dst; - } - - ctx->run_ops = &rockchip_vpu_enc_run_ops; - - return 0; - -err_priv_dst: - rockchip_vpu_aux_buf_free(vpu, &ctx->run.priv_dst); -err_priv_src: - rockchip_vpu_aux_buf_free(vpu, &ctx->run.priv_src); - - return ret; -} - -void rockchip_vpu_enc_exit(struct rockchip_vpu_ctx *ctx) -{ - struct rockchip_vpu_dev *vpu = ctx->dev; - - rockchip_vpu_ctrls_delete(ctx); - - rockchip_vpu_aux_buf_free(vpu, &ctx->run.priv_dst); - rockchip_vpu_aux_buf_free(vpu, &ctx->run.priv_src); -}; - -/* - * WAR for encoder state corruption after decoding - */ - -static const struct rockchip_vpu_run_ops dummy_encode_run_ops = { - /* No ops needed for dummy encoding. */ -}; - -#define DUMMY_W 64 -#define DUMMY_H 64 -#define DUMMY_SRC_FMT V4L2_PIX_FMT_YUYV -#define DUMMY_DST_FMT V4L2_PIX_FMT_VP8 -#define DUMMY_DST_SIZE (32 * 1024) - -int rockchip_vpu_enc_init_dummy_ctx(struct rockchip_vpu_dev *dev) -{ - struct rockchip_vpu_ctx *ctx; - int ret; - int i; - - ctx = devm_kzalloc(dev->dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return -ENOMEM; - - ctx->dev = dev; - - ctx->vpu_src_fmt = find_format(dev, DUMMY_SRC_FMT, false); - ctx->src_fmt.width = DUMMY_W; - ctx->src_fmt.height = DUMMY_H; - ctx->src_fmt.pixelformat = ctx->vpu_src_fmt->fourcc; - ctx->src_fmt.num_planes = ctx->vpu_src_fmt->num_planes; - - calculate_plane_sizes(ctx->vpu_src_fmt, ctx->src_fmt.width, - ctx->src_fmt.height, &ctx->src_fmt); - - ctx->vpu_dst_fmt = find_format(dev, DUMMY_DST_FMT, true); - ctx->dst_fmt.width = ctx->src_fmt.width; - ctx->dst_fmt.height = ctx->src_fmt.height; - ctx->dst_fmt.pixelformat = ctx->vpu_dst_fmt->fourcc; - ctx->dst_fmt.plane_fmt[0].sizeimage = DUMMY_DST_SIZE; - ctx->dst_fmt.plane_fmt[0].bytesperline = 0; - ctx->dst_fmt.num_planes = 1; - - INIT_LIST_HEAD(&ctx->src_queue); - - ctx->src_crop.left = 0; - ctx->src_crop.top = 0; - ctx->src_crop.width = ctx->src_fmt.width; - ctx->src_crop.left = ctx->src_fmt.height; - - INIT_LIST_HEAD(&ctx->dst_queue); - INIT_LIST_HEAD(&ctx->list); - - ctx->run.vp8e.reg_params = - rk3288_vpu_vp8e_get_dummy_params(); - ctx->run_ops = &dummy_encode_run_ops; - - ctx->run.dst = devm_kzalloc(dev->dev, sizeof(*ctx->run.dst), - GFP_KERNEL); - if (!ctx->run.dst) - return -ENOMEM; - - ret = rockchip_vpu_aux_buf_alloc(dev, &ctx->run.priv_src, - ROCKCHIP_HW_PARAMS_SIZE); - if (ret) - return ret; - - ret = rockchip_vpu_aux_buf_alloc(dev, &ctx->run.priv_dst, - ROCKCHIP_RET_PARAMS_SIZE); - if (ret) - goto err_free_priv_src; - - for (i = 0; i < ctx->src_fmt.num_planes; ++i) { - ret = rockchip_vpu_aux_buf_alloc(dev, &dev->dummy_encode_src[i], - ctx->src_fmt.plane_fmt[i].sizeimage); - if (ret) - goto err_free_src; - - memset(dev->dummy_encode_src[i].cpu, 0, - dev->dummy_encode_src[i].size); - } - - ret = rockchip_vpu_aux_buf_alloc(dev, &dev->dummy_encode_dst, - ctx->dst_fmt.plane_fmt[0].sizeimage); - if (ret) - goto err_free_src; - - memset(dev->dummy_encode_dst.cpu, 0, dev->dummy_encode_dst.size); - - ret = rockchip_vpu_init(ctx); - if (ret) - goto err_free_dst; - - dev->dummy_encode_ctx = ctx; - - return 0; - -err_free_dst: - rockchip_vpu_aux_buf_free(dev, &dev->dummy_encode_dst); -err_free_src: - for (i = 0; i < ctx->src_fmt.num_planes; ++i) - if (dev->dummy_encode_src[i].cpu) - rockchip_vpu_aux_buf_free(dev, &dev->dummy_encode_src[i]); - rockchip_vpu_aux_buf_free(dev, &ctx->run.priv_dst); -err_free_priv_src: - rockchip_vpu_aux_buf_free(dev, &ctx->run.priv_src); - - return ret; -} - -void rockchip_vpu_enc_free_dummy_ctx(struct rockchip_vpu_dev *dev) -{ - struct rockchip_vpu_ctx *ctx = dev->dummy_encode_ctx; - int i; - - if (!ctx) - return; - - rockchip_vpu_deinit(ctx); - - for (i = 0; i < ctx->src_fmt.num_planes; ++i) - rockchip_vpu_aux_buf_free(dev, &dev->dummy_encode_src[i]); - rockchip_vpu_aux_buf_free(dev, &dev->dummy_encode_dst); - rockchip_vpu_aux_buf_free(dev, &ctx->run.priv_src); - rockchip_vpu_aux_buf_free(dev, &ctx->run.priv_dst); -} diff --git a/drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.h b/drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.h deleted file mode 100644 index 01008a244203..000000000000 --- a/drivers/media/platform/rockchip-vpu/rockchip_vpu_enc.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Rockchip VPU codec driver - * - * Copyright (c) 2014 Rockchip Electronics Co., Ltd. - * Alpha Lin - * Jeffy Chen - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * Based on s5p-mfc driver by Samsung Electronics Co., Ltd. - * - * Copyright (C) 2011 Samsung Electronics Co., Ltd. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef ROCKCHIP_VPU_ENC_H_ -#define ROCKCHIP_VPU_ENC_H_ - -struct vb2_ops *get_enc_queue_ops(void); -const struct v4l2_ioctl_ops *get_enc_v4l2_ioctl_ops(void); -struct rockchip_vpu_fmt *get_enc_def_fmt(bool src); -int rockchip_vpu_enc_init(struct rockchip_vpu_ctx *ctx); -void rockchip_vpu_enc_exit(struct rockchip_vpu_ctx *ctx); -int rockchip_vpu_enc_init_dummy_ctx(struct rockchip_vpu_dev *dev); -void rockchip_vpu_enc_free_dummy_ctx(struct rockchip_vpu_dev *dev); - -#endif /* ROCKCHIP_VPU_ENC_H_ */ diff --git a/drivers/media/platform/rockchip-vpu/rockchip_vpu_hw.c b/drivers/media/platform/rockchip-vpu/rockchip_vpu_hw.c deleted file mode 100644 index 6006bd1b70c5..000000000000 --- a/drivers/media/platform/rockchip-vpu/rockchip_vpu_hw.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Rockchip VPU codec driver - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "rockchip_vpu_common.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* Various parameters specific to VP8 encoder. */ -#define VP8_KEY_FRAME_HDR_SIZE 10 -#define VP8_INTER_FRAME_HDR_SIZE 3 - -#define VP8_FRAME_TAG_KEY_FRAME_BIT BIT(0) -#define VP8_FRAME_TAG_LENGTH_SHIFT 5 -#define VP8_FRAME_TAG_LENGTH_MASK (0x7ffff << 5) - -/** - * struct rockchip_vpu_codec_ops - codec mode specific operations - * - * @codec_mode: Codec mode related to this format. See - * enum rockchip_vpu_codec_mode. - * @init: Prepare for streaming. Called from VB2 .start_streaming() - * when streaming from both queues is being enabled. - * @exit: Clean-up after streaming. Called from VB2 .stop_streaming() - * when streaming from first of both enabled queues is being - * disabled. - * @irq: Handle {en,de}code irq. Check and clear interrupt. - * @run: Start single {en,de)coding run. Called from non-atomic context - * to indicate that a pair of buffers is ready and the hardware - * should be programmed and started. - * @done: Read back processing results and additional data from hardware. - * @reset: Reset the hardware in case of a timeout. - */ -struct rockchip_vpu_codec_ops { - enum rockchip_vpu_codec_mode codec_mode; - - int (*init)(struct rockchip_vpu_ctx *); - void (*exit)(struct rockchip_vpu_ctx *); - - int (*irq)(int, struct rockchip_vpu_dev *); - void (*run)(struct rockchip_vpu_ctx *); - void (*done)(struct rockchip_vpu_ctx *, enum vb2_buffer_state); - void (*reset)(struct rockchip_vpu_ctx *); -}; - -/* - * Hardware control routines. - */ - -void rockchip_vpu_power_on(struct rockchip_vpu_dev *vpu) -{ - vpu_debug_enter(); - - /* TODO: Clock gating. */ - - pm_runtime_get_sync(vpu->dev); - - vpu_debug_leave(); -} - -static void rockchip_vpu_power_off(struct rockchip_vpu_dev *vpu) -{ - vpu_debug_enter(); - - pm_runtime_mark_last_busy(vpu->dev); - pm_runtime_put_autosuspend(vpu->dev); - - /* TODO: Clock gating. */ - - vpu_debug_leave(); -} - -/* - * Interrupt handlers. - */ - -static irqreturn_t vepu_irq(int irq, void *dev_id) -{ - struct rockchip_vpu_dev *vpu = dev_id; - struct rockchip_vpu_ctx *ctx = vpu->current_ctx; - - if (!ctx->hw.codec_ops->irq(irq, vpu)) { - rockchip_vpu_power_off(vpu); - cancel_delayed_work(&vpu->watchdog_work); - - ctx->hw.codec_ops->done(ctx, VB2_BUF_STATE_DONE); - } - - return IRQ_HANDLED; -} - -static irqreturn_t vdpu_irq(int irq, void *dev_id) -{ - struct rockchip_vpu_dev *vpu = dev_id; - struct rockchip_vpu_ctx *ctx = vpu->current_ctx; - - if (!ctx->hw.codec_ops->irq(irq, vpu)) { - rockchip_vpu_power_off(vpu); - cancel_delayed_work(&vpu->watchdog_work); - - ctx->hw.codec_ops->done(ctx, VB2_BUF_STATE_DONE); - } - - return IRQ_HANDLED; -} - -static void rockchip_vpu_watchdog(struct work_struct *work) -{ - struct rockchip_vpu_dev *vpu = container_of(to_delayed_work(work), - struct rockchip_vpu_dev, watchdog_work); - struct rockchip_vpu_ctx *ctx = vpu->current_ctx; - unsigned long flags; - - spin_lock_irqsave(&vpu->irqlock, flags); - - ctx->hw.codec_ops->reset(ctx); - - spin_unlock_irqrestore(&vpu->irqlock, flags); - - vpu_err("frame processing timed out!\n"); - - rockchip_vpu_power_off(vpu); - ctx->hw.codec_ops->done(ctx, VB2_BUF_STATE_ERROR); -} - -/* - * Initialization/clean-up. - */ - -#if defined(CONFIG_ROCKCHIP_IOMMU) -static int rockchip_vpu_iommu_init(struct rockchip_vpu_dev *vpu) -{ - int ret; - - vpu->dev->dma_parms = devm_kzalloc(vpu->dev, - sizeof(*vpu->dev->dma_parms), - GFP_KERNEL); - if (!vpu->dev->dma_parms) - return -ENOMEM; - - vpu->domain = iommu_domain_alloc(vpu->dev->bus); - if (!vpu->domain) { - ret = -ENOMEM; - goto err_free_parms; - } - - ret = iommu_get_dma_cookie(vpu->domain); - if (ret) - goto err_free_domain; - - ret = dma_set_coherent_mask(vpu->dev, DMA_BIT_MASK(32)); - if (ret) - goto err_put_cookie; - - dma_set_max_seg_size(vpu->dev, DMA_BIT_MASK(32)); - - ret = iommu_attach_device(vpu->domain, vpu->dev); - if (ret) - goto err_put_cookie; - - common_iommu_setup_dma_ops(vpu->dev, 0x10000000, SZ_2G, - vpu->domain->ops); - - return 0; - -err_put_cookie: - iommu_put_dma_cookie(vpu->domain); -err_free_domain: - iommu_domain_free(vpu->domain); -err_free_parms: - return ret; -} - -static void rockchip_vpu_iommu_cleanup(struct rockchip_vpu_dev *vpu) -{ - iommu_detach_device(vpu->domain, vpu->dev); - iommu_put_dma_cookie(vpu->domain); - iommu_domain_free(vpu->domain); -} -#else /* CONFIG_ROCKCHIP_IOMMU */ -static inline int rockchip_vpu_iommu_init(struct rockchip_vpu_dev *vpu) -{ - return 0; -} - -static inline void rockchip_vpu_iommu_cleanup(struct rockchip_vpu_dev *vpu) { } -#endif /* CONFIG_ROCKCHIP_IOMMU */ - -int rockchip_vpu_hw_probe(struct rockchip_vpu_dev *vpu) -{ - struct resource *res; - int irq_enc, irq_dec; - int ret; - - pr_info("probe device %s\n", dev_name(vpu->dev)); - - INIT_DELAYED_WORK(&vpu->watchdog_work, rockchip_vpu_watchdog); - - vpu->aclk = devm_clk_get(vpu->dev, "aclk"); - if (IS_ERR(vpu->aclk)) { - dev_err(vpu->dev, "failed to get aclk\n"); - return PTR_ERR(vpu->aclk); - } - - vpu->hclk = devm_clk_get(vpu->dev, "hclk"); - if (IS_ERR(vpu->hclk)) { - dev_err(vpu->dev, "failed to get hclk\n"); - return PTR_ERR(vpu->hclk); - } - - res = platform_get_resource(vpu->pdev, IORESOURCE_MEM, 0); - vpu->base = devm_ioremap_resource(vpu->dev, res); - if (IS_ERR(vpu->base)) - return PTR_ERR(vpu->base); - - clk_prepare_enable(vpu->aclk); - clk_prepare_enable(vpu->hclk); - - vpu->enc_base = vpu->base + vpu->variant->enc_offset; - vpu->dec_base = vpu->base + vpu->variant->dec_offset; - - ret = dma_set_coherent_mask(vpu->dev, DMA_BIT_MASK(32)); - if (ret) { - dev_err(vpu->dev, "could not set DMA coherent mask\n"); - goto err_power; - } - - ret = rockchip_vpu_iommu_init(vpu); - if (ret) - goto err_power; - - irq_enc = platform_get_irq_byname(vpu->pdev, "vepu"); - if (irq_enc <= 0) { - dev_err(vpu->dev, "could not get vepu IRQ\n"); - ret = -ENXIO; - goto err_iommu; - } - - ret = devm_request_threaded_irq(vpu->dev, irq_enc, NULL, vepu_irq, - IRQF_ONESHOT, dev_name(vpu->dev), vpu); - if (ret) { - dev_err(vpu->dev, "could not request vepu IRQ\n"); - goto err_iommu; - } - - irq_dec = platform_get_irq_byname(vpu->pdev, "vdpu"); - if (irq_dec <= 0) { - dev_err(vpu->dev, "could not get vdpu IRQ\n"); - ret = -ENXIO; - goto err_iommu; - } - - ret = devm_request_threaded_irq(vpu->dev, irq_dec, NULL, vdpu_irq, - IRQF_ONESHOT, dev_name(vpu->dev), vpu); - if (ret) { - dev_err(vpu->dev, "could not request vdpu IRQ\n"); - goto err_iommu; - } - - pm_runtime_set_autosuspend_delay(vpu->dev, 100); - pm_runtime_use_autosuspend(vpu->dev); - pm_runtime_enable(vpu->dev); - - return 0; - -err_iommu: - rockchip_vpu_iommu_cleanup(vpu); -err_power: - clk_disable_unprepare(vpu->hclk); - clk_disable_unprepare(vpu->aclk); - - return ret; -} - -void rockchip_vpu_hw_remove(struct rockchip_vpu_dev *vpu) -{ - rockchip_vpu_iommu_cleanup(vpu); - - pm_runtime_disable(vpu->dev); - - clk_disable_unprepare(vpu->hclk); - clk_disable_unprepare(vpu->aclk); -} - -static const struct rockchip_vpu_codec_ops mode_ops[] = { - { - .codec_mode = RK3288_VPU_CODEC_VP8E, - .init = rk3288_vpu_vp8e_init, - .exit = rk3288_vpu_vp8e_exit, - .irq = rk3288_vpu_enc_irq, - .run = rk3288_vpu_vp8e_run, - .done = rk3288_vpu_vp8e_done, - .reset = rk3288_vpu_enc_reset, - }, - { - .codec_mode = RK3288_VPU_CODEC_VP8D, - .init = rk3288_vpu_vp8d_init, - .exit = rk3288_vpu_vp8d_exit, - .irq = rk3288_vpu_dec_irq, - .run = rk3288_vpu_vp8d_run, - .done = rockchip_vpu_run_done, - .reset = rk3288_vpu_dec_reset, - }, - { - .codec_mode = RK3288_VPU_CODEC_H264E, - .init = rk3288_vpu_h264e_init, - .exit = rk3288_vpu_h264e_exit, - .irq = rk3288_vpu_enc_irq, - .run = rk3288_vpu_h264e_run, - .done = rk3288_vpu_h264e_done, - .reset = rk3288_vpu_enc_reset, - }, - { - .codec_mode = RK3288_VPU_CODEC_H264D, - .init = rk3288_vpu_h264d_init, - .exit = rk3288_vpu_h264d_exit, - .irq = rk3288_vpu_dec_irq, - .run = rk3288_vpu_h264d_run, - .done = rockchip_vpu_run_done, - .reset = rk3288_vpu_dec_reset, - }, -}; - -void rockchip_vpu_run(struct rockchip_vpu_ctx *ctx) -{ - ctx->hw.codec_ops->run(ctx); -} - -int rockchip_vpu_init(struct rockchip_vpu_ctx *ctx) -{ - enum rockchip_vpu_codec_mode codec_mode; - int i; - - if (rockchip_vpu_ctx_is_encoder(ctx)) - codec_mode = ctx->vpu_dst_fmt->codec_mode; /* Encoder */ - else - codec_mode = ctx->vpu_src_fmt->codec_mode; /* Decoder */ - - for (i = 0; i < ARRAY_SIZE(mode_ops); i++) { - if (mode_ops[i].codec_mode == codec_mode) { - ctx->hw.codec_ops = &mode_ops[i]; - break; - } - } - - if (!ctx->hw.codec_ops) - return -1; - - return ctx->hw.codec_ops->init(ctx); -} - -void rockchip_vpu_deinit(struct rockchip_vpu_ctx *ctx) -{ - ctx->hw.codec_ops->exit(ctx); -} - -/* - * The hardware takes care only of ext hdr and dct partition. The software - * must take care of frame header. - * - * Buffer layout as received from hardware: - * |<--gap-->|<--ext hdr-->|<-gap->|<---dct part--- - * |<-------dct part offset------->| - * - * Required buffer layout: - * |<--hdr-->|<--ext hdr-->|<---dct part--- - */ -void rockchip_vpu_vp8e_assemble_bitstream(struct rockchip_vpu_ctx *ctx, - struct rockchip_vpu_buf *dst_buf) -{ - struct vb2_v4l2_buffer *vb2_dst = to_vb2_v4l2_buffer(&dst_buf->vb.vb2_buf); - size_t ext_hdr_size = dst_buf->vp8e.ext_hdr_size; - size_t dct_size = dst_buf->vp8e.dct_size; - size_t hdr_size = dst_buf->vp8e.hdr_size; - size_t dst_size; - size_t tag_size; - void *dst; - u32 *tag; - - dst_size = vb2_plane_size(&dst_buf->vb.vb2_buf, 0); - dst = vb2_plane_vaddr(&dst_buf->vb.vb2_buf, 0); - tag = dst; /* To access frame tag words. */ - - if (WARN_ON(hdr_size + ext_hdr_size + dct_size > dst_size)) - return; - if (WARN_ON(dst_buf->vp8e.dct_offset + dct_size > dst_size)) - return; - - vpu_debug(1, "%s: hdr_size = %d, ext_hdr_size = %d, dct_size = %d\n", - __func__, hdr_size, ext_hdr_size, dct_size); - - memmove(dst + hdr_size + ext_hdr_size, - dst + dst_buf->vp8e.dct_offset, dct_size); - memcpy(dst, dst_buf->vp8e.header, hdr_size); - - /* Patch frame tag at first 32-bit word of the frame. */ - if (vb2_dst->flags & V4L2_BUF_FLAG_KEYFRAME) { - tag_size = VP8_KEY_FRAME_HDR_SIZE; - tag[0] &= ~VP8_FRAME_TAG_KEY_FRAME_BIT; - } else { - tag_size = VP8_INTER_FRAME_HDR_SIZE; - tag[0] |= VP8_FRAME_TAG_KEY_FRAME_BIT; - } - - tag[0] &= ~VP8_FRAME_TAG_LENGTH_MASK; - tag[0] |= (hdr_size + ext_hdr_size - tag_size) - << VP8_FRAME_TAG_LENGTH_SHIFT; - - vb2_set_plane_payload(&dst_buf->vb.vb2_buf, 0, - hdr_size + ext_hdr_size + dct_size); -} - -void rockchip_vpu_h264e_assemble_bitstream(struct rockchip_vpu_ctx *ctx, - struct rockchip_vpu_buf *dst_buf) -{ - size_t sps_size = dst_buf->h264e.sps_size; - size_t pps_size = dst_buf->h264e.pps_size; - size_t slices_size = dst_buf->h264e.slices_size; - size_t dst_size; - void *dst; - - struct stream_s *sps = &ctx->run.h264e.sps; - struct stream_s *pps = &ctx->run.h264e.pps; - - dst_size = vb2_plane_size(&dst_buf->vb.vb2_buf, 0); - dst = vb2_plane_vaddr(&dst_buf->vb.vb2_buf, 0); - - if (WARN_ON(sps_size + pps_size + slices_size > dst_size)) - return; - - vpu_debug(1, "%s: sps_size = %u, pps_size = %u, slices_size = %u\n", - __func__, sps_size, pps_size, slices_size); - - memcpy(dst, sps->buffer, sps_size); - memcpy(dst + sps_size, pps->buffer, pps_size); - - vb2_set_plane_payload(&dst_buf->vb.vb2_buf, 0, - sps_size + pps_size + slices_size); -} diff --git a/drivers/media/platform/rockchip-vpu/rockchip_vpu_hw.h b/drivers/media/platform/rockchip-vpu/rockchip_vpu_hw.h deleted file mode 100644 index c79d7a15a35f..000000000000 --- a/drivers/media/platform/rockchip-vpu/rockchip_vpu_hw.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Rockchip VPU codec driver - * - * Copyright (C) 2014 Google, Inc. - * Tomasz Figa - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef ROCKCHIP_VPU_HW_H_ -#define ROCKCHIP_VPU_HW_H_ - -#include - -#define ROCKCHIP_HEADER_SIZE 1280 -#define ROCKCHIP_HW_PARAMS_SIZE 5487 -#define ROCKCHIP_RET_PARAMS_SIZE 488 - -struct rockchip_vpu_dev; -struct rockchip_vpu_ctx; -struct rockchip_vpu_buf; - -/** - * enum rockchip_vpu_enc_fmt - source format ID for hardware registers. - */ -enum rockchip_vpu_enc_fmt { - ROCKCHIP_VPU_ENC_FMT_YUV420P = 0, - ROCKCHIP_VPU_ENC_FMT_YUV420SP = 1, - ROCKCHIP_VPU_ENC_FMT_YUYV422 = 2, - ROCKCHIP_VPU_ENC_FMT_UYVY422 = 3, -}; - -/** - * struct rk3288_vp8e_reg_params - low level encoding parameters - * TODO: Create abstract structures for more generic controls or just - * remove unused fields. - */ -struct rk3288_vp8e_reg_params { - u32 unused_00[5]; - u32 hdr_len; - u32 unused_18[8]; - u32 enc_ctrl; - u32 unused_3c; - u32 enc_ctrl0; - u32 enc_ctrl1; - u32 enc_ctrl2; - u32 enc_ctrl3; - u32 enc_ctrl5; - u32 enc_ctrl4; - u32 str_hdr_rem_msb; - u32 str_hdr_rem_lsb; - u32 unused_60; - u32 mad_ctrl; - u32 unused_68; - u32 qp_val[8]; - u32 bool_enc; - u32 vp8_ctrl0; - u32 rlc_ctrl; - u32 mb_ctrl; - u32 unused_9c[14]; - u32 rgb_yuv_coeff[2]; - u32 rgb_mask_msb; - u32 intra_area_ctrl; - u32 cir_intra_ctrl; - u32 unused_e8[2]; - u32 first_roi_area; - u32 second_roi_area; - u32 mvc_ctrl; - u32 unused_fc; - u32 intra_penalty[7]; - u32 unused_11c; - u32 seg_qp[24]; - u32 dmv_4p_1p_penalty[32]; - u32 dmv_qpel_penalty[32]; - u32 vp8_ctrl1; - u32 bit_cost_golden; - u32 loop_flt_delta[2]; -}; - -/** - * struct rk3288_h264e_reg_params - low level encoding parameters - * TODO: Create abstract structures for more generic controls or just - * remove unused fields. - */ -struct rk3288_h264e_reg_params { - u32 frame_coding_type; - s32 pic_init_qp; - s32 slice_alpha_offset; - s32 slice_beta_offset; - s32 chroma_qp_index_offset; - s32 filter_disable; - u16 idr_pic_id; - s32 pps_id; - s32 frame_num; - s32 slice_size_mb_rows; - s32 h264_inter4x4_disabled; - s32 enable_cabac; - s32 transform8x8_mode; - s32 cabac_init_idc; - - /* rate control relevant */ - s32 qp; - s32 mad_qp_delta; - s32 mad_threshold; - s32 qp_min; - s32 qp_max; - s32 cp_distance_mbs; - s32 cp_target[10]; - s32 target_error[7]; - s32 delta_qp[7]; -}; - -/** - * struct rockchip_reg_params - low level encoding parameters - */ -struct rockchip_reg_params { - /* Mode-specific data. */ - union { - const struct rk3288_h264e_reg_params rk3288_h264e; - const struct rk3288_vp8e_reg_params rk3288_vp8e; - }; -}; - -struct rockchip_vpu_h264e_feedback { - s32 qp_sum; - s32 cp[10]; - s32 mad_count; - s32 rlc_count; -}; - -/** - * struct rockchip_vpu_aux_buf - auxiliary DMA buffer for hardware data - * @cpu: CPU pointer to the buffer. - * @dma: DMA address of the buffer. - * @size: Size of the buffer. - */ -struct rockchip_vpu_aux_buf { - void *cpu; - dma_addr_t dma; - size_t size; -}; - -/** - * struct rockchip_vpu_vp8e_hw_ctx - Context private data specific to codec mode. - * @ctrl_buf: VP8 control buffer. - * @ext_buf: VP8 ext data buffer. - * @mv_buf: VP8 motion vector buffer. - * @ref_rec_ptr: Bit flag for swapping ref and rec buffers every frame. - */ -struct rockchip_vpu_vp8e_hw_ctx { - struct rockchip_vpu_aux_buf ctrl_buf; - struct rockchip_vpu_aux_buf ext_buf; - struct rockchip_vpu_aux_buf mv_buf; - u8 ref_rec_ptr:1; -}; - -/** - * struct rockchip_vpu_vp8d_hw_ctx - Context private data of VP8 decoder. - * @segment_map: Segment map buffer. - * @prob_tbl: Probability table buffer. - */ -struct rockchip_vpu_vp8d_hw_ctx { - struct rockchip_vpu_aux_buf segment_map; - struct rockchip_vpu_aux_buf prob_tbl; -}; - -/** - * struct rockchip_vpu_h264d_hw_ctx - Per context data specific to H264 decoding. - * @priv_tbl: Private auxiliary buffer for hardware. - */ -struct rockchip_vpu_h264d_hw_ctx { - struct rockchip_vpu_aux_buf priv_tbl; -}; - -/** - * struct rockchip_vpu_h264e_hw_ctx - Context private data specific to codec mode. - * @ctrl_buf: H264 control buffer. - * @ext_buf: H264 ext data buffer. - * @ref_rec_ptr: Bit flag for swapping ref and rec buffers every frame. - */ -struct rockchip_vpu_h264e_hw_ctx { - struct rockchip_vpu_aux_buf cabac_tbl[3]; - struct rockchip_vpu_aux_buf ext_buf; - u8 ref_rec_ptr:1; -}; - -/** - * struct rockchip_vpu_hw_ctx - Context private data of hardware code. - * @codec_ops: Set of operations associated with current codec mode. - */ -struct rockchip_vpu_hw_ctx { - const struct rockchip_vpu_codec_ops *codec_ops; - - /* Specific for particular codec modes. */ - union { - struct rockchip_vpu_vp8e_hw_ctx vp8e; - struct rockchip_vpu_vp8d_hw_ctx vp8d; - struct rockchip_vpu_h264e_hw_ctx h264e; - struct rockchip_vpu_h264d_hw_ctx h264d; - /* Other modes will need different data. */ - }; -}; - -int rockchip_vpu_hw_probe(struct rockchip_vpu_dev *vpu); -void rockchip_vpu_hw_remove(struct rockchip_vpu_dev *vpu); - -void rockchip_vpu_power_on(struct rockchip_vpu_dev *vpu); - -int rockchip_vpu_init(struct rockchip_vpu_ctx *ctx); -void rockchip_vpu_deinit(struct rockchip_vpu_ctx *ctx); - -void rockchip_vpu_run(struct rockchip_vpu_ctx *ctx); - -/* Ops for rk3288 vpu */ -int rk3288_vpu_enc_irq(int irq, struct rockchip_vpu_dev *vpu); -int rk3288_vpu_dec_irq(int irq, struct rockchip_vpu_dev *vpu); -void rk3288_vpu_enc_reset(struct rockchip_vpu_ctx *ctx); -void rk3288_vpu_dec_reset(struct rockchip_vpu_ctx *ctx); - -/* Run ops for rk3288 H264 decoder */ -int rk3288_vpu_h264d_init(struct rockchip_vpu_ctx *ctx); -void rk3288_vpu_h264d_exit(struct rockchip_vpu_ctx *ctx); -void rk3288_vpu_h264d_run(struct rockchip_vpu_ctx *ctx); - -/* Run ops for rk3288 h264 encoder */ -int rk3288_vpu_h264e_init(struct rockchip_vpu_ctx *ctx); -void rk3288_vpu_h264e_exit(struct rockchip_vpu_ctx *ctx); -void rk3288_vpu_h264e_run(struct rockchip_vpu_ctx *ctx); -void rk3288_vpu_h264e_done(struct rockchip_vpu_ctx *ctx, - enum vb2_buffer_state result); - -/* Run ops for rk3288 VP8 decoder */ -int rk3288_vpu_vp8d_init(struct rockchip_vpu_ctx *ctx); -void rk3288_vpu_vp8d_exit(struct rockchip_vpu_ctx *ctx); -void rk3288_vpu_vp8d_run(struct rockchip_vpu_ctx *ctx); - -/* Run ops for rk3288 VP8 encoder */ -int rk3288_vpu_vp8e_init(struct rockchip_vpu_ctx *ctx); -void rk3288_vpu_vp8e_exit(struct rockchip_vpu_ctx *ctx); -void rk3288_vpu_vp8e_run(struct rockchip_vpu_ctx *ctx); -void rk3288_vpu_vp8e_done(struct rockchip_vpu_ctx *ctx, - enum vb2_buffer_state result); - -const struct rockchip_reg_params *rk3288_vpu_vp8e_get_dummy_params(void); - -void rockchip_vpu_vp8e_assemble_bitstream(struct rockchip_vpu_ctx *ctx, - struct rockchip_vpu_buf *dst_buf); -void rockchip_vpu_h264e_assemble_bitstream(struct rockchip_vpu_ctx *ctx, - struct rockchip_vpu_buf *dst_buf); - -#endif /* ROCKCHIP_VPU_HW_H_ */