1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Rockchip RK3288 VPU codec driver
4 *
5 * Copyright (c) 2014 Rockchip Electronics Co., Ltd.
6 * Hertz Wong <hertz.wong@rock-chips.com>
7 * Herman Chen <herman.chen@rock-chips.com>
8 *
9 * Copyright (C) 2014 Google, Inc.
10 * Tomasz Figa <tfiga@chromium.org>
11 */
12
13 #include <linux/types.h>
14 #include <media/v4l2-h264.h>
15 #include <media/v4l2-mem2mem.h>
16
17 #include "hantro.h"
18 #include "hantro_hw.h"
19
20 /* Size with u32 units. */
21 #define CABAC_INIT_BUFFER_SIZE (460 * 2)
22 #define POC_BUFFER_SIZE 34
23 #define SCALING_LIST_SIZE (6 * 16 + 2 * 64)
24
25 /* Data structure describing auxiliary buffer format. */
26 struct hantro_h264_dec_priv_tbl {
27 u32 cabac_table[CABAC_INIT_BUFFER_SIZE];
28 u32 poc[POC_BUFFER_SIZE];
29 u8 scaling_list[SCALING_LIST_SIZE];
30 };
31
32 /*
33 * Constant CABAC table.
34 * From drivers/media/platform/rk3288-vpu/rk3288_vpu_hw_h264d.c
35 * in https://chromium.googlesource.com/chromiumos/third_party/kernel,
36 * chromeos-3.14 branch.
37 */
38 static const u32 h264_cabac_table[] = {
39 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07330000,
40 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
41 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
42 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
43 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
44 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x000b0137,
45 0x0045ef7f, 0xf3660052, 0xf94aeb6b, 0xe57fe17f, 0xe87fee5f, 0xe57feb72,
46 0xe27fef7b, 0xf473f07a, 0xf573f43f, 0xfe44f154, 0xf368fd46, 0xf85df65a,
47 0xe27fff4a, 0xfa61f95b, 0xec7ffc38, 0xfb52f94c, 0xea7df95d, 0xf557fd4d,
48 0xfb47fc3f, 0xfc44f454, 0xf93ef941, 0x083d0538, 0xfe420140, 0x003dfe4e,
49 0x01320734, 0x0a23002c, 0x0b26012d, 0x002e052c, 0x1f110133, 0x07321c13,
50 0x10210e3e, 0xf36cf164, 0xf365f35b, 0xf45ef658, 0xf054f656, 0xf953f357,
51 0xed5e0146, 0x0048fb4a, 0x123bf866, 0xf164005f, 0xfc4b0248, 0xf54bfd47,
52 0x0f2ef345, 0x003e0041, 0x1525f148, 0x09391036, 0x003e0c48, 0x18000f09,
53 0x08190d12, 0x0f090d13, 0x0a250c12, 0x061d1421, 0x0f1e042d, 0x013a003e,
54 0x073d0c26, 0x0b2d0f27, 0x0b2a0d2c, 0x102d0c29, 0x0a311e22, 0x122a0a37,
55 0x1133112e, 0x00591aed, 0x16ef1aef, 0x1ee71cec, 0x21e925e5, 0x21e928e4,
56 0x26ef21f5, 0x28f129fa, 0x26012911, 0x1efa1b03, 0x1a1625f0, 0x23fc26f8,
57 0x26fd2503, 0x26052a00, 0x23102716, 0x0e301b25, 0x153c0c44, 0x0261fd47,
58 0xfa2afb32, 0xfd36fe3e, 0x003a013f, 0xfe48ff4a, 0xf75bfb43, 0xfb1bfd27,
59 0xfe2c002e, 0xf040f844, 0xf64efa4d, 0xf656f45c, 0xf137f63c, 0xfa3efc41,
60 0xf449f84c, 0xf950f758, 0xef6ef561, 0xec54f54f, 0xfa49fc4a, 0xf356f360,
61 0xf561ed75, 0xf84efb21, 0xfc30fe35, 0xfd3ef347, 0xf64ff456, 0xf35af261,
62 0x0000fa5d, 0xfa54f84f, 0x0042ff47, 0x003efe3c, 0xfe3bfb4b, 0xfd3efc3a,
63 0xf742ff4f, 0x00470344, 0x0a2cf93e, 0x0f240e28, 0x101b0c1d, 0x012c1424,
64 0x1220052a, 0x01300a3e, 0x112e0940, 0xf468f561, 0xf060f958, 0xf855f955,
65 0xf755f358, 0x0442fd4d, 0xfd4cfa4c, 0x0a3aff4c, 0xff53f963, 0xf25f025f,
66 0x004cfb4a, 0x0046f54b, 0x01440041, 0xf249033e, 0x043eff44, 0xf34b0b37,
67 0x05400c46, 0x0f060613, 0x07100c0e, 0x120d0d0b, 0x0d0f0f10, 0x0c170d17,
68 0x0f140e1a, 0x0e2c1128, 0x112f1811, 0x15151916, 0x1f1b161d, 0x13230e32,
69 0x0a39073f, 0xfe4dfc52, 0xfd5e0945, 0xf46d24dd, 0x24de20e6, 0x25e22ce0,
70 0x22ee22f1, 0x28f121f9, 0x23fb2100, 0x2602210d, 0x17230d3a, 0x1dfd1a00,
71 0x161e1ff9, 0x23f122fd, 0x220324ff, 0x2205200b, 0x2305220c, 0x270b1e1d,
72 0x221a1d27, 0x13421f15, 0x1f1f1932, 0xef78ec70, 0xee72f555, 0xf15cf259,
73 0xe647f151, 0xf2500044, 0xf246e838, 0xe944e832, 0xf54a17f3, 0x1af328f1,
74 0x31f22c03, 0x2d062c22, 0x21361352, 0xfd4bff17, 0x0122012b, 0x0036fe37,
75 0x003d0140, 0x0044f75c, 0xf26af361, 0xf15af45a, 0xee58f649, 0xf74ff256,
76 0xf649f646, 0xf645fb42, 0xf740fb3a, 0x023b15f6, 0x18f51cf8, 0x1cff1d03,
77 0x1d092314, 0x1d240e43, 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968,
78 0xfa35ff36, 0x07331721, 0x17021500, 0x01090031, 0xdb760539, 0xf34ef541,
79 0x013e0c31, 0xfc491132, 0x1240092b, 0x1d001a43, 0x105a0968, 0xd27fec68,
80 0x0143f34e, 0xf541013e, 0xfa56ef5f, 0xfa3d092d, 0xfd45fa51, 0xf5600637,
81 0x0743fb56, 0x0258003a, 0xfd4cf65e, 0x05360445, 0xfd510058, 0xf943fb4a,
82 0xfc4afb50, 0xf948013a, 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948,
83 0x0d29033e, 0x002dfc4e, 0xfd60e57e, 0xe462e765, 0xe943e452, 0xec5ef053,
84 0xea6eeb5b, 0xee66f35d, 0xe37ff95c, 0xfb59f960, 0xf36cfd2e, 0xff41ff39,
85 0xf75dfd4a, 0xf75cf857, 0xe97e0536, 0x063c063b, 0x0645ff30, 0x0044fc45,
86 0xf858fe55, 0xfa4eff4b, 0xf94d0236, 0x0532fd44, 0x0132062a, 0xfc51013f,
87 0xfc460043, 0x0239fe4c, 0x0b230440, 0x013d0b23, 0x12190c18, 0x0d1d0d24,
88 0xf65df949, 0xfe490d2e, 0x0931f964, 0x09350235, 0x0535fe3d, 0x00380038,
89 0xf33ffb3c, 0xff3e0439, 0xfa450439, 0x0e270433, 0x0d440340, 0x013d093f,
90 0x07321027, 0x052c0434, 0x0b30fb3c, 0xff3b003b, 0x1621052c, 0x0e2bff4e,
91 0x003c0945, 0x0b1c0228, 0x032c0031, 0x002e022c, 0x0233002f, 0x0427023e,
92 0x062e0036, 0x0336023a, 0x043f0633, 0x06390735, 0x06340637, 0x0b2d0e24,
93 0x0835ff52, 0x0737fd4e, 0x0f2e161f, 0xff541907, 0x1ef91c03, 0x1c042000,
94 0x22ff1e06, 0x1e062009, 0x1f131a1b, 0x1a1e2514, 0x1c221146, 0x0143053b,
95 0x0943101e, 0x12201223, 0x161d181f, 0x1726122b, 0x14290b3f, 0x093b0940,
96 0xff5efe59, 0xf76cfa4c, 0xfe2c002d, 0x0034fd40, 0xfe3bfc46, 0xfc4bf852,
97 0xef66f74d, 0x0318002a, 0x00300037, 0xfa3bf947, 0xf453f557, 0xe277013a,
98 0xfd1dff24, 0x0126022b, 0xfa37003a, 0x0040fd4a, 0xf65a0046, 0xfc1d051f,
99 0x072a013b, 0xfe3afd48, 0xfd51f561, 0x003a0805, 0x0a0e0e12, 0x0d1b0228,
100 0x003afd46, 0xfa4ff855, 0x0000f36a, 0xf06af657, 0xeb72ee6e, 0xf262ea6e,
101 0xeb6aee67, 0xeb6be96c, 0xe670f660, 0xf45ffb5b, 0xf75dea5e, 0xfb560943,
102 0xfc50f655, 0xff46073c, 0x093a053d, 0x0c320f32, 0x12311136, 0x0a29072e,
103 0xff330731, 0x08340929, 0x062f0237, 0x0d290a2c, 0x06320535, 0x0d31043f,
104 0x0640fe45, 0xfe3b0646, 0x0a2c091f, 0x0c2b0335, 0x0e220a26, 0xfd340d28,
105 0x1120072c, 0x07260d32, 0x0a391a2b, 0x0e0b0b0e, 0x090b120b, 0x150917fe,
106 0x20f120f1, 0x22eb27e9, 0x2adf29e1, 0x2ee426f4, 0x151d2de8, 0x35d330e6,
107 0x41d52bed, 0x27f61e09, 0x121a141b, 0x0039f252, 0xfb4bed61, 0xdd7d1b00,
108 0x1c001ffc, 0x1b062208, 0x1e0a1816, 0x21131620, 0x1a1f1529, 0x1a2c172f,
109 0x10410e47, 0x083c063f, 0x11411518, 0x17141a17, 0x1b201c17, 0x1c181728,
110 0x18201c1d, 0x172a1339, 0x1635163d, 0x0b560c28, 0x0b330e3b, 0xfc4ff947,
111 0xfb45f746, 0xf842f644, 0xed49f445, 0xf046f143, 0xec3eed46, 0xf042ea41,
112 0xec3f09fe, 0x1af721f7, 0x27f929fe, 0x2d033109, 0x2d1b243b, 0xfa42f923,
113 0xf92af82d, 0xfb30f438, 0xfa3cfb3e, 0xf842f84c, 0xfb55fa51, 0xf64df951,
114 0xef50ee49, 0xfc4af653, 0xf747f743, 0xff3df842, 0xf242003b, 0x023b15f3,
115 0x21f227f9, 0x2efe3302, 0x3c063d11, 0x37222a3e, 0x14f10236, 0x034a14f1,
116 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331619, 0x22001000, 0xfe090429,
117 0xe3760241, 0xfa47f34f, 0x05340932, 0xfd460a36, 0x1a221316, 0x28003902,
118 0x29241a45, 0xd37ff165, 0xfc4cfa47, 0xf34f0534, 0x0645f35a, 0x0034082b,
119 0xfe45fb52, 0xf660023b, 0x024bfd57, 0xfd640138, 0xfd4afa55, 0x003bfd51,
120 0xf956fb5f, 0xff42ff4d, 0x0146fe56, 0xfb48003d, 0x0029003f, 0x003f003f,
121 0xf7530456, 0x0061f948, 0x0d29033e, 0x0d0f0733, 0x0250d97f, 0xee5bef60,
122 0xe651dd62, 0xe866e961, 0xe577e863, 0xeb6eee66, 0xdc7f0050, 0xfb59f95e,
123 0xfc5c0027, 0x0041f154, 0xdd7ffe49, 0xf468f75b, 0xe17f0337, 0x07380737,
124 0x083dfd35, 0x0044f94a, 0xf758f367, 0xf35bf759, 0xf25cf84c, 0xf457e96e,
125 0xe869f64e, 0xec70ef63, 0xb27fba7f, 0xce7fd27f, 0xfc42fb4e, 0xfc47f848,
126 0x023bff37, 0xf946fa4b, 0xf859de77, 0xfd4b2014, 0x1e16d47f, 0x0036fb3d,
127 0x003aff3c, 0xfd3df843, 0xe754f24a, 0xfb410534, 0x0239003d, 0xf745f546,
128 0x1237fc47, 0x003a073d, 0x09291219, 0x0920052b, 0x092f002c, 0x0033022e,
129 0x1326fc42, 0x0f260c2a, 0x09220059, 0x042d0a1c, 0x0a1f21f5, 0x34d5120f,
130 0x1c0023ea, 0x26e72200, 0x27ee20f4, 0x66a20000, 0x38f121fc, 0x1d0a25fb,
131 0x33e327f7, 0x34de45c6, 0x43c12cfb, 0x200737e3, 0x20010000, 0x1b2421e7,
132 0x22e224e4, 0x26e426e5, 0x22ee23f0, 0x22f220f8, 0x25fa2300, 0x1e0a1c12,
133 0x1a191d29, 0x004b0248, 0x084d0e23, 0x121f1123, 0x151e112d, 0x142a122d,
134 0x1b1a1036, 0x07421038, 0x0b490a43, 0xf674e970, 0xf147f93d, 0x0035fb42,
135 0xf54df750, 0xf754f657, 0xde7feb65, 0xfd27fb35, 0xf93df54b, 0xf14def5b,
136 0xe76be76f, 0xe47af54c, 0xf62cf634, 0xf639f73a, 0xf048f945, 0xfc45fb4a,
137 0xf7560242, 0xf7220120, 0x0b1f0534, 0xfe37fe43, 0x0049f859, 0x03340704,
138 0x0a081108, 0x10130325, 0xff3dfb49, 0xff46fc4e, 0x0000eb7e, 0xe97cec6e,
139 0xe67ee77c, 0xef69e579, 0xe575ef66, 0xe675e574, 0xdf7af65f, 0xf264f85f,
140 0xef6fe472, 0xfa59fe50, 0xfc52f755, 0xf851ff48, 0x05400143, 0x09380045,
141 0x01450745, 0xf945fa43, 0xf04dfe40, 0x023dfa43, 0xfd400239, 0xfd41fd42,
142 0x003e0933, 0xff42fe47, 0xfe4bff46, 0xf7480e3c, 0x1025002f, 0x12230b25,
143 0x0c290a29, 0x02300c29, 0x0d29003b, 0x03321328, 0x03421232, 0x13fa12fa,
144 0x0e001af4, 0x1ff021e7, 0x21ea25e4, 0x27e22ae2, 0x2fd62ddc, 0x31de29ef,
145 0x200945b9, 0x3fc142c0, 0x4db636d9, 0x34dd29f6, 0x240028ff, 0x1e0e1c1a,
146 0x17250c37, 0x0b4125df, 0x27dc28db, 0x26e22edf, 0x2ae228e8, 0x31e326f4,
147 0x28f626fd, 0x2efb1f14, 0x1d1e192c, 0x0c300b31, 0x1a2d1616, 0x17161b15,
148 0x21141a1c, 0x1e181b22, 0x122a1927, 0x12320c46, 0x15360e47, 0x0b531920,
149 0x15311536, 0xfb55fa51, 0xf64df951, 0xef50ee49, 0xfc4af653, 0xf747f743,
150 0xff3df842, 0xf242003b, 0x023b11f6, 0x20f32af7, 0x31fb3500, 0x4003440a,
151 0x421b2f39, 0xfb470018, 0xff24fe2a, 0xfe34f739, 0xfa3ffc41, 0xfc43f952,
152 0xfd51fd4c, 0xf948fa4e, 0xf448f244, 0xfd46fa4c, 0xfb42fb3e, 0x0039fc3d,
153 0xf73c0136, 0x023a11f6, 0x20f32af7, 0x31fb3500, 0x4003440a, 0x421b2f39,
154 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331d10,
155 0x19000e00, 0xf633fd3e, 0xe5631a10, 0xfc55e866, 0x05390639, 0xef490e39,
156 0x1428140a, 0x1d003600, 0x252a0c61, 0xe07fea75, 0xfe4afc55, 0xe8660539,
157 0xfa5df258, 0xfa2c0437, 0xf559f167, 0xeb741339, 0x143a0454, 0x0660013f,
158 0xfb55f36a, 0x053f064b, 0xfd5aff65, 0x0337fc4f, 0xfe4bf461, 0xf932013c,
159 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x0722f758,
160 0xec7fdc7f, 0xef5bf25f, 0xe754e756, 0xf459ef5b, 0xe17ff24c, 0xee67f35a,
161 0xdb7f0b50, 0x054c0254, 0x054efa37, 0x043df253, 0xdb7ffb4f, 0xf568f55b,
162 0xe27f0041, 0xfe4f0048, 0xfc5cfa38, 0x0344f847, 0xf362fc56, 0xf458fb52,
163 0xfd48fc43, 0xf848f059, 0xf745ff3b, 0x05420439, 0xfc47fe47, 0x023aff4a,
164 0xfc2cff45, 0x003ef933, 0xfc2ffa2a, 0xfd29fa35, 0x084cf74e, 0xf5530934,
165 0x0043fb5a, 0x0143f148, 0xfb4bf850, 0xeb53eb40, 0xf31fe740, 0xe35e094b,
166 0x113ff84a, 0xfb23fe1b, 0x0d5b0341, 0xf945084d, 0xf642033e, 0xfd44ec51,
167 0x001e0107, 0xfd17eb4a, 0x1042e97c, 0x11252cee, 0x32deea7f, 0x0427002a,
168 0x07220b1d, 0x081f0625, 0x072a0328, 0x08210d2b, 0x0d24042f, 0x0337023a,
169 0x063c082c, 0x0b2c0e2a, 0x07300438, 0x04340d25, 0x0931133a, 0x0a300c2d,
170 0x00451421, 0x083f23ee, 0x21e71cfd, 0x180a1b00, 0x22f234d4, 0x27e81311,
171 0x1f19241d, 0x1821220f, 0x1e141649, 0x1422131f, 0x1b2c1310, 0x0f240f24,
172 0x151c1915, 0x1e141f0c, 0x1b10182a, 0x005d0e38, 0x0f391a26, 0xe87fe873,
173 0xea52f73e, 0x0035003b, 0xf255f359, 0xf35ef55c, 0xe37feb64, 0xf239f443,
174 0xf547f64d, 0xeb55f058, 0xe968f162, 0xdb7ff652, 0xf830f83d, 0xf842f946,
175 0xf24bf64f, 0xf753f45c, 0xee6cfc4f, 0xea45f04b, 0xfe3a013a, 0xf34ef753,
176 0xfc51f363, 0xf351fa26, 0xf33efa3a, 0xfe3bf049, 0xf64cf356, 0xf753f657,
177 0x0000ea7f, 0xe77fe778, 0xe57fed72, 0xe975e776, 0xe675e871, 0xe476e178,
178 0xdb7cf65e, 0xf166f663, 0xf36ace7f, 0xfb5c1139, 0xfb56f35e, 0xf45bfe4d,
179 0x0047ff49, 0x0440f951, 0x05400f39, 0x01430044, 0xf6430144, 0x004d0240,
180 0x0044fb4e, 0x0737053b, 0x02410e36, 0x0f2c053c, 0x0246fe4c, 0xee560c46,
181 0x0540f446, 0x0b370538, 0x00450241, 0xfa4a0536, 0x0736fa4c, 0xf552fe4d,
182 0xfe4d192a, 0x11f310f7, 0x11f41beb, 0x25e229d8, 0x2ad730d1, 0x27e02ed8,
183 0x34cd2ed7, 0x34d92bed, 0x200b3dc9, 0x38d23ece, 0x51bd2dec, 0x23fe1c0f,
184 0x22012701, 0x1e111426, 0x122d0f36, 0x004f24f0, 0x25f225ef, 0x2001220f,
185 0x1d0f1819, 0x22161f10, 0x23121f1c, 0x2129241c, 0x1b2f153e, 0x121f131a,
186 0x24181817, 0x1b10181e, 0x1f1d1629, 0x162a103c, 0x0f340e3c, 0x034ef07b,
187 0x15351638, 0x193d1521, 0x1332113d, 0xfd4ef84a, 0xf748f648, 0xee4bf447,
188 0xf53ffb46, 0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc,
189 0x21ff2107, 0x1f0c2517, 0x1f261440, 0xf747f925, 0xf82cf531, 0xf638f43b,
190 0xf83ff743, 0xfa44f64f, 0xfd4ef84a, 0xf748f648, 0xee4bf447, 0xf53ffb46,
191 0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc, 0x21ff2107,
192 0x1f0c2517, 0x1f261440
193 };
194
195 static void
assemble_scaling_list(struct hantro_ctx * ctx)196 assemble_scaling_list(struct hantro_ctx *ctx)
197 {
198 const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls;
199 const struct v4l2_ctrl_h264_scaling_matrix *scaling = ctrls->scaling;
200 const struct v4l2_ctrl_h264_pps *pps = ctrls->pps;
201 const size_t num_list_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4);
202 const size_t list_len_4x4 = ARRAY_SIZE(scaling->scaling_list_4x4[0]);
203 const size_t list_len_8x8 = ARRAY_SIZE(scaling->scaling_list_8x8[0]);
204 struct hantro_h264_dec_priv_tbl *tbl = ctx->h264_dec.priv.cpu;
205 u32 *dst = (u32 *)tbl->scaling_list;
206 const u32 *src;
207 int i, j;
208
209 if (!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT))
210 return;
211
212 for (i = 0; i < num_list_4x4; i++) {
213 src = (u32 *)&scaling->scaling_list_4x4[i];
214 for (j = 0; j < list_len_4x4 / 4; j++)
215 *dst++ = swab32(src[j]);
216 }
217
218 /* Only Intra/Inter Y lists */
219 for (i = 0; i < 2; i++) {
220 src = (u32 *)&scaling->scaling_list_8x8[i];
221 for (j = 0; j < list_len_8x8 / 4; j++)
222 *dst++ = swab32(src[j]);
223 }
224 }
225
prepare_table(struct hantro_ctx * ctx)226 static void prepare_table(struct hantro_ctx *ctx)
227 {
228 const struct hantro_h264_dec_ctrls *ctrls = &ctx->h264_dec.ctrls;
229 const struct v4l2_ctrl_h264_decode_params *dec_param = ctrls->decode;
230 struct hantro_h264_dec_priv_tbl *tbl = ctx->h264_dec.priv.cpu;
231 const struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
232 u32 dpb_longterm = 0;
233 u32 dpb_valid = 0;
234 int i;
235
236 for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) {
237 tbl->poc[i * 2] = dpb[i].top_field_order_cnt;
238 tbl->poc[i * 2 + 1] = dpb[i].bottom_field_order_cnt;
239
240 /*
241 * Set up bit maps of valid and long term DPBs.
242 * NOTE: The bits are reversed, i.e. MSb is DPB 0.
243 */
244 if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
245 dpb_valid |= BIT(HANTRO_H264_DPB_SIZE - 1 - i);
246 if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
247 dpb_longterm |= BIT(HANTRO_H264_DPB_SIZE - 1 - i);
248 }
249 ctx->h264_dec.dpb_valid = dpb_valid << 16;
250 ctx->h264_dec.dpb_longterm = dpb_longterm << 16;
251
252 tbl->poc[32] = dec_param->top_field_order_cnt;
253 tbl->poc[33] = dec_param->bottom_field_order_cnt;
254
255 assemble_scaling_list(ctx);
256 }
257
dpb_entry_match(const struct v4l2_h264_dpb_entry * a,const struct v4l2_h264_dpb_entry * b)258 static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
259 const struct v4l2_h264_dpb_entry *b)
260 {
261 return a->top_field_order_cnt == b->top_field_order_cnt &&
262 a->bottom_field_order_cnt == b->bottom_field_order_cnt;
263 }
264
update_dpb(struct hantro_ctx * ctx)265 static void update_dpb(struct hantro_ctx *ctx)
266 {
267 const struct v4l2_ctrl_h264_decode_params *dec_param;
268 DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
269 DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
270 unsigned int i, j;
271
272 dec_param = ctx->h264_dec.ctrls.decode;
273
274 /* Disable all entries by default. */
275 for (i = 0; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++)
276 ctx->h264_dec.dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
277
278 /* Try to match new DPB entries with existing ones by their POCs. */
279 for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
280 const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
281
282 if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
283 continue;
284
285 /*
286 * To cut off some comparisons, iterate only on target DPB
287 * entries which are not used yet.
288 */
289 for_each_clear_bit(j, used, ARRAY_SIZE(ctx->h264_dec.dpb)) {
290 struct v4l2_h264_dpb_entry *cdpb;
291
292 cdpb = &ctx->h264_dec.dpb[j];
293 if (cdpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE ||
294 !dpb_entry_match(cdpb, ndpb))
295 continue;
296
297 *cdpb = *ndpb;
298 set_bit(j, used);
299 break;
300 }
301
302 if (j == ARRAY_SIZE(ctx->h264_dec.dpb))
303 set_bit(i, new);
304 }
305
306 /* For entries that could not be matched, use remaining free slots. */
307 for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
308 const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
309 struct v4l2_h264_dpb_entry *cdpb;
310
311 /*
312 * Both arrays are of the same sizes, so there is no way
313 * we can end up with no space in target array, unless
314 * something is buggy.
315 */
316 j = find_first_zero_bit(used, ARRAY_SIZE(ctx->h264_dec.dpb));
317 if (WARN_ON(j >= ARRAY_SIZE(ctx->h264_dec.dpb)))
318 return;
319
320 cdpb = &ctx->h264_dec.dpb[j];
321 *cdpb = *ndpb;
322 set_bit(j, used);
323 }
324 }
325
hantro_h264_get_ref_buf(struct hantro_ctx * ctx,unsigned int dpb_idx)326 dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
327 unsigned int dpb_idx)
328 {
329 struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
330 dma_addr_t dma_addr = 0;
331
332 if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
333 dma_addr = hantro_get_ref(ctx, dpb[dpb_idx].reference_ts);
334
335 if (!dma_addr) {
336 struct vb2_v4l2_buffer *dst_buf;
337 struct vb2_buffer *buf;
338
339 /*
340 * If a DPB entry is unused or invalid, address of current
341 * destination buffer is returned.
342 */
343 dst_buf = hantro_get_dst_buf(ctx);
344 buf = &dst_buf->vb2_buf;
345 dma_addr = hantro_get_dec_buf_addr(ctx, buf);
346 }
347
348 return dma_addr;
349 }
350
hantro_h264_get_ref_nbr(struct hantro_ctx * ctx,unsigned int dpb_idx)351 u16 hantro_h264_get_ref_nbr(struct hantro_ctx *ctx, unsigned int dpb_idx)
352 {
353 const struct v4l2_h264_dpb_entry *dpb = &ctx->h264_dec.dpb[dpb_idx];
354
355 if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
356 return 0;
357 return dpb->frame_num;
358 }
359
hantro_h264_dec_prepare_run(struct hantro_ctx * ctx)360 int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx)
361 {
362 struct hantro_h264_dec_hw_ctx *h264_ctx = &ctx->h264_dec;
363 struct hantro_h264_dec_ctrls *ctrls = &h264_ctx->ctrls;
364 struct v4l2_h264_reflist_builder reflist_builder;
365
366 hantro_start_prepare_run(ctx);
367
368 ctrls->scaling =
369 hantro_get_ctrl(ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
370 if (WARN_ON(!ctrls->scaling))
371 return -EINVAL;
372
373 ctrls->decode =
374 hantro_get_ctrl(ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
375 if (WARN_ON(!ctrls->decode))
376 return -EINVAL;
377
378 ctrls->sps =
379 hantro_get_ctrl(ctx, V4L2_CID_STATELESS_H264_SPS);
380 if (WARN_ON(!ctrls->sps))
381 return -EINVAL;
382
383 ctrls->pps =
384 hantro_get_ctrl(ctx, V4L2_CID_STATELESS_H264_PPS);
385 if (WARN_ON(!ctrls->pps))
386 return -EINVAL;
387
388 /* Update the DPB with new refs. */
389 update_dpb(ctx);
390
391 /* Prepare data in memory. */
392 prepare_table(ctx);
393
394 /* Build the P/B{0,1} ref lists. */
395 v4l2_h264_init_reflist_builder(&reflist_builder, ctrls->decode,
396 ctrls->sps, ctx->h264_dec.dpb);
397 v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p);
398 v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0,
399 h264_ctx->reflists.b1);
400 return 0;
401 }
402
hantro_h264_dec_exit(struct hantro_ctx * ctx)403 void hantro_h264_dec_exit(struct hantro_ctx *ctx)
404 {
405 struct hantro_dev *vpu = ctx->dev;
406 struct hantro_h264_dec_hw_ctx *h264_dec = &ctx->h264_dec;
407 struct hantro_aux_buf *priv = &h264_dec->priv;
408
409 dma_free_coherent(vpu->dev, priv->size, priv->cpu, priv->dma);
410 }
411
hantro_h264_dec_init(struct hantro_ctx * ctx)412 int hantro_h264_dec_init(struct hantro_ctx *ctx)
413 {
414 struct hantro_dev *vpu = ctx->dev;
415 struct hantro_h264_dec_hw_ctx *h264_dec = &ctx->h264_dec;
416 struct hantro_aux_buf *priv = &h264_dec->priv;
417 struct hantro_h264_dec_priv_tbl *tbl;
418
419 priv->cpu = dma_alloc_coherent(vpu->dev, sizeof(*tbl), &priv->dma,
420 GFP_KERNEL);
421 if (!priv->cpu)
422 return -ENOMEM;
423
424 priv->size = sizeof(*tbl);
425 tbl = priv->cpu;
426 memcpy(tbl->cabac_table, h264_cabac_table, sizeof(tbl->cabac_table));
427
428 return 0;
429 }
430