diff --git a/drivers/platform/tegra/dce/dce-client-ipc.c b/drivers/platform/tegra/dce/dce-client-ipc.c index 7aec264e..57b4bbc5 100644 --- a/drivers/platform/tegra/dce/dce-client-ipc.c +++ b/drivers/platform/tegra/dce/dce-client-ipc.c @@ -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); } diff --git a/drivers/platform/tegra/dce/dce-debug.c b/drivers/platform/tegra/dce/dce-debug.c index cb34ec18..5f8e7877 100644 --- a/drivers/platform/tegra/dce/dce-debug.c +++ b/drivers/platform/tegra/dce/dce-debug.c @@ -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", diff --git a/drivers/platform/tegra/dce/dce-ipc.c b/drivers/platform/tegra/dce/dce-ipc.c index cdef4b49..6f0e4ef4 100644 --- a/drivers/platform/tegra/dce/dce-ipc.c +++ b/drivers/platform/tegra/dce/dce-ipc.c @@ -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, + }, + }, }; /** diff --git a/drivers/platform/tegra/dce/include/dce-client-ipc-internal.h b/drivers/platform/tegra/dce/include/dce-client-ipc-internal.h index c9ea161e..171ef4ef 100644 --- a/drivers/platform/tegra/dce/include/dce-client-ipc-internal.h +++ b/drivers/platform/tegra/dce/include/dce-client-ipc-internal.h @@ -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; diff --git a/drivers/platform/tegra/dce/include/dce-ipc.h b/drivers/platform/tegra/dce/include/dce-ipc.h index d39ab07b..5dadbc1d 100644 --- a/drivers/platform/tegra/dce/include/dce-ipc.h +++ b/drivers/platform/tegra/dce/include/dce-ipc.h @@ -25,14 +25,16 @@ #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_ADMIN_CMD_MAX_FSIZE 1024U +#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 #define DCE_IPC_WAIT_TYPE_SYNC 1U @@ -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 * diff --git a/drivers/platform/tegra/dce/include/dce-mailbox.h b/drivers/platform/tegra/dce/include/dce-mailbox.h index e4c05d2b..dc794a04 100644 --- a/drivers/platform/tegra/dce/include/dce-mailbox.h +++ b/drivers/platform/tegra/dce/include/dce-mailbox.h @@ -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 diff --git a/drivers/platform/tegra/dce/include/interface/dce-interface.h b/drivers/platform/tegra/dce/include/interface/dce-interface.h index b8b9c0c1..16d961f9 100644 --- a/drivers/platform/tegra/dce/include/interface/dce-interface.h +++ b/drivers/platform/tegra/dce/include/interface/dce-interface.h @@ -46,18 +46,18 @@ typedef uint32_t hsp_sema_t; /* * Bits set by the R5 and examined by the OS */ -#define DCE_BOOT_TCM_COPY DCE_BIT(15) // uCode has copied to TCM -#define DCE_BOOT_HW_INIT DCE_BIT(14) // hardware init complete -#define DCE_BOOT_MPU_INIT DCE_BIT(13) // MPU initialized -#define DCE_BOOT_CACHE_INIT DCE_BIT(12) // cache initialized -#define DCE_BOOT_R5_INIT DCE_BIT(11) // R5 initialized -#define DCE_BOOT_DRIVER_INIT DCE_BIT(10) // driver init complete -#define DCE_BOOT_MAIN_STARTED DCE_BIT(9) // main started -#define DCE_BOOT_TASK_INIT_START DCE_BIT(8) // task initialization started -#define DCE_BOOT_TASK_INIT_DONE DCE_BIT(7) // task initialization complete +#define DCE_BOOT_TCM_COPY DCE_BIT(15) // uCode has copied to TCM +#define DCE_BOOT_HW_INIT DCE_BIT(14) // hardware init complete +#define DCE_BOOT_MPU_INIT DCE_BIT(13) // MPU initialized +#define DCE_BOOT_CACHE_INIT DCE_BIT(12) // cache initialized +#define DCE_BOOT_R5_INIT DCE_BIT(11) // R5 initialized +#define DCE_BOOT_DRIVER_INIT DCE_BIT(10) // driver init complete +#define DCE_BOOT_MAIN_STARTED DCE_BIT(9) // main started +#define DCE_BOOT_TASK_INIT_START DCE_BIT(8) // task initialization started +#define DCE_BOOT_TASK_INIT_DONE DCE_BIT(7) // task initialization complete -#define DCE_HALTED DCE_BIT(1) // uCode has halted -#define DCE_BOOT_COMPLETE DCE_BIT(0) // uCode boot has completed +#define DCE_HALTED DCE_BIT(1) // uCode has halted +#define DCE_BOOT_COMPLETE DCE_BIT(0) // uCode boot has completed /* * Symbolic definitions of the doorbell registers @@ -69,14 +69,14 @@ typedef uint32_t hsp_sema_t; */ 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_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 -#define DCE_MBOX_IRQ (hsp_mbox_t)7U // general interrupt/status +#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_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 +#define DCE_MBOX_IRQ (hsp_mbox_t)7U // general interrupt/status /* * Generic interrupts & status from the DCE are reported in DCE_MBOX_IRQ */ diff --git a/include/linux/platform/tegra/dce/dce-client-ipc.h b/include/linux/platform/tegra/dce/dce-client-ipc.h index a2e147b8..341dc0ab 100644 --- a/include/linux/platform/tegra/dce/dce-client-ipc.h +++ b/include/linux/platform/tegra/dce/dce-client-ipc.h @@ -15,8 +15,11 @@ #define TEGRA_DCE_CLIENT_IPC_H #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_HDCP_KMD 1U +#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.