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