digital_sensor.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. /*
  2. * Copyright (C) 2017-2020 Alibaba Group Holding Limited
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <asm/io.h>
  8. #include <asm/types.h>
  9. #include <thead/clock_config.h>
  10. #include <linux/bitops.h>
  11. #include <asm/arch-thead/light-iopmp.h>
  12. #include <asm/arch-thead/light-plic.h>
  13. #define LIGHT_TEE_SYSREG_BASE ((void __iomem*)0xffff200000)
  14. #define REG_SECURITY_ERR_3 (LIGHT_TEE_SYSREG_BASE + 0x30)
  15. /* id: 0~8 */
  16. #define DS_C910_BASE(id) (0xffffc57000 + (id) * 0x40)
  17. #define DS_APB_BASE(id) (0xffff270000 + ((id) - 4) * 0x1000)
  18. #define DS_BASE(id) (((id) > 3) ? (DS_APB_BASE(id)) : (DS_C910_BASE(id)))
  19. #define REG_HW_VERSION(id) ((void __iomem *)DS_BASE(id) + 0x00) //RO
  20. #define REG_SENSOR_ALARM(id) ((void __iomem *)DS_BASE(id) + 0x04) //RO
  21. #define REG_HEALTH_TEST_ALARM(id) ((void __iomem *)DS_BASE(id) + 0x08) //RO
  22. #define REG_HEALTH_TEST_STATUS(id) ((void __iomem *)DS_BASE(id) + 0x0C) //RO
  23. #define REG_CONTROL(id) ((void __iomem *)DS_BASE(id) + 0x10) //WO
  24. #define REG_IRQ_STATUS(id) ((void __iomem *)DS_BASE(id) + 0x14) //RO
  25. #define REG_IRQ_CLEAR(id) ((void __iomem *)DS_BASE(id) + 0x18) //WO
  26. #define REG_IRQ_CONFIG(id) ((void __iomem *)DS_BASE(id) + 0x1C) //RW
  27. #define REG_STATUS_DSX(id, x) ((void __iomem *)DS_BASE(id) + 0x20 + 0x04 * x) //RO
  28. #define LIGHT_SEC_IRQ_NUM 91
  29. #define MAX_DIGITAL_SENSOR_NUM 9
  30. #define MAX_HW_MACRO_NUM_PER_DS 16
  31. #define DS_HW_MACRO_TL_MASK 0xffff
  32. #define DS_INVALID_MACRO_ID MAX_HW_MACRO_NUM_PER_DS
  33. #define DS_1_ERR BIT(16) //digital_sensor_C910_0 ~ digital_sensor_C910_3
  34. #define DS_3_ERR BIT(18) //digital_sensor_apb_3
  35. #define DS_4_ERR BIT(19) //digital_sensor_apb_4
  36. #define DS_5_ERR BIT(20) //digital_sensor_apb_5
  37. #define DS_6_ERR BIT(21) //digital_sensor_apb_6
  38. #define DS_7_ERR BIT(22) //digital_sensor_apb_7
  39. #define DS_ERR (DS_1_ERR | DS_3_ERR | DS_4_ERR | DS_5_ERR | DS_6_ERR | DS_7_ERR)
  40. #define CFG_DS_CPU_THREAT_LEVEL 0
  41. #define CFG_APB0_THREAT_LEVEL 0
  42. #define CFG_APB1_THREAT_LEVEL 0
  43. #define AONSYS_RSTGEN_BASE ((void __iomem *)0xFFFFF44000UL)
  44. #define REG_SYS_RST_CFG (AONSYS_RSTGEN_BASE + 0x10)
  45. #define SW_SYS_RST_REQ (1 << 0)
  46. #define REG_RST_REQ_EN_0 (AONSYS_RSTGEN_BASE + 0x140)
  47. #define SW_GLB_RST_EN (1 << 0)
  48. struct ds_data {
  49. int id;
  50. u32 hw_macro_num;
  51. };
  52. struct ds_data ds_array[MAX_DIGITAL_SENSOR_NUM] = {
  53. {0, 4}, //digital_sensor_C910_0
  54. {1, 4}, //digital_sensor_C910_1
  55. {2, 4}, //digital_sensor_C910_2
  56. {3, 4}, //digital_sensor_C910_3
  57. {4, 16}, //digital_sensor_apb_3
  58. {5, 11}, //digital_sensor_apb_4
  59. {6, 4}, //digital_sensor_apb_5
  60. {7, 16}, //digital_sensor_apb_6
  61. {8, 8}, //digital_sensor_apb_7
  62. };
  63. static void system_reset(void)
  64. {
  65. u32 data = readl(REG_RST_REQ_EN_0);
  66. /* global reset enable */
  67. data |= SW_GLB_RST_EN;
  68. writel(data, REG_RST_REQ_EN_0);
  69. /* global reset request */
  70. writel(SW_SYS_RST_REQ, REG_SYS_RST_CFG);
  71. mdelay(1000);
  72. }
  73. static u32 ds_hw_macro_threat_level_get(int ds_id, u32 macro_id)
  74. {
  75. return readl(REG_STATUS_DSX(ds_id, macro_id)) & DS_HW_MACRO_TL_MASK;
  76. }
  77. static __maybe_unused int ds_health_test_done_status(int ds_id, u32 macro_id)
  78. {
  79. return readl(REG_HEALTH_TEST_STATUS(ds_id)) & (1 << macro_id) ? 1 : 0;
  80. }
  81. static __maybe_unused int ds_health_test_alarm_status(int ds_id, u32 macro_id)
  82. {
  83. return readl(REG_HEALTH_TEST_ALARM(ds_id)) & (1 << macro_id) ? 1 : 0;
  84. }
  85. static __maybe_unused bool ds_sensor_alarm_event_hw_macro_get(int ds_id, u32 *event_macro)
  86. {
  87. u32 alarm_status = readl(REG_SENSOR_ALARM(ds_id));
  88. int num = ds_array[ds_id].hw_macro_num;
  89. int s_alarm_bit = 0, j = 0;
  90. bool sensor_alarm_event_occured = false;
  91. for (int i = 0; i < num; i++) {
  92. s_alarm_bit = 1 << i;
  93. if (alarm_status & s_alarm_bit) {
  94. event_macro[j] = i;
  95. j++;
  96. sensor_alarm_event_occured = true;
  97. }
  98. }
  99. return sensor_alarm_event_occured;
  100. }
  101. static __maybe_unused bool ds_health_alarm_event_hw_macro_get(int ds_id, u32 *event_macro)
  102. {
  103. u32 h_alarm_status = readl(REG_HEALTH_TEST_ALARM(ds_id));
  104. int num = ds_array[ds_id].hw_macro_num;
  105. int h_alarm_bit = 0, j = 0;
  106. bool health_alarm_event_occured = false;
  107. for (int i = 0; i < num; i++) {
  108. h_alarm_bit = 1 << i;
  109. if (h_alarm_status & h_alarm_bit) {
  110. event_macro[j] = i;
  111. j++;
  112. health_alarm_event_occured = true;
  113. }
  114. }
  115. return health_alarm_event_occured;
  116. }
  117. static bool ds_sensor_irq_hw_macro_get(int ds_id, u32 *irq_macro)
  118. {
  119. u32 irq_status = readl(REG_IRQ_STATUS(ds_id));
  120. int num = ds_array[ds_id].hw_macro_num;
  121. int s_alarm_bit = 0, j = 0;
  122. bool sensor_alarm_irq_occured = false;
  123. for (int i = 0; i < num; i++) {
  124. s_alarm_bit = 1 << ((i << 1) + 1);
  125. if (irq_status & s_alarm_bit) {
  126. irq_macro[j] = i;
  127. debug("[%s,%d]irq_macro[%d] = %d\n", __func__, __LINE__,
  128. j, irq_macro[j]);
  129. j++;
  130. sensor_alarm_irq_occured = true;
  131. }
  132. }
  133. debug("[%s,%d] sensor_alarm_irq_occured = %d\n", __func__, __LINE__,
  134. sensor_alarm_irq_occured);
  135. return sensor_alarm_irq_occured;
  136. }
  137. static __maybe_unused bool ds_health_irq_hw_macro_get(int ds_id, u32 *irq_macro)
  138. {
  139. u32 irq_status = readl(REG_IRQ_STATUS(ds_id));
  140. int num = ds_array[ds_id].hw_macro_num;
  141. int h_alarm_bit = 0, j = 0;
  142. bool health_alarm_irq_occured = false;
  143. for (int i = 0; i < num; i++) {
  144. h_alarm_bit = 1 << (i << 1);
  145. if (irq_status & h_alarm_bit) {
  146. irq_macro[j] = i;
  147. j++;
  148. health_alarm_irq_occured = true;
  149. }
  150. }
  151. return health_alarm_irq_occured;
  152. }
  153. static void ds_sensor_irq_clear(int ds_id, u32 macro_id)
  154. {
  155. int s_alarm_bit = 1 << ((macro_id << 1) + 1);
  156. debug("[%s,%d]reg: 0x%lx, s_alarm_bit = 0x%x\n", __func__, __LINE__,
  157. (unsigned long)REG_IRQ_CLEAR(ds_id), s_alarm_bit);
  158. writel(s_alarm_bit, REG_IRQ_CLEAR(ds_id));
  159. }
  160. static __maybe_unused void ds_health_irq_clear(int ds_id, u32 macro_id)
  161. {
  162. int h_alarm_bit = 1 << (macro_id << 1);
  163. writel(h_alarm_bit, REG_IRQ_CLEAR(ds_id));
  164. }
  165. static void ds_hw_macro_sensor_alarm_endisable(int ds_id, u32 macro_id, bool en)
  166. {
  167. int s_alarm_bit = 1 << ((macro_id << 1) + 1);
  168. u32 bitmap = readl(REG_IRQ_CONFIG(ds_id));
  169. if (en)
  170. bitmap |= s_alarm_bit;
  171. else
  172. bitmap &= ~s_alarm_bit;
  173. writel(bitmap, REG_IRQ_CONFIG(ds_id));
  174. }
  175. static __maybe_unused void ds_hw_macro_health_alarm_endisable(int ds_id, u32 macro_id, bool en)
  176. {
  177. int h_alarm_bit = 1 << (macro_id << 1);
  178. u32 bitmap = readl(REG_IRQ_CONFIG(ds_id));
  179. if (en)
  180. bitmap |= h_alarm_bit;
  181. else
  182. bitmap &= ~h_alarm_bit;
  183. writel(bitmap, REG_IRQ_CONFIG(ds_id));
  184. }
  185. static void ds_hw_macro_rearm(int ds_id, u32 macro_id, int macro_size)
  186. {
  187. int rearm_bit = 1 << (macro_id + macro_size);
  188. debug("[%s,%d]rearm_bit = 0x%x\n", __func__, __LINE__, rearm_bit);
  189. writel(rearm_bit, REG_CONTROL(ds_id));
  190. }
  191. static __maybe_unused void ds_hw_macro_health_test_start(int ds_id, u32 macro_id)
  192. {
  193. int start_bit = 1 << macro_id;
  194. writel(start_bit, REG_CONTROL(ds_id));
  195. }
  196. static void light_sec_irq_handler(void)
  197. {
  198. u32 id, i, j = 0, t = 0, size;
  199. u32 tl;
  200. u32 irq_macro[MAX_HW_MACRO_NUM_PER_DS] = {0};
  201. u32 apb_ds[8] = {0};
  202. u32 status = readl(REG_SECURITY_ERR_3);
  203. if (!status)
  204. return;
  205. if (!(status & DS_ERR)) {
  206. printf("Unexpected security interrupt but not ditital sensor alarm occured\n");
  207. return; //drop other security interrupts, how to clear ?
  208. }
  209. if (status & DS_1_ERR) {
  210. printf("C910 cpu digital sensor detect error event\n");
  211. for (id = 0; id < 4; id++) {
  212. for (i = 0; i < ARRAY_SIZE(irq_macro); i++)
  213. irq_macro[i] = DS_INVALID_MACRO_ID;
  214. if (!ds_sensor_irq_hw_macro_get(id, irq_macro))
  215. continue;
  216. size = ds_array[id].hw_macro_num;
  217. i = 0;
  218. while (i < MAX_HW_MACRO_NUM_PER_DS && irq_macro[i] != DS_INVALID_MACRO_ID) {
  219. tl = ds_hw_macro_threat_level_get(id, irq_macro[i]);
  220. printf("DS%d-MACRO%d Threat Level: 0x%x\n", id, irq_macro[i], tl);
  221. if (tl >= CFG_DS_CPU_THREAT_LEVEL) {
  222. #if 0
  223. run_command("ds_cpu_alarm 1500000000", 0);
  224. #else
  225. system_reset();
  226. #endif
  227. } else {
  228. #if 0
  229. run_command("ds_cpu_alarm 1500000000", 0);
  230. #else
  231. system_reset();
  232. #endif
  233. }
  234. //Fixmed: before irq clear !!!
  235. ds_hw_macro_rearm(id, irq_macro[i], size);
  236. ds_sensor_irq_clear(id, irq_macro[i]);
  237. i++;
  238. }
  239. }
  240. }
  241. if (status & DS_3_ERR) {
  242. printf("apb digital sensor3 detect error event\n");
  243. apb_ds[j++] = 4;
  244. }
  245. if (status & DS_4_ERR) {
  246. printf("apb digital sensor4 detect error event\n");
  247. apb_ds[j++] = 5;
  248. }
  249. if (status & DS_5_ERR) {
  250. printf("apb digital sensor5 detect error event\n");
  251. apb_ds[j++] = 6;
  252. }
  253. if (status & DS_6_ERR) {
  254. printf("apb digital sensor6 detect error event\n");
  255. apb_ds[j++] = 7;
  256. }
  257. if (status & DS_7_ERR) {
  258. printf("apb digital sensor7 detect error event\n");
  259. apb_ds[j++] = 8;
  260. }
  261. while (apb_ds[t]) {
  262. if (apb_ds[t] < 4 || apb_ds[t] > 8) {
  263. printf("invalid digial sensor id(%d)\n", apb_ds[t]);
  264. return;
  265. }
  266. for (i = 0; i < ARRAY_SIZE(irq_macro); i++)
  267. irq_macro[i] = DS_INVALID_MACRO_ID;
  268. size = ds_array[apb_ds[t]].hw_macro_num;
  269. if (ds_sensor_irq_hw_macro_get(apb_ds[t], irq_macro)) {
  270. i = 0;
  271. while (i < MAX_HW_MACRO_NUM_PER_DS && irq_macro[i] != DS_INVALID_MACRO_ID) {//hardware macro
  272. debug("[%s,%d]irq_status = 0x%x, alarm_status = 0x%x\n", __func__, __LINE__,
  273. readl(REG_IRQ_STATUS(apb_ds[t])), readl(REG_SENSOR_ALARM(apb_ds[t])));
  274. tl = ds_hw_macro_threat_level_get(apb_ds[t], irq_macro[i]);
  275. if (tl)
  276. printf("DS%d-MACRO%d Threat Level: 0x%x\n", apb_ds[t], irq_macro[i], tl);
  277. if (apb_ds[t] == 8 && tl >= CFG_APB1_THREAT_LEVEL) {
  278. //handle1
  279. run_command("ds_3to6_alarm 4", 0);
  280. } else if (tl >= CFG_APB0_THREAT_LEVEL) {
  281. //handle2
  282. run_command("ds_3to6_alarm 4", 0);
  283. } else {
  284. //handle3
  285. run_command("ds_3to6_alarm 4", 0);
  286. }
  287. //Fixmed: before irq clear !!!
  288. ds_hw_macro_rearm(apb_ds[t], irq_macro[i], size);
  289. ds_sensor_irq_clear(apb_ds[t], irq_macro[i]);
  290. i++;
  291. }
  292. }
  293. t++; //digital number
  294. }
  295. }
  296. static int ds_platform_init(void)
  297. {
  298. int ds_id, macro_id, ret = 0;
  299. for (ds_id = 0; ds_id < MAX_DIGITAL_SENSOR_NUM; ds_id++) {
  300. printf("Digital Sensor%d HW Version: 0x%x\n", ds_id, readl(REG_HW_VERSION(ds_id)));
  301. for (macro_id = 0; macro_id < ds_array[ds_id].hw_macro_num; macro_id++) {
  302. ds_hw_macro_sensor_alarm_endisable(ds_id,
  303. macro_id, true);
  304. ds_hw_macro_health_test_start(ds_id, macro_id);
  305. udelay(5);
  306. ret = ds_health_test_done_status(ds_id, macro_id);
  307. if (!ret) {
  308. printf("health test failed for DS%d-Macro%d\n", ds_id, macro_id);
  309. ds_hw_macro_sensor_alarm_endisable(ds_id,
  310. macro_id, false);
  311. } else {
  312. ret = ds_health_test_alarm_status(ds_id, macro_id);
  313. if (ret) {
  314. ds_hw_macro_sensor_alarm_endisable(ds_id,
  315. macro_id, false);
  316. printf("health test failed for DS%d-Macro%d\n", ds_id, macro_id);
  317. }
  318. }
  319. }
  320. }
  321. return 0;
  322. }
  323. static int ds_sec_interrupt_init(void)
  324. {
  325. int ret;
  326. ret = irq_handler_register(LIGHT_SEC_IRQ_NUM, light_sec_irq_handler);
  327. if (ret) {
  328. printf("failed to register security interrupt handler\n");
  329. return ret;
  330. }
  331. irq_priority_set(LIGHT_SEC_IRQ_NUM);
  332. irq_enable(LIGHT_SEC_IRQ_NUM);
  333. return 0;
  334. }
  335. void ds_uninit(void)
  336. {
  337. int ds_id, macro_id;
  338. irq_disable(LIGHT_SEC_IRQ_NUM);
  339. for (ds_id = 0; ds_id < MAX_DIGITAL_SENSOR_NUM; ds_id++) {
  340. for (macro_id = 0; macro_id < ds_array[ds_id].hw_macro_num; macro_id++)
  341. ds_hw_macro_sensor_alarm_endisable(ds_id, macro_id, false);
  342. }
  343. irq_handler_register(LIGHT_SEC_IRQ_NUM, NULL);
  344. }
  345. int ds_init(void)
  346. {
  347. int ret;
  348. ds_platform_init();
  349. ret = ds_sec_interrupt_init();
  350. if (ret)
  351. return ret;
  352. return 0;
  353. }