tegra: dce: Add IPC event notification support

- This change adds support for new IPC type
DCE_IPC_TYPE_RM_NOTIFY wrt event notification from
DCE RM

JIRA TDS-6643

Change-Id: I54b22e3fa86a1dab552f78d609c374d14ce619ad
Signed-off-by: Mahesh Kumar <mahkumar@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-t23x/+/2409904
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Santosh Galma <galmar@nvidia.com>
Reviewed-by: Arun Swain <arswain@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
Tested-by: Santosh Galma <galmar@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Mahesh Kumar
2020-09-01 17:10:15 +05:30
committed by Laxman Dewangan
parent f452d16f44
commit 9764cf5370
8 changed files with 115 additions and 31 deletions

View File

@@ -25,6 +25,7 @@ struct tegra_dce_client_ipc client_handles[DCE_CLIENT_IPC_TYPE_MAX];
static uint32_t dce_interface_type_map[DCE_CLIENT_IPC_TYPE_MAX] = {
[DCE_CLIENT_IPC_TYPE_CPU_RM] = DCE_IPC_TYPE_DISPRM,
[DCE_CLIENT_IPC_TYPE_HDCP_KMD] = DCE_IPC_TYPE_HDCP,
[DCE_CLIENT_IPC_TYPE_RM_EVENT] = DCE_IPC_TYPE_RM_NOTIFY,
};
static inline uint32_t dce_client_get_type(uint32_t int_type)
@@ -146,6 +147,7 @@ int tegra_dce_register_ipc_client(u32 type,
cl->d = d;
cl->type = type;
cl->data = data;
cl->handle = handle;
cl->int_type = int_type;
cl->callback_fn = callback_fn;
atomic_set(&cl->complete, 0);
@@ -251,6 +253,39 @@ int dce_client_ipc_wait(struct tegra_dce *d, u32 w_type, u32 ch_type)
return ret;
}
static void dce_client_process_event_ipc(struct tegra_dce *d,
struct tegra_dce_client_ipc *cl)
{
void *msg_data = NULL;
u32 msg_length;
int ret = 0;
if ((cl == NULL) || (cl->callback_fn == NULL) ||
(cl->type != DCE_CLIENT_IPC_TYPE_RM_EVENT)) {
dce_err(d, "Invalid arg for DCE_CLIENT_IPC_TYPE_RM_EVENT type:[%u]", cl->type);
return;
}
msg_data = dce_kzalloc(d, DCE_CLIENT_MAX_IPC_MSG_SIZE, false);
if (msg_data == NULL) {
dce_err(d, "Could not allocate msg read buffer");
goto done;
}
msg_length = DCE_CLIENT_MAX_IPC_MSG_SIZE;
ret = dce_ipc_read_message(d, cl->int_type, msg_data, msg_length);
if (ret) {
dce_err(d, "Error in reading DCE msg for ch_type [%d]",
cl->int_type);
goto done;
}
cl->callback_fn(cl->handle, cl->type, msg_length, msg_data, cl->data);
done:
if (msg_data)
dce_kfree(d, msg_data);
}
void dce_client_ipc_wakeup(struct tegra_dce *d, u32 ch_type)
{
uint32_t type;
@@ -270,6 +305,9 @@ void dce_client_ipc_wakeup(struct tegra_dce *d, u32 ch_type)
return;
}
if (type == DCE_CLIENT_IPC_TYPE_RM_EVENT)
return dce_client_process_event_ipc(d, cl);
atomic_set(&cl->complete, 1);
dce_cond_signal_interruptible(&cl->recv_wait);
}

View File

@@ -438,10 +438,10 @@ int dump_hsp_regs_show(struct seq_file *s, void *unused)
dce_smb_read(d, DCE_MBOX_FROM_DCE_RM));
dce_info(d, "DCE_MBOX_TO_DCE_RM: 0x%x",
dce_smb_read(d, DCE_MBOX_TO_DCE_RM));
dce_info(d, "DCE_MBOX_FROM_BPMP: 0x%x",
dce_smb_read(d, DCE_MBOX_FROM_BPMP));
dce_info(d, "DCE_MBOX_TO_BPMP: 0x%x",
dce_smb_read(d, DCE_MBOX_TO_BPMP));
dce_info(d, "DCE_MBOX_FROM_DCE_RM_EVENT_NOTIFY: 0x%x",
dce_smb_read(d, DCE_MBOX_FROM_DCE_RM_EVENT_NOTIFY));
dce_info(d, "DCE_MBOX_TO_DCE_RM_EVENT_NOTIFY: 0x%x",
dce_smb_read(d, DCE_MBOX_TO_DCE_RM_EVENT_NOTIFY));
dce_info(d, "DCE_MBOX_FROM_DCE_ADMIN: 0x%x",
dce_smb_read(d, DCE_MBOX_FROM_DCE_ADMIN));
dce_info(d, "DCE_MBOX_BOOT_CMD: 0x%x",

View File

@@ -95,6 +95,43 @@ struct dce_ipc_channel ivc_channels[DCE_IPC_CH_KMD_TYPE_MAX] = {
.frame_sz = DCE_DISPRM_CMD_MAX_FSIZE,
},
},
[DCE_IPC_CH_KMD_TYPE_RM_NOTIFY] = {
.flags = DCE_IPC_CHANNEL_VALID,
.ch_type = DCE_IPC_CH_KMD_TYPE_RM_NOTIFY,
.ipc_type = DCE_IPC_TYPE_RM_NOTIFY,
.signal = {
.to_d = {
.type = DCE_IPC_SIGNAL_MAILBOX,
.sema_num = DCE_NUM_SEMA_REGS,
.sema_bit = 0U,
.form = {
.mbox = {
.mb_type = DCE_MAILBOX_DISPRM_NOTIFY_INTERFACE,
.mb_num = DCE_MBOX_FROM_DCE_RM_EVENT_NOTIFY,
},
},
.signal = NULL,
.next = NULL,
},
.from_d = {
.type = DCE_IPC_SIGNAL_MAILBOX,
.sema_num = DCE_NUM_SEMA_REGS,
.sema_bit = 0U,
.form = {
.mbox = {
.mb_type = DCE_MAILBOX_DISPRM_NOTIFY_INTERFACE,
.mb_num = DCE_MBOX_TO_DCE_RM_EVENT_NOTIFY,
},
},
.signal = NULL,
.next = NULL,
},
},
.q_info = {
.nframes = DCE_DISPRM_EVENT_NOTIFY_CMD_MAX_NFRAMES,
.frame_sz = DCE_DISPRM_EVENT_NOTIFY_CMD_MAX_FSIZE,
},
},
};
/**

View File

@@ -24,6 +24,7 @@
* @data : Pointer to any specific data passed by client during registration
* for corresponding IPC type
* @type : Corresponding IPC type as defined in CPU driver
* @handle : Corresponding handle allocated for client during registration
* @int_type : IPC interface type for above IPC type as defined in CPU driver
* @d : pointer to OS agnostic dce struct. Stores all runtime info for dce
* cluster elements
@@ -36,6 +37,7 @@ struct tegra_dce_client_ipc {
bool valid;
void *data;
uint32_t type;
uint32_t handle;
uint32_t int_type;
struct tegra_dce *d;
struct dce_cond recv_wait;

View File

@@ -25,13 +25,15 @@
#define DCE_IPC_CHANNEL_TYPE_ADMIN 0U
#define DCE_IPC_CHANNEL_TYPE_CPU_CLIENTS 1U
#define DCE_IPC_MAX_IVC_CHANNELS 2U
#define DCE_IPC_MAX_IVC_CHANNELS 4U
/**
* TODO : Move the DispRM max to a config file
*/
#define DCE_DISPRM_CMD_MAX_NFRAMES 1U
#define DCE_DISPRM_CMD_MAX_FSIZE 4096U
#define DCE_DISPRM_EVENT_NOTIFY_CMD_MAX_NFRAMES 1U
#define DCE_DISPRM_EVENT_NOTIFY_CMD_MAX_FSIZE 4096U
#define DCE_ADMIN_CMD_MAX_FSIZE 1024U
#define DCE_IPC_WAIT_TYPE_INVALID 0U
@@ -46,7 +48,8 @@
#define DCE_IPC_CH_KMD_TYPE_ADMIN 0U
#define DCE_IPC_CH_KMD_TYPE_RM 1U
#define DCE_IPC_CH_KMD_TYPE_HDCP 2U
#define DCE_IPC_CH_KMD_TYPE_MAX 3U
#define DCE_IPC_CH_KMD_TYPE_RM_NOTIFY 3U
#define DCE_IPC_CH_KMD_TYPE_MAX 4U
/**
* struct dce_ipc_signal - Stores ivc channel details
*

View File

@@ -19,7 +19,8 @@ struct tegra_dce;
#define DCE_MAILBOX_BOOT_INTERFACE 0U
#define DCE_MAILBOX_ADMIN_INTERFACE 1U
#define DCE_MAILBOX_DISPRM_INTERFACE 2U
#define DCE_MAILBOX_MAX_INTERFACES 3U
#define DCE_MAILBOX_DISPRM_NOTIFY_INTERFACE 3U
#define DCE_MAILBOX_MAX_INTERFACES 4U
/**
* struct dce_mailbox_interface - Contains dce mailbox interface state info

View File

@@ -71,8 +71,8 @@ typedef uint32_t hsp_mbox_t;
#define DCE_MBOX_FROM_DCE_RM (hsp_mbox_t)0U // signal from RM IPC
#define DCE_MBOX_TO_DCE_RM (hsp_mbox_t)1U // signal to RM IPC
#define DCE_MBOX_FROM_BPMP (hsp_mbox_t)2U // signal from BPMP IPC
#define DCE_MBOX_TO_BPMP (hsp_mbox_t)3U // signal to BPMP IPC
#define DCE_MBOX_FROM_DCE_RM_EVENT_NOTIFY (hsp_mbox_t)2U // signal to DCE for event notification
#define DCE_MBOX_TO_DCE_RM_EVENT_NOTIFY (hsp_mbox_t)3U // signal from DCE for event notification IPC
#define DCE_MBOX_FROM_DCE_ADMIN (hsp_mbox_t)4U // signal from DCE ADMIN IPC
#define DCE_MBOX_TO_DCE_ADMIN (hsp_mbox_t)5U // signal to ADMIN IPC
#define DCE_MBOX_BOOT_CMD (hsp_mbox_t)6U // boot commands

View File

@@ -16,7 +16,10 @@
#define DCE_CLIENT_IPC_TYPE_CPU_RM 0U
#define DCE_CLIENT_IPC_TYPE_HDCP_KMD 1U
#define DCE_CLIENT_IPC_TYPE_MAX 2U
#define DCE_CLIENT_IPC_TYPE_RM_EVENT 2U
#define DCE_CLIENT_IPC_TYPE_MAX 3U
#define DCE_CLIENT_MAX_IPC_MSG_SIZE 4096
/**
* struct dce_ipc_message - Contains necessary info for an ipc msg.