Merge tag 'hwlock-v5.3' of git://github.com/andersson/remoteproc
[linux-2.6-microblaze.git] / lib / raid6 / recov_neon.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2012 Intel Corporation
4  * Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
5  */
6
7 #include <linux/raid/pq.h>
8
9 #ifdef __KERNEL__
10 #include <asm/neon.h>
11 #else
12 #define kernel_neon_begin()
13 #define kernel_neon_end()
14 #define cpu_has_neon()          (1)
15 #endif
16
17 static int raid6_has_neon(void)
18 {
19         return cpu_has_neon();
20 }
21
22 void __raid6_2data_recov_neon(int bytes, uint8_t *p, uint8_t *q, uint8_t *dp,
23                               uint8_t *dq, const uint8_t *pbmul,
24                               const uint8_t *qmul);
25
26 void __raid6_datap_recov_neon(int bytes, uint8_t *p, uint8_t *q, uint8_t *dq,
27                               const uint8_t *qmul);
28
29 static void raid6_2data_recov_neon(int disks, size_t bytes, int faila,
30                 int failb, void **ptrs)
31 {
32         u8 *p, *q, *dp, *dq;
33         const u8 *pbmul;        /* P multiplier table for B data */
34         const u8 *qmul;         /* Q multiplier table (for both) */
35
36         p = (u8 *)ptrs[disks - 2];
37         q = (u8 *)ptrs[disks - 1];
38
39         /*
40          * Compute syndrome with zero for the missing data pages
41          * Use the dead data pages as temporary storage for
42          * delta p and delta q
43          */
44         dp = (u8 *)ptrs[faila];
45         ptrs[faila] = (void *)raid6_empty_zero_page;
46         ptrs[disks - 2] = dp;
47         dq = (u8 *)ptrs[failb];
48         ptrs[failb] = (void *)raid6_empty_zero_page;
49         ptrs[disks - 1] = dq;
50
51         raid6_call.gen_syndrome(disks, bytes, ptrs);
52
53         /* Restore pointer table */
54         ptrs[faila]     = dp;
55         ptrs[failb]     = dq;
56         ptrs[disks - 2] = p;
57         ptrs[disks - 1] = q;
58
59         /* Now, pick the proper data tables */
60         pbmul = raid6_vgfmul[raid6_gfexi[failb-faila]];
61         qmul  = raid6_vgfmul[raid6_gfinv[raid6_gfexp[faila] ^
62                                          raid6_gfexp[failb]]];
63
64         kernel_neon_begin();
65         __raid6_2data_recov_neon(bytes, p, q, dp, dq, pbmul, qmul);
66         kernel_neon_end();
67 }
68
69 static void raid6_datap_recov_neon(int disks, size_t bytes, int faila,
70                 void **ptrs)
71 {
72         u8 *p, *q, *dq;
73         const u8 *qmul;         /* Q multiplier table */
74
75         p = (u8 *)ptrs[disks - 2];
76         q = (u8 *)ptrs[disks - 1];
77
78         /*
79          * Compute syndrome with zero for the missing data page
80          * Use the dead data page as temporary storage for delta q
81          */
82         dq = (u8 *)ptrs[faila];
83         ptrs[faila] = (void *)raid6_empty_zero_page;
84         ptrs[disks - 1] = dq;
85
86         raid6_call.gen_syndrome(disks, bytes, ptrs);
87
88         /* Restore pointer table */
89         ptrs[faila]     = dq;
90         ptrs[disks - 1] = q;
91
92         /* Now, pick the proper data tables */
93         qmul = raid6_vgfmul[raid6_gfinv[raid6_gfexp[faila]]];
94
95         kernel_neon_begin();
96         __raid6_datap_recov_neon(bytes, p, q, dq, qmul);
97         kernel_neon_end();
98 }
99
100 const struct raid6_recov_calls raid6_recov_neon = {
101         .data2          = raid6_2data_recov_neon,
102         .datap          = raid6_datap_recov_neon,
103         .valid          = raid6_has_neon,
104         .name           = "neon",
105         .priority       = 10,
106 };