blob: 1ab0fb728e45cd3deb762a27943e613630af0981 [file] [log] [blame]
/* Copyright (c) 2008-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.
*
*/
#ifndef MDSS_FB_H
#define MDSS_FB_H
#include <linux/msm_ion.h>
#include <linux/list.h>
#include <linux/msm_mdp.h>
#include <linux/types.h>
#include <linux/notifier.h>
#include "mdss_panel.h"
#include "mdss_mdp_splash_logo.h"
#define MSM_FB_DEFAULT_PAGE_SIZE 2
#define MFD_KEY 0x11161126
#define MSM_FB_MAX_DEV_LIST 32
#define MSM_FB_ENABLE_DBGFS
#define WAIT_FENCE_FIRST_TIMEOUT (3 * MSEC_PER_SEC)
#define WAIT_FENCE_FINAL_TIMEOUT (10 * MSEC_PER_SEC)
/* Display op timeout should be greater than total timeout */
#define WAIT_DISP_OP_TIMEOUT ((WAIT_FENCE_FIRST_TIMEOUT + \
WAIT_FENCE_FINAL_TIMEOUT) * MDP_MAX_FENCE_FD)
#ifndef MAX
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#endif
#ifndef MIN
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif
/**
* enum mdp_notify_event - Different frame events to indicate frame update state
*
* @MDP_NOTIFY_FRAME_BEGIN: Frame update has started, the frame is about to
* be programmed into hardware.
* @MDP_NOTIFY_FRAME_READY: Frame ready to be kicked off, this can be used
* as the last point in time to synchronized with
* source buffers before kickoff.
* @MDP_NOTIFY_FRAME_FLUSHED: Configuration of frame has been flushed and
* DMA transfer has started.
* @MDP_NOTIFY_FRAME_DONE: Frame DMA transfer has completed.
* - For video mode panels this will indicate that
* previous frame has been replaced by new one.
* - For command mode/writeback frame done happens
* as soon as the DMA of the frame is done.
* @MDP_NOTIFY_FRAME_TIMEOUT: Frame DMA transfer has failed to complete within
* a fair amount of time.
*/
enum mdp_notify_event {
MDP_NOTIFY_FRAME_BEGIN = 1,
MDP_NOTIFY_FRAME_READY,
MDP_NOTIFY_FRAME_FLUSHED,
MDP_NOTIFY_FRAME_DONE,
MDP_NOTIFY_FRAME_TIMEOUT,
};
struct disp_info_type_suspend {
int op_enable;
int panel_power_on;
};
struct disp_info_notify {
int type;
struct timer_list timer;
struct completion comp;
struct mutex lock;
int value;
int is_suspend;
int ref_count;
};
struct msm_sync_pt_data {
char *fence_name;
u32 acq_fen_cnt;
struct sync_fence *acq_fen[MDP_MAX_FENCE_FD];
struct sw_sync_timeline *timeline;
int timeline_value;
u32 threshold;
u32 retire_threshold;
atomic_t commit_cnt;
bool flushed;
bool async_wait_fences;
struct mutex sync_mutex;
struct notifier_block notifier;
struct sync_fence *(*get_retire_fence)
(struct msm_sync_pt_data *sync_pt_data);
};
struct msm_fb_data_type;
struct msm_mdp_interface {
int (*fb_mem_alloc_fnc)(struct msm_fb_data_type *mfd);
int (*fb_mem_get_iommu_domain)(void);
int (*init_fnc)(struct msm_fb_data_type *mfd);
int (*on_fnc)(struct msm_fb_data_type *mfd);
int (*off_fnc)(struct msm_fb_data_type *mfd);
/* called to release resources associated to the process */
int (*release_fnc)(struct msm_fb_data_type *mfd, bool release_all);
int (*kickoff_fnc)(struct msm_fb_data_type *mfd,
struct mdp_display_commit *data);
int (*ioctl_handler)(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
void (*dma_fnc)(struct msm_fb_data_type *mfd);
int (*cursor_update)(struct msm_fb_data_type *mfd,
struct fb_cursor *cursor);
int (*lut_update)(struct msm_fb_data_type *mfd, struct fb_cmap *cmap);
int (*do_histogram)(struct msm_fb_data_type *mfd,
struct mdp_histogram *hist);
int (*update_ad_input)(struct msm_fb_data_type *mfd);
int (*ad_attenuate_bl)(u32 bl, u32 *bl_out,
struct msm_fb_data_type *mfd);
int (*panel_register_done)(struct mdss_panel_data *pdata);
u32 (*fb_stride)(u32 fb_index, u32 xres, int bpp);
int (*splash_init_fnc)(struct msm_fb_data_type *mfd);
struct msm_sync_pt_data *(*get_sync_fnc)(struct msm_fb_data_type *mfd,
const struct mdp_buf_sync *buf_sync);
void (*check_dsi_status)(struct work_struct *work, uint32_t interval);
int (*configure_panel)(struct msm_fb_data_type *mfd, int mode);
void *private1;
};
#define IS_CALIB_MODE_BL(mfd) (((mfd)->calib_mode) & MDSS_CALIB_MODE_BL)
#define MDSS_BRIGHT_TO_BL(out, v, bl_max, max_bright) do {\
out = (2 * (v) * (bl_max) + max_bright)\
/ (2 * max_bright);\
} while (0)
struct mdss_fb_proc_info {
int pid;
u32 ref_cnt;
struct list_head list;
};
struct msm_fb_backup_type {
struct fb_info info;
struct mdp_display_commit disp_commit;
};
struct msm_fb_data_type {
u32 key;
u32 index;
u32 ref_cnt;
u32 fb_page;
struct panel_id panel;
struct mdss_panel_info *panel_info;
int split_display;
int split_fb_left;
int split_fb_right;
u32 dest;
struct fb_info *fbi;
int idle_time;
struct delayed_work idle_notify_work;
int op_enable;
u32 fb_imgType;
int panel_reconfig;
u32 dst_format;
int panel_power_on;
struct disp_info_type_suspend suspend;
struct ion_handle *ihdl;
unsigned long iova;
void *cursor_buf;
unsigned long cursor_buf_phys;
unsigned long cursor_buf_iova;
int ext_ad_ctrl;
u32 ext_bl_ctrl;
u32 calib_mode;
u32 bl_level;
u32 bl_scale;
u32 bl_min_lvl;
u32 unset_bl_level;
u32 bl_updated;
u32 bl_level_scaled;
u32 bl_level_prev_scaled;
struct mutex bl_lock;
struct platform_device *pdev;
u32 mdp_fb_page_protection;
struct disp_info_notify update;
struct disp_info_notify no_update;
struct completion power_off_comp;
struct msm_mdp_interface mdp;
struct msm_sync_pt_data mdp_sync_pt_data;
/* for non-blocking */
struct task_struct *disp_thread;
atomic_t commits_pending;
atomic_t kickoff_pending;
wait_queue_head_t commit_wait_q;
wait_queue_head_t idle_wait_q;
wait_queue_head_t kickoff_wait_q;
bool shutdown_pending;
struct msm_fb_splash_info splash_info;
wait_queue_head_t ioctl_q;
atomic_t ioctl_ref_cnt;
struct msm_fb_backup_type msm_fb_backup;
struct completion power_set_comp;
u32 is_power_setting;
u32 dcm_state;
struct list_head proc_list;
u32 wait_for_kickoff;
};
static inline void mdss_fb_update_notify_update(struct msm_fb_data_type *mfd)
{
int needs_complete = 0;
mutex_lock(&mfd->update.lock);
mfd->update.value = mfd->update.type;
needs_complete = mfd->update.value == NOTIFY_TYPE_UPDATE;
mutex_unlock(&mfd->update.lock);
if (needs_complete) {
complete(&mfd->update.comp);
mutex_lock(&mfd->no_update.lock);
if (mfd->no_update.timer.function)
del_timer(&(mfd->no_update.timer));
mfd->no_update.timer.expires = jiffies + (2 * HZ);
add_timer(&mfd->no_update.timer);
mutex_unlock(&mfd->no_update.lock);
}
}
int mdss_fb_get_phys_info(unsigned long *start, unsigned long *len, int fb_num);
void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl);
void mdss_fb_update_backlight(struct msm_fb_data_type *mfd);
void mdss_fb_wait_for_fence(struct msm_sync_pt_data *sync_pt_data);
void mdss_fb_signal_timeline(struct msm_sync_pt_data *sync_pt_data);
struct sync_fence *mdss_fb_sync_get_fence(struct sw_sync_timeline *timeline,
const char *fence_name, int val);
int mdss_fb_register_mdp_instance(struct msm_mdp_interface *mdp);
int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state);
int mdss_fb_suspres_panel(struct device *dev, void *data);
#endif /* MDSS_FB_H */