Loading Documentation/devicetree/bindings/media/video/msm-sde-rotator.txt +15 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ Required properties - clocks: List of Phandles for clock device nodes needed by the device. - clock-names: List of clock names needed by the device. - #list-cells: Number of rotator cells, must be 1 Bus Scaling Data: - qcom,msm-bus,name: String property describing rotator client. - qcom,msm-bus,num-cases: This is the the number of Bus Scaling use cases Loading Loading @@ -81,6 +83,12 @@ Optional properties priority for rotator clients. - qcom,mdss-rot-mode: This is integer value indicates operation mode of the rotator device - qcom,mdss-sbuf-headroom: This integer value indicates stream buffer headroom in lines. - cache-slice-names: A set of names that identify the usecase names of a client that uses cache slice. These strings are used to look up the cache slice entries by name. - cache-slices: The tuple has phandle to llcc device as the first argument and the second argument is the usecase id of the client. Subnode properties: - compatible: Compatible name used in smmu v2. Loading @@ -102,6 +110,9 @@ Example: reg = <0xfd900000 0x22100>, <0xfd925000 0x1000>; reg-names = "mdp_phys", "rot_vbif_phys"; #list-cells = <1>; interrupt-parent = <&mdss_mdp>; interrupts = <2 0>; Loading Loading @@ -131,6 +142,10 @@ Example: qcom,mdss-default-ot-rd-limit = <8>; qcom,mdss-default-ot-wr-limit = <16>; qcom,mdss-sbuf-headroom = <20>; cache-slice-names = "rotator"; cache-slices = <&llcc 3>; smmu_rot_unsec: qcom,smmu_rot_unsec_cb { compatible = "qcom,smmu_sde_rot_unsec"; iommus = <&mdp_smmu 0xe00>; Loading drivers/media/platform/msm/sde/rotator/sde_rotator_base.h +2 −0 Original line number Diff line number Diff line Loading @@ -96,12 +96,14 @@ enum sde_rot_type { * @SDE_CAPS_R1_WB: MDSS V1.x WB block * @SDE_CAPS_R3_WB: MDSS V3.x WB block * @SDE_CAPS_R3_1P5_DOWNSCALE: 1.5x downscale rotator support * @SDE_CAPS_SBUF_1: stream buffer support for inline rotation */ enum sde_caps_settings { SDE_CAPS_R1_WB, SDE_CAPS_R3_WB, SDE_CAPS_R3_1P5_DOWNSCALE, SDE_CAPS_SEC_ATTACH_DETACH_SMMU, SDE_CAPS_SBUF_1, SDE_CAPS_MAX, }; Loading drivers/media/platform/msm/sde/rotator/sde_rotator_core.c +68 −1 Original line number Diff line number Diff line Loading @@ -532,6 +532,10 @@ static int sde_rotator_import_buffer(struct sde_layer_buffer *buffer, if (!input) dir = DMA_FROM_DEVICE; data->sbuf = buffer->sbuf; data->scid = buffer->scid; data->writeback = buffer->writeback; memset(planes, 0, sizeof(planes)); for (i = 0; i < buffer->plane_count; i++) { Loading @@ -539,6 +543,8 @@ static int sde_rotator_import_buffer(struct sde_layer_buffer *buffer, planes[i].offset = buffer->planes[i].offset; planes[i].buffer = buffer->planes[i].buffer; planes[i].handle = buffer->planes[i].handle; planes[i].addr = buffer->planes[i].addr; planes[i].len = buffer->planes[i].len; } ret = sde_mdp_data_get_and_validate_size(data, planes, Loading Loading @@ -760,6 +766,9 @@ static int sde_rotator_import_data(struct sde_rot_mgr *mgr, if (entry->item.flags & SDE_ROTATION_EXT_DMA_BUF) flag |= SDE_ROT_EXT_DMA_BUF; if (entry->item.flags & SDE_ROTATION_EXT_IOVA) flag |= SDE_ROT_EXT_IOVA; if (entry->item.flags & SDE_ROTATION_SECURE_CAMERA) flag |= SDE_SECURE_CAMERA_SESSION; Loading Loading @@ -800,6 +809,10 @@ static int sde_rotator_require_reconfiguration(struct sde_rot_mgr *mgr, entry->perf->wrot_limit != mgr->wrot_limit)) return true; /* sbuf mode is exclusive and may impact queued entries */ if (!mgr->sbuf_ctx && entry->perf && entry->perf->config.output.sbuf) return true; return false; } Loading Loading @@ -855,6 +868,9 @@ static int sde_rotator_is_hw_available(struct sde_rot_mgr *mgr, entry->item.session_id, entry->item.sequence_id); return sde_rotator_is_hw_idle(mgr, hw); } else if (mgr->sbuf_ctx && mgr->sbuf_ctx != entry->private) { SDEROT_DBG("wait until sbuf mode is off\n"); return false; } else { return (atomic_read(&hw->num_active) < hw->max_active); } Loading Loading @@ -907,6 +923,14 @@ static struct sde_rot_hw_resource *sde_rotator_get_hw_resource( entry->item.session_id, entry->item.sequence_id); mgr->rdot_limit = entry->perf->rdot_limit; mgr->wrot_limit = entry->perf->wrot_limit; if (!mgr->sbuf_ctx && entry->perf->config.output.sbuf) { SDEROT_DBG("acquire sbuf s:%d.%d\n", entry->item.session_id, entry->item.sequence_id); SDEROT_EVTLOG(entry->item.session_id, entry->item.sequence_id); mgr->sbuf_ctx = entry->private; } return hw; } Loading Loading @@ -1560,7 +1584,11 @@ static bool sde_rotator_verify_format(struct sde_rot_mgr *mgr, if ((in_fmt->is_yuv != out_fmt->is_yuv) || (in_fmt->pixel_mode != out_fmt->pixel_mode) || (in_fmt->unpack_tight != out_fmt->unpack_tight)) { SDEROT_ERR("Rotator does not support CSC\n"); SDEROT_ERR( "Rotator does not support CSC yuv:%d/%d pm:%d/%d ut:%d/%d\n", in_fmt->is_yuv, out_fmt->is_yuv, in_fmt->pixel_mode, out_fmt->pixel_mode, in_fmt->unpack_tight, out_fmt->unpack_tight); goto verify_error; } Loading Loading @@ -2029,6 +2057,34 @@ int sde_rotator_validate_request(struct sde_rot_mgr *mgr, return ret; } /* * sde_rotator_commit_request - commit the request to hardware * @mgr: pointer to rotator manager * @private: pointer to per file context * @req: pointer to rotation request * * This differs from sde_rotator_queue_request in that this * function will wait until request is committed to hardware. */ void sde_rotator_commit_request(struct sde_rot_mgr *mgr, struct sde_rot_file_private *ctx, struct sde_rot_entry_container *req) { int i; if (!mgr || !ctx || !req || !req->entries) { SDEROT_ERR("null parameters\n"); return; } sde_rotator_queue_request(mgr, ctx, req); sde_rot_mgr_unlock(mgr); for (i = 0; i < req->count; i++) flush_work(&req->entries[i].commit_work); sde_rot_mgr_lock(mgr); } static int sde_rotator_open_session(struct sde_rot_mgr *mgr, struct sde_rot_file_private *private, u32 session_id) { Loading Loading @@ -2139,6 +2195,12 @@ static int sde_rotator_close_session(struct sde_rot_mgr *mgr, sde_rotator_update_clk(mgr); sde_rotator_resource_ctrl(mgr, false); done: if (mgr->sbuf_ctx == private) { SDEROT_DBG("release sbuf session id:%u\n", id); SDEROT_EVTLOG(id); mgr->sbuf_ctx = NULL; } SDEROT_DBG("Closed session id:%u\n", id); return 0; } Loading Loading @@ -2183,6 +2245,11 @@ static int sde_rotator_config_session(struct sde_rot_mgr *mgr, goto done; } if (config->output.sbuf && mgr->sbuf_ctx != private && mgr->sbuf_ctx) { SDEROT_ERR("too many sbuf sessions\n"); goto done; } SDEROT_DBG( "reconfig session id=%u in{%u,%u}f:%u out{%u,%u}f:%u fps:%d clk:%lu, bw:%llu\n", config->session_id, config->input.width, config->input.height, Loading drivers/media/platform/msm/sde/rotator/sde_rotator_core.h +115 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,9 @@ /* secure camera operation*/ #define SDE_ROTATION_SECURE_CAMERA 0x40000 /* use client mapped i/o virtual address */ #define SDE_ROTATION_EXT_IOVA 0x80000 /********************************************************************** * configuration structures **********************************************************************/ Loading @@ -72,12 +75,14 @@ * @height: height of buffer region to be processed * @format: pixel format of buffer * @comp_ratio: compression ratio for the session * @sbuf: true if buffer is streaming buffer */ struct sde_rotation_buf_info { uint32_t width; uint32_t height; uint32_t format; struct sde_mult_factor comp_ratio; bool sbuf; }; /* Loading Loading @@ -121,10 +126,19 @@ enum sde_rotator_clk_type { SDE_ROTATOR_CLK_MAX }; enum sde_rotator_trigger { SDE_ROTATOR_TRIGGER_IMMEDIATE, SDE_ROTATOR_TRIGGER_VIDEO, SDE_ROTATOR_TRIGGER_COMMAND, }; struct sde_rotation_item { /* rotation request flag */ uint32_t flags; /* rotation trigger mode */ uint32_t trigger; /* Source crop rectangle */ struct sde_rect src_rect; Loading Loading @@ -233,6 +247,26 @@ struct sde_rot_entry_container { struct sde_rot_mgr; struct sde_rot_file_private; /* * struct sde_rot_entry - rotation entry * @item: rotation item * @commit_work: work descriptor for commit handler * @done_work: work descriptor for done handler * @commitq: pointer to commit handler rotator queue * @fenceq: pointer to fence signaling rotator queue * @doneq: pointer to done handler rotator queue * @request: pointer to containing request * @src_buf: descriptor of source buffer * @dst_buf: descriptor of destination buffer * @input_fence: pointer to input fence for when input content is available * @output_fence: pointer to output fence for when output content is available * @output_signaled: true if output fence of this entry has been signaled * @dnsc_factor_w: calculated width downscale factor for this entry * @dnsc_factor_w: calculated height downscale factor for this entry * @perf: pointer to performance configuration associated with this entry * @work_assigned: true if this item is assigned to h/w queue/unit * @private: pointer to controlling session context */ struct sde_rot_entry { struct sde_rotation_item item; struct work_struct commit_work; Loading @@ -258,6 +292,18 @@ struct sde_rot_entry { struct sde_rot_file_private *private; }; /* * struct sde_rot_perf - rotator session performance configuration * @list: list of performance configuration under one session * @config: current rotation configuration * @clk_rate: current clock rate in Hz * @bw: current bandwidth in byte per second * @work_dis_lock: serialization lock for updating work distribution (not used) * @work_distribution: work distribution among multiple hardware queue/unit * @last_wb_idx: last queue/unit index, used to account for pre-distributed work * @rdot_limit: read OT limit of this session * @wrot_limit: write OT limit of this session */ struct sde_rot_perf { struct list_head list; struct sde_rotation_config config; Loading @@ -270,6 +316,14 @@ struct sde_rot_perf { u32 wrot_limit; }; /* * struct sde_rot_file_private - rotator manager per session context * @list: list of all session context * @req_list: list of rotation request for this session * @perf_list: list of performance configuration for this session (only one) * @mgr: pointer to the controlling rotator manager * @fenceq: pointer to rotator queue to signal when entry is done */ struct sde_rot_file_private { struct list_head list; struct list_head req_list; Loading @@ -278,6 +332,13 @@ struct sde_rot_file_private { struct sde_rot_queue *fenceq; }; /* * struct sde_rot_bus_data_type - rotator bus scaling configuration * @bus_cale_pdata: pointer to bus scaling configuration table * @bus_hdl: msm bus scaling handle * @curr_bw_uc_idx; current usecase index into configuration table * @curr_quota_val: current bandwidth request in byte per second */ struct sde_rot_bus_data_type { struct msm_bus_scale_pdata *bus_scale_pdata; u32 bus_hdl; Loading @@ -285,6 +346,35 @@ struct sde_rot_bus_data_type { u64 curr_quota_val; }; /* * struct sde_rot_mgr - core rotator manager * @lock: serialization lock to rotator manager functions * @device_suspended: 0 if device is not suspended; non-zero suspended * @pdev: pointer to controlling platform device * @device: pointer to controlling device * @queue_count: number of hardware queue/unit available * @commitq: array of rotator commit queue corresponding to hardware queue * @doneq: array of rotator done queue corresponding to hardware queue * @file_list: list of all sessions managed by rotator manager * @pending_close_bw_vote: bandwidth of closed sessions with pending work * @data_bus: data bus configuration state * @reg_bus: register bus configuration state * @module_power: power/clock configuration state * @regulator_enable: true if foot switch is enabled; false otherwise * @res_ref_cnt: reference count of how many times resource is requested * @rot_enable_clk_cnt: reference count of how many times clock is requested * @rot_clk: array of rotator and periphery clocks * @num_rot_clk: size of the rotator clock array * @rdot_limit: current read OT limit * @wrot_limit: current write OT limit * @hwacquire_timeout: maximum wait time for hardware availability in msec * @pixel_per_clk: rotator hardware performance in pixel for clock * @fudge_factor: fudge factor for clock calculation * @overhead: software overhead for offline rotation in msec * @sbuf_ctx: pointer to sbuf session context * @ops_xxx: function pointers of rotator HAL layer * @hw_data: private handle of rotator HAL layer */ struct sde_rot_mgr { struct mutex lock; atomic_t device_suspended; Loading Loading @@ -325,6 +415,8 @@ struct sde_rot_mgr { struct sde_mult_factor fudge_factor; struct sde_mult_factor overhead; struct sde_rot_file_private *sbuf_ctx; int (*ops_config_hw)(struct sde_rot_hw_resource *hw, struct sde_rot_entry *entry); int (*ops_kickoff_entry)(struct sde_rot_hw_resource *hw, Loading @@ -351,6 +443,8 @@ struct sde_rot_mgr { bool input); int (*ops_hw_is_valid_pixfmt)(struct sde_rot_mgr *mgr, u32 pixfmt, bool input); int (*ops_hw_get_downscale_caps)(struct sde_rot_mgr *mgr, char *caps, int len); void *hw_data; }; Loading @@ -373,6 +467,15 @@ static inline u32 sde_rotator_get_pixfmt(struct sde_rot_mgr *mgr, return 0; } static inline int sde_rotator_get_downscale_caps(struct sde_rot_mgr *mgr, char *caps, int len) { if (mgr && mgr->ops_hw_get_downscale_caps) return mgr->ops_hw_get_downscale_caps(mgr, caps, len); return 0; } static inline int __compare_session_item_rect( struct sde_rotation_buf_info *s_rect, struct sde_rect *i_rect, uint32_t i_fmt, bool src) Loading Loading @@ -509,6 +612,18 @@ void sde_rotator_queue_request(struct sde_rot_mgr *rot_dev, struct sde_rot_file_private *ctx, struct sde_rot_entry_container *req); /* * sde_rotator_commit_request - queue/schedule the given request and wait * until h/w commit * @rot_dev: Pointer to rotator device * @private: Pointer to rotator manager per file context * @req: Pointer to rotation request * return: 0 if success; error code otherwise */ void sde_rotator_commit_request(struct sde_rot_mgr *mgr, struct sde_rot_file_private *ctx, struct sde_rot_entry_container *req); /* * sde_rotator_verify_config_all - verify given rotation configuration * @rot_dev: Pointer to rotator device Loading drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c +7 −0 Original line number Diff line number Diff line Loading @@ -1283,6 +1283,13 @@ struct dentry *sde_rotator_create_debugfs( return NULL; } if (!debugfs_create_u32("disable_syscache", 0644, debugfs_root, &rot_dev->disable_syscache)) { SDEROT_ERR("fail create disable_syscache\n"); debugfs_remove_recursive(debugfs_root); return NULL; } if (!debugfs_create_u32("streamoff_timeout", 0644, debugfs_root, &rot_dev->streamoff_timeout)) { SDEROT_ERR("fail create streamoff_timeout\n"); Loading Loading
Documentation/devicetree/bindings/media/video/msm-sde-rotator.txt +15 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ Required properties - clocks: List of Phandles for clock device nodes needed by the device. - clock-names: List of clock names needed by the device. - #list-cells: Number of rotator cells, must be 1 Bus Scaling Data: - qcom,msm-bus,name: String property describing rotator client. - qcom,msm-bus,num-cases: This is the the number of Bus Scaling use cases Loading Loading @@ -81,6 +83,12 @@ Optional properties priority for rotator clients. - qcom,mdss-rot-mode: This is integer value indicates operation mode of the rotator device - qcom,mdss-sbuf-headroom: This integer value indicates stream buffer headroom in lines. - cache-slice-names: A set of names that identify the usecase names of a client that uses cache slice. These strings are used to look up the cache slice entries by name. - cache-slices: The tuple has phandle to llcc device as the first argument and the second argument is the usecase id of the client. Subnode properties: - compatible: Compatible name used in smmu v2. Loading @@ -102,6 +110,9 @@ Example: reg = <0xfd900000 0x22100>, <0xfd925000 0x1000>; reg-names = "mdp_phys", "rot_vbif_phys"; #list-cells = <1>; interrupt-parent = <&mdss_mdp>; interrupts = <2 0>; Loading Loading @@ -131,6 +142,10 @@ Example: qcom,mdss-default-ot-rd-limit = <8>; qcom,mdss-default-ot-wr-limit = <16>; qcom,mdss-sbuf-headroom = <20>; cache-slice-names = "rotator"; cache-slices = <&llcc 3>; smmu_rot_unsec: qcom,smmu_rot_unsec_cb { compatible = "qcom,smmu_sde_rot_unsec"; iommus = <&mdp_smmu 0xe00>; Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_base.h +2 −0 Original line number Diff line number Diff line Loading @@ -96,12 +96,14 @@ enum sde_rot_type { * @SDE_CAPS_R1_WB: MDSS V1.x WB block * @SDE_CAPS_R3_WB: MDSS V3.x WB block * @SDE_CAPS_R3_1P5_DOWNSCALE: 1.5x downscale rotator support * @SDE_CAPS_SBUF_1: stream buffer support for inline rotation */ enum sde_caps_settings { SDE_CAPS_R1_WB, SDE_CAPS_R3_WB, SDE_CAPS_R3_1P5_DOWNSCALE, SDE_CAPS_SEC_ATTACH_DETACH_SMMU, SDE_CAPS_SBUF_1, SDE_CAPS_MAX, }; Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_core.c +68 −1 Original line number Diff line number Diff line Loading @@ -532,6 +532,10 @@ static int sde_rotator_import_buffer(struct sde_layer_buffer *buffer, if (!input) dir = DMA_FROM_DEVICE; data->sbuf = buffer->sbuf; data->scid = buffer->scid; data->writeback = buffer->writeback; memset(planes, 0, sizeof(planes)); for (i = 0; i < buffer->plane_count; i++) { Loading @@ -539,6 +543,8 @@ static int sde_rotator_import_buffer(struct sde_layer_buffer *buffer, planes[i].offset = buffer->planes[i].offset; planes[i].buffer = buffer->planes[i].buffer; planes[i].handle = buffer->planes[i].handle; planes[i].addr = buffer->planes[i].addr; planes[i].len = buffer->planes[i].len; } ret = sde_mdp_data_get_and_validate_size(data, planes, Loading Loading @@ -760,6 +766,9 @@ static int sde_rotator_import_data(struct sde_rot_mgr *mgr, if (entry->item.flags & SDE_ROTATION_EXT_DMA_BUF) flag |= SDE_ROT_EXT_DMA_BUF; if (entry->item.flags & SDE_ROTATION_EXT_IOVA) flag |= SDE_ROT_EXT_IOVA; if (entry->item.flags & SDE_ROTATION_SECURE_CAMERA) flag |= SDE_SECURE_CAMERA_SESSION; Loading Loading @@ -800,6 +809,10 @@ static int sde_rotator_require_reconfiguration(struct sde_rot_mgr *mgr, entry->perf->wrot_limit != mgr->wrot_limit)) return true; /* sbuf mode is exclusive and may impact queued entries */ if (!mgr->sbuf_ctx && entry->perf && entry->perf->config.output.sbuf) return true; return false; } Loading Loading @@ -855,6 +868,9 @@ static int sde_rotator_is_hw_available(struct sde_rot_mgr *mgr, entry->item.session_id, entry->item.sequence_id); return sde_rotator_is_hw_idle(mgr, hw); } else if (mgr->sbuf_ctx && mgr->sbuf_ctx != entry->private) { SDEROT_DBG("wait until sbuf mode is off\n"); return false; } else { return (atomic_read(&hw->num_active) < hw->max_active); } Loading Loading @@ -907,6 +923,14 @@ static struct sde_rot_hw_resource *sde_rotator_get_hw_resource( entry->item.session_id, entry->item.sequence_id); mgr->rdot_limit = entry->perf->rdot_limit; mgr->wrot_limit = entry->perf->wrot_limit; if (!mgr->sbuf_ctx && entry->perf->config.output.sbuf) { SDEROT_DBG("acquire sbuf s:%d.%d\n", entry->item.session_id, entry->item.sequence_id); SDEROT_EVTLOG(entry->item.session_id, entry->item.sequence_id); mgr->sbuf_ctx = entry->private; } return hw; } Loading Loading @@ -1560,7 +1584,11 @@ static bool sde_rotator_verify_format(struct sde_rot_mgr *mgr, if ((in_fmt->is_yuv != out_fmt->is_yuv) || (in_fmt->pixel_mode != out_fmt->pixel_mode) || (in_fmt->unpack_tight != out_fmt->unpack_tight)) { SDEROT_ERR("Rotator does not support CSC\n"); SDEROT_ERR( "Rotator does not support CSC yuv:%d/%d pm:%d/%d ut:%d/%d\n", in_fmt->is_yuv, out_fmt->is_yuv, in_fmt->pixel_mode, out_fmt->pixel_mode, in_fmt->unpack_tight, out_fmt->unpack_tight); goto verify_error; } Loading Loading @@ -2029,6 +2057,34 @@ int sde_rotator_validate_request(struct sde_rot_mgr *mgr, return ret; } /* * sde_rotator_commit_request - commit the request to hardware * @mgr: pointer to rotator manager * @private: pointer to per file context * @req: pointer to rotation request * * This differs from sde_rotator_queue_request in that this * function will wait until request is committed to hardware. */ void sde_rotator_commit_request(struct sde_rot_mgr *mgr, struct sde_rot_file_private *ctx, struct sde_rot_entry_container *req) { int i; if (!mgr || !ctx || !req || !req->entries) { SDEROT_ERR("null parameters\n"); return; } sde_rotator_queue_request(mgr, ctx, req); sde_rot_mgr_unlock(mgr); for (i = 0; i < req->count; i++) flush_work(&req->entries[i].commit_work); sde_rot_mgr_lock(mgr); } static int sde_rotator_open_session(struct sde_rot_mgr *mgr, struct sde_rot_file_private *private, u32 session_id) { Loading Loading @@ -2139,6 +2195,12 @@ static int sde_rotator_close_session(struct sde_rot_mgr *mgr, sde_rotator_update_clk(mgr); sde_rotator_resource_ctrl(mgr, false); done: if (mgr->sbuf_ctx == private) { SDEROT_DBG("release sbuf session id:%u\n", id); SDEROT_EVTLOG(id); mgr->sbuf_ctx = NULL; } SDEROT_DBG("Closed session id:%u\n", id); return 0; } Loading Loading @@ -2183,6 +2245,11 @@ static int sde_rotator_config_session(struct sde_rot_mgr *mgr, goto done; } if (config->output.sbuf && mgr->sbuf_ctx != private && mgr->sbuf_ctx) { SDEROT_ERR("too many sbuf sessions\n"); goto done; } SDEROT_DBG( "reconfig session id=%u in{%u,%u}f:%u out{%u,%u}f:%u fps:%d clk:%lu, bw:%llu\n", config->session_id, config->input.width, config->input.height, Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_core.h +115 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,9 @@ /* secure camera operation*/ #define SDE_ROTATION_SECURE_CAMERA 0x40000 /* use client mapped i/o virtual address */ #define SDE_ROTATION_EXT_IOVA 0x80000 /********************************************************************** * configuration structures **********************************************************************/ Loading @@ -72,12 +75,14 @@ * @height: height of buffer region to be processed * @format: pixel format of buffer * @comp_ratio: compression ratio for the session * @sbuf: true if buffer is streaming buffer */ struct sde_rotation_buf_info { uint32_t width; uint32_t height; uint32_t format; struct sde_mult_factor comp_ratio; bool sbuf; }; /* Loading Loading @@ -121,10 +126,19 @@ enum sde_rotator_clk_type { SDE_ROTATOR_CLK_MAX }; enum sde_rotator_trigger { SDE_ROTATOR_TRIGGER_IMMEDIATE, SDE_ROTATOR_TRIGGER_VIDEO, SDE_ROTATOR_TRIGGER_COMMAND, }; struct sde_rotation_item { /* rotation request flag */ uint32_t flags; /* rotation trigger mode */ uint32_t trigger; /* Source crop rectangle */ struct sde_rect src_rect; Loading Loading @@ -233,6 +247,26 @@ struct sde_rot_entry_container { struct sde_rot_mgr; struct sde_rot_file_private; /* * struct sde_rot_entry - rotation entry * @item: rotation item * @commit_work: work descriptor for commit handler * @done_work: work descriptor for done handler * @commitq: pointer to commit handler rotator queue * @fenceq: pointer to fence signaling rotator queue * @doneq: pointer to done handler rotator queue * @request: pointer to containing request * @src_buf: descriptor of source buffer * @dst_buf: descriptor of destination buffer * @input_fence: pointer to input fence for when input content is available * @output_fence: pointer to output fence for when output content is available * @output_signaled: true if output fence of this entry has been signaled * @dnsc_factor_w: calculated width downscale factor for this entry * @dnsc_factor_w: calculated height downscale factor for this entry * @perf: pointer to performance configuration associated with this entry * @work_assigned: true if this item is assigned to h/w queue/unit * @private: pointer to controlling session context */ struct sde_rot_entry { struct sde_rotation_item item; struct work_struct commit_work; Loading @@ -258,6 +292,18 @@ struct sde_rot_entry { struct sde_rot_file_private *private; }; /* * struct sde_rot_perf - rotator session performance configuration * @list: list of performance configuration under one session * @config: current rotation configuration * @clk_rate: current clock rate in Hz * @bw: current bandwidth in byte per second * @work_dis_lock: serialization lock for updating work distribution (not used) * @work_distribution: work distribution among multiple hardware queue/unit * @last_wb_idx: last queue/unit index, used to account for pre-distributed work * @rdot_limit: read OT limit of this session * @wrot_limit: write OT limit of this session */ struct sde_rot_perf { struct list_head list; struct sde_rotation_config config; Loading @@ -270,6 +316,14 @@ struct sde_rot_perf { u32 wrot_limit; }; /* * struct sde_rot_file_private - rotator manager per session context * @list: list of all session context * @req_list: list of rotation request for this session * @perf_list: list of performance configuration for this session (only one) * @mgr: pointer to the controlling rotator manager * @fenceq: pointer to rotator queue to signal when entry is done */ struct sde_rot_file_private { struct list_head list; struct list_head req_list; Loading @@ -278,6 +332,13 @@ struct sde_rot_file_private { struct sde_rot_queue *fenceq; }; /* * struct sde_rot_bus_data_type - rotator bus scaling configuration * @bus_cale_pdata: pointer to bus scaling configuration table * @bus_hdl: msm bus scaling handle * @curr_bw_uc_idx; current usecase index into configuration table * @curr_quota_val: current bandwidth request in byte per second */ struct sde_rot_bus_data_type { struct msm_bus_scale_pdata *bus_scale_pdata; u32 bus_hdl; Loading @@ -285,6 +346,35 @@ struct sde_rot_bus_data_type { u64 curr_quota_val; }; /* * struct sde_rot_mgr - core rotator manager * @lock: serialization lock to rotator manager functions * @device_suspended: 0 if device is not suspended; non-zero suspended * @pdev: pointer to controlling platform device * @device: pointer to controlling device * @queue_count: number of hardware queue/unit available * @commitq: array of rotator commit queue corresponding to hardware queue * @doneq: array of rotator done queue corresponding to hardware queue * @file_list: list of all sessions managed by rotator manager * @pending_close_bw_vote: bandwidth of closed sessions with pending work * @data_bus: data bus configuration state * @reg_bus: register bus configuration state * @module_power: power/clock configuration state * @regulator_enable: true if foot switch is enabled; false otherwise * @res_ref_cnt: reference count of how many times resource is requested * @rot_enable_clk_cnt: reference count of how many times clock is requested * @rot_clk: array of rotator and periphery clocks * @num_rot_clk: size of the rotator clock array * @rdot_limit: current read OT limit * @wrot_limit: current write OT limit * @hwacquire_timeout: maximum wait time for hardware availability in msec * @pixel_per_clk: rotator hardware performance in pixel for clock * @fudge_factor: fudge factor for clock calculation * @overhead: software overhead for offline rotation in msec * @sbuf_ctx: pointer to sbuf session context * @ops_xxx: function pointers of rotator HAL layer * @hw_data: private handle of rotator HAL layer */ struct sde_rot_mgr { struct mutex lock; atomic_t device_suspended; Loading Loading @@ -325,6 +415,8 @@ struct sde_rot_mgr { struct sde_mult_factor fudge_factor; struct sde_mult_factor overhead; struct sde_rot_file_private *sbuf_ctx; int (*ops_config_hw)(struct sde_rot_hw_resource *hw, struct sde_rot_entry *entry); int (*ops_kickoff_entry)(struct sde_rot_hw_resource *hw, Loading @@ -351,6 +443,8 @@ struct sde_rot_mgr { bool input); int (*ops_hw_is_valid_pixfmt)(struct sde_rot_mgr *mgr, u32 pixfmt, bool input); int (*ops_hw_get_downscale_caps)(struct sde_rot_mgr *mgr, char *caps, int len); void *hw_data; }; Loading @@ -373,6 +467,15 @@ static inline u32 sde_rotator_get_pixfmt(struct sde_rot_mgr *mgr, return 0; } static inline int sde_rotator_get_downscale_caps(struct sde_rot_mgr *mgr, char *caps, int len) { if (mgr && mgr->ops_hw_get_downscale_caps) return mgr->ops_hw_get_downscale_caps(mgr, caps, len); return 0; } static inline int __compare_session_item_rect( struct sde_rotation_buf_info *s_rect, struct sde_rect *i_rect, uint32_t i_fmt, bool src) Loading Loading @@ -509,6 +612,18 @@ void sde_rotator_queue_request(struct sde_rot_mgr *rot_dev, struct sde_rot_file_private *ctx, struct sde_rot_entry_container *req); /* * sde_rotator_commit_request - queue/schedule the given request and wait * until h/w commit * @rot_dev: Pointer to rotator device * @private: Pointer to rotator manager per file context * @req: Pointer to rotation request * return: 0 if success; error code otherwise */ void sde_rotator_commit_request(struct sde_rot_mgr *mgr, struct sde_rot_file_private *ctx, struct sde_rot_entry_container *req); /* * sde_rotator_verify_config_all - verify given rotation configuration * @rot_dev: Pointer to rotator device Loading
drivers/media/platform/msm/sde/rotator/sde_rotator_debug.c +7 −0 Original line number Diff line number Diff line Loading @@ -1283,6 +1283,13 @@ struct dentry *sde_rotator_create_debugfs( return NULL; } if (!debugfs_create_u32("disable_syscache", 0644, debugfs_root, &rot_dev->disable_syscache)) { SDEROT_ERR("fail create disable_syscache\n"); debugfs_remove_recursive(debugfs_root); return NULL; } if (!debugfs_create_u32("streamoff_timeout", 0644, debugfs_root, &rot_dev->streamoff_timeout)) { SDEROT_ERR("fail create streamoff_timeout\n"); Loading