vcp_common.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * Copyright (c) 2024, MediaTek Inc. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <errno.h>
  7. #include <inttypes.h>
  8. #include <stdint.h>
  9. #include <stdio.h>
  10. #include <arch_helpers.h>
  11. #include <common/debug.h>
  12. #include <lib/mmio.h>
  13. #include <lib/xlat_tables/xlat_tables_v2.h>
  14. #include <smccc_helpers.h>
  15. #include "mmup_common.h"
  16. #include <mtk_mmap_pool.h>
  17. #include <mtk_sip_svc.h>
  18. #include "vcp_helper.h"
  19. #include "vcp_reg.h"
  20. #define MODULE_TAG "[VCP]"
  21. static const mmap_region_t vcp_mmap[] MTK_MMAP_SECTION = {
  22. MAP_REGION_FLAT(VCP_R_CFGREG, MTK_VCP_REG_BANK_SIZE,
  23. MT_DEVICE | MT_RW | MT_SECURE),
  24. MAP_REGION_FLAT(VCP_R_CFGREG_CORE0, MTK_VCP_REG_BANK_SIZE,
  25. MT_DEVICE | MT_RW | MT_SECURE),
  26. MAP_REGION_FLAT(VCP_R_CFGREG_CORE1, MTK_VCP_REG_BANK_SIZE,
  27. MT_DEVICE | MT_RW | MT_SECURE),
  28. MAP_REGION_FLAT(VCP_R_SEC_CTRL, MTK_VCP_REG_BANK_SIZE,
  29. MT_DEVICE | MT_RW | MT_SECURE),
  30. {0}
  31. };
  32. DECLARE_MTK_MMAP_REGIONS(vcp_mmap);
  33. /* vcp-mmup l2tcm memory offset */
  34. static uint64_t g_l2tcm_offset;
  35. static uint32_t g_mmup_fw_size;
  36. static bool get_vcp_pwr_status(void)
  37. {
  38. #if defined(SPM_BASE)
  39. uint32_t spm_pwr_sta = mmio_read_32(SPM_BASE + VCP_POWER_STATUS);
  40. if (!(spm_pwr_sta & (MMUP_PWR_STA_EN << MMUP_PWR_STA_BIT))) {
  41. ERROR("%s: pwr_sta:%x, bit:%d disable\n", MODULE_TAG,
  42. spm_pwr_sta, MMUP_PWR_STA_BIT);
  43. return false;
  44. }
  45. #endif
  46. return true;
  47. }
  48. uint32_t get_mmup_fw_size(void)
  49. {
  50. return g_mmup_fw_size;
  51. }
  52. uint64_t get_mmup_l2tcm_offset(void)
  53. {
  54. return g_l2tcm_offset;
  55. }
  56. static bool vcp_cold_boot_reset(void)
  57. {
  58. mmio_write_32(VCP_GPR2_CFGREG_SEC, 0);
  59. mmio_write_32(VCP_GPR3_CFGREG_SEC, 0);
  60. return true;
  61. }
  62. static bool mmup_cold_boot_reset(void)
  63. {
  64. mmio_write_32(VCP_GPR0_CFGREG_SEC, 0);
  65. mmio_write_32(VCP_GPR1_CFGREG_SEC, 0);
  66. return true;
  67. }
  68. static bool vcp_set_mmup_l2tcm_offset(uint64_t l2tcm_offset)
  69. {
  70. g_l2tcm_offset = l2tcm_offset;
  71. if (g_l2tcm_offset > MTK_VCP_SRAM_SIZE) {
  72. g_l2tcm_offset = 0;
  73. return false;
  74. }
  75. return true;
  76. }
  77. static bool vcp_set_mmup_fw_size(uint64_t fw_size)
  78. {
  79. g_mmup_fw_size = fw_size;
  80. if (g_mmup_fw_size > MTK_VCP_SRAM_SIZE - g_l2tcm_offset) {
  81. g_mmup_fw_size = 0;
  82. return false;
  83. }
  84. return true;
  85. }
  86. static bool vcp_smc_rstn_set(bool boot_ok)
  87. {
  88. if (mmio_read_32(VCP_GPR_C0_H0_REBOOT) != 0 &&
  89. mmio_read_32(VCP_R_CORE0_STATUS) != 0 &&
  90. (mmio_read_32(VCP_R_GIPC_IN_SET) & B_GIPC3_SETCLR_1) == 0 &&
  91. (mmio_read_32(VCP_R_GIPC_IN_CLR) & B_GIPC3_SETCLR_1) == 0 &&
  92. mmio_read_32(VCP_GPR_C0_H0_REBOOT) != VCP_CORE_RDY_TO_REBOOT &&
  93. mmio_read_32(VCP_GPR_C0_H1_REBOOT) != VCP_CORE_RDY_TO_REBOOT) {
  94. ERROR("%s: [%s] mmup reset set fail!GIPC 0x%x 0x%x REBOOT 0x%x 0x%x\n",
  95. MODULE_TAG, __func__, mmio_read_32(VCP_R_GIPC_IN_SET),
  96. mmio_read_32(VCP_R_GIPC_IN_CLR),
  97. mmio_read_32(VCP_GPR_C0_H0_REBOOT),
  98. mmio_read_32(VCP_GPR_C0_H1_REBOOT));
  99. return false;
  100. }
  101. mmio_write_32(VCP_R_CORE0_SW_RSTN_SET, BIT(0));
  102. /* reset sec control */
  103. mmio_write_32(VCP_R_SEC_CTRL_2, 0);
  104. /* reset domain setting */
  105. mmio_write_32(VCP_R_S_DOM_EN0_31, 0x0);
  106. mmio_write_32(VCP_R_S_DOM_EN32_63, 0x0);
  107. mmio_write_32(VCP_R_NS_DOM_EN0_31, 0x0);
  108. mmio_write_32(VCP_R_NS_DOM_EN32_63, 0x0);
  109. /* reset sec setting */
  110. mmio_clrbits_32(VCP_R_DYN_SECURE,
  111. RESET_NS_SECURE_B_REGION << VCP_NS_SECURE_B_REGION_ENABLE);
  112. if (boot_ok) {
  113. mmio_write_32(VCP_GPR_C0_H0_REBOOT, VCP_CORE_REBOOT_OK);
  114. mmio_write_32(VCP_GPR_C0_H1_REBOOT, VCP_CORE_REBOOT_OK);
  115. }
  116. dsbsy();
  117. return true;
  118. }
  119. static bool vcp_smc_rstn_clr(void)
  120. {
  121. if ((mmio_read_32(VCP_R_CORE0_SW_RSTN_SET) & BIT(0)) == 1) {
  122. ERROR("%s: [%s] mmup not reset set !\n", MODULE_TAG, __func__);
  123. return false;
  124. }
  125. mmio_clrsetbits_32(VCP_R_SEC_DOMAIN,
  126. ~(VCP_DOMAIN_MASK << VCP_HWCCF_DOMAIN), VCP_DOMAIN_SET);
  127. /* enable IOVA Mode */
  128. mmio_write_32(VCP_R_AXIOMMUEN_DEV_APC, BIT(0));
  129. /* reset secure setting */
  130. mmio_setbits_32(VCP_R_SEC_CTRL_2, CORE0_SEC_BIT_SEL);
  131. mmio_clrbits_32(VCP_R_DYN_SECURE, VCP_NS_I0 | VCP_NS_D0);
  132. mmio_clrbits_32(VCP_R_DYN_SECURE_TH1, VCP_NS_I1 | VCP_NS_D1);
  133. /* start vcp */
  134. mmio_write_32(VCP_R_CORE0_SW_RSTN_CLR, BIT(0));
  135. dsbsy();
  136. return true;
  137. }
  138. static u_register_t tinysys_vcp_kernel_control(u_register_t arg0,
  139. u_register_t arg1,
  140. u_register_t arg2,
  141. u_register_t arg3,
  142. void *handle,
  143. struct smccc_res *smccc_ret)
  144. {
  145. uint32_t request_ops;
  146. uint64_t ret = MTK_SIP_E_SUCCESS;
  147. if (!get_vcp_pwr_status())
  148. return MTK_SIP_E_NOT_SUPPORTED;
  149. request_ops = (uint32_t)arg0;
  150. switch (request_ops) {
  151. case MTK_TINYSYS_VCP_KERNEL_OP_RESET_SET:
  152. ret = vcp_smc_rstn_set((bool)!!arg1);
  153. break;
  154. case MTK_TINYSYS_VCP_KERNEL_OP_RESET_RELEASE:
  155. ret = vcp_smc_rstn_clr();
  156. break;
  157. case MTK_TINYSYS_VCP_KERNEL_OP_COLD_BOOT_VCP:
  158. ret = vcp_cold_boot_reset();
  159. break;
  160. case MTK_TINYSYS_MMUP_KERNEL_OP_RESET_SET:
  161. ret = mmup_smc_rstn_set((bool)!!arg1);
  162. break;
  163. case MTK_TINYSYS_MMUP_KERNEL_OP_RESET_RELEASE:
  164. ret = mmup_smc_rstn_clr();
  165. break;
  166. case MTK_TINYSYS_MMUP_KERNEL_OP_SET_L2TCM_OFFSET:
  167. ret = vcp_set_mmup_l2tcm_offset(arg1);
  168. break;
  169. case MTK_TINYSYS_MMUP_KERNEL_OP_SET_FW_SIZE:
  170. ret = vcp_set_mmup_fw_size(arg1);
  171. break;
  172. case MTK_TINYSYS_MMUP_KERNEL_OP_COLD_BOOT_MMUP:
  173. ret = mmup_cold_boot_reset();
  174. break;
  175. default:
  176. ERROR("%s: %s, unknown request_ops = %x\n", MODULE_TAG, __func__, request_ops);
  177. ret = MTK_SIP_E_INVALID_PARAM;
  178. break;
  179. }
  180. return ret;
  181. }
  182. /* Register SiP SMC service */
  183. DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_VCP_CONTROL, tinysys_vcp_kernel_control);