1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219 |
- #ifndef _SDE_CRTC_H_
- #define _SDE_CRTC_H_
- #include <linux/kthread.h>
- #include <linux/of_fdt.h>
- #include <drm/drm_crtc.h>
- #include <drm/drm_vblank.h>
- #include "msm_prop.h"
- #include "sde_fence.h"
- #include "sde_kms.h"
- #include "sde_core_perf.h"
- #include "sde_hw_ds.h"
- #include "sde_color_processing.h"
- #include "sde_encoder.h"
- #define SDE_CRTC_NAME_SIZE 12
- #define SDE_CRTC_EVENT_SIZE (4 * 2)
- enum sde_crtc_client_type {
- RT_CLIENT,
- NRT_CLIENT,
- RT_RSC_CLIENT,
- };
- enum sde_crtc_output_capture_point {
- CAPTURE_MIXER_OUT,
- CAPTURE_DSPP_OUT,
- CAPTURE_DEMURA_OUT
- };
- enum fence_error_handle_flag {
- FENCE_ERROR_HANDLE_DISABLE,
- FENCE_ERROR_HANDLE_ENABLE,
- };
- enum sde_crtc_idle_pc_state {
- IDLE_PC_NONE,
- IDLE_PC_ENABLE,
- IDLE_PC_DISABLE,
- };
- enum sde_crtc_vm_req {
- VM_REQ_NONE,
- VM_REQ_RELEASE,
- VM_REQ_ACQUIRE,
- };
- struct sde_crtc_retire_event {
- struct drm_connector *connectors[MAX_CONNECTORS];
- int num_connectors;
- struct list_head list;
- };
- struct sde_crtc_mixer {
- struct sde_hw_mixer *hw_lm;
- struct sde_hw_ctl *hw_ctl;
- struct sde_hw_dspp *hw_dspp;
- struct sde_hw_ds *hw_ds;
- struct drm_encoder *encoder;
- u32 mixer_op_mode;
- };
- struct sde_crtc_frame_event {
- struct kthread_work work;
- struct drm_crtc *crtc;
- struct drm_connector *connector;
- struct list_head list;
- ktime_t ts;
- u32 event;
- };
- struct sde_crtc_vblank_event {
- struct kthread_work work;
- struct drm_crtc *crtc;
- struct list_head list;
- ktime_t ts;
- };
- struct sde_crtc_event {
- struct list_head list;
- struct kthread_work kt_work;
- void *sde_crtc;
- void (*cb_func)(struct drm_crtc *crtc, void *usr);
- void *usr;
- };
- struct sde_crtc_fps_info {
- u32 frame_count;
- ktime_t last_sampled_time_us;
- u32 measured_fps;
- u32 fps_periodic_duration;
- ktime_t *time_buf;
- u32 next_time_index;
- };
- struct sde_ltm_buffer {
- struct drm_framebuffer *fb;
- struct drm_gem_object *gem;
- struct msm_gem_address_space *aspace;
- u32 drm_fb_id;
- u32 offset;
- u64 iova;
- void *kva;
- struct list_head node;
- };
- struct sde_crtc_misr_info {
- bool misr_enable;
- u32 misr_frame_count;
- };
- #define SDE_CRTC_MAX_EVENT_COUNT 16
- struct sde_frame_data_buffer {
- u32 fd;
- struct drm_framebuffer *fb;
- struct drm_gem_object *gem;
- };
- struct sde_frame_data {
- u32 idx;
- u32 cnt;
- struct sde_frame_data_buffer *buf[SDE_FRAME_DATA_BUFFER_MAX];
- };
- struct sde_opr_value {
- atomic_t num_valid_opr;
- u32 opr_value[MAX_DSI_DISPLAYS];
- };
- enum sde_crtc_hw_fence_flags {
- HW_FENCE_OUT_FENCES_ENABLE,
- HW_FENCE_IN_FENCES_ENABLE,
- HW_FENCE_IN_FENCES_NO_OVERRIDE,
- HW_FENCE_FEATURES_MAX,
- };
- struct sde_crtc {
- struct drm_crtc base;
- char name[SDE_CRTC_NAME_SIZE];
-
- u32 num_ctls;
- u32 num_mixers;
- bool mixers_swapped;
- struct sde_crtc_mixer mixers[MAX_MIXERS_PER_CRTC];
- struct drm_pending_vblank_event *event;
- u32 vsync_count;
- struct msm_property_info property_info;
- struct msm_property_data property_data[CRTC_PROP_COUNT];
- struct drm_property_blob *blob_info;
-
- struct sde_fence_context *output_fence;
- struct sde_hw_stage_cfg stage_cfg[MAX_LAYOUTS_PER_CRTC];
- struct dentry *debugfs_root;
- void *priv_handle;
- u32 vblank_cb_count;
- u64 play_count;
- ktime_t vblank_cb_time;
- ktime_t vblank_last_cb_time;
- ktime_t retire_frame_event_time;
- struct sde_crtc_fps_info fps_info;
- struct device *sysfs_dev;
- struct kernfs_node *vsync_event_sf;
- struct kernfs_node *retire_frame_event_sf;
- bool enabled;
- struct list_head cp_feature_list;
- struct list_head cp_active_list;
- struct list_head cp_dirty_list;
- struct list_head ad_dirty;
- struct list_head ad_active;
- struct list_head user_event_list;
- struct mutex crtc_lock;
- struct mutex crtc_cp_lock;
- atomic_t frame_pending;
- struct sde_crtc_frame_event frame_events[SDE_CRTC_EVENT_SIZE];
- struct list_head frame_event_list;
- struct sde_crtc_vblank_event vblank_events[SDE_CRTC_EVENT_SIZE];
- struct list_head vblank_event_list;
- spinlock_t spin_lock;
- spinlock_t event_spin_lock;
- bool kickoff_in_progress;
- unsigned long revalidate_mask;
-
- struct sde_crtc_event event_cache[SDE_CRTC_MAX_EVENT_COUNT];
- struct list_head event_free_list;
- spinlock_t event_lock;
- bool misr_enable_sui;
- bool misr_enable_debugfs;
- bool misr_reconfigure;
- u32 misr_frame_count;
- struct sde_power_event *power_event;
- struct sde_core_perf_params cur_perf;
- struct sde_core_perf_params new_perf;
- u32 plane_mask_old;
-
- struct drm_property_blob *hist_blob;
- enum frame_trigger_mode_type frame_trigger_mode;
- u32 cp_pu_feature_mask;
- u32 ltm_buffer_cnt;
- struct sde_ltm_buffer *ltm_buffers[LTM_BUFFER_SIZE];
- struct list_head ltm_buf_free;
- struct list_head ltm_buf_busy;
- bool ltm_hist_en;
- bool ltm_merge_clear_pending;
- struct drm_msm_ltm_cfg_param ltm_cfg;
- struct mutex ltm_buffer_lock;
- spinlock_t ltm_lock;
- bool needs_hw_reset;
- bool reinit_crtc_mixers;
- int hist_irq_idx;
- bool disable_pending_cp;
- int src_bpp;
- int target_bpp;
- struct kthread_delayed_work static_cache_read_work;
- enum sde_sys_cache_state cache_state;
- enum sde_sys_cache_type cache_type;
- struct drm_property_blob *dspp_blob_info;
- u32 cached_encoder_mask;
- bool valid_skip_blend_plane;
- enum sde_sspp skip_blend_plane;
- u32 skip_blend_plane_w;
- u32 skip_blend_plane_h;
- u32 line_time_in_ns;
- struct sde_frame_data frame_data;
- struct sde_opr_value previous_opr_value;
- bool opr_event_notify_enabled;
- DECLARE_BITMAP(hwfence_features_mask, HW_FENCE_FEATURES_MAX);
- u32 hwfence_out_fences_skip;
- int input_fence_status;
- bool handle_fence_error_bw_update;
- u32 back_light;
- u32 back_light_max;
- u32 back_light_pending;
- };
- enum sde_crtc_dirty_flags {
- SDE_CRTC_DIRTY_DEST_SCALER,
- SDE_CRTC_DIRTY_DIM_LAYERS,
- SDE_CRTC_NOISE_LAYER,
- SDE_CRTC_DIRTY_MAX,
- };
- #define to_sde_crtc(x) container_of(x, struct sde_crtc, base)
- struct sde_line_insertion_param {
- bool panel_line_insertion_enable;
- u32 padding_height;
- u32 padding_active;
- u32 padding_dummy;
- };
- struct sde_crtc_state {
- struct drm_crtc_state base;
- struct drm_connector *connectors[MAX_CONNECTORS];
- int num_connectors;
- struct sde_rsc_client *rsc_client;
- bool rsc_update;
- bool bw_control;
- bool bw_split_vote;
- bool is_ppsplit;
- struct sde_rect crtc_roi;
- struct sde_rect lm_bounds[MAX_MIXERS_PER_CRTC];
- struct sde_rect lm_roi[MAX_MIXERS_PER_CRTC];
- struct msm_roi_list user_roi_list, cached_user_roi_list;
- struct msm_property_state property_state;
- struct msm_property_value property_values[CRTC_PROP_COUNT];
- DECLARE_BITMAP(dirty, SDE_CRTC_DIRTY_MAX);
- uint64_t input_fence_timeout_ns;
- uint32_t num_dim_layers;
- uint32_t cwb_enc_mask;
- uint32_t cached_cwb_enc_mask;
- struct sde_hw_dim_layer dim_layer[SDE_MAX_DIM_LAYERS];
- uint32_t num_ds;
- uint32_t num_ds_enabled;
- struct sde_hw_ds_cfg ds_cfg[SDE_MAX_DS_COUNT];
- struct sde_hw_scaler3_lut_cfg scl3_lut_cfg;
- struct sde_core_perf_params new_perf;
- bool noise_layer_en;
- struct drm_msm_noise_layer_cfg layer_cfg;
- uint32_t cp_prop_cnt;
- struct sde_cp_crtc_property_state
- cp_prop_values[SDE_CP_CRTC_MAX_FEATURES];
- uint32_t cp_dirty_list[SDE_CP_CRTC_MAX_FEATURES];
- struct sde_cp_crtc_range_prop_payload
- cp_range_payload[SDE_CP_CRTC_MAX_FEATURES];
- bool cont_splash_populated;
- struct sde_line_insertion_param line_insertion;
- bool hwfence_in_fences_set;
- };
- enum sde_crtc_irq_state {
- IRQ_NOINIT,
- IRQ_ENABLED,
- IRQ_DISABLING,
- IRQ_DISABLED,
- };
- struct sde_crtc_irq_info {
- struct sde_irq_callback irq;
- u32 event;
- int (*func)(struct drm_crtc *crtc, bool en,
- struct sde_irq_callback *irq);
- struct list_head list;
- enum sde_crtc_irq_state state;
- spinlock_t state_lock;
- };
- #define to_sde_crtc_state(x) \
- container_of(x, struct sde_crtc_state, base)
- #define sde_crtc_get_property(S, X) \
- ((S) && ((X) < CRTC_PROP_COUNT) ? ((S)->property_values[(X)].value) : 0)
- static inline int sde_crtc_frame_pending(struct drm_crtc *crtc)
- {
- struct sde_crtc *sde_crtc;
- if (!crtc)
- return -EINVAL;
- sde_crtc = to_sde_crtc(crtc);
- return atomic_read(&sde_crtc->frame_pending);
- }
- static inline void sde_crtc_set_needs_hw_reset(struct drm_crtc *crtc)
- {
- struct sde_crtc *sde_crtc;
- if (!crtc)
- return;
- sde_crtc = to_sde_crtc(crtc);
- sde_crtc->needs_hw_reset = true;
- }
- int sde_crtc_reset_hw(struct drm_crtc *crtc, struct drm_crtc_state *old_state,
- bool recovery_events);
- void sde_crtc_dump_fences(struct drm_crtc *crtc);
- bool sde_crtc_is_fence_signaled(struct drm_crtc *crtc);
- static inline int sde_crtc_request_frame_reset(struct drm_crtc *crtc,
- struct drm_encoder *encoder)
- {
- struct sde_crtc *sde_crtc = to_sde_crtc(crtc);
- if (test_bit(HW_FENCE_IN_FENCES_ENABLE, sde_crtc->hwfence_features_mask))
- sde_crtc_dump_fences(crtc);
- if (sde_crtc->frame_trigger_mode == FRAME_DONE_WAIT_POSTED_START ||
- !sde_encoder_is_dsi_display(encoder))
- sde_crtc_reset_hw(crtc, crtc->state, false);
- return 0;
- }
- void sde_crtc_get_mixer_resolution(struct drm_crtc *sde_crtc, struct drm_crtc_state *crtc_state,
- struct drm_display_mode *mode, u32 *width, u32 *height);
- void sde_crtc_get_resolution(struct drm_crtc *sde_crtc, struct drm_crtc_state *crtc_state,
- struct drm_display_mode *mode, u32 *width, u32 *height);
- int sde_crtc_vblank(struct drm_crtc *crtc, bool en);
- struct msm_display_mode *sde_crtc_get_msm_mode(struct drm_crtc_state *c_state);
- void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
- struct drm_crtc_state *old_state);
- void sde_crtc_prepare_commit(struct drm_crtc *crtc,
- struct drm_crtc_state *old_state);
- void sde_crtc_complete_commit(struct drm_crtc *crtc,
- struct drm_crtc_state *old_state);
- struct drm_crtc *sde_crtc_init(struct drm_device *dev, struct drm_plane *plane);
- int sde_crtc_post_init(struct drm_device *dev, struct drm_crtc *crtc);
- void sde_crtc_complete_flip(struct drm_crtc *crtc, struct drm_file *file);
- int sde_crtc_register_custom_event(struct sde_kms *kms,
- struct drm_crtc *crtc_drm, u32 event, bool en);
- enum sde_intf_mode sde_crtc_get_intf_mode(struct drm_crtc *crtc,
- struct drm_crtc_state *cstate);
- u32 sde_crtc_get_fps_mode(struct drm_crtc *crtc);
- u32 sde_crtc_get_dfps_maxfps(struct drm_crtc *crtc);
- enum sde_wb_usage_type sde_crtc_get_wb_usage_type(struct drm_crtc *crtc);
- static inline enum sde_crtc_client_type sde_crtc_get_client_type(
- struct drm_crtc *crtc)
- {
- struct sde_crtc_state *cstate =
- crtc ? to_sde_crtc_state(crtc->state) : NULL;
- if (!cstate)
- return RT_CLIENT;
- return cstate->rsc_client ? RT_RSC_CLIENT : RT_CLIENT;
- }
- static inline bool sde_crtc_is_rt_client(struct drm_crtc *crtc,
- struct drm_crtc_state *cstate)
- {
- if (!crtc || !cstate)
- return true;
- return (sde_crtc_get_intf_mode(crtc, cstate) != INTF_MODE_WB_LINE);
- }
- static inline bool sde_crtc_is_enabled(struct drm_crtc *crtc)
- {
- return crtc ? crtc->enabled : false;
- }
- static inline u32 sde_crtc_get_line_time(struct drm_crtc *crtc)
- {
- struct sde_crtc *sde_crtc;
- if (!crtc)
- return 0;
- sde_crtc = to_sde_crtc(crtc);
- return sde_crtc->line_time_in_ns;
- }
- static inline bool sde_crtc_is_reset_required(struct drm_crtc *crtc)
- {
-
- if (!crtc || !crtc->state)
- return true;
-
- if (sde_kms_is_suspend_state(crtc->dev) && crtc->state->active)
- return false;
- return true;
- }
- int sde_crtc_event_queue(struct drm_crtc *crtc,
- void (*func)(struct drm_crtc *crtc, void *usr),
- void *usr, bool color_processing_event);
- void sde_crtc_get_crtc_roi(struct drm_crtc_state *state,
- const struct sde_rect **crtc_roi);
- bool sde_crtc_is_crtc_roi_dirty(struct drm_crtc_state *state);
- static inline int sde_crtc_get_secure_level(struct drm_crtc *crtc,
- struct drm_crtc_state *state)
- {
- if (!crtc || !state)
- return -EINVAL;
- return sde_crtc_get_property(to_sde_crtc_state(state),
- CRTC_PROP_SECURITY_LEVEL);
- }
- static inline bool sde_crtc_atomic_check_has_modeset(
- struct drm_atomic_state *state, struct drm_crtc *crtc)
- {
- struct drm_crtc_state *crtc_state;
- if (!state || !crtc)
- return false;
- crtc_state = drm_atomic_get_new_crtc_state(state,
- crtc);
- return (crtc_state && drm_atomic_crtc_needs_modeset(crtc_state));
- }
- static inline bool sde_crtc_state_in_clone_mode(struct drm_encoder *encoder,
- struct drm_crtc_state *state)
- {
- struct sde_crtc_state *cstate;
- if (!state || !encoder)
- return false;
- cstate = to_sde_crtc_state(state);
- if (sde_encoder_in_clone_mode(encoder) ||
- (cstate->cwb_enc_mask & drm_encoder_mask(encoder)))
- return true;
- return false;
- }
- static inline void sde_crtc_get_ds_io_res(struct drm_crtc_state *state, struct sde_io_res *res)
- {
- struct sde_crtc_state *cstate;
- int i;
- if (!state || !res)
- return;
- cstate = to_sde_crtc_state(state);
- memset(res, 0, sizeof(struct sde_io_res));
- for (i = 0; i < cstate->num_ds; i++) {
- if (cstate->ds_cfg[i].scl3_cfg.enable) {
- res->enabled = true;
- res->src_w += cstate->ds_cfg[i].lm_width;
- res->dst_w += cstate->ds_cfg[i].scl3_cfg.dst_width;
- res->src_h = cstate->ds_cfg[i].lm_height;
- res->dst_h = cstate->ds_cfg[i].scl3_cfg.dst_height;
- }
- }
- }
- int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
- struct drm_crtc_state *old_crtc_state,
- bool old_valid_fb);
- int sde_crtc_find_plane_fb_modes(struct drm_crtc *crtc,
- uint32_t *fb_ns, uint32_t *fb_sec, uint32_t *fb_sec_dir);
- int sde_crtc_state_find_plane_fb_modes(struct drm_crtc_state *state,
- uint32_t *fb_ns, uint32_t *fb_sec, uint32_t *fb_sec_dir);
- int sde_crtc_secure_ctrl(struct drm_crtc *crtc, bool post_commit);
- int sde_crtc_helper_reset_custom_properties(struct drm_crtc *crtc,
- struct drm_crtc_state *crtc_state);
- void sde_crtc_timeline_status(struct drm_crtc *crtc);
- void sde_crtc_update_cont_splash_settings(
- struct drm_crtc *crtc);
- void sde_crtc_set_qos_dirty(struct drm_crtc *crtc);
- void sde_crtc_misr_setup(struct drm_crtc *crtc, bool enable, u32 frame_count);
- void sde_crtc_get_misr_info(struct drm_crtc *crtc,
- struct sde_crtc_misr_info *crtc_misr_info);
- static inline void sde_crtc_set_bpp(struct sde_crtc *sde_crtc, int src_bpp,
- int target_bpp)
- {
- sde_crtc->src_bpp = src_bpp;
- sde_crtc->target_bpp = target_bpp;
- }
- void sde_crtc_static_img_control(struct drm_crtc *crtc,
- enum sde_sys_cache_state state, bool is_vidmode);
- void sde_crtc_static_cache_read_kickoff(struct drm_crtc *crtc);
- int sde_crtc_get_num_datapath(struct drm_crtc *crtc,
- struct drm_connector *connector, struct drm_crtc_state *crtc_state);
- void sde_crtc_reset_sw_state(struct drm_crtc *crtc);
- void sde_crtc_disable_cp_features(struct drm_crtc *crtc);
- void _sde_crtc_clear_dim_layers_v1(struct drm_crtc_state *state);
- void sde_crtc_cancel_delayed_work(struct drm_crtc *crtc);
- struct drm_encoder *sde_crtc_get_src_encoder_of_clone(struct drm_crtc *crtc);
- void _sde_crtc_vm_release_notify(struct drm_crtc *crtc);
- bool sde_crtc_is_line_insertion_supported(struct drm_crtc *crtc);
- void sde_crtc_calc_vpadding_param(struct drm_crtc_state *state, u32 crtc_y, u32 crtc_h,
- u32 *padding_y, u32 *padding_start, u32 *padding_height);
- void sde_crtc_backlight_notify(struct drm_crtc *crtc, u32 bl_val, u32 bl_max);
- #endif
|