diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
index 375ff9d0e3..aadf851101 100644
--- a/drivers/crypto/fsl/jobdesc.c
+++ b/drivers/crypto/fsl/jobdesc.c
@@ -257,7 +257,7 @@ void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr,
  * Descriptor to instantiate RNG State Handle 0 in normal mode and
  * load the JDKEK, TDKEK and TDSK registers
  */
-void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc)
+void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc, int handle)
 {
 	u32 *jump_cmd;
 
@@ -265,21 +265,24 @@ void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc)
 
 	/* INIT RNG in non-test mode */
 	append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
-			 OP_ALG_AS_INIT);
-
-	/* wait for done */
-	jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
-	set_jump_tgt_here(desc, jump_cmd);
-
-	/*
-	 * load 1 to clear written reg:
-	 * resets the done interrrupt and returns the RNG to idle.
-	 */
-	append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
-
-	/* generate secure keys (non-test) */
-	append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
-			 OP_ALG_RNG4_SK);
+			(handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT);
+
+	/* For SH0, Secure Keys must be generated as well */
+	if (handle == 0) {
+		/* wait for done */
+		jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
+		set_jump_tgt_here(desc, jump_cmd);
+
+		/*
+		 * load 1 to clear written reg:
+		 * resets the done interrupt and returns the RNG to idle.
+		 */
+		append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+
+		/* generate secure keys (non-test) */
+		append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+				OP_ALG_RNG4_SK);
+	}
 }
 
 /* Change key size to bytes form bits in calling function*/
diff --git a/drivers/crypto/fsl/jobdesc.h b/drivers/crypto/fsl/jobdesc.h
index 112404c74d..75c9424c4a 100644
--- a/drivers/crypto/fsl/jobdesc.h
+++ b/drivers/crypto/fsl/jobdesc.h
@@ -40,7 +40,7 @@ void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr,
 				     uint8_t *enc_blob, uint8_t *plain_txt,
 				     uint32_t out_sz);
 
-void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc);
+void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc, int handle);
 
 void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
 				      struct pk_in_params *pkin, uint8_t *out,
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index cbf570de72..3e751df71e 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -444,35 +444,49 @@ int sec_reset(void)
 #ifndef CONFIG_SPL_BUILD
 static int instantiate_rng(uint8_t sec_idx)
 {
-	struct result op;
 	u32 *desc;
 	u32 rdsta_val;
-	int ret = 0;
+	int ret = 0, sh_idx, size;
 	ccsr_sec_t __iomem *sec = (ccsr_sec_t __iomem *)SEC_ADDR(sec_idx);
 	struct rng4tst __iomem *rng =
 			(struct rng4tst __iomem *)&sec->rng;
 
-	memset(&op, 0, sizeof(struct result));
-
 	desc = memalign(ARCH_DMA_MINALIGN, sizeof(uint32_t) * 6);
 	if (!desc) {
 		printf("cannot allocate RNG init descriptor memory\n");
 		return -1;
 	}
 
-	inline_cnstr_jobdesc_rng_instantiation(desc);
-	int size = roundup(sizeof(uint32_t) * 6, ARCH_DMA_MINALIGN);
-	flush_dcache_range((unsigned long)desc,
-			   (unsigned long)desc + size);
+	for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+		/*
+		 * If the corresponding bit is set, this state handle
+		 * was initialized by somebody else, so it's left alone.
+		 */
+		rdsta_val = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK;
+		if (rdsta_val & (1 << sh_idx))
+			continue;
+
+		inline_cnstr_jobdesc_rng_instantiation(desc, sh_idx);
+		size = roundup(sizeof(uint32_t) * 6, ARCH_DMA_MINALIGN);
+		flush_dcache_range((unsigned long)desc,
+				   (unsigned long)desc + size);
 
-	ret = run_descriptor_jr_idx(desc, sec_idx);
+		ret = run_descriptor_jr_idx(desc, sec_idx);
 
-	if (ret)
-		printf("RNG: Instantiation failed with error %x\n", ret);
+		if (ret)
+			printf("RNG: Instantiation failed with error 0x%x\n",
+			       ret);
 
-	rdsta_val = sec_in32(&rng->rdsta);
-	if (op.status || !(rdsta_val & RNG_STATE0_HANDLE_INSTANTIATED))
-		return -1;
+		rdsta_val = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK;
+		if (!(rdsta_val & (1 << sh_idx))) {
+			free(desc);
+			return -1;
+		}
+
+		memset(desc, 0, sizeof(uint32_t) * 6);
+	}
+
+	free(desc);
 
 	return ret;
 }
@@ -524,14 +538,11 @@ static int rng_init(uint8_t sec_idx)
 	ccsr_sec_t __iomem *sec = (ccsr_sec_t __iomem *)SEC_ADDR(sec_idx);
 	struct rng4tst __iomem *rng =
 			(struct rng4tst __iomem *)&sec->rng;
-
-	u32 rdsta = sec_in32(&rng->rdsta);
-
-	/* Check if RNG state 0 handler is already instantiated */
-	if (rdsta & RNG_STATE0_HANDLE_INSTANTIATED)
-		return 0;
+	u32 inst_handles;
 
 	do {
+		inst_handles = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK;
+
 		/*
 		 * If either of the SH's were instantiated by somebody else
 		 * then it is assumed that the entropy
@@ -540,8 +551,10 @@ static int rng_init(uint8_t sec_idx)
 		 * Also, if a handle was instantiated, do not change
 		 * the TRNG parameters.
 		 */
-		kick_trng(ent_delay, sec_idx);
-		ent_delay += 400;
+		if (!inst_handles) {
+			kick_trng(ent_delay, sec_idx);
+			ent_delay += 400;
+		}
 		/*
 		 * if instantiate_rng(...) fails, the loop will rerun
 		 * and the kick_trng(...) function will modfiy the
diff --git a/drivers/crypto/fsl/jr.h b/drivers/crypto/fsl/jr.h
index 72f7501812..258b0b85f0 100644
--- a/drivers/crypto/fsl/jr.h
+++ b/drivers/crypto/fsl/jr.h
@@ -40,6 +40,8 @@
 #define JQ_DEQ_TO_ERR		-2
 #define JQ_ENQ_ERR		-3
 
+#define RNG4_MAX_HANDLES	2
+
 struct op_ring {
 	phys_addr_t desc;
 	uint32_t status;
diff --git a/include/fsl_sec.h b/include/fsl_sec.h
index a2f5f5a5f1..4cbdb2d65a 100644
--- a/include/fsl_sec.h
+++ b/include/fsl_sec.h
@@ -67,6 +67,9 @@ struct rng4tst {
 	};
 	u32 rsvd1[40];
 #define RNG_STATE0_HANDLE_INSTANTIATED	0x00000001
+#define RNG_STATE1_HANDLE_INSTANTIATED	0x00000002
+#define RNG_STATE_HANDLE_MASK	\
+	(RNG_STATE0_HANDLE_INSTANTIATED | RNG_STATE1_HANDLE_INSTANTIATED)
 	u32 rdsta;		/*RNG DRNG Status Register*/
 	u32 rsvd2[15];
 };
