147 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			147 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright 2015 Freescale Semiconductor, Inc.
 | 
						|
 *
 | 
						|
 * SPDX-License-Identifier:	GPL-2.0+
 | 
						|
 */
 | 
						|
 | 
						|
#include <common.h>
 | 
						|
#include <fsl_sec_mon.h>
 | 
						|
 | 
						|
int change_sec_mon_state(u32 initial_state, u32 final_state)
 | 
						|
{
 | 
						|
	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
 | 
						|
						(CONFIG_SYS_SEC_MON_ADDR);
 | 
						|
	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
 | 
						|
	int timeout = 10;
 | 
						|
 | 
						|
	if ((sts & HPSR_SSM_ST_MASK) != initial_state)
 | 
						|
		return -1;
 | 
						|
 | 
						|
	if (initial_state == HPSR_SSM_ST_TRUST) {
 | 
						|
		switch (final_state) {
 | 
						|
		case HPSR_SSM_ST_NON_SECURE:
 | 
						|
			printf("SEC_MON state transitioning to Soft Fail.\n");
 | 
						|
			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV);
 | 
						|
 | 
						|
			/*
 | 
						|
			 * poll till SEC_MON is in
 | 
						|
			 * Soft Fail state
 | 
						|
			 */
 | 
						|
			while (((sts & HPSR_SSM_ST_MASK) !=
 | 
						|
				HPSR_SSM_ST_SOFT_FAIL)) {
 | 
						|
				while (timeout) {
 | 
						|
					sts = sec_mon_in32
 | 
						|
						(&sec_mon_regs->hp_stat);
 | 
						|
 | 
						|
					if ((sts & HPSR_SSM_ST_MASK) ==
 | 
						|
						HPSR_SSM_ST_SOFT_FAIL)
 | 
						|
						break;
 | 
						|
 | 
						|
					udelay(10);
 | 
						|
					timeout--;
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			if (timeout == 0) {
 | 
						|
				printf("SEC_MON state transition timeout.\n");
 | 
						|
				return -1;
 | 
						|
			}
 | 
						|
 | 
						|
			timeout = 10;
 | 
						|
 | 
						|
			printf("SEC_MON state transitioning to Non Secure.\n");
 | 
						|
			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SSM_ST);
 | 
						|
 | 
						|
			/*
 | 
						|
			 * poll till SEC_MON is in
 | 
						|
			 * Non Secure state
 | 
						|
			 */
 | 
						|
			while (((sts & HPSR_SSM_ST_MASK) !=
 | 
						|
				HPSR_SSM_ST_NON_SECURE)) {
 | 
						|
				while (timeout) {
 | 
						|
					sts = sec_mon_in32
 | 
						|
						(&sec_mon_regs->hp_stat);
 | 
						|
 | 
						|
					if ((sts & HPSR_SSM_ST_MASK) ==
 | 
						|
						HPSR_SSM_ST_NON_SECURE)
 | 
						|
						break;
 | 
						|
 | 
						|
					udelay(10);
 | 
						|
					timeout--;
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			if (timeout == 0) {
 | 
						|
				printf("SEC_MON state transition timeout.\n");
 | 
						|
				return -1;
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		case HPSR_SSM_ST_SOFT_FAIL:
 | 
						|
			printf("SEC_MON state transitioning to Soft Fail.\n");
 | 
						|
			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
 | 
						|
 | 
						|
			/*
 | 
						|
			 * polling loop till SEC_MON is in
 | 
						|
			 * Soft Fail state
 | 
						|
			 */
 | 
						|
			while (((sts & HPSR_SSM_ST_MASK) !=
 | 
						|
				HPSR_SSM_ST_SOFT_FAIL)) {
 | 
						|
				while (timeout) {
 | 
						|
					sts = sec_mon_in32
 | 
						|
						(&sec_mon_regs->hp_stat);
 | 
						|
 | 
						|
					if ((sts & HPSR_SSM_ST_MASK) ==
 | 
						|
						HPSR_SSM_ST_SOFT_FAIL)
 | 
						|
						break;
 | 
						|
 | 
						|
					udelay(10);
 | 
						|
					timeout--;
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			if (timeout == 0) {
 | 
						|
				printf("SEC_MON state transition timeout.\n");
 | 
						|
				return -1;
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			return -1;
 | 
						|
		}
 | 
						|
	} else if (initial_state == HPSR_SSM_ST_NON_SECURE) {
 | 
						|
		switch (final_state) {
 | 
						|
		case HPSR_SSM_ST_SOFT_FAIL:
 | 
						|
			printf("SEC_MON state transitioning to Soft Fail.\n");
 | 
						|
			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
 | 
						|
 | 
						|
			/*
 | 
						|
			 * polling loop till SEC_MON is in
 | 
						|
			 * Soft Fail state
 | 
						|
			 */
 | 
						|
			while (((sts & HPSR_SSM_ST_MASK) !=
 | 
						|
				HPSR_SSM_ST_SOFT_FAIL)) {
 | 
						|
				while (timeout) {
 | 
						|
					sts = sec_mon_in32
 | 
						|
						(&sec_mon_regs->hp_stat);
 | 
						|
 | 
						|
					if ((sts & HPSR_SSM_ST_MASK) ==
 | 
						|
						HPSR_SSM_ST_SOFT_FAIL)
 | 
						|
						break;
 | 
						|
 | 
						|
					udelay(10);
 | 
						|
					timeout--;
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			if (timeout == 0) {
 | 
						|
				printf("SEC_MON state transition timeout.\n");
 | 
						|
				return -1;
 | 
						|
			}
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			return -1;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 |