xref: /rk3399_rockchip-uboot/include/rockchip/crypto_v2_pka.h (revision b353a43c9e441e8665efd1cc47824714ad67ed3f)
1*b353a43cSLin Jinhan // SPDX-License-Identifier: GPL-2.0
2*b353a43cSLin Jinhan /*
3*b353a43cSLin Jinhan  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4*b353a43cSLin Jinhan  */
5*b353a43cSLin Jinhan 
6*b353a43cSLin Jinhan #ifndef _ROCKCHIP_CRYPTO_V2_PKA_H_
7*b353a43cSLin Jinhan #define _ROCKCHIP_CRYPTO_V2_PKA_H_
8*b353a43cSLin Jinhan #include <common.h>
9*b353a43cSLin Jinhan #include <rockchip/crypto_v2.h>
10*b353a43cSLin Jinhan #include <rockchip/crypto_v2_util.h>
11*b353a43cSLin Jinhan 
12*b353a43cSLin Jinhan #define CRYPTO_BASE crypto_base
13*b353a43cSLin Jinhan 
14*b353a43cSLin Jinhan struct mpa_num {
15*b353a43cSLin Jinhan 	u32 alloc;
16*b353a43cSLin Jinhan 	s32 size;
17*b353a43cSLin Jinhan 	u32 *d;
18*b353a43cSLin Jinhan };
19*b353a43cSLin Jinhan 
20*b353a43cSLin Jinhan #define RK_MAX_RSA_NBITS	4096
21*b353a43cSLin Jinhan #define RK_MAX_RSA_NCHARS	((RK_MAX_RSA_NBITS) / 8)
22*b353a43cSLin Jinhan #define RK_MAX_RSA_BWORDS	((RK_MAX_RSA_NBITS) / 32)
23*b353a43cSLin Jinhan 
24*b353a43cSLin Jinhan /* define NpCreateFlag values */
25*b353a43cSLin Jinhan #define RK_PKA_CREATE_NP		1
26*b353a43cSLin Jinhan #define RK_PKA_SET_NP		0
27*b353a43cSLin Jinhan /* size of buffer for Barrett modulus tag NP, used in PKI algorithms */
28*b353a43cSLin Jinhan #define RK_PKA_BARRETT_IN_WORDS	5
29*b353a43cSLin Jinhan /* Barrett modulus tag type - 5 words size array */
30*b353a43cSLin Jinhan typedef u32 RK_PKA_NP_t[RK_PKA_BARRETT_IN_WORDS];
31*b353a43cSLin Jinhan 
32*b353a43cSLin Jinhan #define RK_PKA_MemSetZero(buf, size) \
33*b353a43cSLin Jinhan 			util_word_memset((void *)buf, 0x00, size)
34*b353a43cSLin Jinhan 
35*b353a43cSLin Jinhan #define RK_PKA_FastMemCpy(dst, src, size) \
36*b353a43cSLin Jinhan 			util_word_memcpy((void *)dst, (void *)src, size)
37*b353a43cSLin Jinhan 
38*b353a43cSLin Jinhan #define RK_PKA_ReverseMemcpy(dst, src, size) \
39*b353a43cSLin Jinhan 			util_reverse_word_memcpy((void *)dst, (void *)src, size)
40*b353a43cSLin Jinhan 
41*b353a43cSLin Jinhan #define RES_DISCARD 0x3F
42*b353a43cSLin Jinhan 
43*b353a43cSLin Jinhan /* base address -  0x00F10B00 */
44*b353a43cSLin Jinhan #define RK_PKI_ERROR_BASE			0x00F10B00
45*b353a43cSLin Jinhan #define RK_PKI_HW_VER_INCORRECT_ERROR		(RK_PKI_ERROR_BASE + 0x0UL)
46*b353a43cSLin Jinhan #define RK_PKI_HW_DECRYPED_ERROR		(RK_PKI_ERROR_BASE + 0x1UL)
47*b353a43cSLin Jinhan #define RK_PKI_KEY_SIZE_ERROR			(RK_PKI_ERROR_BASE + 0x2UL)
48*b353a43cSLin Jinhan 
49*b353a43cSLin Jinhan /* Error definitions for PKA using */
50*b353a43cSLin Jinhan #define RK_PKA_ILLEGAL_PTR_ERROR		(RK_PKI_ERROR_BASE + 0x20UL)
51*b353a43cSLin Jinhan #define RK_PKA_ENTRIES_COUNT_ERROR		(RK_PKI_ERROR_BASE + 0x21UL)
52*b353a43cSLin Jinhan #define RK_PKA_REGISTER_SIZES_ERROR		(RK_PKI_ERROR_BASE + 0x22UL)
53*b353a43cSLin Jinhan #define RK_PKA_SET_MAP_MODE_ERROR		(RK_PKI_ERROR_BASE + 0x23UL)
54*b353a43cSLin Jinhan 
55*b353a43cSLin Jinhan #define RK_PKA_DIVIDER_IS_NULL_ERROR		(RK_PKI_ERROR_BASE + 0x2EUL)
56*b353a43cSLin Jinhan #define RK_PKA_MODULUS_IS_NULL_ERROR		(RK_PKI_ERROR_BASE + 0x2FUL)
57*b353a43cSLin Jinhan #define RK_PKA_DATA_SIZE_ERROR			(RK_PKI_ERROR_BASE + 0x30UL)
58*b353a43cSLin Jinhan #define RK_PKA_OPERATION_SIZE_ERROR		(RK_PKI_ERROR_BASE + 0x31UL)
59*b353a43cSLin Jinhan 
60*b353a43cSLin Jinhan #define RK_PKA_MAX_REGS_COUNT			8
61*b353a43cSLin Jinhan #define RK_PKA_MAX_PHYS_MEM_REGS_COUNT		32
62*b353a43cSLin Jinhan #define RK_PKA_MAX_REGS_MEM_SIZE_BYTES		4096
63*b353a43cSLin Jinhan 
64*b353a43cSLin Jinhan /* PKA control values  */
65*b353a43cSLin Jinhan #define RK_PKA_PIPE_READY			1
66*b353a43cSLin Jinhan #define RK_PKA_OP_DONE				1
67*b353a43cSLin Jinhan #define RK_PKA_SW_REST				1
68*b353a43cSLin Jinhan 
69*b353a43cSLin Jinhan /* PKA N_NP_T0_T1 register fields positions (low bit position) */
70*b353a43cSLin Jinhan #define RK_PKA_N_NP_T0_T1_REG_N_POS		CRYPTO_N_VIRTUAL_ADDR_SHIFT
71*b353a43cSLin Jinhan #define RK_PKA_N_NP_T0_T1_REG_NP_POS		CRYPTO_NP_VIRTUAL_ADDR_SHIFT
72*b353a43cSLin Jinhan #define RK_PKA_N_NP_T0_T1_REG_T0_POS		CRYPTO_T0_VIRTUAL_ADDR_SHIFT
73*b353a43cSLin Jinhan #define RK_PKA_N_NP_T0_T1_REG_T1_POS		CRYPTO_T1_VIRTUAL_ADDR_SHIFT
74*b353a43cSLin Jinhan 
75*b353a43cSLin Jinhan /* PKA N_NP_T0_T1 register default (reset) value: N=0, NP=1, T0=30, T1=31 */
76*b353a43cSLin Jinhan #define PKA_N					0UL
77*b353a43cSLin Jinhan #define PKA_NP					1UL
78*b353a43cSLin Jinhan #define PKA_T0					30UL
79*b353a43cSLin Jinhan #define PKA_T1					31UL
80*b353a43cSLin Jinhan #define RK_PKA_N_NP_T0_T1_REG_DEFAULT_VAL \
81*b353a43cSLin Jinhan 				(PKA_N  << RK_PKA_N_NP_T0_T1_REG_N_POS | \
82*b353a43cSLin Jinhan 				PKA_NP << RK_PKA_N_NP_T0_T1_REG_NP_POS | \
83*b353a43cSLin Jinhan 				PKA_T0 << RK_PKA_N_NP_T0_T1_REG_T0_POS | \
84*b353a43cSLin Jinhan 				PKA_T1 << RK_PKA_N_NP_T0_T1_REG_T1_POS)
85*b353a43cSLin Jinhan 
86*b353a43cSLin Jinhan /* PKA STATUS register fields positions (low bit position) */
87*b353a43cSLin Jinhan #define RK_PKA_STATUS_PIPE_IS_REDY_POS		0
88*b353a43cSLin Jinhan #define RK_PKA_STATUS_PKA_BUSY_POS		1
89*b353a43cSLin Jinhan #define RK_PKA_STATUS_ALU_OUT_ZERO_POS		2
90*b353a43cSLin Jinhan #define RK_PKA_STATUS_ALU_MODOVRFLW_POS		3
91*b353a43cSLin Jinhan #define RK_PKA_STATUS_DIV_BY_ZERO_POS		4
92*b353a43cSLin Jinhan #define RK_PKA_STATUS_ALU_CARRY_POS		5
93*b353a43cSLin Jinhan #define RK_PKA_STATUS_ALU_SIGN_OUT_POS		6
94*b353a43cSLin Jinhan #define RK_PKA_STATUS_MODINV_OF_ZERO_POS	7
95*b353a43cSLin Jinhan #define RK_PKA_STATUS_PKA_CPU_BUSY_POS		8
96*b353a43cSLin Jinhan #define RK_PKA_STATUS_OPCODE_POS		9
97*b353a43cSLin Jinhan #define RK_PKA_STATUS_TAG_POS			14
98*b353a43cSLin Jinhan 
99*b353a43cSLin Jinhan #define RK_PKA_STATUS_OPCODE_MASK		0x1FUl
100*b353a43cSLin Jinhan #define RK_PKA_STATUS_TAG_MASK			0x3FUl
101*b353a43cSLin Jinhan 
102*b353a43cSLin Jinhan /* PKA OPCODE register fields positions (low bit position) */
103*b353a43cSLin Jinhan #define RK_PKA_OPCODE_TAG_POS			0
104*b353a43cSLin Jinhan #define RK_PKA_OPCODE_RESULT_POS		6
105*b353a43cSLin Jinhan #define RK_PKA_OPCODE_R_DISCARD_POS		11
106*b353a43cSLin Jinhan #define RK_PKA_OPCODE_OPERAND_2_POS		12
107*b353a43cSLin Jinhan #define RK_PKA_OPCODE_OPERAND_2_IMMED_POS	17
108*b353a43cSLin Jinhan #define RK_PKA_OPCODE_OPERAND_1_POS		18
109*b353a43cSLin Jinhan #define RK_PKA_OPCODE_OPERAND_1_IMMED_POS	23
110*b353a43cSLin Jinhan #define RK_PKA_OPCODE_LEN_POS			24
111*b353a43cSLin Jinhan #define RK_PKA_OPCODE_OPERATION_ID_POS		27
112*b353a43cSLin Jinhan 
113*b353a43cSLin Jinhan /* PKA data registers base address
114*b353a43cSLin Jinhan  *should be always zero since it's the offset
115*b353a43cSLin Jinhan  * from the start of the PKA memory and not from the HOST memory
116*b353a43cSLin Jinhan  */
117*b353a43cSLin Jinhan #define RK_PKA_DATA_REGS_BASE_ADDR		(CRYPTO_BASE + CRYPTO_SRAM_BASE)
118*b353a43cSLin Jinhan #define RK_PKA_DATA_REGS_MEMORY_OFFSET_ADDR	(CRYPTO_BASE + CRYPTO_SRAM_BASE)
119*b353a43cSLin Jinhan 
120*b353a43cSLin Jinhan /* Machine Opcodes definitions (according to HW CRS ) */
121*b353a43cSLin Jinhan #define   RK_PKA_MIN_OPCODE			0x00
122*b353a43cSLin Jinhan 
123*b353a43cSLin Jinhan #define PKA_Add					0x04
124*b353a43cSLin Jinhan #define PKA_AddIm				0x04
125*b353a43cSLin Jinhan #define PKA_Sub					0x05
126*b353a43cSLin Jinhan #define PKA_SubIm				0x05
127*b353a43cSLin Jinhan #define PKA_Neg					0x05
128*b353a43cSLin Jinhan #define PKA_ModAdd				0x06
129*b353a43cSLin Jinhan #define PKA_ModAddIm				0x06
130*b353a43cSLin Jinhan #define PKA_ModSub				0x07
131*b353a43cSLin Jinhan #define PKA_ModSubIm				0x07
132*b353a43cSLin Jinhan #define PKA_ModNeg				0x07
133*b353a43cSLin Jinhan #define PKA_AND					0x08
134*b353a43cSLin Jinhan #define PKA_Test0				0x08
135*b353a43cSLin Jinhan #define PKA_Clr0				0x08
136*b353a43cSLin Jinhan #define PKA_Clr					0x08
137*b353a43cSLin Jinhan #define PKA_OR					0x09
138*b353a43cSLin Jinhan #define PKA_Copy				0x09
139*b353a43cSLin Jinhan #define PKA_SetBit0				0x09
140*b353a43cSLin Jinhan #define PKA_XOR					0x0A
141*b353a43cSLin Jinhan #define PKA_Flip0				0x0A
142*b353a43cSLin Jinhan #define PKA_InvertBits				0x0A
143*b353a43cSLin Jinhan #define PKA_Compare				0x0A
144*b353a43cSLin Jinhan #define PKA_SHR0				0x0C
145*b353a43cSLin Jinhan #define PKA_SHR1				0x0D
146*b353a43cSLin Jinhan #define PKA_SHL0				0x0E
147*b353a43cSLin Jinhan #define PKA_SHL1				0x0F
148*b353a43cSLin Jinhan #define PKA_LMul				0x10
149*b353a43cSLin Jinhan #define PKA_ModMul				0x11
150*b353a43cSLin Jinhan #define PKA_ModMulNR				0x12
151*b353a43cSLin Jinhan #define PKA_ModExp				0x13
152*b353a43cSLin Jinhan #define PKA_Div					0x14
153*b353a43cSLin Jinhan #define PKA_ModInv				0x15
154*b353a43cSLin Jinhan #define PKA_ModDiv				0x16
155*b353a43cSLin Jinhan #define PKA_HMul				0x17
156*b353a43cSLin Jinhan #define PKA_Terminate				0x00
157*b353a43cSLin Jinhan 
158*b353a43cSLin Jinhan #define RK_PKA_MAX_OPCODE			0x17
159*b353a43cSLin Jinhan 
160*b353a43cSLin Jinhan /*************************************************************/
161*b353a43cSLin Jinhan /* Macros for waiting PKA machine ready states               */
162*b353a43cSLin Jinhan /*************************************************************/
163*b353a43cSLin Jinhan 
164*b353a43cSLin Jinhan void rk_pka_ram_ctrl_enable(void);
165*b353a43cSLin Jinhan 
166*b353a43cSLin Jinhan void rk_pka_ram_ctrl_disable(void);
167*b353a43cSLin Jinhan 
168*b353a43cSLin Jinhan void rk_pka_wait_on_ram_ready(void);
169*b353a43cSLin Jinhan 
170*b353a43cSLin Jinhan void rk_pka_wait_on_pipe_ready(void);
171*b353a43cSLin Jinhan 
172*b353a43cSLin Jinhan void rk_pka_wait_on_done(void);
173*b353a43cSLin Jinhan 
174*b353a43cSLin Jinhan /*****************************************************
175*b353a43cSLin Jinhan  *  Macros for controlling PKA machine and changing  *
176*b353a43cSLin Jinhan  *  PKA sizes table and mapping table settings.      *
177*b353a43cSLin Jinhan  *****************************************************/
178*b353a43cSLin Jinhan #define PKA_CLK_ENABLE()
179*b353a43cSLin Jinhan 
180*b353a43cSLin Jinhan #define PKA_CLK_DISABLE()
181*b353a43cSLin Jinhan 
182*b353a43cSLin Jinhan void rk_pka_set_startmemaddr_reg(u32 start_mem_addr);
183*b353a43cSLin Jinhan 
184*b353a43cSLin Jinhan void rk_pka_set_N_NP_T0_T1_reg(u32 N, u32 NP, u32 T0, u32 T1);
185*b353a43cSLin Jinhan 
186*b353a43cSLin Jinhan void rk_pka_set_default_N_NP_T0_T1_reg(void);
187*b353a43cSLin Jinhan 
188*b353a43cSLin Jinhan void rk_pka_get_status(u32 *status);
189*b353a43cSLin Jinhan 
190*b353a43cSLin Jinhan void rk_pka_get_status_alu_outzero(u32 *status);
191*b353a43cSLin Jinhan 
192*b353a43cSLin Jinhan void rk_pka_get_status_mod_overfl(u32 *status);
193*b353a43cSLin Jinhan 
194*b353a43cSLin Jinhan void rk_pka_get_status_div_byzero(u32 *status);
195*b353a43cSLin Jinhan 
196*b353a43cSLin Jinhan void rk_pka_get_status_carry(u32 *status);
197*b353a43cSLin Jinhan 
198*b353a43cSLin Jinhan void rk_pka_get_status_alu_signout(u32 *status);
199*b353a43cSLin Jinhan 
200*b353a43cSLin Jinhan void rk_pka_get_status_modinv_ofzero(u32 *status);
201*b353a43cSLin Jinhan 
202*b353a43cSLin Jinhan void rk_pka_get_status_opcode(u32 *status);
203*b353a43cSLin Jinhan 
204*b353a43cSLin Jinhan void rk_pka_get_status_tag(u32 *status);
205*b353a43cSLin Jinhan 
206*b353a43cSLin Jinhan /******************************************************************
207*b353a43cSLin Jinhan  * Macros for setting and reading sizes from PKA regsSizesTable   *
208*b353a43cSLin Jinhan  ******************************************************************/
209*b353a43cSLin Jinhan void rk_pka_set_regsize(u32 size_bits, u32 entry_num);
210*b353a43cSLin Jinhan 
211*b353a43cSLin Jinhan void rk_pka_read_regsize(u32 *size_bits, u32 entry_num);
212*b353a43cSLin Jinhan 
213*b353a43cSLin Jinhan /******************************************************************
214*b353a43cSLin Jinhan  * Macros for setting and reading addresses of PKA data registers *
215*b353a43cSLin Jinhan  ******************************************************************/
216*b353a43cSLin Jinhan void rk_pka_set_regaddr(u32 vir_reg, u32 phys_addr);
217*b353a43cSLin Jinhan 
218*b353a43cSLin Jinhan void rk_pka_get_regaddr(u32 vir_reg, u32 *phys_addr);
219*b353a43cSLin Jinhan 
220*b353a43cSLin Jinhan void rk_pka_read_regaddr(u32 vir_reg, u32 *phys_addr);
221*b353a43cSLin Jinhan 
222*b353a43cSLin Jinhan /**********************************************
223*b353a43cSLin Jinhan  *    Macros for setting Full PKI opcode      *
224*b353a43cSLin Jinhan  **********************************************/
225*b353a43cSLin Jinhan u32 rk_pka_make_full_opcode(u32 opcode, u32 len_id,
226*b353a43cSLin Jinhan 			    u32 is_a_immed, u32 op_a,
227*b353a43cSLin Jinhan 			    u32 is_b_immed, u32 op_b,
228*b353a43cSLin Jinhan 			    u32 res_discard, u32 res,
229*b353a43cSLin Jinhan 			    u32 tag);
230*b353a43cSLin Jinhan 
231*b353a43cSLin Jinhan /******************************************************
232*b353a43cSLin Jinhan  * Macros for reading and loading PKA memory data     *
233*b353a43cSLin Jinhan  ******************************************************/
234*b353a43cSLin Jinhan void rk_pka_hw_load_value2pka_mem(u32 addr, u32 val);
235*b353a43cSLin Jinhan 
236*b353a43cSLin Jinhan void rk_pka_hw_load_block2pka_mem(u32 addr, u32 *ptr,
237*b353a43cSLin Jinhan 				  u32 size_words);
238*b353a43cSLin Jinhan 
239*b353a43cSLin Jinhan void rk_pka_hw_reverse_load_block2pka_mem(u32 addr, u32 *ptr,
240*b353a43cSLin Jinhan 					  u32 size_words);
241*b353a43cSLin Jinhan 
242*b353a43cSLin Jinhan void rk_pka_hw_clear_pka_mem(u32 addr, u32 size_words);
243*b353a43cSLin Jinhan 
244*b353a43cSLin Jinhan void rk_pka_hw_read_value_from_pka_mem(u32 addr, u32 *val);
245*b353a43cSLin Jinhan 
246*b353a43cSLin Jinhan void rk_pka_hw_read_block_from_pka_mem(u32 addr, u32 *ptr,
247*b353a43cSLin Jinhan 				       u32 size_words);
248*b353a43cSLin Jinhan 
249*b353a43cSLin Jinhan void rk_pka_hw_reverse_read_block_from_pka_mem(u32 addr, u32 *ptr,
250*b353a43cSLin Jinhan 					       u32 size_words);
251*b353a43cSLin Jinhan 
252*b353a43cSLin Jinhan u32 rk_pka_exec_operation(u32 opcode, u8 len_id,
253*b353a43cSLin Jinhan 			  u8 is_a_immed, s8 op_a,
254*b353a43cSLin Jinhan 			  u8 is_b_immed, s8 op_b,
255*b353a43cSLin Jinhan 			  u8	res_discard, s8 res, u8 tag);
256*b353a43cSLin Jinhan 
257*b353a43cSLin Jinhan /*************************************************************************
258*b353a43cSLin Jinhan  * Macros for calling PKA operations (names according to operation issue *
259*b353a43cSLin Jinhan  *************************************************************************/
260*b353a43cSLin Jinhan 
261*b353a43cSLin Jinhan /*--------------------------------------*/
262*b353a43cSLin Jinhan /*	 1.  ADD - SUBTRACT operations	*/
263*b353a43cSLin Jinhan /*--------------------------------------*/
264*b353a43cSLin Jinhan /*	Add:   res =  op_a + op_b	*/
265*b353a43cSLin Jinhan #define   RK_PKA_Add(len_id, op_a, op_b, res, tag)   \
266*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_Add, (len_id), 0, (op_a),\
267*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
268*b353a43cSLin Jinhan 
269*b353a43cSLin Jinhan /*	AddIm:	res =  op_a + op_b_im	*/
270*b353a43cSLin Jinhan #define   RK_PKA_AddIm(len_id, op_a, op_b_im, res, tag)   \
271*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_Add, (len_id), 0, (op_a), \
272*b353a43cSLin Jinhan 					      1, (op_b_im), 0, (res), (tag))
273*b353a43cSLin Jinhan 
274*b353a43cSLin Jinhan /*	Sub:  res =  op_a - op_b	*/
275*b353a43cSLin Jinhan #define   RK_PKA_Sub(len_id, op_a, op_b, res, tag)   \
276*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_Sub, (len_id), 0, (op_a), \
277*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
278*b353a43cSLin Jinhan 
279*b353a43cSLin Jinhan /*	SubIm:	res =  op_a - op_b_im	*/
280*b353a43cSLin Jinhan #define   RK_PKA_SubIm(len_id, op_a, op_b_im, res, tag)   \
281*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_Sub, (len_id), 0, (op_a), \
282*b353a43cSLin Jinhan 					      1, (op_b_im), 0, (res), (tag))
283*b353a43cSLin Jinhan 
284*b353a43cSLin Jinhan /*	Neg:  res =  0 - op_b  */
285*b353a43cSLin Jinhan #define   RK_PKA_Neg(len_id, op_b, res, tag)   \
286*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_Sub, (len_id), 1, 0, \
287*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
288*b353a43cSLin Jinhan 
289*b353a43cSLin Jinhan /*	ModAdd:  res =	(op_a + op_b) mod N  */
290*b353a43cSLin Jinhan #define   RK_PKA_ModAdd(len_id, op_a, op_b, res, tag)   \
291*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_ModAdd, (len_id), 0, (op_a), \
292*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
293*b353a43cSLin Jinhan 
294*b353a43cSLin Jinhan /*	ModAddIm:  res =  (op_a + op_b_im) mod N  */
295*b353a43cSLin Jinhan #define   RK_PKA_ModAddIm(len_id, op_a, op_b_im, res, tag)   \
296*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_ModAdd, (len_id), 0, (op_a), \
297*b353a43cSLin Jinhan 					      1, (op_b_im), 0, (res), (tag))
298*b353a43cSLin Jinhan 
299*b353a43cSLin Jinhan /*	ModSub:  res =	(op_a - op_b) mod N  */
300*b353a43cSLin Jinhan #define   RK_PKA_ModSub(len_id, op_a, op_b, res, tag)   \
301*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_ModSub, (len_id), 0, (op_a), \
302*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
303*b353a43cSLin Jinhan 
304*b353a43cSLin Jinhan /*	ModSubIm:  res =  (op_a - op_b_im) mod N  */
305*b353a43cSLin Jinhan #define   RK_PKA_ModSubIm(len_id, op_a, op_b_im, res, tag)   \
306*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_ModSub, (len_id), 0, (op_a), \
307*b353a43cSLin Jinhan 					      1, (op_b_im), 0, (res), (tag))
308*b353a43cSLin Jinhan 
309*b353a43cSLin Jinhan /*	ModNeg:  res =	(0 - op_b) mod N  */
310*b353a43cSLin Jinhan #define   RK_PKA_ModNeg(len_id, op_b, res, tag)   \
311*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_ModSub, (len_id), 1, 0, \
312*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
313*b353a43cSLin Jinhan 
314*b353a43cSLin Jinhan /*--------------------------------------*/
315*b353a43cSLin Jinhan /*	 2.  Logical   operations	*/
316*b353a43cSLin Jinhan /*--------------------------------------*/
317*b353a43cSLin Jinhan 
318*b353a43cSLin Jinhan /*	AND:  res =  op_a & op_b	*/
319*b353a43cSLin Jinhan #define   RK_PKA_AND(len_id, op_a, op_b, res, tag)   \
320*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_AND, (len_id), 0, (op_a), \
321*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
322*b353a43cSLin Jinhan 
323*b353a43cSLin Jinhan /*	AndIm:	res =  op_a & op_b  */
324*b353a43cSLin Jinhan #define   RK_PKA_AndIm(len_id, op_a, op_b, res, tag)   \
325*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_AND, (len_id), 0, (op_a), \
326*b353a43cSLin Jinhan 					      1, (op_b), 0, (res), (tag))
327*b353a43cSLin Jinhan 
328*b353a43cSLin Jinhan /*	Tst0:  op_a & 0x1 - tests the bit 0 of operand A. */
329*b353a43cSLin Jinhan /*	If bit0 = 0, then ZeroOfStatus = 1, else 0  */
330*b353a43cSLin Jinhan #define   RK_PKA_Tst0(len_id, op_a, tag)   \
331*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_AND, (len_id), 0, (op_a), \
332*b353a43cSLin Jinhan 					      1, 0x01, 1, RES_DISCARD, (tag))
333*b353a43cSLin Jinhan 
334*b353a43cSLin Jinhan /*	Clr0:  res =  op_a & (-2)  - clears the bit 0 of operand A. */
335*b353a43cSLin Jinhan /*	Note:  -2 = 0x1E  for 5-bit size */
336*b353a43cSLin Jinhan #define   RK_PKA_Clr0(len_id, op_a, res, tag)   \
337*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_AND, (len_id), 0, (op_a), \
338*b353a43cSLin Jinhan 					      1, 0x1E, 0, (res), (tag))
339*b353a43cSLin Jinhan 
340*b353a43cSLin Jinhan /*	Clr:  res =  op_a & 0  - clears the operand A.  */
341*b353a43cSLin Jinhan #define   RK_PKA_Clr(len_id, op_a, tag)   \
342*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_AND, (len_id), 0, (op_a), \
343*b353a43cSLin Jinhan 					      1, 0x00, 0, (op_a), (tag))
344*b353a43cSLin Jinhan 
345*b353a43cSLin Jinhan /*	Clear:	for full clearing the actual register op_a,
346*b353a43cSLin Jinhan  *	this macro calls Clr operation twice.
347*b353a43cSLin Jinhan  */
348*b353a43cSLin Jinhan #define   RK_PKA_Clear(len_id, op_a, tag)   \
349*b353a43cSLin Jinhan 		       RK_PKA_Clr(len_id, op_a, tag)
350*b353a43cSLin Jinhan 
351*b353a43cSLin Jinhan /*	OR:  res =	op_a || op_b	*/
352*b353a43cSLin Jinhan #define   RK_PKA_OR(len_id, op_a, op_b, res, tag)   \
353*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_OR, (len_id), 0, (op_a), \
354*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
355*b353a43cSLin Jinhan 
356*b353a43cSLin Jinhan /*	OrIm:  res =  op_a || op_b  */
357*b353a43cSLin Jinhan #define   RK_PKA_OrIm(len_id, op_a, op_b, res, tag)   \
358*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_OR, (len_id), 0, (op_a), \
359*b353a43cSLin Jinhan 					      1, (op_b), 0, (res), (tag))
360*b353a43cSLin Jinhan 
361*b353a43cSLin Jinhan /*	Copy:  OpDest =  OpSrc || 0  */
362*b353a43cSLin Jinhan #define   RK_PKA_Copy(len_id, op_dest, op_src, tag)   \
363*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_OR, (len_id), 0, (op_src), \
364*b353a43cSLin Jinhan 					      1, 0x00, 0, (op_dest), (tag))
365*b353a43cSLin Jinhan 
366*b353a43cSLin Jinhan /*	Set0:  res =  op_a || 1	: set bit0 = 1, other bits are not changed */
367*b353a43cSLin Jinhan #define   RK_PKA_Set0(len_id, op_a, res, tag)   \
368*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_OR, (len_id), 0, (op_a), \
369*b353a43cSLin Jinhan 					      1, 0x01, 0, (res), (tag))
370*b353a43cSLin Jinhan 
371*b353a43cSLin Jinhan /*	Xor:  res =  op_a ^ op_b	*/
372*b353a43cSLin Jinhan #define   RK_PKA_Xor(len_id, op_a, op_b, res, tag)   \
373*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_XOR, (len_id), 0, (op_a), \
374*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
375*b353a43cSLin Jinhan 
376*b353a43cSLin Jinhan /*	XorIm:	res =  op_a ^ op_b  */
377*b353a43cSLin Jinhan #define   RK_PKA_XorIm(len_id, op_a, op_b, res, tag)   \
378*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_XOR, (len_id), 0, (op_a), \
379*b353a43cSLin Jinhan 					      1, (op_b), 0, (res), (tag))
380*b353a43cSLin Jinhan 
381*b353a43cSLin Jinhan /*	Flip0:	res =  op_a || 1  - inverts the bit 0 of operand A  */
382*b353a43cSLin Jinhan #define   RK_PKA_Flip0(len_id, op_a, res, tag)   \
383*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_XOR, (len_id), 0, (op_a), \
384*b353a43cSLin Jinhan 					      1, 0x01, 0, (res), (tag))
385*b353a43cSLin Jinhan 
386*b353a43cSLin Jinhan /*	Invert:  res =	op_a ^ 0xFFF.FF	:  inverts all bits of op_a . */
387*b353a43cSLin Jinhan /* Note: 0xFFFFF =  0x1F for 5 bits size of second operand */
388*b353a43cSLin Jinhan #define   RK_PKA_Invert(len_id, op_a, res, tag)   \
389*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_XOR, (len_id), 0, (op_a), \
390*b353a43cSLin Jinhan 					      1, 0x1F, 0, (res), (tag))
391*b353a43cSLin Jinhan 
392*b353a43cSLin Jinhan /*	Compare:  op_a ^ op_b . Rsult of compare in ZeroBitOfStatus: */
393*b353a43cSLin Jinhan /*	If op_a == op_b then Z = 1 */
394*b353a43cSLin Jinhan #define   RK_PKA_Compare(len_id, op_a, op_b, tag)   \
395*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_XOR, (len_id), 0, (op_a), \
396*b353a43cSLin Jinhan 					      0, (op_b), 1, (0), (tag))
397*b353a43cSLin Jinhan 
398*b353a43cSLin Jinhan /*	CompareImmediate:  op_a ^ op_b . Rsult of compare in ZeroBitOfStatus: */
399*b353a43cSLin Jinhan /*	If op_a == op_b then status Z = 1 */
400*b353a43cSLin Jinhan #define   RK_PKA_CompareIm(len_id, op_a, op_b, tag)   \
401*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_XOR, (len_id), 0, (op_a), \
402*b353a43cSLin Jinhan 					      1, (op_b), 1, (0), (tag))
403*b353a43cSLin Jinhan 
404*b353a43cSLin Jinhan /*----------------------------------------------*/
405*b353a43cSLin Jinhan /*	 3.  SHIFT	  operations		*/
406*b353a43cSLin Jinhan /*----------------------------------------------*/
407*b353a43cSLin Jinhan 
408*b353a43cSLin Jinhan /*	SHR0:  res =  op_a >> (S+1) :
409*b353a43cSLin Jinhan  *	shifts right operand A by S+1 bits, insert 0 to left most bits
410*b353a43cSLin Jinhan  */
411*b353a43cSLin Jinhan #define   RK_PKA_SHR0(len_id, op_a, S, res, tag)   \
412*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_SHR0, (len_id), 0, (op_a), \
413*b353a43cSLin Jinhan 					      0, (S), 0, (res), (tag))
414*b353a43cSLin Jinhan 
415*b353a43cSLin Jinhan /*	SHR1:  res =  op_a >> (S+1) :
416*b353a43cSLin Jinhan  *	shifts right operand A by S+1 bits, insert 1 to left most bits
417*b353a43cSLin Jinhan  */
418*b353a43cSLin Jinhan #define   RK_PKA_SHR1(len_id, op_a, S, res, tag)   \
419*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_SHR1, (len_id), 0, (op_a), \
420*b353a43cSLin Jinhan 					      0, (S), 0, (res), (tag))
421*b353a43cSLin Jinhan 
422*b353a43cSLin Jinhan /*	SHL0:  res =  op_a << (S+1) :
423*b353a43cSLin Jinhan  *	shifts left operand A by S+1 bits, insert 0 to right most bits
424*b353a43cSLin Jinhan  */
425*b353a43cSLin Jinhan #define   RK_PKA_SHL0(len_id, op_a, S, res, tag)   \
426*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_SHL0, (len_id), 0, (op_a), \
427*b353a43cSLin Jinhan 					      0, (S), 0, (res), (tag))
428*b353a43cSLin Jinhan 
429*b353a43cSLin Jinhan /*	SHL1:  res =  op_a << (S+1) :
430*b353a43cSLin Jinhan  *	shifts left operand A by S+1 bits, insert 1 to right most bits
431*b353a43cSLin Jinhan  */
432*b353a43cSLin Jinhan #define   RK_PKA_SHL1(len_id, op_a, S, res, tag)   \
433*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_SHL1, (len_id), 0, (op_a), \
434*b353a43cSLin Jinhan 					      0, (S), 0, (res), (tag))
435*b353a43cSLin Jinhan 
436*b353a43cSLin Jinhan /*--------------------------------------------------------------*/
437*b353a43cSLin Jinhan /*	 2.  Multiplication and other	operations		*/
438*b353a43cSLin Jinhan /*		 Note:	See notes to RK_PKAExecOperation	*/
439*b353a43cSLin Jinhan /*--------------------------------------------------------------*/
440*b353a43cSLin Jinhan 
441*b353a43cSLin Jinhan /*	RMul:  res =  LowHalfOf(op_a * op_b), where size of operands and result
442*b353a43cSLin Jinhan  *	is equaled to operation size, defined by len_id. Note: for receiving
443*b353a43cSLin Jinhan  *	full result, the len_id must be set according to (sizeA + sizeB) and
444*b353a43cSLin Jinhan  *	leading not significant bits of operands must be zeroed
445*b353a43cSLin Jinhan  */
446*b353a43cSLin Jinhan #define   RK_PKA_LMul(len_id, op_a, op_b, res, tag)   \
447*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_LMul, (len_id), 0, (op_a), \
448*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
449*b353a43cSLin Jinhan 
450*b353a43cSLin Jinhan /*	HMul:  res =  HighHalfOf(op_a * op_b) + one high word of low half of
451*b353a43cSLin Jinhan  *	(op_a * op_b), where size of operands is equaled to operation size,
452*b353a43cSLin Jinhan  *	defined by len_id. Note: Size of operation result is by one word large,
453*b353a43cSLin Jinhan  *	than operation size
454*b353a43cSLin Jinhan  */
455*b353a43cSLin Jinhan #define   RK_PKA_HMul(len_id, op_a, op_b, res, tag)   \
456*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_HMul, (len_id), 0, (op_a), \
457*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
458*b353a43cSLin Jinhan 
459*b353a43cSLin Jinhan /*	ModMul:  res =	op_a * op_b  mod N - modular multiplication */
460*b353a43cSLin Jinhan #define   RK_PKA_ModMul(len_id, op_a, op_b, res, tag)   \
461*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_ModMul, (len_id), 0, (op_a), \
462*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
463*b353a43cSLin Jinhan 
464*b353a43cSLin Jinhan /*	ModMulN:  res =  op_a * op_b	mod N
465*b353a43cSLin Jinhan  *	- modular multiplication (final reduction is omitted)
466*b353a43cSLin Jinhan  */
467*b353a43cSLin Jinhan #define   RK_PKA_ModMulN(len_id, op_a, op_b, res, tag)   \
468*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_ModMulNR, (len_id), 0, \
469*b353a43cSLin Jinhan 					      (op_a), 0, (op_b), 0, \
470*b353a43cSLin Jinhan 					      (res), (tag))
471*b353a43cSLin Jinhan 
472*b353a43cSLin Jinhan /*	ModExp:  res =	op_a ** op_b	mod N - modular exponentiation */
473*b353a43cSLin Jinhan #define   RK_PKA_ModExp(len_id, op_a, op_b, res, tag)   \
474*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_ModExp, (len_id), 0, (op_a), \
475*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
476*b353a43cSLin Jinhan 
477*b353a43cSLin Jinhan /*	Divide:  res =	op_a / op_b , op_a = op_a mod op_b - division,  */
478*b353a43cSLin Jinhan #define   RK_PKA_Div(len_id, op_a, op_b, res, tag)   \
479*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_Div, (len_id), 0, (op_a), \
480*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
481*b353a43cSLin Jinhan 
482*b353a43cSLin Jinhan /*	ModInv:  Modular inversion: calculates	 res = 1/op_b mod N	*/
483*b353a43cSLin Jinhan #define   RK_PKA_ModInv(len_id, op_b, res, tag)   \
484*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_ModInv, (len_id), 0, 1, \
485*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
486*b353a43cSLin Jinhan #define   RK_PKA_ModDiv(len_id, op_a, op_b, res, tag)   \
487*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_ModDiv, (len_id), 0, (op_a), \
488*b353a43cSLin Jinhan 					      0, (op_b), 0, (res), (tag))
489*b353a43cSLin Jinhan 
490*b353a43cSLin Jinhan /*	Terminate  - special operation, which allows HOST access */
491*b353a43cSLin Jinhan /*	to PKA data memory registers after end of PKA operations */
492*b353a43cSLin Jinhan #define   RK_PKA_Terminate(tag)   \
493*b353a43cSLin Jinhan 			rk_pka_exec_operation(PKA_Terminate, 0, 0, 0, 0, \
494*b353a43cSLin Jinhan 					      0, 0, 0, (tag))
495*b353a43cSLin Jinhan 
496*b353a43cSLin Jinhan struct rk_pka_regs_map {
497*b353a43cSLin Jinhan 	u32 reges_num[RK_PKA_MAX_PHYS_MEM_REGS_COUNT];
498*b353a43cSLin Jinhan 	u32 regs_addr[RK_PKA_MAX_PHYS_MEM_REGS_COUNT];
499*b353a43cSLin Jinhan };
500*b353a43cSLin Jinhan 
501*b353a43cSLin Jinhan u32 rk_pka_set_sizes_tab(u32 regs_sizes_ptr[RK_PKA_MAX_REGS_COUNT],
502*b353a43cSLin Jinhan 			 u32 count_of_sizes,
503*b353a43cSLin Jinhan 			 u32 max_size_bits,
504*b353a43cSLin Jinhan 			 u32 is_default_map);
505*b353a43cSLin Jinhan 
506*b353a43cSLin Jinhan #define RK_PKA_DefaultSetRegsSizesTab(max_size_bits) \
507*b353a43cSLin Jinhan 			rk_pka_set_sizes_tab(0, 0, (max_size_bits), 1)
508*b353a43cSLin Jinhan u32 rk_pka_set_map_tab(struct rk_pka_regs_map *regs_map_ptr, u32 *count_of_regs,
509*b353a43cSLin Jinhan 		       u32 maxsize_words, u32 N_NP_T0_T1,
510*b353a43cSLin Jinhan 		       u32 is_default_map);
511*b353a43cSLin Jinhan 
512*b353a43cSLin Jinhan #define RK_PKA_DefaultSetRegsMapTab(maxsize_words, count_of_regs) \
513*b353a43cSLin Jinhan 			rk_pka_set_map_tab(NULL, (count_of_regs), \
514*b353a43cSLin Jinhan 					   (maxsize_words), 0, 1)
515*b353a43cSLin Jinhan 
516*b353a43cSLin Jinhan u32 rk_pka_clear_block_of_regs(u8 first_reg, u8 count_of_regs, u8 len_id);
517*b353a43cSLin Jinhan 
518*b353a43cSLin Jinhan u32 rk_pka_init(u32 regs_sizes_ptr[RK_PKA_MAX_REGS_COUNT],
519*b353a43cSLin Jinhan 		u32 count_of_sizes,
520*b353a43cSLin Jinhan 		struct rk_pka_regs_map *regs_map_ptr,
521*b353a43cSLin Jinhan 		u32 count_of_regs,
522*b353a43cSLin Jinhan 		u32 op_size_bits,
523*b353a43cSLin Jinhan 		u32 regsize_words,
524*b353a43cSLin Jinhan 		u32 N_NP_T0_T1,
525*b353a43cSLin Jinhan 		u32 is_default_map);
526*b353a43cSLin Jinhan #define RK_PKA_DefaultInitPKA(max_size_bits, regsize_words) \
527*b353a43cSLin Jinhan 			rk_pka_init(0, 0, 0, 0, (max_size_bits), \
528*b353a43cSLin Jinhan 				    (regsize_words), 0, 1)
529*b353a43cSLin Jinhan 
530*b353a43cSLin Jinhan void rk_pka_finish(void);
531*b353a43cSLin Jinhan u32 rk_pka_calcNp_and_initmodop(u32 len_id, u32 mod_size_bits,
532*b353a43cSLin Jinhan 				s8 r_t0, s8 r_t1, s8 r_t2);
533*b353a43cSLin Jinhan 
534*b353a43cSLin Jinhan u32 rk_pka_div_long_num(u8 len_id, s8 op_a, u32 s, s8 op_b,
535*b353a43cSLin Jinhan 			s8 res, s8 r_t1, s8 r_t2);
536*b353a43cSLin Jinhan 
537*b353a43cSLin Jinhan u32 rk_calcNp_and_initmodop(u32 *N_ptr, u32 N_size_bits,
538*b353a43cSLin Jinhan 			    u32 *NP_ptr, u8 np_create_flag,
539*b353a43cSLin Jinhan 			    s8 r_t0, s8 r_t1, s8 r_t2);
540*b353a43cSLin Jinhan 
541*b353a43cSLin Jinhan void rk_pka_copy_data_into_reg(s8 dst_reg, u8 len_id, u32 *src_ptr,
542*b353a43cSLin Jinhan 			       u32 size_words);
543*b353a43cSLin Jinhan void rk_pka_copy_data_from_reg(u32 *dst_ptr, u32  size_words,
544*b353a43cSLin Jinhan 			       s8 src_reg);
545*b353a43cSLin Jinhan int test_rk3326_rsa(void);
546*b353a43cSLin Jinhan int rk_mpa_alloc(struct mpa_num **mpa);
547*b353a43cSLin Jinhan void rk_mpa_free(struct mpa_num **mpa);
548*b353a43cSLin Jinhan int rk_abs_add(void *a, void *b, void *c);
549*b353a43cSLin Jinhan int rk_mod(void *a, void *b, void *c);
550*b353a43cSLin Jinhan int rk_exptmod(void *a, void *b, void *c, void *d);
551*b353a43cSLin Jinhan int rk_exptmod_np(void *m, void *e, void *n, void *np, void *d);
552*b353a43cSLin Jinhan 
553*b353a43cSLin Jinhan #endif
554