diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index e4ca6b6549..ed7e04f09f 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "cvp_hfi_api.h" #include "cvp_hfi_helper.h" @@ -267,6 +268,7 @@ struct iris_hfi_device { struct iris_hfi_vpu_ops *vpu_ops; }; +irqreturn_t cvp_hfi_isr(int irq, void *dev); void cvp_iris_hfi_delete_device(void *device); int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 77d1600967..30dc4f94f8 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -31,9 +30,9 @@ #include "cvp_hfi_io.h" #include "msm_cvp_dsp.h" #include "msm_cvp_clocks.h" +#include "msm_cvp_vm.h" #include "cvp_dump.h" -#define FIRMWARE_SIZE 0X00A00000 #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF #define QDSS_IOVA_START 0x80001000 #define MIN_PAYLOAD_SIZE 3 @@ -2399,48 +2398,6 @@ static int iris_hfi_session_flush(void *sess) return rc; } -static int __check_core_registered(struct iris_hfi_device *device, - phys_addr_t fw_addr, u8 *reg_addr, u32 reg_size, - phys_addr_t irq) -{ - struct cvp_hal_data *cvp_hal_data; - - if (!device) { - dprintk(CVP_INFO, "no device Registered\n"); - return -EINVAL; - } - - cvp_hal_data = device->cvp_hal_data; - if (!cvp_hal_data) - return -EINVAL; - - if (cvp_hal_data->irq == irq && - (CONTAINS(cvp_hal_data->firmware_base, - FIRMWARE_SIZE, fw_addr) || - CONTAINS(fw_addr, FIRMWARE_SIZE, - cvp_hal_data->firmware_base) || - CONTAINS(cvp_hal_data->register_base, - reg_size, reg_addr) || - CONTAINS(reg_addr, reg_size, - cvp_hal_data->register_base) || - OVERLAPS(cvp_hal_data->register_base, - reg_size, reg_addr, reg_size) || - OVERLAPS(reg_addr, reg_size, - cvp_hal_data->register_base, - reg_size) || - OVERLAPS(cvp_hal_data->firmware_base, - FIRMWARE_SIZE, fw_addr, - FIRMWARE_SIZE) || - OVERLAPS(fw_addr, FIRMWARE_SIZE, - cvp_hal_data->firmware_base, - FIRMWARE_SIZE))) { - return 0; - } - - dprintk(CVP_INFO, "Device not registered\n"); - return -EINVAL; -} - static void __process_fatal_error( struct iris_hfi_device *device) { @@ -3049,7 +3006,7 @@ err_no_work: static DECLARE_WORK(iris_hfi_work, iris_hfi_core_work_handler); -static irqreturn_t iris_hfi_isr(int irq, void *dev) +irqreturn_t cvp_hfi_isr(int irq, void *dev) { struct iris_hfi_device *device = dev; @@ -3058,72 +3015,6 @@ static irqreturn_t iris_hfi_isr(int irq, void *dev) return IRQ_HANDLED; } -static int __init_regs_and_interrupts(struct iris_hfi_device *device, - struct msm_cvp_platform_resources *res) -{ - struct cvp_hal_data *hal = NULL; - int rc = 0; - - rc = __check_core_registered(device, res->firmware_base, - (u8 *)(uintptr_t)res->register_base, - res->register_size, res->irq); - if (!rc) { - dprintk(CVP_ERR, "Core present/Already added\n"); - rc = -EEXIST; - goto err_core_init; - } - - hal = kzalloc(sizeof(*hal), GFP_KERNEL); - if (!hal) { - dprintk(CVP_ERR, "Failed to alloc\n"); - rc = -ENOMEM; - goto err_core_init; - } - - hal->irq = res->irq; - hal->firmware_base = res->firmware_base; - hal->register_base = devm_ioremap(&res->pdev->dev, - res->register_base, res->register_size); - hal->register_size = res->register_size; - if (!hal->register_base) { - dprintk(CVP_ERR, - "could not map reg addr %pa of size %d\n", - &res->register_base, res->register_size); - goto error_irq_fail; - } - - if (res->gcc_reg_base) { - hal->gcc_reg_base = devm_ioremap(&res->pdev->dev, - res->gcc_reg_base, res->gcc_reg_size); - hal->gcc_reg_size = res->gcc_reg_size; - if (!hal->gcc_reg_base) - dprintk(CVP_ERR, - "could not map gcc reg addr %pa of size %d\n", - &res->gcc_reg_base, res->gcc_reg_size); - } - - device->cvp_hal_data = hal; - rc = request_irq(res->irq, iris_hfi_isr, IRQF_TRIGGER_HIGH, - "msm_cvp", device); - if (unlikely(rc)) { - dprintk(CVP_ERR, "() :request_irq failed\n"); - goto error_irq_fail; - } - - disable_irq_nosync(res->irq); - dprintk(CVP_INFO, - "firmware_base = %pa, register_base = %pa, register_size = %d\n", - &res->firmware_base, &res->register_base, - res->register_size); - return rc; - -error_irq_fail: - kfree(hal); -err_core_init: - return rc; - -} - static int __handle_reset_clk(struct msm_cvp_platform_resources *res, int reset_index, enum reset_state state, enum power_state pwr_state) @@ -4657,7 +4548,7 @@ static struct iris_hfi_device *__add_device(u32 device_id, goto err_cleanup; } - rc = __init_regs_and_interrupts(hdevice, res); + rc = vm_manager.vm_ops->vm_init_reg_and_irq(hdevice, res); if (rc) goto err_cleanup; diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index fb4f9dcb0f..b6cc53f217 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -135,6 +135,7 @@ struct msm_cvp_platform_data { unsigned int common_data_length; unsigned int sku_version; uint32_t vpu_ver; + unsigned int vm_id; /* pvm: 1; tvm: 2 */ struct msm_cvp_ubwc_config_data *ubwc_config; struct msm_cvp_qos_setting *noc_qos; }; diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 24a438af7d..faf5b4293e 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -147,7 +147,57 @@ static struct msm_cvp_common_data sm8550_common_data[] = { } }; - +static struct msm_cvp_common_data sm8550_tvm_common_data[] = { + { + .key = "qcom,pm-qos-latency-us", + .value = 50, + }, + { + .key = "qcom,sw-power-collapse", + .value = 0, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 0, + }, + { + .key = "qcom,max-secure-instances", + .value = 2, /* + * As per design driver allows 3rd + * instance as well since the secure + * flags were updated later for the + * current instance. Hence total + * secure sessions would be + * max-secure-instances + 1. + */ + }, + { + .key = "qcom,max-ssr-allowed", + .value = 1, /* + * Maxinum number of SSR before BUG_ON + */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 3000, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 2000, + }, + { + .key = "qcom,dsp-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,dsp-enabled", + .value = 0, + } +}; /* Default UBWC config for LPDDR5 */ static struct msm_cvp_ubwc_config_data kona_ubwc_data[] = { @@ -170,6 +220,7 @@ static struct msm_cvp_platform_data default_data = { .vpu_ver = VPU_VERSION_5, .ubwc_config = 0x0, .noc_qos = 0x0, + .vm_id = 1, }; static struct msm_cvp_platform_data sm8450_data = { @@ -179,6 +230,7 @@ static struct msm_cvp_platform_data sm8450_data = { .vpu_ver = VPU_VERSION_5, .ubwc_config = kona_ubwc_data, .noc_qos = &waipio_noc_qos, + .vm_id = 1, }; static struct msm_cvp_platform_data sm8550_data = { @@ -188,6 +240,17 @@ static struct msm_cvp_platform_data sm8550_data = { .vpu_ver = VPU_VERSION_5, .ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/ .noc_qos = &waipio_noc_qos, /*Reuse Waipio setting*/ + .vm_id = 1, +}; + +static struct msm_cvp_platform_data sm8550_tvm_data = { + .common_data = sm8550_tvm_common_data, + .common_data_length = ARRAY_SIZE(sm8550_tvm_common_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_5, + .ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/ + .noc_qos = &waipio_noc_qos, /*Reuse Waipio setting*/ + .vm_id = 2, }; static const struct of_device_id msm_cvp_dt_match[] = { @@ -199,6 +262,10 @@ static const struct of_device_id msm_cvp_dt_match[] = { .compatible = "qcom,kalama-cvp", .data = &sm8550_data, }, + { + .compatible = "qcom,kalama-cvp-tvm", + .data = &sm8550_tvm_data, + }, {}, }; diff --git a/msm/eva/msm_cvp_vm.c b/msm/eva/msm_cvp_vm.c index 9963420083..61aae613e5 100644 --- a/msm/eva/msm_cvp_vm.c +++ b/msm/eva/msm_cvp_vm.c @@ -2,12 +2,163 @@ * * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hfi_packetization.h" +#include "msm_cvp_debug.h" +#include "cvp_core_hfi.h" +#include "cvp_hfi_helper.h" +#include "cvp_hfi_io.h" +#include "msm_cvp_dsp.h" +#include "msm_cvp_clocks.h" +#include "cvp_dump.h" #include "msm_cvp_vm.h" -int msm_cvp_vm_init(struct msm_cvp_core *core) +#define FIRMWARE_SIZE 0X00A00000 + +static int msm_cvp_vm_start(struct msm_cvp_core *core); +static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device, + struct msm_cvp_platform_resources *res); + +static struct msm_cvp_vm_ops vm_ops = { + .vm_start = msm_cvp_vm_start, + .vm_init_reg_and_irq = msm_cvp_vm_init_reg_and_irq, +}; + +struct msm_cvp_vm_manager vm_manager = { + .vm_ops = &vm_ops, +}; + +static int msm_cvp_vm_start(struct msm_cvp_core *core) { + vm_manager.vm_id = core->platform_data->vm_id; return 0; } +static int __check_core_registered(struct iris_hfi_device *device, + phys_addr_t fw_addr, u8 *reg_addr, u32 reg_size, + phys_addr_t irq) +{ + struct cvp_hal_data *cvp_hal_data; + if (!device) { + dprintk(CVP_INFO, "no device Registered\n"); + return -EINVAL; + } + + cvp_hal_data = device->cvp_hal_data; + if (!cvp_hal_data) + return -EINVAL; + + if (cvp_hal_data->irq == irq && + (CONTAINS(cvp_hal_data->firmware_base, + FIRMWARE_SIZE, fw_addr) || + CONTAINS(fw_addr, FIRMWARE_SIZE, + cvp_hal_data->firmware_base) || + CONTAINS(cvp_hal_data->register_base, + reg_size, reg_addr) || + CONTAINS(reg_addr, reg_size, + cvp_hal_data->register_base) || + OVERLAPS(cvp_hal_data->register_base, + reg_size, reg_addr, reg_size) || + OVERLAPS(reg_addr, reg_size, + cvp_hal_data->register_base, + reg_size) || + OVERLAPS(cvp_hal_data->firmware_base, + FIRMWARE_SIZE, fw_addr, + FIRMWARE_SIZE) || + OVERLAPS(fw_addr, FIRMWARE_SIZE, + cvp_hal_data->firmware_base, + FIRMWARE_SIZE))) { + return 0; + } + + dprintk(CVP_INFO, "Device not registered\n"); + return -EINVAL; +} + +static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device, + struct msm_cvp_platform_resources *res) +{ + struct cvp_hal_data *hal = NULL; + int rc = 0; + + if (vm_manager.vm_id == VM_TRUSTED) + return 0; + + rc = __check_core_registered(device, res->firmware_base, + (u8 *)(uintptr_t)res->register_base, + res->register_size, res->irq); + if (!rc) { + dprintk(CVP_ERR, "Core present/Already added\n"); + rc = -EEXIST; + goto err_core_init; + } + + hal = kzalloc(sizeof(*hal), GFP_KERNEL); + if (!hal) { + dprintk(CVP_ERR, "Failed to alloc\n"); + rc = -ENOMEM; + goto err_core_init; + } + + hal->irq = res->irq; + hal->firmware_base = res->firmware_base; + hal->register_base = devm_ioremap(&res->pdev->dev, + res->register_base, res->register_size); + hal->register_size = res->register_size; + if (!hal->register_base) { + dprintk(CVP_ERR, + "could not map reg addr %pa of size %d\n", + &res->register_base, res->register_size); + goto error_irq_fail; + } + + if (res->gcc_reg_base) { + hal->gcc_reg_base = devm_ioremap(&res->pdev->dev, + res->gcc_reg_base, res->gcc_reg_size); + hal->gcc_reg_size = res->gcc_reg_size; + if (!hal->gcc_reg_base) + dprintk(CVP_ERR, + "could not map gcc reg addr %pa of size %d\n", + &res->gcc_reg_base, res->gcc_reg_size); + } + + device->cvp_hal_data = hal; + rc = request_irq(res->irq, cvp_hfi_isr, IRQF_TRIGGER_HIGH, + "msm_cvp", device); + if (unlikely(rc)) { + dprintk(CVP_ERR, "() :request_irq failed\n"); + goto error_irq_fail; + } + + disable_irq_nosync(res->irq); + dprintk(CVP_INFO, + "firmware_base = %pa, register_base = %pa, register_size = %d\n", + &res->firmware_base, &res->register_base, + res->register_size); + return rc; + +error_irq_fail: + kfree(hal); +err_core_init: + return rc; +} diff --git a/msm/eva/msm_cvp_vm.h b/msm/eva/msm_cvp_vm.h index c231bf93fd..19450e7c9a 100644 --- a/msm/eva/msm_cvp_vm.h +++ b/msm/eva/msm_cvp_vm.h @@ -10,7 +10,32 @@ #include "cvp_comm_def.h" #include "msm_cvp_core.h" #include "msm_cvp_internal.h" +#include "cvp_core_hfi.h" -int msm_cvp_vm_init(struct msm_cvp_core *core); +enum cvp_vm_id { + VM_PRIMARY = 1, + VM_TRUSTED = 2, + VM_INVALID = 3, +}; +enum cvp_vm_state { + VM_STATE_INIT = 1, + VM_STATE_ACTIVE = 2, + VM_STATE_ERROR = 3, + VM_STATE_INVALID = 4, +}; + +struct msm_cvp_vm_ops { + int (*vm_start)(struct msm_cvp_core *core); + int (*vm_init_reg_and_irq)(struct iris_hfi_device *device, + struct msm_cvp_platform_resources *res); +}; + +struct msm_cvp_vm_manager { + enum cvp_vm_state vm_state; + enum cvp_vm_id vm_id; + struct msm_cvp_vm_ops *vm_ops; +}; + +extern struct msm_cvp_vm_manager vm_manager; #endif