cvp_vm_main.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /* SPDX-License-Identifier: GPL-2.0-only
  2. *
  3. * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  4. */
  5. #include <asm/memory.h>
  6. #include <linux/coresight-stm.h>
  7. #include <linux/delay.h>
  8. #include <linux/devfreq.h>
  9. #include <linux/hash.h>
  10. #include <linux/io.h>
  11. #include <linux/iommu.h>
  12. #include <linux/iopoll.h>
  13. #include <linux/of.h>
  14. #include <linux/pm_qos.h>
  15. #include <linux/regulator/consumer.h>
  16. #include <linux/slab.h>
  17. #include <linux/workqueue.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/soc/qcom/llcc-qcom.h>
  20. #include <linux/qcom_scm.h>
  21. #include <linux/soc/qcom/smem.h>
  22. #include <linux/dma-mapping.h>
  23. #include <linux/reset.h>
  24. #include <linux/pm_wakeup.h>
  25. #include "hfi_packetization.h"
  26. #include "msm_cvp_debug.h"
  27. #include "cvp_core_hfi.h"
  28. #include "cvp_hfi_helper.h"
  29. #include "cvp_hfi_io.h"
  30. #include "msm_cvp_dsp.h"
  31. #include "msm_cvp_clocks.h"
  32. #include "cvp_dump.h"
  33. #include "cvp_vm.h"
  34. #define FIRMWARE_SIZE 0X00A00000
  35. static int msm_cvp_vm_start(struct msm_cvp_core *core);
  36. static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device,
  37. struct msm_cvp_platform_resources *res);
  38. static struct msm_cvp_vm_ops vm_ops = {
  39. .vm_start = msm_cvp_vm_start,
  40. .vm_init_reg_and_irq = msm_cvp_vm_init_reg_and_irq,
  41. };
  42. struct msm_cvp_vm_manager vm_manager = {
  43. .msgq_drv = &cvp_ipc_msgq,
  44. .vm_rm = &cvp_vm_rm,
  45. .vm_ops = &vm_ops,
  46. };
  47. static int msm_cvp_vm_start(struct msm_cvp_core *core)
  48. {
  49. if (!core || !core->platform_data) {
  50. dprintk(CVP_ERR, "%s: Invalid params %pK %pK\n",
  51. __func__, core,
  52. (core == NULL)? NULL: core->platform_data);
  53. return -EINVAL;
  54. }
  55. vm_manager.vm_id = core->platform_data->vm_id;
  56. return 0;
  57. }
  58. static int __check_core_registered(struct iris_hfi_device *device,
  59. phys_addr_t fw_addr, u8 *reg_addr, u32 reg_size,
  60. phys_addr_t irq)
  61. {
  62. struct cvp_hal_data *cvp_hal_data;
  63. if (!device) {
  64. dprintk(CVP_INFO, "no device Registered\n");
  65. return -EINVAL;
  66. }
  67. cvp_hal_data = device->cvp_hal_data;
  68. if (!cvp_hal_data)
  69. return -EINVAL;
  70. if (cvp_hal_data->irq == irq &&
  71. (CONTAINS(cvp_hal_data->firmware_base,
  72. FIRMWARE_SIZE, fw_addr) ||
  73. CONTAINS(fw_addr, FIRMWARE_SIZE,
  74. cvp_hal_data->firmware_base) ||
  75. CONTAINS(cvp_hal_data->register_base,
  76. reg_size, reg_addr) ||
  77. CONTAINS(reg_addr, reg_size,
  78. cvp_hal_data->register_base) ||
  79. OVERLAPS(cvp_hal_data->register_base,
  80. reg_size, reg_addr, reg_size) ||
  81. OVERLAPS(reg_addr, reg_size,
  82. cvp_hal_data->register_base,
  83. reg_size) ||
  84. OVERLAPS(cvp_hal_data->firmware_base,
  85. FIRMWARE_SIZE, fw_addr,
  86. FIRMWARE_SIZE) ||
  87. OVERLAPS(fw_addr, FIRMWARE_SIZE,
  88. cvp_hal_data->firmware_base,
  89. FIRMWARE_SIZE))) {
  90. return 0;
  91. }
  92. dprintk(CVP_INFO, "Device not registered\n");
  93. return -EINVAL;
  94. }
  95. static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device,
  96. struct msm_cvp_platform_resources *res)
  97. {
  98. struct cvp_hal_data *hal = NULL;
  99. int rc = 0;
  100. if (vm_manager.vm_id == VM_TRUSTED)
  101. return 0;
  102. rc = __check_core_registered(device, res->firmware_base,
  103. (u8 *)(uintptr_t)res->register_base,
  104. res->register_size, res->irq);
  105. if (!rc) {
  106. dprintk(CVP_ERR, "Core present/Already added\n");
  107. rc = -EEXIST;
  108. goto err_core_init;
  109. }
  110. hal = kzalloc(sizeof(*hal), GFP_KERNEL);
  111. if (!hal) {
  112. dprintk(CVP_ERR, "Failed to alloc\n");
  113. rc = -ENOMEM;
  114. goto err_core_init;
  115. }
  116. hal->irq = res->irq;
  117. hal->irq_wd = res->irq_wd;
  118. hal->firmware_base = res->firmware_base;
  119. hal->register_base = devm_ioremap(&res->pdev->dev,
  120. res->register_base, res->register_size);
  121. hal->register_size = res->register_size;
  122. if (!hal->register_base) {
  123. dprintk(CVP_ERR,
  124. "could not map reg addr %pa of size %d\n",
  125. &res->register_base, res->register_size);
  126. goto error_irq_fail;
  127. }
  128. if (res->gcc_reg_base) {
  129. hal->gcc_reg_base = devm_ioremap(&res->pdev->dev,
  130. res->gcc_reg_base, res->gcc_reg_size);
  131. hal->gcc_reg_size = res->gcc_reg_size;
  132. if (!hal->gcc_reg_base)
  133. dprintk(CVP_ERR,
  134. "could not map gcc reg addr %pa of size %d\n",
  135. &res->gcc_reg_base, res->gcc_reg_size);
  136. }
  137. device->cvp_hal_data = hal;
  138. rc = request_threaded_irq(res->irq, cvp_hfi_isr, iris_hfi_core_work_handler,
  139. IRQF_TRIGGER_HIGH, "msm_cvp", device);
  140. if (unlikely(rc)) {
  141. dprintk(CVP_ERR, "%s: request_irq failed rc: %d\n", __func__, rc);
  142. goto error_irq_fail;
  143. }
  144. rc = request_irq(res->irq_wd, iris_hfi_isr_wd, IRQF_TRIGGER_HIGH,
  145. "msm_cvp", device);
  146. if (unlikely(rc)) {
  147. dprintk(CVP_ERR, "() :request_irq for WD failed\n");
  148. goto error_irq_fail;
  149. }
  150. disable_irq_nosync(res->irq);
  151. dprintk(CVP_INFO,
  152. "firmware_base = %pa, register_base = %pa, register_size = %d\n",
  153. &res->firmware_base, &res->register_base,
  154. res->register_size);
  155. return rc;
  156. error_irq_fail:
  157. kfree(hal);
  158. err_core_init:
  159. return rc;
  160. }