blob: 7518089e1e3e7ed603559b94bd7ae7518154cfb9 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
gaurav rana9aaea442015-02-27 09:44:22 +05302/*
3 * Copyright 2015 Freescale Semiconductor, Inc.
gaurav rana9aaea442015-02-27 09:44:22 +05304 */
5
Tom Rinidec7ea02024-05-20 13:35:03 -06006#include <config.h>
gaurav rana9aaea442015-02-27 09:44:22 +05307#include <fsl_sec_mon.h>
Simon Glassdbd79542020-05-10 11:40:11 -06008#include <linux/delay.h>
gaurav rana9aaea442015-02-27 09:44:22 +05309
Sumit Gargbc17f982016-08-31 08:54:15 -040010static u32 get_sec_mon_state(void)
gaurav rana9aaea442015-02-27 09:44:22 +053011{
12 struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
Tom Rini6a5dccc2022-11-16 13:10:41 -050013 (CFG_SYS_SEC_MON_ADDR);
Sumit Gargbc17f982016-08-31 08:54:15 -040014 return sec_mon_in32(&sec_mon_regs->hp_stat) & HPSR_SSM_ST_MASK;
15}
16
17static int set_sec_mon_state_non_sec(void)
18{
19 u32 sts;
gaurav rana9aaea442015-02-27 09:44:22 +053020 int timeout = 10;
Sumit Gargbc17f982016-08-31 08:54:15 -040021 struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
Tom Rini6a5dccc2022-11-16 13:10:41 -050022 (CFG_SYS_SEC_MON_ADDR);
gaurav rana9aaea442015-02-27 09:44:22 +053023
Sumit Gargbc17f982016-08-31 08:54:15 -040024 sts = get_sec_mon_state();
gaurav rana9aaea442015-02-27 09:44:22 +053025
Sumit Gargbc17f982016-08-31 08:54:15 -040026 switch (sts) {
27 /*
28 * If initial state is check or Non-Secure, then set the Software
29 * Security Violation Bit and transition to Non-Secure State.
30 */
31 case HPSR_SSM_ST_CHECK:
32 printf("SEC_MON state transitioning to Non Secure.\n");
33 sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV);
gaurav rana9aaea442015-02-27 09:44:22 +053034
Sumit Gargbc17f982016-08-31 08:54:15 -040035 /* polling loop till SEC_MON is in Non Secure state */
36 while (timeout) {
37 sts = get_sec_mon_state();
gaurav rana9aaea442015-02-27 09:44:22 +053038
Sumit Gargbc17f982016-08-31 08:54:15 -040039 if ((sts & HPSR_SSM_ST_MASK) ==
40 HPSR_SSM_ST_NON_SECURE)
41 break;
gaurav rana9aaea442015-02-27 09:44:22 +053042
Sumit Gargbc17f982016-08-31 08:54:15 -040043 udelay(10);
44 timeout--;
45 }
gaurav rana9aaea442015-02-27 09:44:22 +053046
Sumit Gargbc17f982016-08-31 08:54:15 -040047 if (timeout == 0) {
48 printf("SEC_MON state transition timeout.\n");
49 return -1;
50 }
51 break;
gaurav rana9aaea442015-02-27 09:44:22 +053052
Sumit Gargbc17f982016-08-31 08:54:15 -040053 /*
54 * If initial state is Trusted, Secure or Soft-Fail, then first set
55 * the Software Security Violation Bit and transition to Soft-Fail
56 * State.
57 */
58 case HPSR_SSM_ST_TRUST:
59 case HPSR_SSM_ST_SECURE:
60 case HPSR_SSM_ST_SOFT_FAIL:
61 printf("SEC_MON state transitioning to Soft Fail.\n");
62 sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV);
gaurav rana9aaea442015-02-27 09:44:22 +053063
Sumit Gargbc17f982016-08-31 08:54:15 -040064 /* polling loop till SEC_MON is in Soft-Fail state */
65 while (timeout) {
66 sts = get_sec_mon_state();
gaurav rana9aaea442015-02-27 09:44:22 +053067
Sumit Gargbc17f982016-08-31 08:54:15 -040068 if ((sts & HPSR_SSM_ST_MASK) ==
69 HPSR_SSM_ST_SOFT_FAIL)
70 break;
gaurav rana9aaea442015-02-27 09:44:22 +053071
Sumit Gargbc17f982016-08-31 08:54:15 -040072 udelay(10);
73 timeout--;
74 }
gaurav rana9aaea442015-02-27 09:44:22 +053075
Sumit Gargbc17f982016-08-31 08:54:15 -040076 if (timeout == 0) {
77 printf("SEC_MON state transition timeout.\n");
78 return -1;
79 }
gaurav rana9aaea442015-02-27 09:44:22 +053080
Sumit Gargbc17f982016-08-31 08:54:15 -040081 timeout = 10;
82
83 /*
84 * If SSM Soft Fail to Non-Secure State Transition
85 * disable is not set, then set SSM_ST bit and
86 * transition to Non-Secure State.
87 */
88 if ((sec_mon_in32(&sec_mon_regs->hp_com) &
89 HPCOMR_SSM_SFNS_DIS) == 0) {
90 printf("SEC_MON state transitioning to Non Secure.\n");
91 sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SSM_ST);
gaurav rana9aaea442015-02-27 09:44:22 +053092
Sumit Gargbc17f982016-08-31 08:54:15 -040093 /* polling loop till SEC_MON is in Non Secure*/
94 while (timeout) {
95 sts = get_sec_mon_state();
gaurav rana9aaea442015-02-27 09:44:22 +053096
Sumit Gargbc17f982016-08-31 08:54:15 -040097 if ((sts & HPSR_SSM_ST_MASK) ==
98 HPSR_SSM_ST_NON_SECURE)
99 break;
gaurav rana9aaea442015-02-27 09:44:22 +0530100
Sumit Gargbc17f982016-08-31 08:54:15 -0400101 udelay(10);
102 timeout--;
gaurav rana9aaea442015-02-27 09:44:22 +0530103 }
104
105 if (timeout == 0) {
106 printf("SEC_MON state transition timeout.\n");
107 return -1;
108 }
gaurav rana9aaea442015-02-27 09:44:22 +0530109 }
Sumit Gargbc17f982016-08-31 08:54:15 -0400110 break;
111 default:
112 printf("SEC_MON already in Non Secure state.\n");
113 return 0;
114 }
115 return 0;
116}
gaurav rana9aaea442015-02-27 09:44:22 +0530117
Sumit Gargbc17f982016-08-31 08:54:15 -0400118static int set_sec_mon_state_soft_fail(void)
119{
120 u32 sts;
121 int timeout = 10;
122 struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
Tom Rini6a5dccc2022-11-16 13:10:41 -0500123 (CFG_SYS_SEC_MON_ADDR);
gaurav rana9aaea442015-02-27 09:44:22 +0530124
Sumit Gargbc17f982016-08-31 08:54:15 -0400125 printf("SEC_MON state transitioning to Soft Fail.\n");
126 sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
gaurav rana9aaea442015-02-27 09:44:22 +0530127
Sumit Gargbc17f982016-08-31 08:54:15 -0400128 /* polling loop till SEC_MON is in Soft-Fail state */
129 while (timeout) {
130 sts = get_sec_mon_state();
gaurav rana9aaea442015-02-27 09:44:22 +0530131
Sumit Gargbc17f982016-08-31 08:54:15 -0400132 if ((sts & HPSR_SSM_ST_MASK) ==
133 HPSR_SSM_ST_SOFT_FAIL)
gaurav rana9aaea442015-02-27 09:44:22 +0530134 break;
Sumit Gargbc17f982016-08-31 08:54:15 -0400135
136 udelay(10);
137 timeout--;
gaurav rana9aaea442015-02-27 09:44:22 +0530138 }
139
Sumit Gargbc17f982016-08-31 08:54:15 -0400140 if (timeout == 0) {
141 printf("SEC_MON state transition timeout.\n");
142 return -1;
143 }
gaurav rana9aaea442015-02-27 09:44:22 +0530144 return 0;
145}
Sumit Gargbc17f982016-08-31 08:54:15 -0400146
147int set_sec_mon_state(u32 state)
148{
149 int ret = -1;
150
151 switch (state) {
152 case HPSR_SSM_ST_NON_SECURE:
153 ret = set_sec_mon_state_non_sec();
154 break;
155 case HPSR_SSM_ST_SOFT_FAIL:
156 ret = set_sec_mon_state_soft_fail();
157 break;
158 default:
159 printf("SEC_MON state transition not supported.\n");
160 return 0;
161 }
162
163 return ret;
164}