blob: 19e62995ae691c082b338cf967554c4cf0e47d12 [file] [log] [blame]
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#ifndef MDSS_FB_H
15#define MDSS_FB_H
16
17#include <linux/msm_ion.h>
18#include <linux/list.h>
19#include <linux/msm_mdp_ext.h>
20#include <linux/types.h>
21#include <linux/notifier.h>
22#include <linux/leds.h>
23
24#include "mdss_panel.h"
25#include "mdss_mdp_splash_logo.h"
26
27#define MDSS_LPAE_CHECK(phys) \
28 ((sizeof(phys) > sizeof(unsigned long)) ? ((phys >> 32) & 0xFF) : (0))
29
30#define MSM_FB_DEFAULT_PAGE_SIZE 2
31#define MFD_KEY 0x11161126
32#define MSM_FB_MAX_DEV_LIST 32
33
34#define MSM_FB_ENABLE_DBGFS
35#define WAIT_FENCE_FIRST_TIMEOUT (3 * MSEC_PER_SEC)
36#define WAIT_FENCE_FINAL_TIMEOUT (7 * MSEC_PER_SEC)
37#define WAIT_MAX_FENCE_TIMEOUT (WAIT_FENCE_FIRST_TIMEOUT + \
38 WAIT_FENCE_FINAL_TIMEOUT)
39#define WAIT_MIN_FENCE_TIMEOUT (1)
40/*
41 * Display op timeout should be greater than total time it can take for
42 * a display thread to commit one frame. One of the largest time consuming
43 * activity performed by display thread is waiting for fences. So keeping
44 * that as a reference and add additional 20s to sustain system holdups.
45 */
46#define WAIT_DISP_OP_TIMEOUT (WAIT_FENCE_FIRST_TIMEOUT + \
47 WAIT_FENCE_FINAL_TIMEOUT + (20 * MSEC_PER_SEC))
48
49#ifndef MAX
50#define MAX(x, y) (((x) > (y)) ? (x) : (y))
51#endif
52
53#ifndef MIN
54#define MIN(x, y) (((x) < (y)) ? (x) : (y))
55#endif
56
57#define MDP_PP_AD_BL_LINEAR 0x0
58#define MDP_PP_AD_BL_LINEAR_INV 0x1
59
60/**
61 * enum mdp_notify_event - Different frame events to indicate frame update state
62 *
63 * @MDP_NOTIFY_FRAME_BEGIN: Frame update has started, the frame is about to
64 * be programmed into hardware.
65 * @MDP_NOTIFY_FRAME_CFG_DONE: Frame configuration is done.
66 * @MDP_NOTIFY_FRAME_CTX_DONE: Frame has finished accessing sw context.
67 * Next frame can start preparing.
68 * @MDP_NOTIFY_FRAME_READY: Frame ready to be kicked off, this can be used
69 * as the last point in time to synchronize with
70 * source buffers before kickoff.
71 * @MDP_NOTIFY_FRAME_FLUSHED: Configuration of frame has been flushed and
72 * DMA transfer has started.
73 * @MDP_NOTIFY_FRAME_DONE: Frame DMA transfer has completed.
74 * - For video mode panels this will indicate that
75 * previous frame has been replaced by new one.
76 * - For command mode/writeback frame done happens
77 * as soon as the DMA of the frame is done.
78 * @MDP_NOTIFY_FRAME_TIMEOUT: Frame DMA transfer has failed to complete within
79 * a fair amount of time.
80 */
81enum mdp_notify_event {
82 MDP_NOTIFY_FRAME_BEGIN = 1,
83 MDP_NOTIFY_FRAME_CFG_DONE,
84 MDP_NOTIFY_FRAME_CTX_DONE,
85 MDP_NOTIFY_FRAME_READY,
86 MDP_NOTIFY_FRAME_FLUSHED,
87 MDP_NOTIFY_FRAME_DONE,
88 MDP_NOTIFY_FRAME_TIMEOUT,
89};
90
91/**
92 * enum mdp_split_mode - Lists the possible split modes in the device
93 *
94 * @MDP_SPLIT_MODE_NONE: Single physical display with single ctl path
95 * and single layer mixer.
96 * i.e. 1080p single DSI with single LM.
97 * #MDP_DUAL_LM_SINGLE_DISPLAY: Single physical display with signle ctl
98 * path but two layer mixers.
99 * i.e. WQXGA eDP or 4K HDMI primary or 1080p
100 * single DSI with split LM to reduce power.
101 * @MDP_DUAL_LM_DUAL_DISPLAY: Two physically separate displays with two
102 * separate but synchronized ctl paths. Each ctl
103 * path with its own layer mixer.
104 * i.e. 1440x2560 with two DSI interfaces.
105 * @MDP_PINGPONG_SPLIT: Two physically separate display but single ctl path with
106 * single layer mixer. Data is split at pingpong module.
107 * i.e. 1440x2560 on chipsets with single DSI interface.
108 */
109enum mdp_split_mode {
110 MDP_SPLIT_MODE_NONE,
111 MDP_DUAL_LM_SINGLE_DISPLAY,
112 MDP_DUAL_LM_DUAL_DISPLAY,
113 MDP_PINGPONG_SPLIT,
114};
115
116/* enum mdp_mmap_type - Lists the possible mmap type in the device
117 *
118 * @MDP_FB_MMAP_NONE: Unknown type.
119 * @MDP_FB_MMAP_ION_ALLOC: Use ION allocate a buffer for mmap
120 * @MDP_FB_MMAP_PHYSICAL_ALLOC: Use physical buffer for mmap
121 */
122enum mdp_mmap_type {
123 MDP_FB_MMAP_NONE,
124 MDP_FB_MMAP_ION_ALLOC,
125 MDP_FB_MMAP_PHYSICAL_ALLOC,
126};
127
128/**
129 * enum dyn_mode_switch_state - Lists next stage for dynamic mode switch work
130 *
131 * @MDSS_MDP_NO_UPDATE_REQUESTED: incoming frame is processed normally
132 * @MDSS_MDP_WAIT_FOR_VALIDATE: Waiting for ATOMIC_COMMIT-validate to be called
133 * @MDSS_MDP_WAIT_FOR_COMMIT: Waiting for ATOMIC_COMMIT-commit to be called
134 * @MDSS_MDP_WAIT_FOR_KICKOFF: Waiting for KICKOFF to be called
135 */
136enum dyn_mode_switch_state {
137 MDSS_MDP_NO_UPDATE_REQUESTED,
138 MDSS_MDP_WAIT_FOR_VALIDATE,
139 MDSS_MDP_WAIT_FOR_COMMIT,
140 MDSS_MDP_WAIT_FOR_KICKOFF,
141};
142
143/**
144 * enum mdss_fb_idle_state - idle states based on frame updates
145 * @MDSS_FB_NOT_IDLE: Frame updates have started
146 * @MDSS_FB_IDLE_TIMER_RUNNING: Idle timer has been kicked
147 * @MDSS_FB_IDLE: Currently idle
148 */
149enum mdss_fb_idle_state {
150 MDSS_FB_NOT_IDLE,
151 MDSS_FB_IDLE_TIMER_RUNNING,
152 MDSS_FB_IDLE
153};
154
155struct disp_info_type_suspend {
156 int op_enable;
157 int panel_power_state;
158};
159
160struct disp_info_notify {
161 int type;
162 struct timer_list timer;
163 struct completion comp;
164 struct mutex lock;
165 int value;
166 int is_suspend;
167 int ref_count;
168 bool init_done;
169};
170
171struct msm_sync_pt_data {
172 char *fence_name;
173 u32 acq_fen_cnt;
Sachin Bhayare2b6d0042018-01-13 19:38:21 +0530174 struct mdss_fence *acq_fen[MDP_MAX_FENCE_FD];
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530175 u32 temp_fen_cnt;
Sachin Bhayare2b6d0042018-01-13 19:38:21 +0530176 struct mdss_fence *temp_fen[MDP_MAX_FENCE_FD];
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530177
Sachin Bhayare2b6d0042018-01-13 19:38:21 +0530178 struct mdss_timeline *timeline;
179 struct mdss_timeline *timeline_retire;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530180 int timeline_value;
181 u32 threshold;
182 u32 retire_threshold;
183 atomic_t commit_cnt;
184 bool flushed;
185 bool async_wait_fences;
186
187 struct mutex sync_mutex;
188 struct notifier_block notifier;
189
Sachin Bhayare2b6d0042018-01-13 19:38:21 +0530190 struct mdss_fence *(*get_retire_fence)
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530191 (struct msm_sync_pt_data *sync_pt_data);
192};
193
194struct msm_fb_data_type;
195
196struct msm_mdp_interface {
197 int (*fb_mem_alloc_fnc)(struct msm_fb_data_type *mfd);
198 int (*fb_mem_get_iommu_domain)(void);
199 int (*init_fnc)(struct msm_fb_data_type *mfd);
200 int (*on_fnc)(struct msm_fb_data_type *mfd);
201 int (*off_fnc)(struct msm_fb_data_type *mfd);
202 /* called to release resources associated to the process */
203 int (*release_fnc)(struct msm_fb_data_type *mfd, struct file *file);
204 int (*mode_switch)(struct msm_fb_data_type *mfd,
205 u32 mode);
206 int (*mode_switch_post)(struct msm_fb_data_type *mfd,
207 u32 mode);
208 int (*kickoff_fnc)(struct msm_fb_data_type *mfd,
209 struct mdp_display_commit *data);
210 int (*atomic_validate)(struct msm_fb_data_type *mfd, struct file *file,
211 struct mdp_layer_commit_v1 *commit);
212 bool (*is_config_same)(struct msm_fb_data_type *mfd,
213 struct mdp_output_layer *layer);
214 int (*pre_commit)(struct msm_fb_data_type *mfd, struct file *file,
215 struct mdp_layer_commit_v1 *commit);
216 int (*pre_commit_fnc)(struct msm_fb_data_type *mfd);
217 int (*ioctl_handler)(struct msm_fb_data_type *mfd, u32 cmd, void *arg);
218 void (*dma_fnc)(struct msm_fb_data_type *mfd);
219 int (*cursor_update)(struct msm_fb_data_type *mfd,
220 struct fb_cursor *cursor);
221 int (*async_position_update)(struct msm_fb_data_type *mfd,
222 struct mdp_position_update *update_pos);
223 int (*lut_update)(struct msm_fb_data_type *mfd, struct fb_cmap *cmap);
224 int (*do_histogram)(struct msm_fb_data_type *mfd,
225 struct mdp_histogram *hist);
226 int (*ad_calc_bl)(struct msm_fb_data_type *mfd, int bl_in,
227 int *bl_out, bool *bl_out_notify);
228 int (*panel_register_done)(struct mdss_panel_data *pdata);
229 u32 (*fb_stride)(u32 fb_index, u32 xres, int bpp);
230 struct mdss_mdp_format_params *(*get_format_params)(u32 format);
231 int (*splash_init_fnc)(struct msm_fb_data_type *mfd);
232 void (*check_dsi_status)(struct work_struct *work, uint32_t interval);
233 int (*configure_panel)(struct msm_fb_data_type *mfd, int mode,
234 int dest_ctrl);
235 int (*input_event_handler)(struct msm_fb_data_type *mfd);
236 int (*pp_release_fnc)(struct msm_fb_data_type *mfd);
237 void (*signal_retire_fence)(struct msm_fb_data_type *mfd,
238 int retire_cnt);
239 void *private1;
240};
241
242#define IS_CALIB_MODE_BL(mfd) (((mfd)->calib_mode) & MDSS_CALIB_MODE_BL)
243#define MDSS_BRIGHT_TO_BL(out, v, bl_max, max_bright) do {\
244 out = (2 * (v) * (bl_max) + max_bright);\
245 do_div(out, 2 * max_bright);\
246 } while (0)
247
248struct mdss_fb_file_info {
249 struct file *file;
250 struct list_head list;
251};
252
253struct msm_fb_backup_type {
254 struct fb_info info;
255 struct mdp_display_commit disp_commit;
256 bool atomic_commit;
257};
258
259struct msm_fb_fps_info {
260 u32 frame_count;
261 ktime_t last_sampled_time_us;
262 u32 measured_fps;
263};
264
265struct msm_fb_data_type {
266 u32 key;
267 u32 index;
268 u32 ref_cnt;
269 u32 fb_page;
270
271 struct panel_id panel;
272 struct mdss_panel_info *panel_info;
273 struct mdss_panel_info reconfig_panel_info;
274 int split_mode;
275 int split_fb_left;
276 int split_fb_right;
277
278 u32 dest;
279 struct fb_info *fbi;
280
281 int idle_time;
282 u32 idle_state;
283 struct msm_fb_fps_info fps_info;
284 struct delayed_work idle_notify_work;
285
286 bool atomic_commit_pending;
287
288 int op_enable;
289 u32 fb_imgType;
290 int panel_reconfig;
291 u32 panel_orientation;
292
293 u32 dst_format;
294 int panel_power_state;
295 struct disp_info_type_suspend suspend;
296
297 struct dma_buf *dbuf;
298 struct dma_buf_attachment *attachment;
299 struct sg_table *table;
300 dma_addr_t iova;
301 void *cursor_buf;
302 phys_addr_t cursor_buf_phys;
303 dma_addr_t cursor_buf_iova;
304
305 int ext_ad_ctrl;
306 u32 ext_bl_ctrl;
307 u32 calib_mode;
308 u32 calib_mode_bl;
309 u32 ad_bl_level;
310 u32 bl_level;
311 u32 bl_scale;
312 u32 bl_min_lvl;
313 u32 unset_bl_level;
314 bool allow_bl_update;
315 u32 bl_level_scaled;
316 struct mutex bl_lock;
317 struct mutex mdss_sysfs_lock;
318 bool ipc_resume;
319
320 struct platform_device *pdev;
321
322 u32 mdp_fb_page_protection;
323
324 struct disp_info_notify update;
325 struct disp_info_notify no_update;
326 struct completion power_off_comp;
327
328 struct msm_mdp_interface mdp;
329
330 struct msm_sync_pt_data mdp_sync_pt_data;
331
332 /* for non-blocking */
333 struct task_struct *disp_thread;
334 atomic_t commits_pending;
335 atomic_t kickoff_pending;
336 wait_queue_head_t commit_wait_q;
337 wait_queue_head_t idle_wait_q;
338 wait_queue_head_t kickoff_wait_q;
339 bool shutdown_pending;
340
341 struct msm_fb_splash_info splash_info;
342
343 wait_queue_head_t ioctl_q;
344 atomic_t ioctl_ref_cnt;
345
346 struct msm_fb_backup_type msm_fb_backup;
347 struct completion power_set_comp;
348 u32 is_power_setting;
349
350 u32 dcm_state;
351 struct list_head file_list;
352 struct ion_client *fb_ion_client;
353 struct ion_handle *fb_ion_handle;
354 struct dma_buf *fbmem_buf;
355 struct dma_buf_attachment *fb_attachment;
356 struct sg_table *fb_table;
357
358 bool mdss_fb_split_stored;
359
360 u32 wait_for_kickoff;
361 u32 thermal_level;
362
363 int fb_mmap_type;
364 struct led_trigger *boot_notification_led;
365
366 /* Following is used for dynamic mode switch */
367 enum dyn_mode_switch_state switch_state;
368 u32 switch_new_mode;
369 bool pending_switch;
370 struct mutex switch_lock;
371 struct input_handler *input_handler;
372};
373
374static inline void mdss_fb_update_notify_update(struct msm_fb_data_type *mfd)
375{
376 int needs_complete = 0;
377
378 mutex_lock(&mfd->update.lock);
379 mfd->update.value = mfd->update.type;
380 needs_complete = mfd->update.value == NOTIFY_TYPE_UPDATE;
381 mutex_unlock(&mfd->update.lock);
382 if (needs_complete) {
383 complete(&mfd->update.comp);
384 mutex_lock(&mfd->no_update.lock);
385 if (mfd->no_update.timer.function)
386 del_timer(&(mfd->no_update.timer));
387
388 mfd->no_update.timer.expires = jiffies + (2 * HZ);
389 add_timer(&mfd->no_update.timer);
390 mutex_unlock(&mfd->no_update.lock);
391 }
392}
393
394/* Function returns true for either any kind of dual display */
395static inline bool is_panel_split(struct msm_fb_data_type *mfd)
396{
397 return mfd && mfd->panel_info && mfd->panel_info->is_split_display;
398}
399/* Function returns true, if Layer Mixer split is Set */
400static inline bool is_split_lm(struct msm_fb_data_type *mfd)
401{
402 return mfd &&
403 (mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY ||
404 mfd->split_mode == MDP_DUAL_LM_SINGLE_DISPLAY);
405}
406/* Function returns true, if Ping pong split is Set*/
407static inline bool is_pingpong_split(struct msm_fb_data_type *mfd)
408{
409 return mfd && (mfd->split_mode == MDP_PINGPONG_SPLIT);
410}
411static inline bool is_dual_lm_single_display(struct msm_fb_data_type *mfd)
412{
413 return mfd && (mfd->split_mode == MDP_DUAL_LM_SINGLE_DISPLAY);
414}
415static inline bool mdss_fb_is_power_off(struct msm_fb_data_type *mfd)
416{
417 return mdss_panel_is_power_off(mfd->panel_power_state);
418}
419
420static inline bool mdss_fb_is_power_on_interactive(
421 struct msm_fb_data_type *mfd)
422{
423 return mdss_panel_is_power_on_interactive(mfd->panel_power_state);
424}
425
426static inline bool mdss_fb_is_power_on(struct msm_fb_data_type *mfd)
427{
428 return mdss_panel_is_power_on(mfd->panel_power_state);
429}
430
431static inline bool mdss_fb_is_power_on_lp(struct msm_fb_data_type *mfd)
432{
433 return mdss_panel_is_power_on_lp(mfd->panel_power_state);
434}
435
436static inline bool mdss_fb_is_power_on_ulp(struct msm_fb_data_type *mfd)
437{
438 return mdss_panel_is_power_on_ulp(mfd->panel_power_state);
439}
440
441static inline bool mdss_fb_is_hdmi_primary(struct msm_fb_data_type *mfd)
442{
443 return (mfd && (mfd->index == 0) &&
444 (mfd->panel_info->type == DTV_PANEL));
445}
446
447static inline void mdss_fb_init_fps_info(struct msm_fb_data_type *mfd)
448{
449 memset(&mfd->fps_info, 0, sizeof(mfd->fps_info));
450}
451int mdss_fb_get_phys_info(dma_addr_t *start, unsigned long *len, int fb_num);
452void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl);
453void mdss_fb_update_backlight(struct msm_fb_data_type *mfd);
454int mdss_fb_wait_for_fence(struct msm_sync_pt_data *sync_pt_data);
455void mdss_fb_signal_timeline(struct msm_sync_pt_data *sync_pt_data);
Sachin Bhayare2b6d0042018-01-13 19:38:21 +0530456struct mdss_fence *mdss_fb_sync_get_fence(struct mdss_timeline *timeline,
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530457 const char *fence_name, int val);
458int mdss_fb_register_mdp_instance(struct msm_mdp_interface *mdp);
459int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state);
460int mdss_fb_suspres_panel(struct device *dev, void *data);
461int mdss_fb_do_ioctl(struct fb_info *info, unsigned int cmd,
462 unsigned long arg, struct file *file);
463int mdss_fb_compat_ioctl(struct fb_info *info, unsigned int cmd,
464 unsigned long arg, struct file *file);
465int mdss_fb_atomic_commit(struct fb_info *info,
466 struct mdp_layer_commit *commit, struct file *file);
467int mdss_fb_async_position_update(struct fb_info *info,
468 struct mdp_position_update *update_pos);
469
470u32 mdss_fb_get_mode_switch(struct msm_fb_data_type *mfd);
471void mdss_fb_report_panel_dead(struct msm_fb_data_type *mfd);
472void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo,
473 struct fb_var_screeninfo *var);
474void mdss_fb_calc_fps(struct msm_fb_data_type *mfd);
475#endif /* MDSS_FB_H */