GNU Linux-libre 5.10.219-gnu1
[releases.git] / drivers / staging / media / hantro / hantro_h264.c
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
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
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         int i;
233
234         for (i = 0; i < HANTRO_H264_DPB_SIZE; ++i) {
235                 tbl->poc[i * 2] = dpb[i].top_field_order_cnt;
236                 tbl->poc[i * 2 + 1] = dpb[i].bottom_field_order_cnt;
237         }
238
239         tbl->poc[32] = dec_param->top_field_order_cnt;
240         tbl->poc[33] = dec_param->bottom_field_order_cnt;
241
242         assemble_scaling_list(ctx);
243 }
244
245 static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
246                             const struct v4l2_h264_dpb_entry *b)
247 {
248         return a->top_field_order_cnt == b->top_field_order_cnt &&
249                a->bottom_field_order_cnt == b->bottom_field_order_cnt;
250 }
251
252 static void update_dpb(struct hantro_ctx *ctx)
253 {
254         const struct v4l2_ctrl_h264_decode_params *dec_param;
255         DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
256         DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
257         unsigned int i, j;
258
259         dec_param = ctx->h264_dec.ctrls.decode;
260
261         /* Disable all entries by default. */
262         for (i = 0; i < ARRAY_SIZE(ctx->h264_dec.dpb); i++)
263                 ctx->h264_dec.dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
264
265         /* Try to match new DPB entries with existing ones by their POCs. */
266         for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
267                 const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
268
269                 if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
270                         continue;
271
272                 /*
273                  * To cut off some comparisons, iterate only on target DPB
274                  * entries which are not used yet.
275                  */
276                 for_each_clear_bit(j, used, ARRAY_SIZE(ctx->h264_dec.dpb)) {
277                         struct v4l2_h264_dpb_entry *cdpb;
278
279                         cdpb = &ctx->h264_dec.dpb[j];
280                         if (cdpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE ||
281                             !dpb_entry_match(cdpb, ndpb))
282                                 continue;
283
284                         *cdpb = *ndpb;
285                         set_bit(j, used);
286                         break;
287                 }
288
289                 if (j == ARRAY_SIZE(ctx->h264_dec.dpb))
290                         set_bit(i, new);
291         }
292
293         /* For entries that could not be matched, use remaining free slots. */
294         for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
295                 const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
296                 struct v4l2_h264_dpb_entry *cdpb;
297
298                 /*
299                  * Both arrays are of the same sizes, so there is no way
300                  * we can end up with no space in target array, unless
301                  * something is buggy.
302                  */
303                 j = find_first_zero_bit(used, ARRAY_SIZE(ctx->h264_dec.dpb));
304                 if (WARN_ON(j >= ARRAY_SIZE(ctx->h264_dec.dpb)))
305                         return;
306
307                 cdpb = &ctx->h264_dec.dpb[j];
308                 *cdpb = *ndpb;
309                 set_bit(j, used);
310         }
311 }
312
313 dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx,
314                                    unsigned int dpb_idx)
315 {
316         struct v4l2_h264_dpb_entry *dpb = ctx->h264_dec.dpb;
317         dma_addr_t dma_addr = 0;
318
319         if (dpb[dpb_idx].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
320                 dma_addr = hantro_get_ref(ctx, dpb[dpb_idx].reference_ts);
321
322         if (!dma_addr) {
323                 struct vb2_v4l2_buffer *dst_buf;
324                 struct vb2_buffer *buf;
325
326                 /*
327                  * If a DPB entry is unused or invalid, address of current
328                  * destination buffer is returned.
329                  */
330                 dst_buf = hantro_get_dst_buf(ctx);
331                 buf = &dst_buf->vb2_buf;
332                 dma_addr = hantro_get_dec_buf_addr(ctx, buf);
333         }
334
335         return dma_addr;
336 }
337
338 int hantro_h264_dec_prepare_run(struct hantro_ctx *ctx)
339 {
340         struct hantro_h264_dec_hw_ctx *h264_ctx = &ctx->h264_dec;
341         struct hantro_h264_dec_ctrls *ctrls = &h264_ctx->ctrls;
342         struct v4l2_h264_reflist_builder reflist_builder;
343
344         hantro_start_prepare_run(ctx);
345
346         ctrls->scaling =
347                 hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX);
348         if (WARN_ON(!ctrls->scaling))
349                 return -EINVAL;
350
351         ctrls->decode =
352                 hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
353         if (WARN_ON(!ctrls->decode))
354                 return -EINVAL;
355
356         ctrls->sps =
357                 hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_H264_SPS);
358         if (WARN_ON(!ctrls->sps))
359                 return -EINVAL;
360
361         ctrls->pps =
362                 hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_H264_PPS);
363         if (WARN_ON(!ctrls->pps))
364                 return -EINVAL;
365
366         /* Update the DPB with new refs. */
367         update_dpb(ctx);
368
369         /* Prepare data in memory. */
370         prepare_table(ctx);
371
372         /* Build the P/B{0,1} ref lists. */
373         v4l2_h264_init_reflist_builder(&reflist_builder, ctrls->decode,
374                                        ctrls->sps, ctx->h264_dec.dpb);
375         v4l2_h264_build_p_ref_list(&reflist_builder, h264_ctx->reflists.p);
376         v4l2_h264_build_b_ref_lists(&reflist_builder, h264_ctx->reflists.b0,
377                                     h264_ctx->reflists.b1);
378         return 0;
379 }
380
381 void hantro_h264_dec_exit(struct hantro_ctx *ctx)
382 {
383         struct hantro_dev *vpu = ctx->dev;
384         struct hantro_h264_dec_hw_ctx *h264_dec = &ctx->h264_dec;
385         struct hantro_aux_buf *priv = &h264_dec->priv;
386
387         dma_free_coherent(vpu->dev, priv->size, priv->cpu, priv->dma);
388 }
389
390 int hantro_h264_dec_init(struct hantro_ctx *ctx)
391 {
392         struct hantro_dev *vpu = ctx->dev;
393         struct hantro_h264_dec_hw_ctx *h264_dec = &ctx->h264_dec;
394         struct hantro_aux_buf *priv = &h264_dec->priv;
395         struct hantro_h264_dec_priv_tbl *tbl;
396
397         priv->cpu = dma_alloc_coherent(vpu->dev, sizeof(*tbl), &priv->dma,
398                                        GFP_KERNEL);
399         if (!priv->cpu)
400                 return -ENOMEM;
401
402         priv->size = sizeof(*tbl);
403         tbl = priv->cpu;
404         memcpy(tbl->cabac_table, h264_cabac_table, sizeof(tbl->cabac_table));
405
406         return 0;
407 }