msm_cvp_vm.c 4.1 KB

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