Loading drivers/media/platform/msm/sde/rotator/sde_rotator_core.c +37 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,9 @@ /* waiting for hw time out, 3 vsync for 30fps*/ #define ROT_HW_ACQUIRE_TIMEOUT_IN_MS 100 /* waiting for inline hw start */ #define ROT_INLINE_START_TIMEOUT_IN_MS 2000 /* default pixel per clock ratio */ #define ROT_PIXEL_PER_CLK_NUMERATOR 36 #define ROT_PIXEL_PER_CLK_DENOMINATOR 10 Loading Loading @@ -1508,6 +1511,8 @@ static void sde_rotator_commit_handler(struct work_struct *work) if (entry->item.ts) entry->item.ts[SDE_ROTATOR_TS_FLUSH] = ktime_get(); SDEROT_EVTLOG(entry->item.session_id, 1); queue_work(entry->doneq->rot_work_queue, &entry->done_work); sde_rot_mgr_unlock(mgr); return; Loading Loading @@ -1564,6 +1569,13 @@ static void sde_rotator_done_handler(struct work_struct *work) entry->item.flags, entry->dnsc_factor_w, entry->dnsc_factor_h); wait_for_completion_timeout( &entry->item.inline_start, msecs_to_jiffies(ROT_INLINE_START_TIMEOUT_IN_MS)); if (entry->item.ts) entry->item.ts[SDE_ROTATOR_TS_START] = ktime_get(); SDEROT_EVTLOG(entry->item.session_id, 0); ret = mgr->ops_wait_for_entry(hw, entry); if (ret) { Loading Loading @@ -2332,11 +2344,36 @@ struct sde_rot_entry_container *sde_rotator_req_init( for (i = 0; i < count; i++) { req->entries[i].item = items[i]; req->entries[i].private = private; init_completion(&req->entries[i].item.inline_start); complete_all(&req->entries[i].item.inline_start); } return req; } void sde_rotator_req_reset_start(struct sde_rot_entry_container *req) { int i; if (!req) return; for (i = 0; i < req->count; i++) reinit_completion(&req->entries[i].item.inline_start); } void sde_rotator_req_set_start(struct sde_rot_entry_container *req) { int i; if (!req) return; for (i = 0; i < req->count; i++) complete_all(&req->entries[i].item.inline_start); } void sde_rotator_req_finish(struct sde_rot_mgr *mgr, struct sde_rot_file_private *private, struct sde_rot_entry_container *req) Loading drivers/media/platform/msm/sde/rotator/sde_rotator_core.h +22 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <linux/types.h> #include <linux/cdev.h> #include <linux/pm_runtime.h> #include <linux/completion.h> #include "sde_rotator_base.h" #include "sde_rotator_util.h" Loading Loading @@ -115,6 +116,7 @@ enum sde_rotator_ts { SDE_ROTATOR_TS_QUEUE, /* wait for h/w resource */ SDE_ROTATOR_TS_COMMIT, /* prepare h/w command */ SDE_ROTATOR_TS_FLUSH, /* initiate h/w processing */ SDE_ROTATOR_TS_START, /* h/w triggered (if inline) */ SDE_ROTATOR_TS_DONE, /* receive h/w completion */ SDE_ROTATOR_TS_RETIRE, /* signal destination buffer fence */ SDE_ROTATOR_TS_SRCDQB, /* dequeue source buffer */ Loading Loading @@ -199,6 +201,9 @@ struct sde_rotation_item { /* Time stamp for profiling purposes */ ktime_t *ts; /* Completion structure for inline rotation */ struct completion inline_start; }; /* Loading Loading @@ -603,6 +608,23 @@ struct sde_rot_entry_container *sde_rotator_req_init( struct sde_rotation_item *items, u32 count, u32 flags); /* * sde_rotator_req_reset_start - reset inline h/w 'start' indicator * For inline rotations, the time of rotation start is not controlled * by the rotator driver. This function resets an internal 'start' * indicator that allows the rotator to delay its rotator * timeout waiting until such time as the inline rotation has * really started. * @req: Pointer to rotation request */ void sde_rotator_req_reset_start(struct sde_rot_entry_container *req); /* * sde_rotator_req_set_start - set inline h/w 'start' indicator * @req: Pointer to rotation request */ void sde_rotator_req_set_start(struct sde_rot_entry_container *req); /* * sde_rotator_req_finish - notify manager that client is finished with the * given request and manager can release the request as required Loading drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c +4 −2 Original line number Diff line number Diff line Loading @@ -789,7 +789,7 @@ static int sde_rotator_stat_show(struct seq_file *s, void *data) start_time)); seq_printf(s, "s:%d sq:%lld dq:%lld fe:%lld q:%lld c:%lld fl:%lld d:%lld sdq:%lld ddq:%lld t:%lld oht:%lld\n", "s:%d sq:%lld dq:%lld fe:%lld q:%lld c:%lld fl:%lld st:%lld d:%lld sdq:%lld ddq:%lld t:%lld oht:%lld\n", i, ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_FENCE], ts[SDE_ROTATOR_TS_SRCQB])), Loading @@ -801,8 +801,10 @@ static int sde_rotator_stat_show(struct seq_file *s, void *data) ts[SDE_ROTATOR_TS_QUEUE])), ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_FLUSH], ts[SDE_ROTATOR_TS_COMMIT])), ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_DONE], ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_START], ts[SDE_ROTATOR_TS_FLUSH])), ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_DONE], ts[SDE_ROTATOR_TS_START])), ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_RETIRE], ts[SDE_ROTATOR_TS_DONE])), ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_SRCDQB], Loading drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c +12 −1 Original line number Diff line number Diff line Loading @@ -1467,7 +1467,9 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd, int scid = llcc_get_slice_id(ctx->slice); /* allocate slot for timestamp */ ts = stats->ts[stats->count++ % SDE_ROTATOR_NUM_EVENTS]; ts = stats->ts[stats->count % SDE_ROTATOR_NUM_EVENTS]; if (cmd_type == SDE_ROTATOR_INLINE_CMD_COMMIT) stats->count++; if (cmd->rot90) flags |= SDE_ROTATION_90; Loading Loading @@ -1644,6 +1646,15 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd, /* save request in private handle */ cmd->priv_handle = request; } else if (cmd_type == SDE_ROTATOR_INLINE_CMD_START) { if (!cmd->priv_handle) { ret = -EINVAL; SDEROT_ERR("invalid private handle\n"); goto error_invalid_handle; } request = cmd->priv_handle; sde_rotator_req_set_start(request->req); } else if (cmd_type == SDE_ROTATOR_INLINE_CMD_CLEANUP) { if (!cmd->priv_handle) { ret = -EINVAL; Loading drivers/media/platform/msm/sde/rotator/sde_rotator_inline.h +2 −0 Original line number Diff line number Diff line Loading @@ -25,11 +25,13 @@ * enum sde_rotator_inline_cmd_type - inline rotator command stages * @SDE_ROTATOR_INLINE_CMD_VALIDATE: validate command only * @SDE_ROTATOR_INLINE_CMD_COMMIT: commit command to hardware * @SDE_ROTATOR_INLINE_CMD_START: ready to start inline rotation * @SDE_ROTATOR_INLINE_CMD_CLEANUP: cleanup after commit is done */ enum sde_rotator_inline_cmd_type { SDE_ROTATOR_INLINE_CMD_VALIDATE, SDE_ROTATOR_INLINE_CMD_COMMIT, SDE_ROTATOR_INLINE_CMD_START, SDE_ROTATOR_INLINE_CMD_CLEANUP, }; Loading Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_core.c +37 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,9 @@ /* waiting for hw time out, 3 vsync for 30fps*/ #define ROT_HW_ACQUIRE_TIMEOUT_IN_MS 100 /* waiting for inline hw start */ #define ROT_INLINE_START_TIMEOUT_IN_MS 2000 /* default pixel per clock ratio */ #define ROT_PIXEL_PER_CLK_NUMERATOR 36 #define ROT_PIXEL_PER_CLK_DENOMINATOR 10 Loading Loading @@ -1508,6 +1511,8 @@ static void sde_rotator_commit_handler(struct work_struct *work) if (entry->item.ts) entry->item.ts[SDE_ROTATOR_TS_FLUSH] = ktime_get(); SDEROT_EVTLOG(entry->item.session_id, 1); queue_work(entry->doneq->rot_work_queue, &entry->done_work); sde_rot_mgr_unlock(mgr); return; Loading Loading @@ -1564,6 +1569,13 @@ static void sde_rotator_done_handler(struct work_struct *work) entry->item.flags, entry->dnsc_factor_w, entry->dnsc_factor_h); wait_for_completion_timeout( &entry->item.inline_start, msecs_to_jiffies(ROT_INLINE_START_TIMEOUT_IN_MS)); if (entry->item.ts) entry->item.ts[SDE_ROTATOR_TS_START] = ktime_get(); SDEROT_EVTLOG(entry->item.session_id, 0); ret = mgr->ops_wait_for_entry(hw, entry); if (ret) { Loading Loading @@ -2332,11 +2344,36 @@ struct sde_rot_entry_container *sde_rotator_req_init( for (i = 0; i < count; i++) { req->entries[i].item = items[i]; req->entries[i].private = private; init_completion(&req->entries[i].item.inline_start); complete_all(&req->entries[i].item.inline_start); } return req; } void sde_rotator_req_reset_start(struct sde_rot_entry_container *req) { int i; if (!req) return; for (i = 0; i < req->count; i++) reinit_completion(&req->entries[i].item.inline_start); } void sde_rotator_req_set_start(struct sde_rot_entry_container *req) { int i; if (!req) return; for (i = 0; i < req->count; i++) complete_all(&req->entries[i].item.inline_start); } void sde_rotator_req_finish(struct sde_rot_mgr *mgr, struct sde_rot_file_private *private, struct sde_rot_entry_container *req) Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_core.h +22 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <linux/types.h> #include <linux/cdev.h> #include <linux/pm_runtime.h> #include <linux/completion.h> #include "sde_rotator_base.h" #include "sde_rotator_util.h" Loading Loading @@ -115,6 +116,7 @@ enum sde_rotator_ts { SDE_ROTATOR_TS_QUEUE, /* wait for h/w resource */ SDE_ROTATOR_TS_COMMIT, /* prepare h/w command */ SDE_ROTATOR_TS_FLUSH, /* initiate h/w processing */ SDE_ROTATOR_TS_START, /* h/w triggered (if inline) */ SDE_ROTATOR_TS_DONE, /* receive h/w completion */ SDE_ROTATOR_TS_RETIRE, /* signal destination buffer fence */ SDE_ROTATOR_TS_SRCDQB, /* dequeue source buffer */ Loading Loading @@ -199,6 +201,9 @@ struct sde_rotation_item { /* Time stamp for profiling purposes */ ktime_t *ts; /* Completion structure for inline rotation */ struct completion inline_start; }; /* Loading Loading @@ -603,6 +608,23 @@ struct sde_rot_entry_container *sde_rotator_req_init( struct sde_rotation_item *items, u32 count, u32 flags); /* * sde_rotator_req_reset_start - reset inline h/w 'start' indicator * For inline rotations, the time of rotation start is not controlled * by the rotator driver. This function resets an internal 'start' * indicator that allows the rotator to delay its rotator * timeout waiting until such time as the inline rotation has * really started. * @req: Pointer to rotation request */ void sde_rotator_req_reset_start(struct sde_rot_entry_container *req); /* * sde_rotator_req_set_start - set inline h/w 'start' indicator * @req: Pointer to rotation request */ void sde_rotator_req_set_start(struct sde_rot_entry_container *req); /* * sde_rotator_req_finish - notify manager that client is finished with the * given request and manager can release the request as required Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c +4 −2 Original line number Diff line number Diff line Loading @@ -789,7 +789,7 @@ static int sde_rotator_stat_show(struct seq_file *s, void *data) start_time)); seq_printf(s, "s:%d sq:%lld dq:%lld fe:%lld q:%lld c:%lld fl:%lld d:%lld sdq:%lld ddq:%lld t:%lld oht:%lld\n", "s:%d sq:%lld dq:%lld fe:%lld q:%lld c:%lld fl:%lld st:%lld d:%lld sdq:%lld ddq:%lld t:%lld oht:%lld\n", i, ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_FENCE], ts[SDE_ROTATOR_TS_SRCQB])), Loading @@ -801,8 +801,10 @@ static int sde_rotator_stat_show(struct seq_file *s, void *data) ts[SDE_ROTATOR_TS_QUEUE])), ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_FLUSH], ts[SDE_ROTATOR_TS_COMMIT])), ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_DONE], ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_START], ts[SDE_ROTATOR_TS_FLUSH])), ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_DONE], ts[SDE_ROTATOR_TS_START])), ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_RETIRE], ts[SDE_ROTATOR_TS_DONE])), ktime_to_us(ktime_sub(ts[SDE_ROTATOR_TS_SRCDQB], Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_dev.c +12 −1 Original line number Diff line number Diff line Loading @@ -1467,7 +1467,9 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd, int scid = llcc_get_slice_id(ctx->slice); /* allocate slot for timestamp */ ts = stats->ts[stats->count++ % SDE_ROTATOR_NUM_EVENTS]; ts = stats->ts[stats->count % SDE_ROTATOR_NUM_EVENTS]; if (cmd_type == SDE_ROTATOR_INLINE_CMD_COMMIT) stats->count++; if (cmd->rot90) flags |= SDE_ROTATION_90; Loading Loading @@ -1644,6 +1646,15 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd, /* save request in private handle */ cmd->priv_handle = request; } else if (cmd_type == SDE_ROTATOR_INLINE_CMD_START) { if (!cmd->priv_handle) { ret = -EINVAL; SDEROT_ERR("invalid private handle\n"); goto error_invalid_handle; } request = cmd->priv_handle; sde_rotator_req_set_start(request->req); } else if (cmd_type == SDE_ROTATOR_INLINE_CMD_CLEANUP) { if (!cmd->priv_handle) { ret = -EINVAL; Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_inline.h +2 −0 Original line number Diff line number Diff line Loading @@ -25,11 +25,13 @@ * enum sde_rotator_inline_cmd_type - inline rotator command stages * @SDE_ROTATOR_INLINE_CMD_VALIDATE: validate command only * @SDE_ROTATOR_INLINE_CMD_COMMIT: commit command to hardware * @SDE_ROTATOR_INLINE_CMD_START: ready to start inline rotation * @SDE_ROTATOR_INLINE_CMD_CLEANUP: cleanup after commit is done */ enum sde_rotator_inline_cmd_type { SDE_ROTATOR_INLINE_CMD_VALIDATE, SDE_ROTATOR_INLINE_CMD_COMMIT, SDE_ROTATOR_INLINE_CMD_START, SDE_ROTATOR_INLINE_CMD_CLEANUP, }; Loading