| /* Copyright (c) 2012-2018, 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_H |
| #define MDSS_H |
| |
| #include <linux/msm_ion.h> |
| #include <linux/msm_mdp.h> |
| #include <linux/spinlock.h> |
| #include <linux/types.h> |
| #include <linux/workqueue.h> |
| #include <linux/irqreturn.h> |
| #include <linux/irqdomain.h> |
| #include <linux/mdss_io_util.h> |
| |
| #include <linux/msm-bus.h> |
| #include <linux/file.h> |
| #include <linux/dma-direction.h> |
| |
| #include "mdss_panel.h" |
| |
| #define MAX_DRV_SUP_MMB_BLKS 44 |
| #define MAX_DRV_SUP_PIPES 10 |
| #define MAX_CLIENT_NAME_LEN 20 |
| |
| #define MDSS_PINCTRL_STATE_DEFAULT "mdss_default" |
| #define MDSS_PINCTRL_STATE_SLEEP "mdss_sleep" |
| |
| enum mdss_mdp_clk_type { |
| MDSS_CLK_AHB, |
| MDSS_CLK_AXI, |
| MDSS_CLK_MDP_CORE, |
| MDSS_CLK_MDP_LUT, |
| MDSS_CLK_MDP_VSYNC, |
| MDSS_MAX_CLK |
| }; |
| |
| enum mdss_iommu_domain_type { |
| MDSS_IOMMU_DOMAIN_UNSECURE, |
| MDSS_IOMMU_DOMAIN_ROT_UNSECURE, |
| MDSS_IOMMU_DOMAIN_SECURE, |
| MDSS_IOMMU_DOMAIN_ROT_SECURE, |
| MDSS_IOMMU_MAX_DOMAIN |
| }; |
| |
| enum mdss_bus_vote_type { |
| VOTE_INDEX_DISABLE, |
| VOTE_INDEX_LOW, |
| VOTE_INDEX_MID, |
| VOTE_INDEX_HIGH, |
| VOTE_INDEX_MAX, |
| }; |
| |
| struct mdss_hw_settings { |
| char __iomem *reg; |
| u32 val; |
| }; |
| |
| struct mdss_max_bw_settings { |
| u32 mdss_max_bw_mode; |
| u32 mdss_max_bw_val; |
| }; |
| |
| struct mdss_debug_inf { |
| void *debug_data; |
| void (*debug_enable_clock)(int on); |
| }; |
| |
| struct mdss_perf_tune { |
| unsigned long min_mdp_clk; |
| u64 min_bus_vote; |
| }; |
| |
| #define MDSS_IRQ_SUSPEND -1 |
| #define MDSS_IRQ_RESUME 1 |
| #define MDSS_IRQ_REQ 0 |
| |
| struct mdss_intr { |
| /* requested intr */ |
| u32 req; |
| /* currently enabled intr */ |
| u32 curr; |
| int state; |
| spinlock_t lock; |
| }; |
| |
| struct simplified_prefill_factors { |
| u32 fmt_mt_nv12_factor; |
| u32 fmt_mt_factor; |
| u32 fmt_linear_factor; |
| u32 scale_factor; |
| u32 xtra_ff_factor; |
| }; |
| |
| struct mdss_prefill_data { |
| u32 ot_bytes; |
| u32 y_buf_bytes; |
| u32 y_scaler_lines_bilinear; |
| u32 y_scaler_lines_caf; |
| u32 post_scaler_pixels; |
| u32 pp_pixels; |
| u32 fbc_lines; |
| u32 ts_threshold; |
| u32 ts_end; |
| u32 ts_overhead; |
| struct mult_factor ts_rate; |
| struct simplified_prefill_factors prefill_factors; |
| }; |
| |
| struct mdss_mdp_dsc { |
| u32 num; |
| char __iomem *base; |
| }; |
| |
| enum mdss_hw_index { |
| MDSS_HW_MDP, |
| MDSS_HW_DSI0 = 1, |
| MDSS_HW_DSI1, |
| MDSS_HW_HDMI, |
| MDSS_HW_EDP, |
| MDSS_HW_MISC, |
| MDSS_MAX_HW_BLK |
| }; |
| |
| enum mdss_bus_clients { |
| MDSS_MDP_RT, |
| MDSS_DSI_RT, |
| MDSS_HW_RT, |
| MDSS_MDP_NRT, |
| MDSS_MAX_BUS_CLIENTS |
| }; |
| |
| struct mdss_pp_block_off { |
| u32 sspp_igc_lut_off; |
| u32 vig_pcc_off; |
| u32 rgb_pcc_off; |
| u32 dma_pcc_off; |
| u32 lm_pgc_off; |
| u32 dspp_gamut_off; |
| u32 dspp_pcc_off; |
| u32 dspp_pgc_off; |
| }; |
| |
| enum mdss_hw_quirk { |
| MDSS_QUIRK_BWCPANIC, |
| MDSS_QUIRK_ROTCDP, |
| MDSS_QUIRK_DOWNSCALE_HANG, |
| MDSS_QUIRK_DSC_RIGHT_ONLY_PU, |
| MDSS_QUIRK_DSC_2SLICE_PU_THRPUT, |
| MDSS_QUIRK_DMA_BI_DIR, |
| MDSS_QUIRK_FMT_PACK_PATTERN, |
| MDSS_QUIRK_NEED_SECURE_MAP, |
| MDSS_QUIRK_SRC_SPLIT_ALWAYS, |
| MDSS_QUIRK_HDR_SUPPORT_ENABLED, |
| MDSS_QUIRK_MAX, |
| }; |
| |
| enum mdss_hw_capabilities { |
| MDSS_CAPS_YUV_CONFIG, |
| MDSS_CAPS_SCM_RESTORE_NOT_REQUIRED, |
| MDSS_CAPS_3D_MUX_UNDERRUN_RECOVERY_SUPPORTED, |
| MDSS_CAPS_MIXER_1_FOR_WB, |
| MDSS_CAPS_QSEED3, |
| MDSS_CAPS_DEST_SCALER, |
| MDSS_CAPS_10_BIT_SUPPORTED, |
| MDSS_CAPS_MAX, |
| }; |
| |
| enum mdss_qos_settings { |
| MDSS_QOS_PER_PIPE_IB, |
| MDSS_QOS_OVERHEAD_FACTOR, |
| MDSS_QOS_CDP, |
| MDSS_QOS_OTLIM, |
| MDSS_QOS_PER_PIPE_LUT, |
| MDSS_QOS_SIMPLIFIED_PREFILL, |
| MDSS_QOS_VBLANK_PANIC_CTRL, |
| MDSS_QOS_TS_PREFILL, |
| MDSS_QOS_REMAPPER, |
| MDSS_QOS_IB_NOCR, |
| MDSS_QOS_MAX, |
| }; |
| |
| enum mdss_mdp_pipe_type { |
| MDSS_MDP_PIPE_TYPE_INVALID = -1, |
| MDSS_MDP_PIPE_TYPE_VIG = 0, |
| MDSS_MDP_PIPE_TYPE_RGB, |
| MDSS_MDP_PIPE_TYPE_DMA, |
| MDSS_MDP_PIPE_TYPE_CURSOR, |
| MDSS_MDP_PIPE_TYPE_MAX, |
| }; |
| |
| struct reg_bus_client { |
| char name[MAX_CLIENT_NAME_LEN]; |
| short usecase_ndx; |
| u32 id; |
| struct list_head list; |
| }; |
| |
| struct mdss_smmu_client { |
| struct device *dev; |
| struct dma_iommu_mapping *mmu_mapping; |
| struct mdss_module_power mp; |
| struct reg_bus_client *reg_bus_clt; |
| bool domain_attached; |
| bool handoff_pending; |
| char __iomem *mmu_base; |
| }; |
| |
| struct mdss_mdp_qseed3_lut_tbl { |
| bool valid; |
| u32 *dir_lut; |
| u32 *cir_lut; |
| u32 *sep_lut; |
| }; |
| |
| struct mdss_scaler_block { |
| u32 vig_scaler_off; |
| u32 vig_scaler_lut_off; |
| u32 has_dest_scaler; |
| char __iomem *dest_base; |
| u32 ndest_scalers; |
| u32 *dest_scaler_off; |
| u32 *dest_scaler_lut_off; |
| struct mdss_mdp_qseed3_lut_tbl lut_tbl; |
| |
| /* |
| * Lock is mainly to serialize access to LUT. |
| * LUT values come asynchronously from userspace |
| * via ioctl. |
| */ |
| struct mutex scaler_lock; |
| }; |
| |
| struct mdss_data_type; |
| |
| struct mdss_smmu_ops { |
| int (*smmu_attach)(struct mdss_data_type *mdata); |
| int (*smmu_detach)(struct mdss_data_type *mdata); |
| int (*smmu_get_domain_id)(u32 type); |
| struct dma_buf_attachment * (*smmu_dma_buf_attach)( |
| struct dma_buf *dma_buf, struct device *devce, |
| int domain); |
| int (*smmu_map_dma_buf)(struct dma_buf *dma_buf, |
| struct sg_table *table, int domain, |
| dma_addr_t *iova, unsigned long *size, int dir); |
| void (*smmu_unmap_dma_buf)(struct sg_table *table, int domain, |
| int dir, struct dma_buf *dma_buf); |
| int (*smmu_dma_alloc_coherent)(struct device *dev, size_t size, |
| dma_addr_t *phys, dma_addr_t *iova, void **cpu_addr, |
| gfp_t gfp, int domain); |
| void (*smmu_dma_free_coherent)(struct device *dev, size_t size, |
| void *cpu_addr, dma_addr_t phys, dma_addr_t iova, |
| int domain); |
| int (*smmu_map)(int domain, phys_addr_t iova, phys_addr_t phys, int |
| gfp_order, int prot); |
| void (*smmu_unmap)(int domain, unsigned long iova, int gfp_order); |
| char * (*smmu_dsi_alloc_buf)(struct device *dev, int size, |
| dma_addr_t *dmap, gfp_t gfp); |
| int (*smmu_dsi_map_buffer)(phys_addr_t phys, unsigned int domain, |
| unsigned long size, dma_addr_t *dma_addr, |
| void *cpu_addr, int dir); |
| void (*smmu_dsi_unmap_buffer)(dma_addr_t dma_addr, int domain, |
| unsigned long size, int dir); |
| void (*smmu_deinit)(struct mdss_data_type *mdata); |
| struct sg_table * (*smmu_sg_table_clone)(struct sg_table *orig_table, |
| gfp_t gfp_mask, bool padding); |
| }; |
| |
| struct mdss_data_type { |
| u32 mdp_rev; |
| struct clk *mdp_clk[MDSS_MAX_CLK]; |
| struct regulator *fs; |
| struct regulator *venus; |
| struct regulator *vdd_cx; |
| bool batfet_required; |
| struct regulator *batfet; |
| bool en_svs_high; |
| u32 max_mdp_clk_rate; |
| struct mdss_util_intf *mdss_util; |
| struct mdss_panel_data *pdata; |
| |
| struct platform_device *pdev; |
| struct mdss_io_data mdss_io; |
| struct mdss_io_data vbif_io; |
| struct mdss_io_data vbif_nrt_io; |
| char __iomem *mdp_base; |
| |
| struct mdss_smmu_client mdss_smmu[MDSS_IOMMU_MAX_DOMAIN]; |
| struct mdss_smmu_ops smmu_ops; |
| struct mutex reg_lock; |
| |
| /* bitmap to track pipes that have BWC enabled */ |
| DECLARE_BITMAP(bwc_enable_map, MAX_DRV_SUP_PIPES); |
| /* bitmap to track hw workarounds */ |
| DECLARE_BITMAP(mdss_quirk_map, MDSS_QUIRK_MAX); |
| /* bitmap to track total mmbs in use */ |
| DECLARE_BITMAP(mmb_alloc_map, MAX_DRV_SUP_MMB_BLKS); |
| /* bitmap to track qos applicable settings */ |
| DECLARE_BITMAP(mdss_qos_map, MDSS_QOS_MAX); |
| /* bitmap to track hw capabilities/features */ |
| DECLARE_BITMAP(mdss_caps_map, MDSS_CAPS_MAX); |
| |
| u32 has_bwc; |
| /* values used when HW has a common panic/robust LUT */ |
| u32 default_panic_lut0; |
| u32 default_panic_lut1; |
| u32 default_robust_lut; |
| |
| /* values used when HW has panic/robust LUTs per pipe */ |
| u32 default_panic_lut_per_pipe_linear; |
| u32 default_panic_lut_per_pipe_tile; |
| u32 default_robust_lut_per_pipe_linear; |
| u32 default_robust_lut_per_pipe_tile; |
| |
| u32 has_decimation; |
| bool has_fixed_qos_arbiter_enabled; |
| bool has_panic_ctrl; |
| u32 wfd_mode; |
| u32 has_no_lut_read; |
| atomic_t sd_client_count; |
| u8 has_wb_ad; |
| u8 has_non_scalar_rgb; |
| bool has_src_split; |
| bool idle_pc_enabled; |
| bool has_pingpong_split; |
| bool has_pixel_ram; |
| bool needs_hist_vote; |
| bool has_ubwc; |
| bool has_wb_ubwc; |
| bool has_separate_rotator; |
| |
| u32 default_ot_rd_limit; |
| u32 default_ot_wr_limit; |
| |
| struct irq_domain *irq_domain; |
| u32 *mdp_irq_mask; |
| u32 mdp_hist_irq_mask; |
| u32 mdp_intf_irq_mask; |
| |
| int suspend_fs_ena; |
| u8 clk_ena; |
| u8 fs_ena; |
| u8 vsync_ena; |
| |
| struct notifier_block gdsc_cb; |
| |
| u32 res_init; |
| |
| u32 highest_bank_bit; |
| u32 smp_mb_cnt; |
| u32 smp_mb_size; |
| u32 smp_mb_per_pipe; |
| u32 pixel_ram_size; |
| |
| u32 rot_block_size; |
| |
| /* HW RT bus (AXI) */ |
| u32 hw_rt_bus_hdl; |
| u32 hw_rt_bus_ref_cnt; |
| |
| /* data bus (AXI) */ |
| u32 bus_hdl; |
| u32 bus_ref_cnt; |
| struct mutex bus_lock; |
| |
| /* register bus (AHB) */ |
| u32 reg_bus_hdl; |
| u32 reg_bus_usecase_ndx; |
| struct list_head reg_bus_clist; |
| struct mutex reg_bus_lock; |
| struct reg_bus_client *reg_bus_clt; |
| struct reg_bus_client *pp_reg_bus_clt; |
| |
| u32 axi_port_cnt; |
| u32 nrt_axi_port_cnt; |
| u32 bus_channels; |
| u32 curr_bw_uc_idx; |
| u32 ao_bw_uc_idx; /* active only idx */ |
| struct msm_bus_scale_pdata *bus_scale_table; |
| struct msm_bus_scale_pdata *reg_bus_scale_table; |
| struct msm_bus_scale_pdata *hw_rt_bus_scale_table; |
| u32 max_bw_low; |
| u32 max_bw_high; |
| u32 max_bw_per_pipe; |
| u32 *vbif_rt_qos; |
| u32 *vbif_nrt_qos; |
| u32 npriority_lvl; |
| u32 rot_dwnscale_min; |
| u32 rot_dwnscale_max; |
| |
| struct mult_factor ab_factor; |
| struct mult_factor ib_factor; |
| struct mult_factor ib_factor_overlap; |
| struct mult_factor clk_factor; |
| struct mult_factor per_pipe_ib_factor; |
| bool apply_post_scale_bytes; |
| bool hflip_buffer_reused; |
| |
| u32 disable_prefill; |
| u32 *clock_levels; |
| u32 nclk_lvl; |
| |
| u32 enable_gate; |
| u32 enable_bw_release; |
| u32 enable_rotator_bw_release; |
| u32 serialize_wait4pp; |
| u32 wait4autorefresh; |
| u32 lines_before_active; |
| |
| struct mdss_hw_settings *hw_settings; |
| |
| int rects_per_sspp[MDSS_MDP_PIPE_TYPE_MAX]; |
| struct mdss_mdp_pipe *vig_pipes; |
| struct mdss_mdp_pipe *rgb_pipes; |
| struct mdss_mdp_pipe *dma_pipes; |
| struct mdss_mdp_pipe *cursor_pipes; |
| u32 nvig_pipes; |
| u32 nrgb_pipes; |
| u32 ndma_pipes; |
| u32 max_target_zorder; |
| u8 ncursor_pipes; |
| u32 max_cursor_size; |
| |
| u32 nppb_ctl; |
| u32 *ppb_ctl; |
| u32 nppb_cfg; |
| u32 *ppb_cfg; |
| char __iomem *slave_pingpong_base; |
| |
| struct mdss_mdp_mixer *mixer_intf; |
| struct mdss_mdp_mixer *mixer_wb; |
| u32 nmixers_intf; |
| u32 nmixers_wb; |
| u32 max_mixer_width; |
| u32 max_pipe_width; |
| |
| struct mdss_mdp_writeback *wb; |
| u32 nwb; |
| u32 *wb_offsets; |
| u32 nwb_offsets; |
| struct mutex wb_lock; |
| |
| struct mdss_mdp_ctl *ctl_off; |
| u32 nctl; |
| u32 ndspp; |
| |
| struct mdss_mdp_dp_intf *dp_off; |
| u32 ndp; |
| void *video_intf; |
| u32 nintf; |
| |
| struct mdss_mdp_ad *ad_off; |
| struct mdss_ad_info *ad_cfgs; |
| u32 nad_cfgs; |
| u32 nmax_concurrent_ad_hw; |
| struct workqueue_struct *ad_calc_wq; |
| u32 ad_debugen; |
| |
| struct mdss_intr hist_intr; |
| |
| struct ion_client *iclient; |
| int iommu_attached; |
| |
| struct debug_bus *dbg_bus; |
| u32 dbg_bus_size; |
| struct vbif_debug_bus *vbif_dbg_bus; |
| u32 vbif_dbg_bus_size; |
| struct vbif_debug_bus *nrt_vbif_dbg_bus; |
| u32 nrt_vbif_dbg_bus_size; |
| struct mdss_debug_inf debug_inf; |
| bool mixer_switched; |
| struct mdss_panel_cfg pan_cfg; |
| struct mdss_prefill_data prefill_data; |
| u32 min_prefill_lines; /* this changes within different chipsets */ |
| u32 props; |
| |
| int handoff_pending; |
| bool idle_pc; |
| struct mdss_perf_tune perf_tune; |
| bool traffic_shaper_en; |
| int iommu_ref_cnt; |
| u32 latency_buff_per; |
| atomic_t active_intf_cnt; |
| bool has_rot_dwnscale; |
| bool regulator_notif_register; |
| |
| u64 ab[MDSS_MAX_BUS_CLIENTS]; |
| u64 ib[MDSS_MAX_BUS_CLIENTS]; |
| struct mdss_pp_block_off pp_block_off; |
| |
| struct mdss_mdp_cdm *cdm_off; |
| u32 ncdm; |
| struct mutex cdm_lock; |
| |
| struct mdss_mdp_dsc *dsc_off; |
| u32 ndsc; |
| |
| struct mdss_max_bw_settings *max_bw_settings; |
| u32 bw_mode_bitmap; |
| u32 max_bw_settings_cnt; |
| bool bw_limit_pending; |
| |
| struct mdss_max_bw_settings *max_per_pipe_bw_settings; |
| u32 mdss_per_pipe_bw_cnt; |
| u32 min_bw_per_pipe; |
| |
| u32 bcolor0; |
| u32 bcolor1; |
| u32 bcolor2; |
| struct mdss_scaler_block *scaler_off; |
| |
| u32 splash_intf_sel; |
| u32 splash_split_disp; |
| }; |
| |
| extern struct mdss_data_type *mdss_res; |
| |
| struct irq_info { |
| u32 irq; |
| u32 irq_mask; |
| u32 irq_wake_mask; |
| u32 irq_ena; |
| u32 irq_wake_ena; |
| u32 irq_buzy; |
| }; |
| |
| struct mdss_hw { |
| u32 hw_ndx; |
| void *ptr; |
| struct irq_info *irq_info; |
| irqreturn_t (*irq_handler)(int irq, void *ptr); |
| }; |
| |
| struct irq_info *mdss_intr_line(void); |
| void mdss_bus_bandwidth_ctrl(int enable); |
| int mdss_iommu_ctrl(int enable); |
| int mdss_bus_scale_set_quota(int client, u64 ab_quota, u64 ib_quota); |
| int mdss_update_reg_bus_vote(struct reg_bus_client *bus_client, |
| u32 usecase_ndx); |
| struct reg_bus_client *mdss_reg_bus_vote_client_create(char *client_name); |
| void mdss_reg_bus_vote_client_destroy(struct reg_bus_client *bus_client); |
| |
| struct mdss_util_intf { |
| bool mdp_probe_done; |
| int (*register_irq)(struct mdss_hw *hw); |
| void (*enable_irq)(struct mdss_hw *hw); |
| void (*disable_irq)(struct mdss_hw *hw); |
| void (*enable_wake_irq)(struct mdss_hw *hw); |
| void (*disable_wake_irq)(struct mdss_hw *hw); |
| void (*disable_irq_nosync)(struct mdss_hw *hw); |
| int (*irq_dispatch)(u32 hw_ndx, int irq, void *ptr); |
| int (*get_iommu_domain)(u32 type); |
| int (*iommu_attached)(void); |
| int (*iommu_ctrl)(int enable); |
| void (*iommu_lock)(void); |
| void (*iommu_unlock)(void); |
| void (*bus_bandwidth_ctrl)(int enable); |
| int (*bus_scale_set_quota)(int client, u64 ab_quota, u64 ib_quota); |
| int (*panel_intf_status)(u32 disp_num, u32 intf_type); |
| struct mdss_panel_cfg* (*panel_intf_type)(int intf_val); |
| int (*dyn_clk_gating_ctrl)(int enable); |
| bool (*param_check)(char *param_string); |
| bool display_disabled; |
| }; |
| |
| struct mdss_util_intf *mdss_get_util_intf(void); |
| bool mdss_get_irq_enable_state(struct mdss_hw *hw); |
| |
| static inline int mdss_get_sd_client_cnt(void) |
| { |
| if (!mdss_res) |
| return 0; |
| else |
| return atomic_read(&mdss_res->sd_client_count); |
| } |
| |
| static inline void mdss_set_quirk(struct mdss_data_type *mdata, |
| enum mdss_hw_quirk bit) |
| { |
| set_bit(bit, mdata->mdss_quirk_map); |
| } |
| |
| static inline bool mdss_has_quirk(struct mdss_data_type *mdata, |
| enum mdss_hw_quirk bit) |
| { |
| return test_bit(bit, mdata->mdss_quirk_map); |
| } |
| |
| #define MDSS_VBIF_WRITE(mdata, offset, value, nrt_vbif) \ |
| (nrt_vbif ? mdss_reg_w(&mdata->vbif_nrt_io, offset, value, 0) :\ |
| mdss_reg_w(&mdata->vbif_io, offset, value, 0)) |
| #define MDSS_VBIF_READ(mdata, offset, nrt_vbif) \ |
| (nrt_vbif ? mdss_reg_r(&mdata->vbif_nrt_io, offset, 0) :\ |
| mdss_reg_r(&mdata->vbif_io, offset, 0)) |
| #define MDSS_REG_WRITE(mdata, offset, value) \ |
| mdss_reg_w(&mdata->mdss_io, offset, value, 0) |
| #define MDSS_REG_READ(mdata, offset) \ |
| mdss_reg_r(&mdata->mdss_io, offset, 0) |
| |
| #endif /* MDSS_H */ |