mm-drivers: hw_fence: add implementation of translation to synx API
Add implementation to translate the msm_hw_fence API into synx API. Change-Id: I5d0b7afcc297a4e3c8ec4ed9867831b5d2dfc3af Signed-off-by: Grace An <quic_gracan@quicinc.com>
Dieser Commit ist enthalten in:
@@ -3,7 +3,9 @@
|
||||
KDIR := $(TOP)/kernel_platform/msm-kernel
|
||||
include $(MSM_HW_FENCE_ROOT)/config/kalamammdrivers.conf
|
||||
LINUXINCLUDE += -include $(MSM_HW_FENCE_ROOT)/config/kalamammdriversconf.h \
|
||||
-I$(MSM_HW_FENCE_ROOT)hw_fence/include/
|
||||
-I$(MSM_HW_FENCE_ROOT)hw_fence/include/ \
|
||||
-I$(MSM_HW_FENCE_ROOT)/../synx-kernel/msm/synx/ \
|
||||
-I$(MSM_HW_FENCE_ROOT)/../synx-kernel/include/uapi/synx/media/
|
||||
|
||||
ifdef CONFIG_QTI_HW_FENCE
|
||||
obj-m += msm_hw_fence.o
|
||||
@@ -12,7 +14,8 @@ msm_hw_fence-y := src/msm_hw_fence.o \
|
||||
src/hw_fence_drv_priv.o \
|
||||
src/hw_fence_drv_utils.o \
|
||||
src/hw_fence_drv_debug.o \
|
||||
src/hw_fence_drv_ipc.o
|
||||
src/hw_fence_drv_ipc.o \
|
||||
src/msm_hw_fence_synx_translation.o
|
||||
|
||||
msm_hw_fence-$(CONFIG_DEBUG_FS) += src/hw_fence_ioctl.o
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
#include "hw_fence_drv_ipc.h"
|
||||
|
||||
struct hw_fence_driver_data *hw_fence_drv_data;
|
||||
static bool hw_fence_driver_enable;
|
||||
bool hw_fence_driver_enable;
|
||||
|
||||
void *msm_hw_fence_register(enum hw_fence_client_id client_id_ext,
|
||||
struct msm_hw_fence_mem_addr *mem_descriptor)
|
||||
|
332
hw_fence/src/msm_hw_fence_synx_translation.c
Normale Datei
332
hw_fence/src/msm_hw_fence_synx_translation.c
Normale Datei
@@ -0,0 +1,332 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/soc/qcom/msm_hw_fence.h>
|
||||
#include "msm_hw_fence_synx_translation.h"
|
||||
#include "hw_fence_drv_priv.h"
|
||||
#include "hw_fence_drv_debug.h"
|
||||
|
||||
/**
|
||||
* MAX_SUPPORTED_DPU0:
|
||||
* Maximum number of dpu clients supported
|
||||
*/
|
||||
#define MAX_SUPPORTED_DPU0 (HW_FENCE_CLIENT_ID_CTL5 - HW_FENCE_CLIENT_ID_CTL0)
|
||||
|
||||
static int to_synx_status(int hw_fence_status_code)
|
||||
{
|
||||
int synx_status_code;
|
||||
|
||||
switch (hw_fence_status_code) {
|
||||
case 0:
|
||||
synx_status_code = SYNX_SUCCESS;
|
||||
break;
|
||||
case -ENOMEM:
|
||||
synx_status_code = -SYNX_NOMEM;
|
||||
break;
|
||||
case -EPERM:
|
||||
synx_status_code = -SYNX_NOPERM;
|
||||
break;
|
||||
case -ETIMEDOUT:
|
||||
synx_status_code = -SYNX_TIMEOUT;
|
||||
break;
|
||||
case -EALREADY:
|
||||
synx_status_code = -SYNX_ALREADY;
|
||||
break;
|
||||
case -ENOENT:
|
||||
synx_status_code = -SYNX_NOENT;
|
||||
break;
|
||||
case -EINVAL:
|
||||
synx_status_code = -SYNX_INVALID;
|
||||
break;
|
||||
case -EBUSY:
|
||||
synx_status_code = -SYNX_BUSY;
|
||||
break;
|
||||
default:
|
||||
synx_status_code = hw_fence_status_code;
|
||||
break;
|
||||
}
|
||||
|
||||
return synx_status_code;
|
||||
}
|
||||
|
||||
static enum hw_fence_client_id _get_hw_fence_client_id(enum synx_client_id synx_client_id)
|
||||
{
|
||||
enum hw_fence_client_id hw_fence_client_id;
|
||||
|
||||
switch ((int)synx_client_id) {
|
||||
case SYNX_CLIENT_HW_FENCE_GFX_CTX0:
|
||||
hw_fence_client_id = HW_FENCE_CLIENT_ID_CTX0;
|
||||
break;
|
||||
case SYNX_CLIENT_HW_FENCE_IPE_CTX0 ... SYNX_CLIENT_HW_FENCE_IPE_CTX0 +
|
||||
SYNX_MAX_SIGNAL_PER_CLIENT - 1:
|
||||
hw_fence_client_id = synx_client_id - SYNX_CLIENT_HW_FENCE_IPE_CTX0 +
|
||||
HW_FENCE_CLIENT_ID_IPE;
|
||||
break;
|
||||
case SYNX_CLIENT_HW_FENCE_VID_CTX0 ... SYNX_CLIENT_HW_FENCE_VID_CTX0 +
|
||||
SYNX_MAX_SIGNAL_PER_CLIENT - 1:
|
||||
hw_fence_client_id = synx_client_id - SYNX_CLIENT_HW_FENCE_VID_CTX0 +
|
||||
HW_FENCE_CLIENT_ID_VPU;
|
||||
break;
|
||||
case SYNX_CLIENT_HW_FENCE_DPU0_CTL0 ... SYNX_CLIENT_HW_FENCE_DPU0_CTL0 + MAX_SUPPORTED_DPU0:
|
||||
hw_fence_client_id = synx_client_id - SYNX_CLIENT_HW_FENCE_DPU0_CTL0 +
|
||||
HW_FENCE_CLIENT_ID_CTL0;
|
||||
break;
|
||||
case SYNX_CLIENT_HW_FENCE_IFE0_CTX0 ... SYNX_CLIENT_HW_FENCE_IFE7_CTX0 +
|
||||
SYNX_MAX_SIGNAL_PER_CLIENT - 1:
|
||||
hw_fence_client_id = synx_client_id - SYNX_CLIENT_HW_FENCE_IFE0_CTX0 +
|
||||
HW_FENCE_CLIENT_ID_IFE0;
|
||||
break;
|
||||
default:
|
||||
HWFNC_ERR("Unsupported hw-fence client for synx_id:%d\n", synx_client_id);
|
||||
hw_fence_client_id = HW_FENCE_CLIENT_MAX;
|
||||
break;
|
||||
}
|
||||
|
||||
return hw_fence_client_id;
|
||||
}
|
||||
|
||||
static bool is_hw_fence_client(enum synx_client_id synx_client_id)
|
||||
{
|
||||
return synx_client_id >= SYNX_HW_FENCE_CLIENT_START
|
||||
&& synx_client_id < SYNX_HW_FENCE_CLIENT_END;
|
||||
}
|
||||
|
||||
struct synx_session *synx_hwfence_initialize(struct synx_initialization_params *params)
|
||||
{
|
||||
struct synx_session *session = NULL;
|
||||
enum hw_fence_client_id client_id;
|
||||
void *client_handle;
|
||||
|
||||
if (!hw_fence_driver_enable)
|
||||
return ERR_PTR(-SYNX_INVALID);
|
||||
|
||||
if (IS_ERR_OR_NULL(params) || IS_ERR_OR_NULL(params->ptr)) {
|
||||
HWFNC_ERR("invalid params:0x%pK params->ptr:0x%pK\n", params,
|
||||
IS_ERR_OR_NULL(params) ? NULL : params->ptr);
|
||||
return ERR_PTR(-SYNX_INVALID);
|
||||
}
|
||||
|
||||
client_id = _get_hw_fence_client_id(params->id);
|
||||
if (!is_hw_fence_client(params->id) || client_id == HW_FENCE_CLIENT_MAX) {
|
||||
HWFNC_ERR("Initializing session for invalid synx_id:%d\n", params->id);
|
||||
return ERR_PTR(-SYNX_INVALID);
|
||||
}
|
||||
|
||||
session = kzalloc(sizeof(struct synx_session), GFP_KERNEL);
|
||||
if (!session)
|
||||
return ERR_PTR(-SYNX_NOMEM);
|
||||
|
||||
client_handle = msm_hw_fence_register(client_id,
|
||||
(struct msm_hw_fence_mem_addr *)params->ptr);
|
||||
if (IS_ERR_OR_NULL(client_handle)) {
|
||||
kfree(session);
|
||||
HWFNC_ERR("failed to initialize synx_id:%d ret:%d\n", params->id,
|
||||
PTR_ERR(client_handle));
|
||||
return ERR_PTR(to_synx_status(PTR_ERR(client_handle)));
|
||||
}
|
||||
session->client = client_handle;
|
||||
session->type = params->id;
|
||||
HWFNC_DBG_INIT("initialized session synx_id:%d hw_fence_id:%d\n", params->id, client_id);
|
||||
|
||||
return session;
|
||||
}
|
||||
EXPORT_SYMBOL(synx_hwfence_initialize);
|
||||
|
||||
int synx_hwfence_uninitialize(struct synx_session *session)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (IS_ERR_OR_NULL(session) || !is_hw_fence_client(session->type)) {
|
||||
HWFNC_ERR("invalid session:0x%pK synx_id:%d\n", session,
|
||||
IS_ERR_OR_NULL(session) ? -1 : session->type);
|
||||
return -SYNX_INVALID;
|
||||
}
|
||||
|
||||
ret = msm_hw_fence_deregister(session->client);
|
||||
if (ret)
|
||||
HWFNC_ERR("Failed to deregister synx_id:%d ret:%d\n", session->type, ret);
|
||||
else
|
||||
kfree(session);
|
||||
|
||||
return to_synx_status(ret);
|
||||
}
|
||||
EXPORT_SYMBOL(synx_hwfence_uninitialize);
|
||||
|
||||
int synx_hwfence_create(struct synx_session *session, struct synx_create_params *params)
|
||||
{
|
||||
int ret = 0;
|
||||
struct msm_hw_fence_create_params hwfence_params;
|
||||
u64 handle;
|
||||
|
||||
if (IS_ERR_OR_NULL(session) || !is_hw_fence_client(session->type) ||
|
||||
IS_ERR_OR_NULL(params)) {
|
||||
HWFNC_ERR("invalid session:0x%pK synx_id:%d params:0x%pK\n", session,
|
||||
IS_ERR_OR_NULL(session) ? -1 : session->type, params);
|
||||
return -SYNX_INVALID;
|
||||
}
|
||||
|
||||
if (IS_ERR_OR_NULL(params->h_synx) || (params->flags != SYNX_CREATE_DMA_FENCE) ||
|
||||
IS_ERR_OR_NULL(params->fence)) {
|
||||
HWFNC_ERR("synx_id:%d invalid create params h_synx:0x%pK flags:0x%x fence:0x%pK\n",
|
||||
session->type, params->h_synx, params->flags, params->fence);
|
||||
return -SYNX_INVALID;
|
||||
}
|
||||
|
||||
hwfence_params.fence = params->fence;
|
||||
hwfence_params.handle = &handle;
|
||||
ret = msm_hw_fence_create(session->client, &hwfence_params);
|
||||
if (ret) {
|
||||
HWFNC_ERR("synx_id:%d failed create fence:0x%pK flags:0x%x ret:%d\n", session->type,
|
||||
params->fence, params->flags, ret);
|
||||
return to_synx_status(ret);
|
||||
}
|
||||
if (handle > U32_MAX) {
|
||||
HWFNC_ERR("synx_id:%d fence handle:%llu would overflow h_synx\n", session->type,
|
||||
handle);
|
||||
msm_hw_fence_destroy_with_handle(session->client, handle);
|
||||
return -SYNX_INVALID;
|
||||
}
|
||||
*params->h_synx = handle;
|
||||
|
||||
return SYNX_SUCCESS;
|
||||
}
|
||||
EXPORT_SYMBOL(synx_hwfence_create);
|
||||
|
||||
int synx_hwfence_release(struct synx_session *session, u32 h_synx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (IS_ERR_OR_NULL(session) || !is_hw_fence_client(session->type)) {
|
||||
HWFNC_ERR("invalid session:0x%pK synx_id:%d\n", session,
|
||||
IS_ERR_OR_NULL(session) ? -1 : session->type);
|
||||
return -SYNX_INVALID;
|
||||
}
|
||||
|
||||
ret = msm_hw_fence_destroy_with_handle(session->client, h_synx);
|
||||
if (ret)
|
||||
HWFNC_ERR("synx_id:%d failed to destroy fence h_synx:%u ret:%d\n", session->type,
|
||||
h_synx, ret);
|
||||
|
||||
return to_synx_status(ret);
|
||||
}
|
||||
EXPORT_SYMBOL(synx_hwfence_release);
|
||||
|
||||
int synx_hwfence_signal(struct synx_session *session, u32 h_synx, enum synx_signal_status status)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (IS_ERR_OR_NULL(session) || !is_hw_fence_client(session->type)) {
|
||||
HWFNC_ERR("invalid session:0x%pK synx_id:%d\n", session,
|
||||
IS_ERR_OR_NULL(session) ? -1 : session->type);
|
||||
return -SYNX_INVALID;
|
||||
}
|
||||
|
||||
ret = msm_hw_fence_update_txq(session->client, h_synx, 0, (u32)status);
|
||||
if (ret)
|
||||
HWFNC_ERR("synx_id:%d failed to signal fence h_synx:%u status:%d ret:%d\n",
|
||||
session->type, h_synx, status, ret);
|
||||
|
||||
return to_synx_status(ret);
|
||||
}
|
||||
EXPORT_SYMBOL(synx_hwfence_signal);
|
||||
|
||||
int synx_hwfence_recover(enum synx_client_id id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!is_hw_fence_client(id)) {
|
||||
HWFNC_ERR("invalid synx_id:%d\n", id);
|
||||
return -SYNX_INVALID;
|
||||
}
|
||||
|
||||
ret = msm_hw_fence_reset_client_by_id(_get_hw_fence_client_id(id),
|
||||
MSM_HW_FENCE_RESET_WITHOUT_DESTROY);
|
||||
if (ret)
|
||||
HWFNC_ERR("synx_id:%d failed to recover ret:%d\n", id, ret);
|
||||
|
||||
return to_synx_status(ret);
|
||||
}
|
||||
EXPORT_SYMBOL(synx_hwfence_recover);
|
||||
|
||||
static int synx_hwfence_import_indv(void *client, struct synx_import_indv_params *params)
|
||||
{
|
||||
u64 handle;
|
||||
int ret;
|
||||
|
||||
if (IS_ERR_OR_NULL(client) || IS_ERR_OR_NULL(params) ||
|
||||
IS_ERR_OR_NULL(params->new_h_synx) ||
|
||||
(params->flags != SYNX_IMPORT_DMA_FENCE) || IS_ERR_OR_NULL(params->fence)) {
|
||||
HWFNC_ERR("invalid client:0x%pK params:0x%pK h_synx:0x%pK flags:0x%x fence:0x%pK\n",
|
||||
client, params, IS_ERR_OR_NULL(params) ? NULL : params->new_h_synx,
|
||||
IS_ERR_OR_NULL(params) ? 0 : params->flags,
|
||||
IS_ERR_OR_NULL(params) ? NULL : params->fence);
|
||||
return -SYNX_INVALID;
|
||||
}
|
||||
|
||||
ret = msm_hw_fence_wait_update_v2(client, (struct dma_fence **)¶ms->fence, &handle,
|
||||
NULL, 1, true);
|
||||
if (ret) {
|
||||
HWFNC_ERR("failed to import fence:0x%pK flags:0x%x ret:%d\n", params->fence,
|
||||
params->flags, ret);
|
||||
return to_synx_status(ret);
|
||||
}
|
||||
if (handle > U32_MAX) {
|
||||
HWFNC_ERR("fence handle:%llu would overflow new_h_synx\n", handle);
|
||||
msm_hw_fence_wait_update_v2(client, (struct dma_fence **)¶ms->fence, &handle,
|
||||
NULL, 1, false);
|
||||
return -SYNX_INVALID;
|
||||
}
|
||||
*params->new_h_synx = handle;
|
||||
|
||||
return SYNX_SUCCESS;
|
||||
}
|
||||
|
||||
static int synx_hwfence_import_arr(void *client, struct synx_import_arr_params *params)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
if (IS_ERR_OR_NULL(client) || IS_ERR_OR_NULL(params) || !params->num_fences) {
|
||||
HWFNC_ERR("invalid import arr client:0x%pK params:0x%pK num_fences:%u\n", client,
|
||||
params, IS_ERR_OR_NULL(params) ? -1 : params->num_fences);
|
||||
return -SYNX_INVALID;
|
||||
}
|
||||
|
||||
for (i = 0; i < params->num_fences; i++) {
|
||||
ret = synx_hwfence_import_indv(client, ¶ms->list[i]);
|
||||
if (ret) {
|
||||
HWFNC_ERR("importing fence[%u] 0x%pK failed ret:%d\n", i,
|
||||
params->list[i].fence, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return SYNX_SUCCESS;
|
||||
}
|
||||
|
||||
int synx_hwfence_import(struct synx_session *session, struct synx_import_params *params)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (IS_ERR_OR_NULL(session) || !is_hw_fence_client(session->type)
|
||||
|| IS_ERR_OR_NULL(params)) {
|
||||
HWFNC_ERR("invalid session:0x%pK synx_id:%d params:0x%pK\n", session,
|
||||
IS_ERR_OR_NULL(session) ? -1 : session->type, params);
|
||||
return -SYNX_INVALID;
|
||||
}
|
||||
|
||||
if (params->type == SYNX_IMPORT_ARR_PARAMS)
|
||||
ret = synx_hwfence_import_arr(session->client, ¶ms->arr);
|
||||
else
|
||||
ret = synx_hwfence_import_indv(session->client, ¶ms->indv);
|
||||
|
||||
if (ret)
|
||||
HWFNC_ERR("synx_id:%d failed to import type:%s fences ret:%d\n", session->type,
|
||||
(params->type == SYNX_IMPORT_ARR_PARAMS) ? "arr" : "indv", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(synx_hwfence_import);
|
In neuem Issue referenzieren
Einen Benutzer sperren