--- /dev/null +++ b/include/trace/mdss_mdp_trace.h @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#if !defined(TRACE_MDSS_MDP_H) || defined(TRACE_HEADER_MULTI_READ) +#define TRACE_MDSS_MDP_H + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mdss +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE mdss_mdp_trace + +#include +#include "mdss_mdp.h" + +DECLARE_EVENT_CLASS(mdp_sspp_template, + TP_PROTO(struct mdss_mdp_pipe *pipe), + TP_ARGS(pipe), + TP_STRUCT__entry( + __field(u32, num) + __field(u32, play_cnt) + __field(u32, mixer) + __field(u32, stage) + __field(u32, flags) + __field(u32, format) + __field(u16, img_w) + __field(u16, img_h) + __field(u16, src_x) + __field(u16, src_y) + __field(u16, src_w) + __field(u16, src_h) + __field(u16, dst_x) + __field(u16, dst_y) + __field(u16, dst_w) + __field(u16, dst_h) + ), + TP_fast_assign( + __entry->num = pipe->num; + __entry->play_cnt = pipe->play_cnt; + __entry->mixer = pipe->mixer->num; + __entry->stage = pipe->mixer_stage; + __entry->flags = pipe->flags; + __entry->format = pipe->src_fmt ? + pipe->src_fmt->format : -1; + __entry->img_w = pipe->img_width; + __entry->img_h = pipe->img_height; + __entry->src_x = pipe->src.x; + __entry->src_y = pipe->src.y; + __entry->src_w = pipe->src.w; + __entry->src_h = pipe->src.h; + __entry->dst_x = pipe->dst.x; + __entry->dst_y = pipe->dst.y; + __entry->dst_w = pipe->dst.w; + __entry->dst_h = pipe->dst.h; + ), + + TP_printk("num=%d mixer=%d play_cnt=%d flags=0x%x stage=%d format=%d img=%dx%d src=[%d,%d,%d,%d] dst=[%d,%d,%d,%d]", + __entry->num, __entry->mixer, __entry->play_cnt, + __entry->flags, __entry->stage, + __entry->format, __entry->img_w, __entry->img_h, + __entry->src_x, __entry->src_y, + __entry->src_w, __entry->src_h, + __entry->dst_x, __entry->dst_y, + __entry->dst_w, __entry->dst_h) +); + +DEFINE_EVENT(mdp_sspp_template, mdp_sspp_set, + TP_PROTO(struct mdss_mdp_pipe *pipe), + TP_ARGS(pipe) +); + +DEFINE_EVENT(mdp_sspp_template, mdp_sspp_change, + TP_PROTO(struct mdss_mdp_pipe *pipe), + TP_ARGS(pipe) +); + +TRACE_EVENT(mdp_mixer_update, + TP_PROTO(u32 mixer_num), + TP_ARGS(mixer_num), + TP_STRUCT__entry( + __field(u32, mixer_num) + ), + TP_fast_assign( + __entry->mixer_num = mixer_num; + ), + TP_printk("mixer=%d", + __entry->mixer_num) +); + +TRACE_EVENT(mdp_commit, + TP_PROTO(struct mdss_mdp_ctl *ctl), + TP_ARGS(ctl), + TP_STRUCT__entry( + __field(u32, num) + __field(u32, play_cnt) + __field(u32, clk_rate) + __field(u64, bandwidth) + ), + TP_fast_assign( + __entry->num = ctl->num; + __entry->play_cnt = ctl->play_cnt; + __entry->clk_rate = ctl->new_perf.mdp_clk_rate; + __entry->bandwidth = ctl->new_perf.bw_ctl; + ), + TP_printk("num=%d play_cnt=%d bandwidth=%llu clk_rate=%u", + __entry->num, + __entry->play_cnt, + __entry->bandwidth, + __entry->clk_rate) +); + +TRACE_EVENT(mdp_video_underrun_done, + TP_PROTO(u32 ctl_num, u32 underrun_cnt), + TP_ARGS(ctl_num, underrun_cnt), + TP_STRUCT__entry( + __field(u32, ctl_num) + __field(u32, underrun_cnt) + ), + TP_fast_assign( + __entry->ctl_num = ctl_num; + __entry->underrun_cnt = underrun_cnt; + ), + TP_printk("ctl=%d count=%d", + __entry->ctl_num, __entry->underrun_cnt) +); + +TRACE_EVENT(mdp_perf_update_bus, + TP_PROTO(unsigned long long ab_quota, unsigned long long ib_quota), + TP_ARGS(ab_quota, ib_quota), + TP_STRUCT__entry( + __field(u64, ab_quota) + __field(u64, ib_quota) + ), + TP_fast_assign( + __entry->ab_quota = ab_quota; + __entry->ib_quota = ib_quota; + ), + TP_printk("ab=%llu ib=%llu", + __entry->ab_quota, + __entry->ib_quota) +); + +TRACE_EVENT(mdp_cmd_pingpong_done, + TP_PROTO(struct mdss_mdp_ctl *ctl, u32 pp_num, int koff_cnt), + TP_ARGS(ctl, pp_num, koff_cnt), + TP_STRUCT__entry( + __field(u32, ctl_num) + __field(u32, intf_num) + __field(u32, pp_num) + __field(int, koff_cnt) + ), + TP_fast_assign( + __entry->ctl_num = ctl->num; + __entry->intf_num = ctl->intf_num; + __entry->pp_num = pp_num; + __entry->koff_cnt = koff_cnt; + ), + TP_printk("ctl num:%d intf_num:%d ctx:%d kickoff:%d", + __entry->ctl_num, __entry->intf_num, __entry->pp_num, + __entry->koff_cnt) +); + +TRACE_EVENT(mdp_cmd_release_bw, + TP_PROTO(u32 ctl_num), + TP_ARGS(ctl_num), + TP_STRUCT__entry( + __field(u32, ctl_num) + ), + TP_fast_assign( + __entry->ctl_num = ctl_num; + ), + TP_printk("ctl num:%d", __entry->ctl_num) +); + +TRACE_EVENT(mdp_cmd_kickoff, + TP_PROTO(u32 ctl_num, int kickoff_cnt), + TP_ARGS(ctl_num, kickoff_cnt), + TP_STRUCT__entry( + __field(u32, ctl_num) + __field(int, kickoff_cnt) + ), + TP_fast_assign( + __entry->ctl_num = ctl_num; + __entry->kickoff_cnt = kickoff_cnt; + ), + TP_printk("kickoff ctl=%d cnt=%d", + __entry->ctl_num, + __entry->kickoff_cnt) +); + +TRACE_EVENT(mdp_cmd_wait_pingpong, + TP_PROTO(u32 ctl_num, int kickoff_cnt), + TP_ARGS(ctl_num, kickoff_cnt), + TP_STRUCT__entry( + __field(u32, ctl_num) + __field(int, kickoff_cnt) + ), + TP_fast_assign( + __entry->ctl_num = ctl_num; + __entry->kickoff_cnt = kickoff_cnt; + ), + TP_printk("pingpong ctl=%d cnt=%d", + __entry->ctl_num, + __entry->kickoff_cnt) +); + +TRACE_EVENT(tracing_mark_write, + TP_PROTO(int pid, const char *name, bool trace_begin), + TP_ARGS(pid, name, trace_begin), + TP_STRUCT__entry( + __field(int, pid) + __string(trace_name, name) + __field(bool, trace_begin) + ), + TP_fast_assign( + __entry->pid = pid; + __assign_str(trace_name, name); + __entry->trace_begin = trace_begin; + ), + TP_printk("%s|%d|%s", __entry->trace_begin ? "B" : "E", + __entry->pid, __get_str(trace_name)) +); + +TRACE_EVENT(mdp_trace_counter, + TP_PROTO(int pid, char *name, int value), + TP_ARGS(pid, name, value), + TP_STRUCT__entry( + __field(int, pid) + __string(counter_name, name) + __field(int, value) + ), + TP_fast_assign( + __entry->pid = current->tgid; + __assign_str(counter_name, name); + __entry->value = value; + ), + TP_printk("%d|%s|%d", __entry->pid, + __get_str(counter_name), __entry->value) +); + +#endif /* if !defined(TRACE_MDSS_MDP_H) || defined(TRACE_HEADER_MULTI_READ) */ + +/* This part must be outside protection */ +#include --- /dev/null +++ b/include/trace/mdss_mdp.h @@ -0,0 +1,765 @@ +/* + * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef MDSS_MDP_H +#define MDSS_MDP_H + +#include +#include +#include +#include +#include + +#include "mdss.h" +#include "mdss_mdp_hwio.h" +#include "mdss_fb.h" + +#define MDSS_MDP_DEFAULT_INTR_MASK 0 +#define MDSS_MDP_CURSOR_WIDTH 64 +#define MDSS_MDP_CURSOR_HEIGHT 64 +#define MDSS_MDP_CURSOR_SIZE (MDSS_MDP_CURSOR_WIDTH*MDSS_MDP_CURSOR_WIDTH*4) + +#define MDP_CLK_DEFAULT_RATE 200000000 +#define PHASE_STEP_SHIFT 21 +#define MAX_MIXER_WIDTH 2048 +#define MAX_LINE_BUFFER_WIDTH 2048 +#define MAX_MIXER_HEIGHT 0xFFFF +#define MAX_IMG_WIDTH 0x3FFF +#define MAX_IMG_HEIGHT 0x3FFF +#define MAX_DST_W MAX_MIXER_WIDTH +#define MAX_DST_H MAX_MIXER_HEIGHT +#define MAX_DOWNSCALE_RATIO 4 +#define MAX_UPSCALE_RATIO 20 +#define MAX_DECIMATION 4 +#define MDP_MIN_VBP 4 +#define MAX_FREE_LIST_SIZE 12 + +#define C3_ALPHA 3 /* alpha */ +#define C2_R_Cr 2 /* R/Cr */ +#define C1_B_Cb 1 /* B/Cb */ +#define C0_G_Y 0 /* G/luma */ + +/* wait for at most 2 vsync for lowest refresh rate (24hz) */ +#define KOFF_TIMEOUT msecs_to_jiffies(84) + +#define OVERFETCH_DISABLE_TOP BIT(0) +#define OVERFETCH_DISABLE_BOTTOM BIT(1) +#define OVERFETCH_DISABLE_LEFT BIT(2) +#define OVERFETCH_DISABLE_RIGHT BIT(3) + +#ifdef MDSS_MDP_DEBUG_REG +static inline void mdss_mdp_reg_write(u32 addr, u32 val) +{ + pr_debug("0x%05X = 0x%08X\n", addr, val); + MDSS_REG_WRITE(addr, val); +} +#define MDSS_MDP_REG_WRITE(addr, val) mdss_mdp_reg_write((u32)addr, (u32)(val)) +static inline u32 mdss_mdp_reg_read(u32 addr) +{ + u32 val; + val = MDSS_REG_READ(addr); + pr_debug("0x%05X = 0x%08X\n", addr, val); + return val; +} +#define MDSS_MDP_REG_READ(addr) mdss_mdp_reg_read((u32)(addr)) +#else +#define MDSS_MDP_REG_WRITE(addr, val) MDSS_REG_WRITE((u32)(addr), (u32)(val)) +#define MDSS_MDP_REG_READ(addr) MDSS_REG_READ((u32)(addr)) +#endif +#define PERF_STATUS_DONE 0 +#define PERF_STATUS_BUSY 1 + +enum mdss_mdp_perf_state_type { + PERF_SW_COMMIT_STATE = 0, + PERF_HW_MDP_STATE, +}; + +enum mdss_mdp_block_power_state { + MDP_BLOCK_POWER_OFF = 0, + MDP_BLOCK_POWER_ON = 1, +}; + +enum mdss_mdp_mixer_type { + MDSS_MDP_MIXER_TYPE_UNUSED, + MDSS_MDP_MIXER_TYPE_INTF, + MDSS_MDP_MIXER_TYPE_WRITEBACK, +}; + +enum mdss_mdp_mixer_mux { + MDSS_MDP_MIXER_MUX_DEFAULT, + MDSS_MDP_MIXER_MUX_LEFT, + MDSS_MDP_MIXER_MUX_RIGHT, +}; + +enum mdss_mdp_pipe_type { + MDSS_MDP_PIPE_TYPE_UNUSED, + MDSS_MDP_PIPE_TYPE_VIG, + MDSS_MDP_PIPE_TYPE_RGB, + MDSS_MDP_PIPE_TYPE_DMA, +}; + +enum mdss_mdp_block_type { + MDSS_MDP_BLOCK_UNUSED, + MDSS_MDP_BLOCK_SSPP, + MDSS_MDP_BLOCK_MIXER, + MDSS_MDP_BLOCK_DSPP, + MDSS_MDP_BLOCK_WB, + MDSS_MDP_BLOCK_MAX +}; + +enum mdss_mdp_csc_type { + MDSS_MDP_CSC_RGB2RGB, + MDSS_MDP_CSC_YUV2RGB, + MDSS_MDP_CSC_RGB2YUV, + MDSS_MDP_CSC_YUV2YUV, + MDSS_MDP_MAX_CSC +}; + +struct splash_pipe_cfg { + int width; + int height; + int mixer; +}; + +struct mdss_mdp_ctl; +typedef void (*mdp_vsync_handler_t)(struct mdss_mdp_ctl *, ktime_t); + +struct mdss_mdp_img_rect { + u16 x; + u16 y; + u16 w; + u16 h; +}; + +struct mdss_mdp_vsync_handler { + bool enabled; + bool cmd_post_flush; + mdp_vsync_handler_t vsync_handler; + struct list_head list; +}; + +enum mdss_mdp_wb_ctl_type { + MDSS_MDP_WB_CTL_TYPE_BLOCK = 1, + MDSS_MDP_WB_CTL_TYPE_LINE +}; + +struct mdss_mdp_perf_params { + u64 bw_overlap; + u64 bw_prefill; + u32 prefill_bytes; + u64 bw_ctl; + u32 mdp_clk_rate; +}; + +struct mdss_mdp_ctl { + u32 num; + char __iomem *base; + char __iomem *wb_base; + u32 ref_cnt; + int power_on; + + u32 intf_num; + u32 intf_type; + + u32 opmode; + u32 flush_bits; + + bool is_video_mode; + u32 play_cnt; + u32 vsync_cnt; + u32 underrun_cnt; + + u16 width; + u16 height; + u32 dst_format; + bool is_secure; + + u32 clk_rate; + int force_screen_state; + struct mdss_mdp_perf_params cur_perf; + struct mdss_mdp_perf_params new_perf; + u32 perf_transaction_status; + + struct mdss_data_type *mdata; + struct msm_fb_data_type *mfd; + struct mdss_mdp_mixer *mixer_left; + struct mdss_mdp_mixer *mixer_right; + struct mutex lock; + struct mutex *shared_lock; + struct mutex *wb_lock; + spinlock_t spin_lock; + + struct mdss_panel_data *panel_data; + struct mdss_mdp_vsync_handler vsync_handler; + struct mdss_mdp_vsync_handler recover_underrun_handler; + struct work_struct recover_work; + struct work_struct remove_underrun_handler; + + struct mdss_mdp_img_rect roi; + struct mdss_mdp_img_rect roi_bkup; + u8 roi_changed; + + int (*start_fnc) (struct mdss_mdp_ctl *ctl); + int (*stop_fnc) (struct mdss_mdp_ctl *ctl); + int (*prepare_fnc) (struct mdss_mdp_ctl *ctl, void *arg); + int (*display_fnc) (struct mdss_mdp_ctl *ctl, void *arg); + int (*wait_fnc) (struct mdss_mdp_ctl *ctl, void *arg); + int (*wait_pingpong) (struct mdss_mdp_ctl *ctl, void *arg); + u32 (*read_line_cnt_fnc) (struct mdss_mdp_ctl *); + int (*add_vsync_handler) (struct mdss_mdp_ctl *, + struct mdss_mdp_vsync_handler *); + int (*remove_vsync_handler) (struct mdss_mdp_ctl *, + struct mdss_mdp_vsync_handler *); + int (*config_fps_fnc) (struct mdss_mdp_ctl *ctl, + struct mdss_mdp_ctl *sctl, int new_fps); + + struct blocking_notifier_head notifier_head; + + void *priv_data; + u32 wb_type; + u64 bw_pending; +}; + +struct mdss_mdp_mixer { + u32 num; + u32 ref_cnt; + char __iomem *base; + char __iomem *dspp_base; + char __iomem *pingpong_base; + u8 type; + u8 params_changed; + u16 width; + u16 height; + struct mdss_mdp_img_rect roi; + u8 cursor_enabled; + u8 rotator_mode; + + struct mdss_mdp_ctl *ctl; + struct mdss_mdp_pipe *stage_pipe[MDSS_MDP_MAX_STAGE]; +}; + +struct mdss_mdp_format_params { + u32 format; + u8 is_yuv; + + u8 frame_format; + u8 chroma_sample; + u8 solid_fill; + u8 fetch_planes; + u8 unpack_align_msb; /* 0 to LSB, 1 to MSB */ + u8 unpack_tight; /* 0 for loose, 1 for tight */ + u8 unpack_count; /* 0 = 1 component, 1 = 2 component ... */ + u8 bpp; + u8 alpha_enable; /* source has alpha */ + u8 tile; + u8 bits[MAX_PLANES]; + u8 element[MAX_PLANES]; +}; + +struct mdss_mdp_plane_sizes { + u32 num_planes; + u32 plane_size[MAX_PLANES]; + u32 total_size; + u32 ystride[MAX_PLANES]; + u32 rau_cnt; + u32 rau_h[2]; +}; + +struct mdss_mdp_img_data { + u32 addr; + u32 len; + u32 flags; + int p_need; + bool mapped; + struct file *srcp_file; + struct ion_handle *srcp_ihdl; +}; + +struct mdss_mdp_data { + u8 num_planes; + u8 bwc_enabled; + struct mdss_mdp_img_data p[MAX_PLANES]; +}; + +struct pp_hist_col_info { + u32 col_state; + u32 col_en; + u32 read_request; + u32 hist_cnt_read; + u32 hist_cnt_sent; + u32 hist_cnt_time; + u32 frame_cnt; + struct completion comp; + struct completion first_kick; + u32 data[HIST_V_SIZE]; + struct mutex hist_mutex; + spinlock_t hist_lock; +}; + +struct mdss_mdp_ad { + char __iomem *base; + u8 num; +}; + +struct mdss_ad_info { + u8 num; + u8 calc_hw_num; + u32 ops; + u32 sts; + u32 reg_sts; + u32 state; + u32 ad_data; + u32 ad_data_mode; + struct mdss_ad_init init; + struct mdss_ad_cfg cfg; + struct mutex lock; + struct work_struct calc_work; + struct msm_fb_data_type *mfd; + struct msm_fb_data_type *bl_mfd; + struct mdss_mdp_vsync_handler handle; + struct completion comp; + u32 last_str; + u32 last_bl; + u32 bl_data; + u32 calc_itr; + uint32_t bl_lin[AD_BL_LIN_LEN]; + uint32_t bl_lin_inv[AD_BL_LIN_LEN]; + uint32_t bl_att_lut[AD_BL_ATT_LUT_LEN]; +}; + +struct pp_sts_type { + u32 pa_sts; + u32 pcc_sts; + u32 igc_sts; + u32 igc_tbl_idx; + u32 argc_sts; + u32 enhist_sts; + u32 dither_sts; + u32 gamut_sts; + u32 pgc_sts; + u32 sharp_sts; +}; + +struct mdss_pipe_pp_res { + u32 igc_c0_c1[IGC_LUT_ENTRIES]; + u32 igc_c2[IGC_LUT_ENTRIES]; + u32 hist_lut[ENHIST_LUT_ENTRIES]; + struct pp_hist_col_info hist; + struct pp_sts_type pp_sts; +}; + +struct mdss_mdp_pipe_smp_map { + DECLARE_BITMAP(reserved, MAX_DRV_SUP_MMB_BLKS); + DECLARE_BITMAP(allocated, MAX_DRV_SUP_MMB_BLKS); + DECLARE_BITMAP(fixed, MAX_DRV_SUP_MMB_BLKS); +}; + +struct mdss_mdp_shared_reg_ctrl { + u32 reg_off; + u32 bit_off; +}; + +struct mdss_mdp_pipe { + u32 num; + u32 type; + u32 ndx; + char __iomem *base; + u32 ftch_id; + u32 xin_id; + struct mdss_mdp_shared_reg_ctrl clk_ctrl; + struct mdss_mdp_shared_reg_ctrl clk_status; + + struct kref kref; + + u32 play_cnt; + int pid; + bool is_handed_off; + + u32 flags; + u32 bwc_mode; + + u16 img_width; + u16 img_height; + u8 horz_deci; + u8 vert_deci; + struct mdss_mdp_img_rect src; + struct mdss_mdp_img_rect dst; + struct mdss_mdp_format_params *src_fmt; + struct mdss_mdp_plane_sizes src_planes; + + u8 mixer_stage; + u8 is_fg; + u8 alpha; + u8 blend_op; + u8 overfetch_disable; + u32 transp; + u32 bg_color; + + struct msm_fb_data_type *mfd; + struct mdss_mdp_mixer *mixer; + + struct mdp_overlay req_data; + u32 params_changed; + + struct mdss_mdp_pipe_smp_map smp_map[MAX_PLANES]; + + struct mdss_mdp_data back_buf; + struct mdss_mdp_data front_buf; + + struct list_head list; + + struct mdp_overlay_pp_params pp_cfg; + struct mdss_pipe_pp_res pp_res; + struct mdp_scale_data scale; + u8 chroma_sample_h; + u8 chroma_sample_v; +}; + +struct mdss_mdp_writeback_arg { + struct mdss_mdp_data *data; + void *priv_data; +}; + +struct mdss_overlay_private { + ktime_t vsync_time; + struct sysfs_dirent *vsync_event_sd; + int borderfill_enable; + int overlay_play_enable; + int hw_refresh; + void *cpu_pm_hdl; + + struct mdss_data_type *mdata; + struct mutex ov_lock; + struct mutex dfps_lock; + struct mdss_mdp_ctl *ctl; + struct mdss_mdp_wb *wb; + + struct mutex list_lock; + struct list_head overlay_list; + struct list_head pipes_used; + struct list_head pipes_cleanup; + struct list_head rot_proc_list; + bool mixer_swap; + + struct mdss_mdp_data free_list[MAX_FREE_LIST_SIZE]; + int free_list_size; + int ad_state; + + bool handoff; + u32 splash_mem_addr; + u32 splash_mem_size; + u32 sd_enabled; + + struct sw_sync_timeline *vsync_timeline; + struct mdss_mdp_vsync_handler vsync_retire_handler; + struct work_struct retire_work; + int retire_cnt; +}; + +/** + * enum mdss_screen_state - Screen states that MDP can be forced into + * + * @MDSS_SCREEN_DEFAULT: Do not force MDP into any screen state. + * @MDSS_SCREEN_FORCE_BLANK: Force MDP to generate blank color fill screen. + */ +enum mdss_screen_state { + MDSS_SCREEN_DEFAULT, + MDSS_SCREEN_FORCE_BLANK, +}; + +#define is_vig_pipe(_pipe_id_) ((_pipe_id_) <= MDSS_MDP_SSPP_VIG2) + +static inline struct mdss_mdp_ctl *mdss_mdp_get_split_ctl( + struct mdss_mdp_ctl *ctl) +{ + if (ctl && ctl->mixer_right && (ctl->mixer_right->ctl != ctl)) + return ctl->mixer_right->ctl; + + return NULL; +} + +static inline void mdss_mdp_ctl_write(struct mdss_mdp_ctl *ctl, + u32 reg, u32 val) +{ + writel_relaxed(val, ctl->base + reg); +} + +static inline u32 mdss_mdp_ctl_read(struct mdss_mdp_ctl *ctl, u32 reg) +{ + return readl_relaxed(ctl->base + reg); +} + +static inline void mdss_mdp_pingpong_write(struct mdss_mdp_mixer *mixer, + u32 reg, u32 val) +{ + writel_relaxed(val, mixer->pingpong_base + reg); +} + +static inline u32 mdss_mdp_pingpong_read(struct mdss_mdp_mixer *mixer, u32 reg) +{ + return readl_relaxed(mixer->pingpong_base + reg); +} + +static inline int mdss_mdp_iommu_dyn_attach_supported( + struct mdss_data_type *mdata) +{ + return (mdata->mdp_rev >= MDSS_MDP_HW_REV_103); +} + +static inline int mdss_mdp_line_buffer_width(void) +{ + return MAX_LINE_BUFFER_WIDTH; +} + +static inline void mdss_update_sd_client(struct mdss_data_type *mdata, + bool status) +{ + if (status) + atomic_inc(&mdata->sd_client_count); + else + atomic_add_unless(&mdss_res->sd_client_count, -1, 0); +} + +irqreturn_t mdss_mdp_isr(int irq, void *ptr); +int mdss_iommu_attach(struct mdss_data_type *mdata); +int mdss_iommu_dettach(struct mdss_data_type *mdata); +int mdss_mdp_scan_cont_splash(void); +void mdss_mdp_irq_clear(struct mdss_data_type *mdata, + u32 intr_type, u32 intf_num); +int mdss_mdp_irq_enable(u32 intr_type, u32 intf_num); +void mdss_mdp_irq_disable(u32 intr_type, u32 intf_num); +int mdss_mdp_hist_irq_enable(u32 irq); +void mdss_mdp_hist_irq_disable(u32 irq); +void mdss_mdp_irq_disable_nosync(u32 intr_type, u32 intf_num); +int mdss_mdp_set_intr_callback(u32 intr_type, u32 intf_num, + void (*fnc_ptr)(void *), void *arg); + +void mdss_mdp_footswitch_ctrl_splash(int on); +void mdss_mdp_batfet_ctrl(struct mdss_data_type *mdata, int enable); +int mdss_mdp_bus_scale_set_quota(u64 ab_quota, u64 ib_quota); +void mdss_mdp_set_clk_rate(unsigned long min_clk_rate); +unsigned long mdss_mdp_get_clk_rate(u32 clk_idx); +int mdss_mdp_vsync_clk_enable(int enable); +void mdss_mdp_clk_ctrl(int enable, int isr); +struct mdss_data_type *mdss_mdp_get_mdata(void); +int mdss_mdp_secure_display_ctrl(unsigned int enable); + +int mdss_mdp_overlay_init(struct msm_fb_data_type *mfd); +int mdss_mdp_overlay_req_check(struct msm_fb_data_type *mfd, + struct mdp_overlay *req, + struct mdss_mdp_format_params *fmt); +int mdss_mdp_overlay_vsync_ctrl(struct msm_fb_data_type *mfd, int en); +int mdss_mdp_overlay_get_buf(struct msm_fb_data_type *mfd, + struct mdss_mdp_data *data, + struct msmfb_data *planes, + int num_planes, + u32 flags); +int mdss_mdp_overlay_pipe_setup(struct msm_fb_data_type *mfd, + struct mdp_overlay *req, struct mdss_mdp_pipe **ppipe); +void mdss_mdp_handoff_cleanup_pipes(struct msm_fb_data_type *mfd, + u32 type); +int mdss_mdp_overlay_release(struct msm_fb_data_type *mfd, int ndx); +int mdss_mdp_overlay_start(struct msm_fb_data_type *mfd); +int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata, + u32 *offsets, u32 count); +int mdss_mdp_video_start(struct mdss_mdp_ctl *ctl); +int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl); +int mdss_mdp_writeback_start(struct mdss_mdp_ctl *ctl); +int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, + struct mdp_display_commit *data); + +struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata, + struct msm_fb_data_type *mfd); +int mdss_mdp_video_reconfigure_splash_done(struct mdss_mdp_ctl *ctl, + bool handoff); +int mdss_mdp_cmd_reconfigure_splash_done(struct mdss_mdp_ctl *ctl, + bool handoff); +int mdss_mdp_ctl_splash_finish(struct mdss_mdp_ctl *ctl, bool handoff); +int mdss_mdp_ctl_setup(struct mdss_mdp_ctl *ctl); +int mdss_mdp_ctl_split_display_setup(struct mdss_mdp_ctl *ctl, + struct mdss_panel_data *pdata); +int mdss_mdp_ctl_destroy(struct mdss_mdp_ctl *ctl); +int mdss_mdp_ctl_start(struct mdss_mdp_ctl *ctl, bool handoff); +int mdss_mdp_ctl_stop(struct mdss_mdp_ctl *ctl); +int mdss_mdp_ctl_intf_event(struct mdss_mdp_ctl *ctl, int event, void *arg); +int mdss_mdp_perf_bw_check(struct mdss_mdp_ctl *ctl, + struct mdss_mdp_pipe **left_plist, int left_cnt, + struct mdss_mdp_pipe **right_plist, int right_cnt); +int mdss_mdp_perf_calc_pipe(struct mdss_mdp_pipe *pipe, + struct mdss_mdp_perf_params *perf, struct mdss_mdp_img_rect *roi, + bool apply_fudge); +int mdss_mdp_ctl_notify(struct mdss_mdp_ctl *ctl, int event); +void mdss_mdp_ctl_notifier_register(struct mdss_mdp_ctl *ctl, + struct notifier_block *notifier); +void mdss_mdp_ctl_notifier_unregister(struct mdss_mdp_ctl *ctl, + struct notifier_block *notifier); + +int mdss_mdp_mixer_handoff(struct mdss_mdp_ctl *ctl, u32 num, + struct mdss_mdp_pipe *pipe); + +int mdss_mdp_scan_pipes(void); + +void mdss_mdp_ctl_perf_set_transaction_status(struct mdss_mdp_ctl *ctl, + enum mdss_mdp_perf_state_type component, bool new_status); +void mdss_mdp_ctl_perf_release_bw(struct mdss_mdp_ctl *ctl); + +struct mdss_mdp_mixer *mdss_mdp_wb_mixer_alloc(int rotator); +int mdss_mdp_wb_mixer_destroy(struct mdss_mdp_mixer *mixer); +struct mdss_mdp_mixer *mdss_mdp_mixer_get(struct mdss_mdp_ctl *ctl, int mux); +struct mdss_mdp_pipe *mdss_mdp_mixer_stage_pipe(struct mdss_mdp_ctl *ctl, + int mux, int stage); +int mdss_mdp_mixer_pipe_update(struct mdss_mdp_pipe *pipe, int params_changed); +int mdss_mdp_mixer_pipe_unstage(struct mdss_mdp_pipe *pipe); +void mdss_mdp_mixer_unstage_all(struct mdss_mdp_mixer *mixer); +int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg); +int mdss_mdp_display_wait4comp(struct mdss_mdp_ctl *ctl); +int mdss_mdp_display_wait4pingpong(struct mdss_mdp_ctl *ctl); +int mdss_mdp_display_wakeup_time(struct mdss_mdp_ctl *ctl, + ktime_t *wakeup_time); + +int mdss_mdp_csc_setup(u32 block, u32 blk_idx, u32 tbl_idx, u32 csc_type); +int mdss_mdp_csc_setup_data(u32 block, u32 blk_idx, u32 tbl_idx, + struct mdp_csc_cfg *data); + +int mdss_mdp_pp_init(struct device *dev); +void mdss_mdp_pp_term(struct device *dev); +int mdss_mdp_pp_overlay_init(struct msm_fb_data_type *mfd); + +int mdss_mdp_pp_resume(struct mdss_mdp_ctl *ctl, u32 mixer_num); + +int mdss_mdp_pp_setup(struct mdss_mdp_ctl *ctl); +int mdss_mdp_pp_setup_locked(struct mdss_mdp_ctl *ctl); +int mdss_mdp_pipe_pp_setup(struct mdss_mdp_pipe *pipe, u32 *op); +int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op); +void mdss_mdp_pipe_sspp_term(struct mdss_mdp_pipe *pipe); +int mdss_mdp_smp_setup(struct mdss_data_type *mdata, u32 cnt, u32 size); + +int mdss_hw_init(struct mdss_data_type *mdata); + +int mdss_mdp_pa_config(struct mdp_pa_cfg_data *config, u32 *copyback); +int mdss_mdp_pa_v2_config(struct mdp_pa_v2_cfg_data *config, u32 *copyback); +int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *cfg_ptr, u32 *copyback); +int mdss_mdp_igc_lut_config(struct mdp_igc_lut_data *config, u32 *copyback, + u32 copy_from_kernel); +int mdss_mdp_argc_config(struct mdp_pgc_lut_data *config, u32 *copyback); +int mdss_mdp_hist_lut_config(struct mdp_hist_lut_data *config, u32 *copyback); +int mdss_mdp_dither_config(struct mdp_dither_cfg_data *config, u32 *copyback); +int mdss_mdp_gamut_config(struct mdp_gamut_cfg_data *config, u32 *copyback); + +int mdss_mdp_hist_intr_req(struct mdss_intr *intr, u32 bits, bool en); +int mdss_mdp_hist_intr_setup(struct mdss_intr *intr, int state); +int mdss_mdp_hist_start(struct mdp_histogram_start_req *req); +int mdss_mdp_hist_stop(u32 block); +int mdss_mdp_hist_collect(struct mdp_histogram_data *hist); +void mdss_mdp_hist_intr_done(u32 isr); + +int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, + struct mdss_ad_init_cfg *init_cfg); +int mdss_mdp_ad_input(struct msm_fb_data_type *mfd, + struct mdss_ad_input *input, int wait); +int mdss_mdp_ad_addr_setup(struct mdss_data_type *mdata, u32 *ad_offsets); +int mdss_mdp_calib_mode(struct msm_fb_data_type *mfd, + struct mdss_calib_cfg *cfg); + +int mdss_mdp_pipe_handoff(struct mdss_mdp_pipe *pipe); +int mdss_mdp_smp_handoff(struct mdss_data_type *mdata); +struct mdss_mdp_pipe *mdss_mdp_pipe_alloc(struct mdss_mdp_mixer *mixer, + u32 type); +struct mdss_mdp_pipe *mdss_mdp_pipe_get(struct mdss_data_type *mdata, u32 ndx); +struct mdss_mdp_pipe *mdss_mdp_pipe_search(struct mdss_data_type *mdata, + u32 ndx); +int mdss_mdp_pipe_map(struct mdss_mdp_pipe *pipe); +void mdss_mdp_pipe_unmap(struct mdss_mdp_pipe *pipe); +struct mdss_mdp_pipe *mdss_mdp_pipe_alloc_dma(struct mdss_mdp_mixer *mixer); + +u32 mdss_mdp_smp_get_size(struct mdss_mdp_pipe *pipe); +int mdss_mdp_smp_reserve(struct mdss_mdp_pipe *pipe); +void mdss_mdp_smp_unreserve(struct mdss_mdp_pipe *pipe); +void mdss_mdp_smp_release(struct mdss_mdp_pipe *pipe); + +int mdss_mdp_pipe_addr_setup(struct mdss_data_type *mdata, + struct mdss_mdp_pipe *head, u32 *offsets, u32 *ftch_y_id, u32 *xin_id, + u32 type, u32 num_base, u32 len); +int mdss_mdp_mixer_addr_setup(struct mdss_data_type *mdata, u32 *mixer_offsets, + u32 *dspp_offsets, u32 *pingpong_offsets, u32 type, u32 len); +int mdss_mdp_ctl_addr_setup(struct mdss_data_type *mdata, u32 *ctl_offsets, + u32 *wb_offsets, u32 len); + +int mdss_mdp_pipe_fetch_halt(struct mdss_mdp_pipe *pipe); +int mdss_mdp_pipe_destroy(struct mdss_mdp_pipe *pipe); +int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, + struct mdss_mdp_data *src_data); + +int mdss_mdp_data_check(struct mdss_mdp_data *data, + struct mdss_mdp_plane_sizes *ps); +int mdss_mdp_get_plane_sizes(u32 format, u32 w, u32 h, + struct mdss_mdp_plane_sizes *ps, u32 bwc_mode, bool rotation); +int mdss_mdp_get_rau_strides(u32 w, u32 h, struct mdss_mdp_format_params *fmt, + struct mdss_mdp_plane_sizes *ps); +void mdss_mdp_data_calc_offset(struct mdss_mdp_data *data, u16 x, u16 y, + struct mdss_mdp_plane_sizes *ps, struct mdss_mdp_format_params *fmt); +struct mdss_mdp_format_params *mdss_mdp_get_format_params(u32 format); +int mdss_mdp_put_img(struct mdss_mdp_img_data *data); +int mdss_mdp_get_img(struct msmfb_data *img, struct mdss_mdp_img_data *data); +int mdss_mdp_overlay_free_buf(struct mdss_mdp_data *data); +u32 mdss_get_panel_framerate(struct msm_fb_data_type *mfd); +int mdss_mdp_calc_phase_step(u32 src, u32 dst, u32 *out_phase); +void mdss_mdp_intersect_rect(struct mdss_mdp_img_rect *res_rect, + const struct mdss_mdp_img_rect *dst_rect, + const struct mdss_mdp_img_rect *sci_rect); +void mdss_mdp_crop_rect(struct mdss_mdp_img_rect *src_rect, + struct mdss_mdp_img_rect *dst_rect, + const struct mdss_mdp_img_rect *sci_rect); + + +int mdss_mdp_wb_kickoff(struct msm_fb_data_type *mfd); +int mdss_mdp_wb_ioctl_handler(struct msm_fb_data_type *mfd, u32 cmd, void *arg); + +int mdss_mdp_get_ctl_mixers(u32 fb_num, u32 *mixer_id); +u32 mdss_mdp_fb_stride(u32 fb_index, u32 xres, int bpp); +void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval); + +int mdss_panel_register_done(struct mdss_panel_data *pdata); +int mdss_mdp_limited_lut_igc_config(struct mdss_mdp_ctl *ctl); +int mdss_mdp_calib_config(struct mdp_calib_config_data *cfg, u32 *copyback); +int mdss_mdp_calib_config_buffer(struct mdp_calib_config_buffer *cfg, + u32 *copyback); +int mdss_mdp_ctl_update_fps(struct mdss_mdp_ctl *ctl, int fps); +int mdss_mdp_pipe_is_staged(struct mdss_mdp_pipe *pipe); +int mdss_mdp_writeback_display_commit(struct mdss_mdp_ctl *ctl, void *arg); +struct mdss_mdp_ctl *mdss_mdp_ctl_mixer_switch(struct mdss_mdp_ctl *ctl, + u32 return_type); +void mdss_mdp_set_roi(struct mdss_mdp_ctl *ctl, + struct mdp_display_commit *data); + +int mdss_mdp_wb_set_format(struct msm_fb_data_type *mfd, u32 dst_format); +int mdss_mdp_wb_get_format(struct msm_fb_data_type *mfd, + struct mdp_mixer_cfg *mixer_cfg); + +int mdss_mdp_wb_set_secure(struct msm_fb_data_type *mfd, int enable); +int mdss_mdp_wb_get_secure(struct msm_fb_data_type *mfd, uint8_t *enable); +void mdss_mdp_ctl_restore(struct mdss_mdp_ctl *ctl); +int mdss_mdp_footswitch_ctrl_ulps(int on, struct device *dev); + +int mdss_mdp_pipe_program_pixel_extn(struct mdss_mdp_pipe *pipe); +#define mfd_to_mdp5_data(mfd) (mfd->mdp.private1) +#define mfd_to_mdata(mfd) (((struct mdss_overlay_private *)\ + (mfd->mdp.private1))->mdata) +#define mfd_to_ctl(mfd) (((struct mdss_overlay_private *)\ + (mfd->mdp.private1))->ctl) +#define mfd_to_wb(mfd) (((struct mdss_overlay_private *)\ + (mfd->mdp.private1))->wb) + +int mdss_mdp_ctl_reset(struct mdss_mdp_ctl *ctl); +#endif /* MDSS_MDP_H */