msm: eva: Add initial drop of VM manager

First drop for common code base.

Change-Id: If0147395cc946f1cad69c270226b0ff20e11b6ef
Signed-off-by: George Shen <quic_sqiao@quicinc.com>
This commit is contained in:
George Shen
2022-04-04 09:21:01 -07:00
rodzic 6492155ccc
commit 7a7d1cf8b5
6 zmienionych plików z 253 dodań i 116 usunięć

Wyświetl plik

@@ -12,6 +12,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_qos.h> #include <linux/pm_qos.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/soc/qcom/msm_mmrm.h> #include <linux/soc/qcom/msm_mmrm.h>
#include "cvp_hfi_api.h" #include "cvp_hfi_api.h"
#include "cvp_hfi_helper.h" #include "cvp_hfi_helper.h"
@@ -267,6 +268,7 @@ struct iris_hfi_device {
struct iris_hfi_vpu_ops *vpu_ops; struct iris_hfi_vpu_ops *vpu_ops;
}; };
irqreturn_t cvp_hfi_isr(int irq, void *dev);
void cvp_iris_hfi_delete_device(void *device); void cvp_iris_hfi_delete_device(void *device);
int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id,

Wyświetl plik

@@ -8,7 +8,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/devfreq.h> #include <linux/devfreq.h>
#include <linux/hash.h> #include <linux/hash.h>
#include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/iommu.h> #include <linux/iommu.h>
#include <linux/iopoll.h> #include <linux/iopoll.h>
@@ -31,9 +30,9 @@
#include "cvp_hfi_io.h" #include "cvp_hfi_io.h"
#include "msm_cvp_dsp.h" #include "msm_cvp_dsp.h"
#include "msm_cvp_clocks.h" #include "msm_cvp_clocks.h"
#include "msm_cvp_vm.h"
#include "cvp_dump.h" #include "cvp_dump.h"
#define FIRMWARE_SIZE 0X00A00000
#define REG_ADDR_OFFSET_BITMASK 0x000FFFFF #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF
#define QDSS_IOVA_START 0x80001000 #define QDSS_IOVA_START 0x80001000
#define MIN_PAYLOAD_SIZE 3 #define MIN_PAYLOAD_SIZE 3
@@ -2399,48 +2398,6 @@ static int iris_hfi_session_flush(void *sess)
return rc; 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( static void __process_fatal_error(
struct iris_hfi_device *device) struct iris_hfi_device *device)
{ {
@@ -3049,7 +3006,7 @@ err_no_work:
static DECLARE_WORK(iris_hfi_work, iris_hfi_core_work_handler); 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; struct iris_hfi_device *device = dev;
@@ -3058,72 +3015,6 @@ static irqreturn_t iris_hfi_isr(int irq, void *dev)
return IRQ_HANDLED; 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, static int __handle_reset_clk(struct msm_cvp_platform_resources *res,
int reset_index, enum reset_state state, int reset_index, enum reset_state state,
enum power_state pwr_state) enum power_state pwr_state)
@@ -4657,7 +4548,7 @@ static struct iris_hfi_device *__add_device(u32 device_id,
goto err_cleanup; goto err_cleanup;
} }
rc = __init_regs_and_interrupts(hdevice, res); rc = vm_manager.vm_ops->vm_init_reg_and_irq(hdevice, res);
if (rc) if (rc)
goto err_cleanup; goto err_cleanup;

Wyświetl plik

@@ -135,6 +135,7 @@ struct msm_cvp_platform_data {
unsigned int common_data_length; unsigned int common_data_length;
unsigned int sku_version; unsigned int sku_version;
uint32_t vpu_ver; uint32_t vpu_ver;
unsigned int vm_id; /* pvm: 1; tvm: 2 */
struct msm_cvp_ubwc_config_data *ubwc_config; struct msm_cvp_ubwc_config_data *ubwc_config;
struct msm_cvp_qos_setting *noc_qos; struct msm_cvp_qos_setting *noc_qos;
}; };

Wyświetl plik

@@ -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 */ /* Default UBWC config for LPDDR5 */
static struct msm_cvp_ubwc_config_data kona_ubwc_data[] = { 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, .vpu_ver = VPU_VERSION_5,
.ubwc_config = 0x0, .ubwc_config = 0x0,
.noc_qos = 0x0, .noc_qos = 0x0,
.vm_id = 1,
}; };
static struct msm_cvp_platform_data sm8450_data = { 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, .vpu_ver = VPU_VERSION_5,
.ubwc_config = kona_ubwc_data, .ubwc_config = kona_ubwc_data,
.noc_qos = &waipio_noc_qos, .noc_qos = &waipio_noc_qos,
.vm_id = 1,
}; };
static struct msm_cvp_platform_data sm8550_data = { 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, .vpu_ver = VPU_VERSION_5,
.ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/ .ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/
.noc_qos = &waipio_noc_qos, /*Reuse Waipio 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[] = { 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", .compatible = "qcom,kalama-cvp",
.data = &sm8550_data, .data = &sm8550_data,
}, },
{
.compatible = "qcom,kalama-cvp-tvm",
.data = &sm8550_tvm_data,
},
{}, {},
}; };

Wyświetl plik

@@ -2,12 +2,163 @@
* *
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#include <asm/memory.h>
#include <linux/coresight-stm.h>
#include <linux/delay.h>
#include <linux/devfreq.h>
#include <linux/hash.h>
#include <linux/io.h>
#include <linux/iommu.h>
#include <linux/iopoll.h>
#include <linux/of.h>
#include <linux/pm_qos.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>
#include <linux/soc/qcom/llcc-qcom.h>
#include <linux/qcom_scm.h>
#include <linux/soc/qcom/smem.h>
#include <linux/dma-mapping.h>
#include <linux/reset.h>
#include <linux/pm_wakeup.h>
#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" #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; 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;
}

Wyświetl plik

@@ -10,7 +10,32 @@
#include "cvp_comm_def.h" #include "cvp_comm_def.h"
#include "msm_cvp_core.h" #include "msm_cvp_core.h"
#include "msm_cvp_internal.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 #endif