cvp_vm_main.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /* SPDX-License-Identifier: GPL-2.0-only
  2. *
  3. * Copyright (c) 2022, 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. vm_manager.vm_id = core->platform_data->vm_id;
  50. return 0;
  51. }
  52. static int __check_core_registered(struct iris_hfi_device *device,
  53. phys_addr_t fw_addr, u8 *reg_addr, u32 reg_size,
  54. phys_addr_t irq)
  55. {
  56. struct cvp_hal_data *cvp_hal_data;
  57. if (!device) {
  58. dprintk(CVP_INFO, "no device Registered\n");
  59. return -EINVAL;
  60. }
  61. cvp_hal_data = device->cvp_hal_data;
  62. if (!cvp_hal_data)
  63. return -EINVAL;
  64. if (cvp_hal_data->irq == irq &&
  65. (CONTAINS(cvp_hal_data->firmware_base,
  66. FIRMWARE_SIZE, fw_addr) ||
  67. CONTAINS(fw_addr, FIRMWARE_SIZE,
  68. cvp_hal_data->firmware_base) ||
  69. CONTAINS(cvp_hal_data->register_base,
  70. reg_size, reg_addr) ||
  71. CONTAINS(reg_addr, reg_size,
  72. cvp_hal_data->register_base) ||
  73. OVERLAPS(cvp_hal_data->register_base,
  74. reg_size, reg_addr, reg_size) ||
  75. OVERLAPS(reg_addr, reg_size,
  76. cvp_hal_data->register_base,
  77. reg_size) ||
  78. OVERLAPS(cvp_hal_data->firmware_base,
  79. FIRMWARE_SIZE, fw_addr,
  80. FIRMWARE_SIZE) ||
  81. OVERLAPS(fw_addr, FIRMWARE_SIZE,
  82. cvp_hal_data->firmware_base,
  83. FIRMWARE_SIZE))) {
  84. return 0;
  85. }
  86. dprintk(CVP_INFO, "Device not registered\n");
  87. return -EINVAL;
  88. }
  89. static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device,
  90. struct msm_cvp_platform_resources *res)
  91. {
  92. struct cvp_hal_data *hal = NULL;
  93. int rc = 0;
  94. if (vm_manager.vm_id == VM_TRUSTED)
  95. return 0;
  96. rc = __check_core_registered(device, res->firmware_base,
  97. (u8 *)(uintptr_t)res->register_base,
  98. res->register_size, res->irq);
  99. if (!rc) {
  100. dprintk(CVP_ERR, "Core present/Already added\n");
  101. rc = -EEXIST;
  102. goto err_core_init;
  103. }
  104. hal = kzalloc(sizeof(*hal), GFP_KERNEL);
  105. if (!hal) {
  106. dprintk(CVP_ERR, "Failed to alloc\n");
  107. rc = -ENOMEM;
  108. goto err_core_init;
  109. }
  110. hal->irq = res->irq;
  111. hal->firmware_base = res->firmware_base;
  112. hal->register_base = devm_ioremap(&res->pdev->dev,
  113. res->register_base, res->register_size);
  114. hal->register_size = res->register_size;
  115. if (!hal->register_base) {
  116. dprintk(CVP_ERR,
  117. "could not map reg addr %pa of size %d\n",
  118. &res->register_base, res->register_size);
  119. goto error_irq_fail;
  120. }
  121. if (res->gcc_reg_base) {
  122. hal->gcc_reg_base = devm_ioremap(&res->pdev->dev,
  123. res->gcc_reg_base, res->gcc_reg_size);
  124. hal->gcc_reg_size = res->gcc_reg_size;
  125. if (!hal->gcc_reg_base)
  126. dprintk(CVP_ERR,
  127. "could not map gcc reg addr %pa of size %d\n",
  128. &res->gcc_reg_base, res->gcc_reg_size);
  129. }
  130. device->cvp_hal_data = hal;
  131. rc = request_irq(res->irq, cvp_hfi_isr, IRQF_TRIGGER_HIGH,
  132. "msm_cvp", device);
  133. if (unlikely(rc)) {
  134. dprintk(CVP_ERR, "() :request_irq failed\n");
  135. goto error_irq_fail;
  136. }
  137. disable_irq_nosync(res->irq);
  138. dprintk(CVP_INFO,
  139. "firmware_base = %pa, register_base = %pa, register_size = %d\n",
  140. &res->firmware_base, &res->register_base,
  141. res->register_size);
  142. return rc;
  143. error_irq_fail:
  144. kfree(hal);
  145. err_core_init:
  146. return rc;
  147. }