blob: ae9b7cf9e97965cec3d0e6f07e4d900cc4d2234b [file] [log] [blame]
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301/*
2 * Core MDSS framebuffer driver.
3 *
4 * Copyright (C) 2007 Google Incorporated
5 * Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#define pr_fmt(fmt) "%s: " fmt, __func__
18
19#include <linux/videodev2.h>
20#include <linux/bootmem.h>
21#include <linux/console.h>
22#include <linux/debugfs.h>
23#include <linux/delay.h>
24#include <linux/device.h>
25#include <linux/dma-mapping.h>
26#include <linux/dma-buf.h>
27#include <linux/fb.h>
28#include <linux/init.h>
29#include <linux/ioport.h>
30#include <linux/kernel.h>
31#include <linux/memory.h>
32#include <linux/mm.h>
33#include <linux/module.h>
34#include <linux/moduleparam.h>
35#include <linux/msm_mdp.h>
36#include <linux/of.h>
37#include <linux/of_address.h>
38#include <linux/of_platform.h>
39#include <linux/proc_fs.h>
40#include <linux/pm_runtime.h>
41#include <linux/slab.h>
42#include <linux/string.h>
43#include <linux/uaccess.h>
44#include <linux/version.h>
45#include <linux/vmalloc.h>
Sachin Bhayareeeb88892018-01-02 16:36:01 +053046#include <linux/file.h>
47#include <linux/kthread.h>
48#include <linux/dma-buf.h>
49#include "mdss_fb.h"
50#include "mdss_mdp_splash_logo.h"
51#define CREATE_TRACE_POINTS
52#include "mdss_debug.h"
53#include "mdss_smmu.h"
54#include "mdss_mdp.h"
55#include "mdp3_ctrl.h"
Sachin Bhayare2b6d0042018-01-13 19:38:21 +053056#include "mdss_sync.h"
Sachin Bhayareeeb88892018-01-02 16:36:01 +053057
58#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
59#define MDSS_FB_NUM 3
60#else
61#define MDSS_FB_NUM 2
62#endif
63
64#ifndef EXPORT_COMPAT
65#define EXPORT_COMPAT(x)
66#endif
67
68#define MAX_FBI_LIST 32
69
70#ifndef TARGET_HW_MDSS_MDP3
71#define BLANK_FLAG_LP FB_BLANK_NORMAL
72#define BLANK_FLAG_ULP FB_BLANK_VSYNC_SUSPEND
73#else
74#define BLANK_FLAG_LP FB_BLANK_VSYNC_SUSPEND
75#define BLANK_FLAG_ULP FB_BLANK_NORMAL
76#endif
77
78/*
79 * Time period for fps calulation in micro seconds.
80 * Default value is set to 1 sec.
81 */
82#define MDP_TIME_PERIOD_CALC_FPS_US 1000000
83
84static struct fb_info *fbi_list[MAX_FBI_LIST];
85static int fbi_list_index;
86
87static u32 mdss_fb_pseudo_palette[16] = {
88 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
89 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
90 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
91 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
92};
93
94static struct msm_mdp_interface *mdp_instance;
95
96static int mdss_fb_register(struct msm_fb_data_type *mfd);
97static int mdss_fb_open(struct fb_info *info, int user);
98static int mdss_fb_release(struct fb_info *info, int user);
99static int mdss_fb_release_all(struct fb_info *info, bool release_all);
100static int mdss_fb_pan_display(struct fb_var_screeninfo *var,
101 struct fb_info *info);
102static int mdss_fb_check_var(struct fb_var_screeninfo *var,
103 struct fb_info *info);
104static int mdss_fb_set_par(struct fb_info *info);
105static int mdss_fb_blank_sub(int blank_mode, struct fb_info *info,
106 int op_enable);
107static int mdss_fb_suspend_sub(struct msm_fb_data_type *mfd);
108static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd,
109 unsigned long arg, struct file *file);
110static int mdss_fb_fbmem_ion_mmap(struct fb_info *info,
111 struct vm_area_struct *vma);
112static int mdss_fb_alloc_fb_ion_memory(struct msm_fb_data_type *mfd,
113 size_t size);
114static void mdss_fb_release_fences(struct msm_fb_data_type *mfd);
115static int __mdss_fb_sync_buf_done_callback(struct notifier_block *p,
116 unsigned long val, void *data);
117
118static int __mdss_fb_display_thread(void *data);
119static int mdss_fb_pan_idle(struct msm_fb_data_type *mfd);
120static int mdss_fb_send_panel_event(struct msm_fb_data_type *mfd,
121 int event, void *arg);
122static void mdss_fb_set_mdp_sync_pt_threshold(struct msm_fb_data_type *mfd,
123 int type);
124void mdss_fb_no_update_notify_timer_cb(unsigned long data)
125{
126 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)data;
127
128 if (!mfd) {
129 pr_err("%s mfd NULL\n", __func__);
130 return;
131 }
132 mfd->no_update.value = NOTIFY_TYPE_NO_UPDATE;
133 complete(&mfd->no_update.comp);
134}
135
136void mdss_fb_bl_update_notify(struct msm_fb_data_type *mfd,
137 uint32_t notification_type)
138{
139#ifndef TARGET_HW_MDSS_MDP3
140 struct mdss_overlay_private *mdp5_data = NULL;
141#endif
142#ifdef TARGET_HW_MDSS_MDP3
143 struct mdp3_session_data *mdp3_session = NULL;
144#endif
145 if (!mfd) {
146 pr_err("%s mfd NULL\n", __func__);
147 return;
148 }
149 mutex_lock(&mfd->update.lock);
150 if (mfd->update.is_suspend) {
151 mutex_unlock(&mfd->update.lock);
152 return;
153 }
154 if (mfd->update.ref_count > 0) {
155 mutex_unlock(&mfd->update.lock);
156 mfd->update.value = notification_type;
157 complete(&mfd->update.comp);
158 mutex_lock(&mfd->update.lock);
159 }
160 mutex_unlock(&mfd->update.lock);
161
162 mutex_lock(&mfd->no_update.lock);
163 if (mfd->no_update.ref_count > 0) {
164 mutex_unlock(&mfd->no_update.lock);
165 mfd->no_update.value = notification_type;
166 complete(&mfd->no_update.comp);
167 mutex_lock(&mfd->no_update.lock);
168 }
169 mutex_unlock(&mfd->no_update.lock);
170#ifndef TARGET_HW_MDSS_MDP3
171 mdp5_data = mfd_to_mdp5_data(mfd);
172 if (mdp5_data) {
173 if (notification_type == NOTIFY_TYPE_BL_AD_ATTEN_UPDATE) {
174 mdp5_data->ad_bl_events++;
175 sysfs_notify_dirent(mdp5_data->ad_bl_event_sd);
176 } else if (notification_type == NOTIFY_TYPE_BL_UPDATE) {
177 mdp5_data->bl_events++;
178 sysfs_notify_dirent(mdp5_data->bl_event_sd);
179 }
180 }
181#endif
182#ifdef TARGET_HW_MDSS_MDP3
183 mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
184 if (mdp3_session) {
185 mdp3_session->bl_events++;
186 sysfs_notify_dirent(mdp3_session->bl_event_sd);
187 pr_debug("bl_event = %u\n", mdp3_session->bl_events);
188 }
189#endif
190}
191
192static int mdss_fb_notify_update(struct msm_fb_data_type *mfd,
193 unsigned long *argp)
194{
195 int ret;
196 unsigned int notify = 0x0, to_user = 0x0;
197
198 ret = copy_from_user(&notify, argp, sizeof(unsigned int));
199 if (ret) {
200 pr_err("%s:ioctl failed\n", __func__);
201 return ret;
202 }
203
204 if (notify > NOTIFY_UPDATE_POWER_OFF)
205 return -EINVAL;
206
207 if (notify == NOTIFY_UPDATE_INIT) {
208 mutex_lock(&mfd->update.lock);
209 mfd->update.init_done = true;
210 mutex_unlock(&mfd->update.lock);
211 ret = 1;
212 } else if (notify == NOTIFY_UPDATE_DEINIT) {
213 mutex_lock(&mfd->update.lock);
214 mfd->update.init_done = false;
215 mutex_unlock(&mfd->update.lock);
216 complete(&mfd->update.comp);
217 complete(&mfd->no_update.comp);
218 ret = 1;
219 } else if (mfd->update.is_suspend) {
220 to_user = NOTIFY_TYPE_SUSPEND;
221 mfd->update.is_suspend = 0;
222 ret = 1;
223 } else if (notify == NOTIFY_UPDATE_START) {
224 mutex_lock(&mfd->update.lock);
225 if (mfd->update.init_done)
226 reinit_completion(&mfd->update.comp);
227 else {
228 mutex_unlock(&mfd->update.lock);
229 pr_err("notify update start called without init\n");
230 return -EINVAL;
231 }
232 mfd->update.ref_count++;
233 mutex_unlock(&mfd->update.lock);
234 ret = wait_for_completion_interruptible_timeout(
235 &mfd->update.comp, 4 * HZ);
236 mutex_lock(&mfd->update.lock);
237 mfd->update.ref_count--;
238 mutex_unlock(&mfd->update.lock);
239 to_user = (unsigned int)mfd->update.value;
240 if (mfd->update.type == NOTIFY_TYPE_SUSPEND) {
241 to_user = (unsigned int)mfd->update.type;
242 ret = 1;
243 }
244 } else if (notify == NOTIFY_UPDATE_STOP) {
245 mutex_lock(&mfd->update.lock);
246 if (mfd->update.init_done)
247 reinit_completion(&mfd->no_update.comp);
248 else {
249 mutex_unlock(&mfd->update.lock);
250 pr_err("notify update stop called without init\n");
251 return -EINVAL;
252 }
253 mfd->no_update.ref_count++;
254 mutex_unlock(&mfd->no_update.lock);
255 ret = wait_for_completion_interruptible_timeout(
256 &mfd->no_update.comp, 4 * HZ);
257 mutex_lock(&mfd->no_update.lock);
258 mfd->no_update.ref_count--;
259 mutex_unlock(&mfd->no_update.lock);
260 to_user = (unsigned int)mfd->no_update.value;
261 } else {
262 if (mdss_fb_is_power_on(mfd)) {
263 reinit_completion(&mfd->power_off_comp);
264 ret = wait_for_completion_interruptible_timeout(
265 &mfd->power_off_comp, 1 * HZ);
266 }
267 }
268
269 if (ret == 0)
270 ret = -ETIMEDOUT;
271 else if (ret > 0)
272 ret = copy_to_user(argp, &to_user, sizeof(unsigned int));
273 return ret;
274}
275
276static int lcd_backlight_registered;
277
278static void mdss_fb_set_bl_brightness(struct led_classdev *led_cdev,
279 enum led_brightness value)
280{
281 struct msm_fb_data_type *mfd = dev_get_drvdata(led_cdev->dev->parent);
Sachin Bhayareb6b5a0f2018-03-02 19:50:39 +0530282 u64 bl_lvl;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530283
284 if (mfd->boot_notification_led) {
285 led_trigger_event(mfd->boot_notification_led, 0);
286 mfd->boot_notification_led = NULL;
287 }
288
289 if (value > mfd->panel_info->brightness_max)
290 value = mfd->panel_info->brightness_max;
291
292 /* This maps android backlight level 0 to 255 into
293 * driver backlight level 0 to bl_max with rounding
294 */
295 MDSS_BRIGHT_TO_BL(bl_lvl, value, mfd->panel_info->bl_max,
296 mfd->panel_info->brightness_max);
297
298 if (!bl_lvl && value)
299 bl_lvl = 1;
300
301 if (!IS_CALIB_MODE_BL(mfd) && (!mfd->ext_bl_ctrl || !value ||
302 !mfd->bl_level)) {
303 mutex_lock(&mfd->bl_lock);
304 mdss_fb_set_backlight(mfd, bl_lvl);
305 mutex_unlock(&mfd->bl_lock);
306 }
307}
308
309static struct led_classdev backlight_led = {
310 .name = "lcd-backlight",
311 .brightness = MDSS_MAX_BL_BRIGHTNESS / 2,
312 .brightness_set = mdss_fb_set_bl_brightness,
313 .max_brightness = MDSS_MAX_BL_BRIGHTNESS,
314};
315
316static ssize_t mdss_fb_get_type(struct device *dev,
317 struct device_attribute *attr, char *buf)
318{
319 ssize_t ret = 0;
320 struct fb_info *fbi = dev_get_drvdata(dev);
321 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
322
323 switch (mfd->panel.type) {
324 case NO_PANEL:
325 ret = snprintf(buf, PAGE_SIZE, "no panel\n");
326 break;
327 case HDMI_PANEL:
328 ret = snprintf(buf, PAGE_SIZE, "hdmi panel\n");
329 break;
330 case LVDS_PANEL:
331 ret = snprintf(buf, PAGE_SIZE, "lvds panel\n");
332 break;
333 case DTV_PANEL:
334 ret = snprintf(buf, PAGE_SIZE, "dtv panel\n");
335 break;
336 case MIPI_VIDEO_PANEL:
337 ret = snprintf(buf, PAGE_SIZE, "mipi dsi video panel\n");
338 break;
339 case MIPI_CMD_PANEL:
340 ret = snprintf(buf, PAGE_SIZE, "mipi dsi cmd panel\n");
341 break;
342 case WRITEBACK_PANEL:
343 ret = snprintf(buf, PAGE_SIZE, "writeback panel\n");
344 break;
345 case EDP_PANEL:
346 ret = snprintf(buf, PAGE_SIZE, "edp panel\n");
347 break;
348 default:
349 ret = snprintf(buf, PAGE_SIZE, "unknown panel\n");
350 break;
351 }
352
353 return ret;
354}
355
356static int mdss_fb_get_panel_xres(struct mdss_panel_info *pinfo)
357{
358 struct mdss_panel_data *pdata;
359 int xres;
360
361 pdata = container_of(pinfo, struct mdss_panel_data, panel_info);
362
363 xres = pinfo->xres;
364 if (pdata->next && pdata->next->active)
365 xres += mdss_fb_get_panel_xres(&pdata->next->panel_info);
366
367 return xres;
368}
369
370static inline int mdss_fb_validate_split(int left, int right,
371 struct msm_fb_data_type *mfd)
372{
373 int rc = -EINVAL;
374 u32 panel_xres = mdss_fb_get_panel_xres(mfd->panel_info);
375
376 pr_debug("%pS: split_mode = %d left=%d right=%d panel_xres=%d\n",
377 __builtin_return_address(0), mfd->split_mode,
378 left, right, panel_xres);
379
380 /* more validate condition could be added if needed */
381 if (left && right) {
382 if (panel_xres == left + right) {
383 mfd->split_fb_left = left;
384 mfd->split_fb_right = right;
385 rc = 0;
386 }
387 } else {
388 if (mfd->split_mode == MDP_DUAL_LM_DUAL_DISPLAY) {
389 mfd->split_fb_left = mfd->panel_info->xres;
390 mfd->split_fb_right = panel_xres - mfd->split_fb_left;
391 rc = 0;
392 } else {
393 mfd->split_fb_left = mfd->split_fb_right = 0;
394 }
395 }
396
397 return rc;
398}
399
400static ssize_t mdss_fb_store_split(struct device *dev,
401 struct device_attribute *attr, const char *buf, size_t len)
402{
403 int data[2] = {0};
404 struct fb_info *fbi = dev_get_drvdata(dev);
405 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
406
407 if (sscanf(buf, "%d %d", &data[0], &data[1]) != 2)
408 pr_debug("Not able to read split values\n");
409 else if (!mdss_fb_validate_split(data[0], data[1], mfd))
410 pr_debug("split left=%d right=%d\n", data[0], data[1]);
411
412 return len;
413}
414
415static ssize_t mdss_fb_show_split(struct device *dev,
416 struct device_attribute *attr, char *buf)
417{
418 ssize_t ret = 0;
419 struct fb_info *fbi = dev_get_drvdata(dev);
420 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
421
422 ret = snprintf(buf, PAGE_SIZE, "%d %d\n",
423 mfd->split_fb_left, mfd->split_fb_right);
424 return ret;
425}
426
427static void mdss_fb_get_split(struct msm_fb_data_type *mfd)
428{
429 if ((mfd->split_mode == MDP_SPLIT_MODE_NONE) &&
430 (mfd->split_fb_left && mfd->split_fb_right))
431 mfd->split_mode = MDP_DUAL_LM_SINGLE_DISPLAY;
432
433 pr_debug("split fb%d left=%d right=%d mode=%d\n", mfd->index,
434 mfd->split_fb_left, mfd->split_fb_right, mfd->split_mode);
435}
436
437static ssize_t mdss_fb_get_src_split_info(struct device *dev,
438 struct device_attribute *attr, char *buf)
439{
440 int ret = 0;
441 struct fb_info *fbi = dev_get_drvdata(dev);
442 struct msm_fb_data_type *mfd = fbi->par;
443
444 if (is_split_lm(mfd) && (fbi->var.yres > fbi->var.xres)) {
445 pr_debug("always split mode enabled\n");
446 ret = scnprintf(buf, PAGE_SIZE,
447 "src_split_always\n");
448 }
449
450 return ret;
451}
452
453static ssize_t mdss_fb_get_thermal_level(struct device *dev,
454 struct device_attribute *attr, char *buf)
455{
456 struct fb_info *fbi = dev_get_drvdata(dev);
457 struct msm_fb_data_type *mfd = fbi->par;
458 int ret;
459
460 ret = scnprintf(buf, PAGE_SIZE, "thermal_level=%d\n",
461 mfd->thermal_level);
462
463 return ret;
464}
465
466static ssize_t mdss_fb_set_thermal_level(struct device *dev,
467 struct device_attribute *attr, const char *buf, size_t count)
468{
469 struct fb_info *fbi = dev_get_drvdata(dev);
470 struct msm_fb_data_type *mfd = fbi->par;
471 int rc = 0;
472 int thermal_level = 0;
473
474 rc = kstrtoint(buf, 10, &thermal_level);
475 if (rc) {
476 pr_err("kstrtoint failed. rc=%d\n", rc);
477 return rc;
478 }
479
480 pr_debug("Thermal level set to %d\n", thermal_level);
481 mfd->thermal_level = thermal_level;
482 sysfs_notify(&mfd->fbi->dev->kobj, NULL, "msm_fb_thermal_level");
483
484 return count;
485}
486
487static ssize_t mdss_mdp_show_blank_event(struct device *dev,
488 struct device_attribute *attr, char *buf)
489{
490 struct fb_info *fbi = dev_get_drvdata(dev);
491 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
492 int ret;
493
494 pr_debug("fb%d panel_power_state = %d\n", mfd->index,
495 mfd->panel_power_state);
496 ret = scnprintf(buf, PAGE_SIZE, "panel_power_on = %d\n",
497 mfd->panel_power_state);
498
499 return ret;
500}
501
502static void __mdss_fb_idle_notify_work(struct work_struct *work)
503{
504 struct delayed_work *dw = to_delayed_work(work);
505 struct msm_fb_data_type *mfd = container_of(dw, struct msm_fb_data_type,
506 idle_notify_work);
507
508 /* Notify idle-ness here */
509 pr_debug("Idle timeout %dms expired!\n", mfd->idle_time);
510 if (mfd->idle_time)
511 sysfs_notify(&mfd->fbi->dev->kobj, NULL, "idle_notify");
512 mfd->idle_state = MDSS_FB_IDLE;
513}
514
515
516static ssize_t mdss_fb_get_fps_info(struct device *dev,
517 struct device_attribute *attr, char *buf)
518{
519 struct fb_info *fbi = dev_get_drvdata(dev);
520 struct msm_fb_data_type *mfd = fbi->par;
Sachin Bhayareb6b5a0f2018-03-02 19:50:39 +0530521 u64 fps_int, fps_float;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530522
523 if (mfd->panel_power_state != MDSS_PANEL_POWER_ON)
524 mfd->fps_info.measured_fps = 0;
Sachin Bhayareb6b5a0f2018-03-02 19:50:39 +0530525 fps_int = (u64) mfd->fps_info.measured_fps;
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530526 fps_float = do_div(fps_int, 10);
Sachin Bhayareb6b5a0f2018-03-02 19:50:39 +0530527 return scnprintf(buf, PAGE_SIZE, "%llu.%llu\n", fps_int, fps_float);
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530528
529}
530
531static ssize_t mdss_fb_get_idle_time(struct device *dev,
532 struct device_attribute *attr, char *buf)
533{
534 struct fb_info *fbi = dev_get_drvdata(dev);
535 struct msm_fb_data_type *mfd = fbi->par;
536 int ret;
537
538 ret = scnprintf(buf, PAGE_SIZE, "%d", mfd->idle_time);
539
540 return ret;
541}
542
543static ssize_t mdss_fb_set_idle_time(struct device *dev,
544 struct device_attribute *attr, const char *buf, size_t count)
545{
546 struct fb_info *fbi = dev_get_drvdata(dev);
547 struct msm_fb_data_type *mfd = fbi->par;
548 int rc = 0;
549 int idle_time = 0;
550
551 rc = kstrtoint(buf, 10, &idle_time);
552 if (rc) {
553 pr_err("kstrtoint failed. rc=%d\n", rc);
554 return rc;
555 }
556
557 pr_debug("Idle time = %d\n", idle_time);
558 mfd->idle_time = idle_time;
559
560 return count;
561}
562
563static ssize_t mdss_fb_get_idle_notify(struct device *dev,
564 struct device_attribute *attr, char *buf)
565{
566 struct fb_info *fbi = dev_get_drvdata(dev);
567 struct msm_fb_data_type *mfd = fbi->par;
568 int ret;
569
570 ret = scnprintf(buf, PAGE_SIZE, "%s",
571 work_busy(&mfd->idle_notify_work.work) ? "no" : "yes");
572
573 return ret;
574}
575
576static ssize_t mdss_fb_get_panel_info(struct device *dev,
577 struct device_attribute *attr, char *buf)
578{
579 struct fb_info *fbi = dev_get_drvdata(dev);
580 struct msm_fb_data_type *mfd = fbi->par;
581 struct mdss_panel_info *pinfo = mfd->panel_info;
582 int ret;
583
584 ret = scnprintf(buf, PAGE_SIZE,
585 "pu_en=%d\nxstart=%d\nwalign=%d\nystart=%d\nhalign=%d\n"
586 "min_w=%d\nmin_h=%d\nroi_merge=%d\ndyn_fps_en=%d\n"
587 "min_fps=%d\nmax_fps=%d\npanel_name=%s\n"
588 "primary_panel=%d\nis_pluggable=%d\ndisplay_id=%s\n"
589 "is_cec_supported=%d\nis_pingpong_split=%d\n"
590 "is_hdr_enabled=%d\n"
591 "peak_brightness=%d\nblackness_level=%d\n"
592 "white_chromaticity_x=%d\nwhite_chromaticity_y=%d\n"
593 "red_chromaticity_x=%d\nred_chromaticity_y=%d\n"
594 "green_chromaticity_x=%d\ngreen_chromaticity_y=%d\n"
595 "blue_chromaticity_x=%d\nblue_chromaticity_y=%d\n",
596 pinfo->partial_update_enabled,
597 pinfo->roi_alignment.xstart_pix_align,
598 pinfo->roi_alignment.width_pix_align,
599 pinfo->roi_alignment.ystart_pix_align,
600 pinfo->roi_alignment.height_pix_align,
601 pinfo->roi_alignment.min_width,
602 pinfo->roi_alignment.min_height,
603 pinfo->partial_update_roi_merge,
604 pinfo->dynamic_fps, pinfo->min_fps, pinfo->max_fps,
605 pinfo->panel_name, pinfo->is_prim_panel,
606 pinfo->is_pluggable, pinfo->display_id,
607 pinfo->is_cec_supported, is_pingpong_split(mfd),
608 pinfo->hdr_properties.hdr_enabled,
609 pinfo->hdr_properties.peak_brightness,
610 pinfo->hdr_properties.blackness_level,
611 pinfo->hdr_properties.display_primaries[0],
612 pinfo->hdr_properties.display_primaries[1],
613 pinfo->hdr_properties.display_primaries[2],
614 pinfo->hdr_properties.display_primaries[3],
615 pinfo->hdr_properties.display_primaries[4],
616 pinfo->hdr_properties.display_primaries[5],
617 pinfo->hdr_properties.display_primaries[6],
618 pinfo->hdr_properties.display_primaries[7]);
619
620 return ret;
621}
622
623static ssize_t mdss_fb_get_panel_status(struct device *dev,
624 struct device_attribute *attr, char *buf)
625{
626 struct fb_info *fbi = dev_get_drvdata(dev);
627 struct msm_fb_data_type *mfd = fbi->par;
628 int ret;
629 int panel_status;
630
631 if (mdss_panel_is_power_off(mfd->panel_power_state)) {
632 ret = scnprintf(buf, PAGE_SIZE, "panel_status=%s\n", "suspend");
633 } else {
634 panel_status = mdss_fb_send_panel_event(mfd,
635 MDSS_EVENT_DSI_PANEL_STATUS, NULL);
636 ret = scnprintf(buf, PAGE_SIZE, "panel_status=%s\n",
637 panel_status > 0 ? "alive" : "dead");
638 }
639
640 return ret;
641}
642
643static ssize_t mdss_fb_force_panel_dead(struct device *dev,
644 struct device_attribute *attr, const char *buf, size_t len)
645{
646 struct fb_info *fbi = dev_get_drvdata(dev);
647 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
648 struct mdss_panel_data *pdata;
649
650 pdata = dev_get_platdata(&mfd->pdev->dev);
651 if (!pdata) {
652 pr_err("no panel connected!\n");
653 return len;
654 }
655
656 if (kstrtouint(buf, 0, &pdata->panel_info.panel_force_dead))
657 pr_err("kstrtouint buf error!\n");
658
659 return len;
660}
661
662/*
663 * mdss_fb_blanking_mode_switch() - Function triggers dynamic mode switch
664 * @mfd: Framebuffer data structure for display
665 * @mode: Enabled/Disable LowPowerMode
666 * 1: Enter into LowPowerMode
667 * 0: Exit from LowPowerMode
668 *
669 * This Function dynamically switches to and from video mode. This
670 * swtich involves the panel turning off backlight during trantision.
671 */
672static int mdss_fb_blanking_mode_switch(struct msm_fb_data_type *mfd, int mode)
673{
674 int ret = 0;
675 u32 bl_lvl = 0;
676 struct mdss_panel_info *pinfo = NULL;
677 struct mdss_panel_data *pdata;
678
679 if (!mfd || !mfd->panel_info)
680 return -EINVAL;
681
682 pinfo = mfd->panel_info;
683
684 if (!pinfo->mipi.dms_mode) {
685 pr_warn("Panel does not support dynamic switch!\n");
686 return 0;
687 }
688
689 if (mode == pinfo->mipi.mode) {
690 pr_debug("Already in requested mode!\n");
691 return 0;
692 }
693 pr_debug("Enter mode: %d\n", mode);
694
695 pdata = dev_get_platdata(&mfd->pdev->dev);
696
697 pdata->panel_info.dynamic_switch_pending = true;
698 ret = mdss_fb_pan_idle(mfd);
699 if (ret) {
700 pr_err("mdss_fb_pan_idle for fb%d failed. ret=%d\n",
701 mfd->index, ret);
702 pdata->panel_info.dynamic_switch_pending = false;
703 return ret;
704 }
705
706 mutex_lock(&mfd->bl_lock);
707 bl_lvl = mfd->bl_level;
708 mdss_fb_set_backlight(mfd, 0);
709 mutex_unlock(&mfd->bl_lock);
710
711 lock_fb_info(mfd->fbi);
712 ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, mfd->fbi,
713 mfd->op_enable);
714 if (ret) {
715 pr_err("can't turn off display!\n");
716 unlock_fb_info(mfd->fbi);
717 return ret;
718 }
719
720 mfd->op_enable = false;
721
722 ret = mfd->mdp.configure_panel(mfd, mode, 1);
723 mdss_fb_set_mdp_sync_pt_threshold(mfd, mfd->panel.type);
724
725 mfd->op_enable = true;
726
727 ret = mdss_fb_blank_sub(FB_BLANK_UNBLANK, mfd->fbi,
728 mfd->op_enable);
729 if (ret) {
730 pr_err("can't turn on display!\n");
731 unlock_fb_info(mfd->fbi);
732 return ret;
733 }
734 unlock_fb_info(mfd->fbi);
735
736 mutex_lock(&mfd->bl_lock);
737 mfd->allow_bl_update = true;
738 mdss_fb_set_backlight(mfd, bl_lvl);
739 mutex_unlock(&mfd->bl_lock);
740
741 pdata->panel_info.dynamic_switch_pending = false;
742 pdata->panel_info.is_lpm_mode = mode ? 1 : 0;
743
744 if (ret) {
745 pr_err("can't turn on display!\n");
746 return ret;
747 }
748
749 pr_debug("Exit mode: %d\n", mode);
750
751 return 0;
752}
753
754static ssize_t mdss_fb_change_dfps_mode(struct device *dev,
755 struct device_attribute *attr, const char *buf, size_t len)
756{
757 struct fb_info *fbi = dev_get_drvdata(dev);
758 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
759 struct mdss_panel_data *pdata;
760 struct mdss_panel_info *pinfo;
761 u32 dfps_mode;
762
763 pdata = dev_get_platdata(&mfd->pdev->dev);
764 if (!pdata) {
765 pr_err("no panel connected!\n");
766 return len;
767 }
768 pinfo = &pdata->panel_info;
769
770 if (kstrtouint(buf, 0, &dfps_mode)) {
771 pr_err("kstrtouint buf error!\n");
772 return len;
773 }
774
775 if (dfps_mode >= DFPS_MODE_MAX) {
776 pinfo->dynamic_fps = false;
777 return len;
778 }
779
780 if (mfd->idle_time != 0) {
781 pr_err("ERROR: Idle time is not disabled.\n");
782 return len;
783 }
784
785 if (pinfo->current_fps != pinfo->default_fps) {
786 pr_err("ERROR: panel not configured to default fps\n");
787 return len;
788 }
789
790 pinfo->dynamic_fps = true;
791 pinfo->dfps_update = dfps_mode;
792
793 if (pdata->next)
794 pdata->next->panel_info.dfps_update = dfps_mode;
795
796 return len;
797}
798
799static ssize_t mdss_fb_get_dfps_mode(struct device *dev,
800 struct device_attribute *attr, char *buf)
801{
802 struct fb_info *fbi = dev_get_drvdata(dev);
803 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
804 struct mdss_panel_data *pdata;
805 struct mdss_panel_info *pinfo;
806 int ret;
807
808 pdata = dev_get_platdata(&mfd->pdev->dev);
809 if (!pdata) {
810 pr_err("no panel connected!\n");
811 return -EINVAL;
812 }
813 pinfo = &pdata->panel_info;
814
815 ret = scnprintf(buf, PAGE_SIZE, "dfps enabled=%d mode=%d\n",
816 pinfo->dynamic_fps, pinfo->dfps_update);
817
818 return ret;
819}
820
821static ssize_t mdss_fb_change_persist_mode(struct device *dev,
822 struct device_attribute *attr, const char *buf, size_t len)
823{
824 struct fb_info *fbi = dev_get_drvdata(dev);
825 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
826 struct mdss_panel_info *pinfo = NULL;
827 struct mdss_panel_data *pdata;
828 int ret = 0;
829 u32 persist_mode;
830
831 if (!mfd || !mfd->panel_info) {
832 pr_err("%s: Panel info is NULL!\n", __func__);
833 return len;
834 }
835
836 pinfo = mfd->panel_info;
837
838 if (kstrtouint(buf, 0, &persist_mode)) {
839 pr_err("kstrtouint buf error!\n");
840 return len;
841 }
842
843 mutex_lock(&mfd->mdss_sysfs_lock);
844 if (mdss_panel_is_power_off(mfd->panel_power_state)) {
845 pinfo->persist_mode = persist_mode;
846 goto end;
847 }
848
849 mutex_lock(&mfd->bl_lock);
850
851 pdata = dev_get_platdata(&mfd->pdev->dev);
852 if ((pdata) && (pdata->apply_display_setting))
853 ret = pdata->apply_display_setting(pdata, persist_mode);
854
855 mutex_unlock(&mfd->bl_lock);
856
857 if (!ret) {
858 pr_debug("%s: Persist mode %d\n", __func__, persist_mode);
859 pinfo->persist_mode = persist_mode;
860 }
861
862end:
863 mutex_unlock(&mfd->mdss_sysfs_lock);
864 return len;
865}
866
867static ssize_t mdss_fb_get_persist_mode(struct device *dev,
868 struct device_attribute *attr, char *buf)
869{
870 struct fb_info *fbi = dev_get_drvdata(dev);
871 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
872 struct mdss_panel_data *pdata;
873 struct mdss_panel_info *pinfo;
874 int ret;
875
876 pdata = dev_get_platdata(&mfd->pdev->dev);
877 if (!pdata) {
878 pr_err("no panel connected!\n");
879 return -EINVAL;
880 }
881 pinfo = &pdata->panel_info;
882
883 ret = scnprintf(buf, PAGE_SIZE, "%d\n", pinfo->persist_mode);
884
885 return ret;
886}
887
888static DEVICE_ATTR(msm_fb_type, 0444, mdss_fb_get_type, NULL);
889static DEVICE_ATTR(msm_fb_split, 0644, mdss_fb_show_split,
890 mdss_fb_store_split);
891static DEVICE_ATTR(show_blank_event, 0444, mdss_mdp_show_blank_event, NULL);
892static DEVICE_ATTR(idle_time, 0644,
893 mdss_fb_get_idle_time, mdss_fb_set_idle_time);
894static DEVICE_ATTR(idle_notify, 0444, mdss_fb_get_idle_notify, NULL);
895static DEVICE_ATTR(msm_fb_panel_info, 0444, mdss_fb_get_panel_info, NULL);
896static DEVICE_ATTR(msm_fb_src_split_info, 0444, mdss_fb_get_src_split_info,
897 NULL);
898static DEVICE_ATTR(msm_fb_thermal_level, 0644,
899 mdss_fb_get_thermal_level, mdss_fb_set_thermal_level);
900static DEVICE_ATTR(msm_fb_panel_status, 0644,
901 mdss_fb_get_panel_status, mdss_fb_force_panel_dead);
902static DEVICE_ATTR(msm_fb_dfps_mode, 0644,
903 mdss_fb_get_dfps_mode, mdss_fb_change_dfps_mode);
904static DEVICE_ATTR(measured_fps, 0664,
905 mdss_fb_get_fps_info, NULL);
906static DEVICE_ATTR(msm_fb_persist_mode, 0644,
907 mdss_fb_get_persist_mode, mdss_fb_change_persist_mode);
908static struct attribute *mdss_fb_attrs[] = {
909 &dev_attr_msm_fb_type.attr,
910 &dev_attr_msm_fb_split.attr,
911 &dev_attr_show_blank_event.attr,
912 &dev_attr_idle_time.attr,
913 &dev_attr_idle_notify.attr,
914 &dev_attr_msm_fb_panel_info.attr,
915 &dev_attr_msm_fb_src_split_info.attr,
916 &dev_attr_msm_fb_thermal_level.attr,
917 &dev_attr_msm_fb_panel_status.attr,
918 &dev_attr_msm_fb_dfps_mode.attr,
919 &dev_attr_measured_fps.attr,
920 &dev_attr_msm_fb_persist_mode.attr,
921 NULL,
922};
923
924static struct attribute_group mdss_fb_attr_group = {
925 .attrs = mdss_fb_attrs,
926};
927
928static int mdss_fb_create_sysfs(struct msm_fb_data_type *mfd)
929{
930 int rc;
931
932 rc = sysfs_create_group(&mfd->fbi->dev->kobj, &mdss_fb_attr_group);
933 if (rc)
934 pr_err("sysfs group creation failed, rc=%d\n", rc);
935 return rc;
936}
937
938static void mdss_fb_remove_sysfs(struct msm_fb_data_type *mfd)
939{
940 sysfs_remove_group(&mfd->fbi->dev->kobj, &mdss_fb_attr_group);
941}
942
943static void mdss_fb_shutdown(struct platform_device *pdev)
944{
945 struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
946
Sachin Bhayareeeb88892018-01-02 16:36:01 +0530947 mfd->shutdown_pending = true;
948
949 /* wake up threads waiting on idle or kickoff queues */
950 wake_up_all(&mfd->idle_wait_q);
951 wake_up_all(&mfd->kickoff_wait_q);
952
953 lock_fb_info(mfd->fbi);
954 mdss_fb_release_all(mfd->fbi, true);
955 sysfs_notify(&mfd->fbi->dev->kobj, NULL, "show_blank_event");
956 unlock_fb_info(mfd->fbi);
957}
958
959static void mdss_fb_input_event_handler(struct input_handle *handle,
960 unsigned int type,
961 unsigned int code,
962 int value)
963{
964 struct msm_fb_data_type *mfd = handle->handler->private;
965 int rc;
966
967 if ((type != EV_ABS) || !mdss_fb_is_power_on(mfd))
968 return;
969
970 if (mfd->mdp.input_event_handler) {
971 rc = mfd->mdp.input_event_handler(mfd);
972 if (rc)
973 pr_err("mdp input event handler failed\n");
974 }
975}
976
977static int mdss_fb_input_connect(struct input_handler *handler,
978 struct input_dev *dev,
979 const struct input_device_id *id)
980{
981 int rc;
982 struct input_handle *handle;
983
984 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
985 if (!handle)
986 return -ENOMEM;
987
988 handle->dev = dev;
989 handle->handler = handler;
990 handle->name = handler->name;
991
992 rc = input_register_handle(handle);
993 if (rc) {
994 pr_err("failed to register input handle, rc = %d\n", rc);
995 goto error;
996 }
997
998 rc = input_open_device(handle);
999 if (rc) {
1000 pr_err("failed to open input device, rc = %d\n", rc);
1001 goto error_unregister;
1002 }
1003
1004 return 0;
1005
1006error_unregister:
1007 input_unregister_handle(handle);
1008error:
1009 kfree(handle);
1010 return rc;
1011}
1012
1013static void mdss_fb_input_disconnect(struct input_handle *handle)
1014{
1015 input_close_device(handle);
1016 input_unregister_handle(handle);
1017 kfree(handle);
1018}
1019
1020/*
1021 * Structure for specifying event parameters on which to receive callbacks.
1022 * This structure will trigger a callback in case of a touch event (specified by
1023 * EV_ABS) where there is a change in X and Y coordinates,
1024 */
1025static const struct input_device_id mdss_fb_input_ids[] = {
1026 {
1027 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1028 .evbit = { BIT_MASK(EV_ABS) },
1029 .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] =
1030 BIT_MASK(ABS_MT_POSITION_X) |
1031 BIT_MASK(ABS_MT_POSITION_Y) },
1032 },
1033 { },
1034};
1035
1036static int mdss_fb_register_input_handler(struct msm_fb_data_type *mfd)
1037{
1038 int rc;
1039 struct input_handler *handler;
1040
1041 if (mfd->input_handler)
1042 return -EINVAL;
1043
1044 handler = kzalloc(sizeof(*handler), GFP_KERNEL);
1045 if (!handler)
1046 return -ENOMEM;
1047
1048 handler->event = mdss_fb_input_event_handler;
1049 handler->connect = mdss_fb_input_connect;
1050 handler->disconnect = mdss_fb_input_disconnect,
1051 handler->name = "mdss_fb",
1052 handler->id_table = mdss_fb_input_ids;
1053 handler->private = mfd;
1054
1055 rc = input_register_handler(handler);
1056 if (rc) {
1057 pr_err("Unable to register the input handler\n");
1058 kfree(handler);
1059 } else {
1060 mfd->input_handler = handler;
1061 }
1062
1063 return rc;
1064}
1065
1066static void mdss_fb_unregister_input_handler(struct msm_fb_data_type *mfd)
1067{
1068 if (!mfd->input_handler)
1069 return;
1070
1071 input_unregister_handler(mfd->input_handler);
1072 kfree(mfd->input_handler);
1073}
1074
1075static void mdss_fb_videomode_from_panel_timing(struct fb_videomode *videomode,
1076 struct mdss_panel_timing *pt)
1077{
1078 videomode->name = pt->name;
1079 videomode->xres = pt->xres;
1080 videomode->yres = pt->yres;
1081 videomode->left_margin = pt->h_back_porch;
1082 videomode->right_margin = pt->h_front_porch;
1083 videomode->hsync_len = pt->h_pulse_width;
1084 videomode->upper_margin = pt->v_back_porch;
1085 videomode->lower_margin = pt->v_front_porch;
1086 videomode->vsync_len = pt->v_pulse_width;
1087 videomode->refresh = pt->frame_rate;
1088 videomode->flag = 0;
1089 videomode->vmode = 0;
1090 videomode->sync = 0;
1091
1092 if (videomode->refresh) {
1093 unsigned long clk_rate, h_total, v_total;
1094
1095 h_total = videomode->xres + videomode->left_margin
1096 + videomode->right_margin + videomode->hsync_len;
1097 v_total = videomode->yres + videomode->lower_margin
1098 + videomode->upper_margin + videomode->vsync_len;
1099 clk_rate = h_total * v_total * videomode->refresh;
1100 videomode->pixclock =
1101 KHZ2PICOS(clk_rate / 1000);
1102 } else {
1103 videomode->pixclock =
1104 KHZ2PICOS((unsigned long)pt->clk_rate / 1000);
1105 }
1106}
1107
1108static void mdss_fb_set_split_mode(struct msm_fb_data_type *mfd,
1109 struct mdss_panel_data *pdata)
1110{
1111 if (pdata->panel_info.is_split_display) {
1112 struct mdss_panel_data *pnext = pdata->next;
1113
1114 mfd->split_fb_left = pdata->panel_info.lm_widths[0];
1115 if (pnext)
1116 mfd->split_fb_right = pnext->panel_info.lm_widths[0];
1117
1118 if (pdata->panel_info.use_pingpong_split)
1119 mfd->split_mode = MDP_PINGPONG_SPLIT;
1120 else
1121 mfd->split_mode = MDP_DUAL_LM_DUAL_DISPLAY;
1122 } else if ((pdata->panel_info.lm_widths[0] != 0)
1123 && (pdata->panel_info.lm_widths[1] != 0)) {
1124 mfd->split_fb_left = pdata->panel_info.lm_widths[0];
1125 mfd->split_fb_right = pdata->panel_info.lm_widths[1];
1126 mfd->split_mode = MDP_DUAL_LM_SINGLE_DISPLAY;
1127 } else {
1128 mfd->split_mode = MDP_SPLIT_MODE_NONE;
1129 }
1130}
1131
1132static int mdss_fb_init_panel_modes(struct msm_fb_data_type *mfd,
1133 struct mdss_panel_data *pdata)
1134{
1135 struct fb_info *fbi = mfd->fbi;
1136 struct fb_videomode *modedb;
1137 struct mdss_panel_timing *pt;
1138 struct list_head *pos;
1139 int num_timings = 0;
1140 int i = 0;
1141
1142 /* check if multiple modes are supported */
1143 if (!pdata->timings_list.prev || !pdata->timings_list.next)
1144 INIT_LIST_HEAD(&pdata->timings_list);
1145
1146 if (!fbi || !pdata->current_timing || list_empty(&pdata->timings_list))
1147 return 0;
1148
1149 list_for_each(pos, &pdata->timings_list)
1150 num_timings++;
1151
1152 modedb = devm_kzalloc(fbi->dev, num_timings * sizeof(*modedb),
1153 GFP_KERNEL);
1154 if (!modedb)
1155 return -ENOMEM;
1156
1157 list_for_each_entry(pt, &pdata->timings_list, list) {
1158 struct mdss_panel_timing *spt = NULL;
1159
1160 mdss_fb_videomode_from_panel_timing(modedb + i, pt);
1161 if (pdata->next) {
1162 spt = mdss_panel_get_timing_by_name(pdata->next,
1163 modedb[i].name);
1164 if (!IS_ERR_OR_NULL(spt))
1165 modedb[i].xres += spt->xres;
1166 else
1167 pr_debug("no matching split config for %s\n",
1168 modedb[i].name);
1169
1170 /*
1171 * if no panel timing found for current, need to
1172 * disable it otherwise mark it as active
1173 */
1174 if (pt == pdata->current_timing)
1175 pdata->next->active = !IS_ERR_OR_NULL(spt);
1176 }
1177
1178 if (pt == pdata->current_timing) {
1179 pr_debug("found current mode: %s\n", pt->name);
1180 fbi->mode = modedb + i;
1181 }
1182 i++;
1183 }
1184
1185 fbi->monspecs.modedb = modedb;
1186 fbi->monspecs.modedb_len = num_timings;
1187
1188 /* destroy and recreate modelist */
1189 fb_destroy_modelist(&fbi->modelist);
1190
1191 if (fbi->mode)
1192 fb_videomode_to_var(&fbi->var, fbi->mode);
1193 fb_videomode_to_modelist(modedb, num_timings, &fbi->modelist);
1194
1195 return 0;
1196}
1197
1198static int mdss_fb_probe(struct platform_device *pdev)
1199{
1200 struct msm_fb_data_type *mfd = NULL;
1201 struct mdss_panel_data *pdata;
1202 struct fb_info *fbi;
1203 int rc;
1204
1205 if (fbi_list_index >= MAX_FBI_LIST)
1206 return -ENOMEM;
1207
1208 pdata = dev_get_platdata(&pdev->dev);
1209 if (!pdata)
1210 return -EPROBE_DEFER;
1211
1212 if (!mdp_instance) {
1213 pr_err("mdss mdp resource not initialized yet\n");
1214 return -ENODEV;
1215 }
1216
1217 /*
1218 * alloc framebuffer info + par data
1219 */
1220 fbi = framebuffer_alloc(sizeof(struct msm_fb_data_type), NULL);
1221 if (fbi == NULL) {
1222 pr_err("can't allocate framebuffer info data!\n");
1223 return -ENOMEM;
1224 }
1225
1226 mfd = (struct msm_fb_data_type *)fbi->par;
1227 mfd->key = MFD_KEY;
1228 mfd->fbi = fbi;
1229 mfd->panel_info = &pdata->panel_info;
1230 mfd->panel.type = pdata->panel_info.type;
1231 mfd->panel.id = mfd->index;
1232 mfd->fb_page = MDSS_FB_NUM;
1233 mfd->index = fbi_list_index;
1234 mfd->mdp_fb_page_protection = MDP_FB_PAGE_PROTECTION_WRITECOMBINE;
1235
1236 mfd->ext_ad_ctrl = -1;
1237 if (mfd->panel_info && mfd->panel_info->brightness_max > 0)
1238 MDSS_BRIGHT_TO_BL(mfd->bl_level, backlight_led.brightness,
1239 mfd->panel_info->bl_max, mfd->panel_info->brightness_max);
1240 else
1241 mfd->bl_level = 0;
1242
1243 mfd->bl_scale = 1024;
1244 mfd->bl_min_lvl = 30;
1245 mfd->ad_bl_level = 0;
1246 mfd->fb_imgType = MDP_RGBA_8888;
1247 mfd->calib_mode_bl = 0;
1248 mfd->unset_bl_level = U32_MAX;
1249
1250 mfd->pdev = pdev;
1251
1252 mfd->split_fb_left = mfd->split_fb_right = 0;
1253
1254 mdss_fb_set_split_mode(mfd, pdata);
1255 pr_info("fb%d: split_mode:%d left:%d right:%d\n", mfd->index,
1256 mfd->split_mode, mfd->split_fb_left, mfd->split_fb_right);
1257
1258 mfd->mdp = *mdp_instance;
1259
1260 rc = of_property_read_bool(pdev->dev.of_node,
1261 "qcom,boot-indication-enabled");
1262
1263 if (rc) {
1264 led_trigger_register_simple("boot-indication",
1265 &(mfd->boot_notification_led));
1266 }
1267
1268 INIT_LIST_HEAD(&mfd->file_list);
1269
1270 mutex_init(&mfd->bl_lock);
1271 mutex_init(&mfd->mdss_sysfs_lock);
1272 mutex_init(&mfd->switch_lock);
1273
1274 fbi_list[fbi_list_index++] = fbi;
1275
1276 platform_set_drvdata(pdev, mfd);
1277
1278 rc = mdss_fb_register(mfd);
1279 if (rc)
1280 return rc;
1281
1282 mdss_fb_create_sysfs(mfd);
1283 mdss_fb_send_panel_event(mfd, MDSS_EVENT_FB_REGISTERED, fbi);
1284
1285 if (mfd->mdp.init_fnc) {
1286 rc = mfd->mdp.init_fnc(mfd);
1287 if (rc) {
1288 pr_err("init_fnc failed\n");
1289 return rc;
1290 }
1291 }
1292 mdss_fb_init_fps_info(mfd);
1293
1294 rc = pm_runtime_set_active(mfd->fbi->dev);
1295 if (rc < 0)
1296 pr_err("pm_runtime: fail to set active.\n");
1297 pm_runtime_enable(mfd->fbi->dev);
1298
1299 /* android supports only one lcd-backlight/lcd for now */
1300 if (!lcd_backlight_registered) {
1301 backlight_led.brightness = mfd->panel_info->brightness_max;
1302 backlight_led.max_brightness = mfd->panel_info->brightness_max;
1303 if (led_classdev_register(&pdev->dev, &backlight_led))
1304 pr_err("led_classdev_register failed\n");
1305 else
1306 lcd_backlight_registered = 1;
1307 }
1308
1309 mdss_fb_init_panel_modes(mfd, pdata);
1310
1311 mfd->mdp_sync_pt_data.fence_name = "mdp-fence";
1312 if (mfd->mdp_sync_pt_data.timeline == NULL) {
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05301313 char timeline_name[32];
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301314
1315 snprintf(timeline_name, sizeof(timeline_name),
1316 "mdss_fb_%d", mfd->index);
1317 mfd->mdp_sync_pt_data.timeline =
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05301318 mdss_create_timeline(timeline_name);
1319 if (mfd->mdp_sync_pt_data.timeline == NULL) {
1320 pr_err("cannot create release fence time line\n");
1321 return -ENOMEM;
1322 }
1323 snprintf(timeline_name, sizeof(timeline_name),
1324 "mdss_fb_%d_retire", mfd->index);
1325 mfd->mdp_sync_pt_data.timeline_retire =
1326 mdss_create_timeline(timeline_name);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301327 if (mfd->mdp_sync_pt_data.timeline == NULL) {
1328 pr_err("cannot create release fence time line\n");
1329 return -ENOMEM;
1330 }
1331 mfd->mdp_sync_pt_data.notifier.notifier_call =
1332 __mdss_fb_sync_buf_done_callback;
1333 }
1334
1335 mdss_fb_set_mdp_sync_pt_threshold(mfd, mfd->panel.type);
1336
1337 if (mfd->mdp.splash_init_fnc)
1338 mfd->mdp.splash_init_fnc(mfd);
1339
1340 /*
1341 * Register with input driver for a callback for command mode panels.
1342 * When there is an input event, mdp clocks will be turned on to reduce
1343 * latency when a frame update happens.
1344 * For video mode panels, idle timeout will be delayed so that userspace
1345 * does not get an idle event while new frames are expected. In case of
1346 * an idle event, user space tries to fall back to GPU composition which
1347 * can lead to increased load when there are new frames.
1348 */
1349 if (mfd->mdp.input_event_handler &&
1350 ((mfd->panel_info->type == MIPI_CMD_PANEL) ||
1351 (mfd->panel_info->type == MIPI_VIDEO_PANEL)))
1352 if (mdss_fb_register_input_handler(mfd))
1353 pr_err("failed to register input handler\n");
1354
1355 INIT_DELAYED_WORK(&mfd->idle_notify_work, __mdss_fb_idle_notify_work);
1356
1357 return rc;
1358}
1359
1360static void mdss_fb_set_mdp_sync_pt_threshold(struct msm_fb_data_type *mfd,
1361 int type)
1362{
1363 if (!mfd)
1364 return;
1365
1366 switch (type) {
1367 case WRITEBACK_PANEL:
1368 mfd->mdp_sync_pt_data.threshold = 1;
1369 mfd->mdp_sync_pt_data.retire_threshold = 0;
1370 break;
1371 case MIPI_CMD_PANEL:
1372 mfd->mdp_sync_pt_data.threshold = 1;
1373 mfd->mdp_sync_pt_data.retire_threshold = 1;
1374 break;
1375 default:
1376 mfd->mdp_sync_pt_data.threshold = 2;
1377 mfd->mdp_sync_pt_data.retire_threshold = 0;
1378 break;
1379 }
1380}
1381
1382static int mdss_fb_remove(struct platform_device *pdev)
1383{
1384 struct msm_fb_data_type *mfd;
1385
1386 mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
1387
1388 if (!mfd)
1389 return -ENODEV;
1390
1391 mdss_fb_remove_sysfs(mfd);
1392
1393 pm_runtime_disable(mfd->fbi->dev);
1394
1395 if (mfd->key != MFD_KEY)
1396 return -EINVAL;
1397
1398 mdss_fb_unregister_input_handler(mfd);
1399 mdss_panel_debugfs_cleanup(mfd->panel_info);
1400
1401 if (mdss_fb_suspend_sub(mfd))
1402 pr_err("msm_fb_remove: can't stop the device %d\n",
1403 mfd->index);
1404
1405 /* remove /dev/fb* */
1406 unregister_framebuffer(mfd->fbi);
1407
1408 if (lcd_backlight_registered) {
1409 lcd_backlight_registered = 0;
1410 led_classdev_unregister(&backlight_led);
1411 }
1412
1413 return 0;
1414}
1415
1416static int mdss_fb_send_panel_event(struct msm_fb_data_type *mfd,
1417 int event, void *arg)
1418{
1419 int ret = 0;
1420 struct mdss_panel_data *pdata;
1421
1422 pdata = dev_get_platdata(&mfd->pdev->dev);
1423 if (!pdata) {
1424 pr_err("no panel connected\n");
1425 return -ENODEV;
1426 }
1427
1428 pr_debug("sending event=%d for fb%d\n", event, mfd->index);
1429
1430 do {
1431 if (pdata->event_handler)
1432 ret = pdata->event_handler(pdata, event, arg);
1433
1434 pdata = pdata->next;
1435 } while (!ret && pdata);
1436
1437 return ret;
1438}
1439
1440static int mdss_fb_suspend_sub(struct msm_fb_data_type *mfd)
1441{
1442 int ret = 0;
1443
1444 if ((!mfd) || (mfd->key != MFD_KEY))
1445 return 0;
1446
1447 pr_debug("mdss_fb suspend index=%d\n", mfd->index);
1448
1449 ret = mdss_fb_pan_idle(mfd);
1450 if (ret) {
1451 pr_warn("mdss_fb_pan_idle for fb%d failed. ret=%d\n",
1452 mfd->index, ret);
1453 goto exit;
1454 }
1455
1456 ret = mdss_fb_send_panel_event(mfd, MDSS_EVENT_SUSPEND, NULL);
1457 if (ret) {
1458 pr_warn("unable to suspend fb%d (%d)\n", mfd->index, ret);
1459 goto exit;
1460 }
1461
1462 mfd->suspend.op_enable = mfd->op_enable;
1463 mfd->suspend.panel_power_state = mfd->panel_power_state;
1464
1465 if (mfd->op_enable) {
1466 /*
1467 * Ideally, display should have either been blanked by now, or
1468 * should have transitioned to a low power state. If not, then
1469 * as a fall back option, enter ulp state to leave the display
1470 * on, but turn off all interface clocks.
1471 */
1472 if (mdss_fb_is_power_on(mfd)) {
1473 ret = mdss_fb_blank_sub(BLANK_FLAG_ULP, mfd->fbi,
1474 mfd->suspend.op_enable);
1475 if (ret) {
1476 pr_err("can't turn off display!\n");
1477 goto exit;
1478 }
1479 }
1480 mfd->op_enable = false;
1481 fb_set_suspend(mfd->fbi, FBINFO_STATE_SUSPENDED);
1482 }
1483exit:
1484 return ret;
1485}
1486
1487static int mdss_fb_resume_sub(struct msm_fb_data_type *mfd)
1488{
1489 int ret = 0;
1490
1491 if ((!mfd) || (mfd->key != MFD_KEY))
1492 return 0;
1493
1494 reinit_completion(&mfd->power_set_comp);
1495 mfd->is_power_setting = true;
1496 pr_debug("mdss_fb resume index=%d\n", mfd->index);
1497
1498 ret = mdss_fb_pan_idle(mfd);
1499 if (ret) {
1500 pr_warn("mdss_fb_pan_idle for fb%d failed. ret=%d\n",
1501 mfd->index, ret);
1502 return ret;
1503 }
1504
1505 ret = mdss_fb_send_panel_event(mfd, MDSS_EVENT_RESUME, NULL);
1506 if (ret) {
1507 pr_warn("unable to resume fb%d (%d)\n", mfd->index, ret);
1508 return ret;
1509 }
1510
1511 /* resume state var recover */
1512 mfd->op_enable = mfd->suspend.op_enable;
1513
1514 /*
1515 * If the fb was explicitly blanked or transitioned to ulp during
1516 * suspend, then undo it during resume with the appropriate unblank
1517 * flag. If fb was in ulp state when entering suspend, then nothing
1518 * needs to be done.
1519 */
1520 if (mdss_panel_is_power_on(mfd->suspend.panel_power_state) &&
1521 !mdss_panel_is_power_on_ulp(mfd->suspend.panel_power_state)) {
1522 int unblank_flag = mdss_panel_is_power_on_interactive(
1523 mfd->suspend.panel_power_state) ? FB_BLANK_UNBLANK :
1524 BLANK_FLAG_LP;
1525
1526 ret = mdss_fb_blank_sub(unblank_flag, mfd->fbi, mfd->op_enable);
1527 if (ret)
1528 pr_warn("can't turn on display!\n");
1529 else
1530 fb_set_suspend(mfd->fbi, FBINFO_STATE_RUNNING);
1531 }
1532 mfd->is_power_setting = false;
1533 complete_all(&mfd->power_set_comp);
1534
1535 return ret;
1536}
1537
1538#if defined(CONFIG_PM) && !defined(CONFIG_PM_SLEEP)
1539static int mdss_fb_suspend(struct platform_device *pdev, pm_message_t state)
1540{
1541 struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
1542
1543 if (!mfd)
1544 return -ENODEV;
1545
1546 dev_dbg(&pdev->dev, "display suspend\n");
1547
1548 return mdss_fb_suspend_sub(mfd);
1549}
1550
1551static int mdss_fb_resume(struct platform_device *pdev)
1552{
1553 struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
1554
1555 if (!mfd)
1556 return -ENODEV;
1557
1558 dev_dbg(&pdev->dev, "display resume\n");
1559
1560 return mdss_fb_resume_sub(mfd);
1561}
1562#else
1563#define mdss_fb_suspend NULL
1564#define mdss_fb_resume NULL
1565#endif
1566
1567#ifdef CONFIG_PM_SLEEP
1568static int mdss_fb_pm_suspend(struct device *dev)
1569{
1570 struct msm_fb_data_type *mfd = dev_get_drvdata(dev);
1571
1572 if (!mfd)
1573 return -ENODEV;
1574
1575 dev_dbg(dev, "display pm suspend\n");
1576
1577 return mdss_fb_suspend_sub(mfd);
1578}
1579
1580static int mdss_fb_pm_resume(struct device *dev)
1581{
1582 struct msm_fb_data_type *mfd = dev_get_drvdata(dev);
1583
1584 if (!mfd)
1585 return -ENODEV;
1586
1587 dev_dbg(dev, "display pm resume\n");
1588
1589 /*
1590 * It is possible that the runtime status of the fb device may
1591 * have been active when the system was suspended. Reset the runtime
1592 * status to suspended state after a complete system resume.
1593 */
1594 pm_runtime_disable(dev);
1595 pm_runtime_set_suspended(dev);
1596 pm_runtime_enable(dev);
1597
1598 return mdss_fb_resume_sub(mfd);
1599}
1600#endif
1601
1602static const struct dev_pm_ops mdss_fb_pm_ops = {
1603 SET_SYSTEM_SLEEP_PM_OPS(mdss_fb_pm_suspend, mdss_fb_pm_resume)
1604};
1605
1606static const struct of_device_id mdss_fb_dt_match[] = {
1607 { .compatible = "qcom,mdss-fb",},
1608 {}
1609};
1610EXPORT_COMPAT("qcom,mdss-fb");
1611
1612static struct platform_driver mdss_fb_driver = {
1613 .probe = mdss_fb_probe,
1614 .remove = mdss_fb_remove,
1615 .suspend = mdss_fb_suspend,
1616 .resume = mdss_fb_resume,
1617 .shutdown = mdss_fb_shutdown,
1618 .driver = {
1619 .name = "mdss_fb",
1620 .of_match_table = mdss_fb_dt_match,
1621 .pm = &mdss_fb_pm_ops,
1622 },
1623};
1624
1625static void mdss_fb_scale_bl(struct msm_fb_data_type *mfd, u32 *bl_lvl)
1626{
1627 u32 temp = *bl_lvl;
1628
1629 pr_debug("input = %d, scale = %d\n", temp, mfd->bl_scale);
1630 if (temp >= mfd->bl_min_lvl) {
1631 if (temp > mfd->panel_info->bl_max) {
1632 pr_warn("%s: invalid bl level\n",
1633 __func__);
1634 temp = mfd->panel_info->bl_max;
1635 }
1636 if (mfd->bl_scale > 1024) {
1637 pr_warn("%s: invalid bl scale\n",
1638 __func__);
1639 mfd->bl_scale = 1024;
1640 }
1641 /*
1642 * bl_scale is the numerator of
1643 * scaling fraction (x/1024)
1644 */
1645 temp = (temp * mfd->bl_scale) / 1024;
1646
1647 /*if less than minimum level, use min level*/
1648 if (temp < mfd->bl_min_lvl)
1649 temp = mfd->bl_min_lvl;
1650 }
1651 pr_debug("output = %d\n", temp);
1652
1653 (*bl_lvl) = temp;
1654}
1655
1656/* must call this function from within mfd->bl_lock */
1657void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl)
1658{
1659 struct mdss_panel_data *pdata;
1660 u32 temp = bkl_lvl;
1661 bool ad_bl_notify_needed = false;
1662 bool bl_notify_needed = false;
1663
1664 if ((((mdss_fb_is_power_off(mfd) && mfd->dcm_state != DCM_ENTER)
1665 || !mfd->allow_bl_update) && !IS_CALIB_MODE_BL(mfd)) ||
1666 mfd->panel_info->cont_splash_enabled) {
1667 mfd->unset_bl_level = bkl_lvl;
1668 return;
1669 } else if (mdss_fb_is_power_on(mfd) && mfd->panel_info->panel_dead) {
1670 mfd->unset_bl_level = mfd->bl_level;
1671 } else {
1672 mfd->unset_bl_level = U32_MAX;
1673 }
1674
1675 pdata = dev_get_platdata(&mfd->pdev->dev);
1676
1677 if ((pdata) && (pdata->set_backlight)) {
1678 if (mfd->mdp.ad_calc_bl)
1679 (*mfd->mdp.ad_calc_bl)(mfd, temp, &temp,
1680 &ad_bl_notify_needed);
1681 if (!IS_CALIB_MODE_BL(mfd))
1682 mdss_fb_scale_bl(mfd, &temp);
1683 /*
1684 * Even though backlight has been scaled, want to show that
1685 * backlight has been set to bkl_lvl to those that read from
1686 * sysfs node. Thus, need to set bl_level even if it appears
1687 * the backlight has already been set to the level it is at,
1688 * as well as setting bl_level to bkl_lvl even though the
1689 * backlight has been set to the scaled value.
1690 */
1691 if (mfd->bl_level_scaled == temp) {
1692 mfd->bl_level = bkl_lvl;
1693 } else {
1694 if (mfd->bl_level != bkl_lvl)
1695 bl_notify_needed = true;
1696 pr_debug("backlight sent to panel :%d\n", temp);
1697 pdata->set_backlight(pdata, temp);
1698 mfd->bl_level = bkl_lvl;
1699 mfd->bl_level_scaled = temp;
1700 }
1701 if (ad_bl_notify_needed)
1702 mdss_fb_bl_update_notify(mfd,
1703 NOTIFY_TYPE_BL_AD_ATTEN_UPDATE);
1704 if (bl_notify_needed)
1705 mdss_fb_bl_update_notify(mfd,
1706 NOTIFY_TYPE_BL_UPDATE);
1707 }
1708}
1709
1710void mdss_fb_update_backlight(struct msm_fb_data_type *mfd)
1711{
1712 struct mdss_panel_data *pdata;
1713 u32 temp;
1714 bool bl_notify = false;
1715
1716 if (mfd->unset_bl_level == U32_MAX)
1717 return;
1718 mutex_lock(&mfd->bl_lock);
1719 if (!mfd->allow_bl_update) {
1720 pdata = dev_get_platdata(&mfd->pdev->dev);
1721 if ((pdata) && (pdata->set_backlight)) {
1722 mfd->bl_level = mfd->unset_bl_level;
1723 temp = mfd->bl_level;
1724 if (mfd->mdp.ad_calc_bl)
1725 (*mfd->mdp.ad_calc_bl)(mfd, temp, &temp,
1726 &bl_notify);
1727 if (bl_notify)
1728 mdss_fb_bl_update_notify(mfd,
1729 NOTIFY_TYPE_BL_AD_ATTEN_UPDATE);
1730 mdss_fb_bl_update_notify(mfd, NOTIFY_TYPE_BL_UPDATE);
1731 pdata->set_backlight(pdata, temp);
1732 mfd->bl_level_scaled = mfd->unset_bl_level;
1733 mfd->allow_bl_update = true;
1734 }
1735 }
1736 mutex_unlock(&mfd->bl_lock);
1737}
1738
1739static int mdss_fb_start_disp_thread(struct msm_fb_data_type *mfd)
1740{
1741 int ret = 0;
1742
1743 pr_debug("%pS: start display thread fb%d\n",
1744 __builtin_return_address(0), mfd->index);
1745
1746 /* this is needed for new split request from debugfs */
1747 mdss_fb_get_split(mfd);
1748
1749 atomic_set(&mfd->commits_pending, 0);
1750 mfd->disp_thread = kthread_run(__mdss_fb_display_thread,
1751 mfd, "mdss_fb%d", mfd->index);
1752
1753 if (IS_ERR(mfd->disp_thread)) {
1754 pr_err("ERROR: unable to start display thread %d\n",
1755 mfd->index);
1756 ret = PTR_ERR(mfd->disp_thread);
1757 mfd->disp_thread = NULL;
1758 }
1759
1760 return ret;
1761}
1762
1763static void mdss_fb_stop_disp_thread(struct msm_fb_data_type *mfd)
1764{
1765 pr_debug("%pS: stop display thread fb%d\n",
1766 __builtin_return_address(0), mfd->index);
1767
1768 kthread_stop(mfd->disp_thread);
1769 mfd->disp_thread = NULL;
1770}
1771
1772static void mdss_panel_validate_debugfs_info(struct msm_fb_data_type *mfd)
1773{
1774 struct mdss_panel_info *panel_info = mfd->panel_info;
1775 struct fb_info *fbi = mfd->fbi;
1776 struct fb_var_screeninfo *var = &fbi->var;
1777 struct mdss_panel_data *pdata = container_of(panel_info,
1778 struct mdss_panel_data, panel_info);
1779
1780 if (panel_info->debugfs_info->override_flag) {
1781 if (mfd->mdp.off_fnc) {
1782 mfd->panel_reconfig = true;
1783 mfd->mdp.off_fnc(mfd);
1784 mfd->panel_reconfig = false;
1785 }
1786
1787 pr_debug("Overriding panel_info with debugfs_info\n");
1788 panel_info->debugfs_info->override_flag = 0;
1789 mdss_panel_debugfsinfo_to_panelinfo(panel_info);
1790 if (is_panel_split(mfd) && pdata->next)
1791 mdss_fb_validate_split(pdata->panel_info.xres,
1792 pdata->next->panel_info.xres, mfd);
1793 mdss_panelinfo_to_fb_var(panel_info, var);
1794 if (mdss_fb_send_panel_event(mfd, MDSS_EVENT_CHECK_PARAMS,
1795 panel_info))
1796 pr_err("Failed to send panel event CHECK_PARAMS\n");
1797 }
1798}
1799
1800static int mdss_fb_blank_blank(struct msm_fb_data_type *mfd,
1801 int req_power_state)
1802{
1803 int ret = 0;
1804 int cur_power_state, current_bl;
1805
1806 if (!mfd)
1807 return -EINVAL;
1808
1809 if (!mdss_fb_is_power_on(mfd) || !mfd->mdp.off_fnc)
1810 return 0;
1811
1812 cur_power_state = mfd->panel_power_state;
1813
1814 pr_debug("Transitioning from %d --> %d\n", cur_power_state,
1815 req_power_state);
1816
1817 if (cur_power_state == req_power_state) {
1818 pr_debug("No change in power state\n");
1819 return 0;
1820 }
1821
1822 mutex_lock(&mfd->update.lock);
1823 mfd->update.type = NOTIFY_TYPE_SUSPEND;
1824 mfd->update.is_suspend = 1;
1825 mutex_unlock(&mfd->update.lock);
1826 complete(&mfd->update.comp);
1827 del_timer(&mfd->no_update.timer);
1828 mfd->no_update.value = NOTIFY_TYPE_SUSPEND;
1829 complete(&mfd->no_update.comp);
1830
1831 mfd->op_enable = false;
1832 if (mdss_panel_is_power_off(req_power_state)) {
1833 /* Stop Display thread */
1834 if (mfd->disp_thread)
1835 mdss_fb_stop_disp_thread(mfd);
1836 mutex_lock(&mfd->bl_lock);
1837 current_bl = mfd->bl_level;
1838 mfd->allow_bl_update = true;
1839 mdss_fb_set_backlight(mfd, 0);
1840 mfd->allow_bl_update = false;
1841 mfd->unset_bl_level = current_bl;
1842 mutex_unlock(&mfd->bl_lock);
1843 }
1844 mfd->panel_power_state = req_power_state;
1845
1846 ret = mfd->mdp.off_fnc(mfd);
1847 if (ret)
1848 mfd->panel_power_state = cur_power_state;
1849 else if (mdss_panel_is_power_off(req_power_state))
1850 mdss_fb_release_fences(mfd);
1851 mfd->op_enable = true;
1852 complete(&mfd->power_off_comp);
1853
1854 return ret;
1855}
1856
1857static int mdss_fb_blank_unblank(struct msm_fb_data_type *mfd)
1858{
1859 int ret = 0;
1860 int cur_power_state;
1861
1862 if (!mfd)
1863 return -EINVAL;
1864
1865 if (mfd->panel_info->debugfs_info)
1866 mdss_panel_validate_debugfs_info(mfd);
1867
1868 /* Start Display thread */
1869 if (mfd->disp_thread == NULL) {
1870 ret = mdss_fb_start_disp_thread(mfd);
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05301871 if (IS_ERR_VALUE((unsigned long)ret))
Sachin Bhayareeeb88892018-01-02 16:36:01 +05301872 return ret;
1873 }
1874
1875 cur_power_state = mfd->panel_power_state;
1876 pr_debug("Transitioning from %d --> %d\n", cur_power_state,
1877 MDSS_PANEL_POWER_ON);
1878
1879 if (mdss_panel_is_power_on_interactive(cur_power_state)) {
1880 pr_debug("No change in power state\n");
1881 return 0;
1882 }
1883
1884 if (mfd->mdp.on_fnc) {
1885 struct mdss_panel_info *panel_info = mfd->panel_info;
1886 struct fb_var_screeninfo *var = &mfd->fbi->var;
1887
1888 ret = mfd->mdp.on_fnc(mfd);
1889 if (ret) {
1890 mdss_fb_stop_disp_thread(mfd);
1891 goto error;
1892 }
1893
1894 mfd->panel_power_state = MDSS_PANEL_POWER_ON;
1895 mfd->panel_info->panel_dead = false;
1896 mutex_lock(&mfd->update.lock);
1897 mfd->update.type = NOTIFY_TYPE_UPDATE;
1898 mfd->update.is_suspend = 0;
1899 mutex_unlock(&mfd->update.lock);
1900
1901 /*
1902 * Panel info can change depending in the information
1903 * programmed in the controller.
1904 * Update this info in the upstream structs.
1905 */
1906 mdss_panelinfo_to_fb_var(panel_info, var);
1907
1908 /* Start the work thread to signal idle time */
1909 if (mfd->idle_time)
1910 schedule_delayed_work(&mfd->idle_notify_work,
1911 msecs_to_jiffies(mfd->idle_time));
1912 }
1913
1914 /* Reset the backlight only if the panel was off */
1915 if (mdss_panel_is_power_off(cur_power_state)) {
1916 mutex_lock(&mfd->bl_lock);
1917 if (!mfd->allow_bl_update) {
1918 mfd->allow_bl_update = true;
1919 /*
1920 * If in AD calibration mode then frameworks would not
1921 * be allowed to update backlight hence post unblank
1922 * the backlight would remain 0 (0 is set in blank).
1923 * Hence resetting back to calibration mode value
1924 */
1925 if (IS_CALIB_MODE_BL(mfd))
1926 mdss_fb_set_backlight(mfd, mfd->calib_mode_bl);
1927 else if ((!mfd->panel_info->mipi.post_init_delay) &&
1928 (mfd->unset_bl_level != U32_MAX))
1929 mdss_fb_set_backlight(mfd, mfd->unset_bl_level);
1930
1931 /*
1932 * it blocks the backlight update between unblank and
1933 * first kickoff to avoid backlight turn on before black
1934 * frame is transferred to panel through unblank call.
1935 */
1936 mfd->allow_bl_update = false;
1937 }
1938 mutex_unlock(&mfd->bl_lock);
1939 }
1940
1941error:
1942 return ret;
1943}
1944
1945static int mdss_fb_blank_sub(int blank_mode, struct fb_info *info,
1946 int op_enable)
1947{
1948 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1949 int ret = 0;
1950 int cur_power_state, req_power_state = MDSS_PANEL_POWER_OFF;
1951 char trace_buffer[32];
1952
1953 if (!mfd || !op_enable)
1954 return -EPERM;
1955
1956 if (mfd->dcm_state == DCM_ENTER)
1957 return -EPERM;
1958
1959 pr_debug("%pS mode:%d\n", __builtin_return_address(0),
1960 blank_mode);
1961
1962 snprintf(trace_buffer, sizeof(trace_buffer), "fb%d blank %d",
1963 mfd->index, blank_mode);
1964 ATRACE_BEGIN(trace_buffer);
1965
1966 cur_power_state = mfd->panel_power_state;
1967
1968 /*
1969 * Low power (lp) and ultra low power (ulp) modes are currently only
1970 * supported for command mode panels. For all other panel, treat lp
1971 * mode as full unblank and ulp mode as full blank.
1972 */
1973 if (mfd->panel_info->type != MIPI_CMD_PANEL) {
1974 if (blank_mode == BLANK_FLAG_LP) {
1975 pr_debug("lp mode only valid for cmd mode panels\n");
1976 if (mdss_fb_is_power_on_interactive(mfd))
1977 return 0;
1978 blank_mode = FB_BLANK_UNBLANK;
1979 } else if (blank_mode == BLANK_FLAG_ULP) {
1980 pr_debug("ulp mode valid for cmd mode panels\n");
1981 if (mdss_fb_is_power_off(mfd))
1982 return 0;
1983 blank_mode = FB_BLANK_POWERDOWN;
1984 }
1985 }
1986
1987 switch (blank_mode) {
1988 case FB_BLANK_UNBLANK:
1989 pr_debug("unblank called. cur pwr state=%d\n", cur_power_state);
1990 ret = mdss_fb_blank_unblank(mfd);
1991 break;
1992 case BLANK_FLAG_ULP:
1993 req_power_state = MDSS_PANEL_POWER_LP2;
1994 pr_debug("ultra low power mode requested\n");
1995 if (mdss_fb_is_power_off(mfd)) {
1996 pr_debug("Unsupp transition: off --> ulp\n");
1997 return 0;
1998 }
1999
2000 ret = mdss_fb_blank_blank(mfd, req_power_state);
2001 break;
2002 case BLANK_FLAG_LP:
2003 req_power_state = MDSS_PANEL_POWER_LP1;
2004 pr_debug(" power mode requested\n");
2005
2006 /*
2007 * If low power mode is requested when panel is already off,
2008 * then first unblank the panel before entering low power mode
2009 */
2010 if (mdss_fb_is_power_off(mfd) && mfd->mdp.on_fnc) {
2011 pr_debug("off --> lp. switch to on first\n");
2012 ret = mdss_fb_blank_unblank(mfd);
2013 if (ret)
2014 break;
2015 }
2016
2017 ret = mdss_fb_blank_blank(mfd, req_power_state);
2018 break;
2019 case FB_BLANK_HSYNC_SUSPEND:
2020 case FB_BLANK_POWERDOWN:
2021 default:
2022 req_power_state = MDSS_PANEL_POWER_OFF;
2023 pr_debug("blank powerdown called\n");
2024 ret = mdss_fb_blank_blank(mfd, req_power_state);
2025 break;
2026 }
2027
2028 /* Notify listeners */
2029 sysfs_notify(&mfd->fbi->dev->kobj, NULL, "show_blank_event");
2030
2031 ATRACE_END(trace_buffer);
2032
2033 return ret;
2034}
2035
2036static int mdss_fb_blank(int blank_mode, struct fb_info *info)
2037{
2038 int ret;
2039 struct mdss_panel_data *pdata;
2040 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2041
2042 ret = mdss_fb_pan_idle(mfd);
2043 if (ret) {
2044 pr_warn("mdss_fb_pan_idle for fb%d failed. ret=%d\n",
2045 mfd->index, ret);
2046 return ret;
2047 }
2048 mutex_lock(&mfd->mdss_sysfs_lock);
2049 if (mfd->op_enable == 0) {
2050 if (blank_mode == FB_BLANK_UNBLANK)
2051 mfd->suspend.panel_power_state = MDSS_PANEL_POWER_ON;
2052 else if (blank_mode == BLANK_FLAG_ULP)
2053 mfd->suspend.panel_power_state = MDSS_PANEL_POWER_LP2;
2054 else if (blank_mode == BLANK_FLAG_LP)
2055 mfd->suspend.panel_power_state = MDSS_PANEL_POWER_LP1;
2056 else
2057 mfd->suspend.panel_power_state = MDSS_PANEL_POWER_OFF;
2058 ret = 0;
2059 goto end;
2060 }
2061 pr_debug("mode: %d\n", blank_mode);
2062
2063 pdata = dev_get_platdata(&mfd->pdev->dev);
2064
2065 if (pdata->panel_info.is_lpm_mode &&
2066 blank_mode == FB_BLANK_UNBLANK) {
2067 pr_debug("panel is in lpm mode\n");
2068 mfd->mdp.configure_panel(mfd, 0, 1);
2069 mdss_fb_set_mdp_sync_pt_threshold(mfd, mfd->panel.type);
2070 pdata->panel_info.is_lpm_mode = false;
2071 }
2072
2073 ret = mdss_fb_blank_sub(blank_mode, info, mfd->op_enable);
2074
2075end:
2076 mutex_unlock(&mfd->mdss_sysfs_lock);
2077 return ret;
2078}
2079
2080static inline int mdss_fb_create_ion_client(struct msm_fb_data_type *mfd)
2081{
2082 mfd->fb_ion_client = msm_ion_client_create("mdss_fb_iclient");
2083 if (IS_ERR_OR_NULL(mfd->fb_ion_client)) {
2084 pr_err("Err:client not created, val %d\n",
2085 PTR_RET(mfd->fb_ion_client));
2086 mfd->fb_ion_client = NULL;
2087 return PTR_RET(mfd->fb_ion_client);
2088 }
2089 return 0;
2090}
2091
2092void mdss_fb_free_fb_ion_memory(struct msm_fb_data_type *mfd)
2093{
2094 if (!mfd) {
2095 pr_err("no mfd\n");
2096 return;
2097 }
2098
2099 if (!mfd->fbi->screen_base)
2100 return;
2101
2102 if (!mfd->fb_ion_client || !mfd->fb_ion_handle) {
2103 pr_err("invalid input parameters for fb%d\n", mfd->index);
2104 return;
2105 }
2106
2107 mfd->fbi->screen_base = NULL;
2108 mfd->fbi->fix.smem_start = 0;
2109
2110 ion_unmap_kernel(mfd->fb_ion_client, mfd->fb_ion_handle);
2111
2112 if (mfd->mdp.fb_mem_get_iommu_domain && !(!mfd->fb_attachment ||
2113 !mfd->fb_attachment->dmabuf ||
2114 !mfd->fb_attachment->dmabuf->ops)) {
2115 dma_buf_unmap_attachment(mfd->fb_attachment, mfd->fb_table,
2116 DMA_BIDIRECTIONAL);
2117 dma_buf_detach(mfd->fbmem_buf, mfd->fb_attachment);
2118 dma_buf_put(mfd->fbmem_buf);
2119 }
2120
2121 ion_free(mfd->fb_ion_client, mfd->fb_ion_handle);
2122 mfd->fb_ion_handle = NULL;
2123 mfd->fbmem_buf = NULL;
2124}
2125
2126int mdss_fb_alloc_fb_ion_memory(struct msm_fb_data_type *mfd, size_t fb_size)
2127{
2128 int rc = 0;
2129 void *vaddr;
2130 int domain;
2131
2132 if (!mfd) {
2133 pr_err("Invalid input param - no mfd\n");
2134 return -EINVAL;
2135 }
2136
2137 if (!mfd->fb_ion_client) {
2138 rc = mdss_fb_create_ion_client(mfd);
2139 if (rc < 0) {
2140 pr_err("fb ion client couldn't be created - %d\n", rc);
2141 return rc;
2142 }
2143 }
2144
2145 pr_debug("size for mmap = %zu\n", fb_size);
2146 mfd->fb_ion_handle = ion_alloc(mfd->fb_ion_client, fb_size, SZ_4K,
2147 ION_HEAP(ION_SYSTEM_HEAP_ID), 0);
2148 if (IS_ERR_OR_NULL(mfd->fb_ion_handle)) {
2149 pr_err("unable to alloc fbmem from ion - %ld\n",
2150 PTR_ERR(mfd->fb_ion_handle));
2151 return PTR_ERR(mfd->fb_ion_handle);
2152 }
2153
2154 if (mfd->mdp.fb_mem_get_iommu_domain) {
2155 mfd->fbmem_buf = ion_share_dma_buf(mfd->fb_ion_client,
2156 mfd->fb_ion_handle);
2157 if (IS_ERR(mfd->fbmem_buf)) {
2158 rc = PTR_ERR(mfd->fbmem_buf);
2159 goto fb_mmap_failed;
2160 }
2161
2162 domain = mfd->mdp.fb_mem_get_iommu_domain();
2163
2164 mfd->fb_attachment = mdss_smmu_dma_buf_attach(mfd->fbmem_buf,
2165 &mfd->pdev->dev, domain);
2166 if (IS_ERR(mfd->fb_attachment)) {
2167 rc = PTR_ERR(mfd->fb_attachment);
2168 goto err_put;
2169 }
2170
2171 mfd->fb_table = dma_buf_map_attachment(mfd->fb_attachment,
2172 DMA_BIDIRECTIONAL);
2173 if (IS_ERR(mfd->fb_table)) {
2174 rc = PTR_ERR(mfd->fb_table);
2175 goto err_detach;
2176 }
2177 } else {
2178 pr_err("No IOMMU Domain\n");
2179 rc = -EINVAL;
2180 goto fb_mmap_failed;
2181 }
2182
2183 vaddr = ion_map_kernel(mfd->fb_ion_client, mfd->fb_ion_handle);
2184 if (IS_ERR_OR_NULL(vaddr)) {
2185 pr_err("ION memory mapping failed - %ld\n", PTR_ERR(vaddr));
2186 rc = PTR_ERR(vaddr);
2187 goto err_unmap;
2188 }
2189 pr_debug("alloc 0x%zxB vaddr = %pK for fb%d\n", fb_size,
2190 vaddr, mfd->index);
2191
2192 mfd->fbi->screen_base = (char *) vaddr;
2193 mfd->fbi->fix.smem_len = fb_size;
2194
2195 return rc;
2196
2197err_unmap:
2198 dma_buf_unmap_attachment(mfd->fb_attachment, mfd->fb_table,
2199 DMA_BIDIRECTIONAL);
2200err_detach:
2201 dma_buf_detach(mfd->fbmem_buf, mfd->fb_attachment);
2202err_put:
2203 dma_buf_put(mfd->fbmem_buf);
2204fb_mmap_failed:
2205 ion_free(mfd->fb_ion_client, mfd->fb_ion_handle);
2206 mfd->fb_attachment = NULL;
2207 mfd->fb_table = NULL;
2208 mfd->fb_ion_handle = NULL;
2209 mfd->fbmem_buf = NULL;
2210 return rc;
2211}
2212
2213/**
2214 * mdss_fb_fbmem_ion_mmap() - Custom fb mmap() function for MSM driver.
2215 *
2216 * @info - Framebuffer info.
2217 * @vma - VM area which is part of the process virtual memory.
2218 *
2219 * This framebuffer mmap function differs from standard mmap() function by
2220 * allowing for customized page-protection and dynamically allocate framebuffer
2221 * memory from system heap and map to iommu virtual address.
2222 *
2223 * Return: virtual address is returned through vma
2224 */
2225static int mdss_fb_fbmem_ion_mmap(struct fb_info *info,
2226 struct vm_area_struct *vma)
2227{
2228 int rc = 0;
2229 size_t req_size, fb_size;
2230 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2231 struct sg_table *table;
2232 unsigned long addr = vma->vm_start;
2233 unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
2234 struct scatterlist *sg;
2235 unsigned int i;
2236 struct page *page;
2237
2238 if (!mfd || !mfd->pdev || !mfd->pdev->dev.of_node) {
2239 pr_err("Invalid device node\n");
2240 return -ENODEV;
2241 }
2242
2243 req_size = vma->vm_end - vma->vm_start;
2244 fb_size = mfd->fbi->fix.smem_len;
2245 if (req_size > fb_size) {
2246 pr_warn("requested map is greater than framebuffer\n");
2247 return -EOVERFLOW;
2248 }
2249
2250 if (!mfd->fbi->screen_base) {
2251 rc = mdss_fb_alloc_fb_ion_memory(mfd, fb_size);
2252 if (rc < 0) {
2253 pr_err("fb mmap failed!!!!\n");
2254 return rc;
2255 }
2256 }
2257
2258 table = mfd->fb_table;
2259 if (IS_ERR(table)) {
2260 pr_err("Unable to get sg_table from ion:%ld\n", PTR_ERR(table));
2261 mfd->fbi->screen_base = NULL;
2262 return PTR_ERR(table);
2263 } else if (!table) {
2264 pr_err("sg_list is NULL\n");
2265 mfd->fbi->screen_base = NULL;
2266 return -EINVAL;
2267 }
2268
2269 page = sg_page(table->sgl);
2270 if (page) {
2271 for_each_sg(table->sgl, sg, table->nents, i) {
2272 unsigned long remainder = vma->vm_end - addr;
2273 unsigned long len = sg->length;
2274
2275 page = sg_page(sg);
2276
2277 if (offset >= sg->length) {
2278 offset -= sg->length;
2279 continue;
2280 } else if (offset) {
2281 page += offset / PAGE_SIZE;
2282 len = sg->length - offset;
2283 offset = 0;
2284 }
2285 len = min(len, remainder);
2286
2287 if (mfd->mdp_fb_page_protection ==
2288 MDP_FB_PAGE_PROTECTION_WRITECOMBINE)
2289 vma->vm_page_prot =
2290 pgprot_writecombine(vma->vm_page_prot);
2291
2292 pr_debug("vma=%pK, addr=%x len=%ld\n",
2293 vma, (unsigned int)addr, len);
2294 pr_debug("vm_start=%x vm_end=%x vm_page_prot=%ld\n",
Sachin Bhayareb6b5a0f2018-03-02 19:50:39 +05302295 (unsigned int)vma->vm_start,
2296 (unsigned int)vma->vm_end,
2297 (unsigned long int)pgprot_val(
2298 vma->vm_page_prot));
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302299
2300 io_remap_pfn_range(vma, addr, page_to_pfn(page), len,
2301 vma->vm_page_prot);
2302 addr += len;
2303 if (addr >= vma->vm_end)
2304 break;
2305 }
2306 } else {
2307 pr_err("PAGE is null\n");
2308 mdss_fb_free_fb_ion_memory(mfd);
2309 return -ENOMEM;
2310 }
2311
2312 return rc;
2313}
2314
2315/*
2316 * mdss_fb_physical_mmap() - Custom fb mmap() function for MSM driver.
2317 *
2318 * @info - Framebuffer info.
2319 * @vma - VM area which is part of the process virtual memory.
2320 *
2321 * This framebuffer mmap function differs from standard mmap() function as
2322 * map to framebuffer memory from the CMA memory which is allocated during
2323 * bootup.
2324 *
2325 * Return: virtual address is returned through vma
2326 */
2327static int mdss_fb_physical_mmap(struct fb_info *info,
2328 struct vm_area_struct *vma)
2329{
2330 /* Get frame buffer memory range. */
2331 unsigned long start = info->fix.smem_start;
2332 u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
2333 unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
2334 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2335
2336 if (!start) {
2337 pr_warn("No framebuffer memory is allocated\n");
2338 return -ENOMEM;
2339 }
2340
2341 /* Set VM flags. */
2342 start &= PAGE_MASK;
2343 if ((vma->vm_end <= vma->vm_start) ||
2344 (off >= len) ||
2345 ((vma->vm_end - vma->vm_start) > (len - off)))
2346 return -EINVAL;
2347 off += start;
2348 if (off < start)
2349 return -EINVAL;
2350 vma->vm_pgoff = off >> PAGE_SHIFT;
2351 /* This is an IO map - tell maydump to skip this VMA */
2352 vma->vm_flags |= VM_IO;
2353
2354 if (mfd->mdp_fb_page_protection == MDP_FB_PAGE_PROTECTION_WRITECOMBINE)
2355 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
2356
2357 /* Remap the frame buffer I/O range */
2358 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
2359 vma->vm_end - vma->vm_start,
2360 vma->vm_page_prot))
2361 return -EAGAIN;
2362
2363 return 0;
2364}
2365
2366static int mdss_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
2367{
2368 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2369 int rc = -EINVAL;
2370
2371 if (mfd->fb_mmap_type == MDP_FB_MMAP_ION_ALLOC) {
2372 rc = mdss_fb_fbmem_ion_mmap(info, vma);
2373 } else if (mfd->fb_mmap_type == MDP_FB_MMAP_PHYSICAL_ALLOC) {
2374 rc = mdss_fb_physical_mmap(info, vma);
2375 } else {
2376 if (!info->fix.smem_start && !mfd->fb_ion_handle) {
2377 rc = mdss_fb_fbmem_ion_mmap(info, vma);
2378 mfd->fb_mmap_type = MDP_FB_MMAP_ION_ALLOC;
2379 } else {
2380 rc = mdss_fb_physical_mmap(info, vma);
2381 mfd->fb_mmap_type = MDP_FB_MMAP_PHYSICAL_ALLOC;
2382 }
2383 }
2384 if (rc < 0)
2385 pr_err("fb mmap failed with rc = %d\n", rc);
2386
2387 return rc;
2388}
2389
2390static struct fb_ops mdss_fb_ops = {
2391 .owner = THIS_MODULE,
2392 .fb_open = mdss_fb_open,
2393 .fb_release = mdss_fb_release,
2394 .fb_check_var = mdss_fb_check_var, /* vinfo check */
2395 .fb_set_par = mdss_fb_set_par, /* set the video mode */
2396 .fb_blank = mdss_fb_blank, /* blank display */
2397 .fb_pan_display = mdss_fb_pan_display, /* pan display */
2398 .fb_ioctl_v2 = mdss_fb_ioctl, /* perform fb specific ioctl */
2399#ifdef CONFIG_COMPAT
2400 .fb_compat_ioctl_v2 = mdss_fb_compat_ioctl,
2401#endif
2402 .fb_mmap = mdss_fb_mmap,
2403};
2404
2405static int mdss_fb_alloc_fbmem_iommu(struct msm_fb_data_type *mfd, int dom)
2406{
2407 void *virt = NULL;
2408 phys_addr_t phys = 0;
2409 size_t size = 0;
2410 struct platform_device *pdev = mfd->pdev;
2411 int rc = 0;
2412 struct device_node *fbmem_pnode = NULL;
2413
2414 if (!pdev || !pdev->dev.of_node) {
2415 pr_err("Invalid device node\n");
2416 return -ENODEV;
2417 }
2418
2419 fbmem_pnode = of_parse_phandle(pdev->dev.of_node,
2420 "linux,contiguous-region", 0);
2421 if (!fbmem_pnode) {
2422 pr_debug("fbmem is not reserved for %s\n", pdev->name);
2423 mfd->fbi->screen_base = NULL;
2424 mfd->fbi->fix.smem_start = 0;
2425 return 0;
2426 }
2427 {
2428 const u32 *addr;
2429 u64 len;
2430
2431 addr = of_get_address(fbmem_pnode, 0, &len, NULL);
2432 if (!addr) {
2433 pr_err("fbmem size is not specified\n");
2434 of_node_put(fbmem_pnode);
2435 return -EINVAL;
2436 }
2437 size = (size_t)len;
2438 of_node_put(fbmem_pnode);
2439 }
2440
2441 pr_debug("%s frame buffer reserve_size=0x%zx\n", __func__, size);
2442
2443 if (size < PAGE_ALIGN(mfd->fbi->fix.line_length *
2444 mfd->fbi->var.yres_virtual))
2445 pr_warn("reserve size is smaller than framebuffer size\n");
2446
2447 rc = mdss_smmu_dma_alloc_coherent(&pdev->dev, size, &phys, &mfd->iova,
2448 &virt, GFP_KERNEL, dom);
2449 if (rc) {
2450 pr_err("unable to alloc fbmem size=%zx\n", size);
2451 return -ENOMEM;
2452 }
2453
2454 if (MDSS_LPAE_CHECK(phys)) {
2455 pr_warn("fb mem phys %pa > 4GB is not supported.\n", &phys);
2456 mdss_smmu_dma_free_coherent(&pdev->dev, size, &virt,
2457 phys, mfd->iova, dom);
2458 return -ERANGE;
2459 }
2460
2461 pr_debug("alloc 0x%zxB @ (%pa phys) (0x%pK virt) (%pa iova) for fb%d\n",
2462 size, &phys, virt, &mfd->iova, mfd->index);
2463
2464 mfd->fbi->screen_base = virt;
2465 mfd->fbi->fix.smem_start = phys;
2466 mfd->fbi->fix.smem_len = size;
2467
2468 return 0;
2469}
2470
2471static int mdss_fb_alloc_fbmem(struct msm_fb_data_type *mfd)
2472{
2473
2474 if (mfd->mdp.fb_mem_alloc_fnc) {
2475 return mfd->mdp.fb_mem_alloc_fnc(mfd);
2476 } else if (mfd->mdp.fb_mem_get_iommu_domain) {
2477 int dom = mfd->mdp.fb_mem_get_iommu_domain();
2478
2479 if (dom >= 0)
2480 return mdss_fb_alloc_fbmem_iommu(mfd, dom);
2481 else
2482 return -ENOMEM;
2483 } else {
2484 pr_err("no fb memory allocator function defined\n");
2485 return -ENOMEM;
2486 }
2487}
2488
2489static int mdss_fb_register(struct msm_fb_data_type *mfd)
2490{
2491 int ret = -ENODEV;
2492 int bpp;
2493 char panel_name[20];
2494 struct mdss_panel_info *panel_info = mfd->panel_info;
2495 struct fb_info *fbi = mfd->fbi;
2496 struct fb_fix_screeninfo *fix;
2497 struct fb_var_screeninfo *var;
2498 int *id;
2499
2500 /*
2501 * fb info initialization
2502 */
2503 fix = &fbi->fix;
2504 var = &fbi->var;
2505
2506 fix->type_aux = 0; /* if type == FB_TYPE_INTERLEAVED_PLANES */
2507 fix->visual = FB_VISUAL_TRUECOLOR; /* True Color */
2508 fix->ywrapstep = 0; /* No support */
2509 fix->mmio_start = 0; /* No MMIO Address */
2510 fix->mmio_len = 0; /* No MMIO Address */
2511 fix->accel = FB_ACCEL_NONE;/* FB_ACCEL_MSM needes to be added in fb.h */
2512
2513 var->xoffset = 0, /* Offset from virtual to visible */
2514 var->yoffset = 0, /* resolution */
2515 var->grayscale = 0, /* No graylevels */
2516 var->nonstd = 0, /* standard pixel format */
2517 var->activate = FB_ACTIVATE_VBL, /* activate it at vsync */
2518 var->height = -1, /* height of picture in mm */
2519 var->width = -1, /* width of picture in mm */
2520 var->accel_flags = 0, /* acceleration flags */
2521 var->sync = 0, /* see FB_SYNC_* */
2522 var->rotate = 0, /* angle we rotate counter clockwise */
2523 mfd->op_enable = false;
2524
2525 switch (mfd->fb_imgType) {
2526 case MDP_RGB_565:
2527 fix->type = FB_TYPE_PACKED_PIXELS;
2528 fix->xpanstep = 1;
2529 fix->ypanstep = 1;
2530 var->vmode = FB_VMODE_NONINTERLACED;
2531 var->blue.offset = 0;
2532 var->green.offset = 5;
2533 var->red.offset = 11;
2534 var->blue.length = 5;
2535 var->green.length = 6;
2536 var->red.length = 5;
2537 var->blue.msb_right = 0;
2538 var->green.msb_right = 0;
2539 var->red.msb_right = 0;
2540 var->transp.offset = 0;
2541 var->transp.length = 0;
2542 bpp = 2;
2543 break;
2544
2545 case MDP_RGB_888:
2546 fix->type = FB_TYPE_PACKED_PIXELS;
2547 fix->xpanstep = 1;
2548 fix->ypanstep = 1;
2549 var->vmode = FB_VMODE_NONINTERLACED;
2550 var->blue.offset = 0;
2551 var->green.offset = 8;
2552 var->red.offset = 16;
2553 var->blue.length = 8;
2554 var->green.length = 8;
2555 var->red.length = 8;
2556 var->blue.msb_right = 0;
2557 var->green.msb_right = 0;
2558 var->red.msb_right = 0;
2559 var->transp.offset = 0;
2560 var->transp.length = 0;
2561 bpp = 3;
2562 break;
2563
2564 case MDP_ARGB_8888:
2565 fix->type = FB_TYPE_PACKED_PIXELS;
2566 fix->xpanstep = 1;
2567 fix->ypanstep = 1;
2568 var->vmode = FB_VMODE_NONINTERLACED;
2569 var->blue.offset = 24;
2570 var->green.offset = 16;
2571 var->red.offset = 8;
2572 var->blue.length = 8;
2573 var->green.length = 8;
2574 var->red.length = 8;
2575 var->blue.msb_right = 0;
2576 var->green.msb_right = 0;
2577 var->red.msb_right = 0;
2578 var->transp.offset = 0;
2579 var->transp.length = 8;
2580 bpp = 4;
2581 break;
2582
2583 case MDP_RGBA_8888:
2584 fix->type = FB_TYPE_PACKED_PIXELS;
2585 fix->xpanstep = 1;
2586 fix->ypanstep = 1;
2587 var->vmode = FB_VMODE_NONINTERLACED;
2588 var->blue.offset = 16;
2589 var->green.offset = 8;
2590 var->red.offset = 0;
2591 var->blue.length = 8;
2592 var->green.length = 8;
2593 var->red.length = 8;
2594 var->blue.msb_right = 0;
2595 var->green.msb_right = 0;
2596 var->red.msb_right = 0;
2597 var->transp.offset = 24;
2598 var->transp.length = 8;
2599 bpp = 4;
2600 break;
2601
2602 case MDP_YCRYCB_H2V1:
2603 fix->type = FB_TYPE_INTERLEAVED_PLANES;
2604 fix->xpanstep = 2;
2605 fix->ypanstep = 1;
2606 var->vmode = FB_VMODE_NONINTERLACED;
2607
2608 /* how about R/G/B offset? */
2609 var->blue.offset = 0;
2610 var->green.offset = 5;
2611 var->red.offset = 11;
2612 var->blue.length = 5;
2613 var->green.length = 6;
2614 var->red.length = 5;
2615 var->blue.msb_right = 0;
2616 var->green.msb_right = 0;
2617 var->red.msb_right = 0;
2618 var->transp.offset = 0;
2619 var->transp.length = 0;
2620 bpp = 2;
2621 break;
2622
2623 default:
2624 pr_err("msm_fb_init: fb %d unknown image type!\n",
2625 mfd->index);
2626 return ret;
2627 }
2628
2629 mdss_panelinfo_to_fb_var(panel_info, var);
2630
2631 fix->type = panel_info->is_3d_panel;
2632 if (mfd->mdp.fb_stride)
2633 fix->line_length = mfd->mdp.fb_stride(mfd->index, var->xres,
2634 bpp);
2635 else
2636 fix->line_length = var->xres * bpp;
2637
2638 var->xres_virtual = var->xres;
2639 var->yres_virtual = panel_info->yres * mfd->fb_page;
2640 var->bits_per_pixel = bpp * 8; /* FrameBuffer color depth */
2641
2642 /*
2643 * Populate smem length here for uspace to get the
2644 * Framebuffer size when FBIO_FSCREENINFO ioctl is called.
2645 */
2646 fix->smem_len = PAGE_ALIGN(fix->line_length * var->yres) * mfd->fb_page;
2647
2648 /* id field for fb app */
2649 id = (int *)&mfd->panel;
2650
2651 snprintf(fix->id, sizeof(fix->id), "mdssfb_%x", (u32) *id);
2652
2653 fbi->fbops = &mdss_fb_ops;
2654 fbi->flags = FBINFO_FLAG_DEFAULT;
2655 fbi->pseudo_palette = mdss_fb_pseudo_palette;
2656
2657 mfd->ref_cnt = 0;
2658 mfd->panel_power_state = MDSS_PANEL_POWER_OFF;
2659 mfd->dcm_state = DCM_UNINIT;
2660
2661 if (mdss_fb_alloc_fbmem(mfd))
2662 pr_warn("unable to allocate fb memory in fb register\n");
2663
2664 mfd->op_enable = true;
2665
2666 mutex_init(&mfd->update.lock);
2667 mutex_init(&mfd->no_update.lock);
2668 mutex_init(&mfd->mdp_sync_pt_data.sync_mutex);
2669 atomic_set(&mfd->mdp_sync_pt_data.commit_cnt, 0);
2670 atomic_set(&mfd->commits_pending, 0);
2671 atomic_set(&mfd->ioctl_ref_cnt, 0);
2672 atomic_set(&mfd->kickoff_pending, 0);
2673
2674 init_timer(&mfd->no_update.timer);
2675 mfd->no_update.timer.function = mdss_fb_no_update_notify_timer_cb;
2676 mfd->no_update.timer.data = (unsigned long)mfd;
2677 mfd->update.ref_count = 0;
2678 mfd->no_update.ref_count = 0;
2679 mfd->update.init_done = false;
2680 init_completion(&mfd->update.comp);
2681 init_completion(&mfd->no_update.comp);
2682 init_completion(&mfd->power_off_comp);
2683 init_completion(&mfd->power_set_comp);
2684 init_waitqueue_head(&mfd->commit_wait_q);
2685 init_waitqueue_head(&mfd->idle_wait_q);
2686 init_waitqueue_head(&mfd->ioctl_q);
2687 init_waitqueue_head(&mfd->kickoff_wait_q);
2688
2689 ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
2690 if (ret)
2691 pr_err("fb_alloc_cmap() failed!\n");
2692
2693 if (register_framebuffer(fbi) < 0) {
2694 fb_dealloc_cmap(&fbi->cmap);
2695
2696 mfd->op_enable = false;
2697 return -EPERM;
2698 }
2699
2700 snprintf(panel_name, ARRAY_SIZE(panel_name), "mdss_panel_fb%d",
2701 mfd->index);
2702 mdss_panel_debugfs_init(panel_info, panel_name);
2703 pr_info("FrameBuffer[%d] %dx%d registered successfully!\n", mfd->index,
2704 fbi->var.xres, fbi->var.yres);
2705
2706 return 0;
2707}
2708
2709static int mdss_fb_open(struct fb_info *info, int user)
2710{
2711 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2712 struct mdss_fb_file_info *file_info = NULL;
2713 int result;
2714 struct task_struct *task = current->group_leader;
2715
2716 if (mfd->shutdown_pending) {
2717 pr_err_once("Shutdown pending. Aborting operation. Request from pid:%d name=%s\n",
2718 current->tgid, task->comm);
2719 sysfs_notify(&mfd->fbi->dev->kobj, NULL, "show_blank_event");
2720 return -ESHUTDOWN;
2721 }
2722
2723 file_info = kmalloc(sizeof(*file_info), GFP_KERNEL);
2724 if (!file_info)
2725 return -ENOMEM;
2726
2727 file_info->file = info->file;
2728 list_add(&file_info->list, &mfd->file_list);
2729
2730 result = pm_runtime_get_sync(info->dev);
2731
2732 if (result < 0) {
2733 pr_err("pm_runtime: fail to wake up\n");
2734 goto pm_error;
2735 }
2736
2737 if (!mfd->ref_cnt) {
2738 result = mdss_fb_blank_sub(FB_BLANK_UNBLANK, info,
2739 mfd->op_enable);
2740 if (result) {
2741 pr_err("can't turn on fb%d! rc=%d\n", mfd->index,
2742 result);
2743 goto blank_error;
2744 }
2745 }
2746
2747 mfd->ref_cnt++;
2748 pr_debug("mfd refcount:%d file:%pK\n", mfd->ref_cnt, info->file);
2749
2750 return 0;
2751
2752blank_error:
2753 pm_runtime_put(info->dev);
2754pm_error:
2755 list_del(&file_info->list);
2756 kfree(file_info);
2757 return result;
2758}
2759
2760static int mdss_fb_release_all(struct fb_info *info, bool release_all)
2761{
2762 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2763 struct mdss_fb_file_info *file_info = NULL, *temp_file_info = NULL;
2764 struct file *file = info->file;
2765 int ret = 0;
2766 bool node_found = false;
2767 struct task_struct *task = current->group_leader;
2768
2769 if (!mfd->ref_cnt) {
2770 pr_info("try to close unopened fb %d! from pid:%d name:%s\n",
2771 mfd->index, current->tgid, task->comm);
2772 return -EINVAL;
2773 }
2774
2775 if (!wait_event_timeout(mfd->ioctl_q,
2776 !atomic_read(&mfd->ioctl_ref_cnt) || !release_all,
2777 msecs_to_jiffies(1000)))
2778 pr_warn("fb%d ioctl could not finish. waited 1 sec.\n",
2779 mfd->index);
2780
2781 /* wait only for the last release */
2782 if (release_all || (mfd->ref_cnt == 1)) {
2783 ret = mdss_fb_pan_idle(mfd);
2784 if (ret && (ret != -ESHUTDOWN))
2785 pr_warn("mdss_fb_pan_idle for fb%d failed. ret=%d ignoring.\n",
2786 mfd->index, ret);
2787 }
2788
2789 pr_debug("release_all = %s\n", release_all ? "true" : "false");
2790
2791 list_for_each_entry_safe(file_info, temp_file_info, &mfd->file_list,
2792 list) {
2793 if (!release_all && file_info->file != file)
2794 continue;
2795
2796 pr_debug("found file node mfd->ref=%d\n", mfd->ref_cnt);
2797 list_del(&file_info->list);
2798 kfree(file_info);
2799
2800 mfd->ref_cnt--;
2801 pm_runtime_put(info->dev);
2802
2803 node_found = true;
2804
2805 if (!release_all)
2806 break;
2807 }
2808
2809 if (!node_found || (release_all && mfd->ref_cnt))
2810 pr_warn("file node not found or wrong ref cnt: release all:%d refcnt:%d\n",
2811 release_all, mfd->ref_cnt);
2812
2813 pr_debug("current process=%s pid=%d mfd->ref=%d file:%pK\n",
2814 task->comm, current->tgid, mfd->ref_cnt, info->file);
2815
2816 if (!mfd->ref_cnt || release_all) {
2817 /* resources (if any) will be released during blank */
2818 if (mfd->mdp.release_fnc)
2819 mfd->mdp.release_fnc(mfd, NULL);
2820
2821 if (mfd->mdp.pp_release_fnc) {
2822 ret = (*mfd->mdp.pp_release_fnc)(mfd);
2823 if (ret)
2824 pr_err("PP release failed ret %d\n", ret);
2825 }
2826
2827 /* reset backlight before blank to prevent backlight from
2828 * enabling ahead of unblank. for some special cases like
2829 * adb shell stop/start.
2830 */
2831 mdss_fb_set_backlight(mfd, 0);
2832
2833 ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info,
2834 mfd->op_enable);
2835 if (ret) {
2836 pr_err("can't turn off fb%d! rc=%d current process=%s pid=%d\n",
2837 mfd->index, ret, task->comm, current->tgid);
2838 return ret;
2839 }
2840 if (mfd->fb_ion_handle)
2841 mdss_fb_free_fb_ion_memory(mfd);
2842
2843 atomic_set(&mfd->ioctl_ref_cnt, 0);
2844 } else {
2845 if (mfd->mdp.release_fnc)
2846 ret = mfd->mdp.release_fnc(mfd, file);
2847
2848 /* display commit is needed to release resources */
2849 if (ret)
2850 mdss_fb_pan_display(&mfd->fbi->var, mfd->fbi);
2851 }
2852
2853 return ret;
2854}
2855
2856static int mdss_fb_release(struct fb_info *info, int user)
2857{
2858 return mdss_fb_release_all(info, false);
2859}
2860
2861static void mdss_fb_power_setting_idle(struct msm_fb_data_type *mfd)
2862{
2863 int ret;
2864
2865 if (mfd->is_power_setting) {
2866 ret = wait_for_completion_timeout(
2867 &mfd->power_set_comp,
2868 msecs_to_jiffies(WAIT_DISP_OP_TIMEOUT));
2869 if (ret < 0)
2870 ret = -ERESTARTSYS;
2871 else if (!ret)
2872 pr_err("%s wait for power_set_comp timeout %d %d",
2873 __func__, ret, mfd->is_power_setting);
2874 if (ret <= 0) {
2875 mfd->is_power_setting = false;
2876 complete_all(&mfd->power_set_comp);
2877 }
2878 }
2879}
2880
2881static void __mdss_fb_copy_fence(struct msm_sync_pt_data *sync_pt_data,
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05302882 struct mdss_fence **fences, u32 *fence_cnt)
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302883{
2884 pr_debug("%s: wait for fences\n", sync_pt_data->fence_name);
2885
2886 mutex_lock(&sync_pt_data->sync_mutex);
2887 /*
2888 * Assuming that acq_fen_cnt is sanitized in bufsync ioctl
2889 * to check for sync_pt_data->acq_fen_cnt <= MDP_MAX_FENCE_FD
2890 */
2891 *fence_cnt = sync_pt_data->acq_fen_cnt;
2892 sync_pt_data->acq_fen_cnt = 0;
2893 if (*fence_cnt)
2894 memcpy(fences, sync_pt_data->acq_fen,
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05302895 *fence_cnt * sizeof(struct mdss_fence *));
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302896 mutex_unlock(&sync_pt_data->sync_mutex);
2897}
2898
2899static int __mdss_fb_wait_for_fence_sub(struct msm_sync_pt_data *sync_pt_data,
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05302900 struct mdss_fence **fences, int fence_cnt)
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302901{
2902 int i, ret = 0;
2903 unsigned long max_wait = msecs_to_jiffies(WAIT_MAX_FENCE_TIMEOUT);
2904 unsigned long timeout = jiffies + max_wait;
2905 long wait_ms, wait_jf;
2906
2907 /* buf sync */
2908 for (i = 0; i < fence_cnt && !ret; i++) {
2909 wait_jf = timeout - jiffies;
2910 wait_ms = jiffies_to_msecs(wait_jf);
2911
2912 /*
2913 * In this loop, if one of the previous fence took long
2914 * time, give a chance for the next fence to check if
2915 * fence is already signalled. If not signalled it breaks
2916 * in the final wait timeout.
2917 */
2918 if (wait_jf < 0)
2919 wait_ms = WAIT_MIN_FENCE_TIMEOUT;
2920 else
2921 wait_ms = min_t(long, WAIT_FENCE_FIRST_TIMEOUT,
2922 wait_ms);
2923
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05302924 ret = mdss_wait_sync_fence(fences[i], wait_ms);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302925
2926 if (ret == -ETIME) {
2927 wait_jf = timeout - jiffies;
2928 wait_ms = jiffies_to_msecs(wait_jf);
2929 if (wait_jf < 0)
2930 break;
2931
2932 wait_ms = min_t(long, WAIT_FENCE_FINAL_TIMEOUT,
2933 wait_ms);
2934
2935 pr_warn("%s: sync_fence_wait timed out! ",
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05302936 mdss_get_sync_fence_name(fences[i]));
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302937 pr_cont("Waiting %ld.%ld more seconds\n",
2938 (wait_ms/MSEC_PER_SEC), (wait_ms%MSEC_PER_SEC));
2939 MDSS_XLOG(sync_pt_data->timeline_value);
2940 MDSS_XLOG_TOUT_HANDLER("mdp");
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05302941 ret = mdss_wait_sync_fence(fences[i], wait_ms);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302942
2943 if (ret == -ETIME)
2944 break;
2945 }
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05302946 mdss_put_sync_fence(fences[i]);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302947 }
2948
2949 if (ret < 0) {
2950 pr_err("%s: sync_fence_wait failed! ret = %x\n",
2951 sync_pt_data->fence_name, ret);
2952 for (; i < fence_cnt; i++)
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05302953 mdss_put_sync_fence(fences[i]);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302954 }
2955 return ret;
2956}
2957
2958int mdss_fb_wait_for_fence(struct msm_sync_pt_data *sync_pt_data)
2959{
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05302960 struct mdss_fence *fences[MDP_MAX_FENCE_FD];
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302961 int fence_cnt = 0;
2962
2963 __mdss_fb_copy_fence(sync_pt_data, fences, &fence_cnt);
2964
2965 if (fence_cnt)
2966 __mdss_fb_wait_for_fence_sub(sync_pt_data,
2967 fences, fence_cnt);
2968
2969 return fence_cnt;
2970}
2971
2972/**
2973 * mdss_fb_signal_timeline() - signal a single release fence
2974 * @sync_pt_data: Sync point data structure for the timeline which
2975 * should be signaled.
2976 *
2977 * This is called after a frame has been pushed to display. This signals the
2978 * timeline to release the fences associated with this frame.
2979 */
2980void mdss_fb_signal_timeline(struct msm_sync_pt_data *sync_pt_data)
2981{
2982 mutex_lock(&sync_pt_data->sync_mutex);
2983 if (atomic_add_unless(&sync_pt_data->commit_cnt, -1, 0) &&
2984 sync_pt_data->timeline) {
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05302985 mdss_inc_timeline(sync_pt_data->timeline, 1);
2986 mdss_inc_timeline(sync_pt_data->timeline_retire, 1);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05302987 MDSS_XLOG(sync_pt_data->timeline_value);
2988 sync_pt_data->timeline_value++;
2989
2990 pr_debug("%s: buffer signaled! timeline val=%d remaining=%d\n",
2991 sync_pt_data->fence_name, sync_pt_data->timeline_value,
2992 atomic_read(&sync_pt_data->commit_cnt));
2993 } else {
2994 pr_debug("%s timeline signaled without commits val=%d\n",
2995 sync_pt_data->fence_name, sync_pt_data->timeline_value);
2996 }
2997 mutex_unlock(&sync_pt_data->sync_mutex);
2998}
2999
3000/**
3001 * mdss_fb_release_fences() - signal all pending release fences
3002 * @mfd: Framebuffer data structure for display
3003 *
3004 * Release all currently pending release fences, including those that are in
3005 * the process to be commtted.
3006 *
3007 * Note: this should only be called during close or suspend sequence.
3008 */
3009static void mdss_fb_release_fences(struct msm_fb_data_type *mfd)
3010{
3011 struct msm_sync_pt_data *sync_pt_data = &mfd->mdp_sync_pt_data;
3012 int val;
3013
3014 mutex_lock(&sync_pt_data->sync_mutex);
3015 if (sync_pt_data->timeline) {
3016 val = sync_pt_data->threshold +
3017 atomic_read(&sync_pt_data->commit_cnt);
Sachin Bhayare9b5caf22018-02-20 22:05:47 +05303018 mdss_resync_timeline(sync_pt_data->timeline);
3019 mdss_resync_timeline(sync_pt_data->timeline_retire);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303020 sync_pt_data->timeline_value += val;
3021 atomic_set(&sync_pt_data->commit_cnt, 0);
3022 }
3023 mutex_unlock(&sync_pt_data->sync_mutex);
3024}
3025
3026static void mdss_fb_release_kickoff(struct msm_fb_data_type *mfd)
3027{
3028 if (mfd->wait_for_kickoff) {
3029 atomic_set(&mfd->kickoff_pending, 0);
3030 wake_up_all(&mfd->kickoff_wait_q);
3031 }
3032}
3033
3034/**
3035 * __mdss_fb_sync_buf_done_callback() - process async display events
3036 * @p: Notifier block registered for async events.
3037 * @event: Event enum to identify the event.
3038 * @data: Optional argument provided with the event.
3039 *
3040 * See enum mdp_notify_event for events handled.
3041 */
3042static int __mdss_fb_sync_buf_done_callback(struct notifier_block *p,
3043 unsigned long event, void *data)
3044{
3045 struct msm_sync_pt_data *sync_pt_data;
3046 struct msm_fb_data_type *mfd;
3047 int fence_cnt;
3048 int ret = NOTIFY_OK;
3049
3050 sync_pt_data = container_of(p, struct msm_sync_pt_data, notifier);
3051 mfd = container_of(sync_pt_data, struct msm_fb_data_type,
3052 mdp_sync_pt_data);
3053
3054 switch (event) {
3055 case MDP_NOTIFY_FRAME_BEGIN:
3056 if (mfd->idle_time && !mod_delayed_work(system_wq,
3057 &mfd->idle_notify_work,
3058 msecs_to_jiffies(WAIT_DISP_OP_TIMEOUT)))
3059 pr_debug("fb%d: start idle delayed work\n",
3060 mfd->index);
3061
3062 mfd->idle_state = MDSS_FB_NOT_IDLE;
3063 break;
3064 case MDP_NOTIFY_FRAME_READY:
3065 if (sync_pt_data->async_wait_fences &&
3066 sync_pt_data->temp_fen_cnt) {
3067 fence_cnt = sync_pt_data->temp_fen_cnt;
3068 sync_pt_data->temp_fen_cnt = 0;
3069 ret = __mdss_fb_wait_for_fence_sub(sync_pt_data,
3070 sync_pt_data->temp_fen, fence_cnt);
3071 }
3072 if (mfd->idle_time && !mod_delayed_work(system_wq,
3073 &mfd->idle_notify_work,
3074 msecs_to_jiffies(mfd->idle_time)))
3075 pr_debug("fb%d: restarted idle work\n",
3076 mfd->index);
3077 if (ret == -ETIME)
3078 ret = NOTIFY_BAD;
3079 mfd->idle_state = MDSS_FB_IDLE_TIMER_RUNNING;
3080 break;
3081 case MDP_NOTIFY_FRAME_FLUSHED:
3082 pr_debug("%s: frame flushed\n", sync_pt_data->fence_name);
3083 sync_pt_data->flushed = true;
3084 break;
3085 case MDP_NOTIFY_FRAME_TIMEOUT:
3086 pr_err("%s: frame timeout\n", sync_pt_data->fence_name);
3087 mdss_fb_signal_timeline(sync_pt_data);
3088 break;
3089 case MDP_NOTIFY_FRAME_DONE:
3090 pr_debug("%s: frame done\n", sync_pt_data->fence_name);
3091 mdss_fb_signal_timeline(sync_pt_data);
3092 mdss_fb_calc_fps(mfd);
3093 break;
3094 case MDP_NOTIFY_FRAME_CFG_DONE:
3095 if (sync_pt_data->async_wait_fences)
3096 __mdss_fb_copy_fence(sync_pt_data,
3097 sync_pt_data->temp_fen,
3098 &sync_pt_data->temp_fen_cnt);
3099 break;
3100 case MDP_NOTIFY_FRAME_CTX_DONE:
3101 mdss_fb_release_kickoff(mfd);
3102 break;
3103 }
3104
3105 return ret;
3106}
3107
3108/**
3109 * mdss_fb_pan_idle() - wait for panel programming to be idle
3110 * @mfd: Framebuffer data structure for display
3111 *
3112 * Wait for any pending programming to be done if in the process of programming
3113 * hardware configuration. After this function returns it is safe to perform
3114 * software updates for next frame.
3115 */
3116static int mdss_fb_pan_idle(struct msm_fb_data_type *mfd)
3117{
3118 int ret = 0;
3119
3120 ret = wait_event_timeout(mfd->idle_wait_q,
3121 (!atomic_read(&mfd->commits_pending) ||
3122 mfd->shutdown_pending),
3123 msecs_to_jiffies(WAIT_DISP_OP_TIMEOUT));
3124 if (!ret) {
3125 pr_err("%pS: wait for idle timeout commits=%d\n",
3126 __builtin_return_address(0),
3127 atomic_read(&mfd->commits_pending));
3128 MDSS_XLOG_TOUT_HANDLER("mdp", "vbif", "vbif_nrt",
3129 "dbg_bus", "vbif_dbg_bus");
3130 ret = -ETIMEDOUT;
3131 } else if (mfd->shutdown_pending) {
3132 pr_debug("Shutdown signalled\n");
3133 ret = -ESHUTDOWN;
3134 } else {
3135 ret = 0;
3136 }
3137
3138 return ret;
3139}
3140
3141static int mdss_fb_wait_for_kickoff(struct msm_fb_data_type *mfd)
3142{
3143 int ret = 0;
3144
3145 if (!mfd->wait_for_kickoff)
3146 return mdss_fb_pan_idle(mfd);
3147
3148 ret = wait_event_timeout(mfd->kickoff_wait_q,
3149 (!atomic_read(&mfd->kickoff_pending) ||
3150 mfd->shutdown_pending),
3151 msecs_to_jiffies(WAIT_DISP_OP_TIMEOUT));
3152 if (!ret) {
3153 pr_err("%pS: wait for kickoff timeout koff=%d commits=%d\n",
3154 __builtin_return_address(0),
3155 atomic_read(&mfd->kickoff_pending),
3156 atomic_read(&mfd->commits_pending));
3157 MDSS_XLOG_TOUT_HANDLER("mdp", "vbif", "vbif_nrt",
3158 "dbg_bus", "vbif_dbg_bus");
3159 ret = -ETIMEDOUT;
3160 } else if (mfd->shutdown_pending) {
3161 pr_debug("Shutdown signalled\n");
3162 ret = -ESHUTDOWN;
3163 } else {
3164 ret = 0;
3165 }
3166
3167 return ret;
3168}
3169
3170static int mdss_fb_pan_display_ex(struct fb_info *info,
3171 struct mdp_display_commit *disp_commit)
3172{
3173 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
3174 struct fb_var_screeninfo *var = &disp_commit->var;
3175 u32 wait_for_finish = disp_commit->wait_for_finish;
3176 int ret = 0;
3177
3178 if (!mfd || (!mfd->op_enable))
3179 return -EPERM;
3180
3181 if ((mdss_fb_is_power_off(mfd)) &&
3182 !((mfd->dcm_state == DCM_ENTER) &&
3183 (mfd->panel.type == MIPI_CMD_PANEL)))
3184 return -EPERM;
3185
3186 if (var->xoffset > (info->var.xres_virtual - info->var.xres))
3187 return -EINVAL;
3188
3189 if (var->yoffset > (info->var.yres_virtual - info->var.yres))
3190 return -EINVAL;
3191
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05303192 ret = mdss_fb_wait_for_kickoff(mfd);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303193 if (ret) {
3194 pr_err("wait_for_kick failed. rc=%d\n", ret);
3195 return ret;
3196 }
3197
3198 if (mfd->mdp.pre_commit_fnc) {
3199 ret = mfd->mdp.pre_commit_fnc(mfd);
3200 if (ret) {
3201 pr_err("fb%d: pre commit failed %d\n",
3202 mfd->index, ret);
3203 return ret;
3204 }
3205 }
3206
3207 mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex);
3208 if (info->fix.xpanstep)
3209 info->var.xoffset =
3210 (var->xoffset / info->fix.xpanstep) * info->fix.xpanstep;
3211
3212 if (info->fix.ypanstep)
3213 info->var.yoffset =
3214 (var->yoffset / info->fix.ypanstep) * info->fix.ypanstep;
3215
3216 mfd->msm_fb_backup.info = *info;
3217 mfd->msm_fb_backup.disp_commit = *disp_commit;
3218
3219 atomic_inc(&mfd->mdp_sync_pt_data.commit_cnt);
3220 atomic_inc(&mfd->commits_pending);
3221 atomic_inc(&mfd->kickoff_pending);
3222 wake_up_all(&mfd->commit_wait_q);
3223 mutex_unlock(&mfd->mdp_sync_pt_data.sync_mutex);
3224 if (wait_for_finish) {
3225 ret = mdss_fb_pan_idle(mfd);
3226 if (ret)
3227 pr_err("mdss_fb_pan_idle failed. rc=%d\n", ret);
3228 }
3229 return ret;
3230}
3231
3232u32 mdss_fb_get_mode_switch(struct msm_fb_data_type *mfd)
3233{
3234 /* If there is no attached mfd then there is no pending mode switch */
3235 if (!mfd)
3236 return 0;
3237
3238 if (mfd->pending_switch)
3239 return mfd->switch_new_mode;
3240
3241 return 0;
3242}
3243
3244/*
3245 * __ioctl_transition_dyn_mode_state() - State machine for mode switch
3246 * @mfd: Framebuffer data structure for display
3247 * @cmd: ioctl that was called
3248 * @validate: used with atomic commit when doing validate layers
3249 *
3250 * This function assists with dynamic mode switch of DSI panel. States
3251 * are used to make sure that panel mode switch occurs on next
3252 * prepare/sync/commit (for legacy) and validate/pre_commit (for
3253 * atomic commit) pairing. This state machine insure that calculation
3254 * and return values (such as buffer release fences) are based on the
3255 * panel mode being switching into.
3256 */
3257static int __ioctl_transition_dyn_mode_state(struct msm_fb_data_type *mfd,
3258 unsigned int cmd, bool validate, bool null_commit)
3259{
3260 if (mfd->switch_state == MDSS_MDP_NO_UPDATE_REQUESTED)
3261 return 0;
3262
3263 mutex_lock(&mfd->switch_lock);
3264 switch (cmd) {
3265 case MSMFB_ATOMIC_COMMIT:
3266 if ((mfd->switch_state == MDSS_MDP_WAIT_FOR_VALIDATE)
3267 && validate) {
3268 if (mfd->switch_new_mode != SWITCH_RESOLUTION)
3269 mfd->pending_switch = true;
3270 mfd->switch_state = MDSS_MDP_WAIT_FOR_COMMIT;
3271 } else if (mfd->switch_state == MDSS_MDP_WAIT_FOR_COMMIT) {
3272 if (mfd->switch_new_mode != SWITCH_RESOLUTION)
3273 mdss_fb_set_mdp_sync_pt_threshold(mfd,
3274 mfd->switch_new_mode);
3275 mfd->switch_state = MDSS_MDP_WAIT_FOR_KICKOFF;
3276 } else if ((mfd->switch_state == MDSS_MDP_WAIT_FOR_VALIDATE)
3277 && null_commit) {
3278 mfd->switch_state = MDSS_MDP_WAIT_FOR_KICKOFF;
3279 }
3280 break;
3281 }
3282 mutex_unlock(&mfd->switch_lock);
3283 return 0;
3284}
3285
3286static inline bool mdss_fb_is_wb_config_same(struct msm_fb_data_type *mfd,
3287 struct mdp_output_layer *output_layer)
3288{
3289 struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
3290 struct msm_mdp_interface *mdp5_interface = &mfd->mdp;
3291
3292 if (!mdp5_data->wfd
3293 || (mdp5_interface->is_config_same
3294 && !mdp5_interface->is_config_same(mfd, output_layer)))
3295 return false;
3296 return true;
3297}
3298
3299/* update pinfo and var for WB on config change */
3300static void mdss_fb_update_resolution(struct msm_fb_data_type *mfd,
3301 u32 xres, u32 yres, u32 format)
3302{
3303 struct mdss_panel_info *pinfo = mfd->panel_info;
3304 struct fb_var_screeninfo *var = &mfd->fbi->var;
3305 struct fb_fix_screeninfo *fix = &mfd->fbi->fix;
3306 struct mdss_mdp_format_params *fmt = NULL;
3307
3308 pinfo->xres = xres;
3309 pinfo->yres = yres;
3310 mfd->fb_imgType = format;
3311 if (mfd->mdp.get_format_params) {
3312 fmt = mfd->mdp.get_format_params(format);
3313 if (fmt) {
3314 pinfo->bpp = fmt->bpp;
3315 var->bits_per_pixel = fmt->bpp * 8;
3316 }
3317 if (mfd->mdp.fb_stride)
3318 fix->line_length = mfd->mdp.fb_stride(mfd->index,
3319 var->xres,
3320 var->bits_per_pixel / 8);
3321 else
3322 fix->line_length = var->xres * var->bits_per_pixel / 8;
3323
3324 }
3325 var->xres_virtual = var->xres;
3326 var->yres_virtual = pinfo->yres * mfd->fb_page;
3327 mdss_panelinfo_to_fb_var(pinfo, var);
3328}
3329
3330int mdss_fb_atomic_commit(struct fb_info *info,
3331 struct mdp_layer_commit *commit, struct file *file)
3332{
3333 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
3334 struct mdp_layer_commit_v1 *commit_v1;
3335 struct mdp_output_layer *output_layer;
3336 struct mdss_panel_info *pinfo;
3337 bool wait_for_finish, wb_change = false;
3338 int ret = -EPERM;
3339 u32 old_xres, old_yres, old_format;
3340
3341 if (!mfd || (!mfd->op_enable)) {
3342 pr_err("mfd is NULL or operation not permitted\n");
3343 return -EPERM;
3344 }
3345
3346 if ((mdss_fb_is_power_off(mfd)) &&
3347 !((mfd->dcm_state == DCM_ENTER) &&
3348 (mfd->panel.type == MIPI_CMD_PANEL))) {
3349 pr_err("commit is not supported when interface is in off state\n");
3350 goto end;
3351 }
3352 pinfo = mfd->panel_info;
3353
3354 /* only supports version 1.0 */
3355 if (commit->version != MDP_COMMIT_VERSION_1_0) {
3356 pr_err("commit version is not supported\n");
3357 goto end;
3358 }
3359
3360 if (!mfd->mdp.pre_commit || !mfd->mdp.atomic_validate) {
3361 pr_err("commit callback is not registered\n");
3362 goto end;
3363 }
3364
3365 commit_v1 = &commit->commit_v1;
3366 if (commit_v1->flags & MDP_VALIDATE_LAYER) {
3367 ret = mdss_fb_wait_for_kickoff(mfd);
3368 if (ret) {
3369 pr_err("wait for kickoff failed\n");
3370 } else {
3371 __ioctl_transition_dyn_mode_state(mfd,
3372 MSMFB_ATOMIC_COMMIT, true, false);
3373 if (mfd->panel.type == WRITEBACK_PANEL) {
3374 output_layer = commit_v1->output_layer;
3375 if (!output_layer) {
3376 pr_err("Output layer is null\n");
3377 goto end;
3378 }
3379 wb_change = !mdss_fb_is_wb_config_same(mfd,
3380 commit_v1->output_layer);
3381 if (wb_change) {
3382 old_xres = pinfo->xres;
3383 old_yres = pinfo->yres;
3384 old_format = mfd->fb_imgType;
3385 mdss_fb_update_resolution(mfd,
3386 output_layer->buffer.width,
3387 output_layer->buffer.height,
3388 output_layer->buffer.format);
3389 }
3390 }
3391 ret = mfd->mdp.atomic_validate(mfd, file, commit_v1);
3392 if (!ret)
3393 mfd->atomic_commit_pending = true;
3394 }
3395 goto end;
3396 } else {
3397 ret = mdss_fb_pan_idle(mfd);
3398 if (ret) {
3399 pr_err("pan display idle call failed\n");
3400 goto end;
3401 }
3402 __ioctl_transition_dyn_mode_state(mfd,
3403 MSMFB_ATOMIC_COMMIT, false,
3404 (commit_v1->input_layer_cnt ? 0 : 1));
3405
3406 ret = mfd->mdp.pre_commit(mfd, file, commit_v1);
3407 if (ret) {
3408 pr_err("atomic pre commit failed\n");
3409 goto end;
3410 }
3411 }
3412
3413 wait_for_finish = commit_v1->flags & MDP_COMMIT_WAIT_FOR_FINISH;
3414 mfd->msm_fb_backup.atomic_commit = true;
3415 mfd->msm_fb_backup.disp_commit.l_roi = commit_v1->left_roi;
3416 mfd->msm_fb_backup.disp_commit.r_roi = commit_v1->right_roi;
3417
3418 mutex_lock(&mfd->mdp_sync_pt_data.sync_mutex);
3419 atomic_inc(&mfd->mdp_sync_pt_data.commit_cnt);
3420 atomic_inc(&mfd->commits_pending);
3421 atomic_inc(&mfd->kickoff_pending);
3422 wake_up_all(&mfd->commit_wait_q);
3423 mutex_unlock(&mfd->mdp_sync_pt_data.sync_mutex);
3424
3425 if (wait_for_finish)
3426 ret = mdss_fb_pan_idle(mfd);
3427
3428end:
3429 if (ret && (mfd->panel.type == WRITEBACK_PANEL) && wb_change)
3430 mdss_fb_update_resolution(mfd, old_xres, old_yres, old_format);
3431 return ret;
3432}
3433
3434static int mdss_fb_pan_display(struct fb_var_screeninfo *var,
3435 struct fb_info *info)
3436{
3437 struct mdp_display_commit disp_commit;
3438 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
3439
3440 /*
3441 * during mode switch through mode sysfs node, it will trigger a
3442 * pan_display after switch. This assumes that fb has been adjusted,
3443 * however when using overlays we may not have the right size at this
3444 * point, so it needs to go through PREPARE first. Abort pan_display
3445 * operations until that happens
3446 */
3447 if (mfd->switch_state != MDSS_MDP_NO_UPDATE_REQUESTED) {
3448 pr_debug("fb%d: pan_display skipped during switch\n",
3449 mfd->index);
3450 return 0;
3451 }
3452
3453 memset(&disp_commit, 0, sizeof(disp_commit));
3454 disp_commit.wait_for_finish = true;
3455 memcpy(&disp_commit.var, var, sizeof(struct fb_var_screeninfo));
3456 return mdss_fb_pan_display_ex(info, &disp_commit);
3457}
3458
3459static int mdss_fb_pan_display_sub(struct fb_var_screeninfo *var,
3460 struct fb_info *info)
3461{
3462 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
3463
3464 if (!mfd->op_enable)
3465 return -EPERM;
3466
3467 if ((mdss_fb_is_power_off(mfd)) &&
3468 !((mfd->dcm_state == DCM_ENTER) &&
3469 (mfd->panel.type == MIPI_CMD_PANEL)))
3470 return -EPERM;
3471
3472 if (var->xoffset > (info->var.xres_virtual - info->var.xres))
3473 return -EINVAL;
3474
3475 if (var->yoffset > (info->var.yres_virtual - info->var.yres))
3476 return -EINVAL;
3477
3478 if (info->fix.xpanstep)
3479 info->var.xoffset =
3480 (var->xoffset / info->fix.xpanstep) * info->fix.xpanstep;
3481
3482 if (info->fix.ypanstep)
3483 info->var.yoffset =
3484 (var->yoffset / info->fix.ypanstep) * info->fix.ypanstep;
3485
3486 if (mfd->mdp.dma_fnc)
3487 mfd->mdp.dma_fnc(mfd);
3488 else
3489 pr_warn("dma function not set for panel type=%d\n",
3490 mfd->panel.type);
3491
3492 return 0;
3493}
3494
3495static int mdss_grayscale_to_mdp_format(u32 grayscale)
3496{
3497 switch (grayscale) {
3498 case V4L2_PIX_FMT_RGB24:
3499 return MDP_RGB_888;
3500 case V4L2_PIX_FMT_NV12:
3501 return MDP_Y_CBCR_H2V2;
3502 default:
3503 return -EINVAL;
3504 }
3505}
3506
3507static void mdss_fb_var_to_panelinfo(struct fb_var_screeninfo *var,
3508 struct mdss_panel_info *pinfo)
3509{
3510 int format = -EINVAL;
3511
3512 pinfo->xres = var->xres;
3513 pinfo->yres = var->yres;
3514 pinfo->lcdc.v_front_porch = var->lower_margin;
3515 pinfo->lcdc.v_back_porch = var->upper_margin;
3516 pinfo->lcdc.v_pulse_width = var->vsync_len;
3517 pinfo->lcdc.h_front_porch = var->right_margin;
3518 pinfo->lcdc.h_back_porch = var->left_margin;
3519 pinfo->lcdc.h_pulse_width = var->hsync_len;
3520
3521 if (var->grayscale > 1) {
3522 format = mdss_grayscale_to_mdp_format(var->grayscale);
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05303523 if (!IS_ERR_VALUE((unsigned long)format))
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303524 pinfo->out_format = format;
3525 else
3526 pr_warn("Failed to map grayscale value (%d) to an MDP format\n",
3527 var->grayscale);
3528 }
3529
3530 /*
3531 * if greater than 1M, then rate would fall below 1mhz which is not
3532 * even supported. In this case it means clock rate is actually
3533 * passed directly in hz.
3534 */
3535 if (var->pixclock > SZ_1M)
3536 pinfo->clk_rate = var->pixclock;
3537 else
3538 pinfo->clk_rate = PICOS2KHZ(var->pixclock) * 1000;
3539
3540 /*
3541 * if it is a DBA panel i.e. HDMI TV connected through
3542 * DSI interface, then store the pixel clock value in
3543 * DSI specific variable.
3544 */
3545 if (pinfo->is_dba_panel)
3546 pinfo->mipi.dsi_pclk_rate = pinfo->clk_rate;
3547}
3548
3549void mdss_panelinfo_to_fb_var(struct mdss_panel_info *pinfo,
3550 struct fb_var_screeninfo *var)
3551{
3552 u32 frame_rate;
3553
3554 var->xres = mdss_fb_get_panel_xres(pinfo);
3555 var->yres = pinfo->yres;
3556 var->lower_margin = pinfo->lcdc.v_front_porch -
3557 pinfo->prg_fet;
3558 var->upper_margin = pinfo->lcdc.v_back_porch +
3559 pinfo->prg_fet;
3560 var->vsync_len = pinfo->lcdc.v_pulse_width;
3561 var->right_margin = pinfo->lcdc.h_front_porch;
3562 var->left_margin = pinfo->lcdc.h_back_porch;
3563 var->hsync_len = pinfo->lcdc.h_pulse_width;
3564
3565 frame_rate = mdss_panel_get_framerate(pinfo,
3566 FPS_RESOLUTION_HZ);
3567 if (frame_rate) {
3568 unsigned long clk_rate, h_total, v_total;
3569
3570 h_total = var->xres + var->left_margin
3571 + var->right_margin + var->hsync_len;
3572 v_total = var->yres + var->lower_margin
3573 + var->upper_margin + var->vsync_len;
3574 clk_rate = h_total * v_total * frame_rate;
3575 var->pixclock = KHZ2PICOS(clk_rate / 1000);
3576 } else if (pinfo->clk_rate) {
3577 var->pixclock = KHZ2PICOS(
3578 (unsigned long int) pinfo->clk_rate / 1000);
3579 }
3580
3581 if (pinfo->physical_width)
3582 var->width = pinfo->physical_width;
3583 if (pinfo->physical_height)
3584 var->height = pinfo->physical_height;
3585
3586 pr_debug("ScreenInfo: res=%dx%d [%d, %d] [%d, %d]\n",
3587 var->xres, var->yres, var->left_margin,
3588 var->right_margin, var->upper_margin,
3589 var->lower_margin);
3590}
3591
3592/**
3593 * __mdss_fb_perform_commit() - process a frame to display
3594 * @mfd: Framebuffer data structure for display
3595 *
3596 * Processes all layers and buffers programmed and ensures all pending release
3597 * fences are signaled once the buffer is transferred to display.
3598 */
3599static int __mdss_fb_perform_commit(struct msm_fb_data_type *mfd)
3600{
3601 struct msm_sync_pt_data *sync_pt_data = &mfd->mdp_sync_pt_data;
3602 struct msm_fb_backup_type *fb_backup = &mfd->msm_fb_backup;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05303603 int ret = -ENOTSUPP;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303604 u32 new_dsi_mode, dynamic_dsi_switch = 0;
3605
3606 if (!sync_pt_data->async_wait_fences)
3607 mdss_fb_wait_for_fence(sync_pt_data);
3608 sync_pt_data->flushed = false;
3609
3610 mutex_lock(&mfd->switch_lock);
3611 if (mfd->switch_state == MDSS_MDP_WAIT_FOR_KICKOFF) {
3612 dynamic_dsi_switch = 1;
3613 new_dsi_mode = mfd->switch_new_mode;
3614 } else if (mfd->switch_state != MDSS_MDP_NO_UPDATE_REQUESTED) {
3615 pr_err("invalid commit on fb%d with state = %d\n",
3616 mfd->index, mfd->switch_state);
3617 mutex_unlock(&mfd->switch_lock);
3618 goto skip_commit;
3619 }
3620 mutex_unlock(&mfd->switch_lock);
3621 if (dynamic_dsi_switch) {
3622 MDSS_XLOG(mfd->index, mfd->split_mode, new_dsi_mode,
3623 XLOG_FUNC_ENTRY);
3624 pr_debug("Triggering dyn mode switch to %d\n", new_dsi_mode);
3625 ret = mfd->mdp.mode_switch(mfd, new_dsi_mode);
3626 if (ret)
3627 pr_err("DSI mode switch has failed");
3628 else
3629 mfd->pending_switch = false;
3630 }
3631 if (fb_backup->disp_commit.flags & MDP_DISPLAY_COMMIT_OVERLAY) {
3632 if (mfd->mdp.kickoff_fnc)
3633 ret = mfd->mdp.kickoff_fnc(mfd,
3634 &fb_backup->disp_commit);
3635 else
3636 pr_warn("no kickoff function setup for fb%d\n",
3637 mfd->index);
3638 } else if (fb_backup->atomic_commit) {
3639 if (mfd->mdp.kickoff_fnc)
3640 ret = mfd->mdp.kickoff_fnc(mfd,
3641 &fb_backup->disp_commit);
3642 else
3643 pr_warn("no kickoff function setup for fb%d\n",
3644 mfd->index);
3645 fb_backup->atomic_commit = false;
3646 } else {
3647 ret = mdss_fb_pan_display_sub(&fb_backup->disp_commit.var,
3648 &fb_backup->info);
3649 if (ret)
3650 pr_err("pan display failed %x on fb%d\n", ret,
3651 mfd->index);
3652 }
3653
3654skip_commit:
3655 if (!ret)
3656 mdss_fb_update_backlight(mfd);
3657
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05303658 if (IS_ERR_VALUE((unsigned long)ret) || !sync_pt_data->flushed) {
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303659 mdss_fb_release_kickoff(mfd);
3660 mdss_fb_signal_timeline(sync_pt_data);
3661 if ((mfd->panel.type == MIPI_CMD_PANEL) &&
3662 (mfd->mdp.signal_retire_fence))
3663 mfd->mdp.signal_retire_fence(mfd, 1);
3664 }
3665
3666 if (dynamic_dsi_switch) {
3667 MDSS_XLOG(mfd->index, mfd->split_mode, new_dsi_mode,
3668 XLOG_FUNC_EXIT);
3669 mfd->mdp.mode_switch_post(mfd, new_dsi_mode);
3670 mutex_lock(&mfd->switch_lock);
3671 mfd->switch_state = MDSS_MDP_NO_UPDATE_REQUESTED;
3672 mutex_unlock(&mfd->switch_lock);
3673 if (new_dsi_mode != SWITCH_RESOLUTION)
3674 mfd->panel.type = new_dsi_mode;
3675 pr_debug("Dynamic mode switch completed\n");
3676 }
3677
3678 return ret;
3679}
3680
3681static int __mdss_fb_display_thread(void *data)
3682{
3683 struct msm_fb_data_type *mfd = data;
3684 int ret;
3685 struct sched_param param;
3686
3687 /*
3688 * this priority was found during empiric testing to have appropriate
3689 * realtime scheduling to process display updates and interact with
3690 * other real time and normal priority tasks
3691 */
3692 param.sched_priority = 16;
3693 ret = sched_setscheduler(current, SCHED_FIFO, &param);
3694 if (ret)
3695 pr_warn("set priority failed for fb%d display thread\n",
3696 mfd->index);
3697
3698 while (1) {
3699 wait_event(mfd->commit_wait_q,
3700 (atomic_read(&mfd->commits_pending) ||
3701 kthread_should_stop()));
3702
3703 if (kthread_should_stop())
3704 break;
3705
3706 MDSS_XLOG(mfd->index, XLOG_FUNC_ENTRY);
3707 ret = __mdss_fb_perform_commit(mfd);
3708 MDSS_XLOG(mfd->index, XLOG_FUNC_EXIT);
3709
3710 atomic_dec(&mfd->commits_pending);
3711 wake_up_all(&mfd->idle_wait_q);
3712 }
3713
3714 mdss_fb_release_kickoff(mfd);
3715 atomic_set(&mfd->commits_pending, 0);
3716 wake_up_all(&mfd->idle_wait_q);
3717
3718 return ret;
3719}
3720
3721static int mdss_fb_check_var(struct fb_var_screeninfo *var,
3722 struct fb_info *info)
3723{
3724 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
3725
3726 if (var->rotate != FB_ROTATE_UR && var->rotate != FB_ROTATE_UD)
3727 return -EINVAL;
3728
3729 switch (var->bits_per_pixel) {
3730 case 16:
3731 if ((var->green.offset != 5) ||
3732 !((var->blue.offset == 11)
3733 || (var->blue.offset == 0)) ||
3734 !((var->red.offset == 11)
3735 || (var->red.offset == 0)) ||
3736 (var->blue.length != 5) ||
3737 (var->green.length != 6) ||
3738 (var->red.length != 5) ||
3739 (var->blue.msb_right != 0) ||
3740 (var->green.msb_right != 0) ||
3741 (var->red.msb_right != 0) ||
3742 (var->transp.offset != 0) ||
3743 (var->transp.length != 0))
3744 return -EINVAL;
3745 break;
3746
3747 case 24:
3748 if ((var->blue.offset != 0) ||
3749 (var->green.offset != 8) ||
3750 (var->red.offset != 16) ||
3751 (var->blue.length != 8) ||
3752 (var->green.length != 8) ||
3753 (var->red.length != 8) ||
3754 (var->blue.msb_right != 0) ||
3755 (var->green.msb_right != 0) ||
3756 (var->red.msb_right != 0) ||
3757 !(((var->transp.offset == 0) &&
3758 (var->transp.length == 0)) ||
3759 ((var->transp.offset == 24) &&
3760 (var->transp.length == 8))))
3761 return -EINVAL;
3762 break;
3763
3764 case 32:
3765 /*
3766 * Check user specified color format BGRA/ARGB/RGBA
3767 * and verify the position of the RGB components
3768 */
3769
3770 if (!((var->transp.offset == 24) &&
3771 (var->blue.offset == 0) &&
3772 (var->green.offset == 8) &&
3773 (var->red.offset == 16)) &&
3774 !((var->transp.offset == 0) &&
3775 (var->blue.offset == 24) &&
3776 (var->green.offset == 16) &&
3777 (var->red.offset == 8)) &&
3778 !((var->transp.offset == 24) &&
3779 (var->blue.offset == 16) &&
3780 (var->green.offset == 8) &&
3781 (var->red.offset == 0)))
3782 return -EINVAL;
3783
3784 /* Check the common values for both RGBA and ARGB */
3785
3786 if ((var->blue.length != 8) ||
3787 (var->green.length != 8) ||
3788 (var->red.length != 8) ||
3789 (var->transp.length != 8) ||
3790 (var->blue.msb_right != 0) ||
3791 (var->green.msb_right != 0) ||
3792 (var->red.msb_right != 0))
3793 return -EINVAL;
3794
3795 break;
3796
3797 default:
3798 return -EINVAL;
3799 }
3800
3801 if ((var->xres_virtual <= 0) || (var->yres_virtual <= 0))
3802 return -EINVAL;
3803
3804 if ((var->xres == 0) || (var->yres == 0))
3805 return -EINVAL;
3806
3807 if (var->xoffset > (var->xres_virtual - var->xres))
3808 return -EINVAL;
3809
3810 if (var->yoffset > (var->yres_virtual - var->yres))
3811 return -EINVAL;
3812
3813 if (info->mode) {
3814 const struct fb_videomode *mode;
3815
3816 mode = fb_match_mode(var, &info->modelist);
3817 if (mode == NULL)
3818 return -EINVAL;
3819 } else if (mfd->panel_info && !(var->activate & FB_ACTIVATE_TEST)) {
3820 struct mdss_panel_info *panel_info;
3821 int rc;
3822
3823 panel_info = kzalloc(sizeof(struct mdss_panel_info),
3824 GFP_KERNEL);
3825 if (!panel_info)
3826 return -ENOMEM;
3827
3828 memcpy(panel_info, mfd->panel_info,
3829 sizeof(struct mdss_panel_info));
3830 mdss_fb_var_to_panelinfo(var, panel_info);
3831 rc = mdss_fb_send_panel_event(mfd, MDSS_EVENT_CHECK_PARAMS,
3832 panel_info);
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05303833 if (IS_ERR_VALUE((unsigned long)rc)) {
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303834 kfree(panel_info);
3835 return rc;
3836 }
3837 mfd->panel_reconfig = rc;
3838 kfree(panel_info);
3839 }
3840
3841 return 0;
3842}
3843
3844static int mdss_fb_videomode_switch(struct msm_fb_data_type *mfd,
3845 const struct fb_videomode *mode)
3846{
3847 int ret = 0;
3848 struct mdss_panel_data *pdata, *tmp;
3849 struct mdss_panel_timing *timing;
3850
3851 pdata = dev_get_platdata(&mfd->pdev->dev);
3852 if (!pdata) {
3853 pr_err("no panel connected\n");
3854 return -ENODEV;
3855 }
3856
3857 /* make sure that we are idle while switching */
3858 mdss_fb_wait_for_kickoff(mfd);
3859
3860 pr_debug("fb%d: changing display mode to %s\n", mfd->index, mode->name);
3861 MDSS_XLOG(mfd->index, mode->name,
3862 mdss_fb_get_panel_xres(mfd->panel_info),
3863 mfd->panel_info->yres, mfd->split_mode,
3864 XLOG_FUNC_ENTRY);
3865 tmp = pdata;
3866 do {
3867 if (!tmp->event_handler) {
3868 pr_warn("no event handler for panel\n");
3869 continue;
3870 }
3871 timing = mdss_panel_get_timing_by_name(tmp, mode->name);
3872 ret = tmp->event_handler(tmp,
3873 MDSS_EVENT_PANEL_TIMING_SWITCH, timing);
3874
3875 tmp->active = timing != NULL;
3876 tmp = tmp->next;
3877 } while (tmp && !ret);
3878
3879 if (!ret)
3880 mdss_fb_set_split_mode(mfd, pdata);
3881
3882 if (!ret && mfd->mdp.configure_panel) {
3883 int dest_ctrl = 1;
3884
3885 /* todo: currently assumes no changes in video/cmd mode */
3886 if (!mdss_fb_is_power_off(mfd)) {
3887 mutex_lock(&mfd->switch_lock);
3888 mfd->switch_state = MDSS_MDP_WAIT_FOR_VALIDATE;
3889 mfd->switch_new_mode = SWITCH_RESOLUTION;
3890 mutex_unlock(&mfd->switch_lock);
3891 dest_ctrl = 0;
3892 }
3893 ret = mfd->mdp.configure_panel(mfd,
3894 pdata->panel_info.mipi.mode, dest_ctrl);
3895 }
3896
3897 MDSS_XLOG(mfd->index, mode->name,
3898 mdss_fb_get_panel_xres(mfd->panel_info),
3899 mfd->panel_info->yres, mfd->split_mode,
3900 XLOG_FUNC_EXIT);
3901 pr_debug("fb%d: %s mode change complete\n", mfd->index, mode->name);
3902
3903 return ret;
3904}
3905
3906static int mdss_fb_set_par(struct fb_info *info)
3907{
3908 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
3909 struct fb_var_screeninfo *var = &info->var;
3910 int old_imgType, old_format;
3911 int ret = 0;
3912
3913 ret = mdss_fb_pan_idle(mfd);
3914 if (ret) {
3915 pr_err("mdss_fb_pan_idle failed. rc=%d\n", ret);
3916 return ret;
3917 }
3918
3919 old_imgType = mfd->fb_imgType;
3920 switch (var->bits_per_pixel) {
3921 case 16:
3922 if (var->red.offset == 0)
3923 mfd->fb_imgType = MDP_BGR_565;
3924 else
3925 mfd->fb_imgType = MDP_RGB_565;
3926 break;
3927
3928 case 24:
3929 if ((var->transp.offset == 0) && (var->transp.length == 0))
3930 mfd->fb_imgType = MDP_RGB_888;
3931 else if ((var->transp.offset == 24) &&
3932 (var->transp.length == 8)) {
3933 mfd->fb_imgType = MDP_ARGB_8888;
3934 info->var.bits_per_pixel = 32;
3935 }
3936 break;
3937
3938 case 32:
3939 if ((var->red.offset == 0) &&
3940 (var->green.offset == 8) &&
3941 (var->blue.offset == 16) &&
3942 (var->transp.offset == 24))
3943 mfd->fb_imgType = MDP_RGBA_8888;
3944 else if ((var->red.offset == 16) &&
3945 (var->green.offset == 8) &&
3946 (var->blue.offset == 0) &&
3947 (var->transp.offset == 24))
3948 mfd->fb_imgType = MDP_BGRA_8888;
3949 else if ((var->red.offset == 8) &&
3950 (var->green.offset == 16) &&
3951 (var->blue.offset == 24) &&
3952 (var->transp.offset == 0))
3953 mfd->fb_imgType = MDP_ARGB_8888;
3954 else
3955 mfd->fb_imgType = MDP_RGBA_8888;
3956 break;
3957
3958 default:
3959 return -EINVAL;
3960 }
3961
3962 if (info->mode) {
3963 const struct fb_videomode *mode;
3964
3965 mode = fb_match_mode(var, &info->modelist);
3966 if (!mode)
3967 return -EINVAL;
3968
3969 pr_debug("found mode: %s\n", mode->name);
3970
3971 if (fb_mode_is_equal(mode, info->mode)) {
3972 pr_debug("mode is equal to current mode\n");
3973 return 0;
3974 }
3975
3976 ret = mdss_fb_videomode_switch(mfd, mode);
3977 if (ret)
3978 return ret;
3979 }
3980
3981 if (mfd->mdp.fb_stride)
3982 mfd->fbi->fix.line_length = mfd->mdp.fb_stride(mfd->index,
3983 var->xres,
3984 var->bits_per_pixel / 8);
3985 else
3986 mfd->fbi->fix.line_length = var->xres * var->bits_per_pixel / 8;
3987
3988 /* if memory is not allocated yet, change memory size for fb */
3989 if (!info->fix.smem_start)
3990 mfd->fbi->fix.smem_len = PAGE_ALIGN(mfd->fbi->fix.line_length *
3991 mfd->fbi->var.yres) * mfd->fb_page;
3992
3993 old_format = mdss_grayscale_to_mdp_format(var->grayscale);
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05303994 if (!IS_ERR_VALUE((unsigned long)old_format)) {
Sachin Bhayareeeb88892018-01-02 16:36:01 +05303995 if (old_format != mfd->panel_info->out_format)
3996 mfd->panel_reconfig = true;
3997 }
3998
3999 if (mfd->panel_reconfig || (mfd->fb_imgType != old_imgType)) {
4000 mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info, mfd->op_enable);
4001 mdss_fb_var_to_panelinfo(var, mfd->panel_info);
4002 if (mfd->panel_info->is_dba_panel &&
4003 mdss_fb_send_panel_event(mfd, MDSS_EVENT_UPDATE_PARAMS,
4004 mfd->panel_info))
4005 pr_debug("Failed to send panel event UPDATE_PARAMS\n");
4006 mdss_fb_blank_sub(FB_BLANK_UNBLANK, info, mfd->op_enable);
4007 mfd->panel_reconfig = false;
4008 }
4009
4010 return ret;
4011}
4012
4013int mdss_fb_dcm(struct msm_fb_data_type *mfd, int req_state)
4014{
4015 int ret = 0;
4016
4017 if (req_state == mfd->dcm_state) {
4018 pr_warn("Already in correct DCM/DTM state\n");
4019 return ret;
4020 }
4021
4022 switch (req_state) {
4023 case DCM_UNBLANK:
4024 if (mfd->dcm_state == DCM_UNINIT &&
4025 mdss_fb_is_power_off(mfd) && mfd->mdp.on_fnc) {
4026 if (mfd->disp_thread == NULL) {
4027 ret = mdss_fb_start_disp_thread(mfd);
4028 if (ret < 0)
4029 return ret;
4030 }
4031 ret = mfd->mdp.on_fnc(mfd);
4032 if (ret == 0) {
4033 mfd->panel_power_state = MDSS_PANEL_POWER_ON;
4034 mfd->dcm_state = DCM_UNBLANK;
4035 }
4036 }
4037 break;
4038 case DCM_ENTER:
4039 if (mfd->dcm_state == DCM_UNBLANK) {
4040 /*
4041 * Keep unblank path available for only
4042 * DCM operation
4043 */
4044 mfd->panel_power_state = MDSS_PANEL_POWER_OFF;
4045 mfd->dcm_state = DCM_ENTER;
4046 }
4047 break;
4048 case DCM_EXIT:
4049 if (mfd->dcm_state == DCM_ENTER) {
4050 /* Release the unblank path for exit */
4051 mfd->panel_power_state = MDSS_PANEL_POWER_ON;
4052 mfd->dcm_state = DCM_EXIT;
4053 }
4054 break;
4055 case DCM_BLANK:
4056 if ((mfd->dcm_state == DCM_EXIT ||
4057 mfd->dcm_state == DCM_UNBLANK) &&
4058 mdss_fb_is_power_on(mfd) && mfd->mdp.off_fnc) {
4059 mfd->panel_power_state = MDSS_PANEL_POWER_OFF;
4060 ret = mfd->mdp.off_fnc(mfd);
4061 if (ret == 0)
4062 mfd->dcm_state = DCM_UNINIT;
4063 else
4064 pr_err("DCM_BLANK failed\n");
4065
4066 if (mfd->disp_thread)
4067 mdss_fb_stop_disp_thread(mfd);
4068 }
4069 break;
4070 case DTM_ENTER:
4071 if (mfd->dcm_state == DCM_UNINIT)
4072 mfd->dcm_state = DTM_ENTER;
4073 break;
4074 case DTM_EXIT:
4075 if (mfd->dcm_state == DTM_ENTER)
4076 mfd->dcm_state = DCM_UNINIT;
4077 break;
4078 }
4079
4080 return ret;
4081}
4082
4083static int mdss_fb_cursor(struct fb_info *info, void __user *p)
4084{
4085 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
4086 struct fb_cursor cursor;
4087 int ret;
4088
4089 if (!mfd->mdp.cursor_update)
4090 return -ENODEV;
4091
4092 ret = copy_from_user(&cursor, p, sizeof(cursor));
4093 if (ret)
4094 return ret;
4095
4096 return mfd->mdp.cursor_update(mfd, &cursor);
4097}
4098
4099int mdss_fb_async_position_update(struct fb_info *info,
4100 struct mdp_position_update *update_pos)
4101{
4102 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
4103
4104 if (!update_pos->input_layer_cnt) {
4105 pr_err("no input layers for position update\n");
4106 return -EINVAL;
4107 }
4108 return mfd->mdp.async_position_update(mfd, update_pos);
4109}
4110
4111static int mdss_fb_async_position_update_ioctl(struct fb_info *info,
4112 unsigned long *argp)
4113{
4114 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
4115 struct mdp_position_update update_pos;
4116 int ret, rc;
4117 u32 buffer_size, layer_cnt;
4118 struct mdp_async_layer *layer_list = NULL;
4119 struct mdp_async_layer __user *input_layer_list;
4120
4121 if (!mfd->mdp.async_position_update)
4122 return -ENODEV;
4123
4124 ret = copy_from_user(&update_pos, argp, sizeof(update_pos));
4125 if (ret) {
4126 pr_err("copy from user failed\n");
4127 return ret;
4128 }
4129 input_layer_list = update_pos.input_layers;
4130
4131 layer_cnt = update_pos.input_layer_cnt;
4132 if ((!layer_cnt) || (layer_cnt > MAX_LAYER_COUNT)) {
4133 pr_err("invalid async layers :%d to update\n", layer_cnt);
4134 return -EINVAL;
4135 }
4136
4137 buffer_size = sizeof(struct mdp_async_layer) * layer_cnt;
4138 layer_list = kmalloc(buffer_size, GFP_KERNEL);
4139 if (!layer_list) {
4140 pr_err("unable to allocate memory for layers\n");
4141 return -ENOMEM;
4142 }
4143
4144 ret = copy_from_user(layer_list, input_layer_list, buffer_size);
4145 if (ret) {
4146 pr_err("layer list copy from user failed\n");
4147 goto end;
4148 }
4149 update_pos.input_layers = layer_list;
4150
4151 ret = mdss_fb_async_position_update(info, &update_pos);
4152 if (ret)
4153 pr_err("async position update failed ret:%d\n", ret);
4154
4155 rc = copy_to_user(input_layer_list, layer_list, buffer_size);
4156 if (rc)
4157 pr_err("layer error code copy to user failed\n");
4158
4159 update_pos.input_layers = input_layer_list;
4160 rc = copy_to_user(argp, &update_pos,
4161 sizeof(struct mdp_position_update));
4162 if (rc)
4163 pr_err("copy to user for layers failed");
4164
4165end:
4166 kfree(layer_list);
4167 return ret;
4168}
4169
4170static int mdss_fb_set_lut(struct fb_info *info, void __user *p)
4171{
4172 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
4173 struct fb_cmap cmap;
4174 int ret;
4175
4176 if (!mfd->mdp.lut_update)
4177 return -ENODEV;
4178
4179 ret = copy_from_user(&cmap, p, sizeof(cmap));
4180 if (ret)
4181 return ret;
4182
4183 mfd->mdp.lut_update(mfd, &cmap);
4184 return 0;
4185}
4186
4187/**
4188 * mdss_fb_sync_get_fence() - get fence from timeline
4189 * @timeline: Timeline to create the fence on
4190 * @fence_name: Name of the fence that will be created for debugging
4191 * @val: Timeline value at which the fence will be signaled
4192 *
4193 * Function returns a fence on the timeline given with the name provided.
4194 * The fence created will be signaled when the timeline is advanced.
4195 */
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304196struct mdss_fence *mdss_fb_sync_get_fence(struct mdss_timeline *timeline,
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304197 const char *fence_name, int val)
4198{
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304199 struct mdss_fence *fence;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304200
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304201
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304202 fence = mdss_get_sync_fence(timeline, fence_name, NULL, val);
4203 pr_debug("%s: buf sync fence timeline=%d\n",
4204 mdss_get_sync_fence_name(fence), val);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304205 if (fence == NULL) {
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304206 pr_err("%s: cannot create fence\n", fence_name);
4207 return NULL;
4208 }
4209
4210 return fence;
4211}
4212
4213static int mdss_fb_handle_buf_sync_ioctl(struct msm_sync_pt_data *sync_pt_data,
4214 struct mdp_buf_sync *buf_sync)
4215{
4216 int i, ret = 0;
4217 int acq_fen_fd[MDP_MAX_FENCE_FD];
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304218 struct mdss_fence *fence, *rel_fence, *retire_fence;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304219 int rel_fen_fd;
4220 int retire_fen_fd;
4221 int val;
4222
4223 if ((buf_sync->acq_fen_fd_cnt > MDP_MAX_FENCE_FD) ||
4224 (sync_pt_data->timeline == NULL))
4225 return -EINVAL;
4226
4227 if (buf_sync->acq_fen_fd_cnt)
4228 ret = copy_from_user(acq_fen_fd, buf_sync->acq_fen_fd,
4229 buf_sync->acq_fen_fd_cnt * sizeof(int));
4230 if (ret) {
4231 pr_err("%s: copy_from_user failed\n", sync_pt_data->fence_name);
4232 return ret;
4233 }
4234
4235 i = mdss_fb_wait_for_fence(sync_pt_data);
4236 if (i > 0)
4237 pr_warn("%s: waited on %d active fences\n",
4238 sync_pt_data->fence_name, i);
4239
4240 mutex_lock(&sync_pt_data->sync_mutex);
4241 for (i = 0; i < buf_sync->acq_fen_fd_cnt; i++) {
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304242 fence = mdss_get_fd_sync_fence(acq_fen_fd[i]);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304243 if (fence == NULL) {
4244 pr_err("%s: null fence! i=%d fd=%d\n",
4245 sync_pt_data->fence_name, i,
4246 acq_fen_fd[i]);
4247 ret = -EINVAL;
4248 break;
4249 }
4250 sync_pt_data->acq_fen[i] = fence;
4251 }
4252 sync_pt_data->acq_fen_cnt = i;
4253 if (ret)
4254 goto buf_sync_err_1;
4255
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304256 val = sync_pt_data->threshold +
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304257 atomic_read(&sync_pt_data->commit_cnt);
4258
4259 MDSS_XLOG(sync_pt_data->timeline_value, val,
4260 atomic_read(&sync_pt_data->commit_cnt));
4261 pr_debug("%s: fence CTL%d Commit_cnt%d\n", sync_pt_data->fence_name,
4262 sync_pt_data->timeline_value,
4263 atomic_read(&sync_pt_data->commit_cnt));
4264 /* Set release fence */
4265 rel_fence = mdss_fb_sync_get_fence(sync_pt_data->timeline,
4266 sync_pt_data->fence_name, val);
4267 if (IS_ERR_OR_NULL(rel_fence)) {
4268 pr_err("%s: unable to retrieve release fence\n",
4269 sync_pt_data->fence_name);
4270 ret = rel_fence ? PTR_ERR(rel_fence) : -ENOMEM;
4271 goto buf_sync_err_1;
4272 }
4273
4274 /* create fd */
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304275 rel_fen_fd = mdss_get_sync_fence_fd(rel_fence);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304276 if (rel_fen_fd < 0) {
4277 pr_err("%s: get_unused_fd_flags failed error:0x%x\n",
4278 sync_pt_data->fence_name, rel_fen_fd);
4279 ret = rel_fen_fd;
4280 goto buf_sync_err_2;
4281 }
4282
4283 ret = copy_to_user(buf_sync->rel_fen_fd, &rel_fen_fd, sizeof(int));
4284 if (ret) {
4285 pr_err("%s: copy_to_user failed\n", sync_pt_data->fence_name);
4286 goto buf_sync_err_3;
4287 }
4288
4289 if (!(buf_sync->flags & MDP_BUF_SYNC_FLAG_RETIRE_FENCE))
4290 goto skip_retire_fence;
4291
4292 if (sync_pt_data->get_retire_fence)
4293 retire_fence = sync_pt_data->get_retire_fence(sync_pt_data);
4294 else
4295 retire_fence = NULL;
4296
4297 if (IS_ERR_OR_NULL(retire_fence)) {
4298 val += sync_pt_data->retire_threshold;
4299 retire_fence = mdss_fb_sync_get_fence(
4300 sync_pt_data->timeline, "mdp-retire", val);
4301 }
4302
4303 if (IS_ERR_OR_NULL(retire_fence)) {
4304 pr_err("%s: unable to retrieve retire fence\n",
4305 sync_pt_data->fence_name);
4306 ret = retire_fence ? PTR_ERR(rel_fence) : -ENOMEM;
4307 goto buf_sync_err_3;
4308 }
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304309 retire_fen_fd = mdss_get_sync_fence_fd(retire_fence);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304310
4311 if (retire_fen_fd < 0) {
4312 pr_err("%s: get_unused_fd_flags failed for retire fence error:0x%x\n",
4313 sync_pt_data->fence_name, retire_fen_fd);
4314 ret = retire_fen_fd;
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304315 mdss_put_sync_fence(retire_fence);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304316 goto buf_sync_err_3;
4317 }
4318
4319 ret = copy_to_user(buf_sync->retire_fen_fd, &retire_fen_fd,
4320 sizeof(int));
4321 if (ret) {
4322 pr_err("%s: copy_to_user failed for retire fence\n",
4323 sync_pt_data->fence_name);
4324 put_unused_fd(retire_fen_fd);
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304325 mdss_put_sync_fence(retire_fence);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304326 goto buf_sync_err_3;
4327 }
4328
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304329skip_retire_fence:
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304330 mdss_get_sync_fence_fd(rel_fence);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304331 mutex_unlock(&sync_pt_data->sync_mutex);
4332
4333 if (buf_sync->flags & MDP_BUF_SYNC_FLAG_WAIT)
4334 mdss_fb_wait_for_fence(sync_pt_data);
4335
4336 return ret;
4337buf_sync_err_3:
4338 put_unused_fd(rel_fen_fd);
4339buf_sync_err_2:
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304340 mdss_put_sync_fence(rel_fence);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304341buf_sync_err_1:
4342 for (i = 0; i < sync_pt_data->acq_fen_cnt; i++)
Sachin Bhayare2b6d0042018-01-13 19:38:21 +05304343 mdss_put_sync_fence(sync_pt_data->acq_fen[i]);
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304344 sync_pt_data->acq_fen_cnt = 0;
4345 mutex_unlock(&sync_pt_data->sync_mutex);
4346 return ret;
4347}
4348static int mdss_fb_display_commit(struct fb_info *info,
4349 unsigned long *argp)
4350{
4351 int ret;
4352 struct mdp_display_commit disp_commit;
4353
4354 ret = copy_from_user(&disp_commit, argp,
4355 sizeof(disp_commit));
4356 if (ret) {
4357 pr_err("%s:copy_from_user failed\n", __func__);
4358 return ret;
4359 }
4360 ret = mdss_fb_pan_display_ex(info, &disp_commit);
4361 return ret;
4362}
4363
4364/**
4365 * __mdss_fb_copy_pixel_ext() - copy pixel extension payload
4366 * @src: pixel extn structure
4367 * @dest: Qseed3/pixel extn common payload
4368 *
4369 * Function copies the pixel extension parameters into the scale data structure,
4370 * this is required to allow using the scale_v2 data structure for both
4371 * QSEED2 and QSEED3
4372 */
4373static void __mdss_fb_copy_pixel_ext(struct mdp_scale_data *src,
4374 struct mdp_scale_data_v2 *dest)
4375{
4376 if (!src || !dest)
4377 return;
4378 memcpy(dest->init_phase_x, src->init_phase_x,
4379 sizeof(src->init_phase_x));
4380 memcpy(dest->phase_step_x, src->phase_step_x,
4381 sizeof(src->init_phase_x));
4382 memcpy(dest->init_phase_y, src->init_phase_y,
4383 sizeof(src->init_phase_x));
4384 memcpy(dest->phase_step_y, src->phase_step_y,
4385 sizeof(src->init_phase_x));
4386
4387 memcpy(dest->num_ext_pxls_left, src->num_ext_pxls_left,
4388 sizeof(src->num_ext_pxls_left));
4389 memcpy(dest->num_ext_pxls_right, src->num_ext_pxls_right,
4390 sizeof(src->num_ext_pxls_right));
4391 memcpy(dest->num_ext_pxls_top, src->num_ext_pxls_top,
4392 sizeof(src->num_ext_pxls_top));
4393 memcpy(dest->num_ext_pxls_btm, src->num_ext_pxls_btm,
4394 sizeof(src->num_ext_pxls_btm));
4395
4396 memcpy(dest->left_ftch, src->left_ftch, sizeof(src->left_ftch));
4397 memcpy(dest->left_rpt, src->left_rpt, sizeof(src->left_rpt));
4398 memcpy(dest->right_ftch, src->right_ftch, sizeof(src->right_ftch));
4399 memcpy(dest->right_rpt, src->right_rpt, sizeof(src->right_rpt));
4400
4401
4402 memcpy(dest->top_rpt, src->top_rpt, sizeof(src->top_rpt));
4403 memcpy(dest->btm_rpt, src->btm_rpt, sizeof(src->btm_rpt));
4404 memcpy(dest->top_ftch, src->top_ftch, sizeof(src->top_ftch));
4405 memcpy(dest->btm_ftch, src->btm_ftch, sizeof(src->btm_ftch));
4406
4407 memcpy(dest->roi_w, src->roi_w, sizeof(src->roi_w));
4408}
4409
4410static int __mdss_fb_scaler_handler(struct mdp_input_layer *layer)
4411{
4412 int ret = 0;
4413 struct mdp_scale_data *pixel_ext = NULL;
4414 struct mdp_scale_data_v2 *scale = NULL;
4415
4416 if ((layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT) &&
4417 (layer->flags & MDP_LAYER_ENABLE_QSEED3_SCALE)) {
4418 pr_err("Invalid flag configuration for scaler, %x\n",
4419 layer->flags);
4420 ret = -EINVAL;
4421 goto err;
4422 }
4423
4424 if (layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT) {
4425 scale = kzalloc(sizeof(struct mdp_scale_data_v2),
4426 GFP_KERNEL);
4427 pixel_ext = kzalloc(sizeof(struct mdp_scale_data),
4428 GFP_KERNEL);
4429 if (!scale || !pixel_ext) {
4430 mdss_mdp_free_layer_pp_info(layer);
4431 ret = -ENOMEM;
4432 goto err;
4433 }
4434 ret = copy_from_user(pixel_ext, layer->scale,
4435 sizeof(struct mdp_scale_data));
4436 if (ret) {
4437 mdss_mdp_free_layer_pp_info(layer);
4438 ret = -EFAULT;
4439 goto err;
4440 }
4441 __mdss_fb_copy_pixel_ext(pixel_ext, scale);
4442 layer->scale = scale;
4443 } else if (layer->flags & MDP_LAYER_ENABLE_QSEED3_SCALE) {
4444 scale = kzalloc(sizeof(struct mdp_scale_data_v2),
4445 GFP_KERNEL);
4446 if (!scale) {
4447 mdss_mdp_free_layer_pp_info(layer);
4448 ret = -ENOMEM;
4449 goto err;
4450 }
4451
4452 ret = copy_from_user(scale, layer->scale,
4453 sizeof(struct mdp_scale_data_v2));
4454 if (ret) {
4455 mdss_mdp_free_layer_pp_info(layer);
4456 ret = -EFAULT;
4457 goto err;
4458 }
4459 layer->scale = scale;
4460 } else {
4461 layer->scale = NULL;
4462 }
4463 kfree(pixel_ext);
4464 return ret;
4465err:
4466 kfree(pixel_ext);
4467 kfree(scale);
4468 layer->scale = NULL;
4469 return ret;
4470}
4471
4472static int mdss_fb_atomic_commit_ioctl(struct fb_info *info,
4473 unsigned long *argp, struct file *file)
4474{
4475 int ret, i = 0, j = 0, rc;
4476 struct mdp_layer_commit commit;
4477 u32 buffer_size, layer_count;
4478 struct mdp_input_layer *layer, *layer_list = NULL;
4479 struct mdp_input_layer __user *input_layer_list;
4480 struct mdp_output_layer *output_layer = NULL;
4481 struct mdp_output_layer __user *output_layer_user;
4482 struct mdp_frc_info *frc_info = NULL;
4483 struct mdp_frc_info __user *frc_info_user;
4484 struct msm_fb_data_type *mfd;
4485 struct mdss_overlay_private *mdp5_data = NULL;
4486
4487 ret = copy_from_user(&commit, argp, sizeof(struct mdp_layer_commit));
4488 if (ret) {
4489 pr_err("%s:copy_from_user failed\n", __func__);
4490 return ret;
4491 }
4492
4493 mfd = (struct msm_fb_data_type *)info->par;
4494 if (!mfd)
4495 return -EINVAL;
4496
4497 mdp5_data = mfd_to_mdp5_data(mfd);
4498
4499 if (mfd->panel_info->panel_dead) {
4500 pr_debug("early commit return\n");
4501 MDSS_XLOG(mfd->panel_info->panel_dead);
4502 /*
4503 * In case of an ESD attack, since we early return from the
4504 * commits, we need to signal the outstanding fences.
4505 */
4506 mdss_fb_release_fences(mfd);
4507 if ((mfd->panel.type == MIPI_CMD_PANEL) &&
4508 mfd->mdp.signal_retire_fence && mdp5_data)
4509 mfd->mdp.signal_retire_fence(mfd,
4510 mdp5_data->retire_cnt);
4511 return 0;
4512 }
4513
4514 output_layer_user = commit.commit_v1.output_layer;
4515 if (output_layer_user) {
4516 buffer_size = sizeof(struct mdp_output_layer);
4517 output_layer = kzalloc(buffer_size, GFP_KERNEL);
4518 if (!output_layer) {
4519 pr_err("unable to allocate memory for output layer\n");
4520 return -ENOMEM;
4521 }
4522
4523 ret = copy_from_user(output_layer,
4524 output_layer_user, buffer_size);
4525 if (ret) {
4526 pr_err("layer list copy from user failed\n");
4527 goto err;
4528 }
4529 commit.commit_v1.output_layer = output_layer;
4530 }
4531
4532 layer_count = commit.commit_v1.input_layer_cnt;
4533 input_layer_list = commit.commit_v1.input_layers;
4534
4535 if (layer_count > MAX_LAYER_COUNT) {
4536 ret = -EINVAL;
4537 goto err;
4538 } else if (layer_count) {
4539 buffer_size = sizeof(struct mdp_input_layer) * layer_count;
4540 layer_list = kzalloc(buffer_size, GFP_KERNEL);
4541 if (!layer_list) {
4542 pr_err("unable to allocate memory for layers\n");
4543 ret = -ENOMEM;
4544 goto err;
4545 }
4546
4547 ret = copy_from_user(layer_list, input_layer_list, buffer_size);
4548 if (ret) {
4549 pr_err("layer list copy from user failed\n");
4550 goto err;
4551 }
4552
4553 commit.commit_v1.input_layers = layer_list;
4554
4555 for (i = 0; i < layer_count; i++) {
4556 layer = &layer_list[i];
4557
4558 if (!(layer->flags & MDP_LAYER_PP)) {
4559 layer->pp_info = NULL;
4560 } else {
4561 ret = mdss_mdp_copy_layer_pp_info(layer);
4562 if (ret) {
4563 pr_err("failure to copy pp_info data for layer %d, ret = %d\n",
4564 i, ret);
4565 goto err;
4566 }
4567 }
4568
4569 if ((layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT) ||
4570 (layer->flags &
4571 MDP_LAYER_ENABLE_QSEED3_SCALE)) {
4572 ret = __mdss_fb_scaler_handler(layer);
4573 if (ret) {
4574 pr_err("failure to copy scale params for layer %d, ret = %d\n",
4575 i, ret);
4576 goto err;
4577 }
4578 } else {
4579 layer->scale = NULL;
4580 }
4581 }
4582 }
4583
4584 /* Copy Deterministic Frame Rate Control info from userspace */
4585 frc_info_user = commit.commit_v1.frc_info;
4586 if (frc_info_user) {
4587 frc_info = kzalloc(sizeof(struct mdp_frc_info), GFP_KERNEL);
4588 if (!frc_info) {
4589 pr_err("unable to allocate memory for frc\n");
4590 ret = -ENOMEM;
4591 goto err;
4592 }
4593
4594 ret = copy_from_user(frc_info, frc_info_user,
4595 sizeof(struct mdp_frc_info));
4596 if (ret) {
4597 pr_err("frc info copy from user failed\n");
4598 goto frc_err;
4599 }
4600
4601 commit.commit_v1.frc_info = frc_info;
4602 }
4603
4604 ATRACE_BEGIN("ATOMIC_COMMIT");
4605 ret = mdss_fb_atomic_commit(info, &commit, file);
4606 if (ret)
4607 pr_err("atomic commit failed ret:%d\n", ret);
4608 ATRACE_END("ATOMIC_COMMIT");
4609
4610 if (layer_count) {
4611 for (j = 0; j < layer_count; j++) {
4612 rc = copy_to_user(&input_layer_list[j].error_code,
4613 &layer_list[j].error_code, sizeof(int));
4614 if (rc)
4615 pr_err("layer error code copy to user failed\n");
4616 }
4617
4618 commit.commit_v1.input_layers = input_layer_list;
4619 commit.commit_v1.output_layer = output_layer_user;
4620 commit.commit_v1.frc_info = frc_info_user;
4621 rc = copy_to_user(argp, &commit,
4622 sizeof(struct mdp_layer_commit));
4623 if (rc)
4624 pr_err("copy to user for release & retire fence failed\n");
4625 }
4626
4627frc_err:
4628 kfree(frc_info);
4629err:
4630 for (i--; i >= 0; i--) {
4631 kfree(layer_list[i].scale);
4632 layer_list[i].scale = NULL;
4633 mdss_mdp_free_layer_pp_info(&layer_list[i]);
4634 }
4635 kfree(layer_list);
4636 kfree(output_layer);
4637
4638 return ret;
4639}
4640
4641int mdss_fb_switch_check(struct msm_fb_data_type *mfd, u32 mode)
4642{
4643 struct mdss_panel_info *pinfo = NULL;
4644 int panel_type;
4645
4646 if (!mfd || !mfd->panel_info)
4647 return -EINVAL;
4648
4649 pinfo = mfd->panel_info;
4650
4651 if ((!mfd->op_enable) || (mdss_fb_is_power_off(mfd)))
4652 return -EPERM;
4653
4654 if (pinfo->mipi.dms_mode != DYNAMIC_MODE_SWITCH_IMMEDIATE) {
4655 pr_warn("Panel does not support immediate dynamic switch!\n");
4656 return -EPERM;
4657 }
4658
4659 if (mfd->dcm_state != DCM_UNINIT) {
4660 pr_warn("Switch not supported during DCM!\n");
4661 return -EPERM;
4662 }
4663
4664 mutex_lock(&mfd->switch_lock);
4665 if (mode == pinfo->type) {
4666 pr_debug("Already in requested mode!\n");
4667 mutex_unlock(&mfd->switch_lock);
4668 return -EPERM;
4669 }
4670 mutex_unlock(&mfd->switch_lock);
4671
4672 panel_type = mfd->panel.type;
4673 if (panel_type != MIPI_VIDEO_PANEL && panel_type != MIPI_CMD_PANEL) {
4674 pr_debug("Panel not in mipi video or cmd mode, cannot change\n");
4675 return -EPERM;
4676 }
4677
4678 return 0;
4679}
4680
4681static int mdss_fb_immediate_mode_switch(struct msm_fb_data_type *mfd, u32 mode)
4682{
4683 int ret;
4684 u32 tranlated_mode;
4685
4686 if (mode)
4687 tranlated_mode = MIPI_CMD_PANEL;
4688 else
4689 tranlated_mode = MIPI_VIDEO_PANEL;
4690
4691 pr_debug("%s: Request to switch to %d,", __func__, tranlated_mode);
4692
4693 ret = mdss_fb_switch_check(mfd, tranlated_mode);
4694 if (ret)
4695 return ret;
4696
4697 mutex_lock(&mfd->switch_lock);
4698 if (mfd->switch_state != MDSS_MDP_NO_UPDATE_REQUESTED) {
4699 pr_err("%s: Mode switch already in progress\n", __func__);
4700 ret = -EAGAIN;
4701 goto exit;
4702 }
4703 mfd->switch_state = MDSS_MDP_WAIT_FOR_VALIDATE;
4704 mfd->switch_new_mode = tranlated_mode;
4705
4706exit:
4707 mutex_unlock(&mfd->switch_lock);
4708 return ret;
4709}
4710
4711/*
4712 * mdss_fb_mode_switch() - Function to change DSI mode
4713 * @mfd: Framebuffer data structure for display
4714 * @mode: Enabled/Disable LowPowerMode
4715 * 1: Switch to Command Mode
4716 * 0: Switch to video Mode
4717 *
4718 * This function is used to change from DSI mode based on the
4719 * argument @mode on the next frame to be displayed.
4720 */
4721static int mdss_fb_mode_switch(struct msm_fb_data_type *mfd, u32 mode)
4722{
4723 struct mdss_panel_info *pinfo = NULL;
4724 int ret = 0;
4725
4726 if (!mfd || !mfd->panel_info)
4727 return -EINVAL;
4728
4729 pinfo = mfd->panel_info;
4730 if (pinfo->mipi.dms_mode == DYNAMIC_MODE_SWITCH_SUSPEND_RESUME) {
4731 ret = mdss_fb_blanking_mode_switch(mfd, mode);
4732 } else if (pinfo->mipi.dms_mode == DYNAMIC_MODE_SWITCH_IMMEDIATE) {
4733 ret = mdss_fb_immediate_mode_switch(mfd, mode);
4734 } else {
4735 pr_warn("Panel does not support dynamic mode switch!\n");
4736 ret = -EPERM;
4737 }
4738
4739 return ret;
4740}
4741
4742static int __ioctl_wait_idle(struct msm_fb_data_type *mfd, u32 cmd)
4743{
4744 int ret = 0;
4745
4746 if (mfd->wait_for_kickoff &&
4747 ((cmd == MSMFB_OVERLAY_PREPARE) ||
4748 (cmd == MSMFB_BUFFER_SYNC) ||
4749 (cmd == MSMFB_OVERLAY_PLAY) ||
4750 (cmd == MSMFB_CURSOR) ||
4751 (cmd == MSMFB_METADATA_GET) ||
4752 (cmd == MSMFB_METADATA_SET) ||
4753 (cmd == MSMFB_OVERLAY_GET) ||
4754 (cmd == MSMFB_OVERLAY_UNSET) ||
4755 (cmd == MSMFB_OVERLAY_SET))) {
4756 ret = mdss_fb_wait_for_kickoff(mfd);
4757 }
4758
4759 if (ret && (ret != -ESHUTDOWN))
4760 pr_err("wait_idle failed. cmd=0x%x rc=%d\n", cmd, ret);
4761
4762 return ret;
4763}
4764
4765#ifdef TARGET_HW_MDSS_MDP3
4766static bool check_not_supported_ioctl(u32 cmd)
4767{
4768 return false;
4769}
4770#else
4771static bool check_not_supported_ioctl(u32 cmd)
4772{
4773 return((cmd == MSMFB_OVERLAY_SET) || (cmd == MSMFB_OVERLAY_UNSET) ||
4774 (cmd == MSMFB_OVERLAY_GET) || (cmd == MSMFB_OVERLAY_PREPARE) ||
4775 (cmd == MSMFB_DISPLAY_COMMIT) || (cmd == MSMFB_OVERLAY_PLAY) ||
4776 (cmd == MSMFB_BUFFER_SYNC) || (cmd == MSMFB_OVERLAY_QUEUE) ||
4777 (cmd == MSMFB_NOTIFY_UPDATE));
4778}
4779#endif
4780
4781/*
4782 * mdss_fb_do_ioctl() - MDSS Framebuffer ioctl function
4783 * @info: pointer to framebuffer info
4784 * @cmd: ioctl command
4785 * @arg: argument to ioctl
4786 *
4787 * This function provides an architecture agnostic implementation
4788 * of the mdss framebuffer ioctl. This function can be called
4789 * by compat ioctl or regular ioctl to handle the supported commands.
4790 */
4791int mdss_fb_do_ioctl(struct fb_info *info, unsigned int cmd,
4792 unsigned long arg, struct file *file)
4793{
4794 struct msm_fb_data_type *mfd;
4795 void __user *argp = (void __user *)arg;
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05304796 int ret = -ENOTSUPP;
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304797 struct mdp_buf_sync buf_sync;
4798 unsigned int dsi_mode = 0;
4799 struct mdss_panel_data *pdata = NULL;
4800
4801 if (!info || !info->par)
4802 return -EINVAL;
4803
4804 mfd = (struct msm_fb_data_type *)info->par;
4805 if (!mfd)
4806 return -EINVAL;
4807
4808 if (mfd->shutdown_pending)
4809 return -ESHUTDOWN;
4810
4811 pdata = dev_get_platdata(&mfd->pdev->dev);
4812 if (!pdata || pdata->panel_info.dynamic_switch_pending)
4813 return -EPERM;
4814
4815 if (check_not_supported_ioctl(cmd)) {
4816 pr_err("Unsupported ioctl\n");
4817 return -EINVAL;
4818 }
4819
4820 atomic_inc(&mfd->ioctl_ref_cnt);
4821
4822 mdss_fb_power_setting_idle(mfd);
4823
4824 ret = __ioctl_wait_idle(mfd, cmd);
4825 if (ret)
4826 goto exit;
4827
4828 switch (cmd) {
4829 case MSMFB_CURSOR:
4830 ret = mdss_fb_cursor(info, argp);
4831 break;
4832
4833 case MSMFB_SET_LUT:
4834 ret = mdss_fb_set_lut(info, argp);
4835 break;
4836
4837 case MSMFB_BUFFER_SYNC:
4838 ret = copy_from_user(&buf_sync, argp, sizeof(buf_sync));
4839 if (ret)
4840 goto exit;
4841
4842 if ((!mfd->op_enable) || (mdss_fb_is_power_off(mfd))) {
4843 ret = -EPERM;
4844 goto exit;
4845 }
4846
4847 ret = mdss_fb_handle_buf_sync_ioctl(&mfd->mdp_sync_pt_data,
4848 &buf_sync);
4849 if (!ret)
4850 ret = copy_to_user(argp, &buf_sync, sizeof(buf_sync));
4851 break;
4852
4853 case MSMFB_NOTIFY_UPDATE:
4854 ret = mdss_fb_notify_update(mfd, argp);
4855 break;
4856
4857 case MSMFB_DISPLAY_COMMIT:
4858 ret = mdss_fb_display_commit(info, argp);
4859 break;
4860
4861 case MSMFB_LPM_ENABLE:
4862 ret = copy_from_user(&dsi_mode, argp, sizeof(dsi_mode));
4863 if (ret) {
4864 pr_err("%s: MSMFB_LPM_ENABLE ioctl failed\n", __func__);
4865 goto exit;
4866 }
4867
4868 ret = mdss_fb_mode_switch(mfd, dsi_mode);
4869 break;
4870 case MSMFB_ATOMIC_COMMIT:
4871 ret = mdss_fb_atomic_commit_ioctl(info, argp, file);
4872 break;
4873
4874 case MSMFB_ASYNC_POSITION_UPDATE:
4875 ret = mdss_fb_async_position_update_ioctl(info, argp);
4876 break;
4877
4878 default:
4879 if (mfd->mdp.ioctl_handler)
4880 ret = mfd->mdp.ioctl_handler(mfd, cmd, argp);
4881 break;
4882 }
4883
Sachin Bhayare3d3767e2018-01-02 21:10:57 +05304884 if (ret == -ENOTSUPP)
Sachin Bhayareeeb88892018-01-02 16:36:01 +05304885 pr_err("unsupported ioctl (%x)\n", cmd);
4886
4887exit:
4888 if (!atomic_dec_return(&mfd->ioctl_ref_cnt))
4889 wake_up_all(&mfd->ioctl_q);
4890
4891 return ret;
4892}
4893
4894static int mdss_fb_ioctl(struct fb_info *info, unsigned int cmd,
4895 unsigned long arg, struct file *file)
4896{
4897 if (!info || !info->par)
4898 return -EINVAL;
4899
4900 return mdss_fb_do_ioctl(info, cmd, arg, file);
4901}
4902
4903static int mdss_fb_register_extra_panel(struct platform_device *pdev,
4904 struct mdss_panel_data *pdata)
4905{
4906 struct mdss_panel_data *fb_pdata;
4907
4908 fb_pdata = dev_get_platdata(&pdev->dev);
4909 if (!fb_pdata) {
4910 pr_err("framebuffer device %s contains invalid panel data\n",
4911 dev_name(&pdev->dev));
4912 return -EINVAL;
4913 }
4914
4915 if (fb_pdata->next) {
4916 pr_err("split panel already setup for framebuffer device %s\n",
4917 dev_name(&pdev->dev));
4918 return -EEXIST;
4919 }
4920
4921 fb_pdata->next = pdata;
4922
4923 return 0;
4924}
4925
4926int mdss_register_panel(struct platform_device *pdev,
4927 struct mdss_panel_data *pdata)
4928{
4929 struct platform_device *fb_pdev, *mdss_pdev;
4930 struct device_node *node = NULL;
4931 int rc = 0;
4932 bool master_panel = true;
4933
4934 if (!pdev || !pdev->dev.of_node) {
4935 pr_err("Invalid device node\n");
4936 return -ENODEV;
4937 }
4938
4939 if (!mdp_instance) {
4940 pr_err("mdss mdp resource not initialized yet\n");
4941 return -EPROBE_DEFER;
4942 }
4943
4944 if (pdata->get_fb_node)
4945 node = pdata->get_fb_node(pdev);
4946
4947 if (!node) {
4948 node = of_parse_phandle(pdev->dev.of_node,
4949 "qcom,mdss-fb-map", 0);
4950 if (!node) {
4951 pr_err("Unable to find fb node for device: %s\n",
4952 pdev->name);
4953 return -ENODEV;
4954 }
4955 }
4956 mdss_pdev = of_find_device_by_node(node->parent);
4957 if (!mdss_pdev) {
4958 pr_err("Unable to find mdss for node: %s\n", node->full_name);
4959 rc = -ENODEV;
4960 goto mdss_notfound;
4961 }
4962
4963 pdata->active = true;
4964 fb_pdev = of_find_device_by_node(node);
4965 if (fb_pdev) {
4966 rc = mdss_fb_register_extra_panel(fb_pdev, pdata);
4967 if (rc == 0)
4968 master_panel = false;
4969 } else {
4970 pr_info("adding framebuffer device %s\n", dev_name(&pdev->dev));
4971 fb_pdev = of_platform_device_create(node, NULL,
4972 &mdss_pdev->dev);
4973 if (fb_pdev)
4974 fb_pdev->dev.platform_data = pdata;
4975 }
4976
4977 if (master_panel && mdp_instance->panel_register_done)
4978 mdp_instance->panel_register_done(pdata);
4979
4980mdss_notfound:
4981 of_node_put(node);
4982 return rc;
4983}
4984EXPORT_SYMBOL(mdss_register_panel);
4985
4986int mdss_fb_register_mdp_instance(struct msm_mdp_interface *mdp)
4987{
4988 if (mdp_instance) {
4989 pr_err("multiple MDP instance registration\n");
4990 return -EINVAL;
4991 }
4992
4993 mdp_instance = mdp;
4994 return 0;
4995}
4996EXPORT_SYMBOL(mdss_fb_register_mdp_instance);
4997
4998int mdss_fb_get_phys_info(dma_addr_t *start, unsigned long *len, int fb_num)
4999{
5000 struct fb_info *info;
5001 struct msm_fb_data_type *mfd;
5002
5003 if (fb_num >= MAX_FBI_LIST)
5004 return -EINVAL;
5005
5006 info = fbi_list[fb_num];
5007 if (!info)
5008 return -ENOENT;
5009
5010 mfd = (struct msm_fb_data_type *)info->par;
5011 if (!mfd)
5012 return -ENODEV;
5013
5014 if (mfd->iova)
5015 *start = mfd->iova;
5016 else
5017 *start = info->fix.smem_start;
5018 *len = info->fix.smem_len;
5019
5020 return 0;
5021}
5022EXPORT_SYMBOL(mdss_fb_get_phys_info);
5023
5024int __init mdss_fb_init(void)
5025{
5026 int rc = -ENODEV;
5027
5028 if (fb_get_options("msmfb", NULL))
5029 return rc;
5030
5031 if (platform_driver_register(&mdss_fb_driver))
5032 return rc;
5033
5034 return 0;
5035}
5036
5037module_init(mdss_fb_init);
5038
5039int mdss_fb_suspres_panel(struct device *dev, void *data)
5040{
5041 struct msm_fb_data_type *mfd;
5042 int rc = 0;
5043 u32 event;
5044
5045 if (!data) {
5046 pr_err("Device state not defined\n");
5047 return -EINVAL;
5048 }
5049 mfd = dev_get_drvdata(dev);
5050 if (!mfd)
5051 return 0;
5052
5053 event = *((bool *) data) ? MDSS_EVENT_RESUME : MDSS_EVENT_SUSPEND;
5054
5055 /* Do not send runtime suspend/resume for HDMI primary */
5056 if (!mdss_fb_is_hdmi_primary(mfd)) {
5057 rc = mdss_fb_send_panel_event(mfd, event, NULL);
5058 if (rc)
5059 pr_warn("unable to %s fb%d (%d)\n",
5060 event == MDSS_EVENT_RESUME ?
5061 "resume" : "suspend",
5062 mfd->index, rc);
5063 }
5064 return rc;
5065}
5066
5067/*
5068 * mdss_fb_report_panel_dead() - Sends the PANEL_ALIVE=0 status to HAL layer.
5069 * @mfd : frame buffer structure associated with fb device.
5070 *
5071 * This function is called if the panel fails to respond as expected to
5072 * the register read/BTA or if the TE signal is not coming as expected
5073 * from the panel. The function sends the PANEL_ALIVE=0 status to HAL
5074 * layer.
5075 */
5076void mdss_fb_report_panel_dead(struct msm_fb_data_type *mfd)
5077{
5078 char *envp[2] = {"PANEL_ALIVE=0", NULL};
5079 struct mdss_panel_data *pdata =
5080 dev_get_platdata(&mfd->pdev->dev);
5081 if (!pdata) {
5082 pr_err("Panel data not available\n");
5083 return;
5084 }
5085
5086 pdata->panel_info.panel_dead = true;
5087 kobject_uevent_env(&mfd->fbi->dev->kobj,
5088 KOBJ_CHANGE, envp);
5089 pr_err("Panel has gone bad, sending uevent - %s\n", envp[0]);
5090}
5091
5092
5093/*
5094 * mdss_fb_calc_fps() - Calculates fps value.
5095 * @mfd : frame buffer structure associated with fb device.
5096 *
5097 * This function is called at frame done. It counts the number
5098 * of frames done for every 1 sec. Stores the value in measured_fps.
5099 * measured_fps value is 10 times the calculated fps value.
5100 * For example, measured_fps= 594 for calculated fps of 59.4
5101 */
5102void mdss_fb_calc_fps(struct msm_fb_data_type *mfd)
5103{
5104 ktime_t current_time_us;
5105 u64 fps, diff_us;
5106
5107 current_time_us = ktime_get();
5108 diff_us = (u64)ktime_us_delta(current_time_us,
5109 mfd->fps_info.last_sampled_time_us);
5110 mfd->fps_info.frame_count++;
5111
5112 if (diff_us >= MDP_TIME_PERIOD_CALC_FPS_US) {
5113 fps = ((u64)mfd->fps_info.frame_count) * 10000000;
5114 do_div(fps, diff_us);
5115 mfd->fps_info.measured_fps = (unsigned int)fps;
5116 pr_debug(" MDP_FPS for fb%d is %d.%d\n",
5117 mfd->index, (unsigned int)fps/10, (unsigned int)fps%10);
5118 mfd->fps_info.last_sampled_time_us = current_time_us;
5119 mfd->fps_info.frame_count = 0;
5120 }
5121}