xref: /rk3399_ARM-atf/drivers/nxp/crypto/caam/src/sec_hw_specific.c (revision 9719e19a977df3e8bf7567b3c0e1d6b2ebc5b46f)
1*a0edacb8SPankaj Gupta /*
2*a0edacb8SPankaj Gupta  * Copyright 2021 NXP
3*a0edacb8SPankaj Gupta  *
4*a0edacb8SPankaj Gupta  * SPDX-License-Identifier: BSD-3-Clause
5*a0edacb8SPankaj Gupta  *
6*a0edacb8SPankaj Gupta  */
7*a0edacb8SPankaj Gupta 
8*a0edacb8SPankaj Gupta #include <assert.h>
9*a0edacb8SPankaj Gupta #include <errno.h>
10*a0edacb8SPankaj Gupta #include <stdbool.h>
11*a0edacb8SPankaj Gupta #include <stdint.h>
12*a0edacb8SPankaj Gupta #include <stdio.h>
13*a0edacb8SPankaj Gupta #include <stdlib.h>
14*a0edacb8SPankaj Gupta 
15*a0edacb8SPankaj Gupta #include <arch_helpers.h>
16*a0edacb8SPankaj Gupta #include "caam.h"
17*a0edacb8SPankaj Gupta #include <common/debug.h>
18*a0edacb8SPankaj Gupta #include "jobdesc.h"
19*a0edacb8SPankaj Gupta #include "sec_hw_specific.h"
20*a0edacb8SPankaj Gupta 
21*a0edacb8SPankaj Gupta 
22*a0edacb8SPankaj Gupta /* Job rings used for communication with SEC HW */
23*a0edacb8SPankaj Gupta extern struct sec_job_ring_t g_job_rings[MAX_SEC_JOB_RINGS];
24*a0edacb8SPankaj Gupta 
25*a0edacb8SPankaj Gupta /* The current state of SEC user space driver */
26*a0edacb8SPankaj Gupta extern volatile sec_driver_state_t g_driver_state;
27*a0edacb8SPankaj Gupta 
28*a0edacb8SPankaj Gupta /* The number of job rings used by SEC user space driver */
29*a0edacb8SPankaj Gupta extern int g_job_rings_no;
30*a0edacb8SPankaj Gupta 
31*a0edacb8SPankaj Gupta /* LOCAL FUNCTIONS */
hw_set_input_ring_start_addr(struct jobring_regs * regs,phys_addr_t * start_addr)32*a0edacb8SPankaj Gupta static inline void hw_set_input_ring_start_addr(struct jobring_regs *regs,
33*a0edacb8SPankaj Gupta 						phys_addr_t *start_addr)
34*a0edacb8SPankaj Gupta {
35*a0edacb8SPankaj Gupta #if defined(CONFIG_PHYS_64BIT)
36*a0edacb8SPankaj Gupta 	sec_out32(&regs->irba_h, PHYS_ADDR_HI(start_addr));
37*a0edacb8SPankaj Gupta #else
38*a0edacb8SPankaj Gupta 	sec_out32(&regs->irba_h, 0);
39*a0edacb8SPankaj Gupta #endif
40*a0edacb8SPankaj Gupta 	sec_out32(&regs->irba_l, PHYS_ADDR_LO(start_addr));
41*a0edacb8SPankaj Gupta }
42*a0edacb8SPankaj Gupta 
hw_set_output_ring_start_addr(struct jobring_regs * regs,phys_addr_t * start_addr)43*a0edacb8SPankaj Gupta static inline void hw_set_output_ring_start_addr(struct jobring_regs *regs,
44*a0edacb8SPankaj Gupta 						 phys_addr_t *start_addr)
45*a0edacb8SPankaj Gupta {
46*a0edacb8SPankaj Gupta #if defined(CONFIG_PHYS_64BIT)
47*a0edacb8SPankaj Gupta 	sec_out32(&regs->orba_h, PHYS_ADDR_HI(start_addr));
48*a0edacb8SPankaj Gupta #else
49*a0edacb8SPankaj Gupta 	sec_out32(&regs->orba_h, 0);
50*a0edacb8SPankaj Gupta #endif
51*a0edacb8SPankaj Gupta 	sec_out32(&regs->orba_l, PHYS_ADDR_LO(start_addr));
52*a0edacb8SPankaj Gupta }
53*a0edacb8SPankaj Gupta 
54*a0edacb8SPankaj Gupta /* ORJR - Output Ring Jobs Removed Register shows how many jobs were
55*a0edacb8SPankaj Gupta  * removed from the Output Ring for processing by software. This is done after
56*a0edacb8SPankaj Gupta  * the software has processed the entries.
57*a0edacb8SPankaj Gupta  */
hw_remove_entries(sec_job_ring_t * jr,int num)58*a0edacb8SPankaj Gupta static inline void hw_remove_entries(sec_job_ring_t *jr, int num)
59*a0edacb8SPankaj Gupta {
60*a0edacb8SPankaj Gupta 	struct jobring_regs *regs =
61*a0edacb8SPankaj Gupta 	    (struct jobring_regs *)jr->register_base_addr;
62*a0edacb8SPankaj Gupta 
63*a0edacb8SPankaj Gupta 	sec_out32(&regs->orjr, num);
64*a0edacb8SPankaj Gupta }
65*a0edacb8SPankaj Gupta 
66*a0edacb8SPankaj Gupta /* IRSA - Input Ring Slots Available register holds the number of entries in
67*a0edacb8SPankaj Gupta  * the Job Ring's input ring. Once a job is enqueued, the value returned is
68*a0edacb8SPankaj Gupta  * decremented by the hardware by the number of jobs enqueued.
69*a0edacb8SPankaj Gupta  */
hw_get_available_slots(sec_job_ring_t * jr)70*a0edacb8SPankaj Gupta static inline int hw_get_available_slots(sec_job_ring_t *jr)
71*a0edacb8SPankaj Gupta {
72*a0edacb8SPankaj Gupta 	struct jobring_regs *regs =
73*a0edacb8SPankaj Gupta 	    (struct jobring_regs *)jr->register_base_addr;
74*a0edacb8SPankaj Gupta 
75*a0edacb8SPankaj Gupta 	return sec_in32(&regs->irsa);
76*a0edacb8SPankaj Gupta }
77*a0edacb8SPankaj Gupta 
78*a0edacb8SPankaj Gupta /* ORSFR - Output Ring Slots Full register holds the number of jobs which were
79*a0edacb8SPankaj Gupta  * processed by the SEC and can be retrieved by the software. Once a job has
80*a0edacb8SPankaj Gupta  * been processed by software, the user will call hw_remove_one_entry in order
81*a0edacb8SPankaj Gupta  * to notify the SEC that the entry was processed
82*a0edacb8SPankaj Gupta  */
hw_get_no_finished_jobs(sec_job_ring_t * jr)83*a0edacb8SPankaj Gupta static inline int hw_get_no_finished_jobs(sec_job_ring_t *jr)
84*a0edacb8SPankaj Gupta {
85*a0edacb8SPankaj Gupta 	struct jobring_regs *regs =
86*a0edacb8SPankaj Gupta 	    (struct jobring_regs *)jr->register_base_addr;
87*a0edacb8SPankaj Gupta 
88*a0edacb8SPankaj Gupta 	return sec_in32(&regs->orsf);
89*a0edacb8SPankaj Gupta }
90*a0edacb8SPankaj Gupta 
91*a0edacb8SPankaj Gupta /* @brief Process Jump Halt Condition related errors
92*a0edacb8SPankaj Gupta  * @param [in]  error_code The error code in the descriptor status word
93*a0edacb8SPankaj Gupta  */
hw_handle_jmp_halt_cond_err(union hw_error_code error_code)94*a0edacb8SPankaj Gupta static inline void hw_handle_jmp_halt_cond_err(union hw_error_code error_code)
95*a0edacb8SPankaj Gupta {
96*a0edacb8SPankaj Gupta 	ERROR("JMP %x\n", error_code.error_desc.jmp_halt_cond_src.jmp);
97*a0edacb8SPankaj Gupta 	ERROR("Descriptor Index: %d\n",
98*a0edacb8SPankaj Gupta 	      error_code.error_desc.jmp_halt_cond_src.desc_idx);
99*a0edacb8SPankaj Gupta 	ERROR(" Condition %x\n", error_code.error_desc.jmp_halt_cond_src.cond);
100*a0edacb8SPankaj Gupta }
101*a0edacb8SPankaj Gupta 
102*a0edacb8SPankaj Gupta /* @brief Process DECO related errors
103*a0edacb8SPankaj Gupta  * @param [in]  error_code      The error code in the descriptor status word
104*a0edacb8SPankaj Gupta  */
hw_handle_deco_err(union hw_error_code error_code)105*a0edacb8SPankaj Gupta static inline void hw_handle_deco_err(union hw_error_code error_code)
106*a0edacb8SPankaj Gupta {
107*a0edacb8SPankaj Gupta 	ERROR("JMP %x\n", error_code.error_desc.deco_src.jmp);
108*a0edacb8SPankaj Gupta 	ERROR("Descriptor Index: 0x%x",
109*a0edacb8SPankaj Gupta 	      error_code.error_desc.deco_src.desc_idx);
110*a0edacb8SPankaj Gupta 
111*a0edacb8SPankaj Gupta 	switch (error_code.error_desc.deco_src.desc_err) {
112*a0edacb8SPankaj Gupta 	case SEC_HW_ERR_DECO_HFN_THRESHOLD:
113*a0edacb8SPankaj Gupta 		WARN(" Descriptor completed but exceeds the Threshold");
114*a0edacb8SPankaj Gupta 		break;
115*a0edacb8SPankaj Gupta 	default:
116*a0edacb8SPankaj Gupta 		ERROR("Error 0x%04x not implemented",
117*a0edacb8SPankaj Gupta 		      error_code.error_desc.deco_src.desc_err);
118*a0edacb8SPankaj Gupta 		break;
119*a0edacb8SPankaj Gupta 	}
120*a0edacb8SPankaj Gupta }
121*a0edacb8SPankaj Gupta 
122*a0edacb8SPankaj Gupta /* @brief Process  Jump Halt User Status related errors
123*a0edacb8SPankaj Gupta  * @param [in]  error_code      The error code in the descriptor status word
124*a0edacb8SPankaj Gupta  */
hw_handle_jmp_halt_user_err(union hw_error_code error_code)125*a0edacb8SPankaj Gupta static inline void hw_handle_jmp_halt_user_err(union hw_error_code error_code)
126*a0edacb8SPankaj Gupta {
127*a0edacb8SPankaj Gupta 	WARN(" Not implemented");
128*a0edacb8SPankaj Gupta }
129*a0edacb8SPankaj Gupta 
130*a0edacb8SPankaj Gupta /* @brief Process CCB related errors
131*a0edacb8SPankaj Gupta  * @param [in]  error_code      The error code in the descriptor status word
132*a0edacb8SPankaj Gupta  */
hw_handle_ccb_err(union hw_error_code hw_error_code)133*a0edacb8SPankaj Gupta static inline void hw_handle_ccb_err(union hw_error_code hw_error_code)
134*a0edacb8SPankaj Gupta {
135*a0edacb8SPankaj Gupta 	WARN(" Not implemented");
136*a0edacb8SPankaj Gupta }
137*a0edacb8SPankaj Gupta 
138*a0edacb8SPankaj Gupta /* @brief Process Job Ring related errors
139*a0edacb8SPankaj Gupta  * @param [in]  error_code      The error code in the descriptor status word
140*a0edacb8SPankaj Gupta  */
hw_handle_jr_err(union hw_error_code hw_error_code)141*a0edacb8SPankaj Gupta static inline void hw_handle_jr_err(union hw_error_code hw_error_code)
142*a0edacb8SPankaj Gupta {
143*a0edacb8SPankaj Gupta 	WARN(" Not implemented");
144*a0edacb8SPankaj Gupta }
145*a0edacb8SPankaj Gupta 
146*a0edacb8SPankaj Gupta /* GLOBAL FUNCTIONS */
147*a0edacb8SPankaj Gupta 
hw_reset_job_ring(sec_job_ring_t * job_ring)148*a0edacb8SPankaj Gupta int hw_reset_job_ring(sec_job_ring_t *job_ring)
149*a0edacb8SPankaj Gupta {
150*a0edacb8SPankaj Gupta 	int ret = 0;
151*a0edacb8SPankaj Gupta 	struct jobring_regs *regs =
152*a0edacb8SPankaj Gupta 	    (struct jobring_regs *)job_ring->register_base_addr;
153*a0edacb8SPankaj Gupta 
154*a0edacb8SPankaj Gupta 	/* First reset the job ring in hw */
155*a0edacb8SPankaj Gupta 	ret = hw_shutdown_job_ring(job_ring);
156*a0edacb8SPankaj Gupta 	if (ret != 0) {
157*a0edacb8SPankaj Gupta 		ERROR("Failed resetting job ring in hardware");
158*a0edacb8SPankaj Gupta 		return ret;
159*a0edacb8SPankaj Gupta 	}
160*a0edacb8SPankaj Gupta 	/* In order to have the HW JR in a workable state
161*a0edacb8SPankaj Gupta 	 *after a reset, I need to re-write the input
162*a0edacb8SPankaj Gupta 	 * queue size, input start address, output queue
163*a0edacb8SPankaj Gupta 	 * size and output start address
164*a0edacb8SPankaj Gupta 	 * Write the JR input queue size to the HW register
165*a0edacb8SPankaj Gupta 	 */
166*a0edacb8SPankaj Gupta 	sec_out32(&regs->irs, SEC_JOB_RING_SIZE);
167*a0edacb8SPankaj Gupta 
168*a0edacb8SPankaj Gupta 	/* Write the JR output queue size to the HW register */
169*a0edacb8SPankaj Gupta 	sec_out32(&regs->ors, SEC_JOB_RING_SIZE);
170*a0edacb8SPankaj Gupta 
171*a0edacb8SPankaj Gupta 	/* Write the JR input queue start address */
172*a0edacb8SPankaj Gupta 	hw_set_input_ring_start_addr(regs, vtop(job_ring->input_ring));
173*a0edacb8SPankaj Gupta 
174*a0edacb8SPankaj Gupta 	/* Write the JR output queue start address */
175*a0edacb8SPankaj Gupta 	hw_set_output_ring_start_addr(regs, vtop(job_ring->output_ring));
176*a0edacb8SPankaj Gupta 
177*a0edacb8SPankaj Gupta 	return 0;
178*a0edacb8SPankaj Gupta }
179*a0edacb8SPankaj Gupta 
hw_shutdown_job_ring(sec_job_ring_t * job_ring)180*a0edacb8SPankaj Gupta int hw_shutdown_job_ring(sec_job_ring_t *job_ring)
181*a0edacb8SPankaj Gupta {
182*a0edacb8SPankaj Gupta 	struct jobring_regs *regs =
183*a0edacb8SPankaj Gupta 	    (struct jobring_regs *)job_ring->register_base_addr;
184*a0edacb8SPankaj Gupta 	unsigned int timeout = SEC_TIMEOUT;
185*a0edacb8SPankaj Gupta 	uint32_t tmp = 0U;
186*a0edacb8SPankaj Gupta 
187*a0edacb8SPankaj Gupta 	VERBOSE("Resetting Job ring\n");
188*a0edacb8SPankaj Gupta 
189*a0edacb8SPankaj Gupta 	/*
190*a0edacb8SPankaj Gupta 	 * Mask interrupts since we are going to poll
191*a0edacb8SPankaj Gupta 	 * for reset completion status
192*a0edacb8SPankaj Gupta 	 * Also, at POR, interrupts are ENABLED on a JR, thus
193*a0edacb8SPankaj Gupta 	 * this is the point where I can disable them without
194*a0edacb8SPankaj Gupta 	 * changing the code logic too much
195*a0edacb8SPankaj Gupta 	 */
196*a0edacb8SPankaj Gupta 
197*a0edacb8SPankaj Gupta 	jr_disable_irqs(job_ring);
198*a0edacb8SPankaj Gupta 
199*a0edacb8SPankaj Gupta 	/* initiate flush (required prior to reset) */
200*a0edacb8SPankaj Gupta 	sec_out32(&regs->jrcr, JR_REG_JRCR_VAL_RESET);
201*a0edacb8SPankaj Gupta 
202*a0edacb8SPankaj Gupta 	/* dummy read */
203*a0edacb8SPankaj Gupta 	tmp = sec_in32(&regs->jrcr);
204*a0edacb8SPankaj Gupta 
205*a0edacb8SPankaj Gupta 	do {
206*a0edacb8SPankaj Gupta 		tmp = sec_in32(&regs->jrint);
207*a0edacb8SPankaj Gupta 	} while (((tmp & JRINT_ERR_HALT_MASK) ==
208*a0edacb8SPankaj Gupta 		  JRINT_ERR_HALT_INPROGRESS) && ((--timeout) != 0U));
209*a0edacb8SPankaj Gupta 
210*a0edacb8SPankaj Gupta 	if ((tmp & JRINT_ERR_HALT_MASK) != JRINT_ERR_HALT_COMPLETE ||
211*a0edacb8SPankaj Gupta 	    timeout == 0U) {
212*a0edacb8SPankaj Gupta 		ERROR("Failed to flush hw job ring %x\n %u", tmp, timeout);
213*a0edacb8SPankaj Gupta 		/* unmask interrupts */
214*a0edacb8SPankaj Gupta 		if (job_ring->jr_mode != SEC_NOTIFICATION_TYPE_POLL) {
215*a0edacb8SPankaj Gupta 			jr_enable_irqs(job_ring);
216*a0edacb8SPankaj Gupta 		}
217*a0edacb8SPankaj Gupta 		return -1;
218*a0edacb8SPankaj Gupta 	}
219*a0edacb8SPankaj Gupta 	/* Initiate reset */
220*a0edacb8SPankaj Gupta 	timeout = SEC_TIMEOUT;
221*a0edacb8SPankaj Gupta 	sec_out32(&regs->jrcr, JR_REG_JRCR_VAL_RESET);
222*a0edacb8SPankaj Gupta 
223*a0edacb8SPankaj Gupta 	do {
224*a0edacb8SPankaj Gupta 		tmp = sec_in32(&regs->jrcr);
225*a0edacb8SPankaj Gupta 	} while (((tmp & JR_REG_JRCR_VAL_RESET) != 0U) &&
226*a0edacb8SPankaj Gupta 		 ((--timeout) != 0U));
227*a0edacb8SPankaj Gupta 
228*a0edacb8SPankaj Gupta 	if (timeout == 0U) {
229*a0edacb8SPankaj Gupta 		ERROR("Failed to reset hw job ring\n");
230*a0edacb8SPankaj Gupta 		/* unmask interrupts */
231*a0edacb8SPankaj Gupta 		if (job_ring->jr_mode != SEC_NOTIFICATION_TYPE_POLL) {
232*a0edacb8SPankaj Gupta 			jr_enable_irqs(job_ring);
233*a0edacb8SPankaj Gupta 		}
234*a0edacb8SPankaj Gupta 		return -1;
235*a0edacb8SPankaj Gupta 	}
236*a0edacb8SPankaj Gupta 	/* unmask interrupts */
237*a0edacb8SPankaj Gupta 	if (job_ring->jr_mode != SEC_NOTIFICATION_TYPE_POLL) {
238*a0edacb8SPankaj Gupta 		jr_enable_irqs(job_ring);
239*a0edacb8SPankaj Gupta 	}
240*a0edacb8SPankaj Gupta 	return 0;
241*a0edacb8SPankaj Gupta 
242*a0edacb8SPankaj Gupta }
243*a0edacb8SPankaj Gupta 
hw_handle_job_ring_error(sec_job_ring_t * job_ring,uint32_t error_code)244*a0edacb8SPankaj Gupta void hw_handle_job_ring_error(sec_job_ring_t *job_ring, uint32_t error_code)
245*a0edacb8SPankaj Gupta {
246*a0edacb8SPankaj Gupta 	union hw_error_code hw_err_code;
247*a0edacb8SPankaj Gupta 
248*a0edacb8SPankaj Gupta 	hw_err_code.error = error_code;
249*a0edacb8SPankaj Gupta 
250*a0edacb8SPankaj Gupta 	switch (hw_err_code.error_desc.value.ssrc) {
251*a0edacb8SPankaj Gupta 	case SEC_HW_ERR_SSRC_NO_SRC:
252*a0edacb8SPankaj Gupta 		INFO("No Status Source ");
253*a0edacb8SPankaj Gupta 		break;
254*a0edacb8SPankaj Gupta 	case SEC_HW_ERR_SSRC_CCB_ERR:
255*a0edacb8SPankaj Gupta 		INFO("CCB Status Source");
256*a0edacb8SPankaj Gupta 		hw_handle_ccb_err(hw_err_code);
257*a0edacb8SPankaj Gupta 		break;
258*a0edacb8SPankaj Gupta 	case SEC_HW_ERR_SSRC_JMP_HALT_U:
259*a0edacb8SPankaj Gupta 		INFO("Jump Halt User Status Source");
260*a0edacb8SPankaj Gupta 		hw_handle_jmp_halt_user_err(hw_err_code);
261*a0edacb8SPankaj Gupta 		break;
262*a0edacb8SPankaj Gupta 	case SEC_HW_ERR_SSRC_DECO:
263*a0edacb8SPankaj Gupta 		INFO("DECO Status Source");
264*a0edacb8SPankaj Gupta 		hw_handle_deco_err(hw_err_code);
265*a0edacb8SPankaj Gupta 		break;
266*a0edacb8SPankaj Gupta 	case SEC_HW_ERR_SSRC_JR:
267*a0edacb8SPankaj Gupta 		INFO("Job Ring Status Source");
268*a0edacb8SPankaj Gupta 		hw_handle_jr_err(hw_err_code);
269*a0edacb8SPankaj Gupta 		break;
270*a0edacb8SPankaj Gupta 	case SEC_HW_ERR_SSRC_JMP_HALT_COND:
271*a0edacb8SPankaj Gupta 		INFO("Jump Halt Condition Codes");
272*a0edacb8SPankaj Gupta 		hw_handle_jmp_halt_cond_err(hw_err_code);
273*a0edacb8SPankaj Gupta 		break;
274*a0edacb8SPankaj Gupta 	default:
275*a0edacb8SPankaj Gupta 		INFO("Unknown SSRC");
276*a0edacb8SPankaj Gupta 		break;
277*a0edacb8SPankaj Gupta 	}
278*a0edacb8SPankaj Gupta }
279*a0edacb8SPankaj Gupta 
hw_job_ring_error(sec_job_ring_t * job_ring)280*a0edacb8SPankaj Gupta int hw_job_ring_error(sec_job_ring_t *job_ring)
281*a0edacb8SPankaj Gupta {
282*a0edacb8SPankaj Gupta 	uint32_t jrint_error_code;
283*a0edacb8SPankaj Gupta 	struct jobring_regs *regs =
284*a0edacb8SPankaj Gupta 	    (struct jobring_regs *)job_ring->register_base_addr;
285*a0edacb8SPankaj Gupta 
286*a0edacb8SPankaj Gupta 	if (JR_REG_JRINT_JRE_EXTRACT(sec_in32(&regs->jrint)) == 0) {
287*a0edacb8SPankaj Gupta 		return 0;
288*a0edacb8SPankaj Gupta 	}
289*a0edacb8SPankaj Gupta 
290*a0edacb8SPankaj Gupta 	jrint_error_code =
291*a0edacb8SPankaj Gupta 	    JR_REG_JRINT_ERR_TYPE_EXTRACT(sec_in32(&regs->jrint));
292*a0edacb8SPankaj Gupta 	switch (jrint_error_code) {
293*a0edacb8SPankaj Gupta 	case JRINT_ERR_WRITE_STATUS:
294*a0edacb8SPankaj Gupta 		ERROR("Error writing status to Output Ring ");
295*a0edacb8SPankaj Gupta 		break;
296*a0edacb8SPankaj Gupta 	case JRINT_ERR_BAD_INPUT_BASE:
297*a0edacb8SPankaj Gupta 		ERROR("Bad Input Ring Base (not on a 4-byte boundary)\n");
298*a0edacb8SPankaj Gupta 		break;
299*a0edacb8SPankaj Gupta 	case JRINT_ERR_BAD_OUTPUT_BASE:
300*a0edacb8SPankaj Gupta 		ERROR("Bad Output Ring Base (not on a 4-byte boundary)\n");
301*a0edacb8SPankaj Gupta 		break;
302*a0edacb8SPankaj Gupta 	case JRINT_ERR_WRITE_2_IRBA:
303*a0edacb8SPankaj Gupta 		ERROR("Invalid write to Input Ring Base Address Register\n");
304*a0edacb8SPankaj Gupta 		break;
305*a0edacb8SPankaj Gupta 	case JRINT_ERR_WRITE_2_ORBA:
306*a0edacb8SPankaj Gupta 		ERROR("Invalid write to Output Ring Base Address Register\n");
307*a0edacb8SPankaj Gupta 		break;
308*a0edacb8SPankaj Gupta 	case JRINT_ERR_RES_B4_HALT:
309*a0edacb8SPankaj Gupta 		ERROR("Job Ring released before Job Ring is halted\n");
310*a0edacb8SPankaj Gupta 		break;
311*a0edacb8SPankaj Gupta 	case JRINT_ERR_REM_TOO_MANY:
312*a0edacb8SPankaj Gupta 		ERROR("Removed too many jobs from job ring\n");
313*a0edacb8SPankaj Gupta 		break;
314*a0edacb8SPankaj Gupta 	case JRINT_ERR_ADD_TOO_MANY:
315*a0edacb8SPankaj Gupta 		ERROR("Added too many jobs on job ring\n");
316*a0edacb8SPankaj Gupta 		break;
317*a0edacb8SPankaj Gupta 	default:
318*a0edacb8SPankaj Gupta 		ERROR("Unknown SEC JR Error :%d\n", jrint_error_code);
319*a0edacb8SPankaj Gupta 		break;
320*a0edacb8SPankaj Gupta 	}
321*a0edacb8SPankaj Gupta 	return jrint_error_code;
322*a0edacb8SPankaj Gupta }
323*a0edacb8SPankaj Gupta 
hw_job_ring_set_coalescing_param(sec_job_ring_t * job_ring,uint16_t irq_coalescing_timer,uint8_t irq_coalescing_count)324*a0edacb8SPankaj Gupta int hw_job_ring_set_coalescing_param(sec_job_ring_t *job_ring,
325*a0edacb8SPankaj Gupta 				     uint16_t irq_coalescing_timer,
326*a0edacb8SPankaj Gupta 				     uint8_t irq_coalescing_count)
327*a0edacb8SPankaj Gupta {
328*a0edacb8SPankaj Gupta 	uint32_t reg_val = 0U;
329*a0edacb8SPankaj Gupta 	struct jobring_regs *regs =
330*a0edacb8SPankaj Gupta 	    (struct jobring_regs *)job_ring->register_base_addr;
331*a0edacb8SPankaj Gupta 
332*a0edacb8SPankaj Gupta 	/* Set descriptor count coalescing */
333*a0edacb8SPankaj Gupta 	reg_val |= (irq_coalescing_count << JR_REG_JRCFG_LO_ICDCT_SHIFT);
334*a0edacb8SPankaj Gupta 
335*a0edacb8SPankaj Gupta 	/* Set coalescing timer value */
336*a0edacb8SPankaj Gupta 	reg_val |= (irq_coalescing_timer << JR_REG_JRCFG_LO_ICTT_SHIFT);
337*a0edacb8SPankaj Gupta 
338*a0edacb8SPankaj Gupta 	/* Update parameters in HW */
339*a0edacb8SPankaj Gupta 	sec_out32(&regs->jrcfg1, reg_val);
340*a0edacb8SPankaj Gupta 
341*a0edacb8SPankaj Gupta 	VERBOSE("Set coalescing params on jr\n");
342*a0edacb8SPankaj Gupta 
343*a0edacb8SPankaj Gupta 	return 0;
344*a0edacb8SPankaj Gupta }
345*a0edacb8SPankaj Gupta 
hw_job_ring_enable_coalescing(sec_job_ring_t * job_ring)346*a0edacb8SPankaj Gupta int hw_job_ring_enable_coalescing(sec_job_ring_t *job_ring)
347*a0edacb8SPankaj Gupta {
348*a0edacb8SPankaj Gupta 	uint32_t reg_val = 0U;
349*a0edacb8SPankaj Gupta 	struct jobring_regs *regs =
350*a0edacb8SPankaj Gupta 	    (struct jobring_regs *)job_ring->register_base_addr;
351*a0edacb8SPankaj Gupta 
352*a0edacb8SPankaj Gupta 	/* Get the current value of the register */
353*a0edacb8SPankaj Gupta 	reg_val = sec_in32(&regs->jrcfg1);
354*a0edacb8SPankaj Gupta 
355*a0edacb8SPankaj Gupta 	/* Enable coalescing */
356*a0edacb8SPankaj Gupta 	reg_val |= JR_REG_JRCFG_LO_ICEN_EN;
357*a0edacb8SPankaj Gupta 
358*a0edacb8SPankaj Gupta 	/* Write in hw */
359*a0edacb8SPankaj Gupta 	sec_out32(&regs->jrcfg1, reg_val);
360*a0edacb8SPankaj Gupta 
361*a0edacb8SPankaj Gupta 	VERBOSE("Enabled coalescing on jr\n");
362*a0edacb8SPankaj Gupta 
363*a0edacb8SPankaj Gupta 	return 0;
364*a0edacb8SPankaj Gupta }
365*a0edacb8SPankaj Gupta 
hw_job_ring_disable_coalescing(sec_job_ring_t * job_ring)366*a0edacb8SPankaj Gupta int hw_job_ring_disable_coalescing(sec_job_ring_t *job_ring)
367*a0edacb8SPankaj Gupta {
368*a0edacb8SPankaj Gupta 	uint32_t reg_val = 0U;
369*a0edacb8SPankaj Gupta 	struct jobring_regs *regs =
370*a0edacb8SPankaj Gupta 	    (struct jobring_regs *)job_ring->register_base_addr;
371*a0edacb8SPankaj Gupta 
372*a0edacb8SPankaj Gupta 	/* Get the current value of the register */
373*a0edacb8SPankaj Gupta 	reg_val = sec_in32(&regs->jrcfg1);
374*a0edacb8SPankaj Gupta 
375*a0edacb8SPankaj Gupta 	/* Disable coalescing */
376*a0edacb8SPankaj Gupta 	reg_val &= ~JR_REG_JRCFG_LO_ICEN_EN;
377*a0edacb8SPankaj Gupta 
378*a0edacb8SPankaj Gupta 	/* Write in hw */
379*a0edacb8SPankaj Gupta 	sec_out32(&regs->jrcfg1, reg_val);
380*a0edacb8SPankaj Gupta 
381*a0edacb8SPankaj Gupta 	VERBOSE("Disabled coalescing on jr");
382*a0edacb8SPankaj Gupta 
383*a0edacb8SPankaj Gupta 	return 0;
384*a0edacb8SPankaj Gupta 
385*a0edacb8SPankaj Gupta }
386*a0edacb8SPankaj Gupta 
hw_flush_job_ring(struct sec_job_ring_t * job_ring,uint32_t do_notify,uint32_t error_code,uint32_t * notified_descs)387*a0edacb8SPankaj Gupta void hw_flush_job_ring(struct sec_job_ring_t *job_ring,
388*a0edacb8SPankaj Gupta 		       uint32_t do_notify,
389*a0edacb8SPankaj Gupta 		       uint32_t error_code, uint32_t *notified_descs)
390*a0edacb8SPankaj Gupta {
391*a0edacb8SPankaj Gupta 	int32_t jobs_no_to_discard = 0;
392*a0edacb8SPankaj Gupta 	int32_t discarded_descs_no = 0;
393*a0edacb8SPankaj Gupta 	int32_t number_of_jobs_available = 0;
394*a0edacb8SPankaj Gupta 
395*a0edacb8SPankaj Gupta 	VERBOSE("JR pi[%d]i ci[%d]\n", job_ring->pidx, job_ring->cidx);
396*a0edacb8SPankaj Gupta 	VERBOSE("error code %x\n", error_code);
397*a0edacb8SPankaj Gupta 	VERBOSE("Notify_desc = %d\n", do_notify);
398*a0edacb8SPankaj Gupta 
399*a0edacb8SPankaj Gupta 	number_of_jobs_available = hw_get_no_finished_jobs(job_ring);
400*a0edacb8SPankaj Gupta 
401*a0edacb8SPankaj Gupta 	/* Discard all jobs */
402*a0edacb8SPankaj Gupta 	jobs_no_to_discard = number_of_jobs_available;
403*a0edacb8SPankaj Gupta 
404*a0edacb8SPankaj Gupta 	VERBOSE("JR pi[%d]i ci[%d]\n", job_ring->pidx, job_ring->cidx);
405*a0edacb8SPankaj Gupta 	VERBOSE("Discarding desc = %d\n", jobs_no_to_discard);
406*a0edacb8SPankaj Gupta 
407*a0edacb8SPankaj Gupta 	while (jobs_no_to_discard > discarded_descs_no) {
408*a0edacb8SPankaj Gupta 		discarded_descs_no++;
409*a0edacb8SPankaj Gupta 		/* Now increment the consumer index for the current job ring,
410*a0edacb8SPankaj Gupta 		 * AFTER saving job in temporary location!
411*a0edacb8SPankaj Gupta 		 * Increment the consumer index for the current job ring
412*a0edacb8SPankaj Gupta 		 */
413*a0edacb8SPankaj Gupta 
414*a0edacb8SPankaj Gupta 		job_ring->cidx = SEC_CIRCULAR_COUNTER(job_ring->cidx,
415*a0edacb8SPankaj Gupta 						      SEC_JOB_RING_SIZE);
416*a0edacb8SPankaj Gupta 
417*a0edacb8SPankaj Gupta 		hw_remove_entries(job_ring, 1);
418*a0edacb8SPankaj Gupta 	}
419*a0edacb8SPankaj Gupta 
420*a0edacb8SPankaj Gupta 	if (do_notify == true) {
421*a0edacb8SPankaj Gupta 		if (notified_descs == NULL) {
422*a0edacb8SPankaj Gupta 			return;
423*a0edacb8SPankaj Gupta 		}
424*a0edacb8SPankaj Gupta 		*notified_descs = discarded_descs_no;
425*a0edacb8SPankaj Gupta 	}
426*a0edacb8SPankaj Gupta }
427*a0edacb8SPankaj Gupta 
428*a0edacb8SPankaj Gupta /* return >0 in case of success
429*a0edacb8SPankaj Gupta  *  -1 in case of error from SEC block
430*a0edacb8SPankaj Gupta  *  0 in case job not yet processed by SEC
431*a0edacb8SPankaj Gupta  *   or  Descriptor returned is NULL after dequeue
432*a0edacb8SPankaj Gupta  */
hw_poll_job_ring(struct sec_job_ring_t * job_ring,int32_t limit)433*a0edacb8SPankaj Gupta int hw_poll_job_ring(struct sec_job_ring_t *job_ring, int32_t limit)
434*a0edacb8SPankaj Gupta {
435*a0edacb8SPankaj Gupta 	int32_t jobs_no_to_notify = 0;
436*a0edacb8SPankaj Gupta 	int32_t number_of_jobs_available = 0;
437*a0edacb8SPankaj Gupta 	int32_t notified_descs_no = 0;
438*a0edacb8SPankaj Gupta 	uint32_t error_descs_no = 0U;
439*a0edacb8SPankaj Gupta 	uint32_t sec_error_code = 0U;
440*a0edacb8SPankaj Gupta 	uint32_t do_driver_shutdown = false;
441*a0edacb8SPankaj Gupta 	phys_addr_t *fnptr, *arg_addr;
442*a0edacb8SPankaj Gupta 	user_callback usercall = NULL;
443*a0edacb8SPankaj Gupta 	uint8_t *current_desc;
444*a0edacb8SPankaj Gupta 	void *arg;
445*a0edacb8SPankaj Gupta 	uintptr_t current_desc_addr;
446*a0edacb8SPankaj Gupta 	phys_addr_t current_desc_loc;
447*a0edacb8SPankaj Gupta 
448*a0edacb8SPankaj Gupta #if defined(SEC_MEM_NON_COHERENT) && defined(IMAGE_BL2)
449*a0edacb8SPankaj Gupta 	inv_dcache_range((uintptr_t)job_ring->register_base_addr, sizeof(struct jobring_regs));
450*a0edacb8SPankaj Gupta 	dmbsy();
451*a0edacb8SPankaj Gupta #endif
452*a0edacb8SPankaj Gupta 
453*a0edacb8SPankaj Gupta 	/* check here if any JR error that cannot be written
454*a0edacb8SPankaj Gupta 	 * in the output status word has occurred
455*a0edacb8SPankaj Gupta 	 */
456*a0edacb8SPankaj Gupta 	sec_error_code = hw_job_ring_error(job_ring);
457*a0edacb8SPankaj Gupta 	if (unlikely(sec_error_code) != 0) {
458*a0edacb8SPankaj Gupta 		ERROR("Error here itself %x\n", sec_error_code);
459*a0edacb8SPankaj Gupta 		return -1;
460*a0edacb8SPankaj Gupta 	}
461*a0edacb8SPankaj Gupta 	/* Compute the number of notifications that need to be raised to UA
462*a0edacb8SPankaj Gupta 	 * If limit < 0 -> notify all done jobs
463*a0edacb8SPankaj Gupta 	 * If limit > total number of done jobs -> notify all done jobs
464*a0edacb8SPankaj Gupta 	 * If limit = 0 -> error
465*a0edacb8SPankaj Gupta 	 * If limit > 0 && limit < total number of done jobs -> notify a number
466*a0edacb8SPankaj Gupta 	 * of done jobs equal with limit
467*a0edacb8SPankaj Gupta 	 */
468*a0edacb8SPankaj Gupta 
469*a0edacb8SPankaj Gupta 	/*compute the number of jobs available in the job ring based on the
470*a0edacb8SPankaj Gupta 	 * producer and consumer index values.
471*a0edacb8SPankaj Gupta 	 */
472*a0edacb8SPankaj Gupta 
473*a0edacb8SPankaj Gupta 	number_of_jobs_available = hw_get_no_finished_jobs(job_ring);
474*a0edacb8SPankaj Gupta 	jobs_no_to_notify = (limit < 0 || limit > number_of_jobs_available) ?
475*a0edacb8SPankaj Gupta 	    number_of_jobs_available : limit;
476*a0edacb8SPankaj Gupta 	VERBOSE("JR - pi %d, ci %d, ", job_ring->pidx, job_ring->cidx);
477*a0edacb8SPankaj Gupta 	VERBOSE("Jobs submitted %d", number_of_jobs_available);
478*a0edacb8SPankaj Gupta 	VERBOSE("Jobs to notify %d\n", jobs_no_to_notify);
479*a0edacb8SPankaj Gupta 
480*a0edacb8SPankaj Gupta 	while (jobs_no_to_notify > notified_descs_no) {
481*a0edacb8SPankaj Gupta 
482*a0edacb8SPankaj Gupta #if defined(SEC_MEM_NON_COHERENT) && defined(IMAGE_BL2)
483*a0edacb8SPankaj Gupta 		inv_dcache_range(
484*a0edacb8SPankaj Gupta 			(uintptr_t)(&job_ring->output_ring[job_ring->cidx]),
485*a0edacb8SPankaj Gupta 			sizeof(struct sec_outring_entry));
486*a0edacb8SPankaj Gupta 		dmbsy();
487*a0edacb8SPankaj Gupta #endif
488*a0edacb8SPankaj Gupta 
489*a0edacb8SPankaj Gupta 		/* Get job status here */
490*a0edacb8SPankaj Gupta 		sec_error_code =
491*a0edacb8SPankaj Gupta 		    sec_in32(&(job_ring->output_ring[job_ring->cidx].status));
492*a0edacb8SPankaj Gupta 
493*a0edacb8SPankaj Gupta 		/* Get completed descriptor
494*a0edacb8SPankaj Gupta 		 */
495*a0edacb8SPankaj Gupta 		current_desc_loc = (uintptr_t)
496*a0edacb8SPankaj Gupta 		    &job_ring->output_ring[job_ring->cidx].desc;
497*a0edacb8SPankaj Gupta 		current_desc_addr = sec_read_addr(current_desc_loc);
498*a0edacb8SPankaj Gupta 
499*a0edacb8SPankaj Gupta 		current_desc = ptov((phys_addr_t *) current_desc_addr);
500*a0edacb8SPankaj Gupta 		if (current_desc == 0) {
501*a0edacb8SPankaj Gupta 			ERROR("No descriptor returned from SEC");
502*a0edacb8SPankaj Gupta 			assert(current_desc);
503*a0edacb8SPankaj Gupta 			return 0;
504*a0edacb8SPankaj Gupta 		}
505*a0edacb8SPankaj Gupta 		/* now increment the consumer index for the current job ring,
506*a0edacb8SPankaj Gupta 		 * AFTER saving job in temporary location!
507*a0edacb8SPankaj Gupta 		 */
508*a0edacb8SPankaj Gupta 		job_ring->cidx = SEC_CIRCULAR_COUNTER(job_ring->cidx,
509*a0edacb8SPankaj Gupta 						      SEC_JOB_RING_SIZE);
510*a0edacb8SPankaj Gupta 
511*a0edacb8SPankaj Gupta 		if (sec_error_code != 0) {
512*a0edacb8SPankaj Gupta 			ERROR("desc at cidx %d\n ", job_ring->cidx);
513*a0edacb8SPankaj Gupta 			ERROR("generated error %x\n", sec_error_code);
514*a0edacb8SPankaj Gupta 
515*a0edacb8SPankaj Gupta 			sec_handle_desc_error(job_ring,
516*a0edacb8SPankaj Gupta 					      sec_error_code,
517*a0edacb8SPankaj Gupta 					      &error_descs_no,
518*a0edacb8SPankaj Gupta 					      &do_driver_shutdown);
519*a0edacb8SPankaj Gupta 			hw_remove_entries(job_ring, 1);
520*a0edacb8SPankaj Gupta 
521*a0edacb8SPankaj Gupta 			return -1;
522*a0edacb8SPankaj Gupta 		}
523*a0edacb8SPankaj Gupta 		/* Signal that the job has been processed & the slot is free */
524*a0edacb8SPankaj Gupta 		hw_remove_entries(job_ring, 1);
525*a0edacb8SPankaj Gupta 		notified_descs_no++;
526*a0edacb8SPankaj Gupta 
527*a0edacb8SPankaj Gupta 		arg_addr = (phys_addr_t *) (current_desc +
528*a0edacb8SPankaj Gupta 				(MAX_DESC_SIZE_WORDS * sizeof(uint32_t)));
529*a0edacb8SPankaj Gupta 
530*a0edacb8SPankaj Gupta 		fnptr = (phys_addr_t *) (current_desc +
531*a0edacb8SPankaj Gupta 					(MAX_DESC_SIZE_WORDS * sizeof(uint32_t)
532*a0edacb8SPankaj Gupta 					+  sizeof(void *)));
533*a0edacb8SPankaj Gupta 
534*a0edacb8SPankaj Gupta 		arg = (void *)*(arg_addr);
535*a0edacb8SPankaj Gupta 		if (*fnptr != 0) {
536*a0edacb8SPankaj Gupta 			VERBOSE("Callback Function called\n");
537*a0edacb8SPankaj Gupta 			usercall = (user_callback) *(fnptr);
538*a0edacb8SPankaj Gupta 			(*usercall) ((uint32_t *) current_desc,
539*a0edacb8SPankaj Gupta 				     sec_error_code, arg, job_ring);
540*a0edacb8SPankaj Gupta 		}
541*a0edacb8SPankaj Gupta 	}
542*a0edacb8SPankaj Gupta 
543*a0edacb8SPankaj Gupta 	return notified_descs_no;
544*a0edacb8SPankaj Gupta }
545*a0edacb8SPankaj Gupta 
sec_handle_desc_error(sec_job_ring_t * job_ring,uint32_t sec_error_code,uint32_t * notified_descs,uint32_t * do_driver_shutdown)546*a0edacb8SPankaj Gupta void sec_handle_desc_error(sec_job_ring_t *job_ring,
547*a0edacb8SPankaj Gupta 			   uint32_t sec_error_code,
548*a0edacb8SPankaj Gupta 			   uint32_t *notified_descs,
549*a0edacb8SPankaj Gupta 			   uint32_t *do_driver_shutdown)
550*a0edacb8SPankaj Gupta {
551*a0edacb8SPankaj Gupta 	/* Analyze the SEC error on this job ring */
552*a0edacb8SPankaj Gupta 	hw_handle_job_ring_error(job_ring, sec_error_code);
553*a0edacb8SPankaj Gupta }
554*a0edacb8SPankaj Gupta 
flush_job_rings(void)555*a0edacb8SPankaj Gupta void flush_job_rings(void)
556*a0edacb8SPankaj Gupta {
557*a0edacb8SPankaj Gupta 	struct sec_job_ring_t *job_ring = NULL;
558*a0edacb8SPankaj Gupta 	int i = 0;
559*a0edacb8SPankaj Gupta 
560*a0edacb8SPankaj Gupta 	for (i = 0; i < g_job_rings_no; i++) {
561*a0edacb8SPankaj Gupta 		job_ring = &g_job_rings[i];
562*a0edacb8SPankaj Gupta 		/* Producer index is frozen. If consumer index is not equal
563*a0edacb8SPankaj Gupta 		 * with producer index, then we have descs to flush.
564*a0edacb8SPankaj Gupta 		 */
565*a0edacb8SPankaj Gupta 		while (job_ring->pidx != job_ring->cidx) {
566*a0edacb8SPankaj Gupta 			hw_flush_job_ring(job_ring, false, 0,	/* no error */
567*a0edacb8SPankaj Gupta 					  NULL);
568*a0edacb8SPankaj Gupta 		}
569*a0edacb8SPankaj Gupta 	}
570*a0edacb8SPankaj Gupta }
571*a0edacb8SPankaj Gupta 
shutdown_job_ring(struct sec_job_ring_t * job_ring)572*a0edacb8SPankaj Gupta int shutdown_job_ring(struct sec_job_ring_t *job_ring)
573*a0edacb8SPankaj Gupta {
574*a0edacb8SPankaj Gupta 	int ret = 0;
575*a0edacb8SPankaj Gupta 
576*a0edacb8SPankaj Gupta 	ret = hw_shutdown_job_ring(job_ring);
577*a0edacb8SPankaj Gupta 	if (ret != 0) {
578*a0edacb8SPankaj Gupta 		ERROR("Failed to shutdown hardware job ring\n");
579*a0edacb8SPankaj Gupta 		return ret;
580*a0edacb8SPankaj Gupta 	}
581*a0edacb8SPankaj Gupta 
582*a0edacb8SPankaj Gupta 	if (job_ring->coalescing_en != 0) {
583*a0edacb8SPankaj Gupta 		hw_job_ring_disable_coalescing(job_ring);
584*a0edacb8SPankaj Gupta 	}
585*a0edacb8SPankaj Gupta 
586*a0edacb8SPankaj Gupta 	if (job_ring->jr_mode != SEC_NOTIFICATION_TYPE_POLL) {
587*a0edacb8SPankaj Gupta 		ret = jr_disable_irqs(job_ring);
588*a0edacb8SPankaj Gupta 		if (ret != 0) {
589*a0edacb8SPankaj Gupta 			ERROR("Failed to disable irqs for job ring");
590*a0edacb8SPankaj Gupta 			return ret;
591*a0edacb8SPankaj Gupta 		}
592*a0edacb8SPankaj Gupta 	}
593*a0edacb8SPankaj Gupta 
594*a0edacb8SPankaj Gupta 	return 0;
595*a0edacb8SPankaj Gupta }
596*a0edacb8SPankaj Gupta 
jr_enable_irqs(struct sec_job_ring_t * job_ring)597*a0edacb8SPankaj Gupta int jr_enable_irqs(struct sec_job_ring_t *job_ring)
598*a0edacb8SPankaj Gupta {
599*a0edacb8SPankaj Gupta 	uint32_t reg_val = 0U;
600*a0edacb8SPankaj Gupta 	struct jobring_regs *regs =
601*a0edacb8SPankaj Gupta 	    (struct jobring_regs *)job_ring->register_base_addr;
602*a0edacb8SPankaj Gupta 
603*a0edacb8SPankaj Gupta 	/* Get the current value of the register */
604*a0edacb8SPankaj Gupta 	reg_val = sec_in32(&regs->jrcfg1);
605*a0edacb8SPankaj Gupta 
606*a0edacb8SPankaj Gupta 	/* Enable interrupts by disabling interrupt masking*/
607*a0edacb8SPankaj Gupta 	reg_val &= ~JR_REG_JRCFG_LO_IMSK_EN;
608*a0edacb8SPankaj Gupta 
609*a0edacb8SPankaj Gupta 	/* Update parameters in HW */
610*a0edacb8SPankaj Gupta 	sec_out32(&regs->jrcfg1, reg_val);
611*a0edacb8SPankaj Gupta 
612*a0edacb8SPankaj Gupta 	VERBOSE("Enable interrupts on JR\n");
613*a0edacb8SPankaj Gupta 
614*a0edacb8SPankaj Gupta 	return 0;
615*a0edacb8SPankaj Gupta }
616*a0edacb8SPankaj Gupta 
jr_disable_irqs(struct sec_job_ring_t * job_ring)617*a0edacb8SPankaj Gupta int jr_disable_irqs(struct sec_job_ring_t *job_ring)
618*a0edacb8SPankaj Gupta {
619*a0edacb8SPankaj Gupta 	uint32_t reg_val = 0U;
620*a0edacb8SPankaj Gupta 	struct jobring_regs *regs =
621*a0edacb8SPankaj Gupta 	    (struct jobring_regs *)job_ring->register_base_addr;
622*a0edacb8SPankaj Gupta 
623*a0edacb8SPankaj Gupta 	/* Get the current value of the register */
624*a0edacb8SPankaj Gupta 	reg_val = sec_in32(&regs->jrcfg1);
625*a0edacb8SPankaj Gupta 
626*a0edacb8SPankaj Gupta 	/* Disable interrupts by enabling interrupt masking*/
627*a0edacb8SPankaj Gupta 	reg_val |= JR_REG_JRCFG_LO_IMSK_EN;
628*a0edacb8SPankaj Gupta 
629*a0edacb8SPankaj Gupta 	/* Update parameters in HW */
630*a0edacb8SPankaj Gupta 	sec_out32(&regs->jrcfg1, reg_val);
631*a0edacb8SPankaj Gupta 
632*a0edacb8SPankaj Gupta 	VERBOSE("Disable interrupts on JR\n");
633*a0edacb8SPankaj Gupta 
634*a0edacb8SPankaj Gupta 	return 0;
635*a0edacb8SPankaj Gupta }
636