xref: /openbmc/u-boot/drivers/misc/fsl_sec_mon.c (revision ad5b5801)
1 /*
2  * Copyright 2015 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <fsl_sec_mon.h>
9 
10 int change_sec_mon_state(u32 initial_state, u32 final_state)
11 {
12 	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
13 						(CONFIG_SYS_SEC_MON_ADDR);
14 	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
15 	int timeout = 10;
16 
17 	if ((sts & HPSR_SSM_ST_MASK) != initial_state)
18 		return -1;
19 
20 	if (initial_state == HPSR_SSM_ST_TRUST) {
21 		switch (final_state) {
22 		case HPSR_SSM_ST_NON_SECURE:
23 			printf("SEC_MON state transitioning to Soft Fail.\n");
24 			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV);
25 
26 			/*
27 			 * poll till SEC_MON is in
28 			 * Soft Fail state
29 			 */
30 			while (((sts & HPSR_SSM_ST_MASK) !=
31 				HPSR_SSM_ST_SOFT_FAIL)) {
32 				while (timeout) {
33 					sts = sec_mon_in32
34 						(&sec_mon_regs->hp_stat);
35 
36 					if ((sts & HPSR_SSM_ST_MASK) ==
37 						HPSR_SSM_ST_SOFT_FAIL)
38 						break;
39 
40 					udelay(10);
41 					timeout--;
42 				}
43 			}
44 
45 			if (timeout == 0) {
46 				printf("SEC_MON state transition timeout.\n");
47 				return -1;
48 			}
49 
50 			timeout = 10;
51 
52 			printf("SEC_MON state transitioning to Non Secure.\n");
53 			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SSM_ST);
54 
55 			/*
56 			 * poll till SEC_MON is in
57 			 * Non Secure state
58 			 */
59 			while (((sts & HPSR_SSM_ST_MASK) !=
60 				HPSR_SSM_ST_NON_SECURE)) {
61 				while (timeout) {
62 					sts = sec_mon_in32
63 						(&sec_mon_regs->hp_stat);
64 
65 					if ((sts & HPSR_SSM_ST_MASK) ==
66 						HPSR_SSM_ST_NON_SECURE)
67 						break;
68 
69 					udelay(10);
70 					timeout--;
71 				}
72 			}
73 
74 			if (timeout == 0) {
75 				printf("SEC_MON state transition timeout.\n");
76 				return -1;
77 			}
78 			break;
79 		case HPSR_SSM_ST_SOFT_FAIL:
80 			printf("SEC_MON state transitioning to Soft Fail.\n");
81 			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
82 
83 			/*
84 			 * polling loop till SEC_MON is in
85 			 * Soft Fail state
86 			 */
87 			while (((sts & HPSR_SSM_ST_MASK) !=
88 				HPSR_SSM_ST_SOFT_FAIL)) {
89 				while (timeout) {
90 					sts = sec_mon_in32
91 						(&sec_mon_regs->hp_stat);
92 
93 					if ((sts & HPSR_SSM_ST_MASK) ==
94 						HPSR_SSM_ST_SOFT_FAIL)
95 						break;
96 
97 					udelay(10);
98 					timeout--;
99 				}
100 			}
101 
102 			if (timeout == 0) {
103 				printf("SEC_MON state transition timeout.\n");
104 				return -1;
105 			}
106 			break;
107 		default:
108 			return -1;
109 		}
110 	} else if (initial_state == HPSR_SSM_ST_NON_SECURE) {
111 		switch (final_state) {
112 		case HPSR_SSM_ST_SOFT_FAIL:
113 			printf("SEC_MON state transitioning to Soft Fail.\n");
114 			sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
115 
116 			/*
117 			 * polling loop till SEC_MON is in
118 			 * Soft Fail state
119 			 */
120 			while (((sts & HPSR_SSM_ST_MASK) !=
121 				HPSR_SSM_ST_SOFT_FAIL)) {
122 				while (timeout) {
123 					sts = sec_mon_in32
124 						(&sec_mon_regs->hp_stat);
125 
126 					if ((sts & HPSR_SSM_ST_MASK) ==
127 						HPSR_SSM_ST_SOFT_FAIL)
128 						break;
129 
130 					udelay(10);
131 					timeout--;
132 				}
133 			}
134 
135 			if (timeout == 0) {
136 				printf("SEC_MON state transition timeout.\n");
137 				return -1;
138 			}
139 			break;
140 		default:
141 			return -1;
142 		}
143 	}
144 
145 	return 0;
146 }
147