video: tegra: dc: rename tegra_dc_blank
[linux-3.10.git] / drivers / video / tegra / dc / ext / dev.c
1 /*
2  * drivers/video/tegra/dc/ext/dev.c
3  *
4  * Copyright (c) 2011-2017, NVIDIA CORPORATION, All rights reserved.
5  *
6  * Author: Robert Morell <rmorell@nvidia.com>
7  * Some code based on fbdev extensions written by:
8  *      Erik Gilling <konkers@android.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18  * more details.
19  */
20
21 #include <linux/file.h>
22 #include <linux/fs.h>
23 #include <linux/uaccess.h>
24 #include <linux/slab.h>
25 #include <linux/workqueue.h>
26 #include <linux/export.h>
27 #include <linux/delay.h>
28 #include <mach/fb.h>
29 #include <linux/fb.h>
30 #include <video/tegra_dc_ext.h>
31
32 #include <mach/dc.h>
33 #include <mach/tegra_dc_ext.h>
34 #include <trace/events/display.h>
35
36 /* XXX ew */
37 #include "../dc_priv.h"
38 #include "../dc_config.h"
39 /* XXX ew 2 */
40 #include "../../host/dev.h"
41 /* XXX ew 3 */
42 #include "tegra_dc_ext_priv.h"
43 /* XXX ew 4 */
44 #ifdef CONFIG_TEGRA_GRHOST_SYNC
45 #include "../../../staging/android/sync.h"
46 #endif
47
48 #include "../edid.h"
49
50 #define TEGRA_DC_TS_MAX_DELAY_US 1000000
51 #define TEGRA_DC_TS_SLACK_US 100
52
53 #define TEGRA_DC_SMOOTHING_CR_PC 75
54 #define TEGRA_DC_SMOOTHING_MAX_APC_US 64000
55 #define TEGRA_DC_SMOOTHING_LATENCY_US 4000
56 #define TEGRA_DC_SMOOTHING_SLACK_US 50
57
58 #define BEGIN_TRACE() trace_function_frame(__func__, 'B')
59 #define TRACE_NAME_BEGIN(NAME) trace_function_frame(#NAME, 'B')
60 #define END_TRACE() trace_function_frame(__func__, 'E')
61 #define TRACE_NAME_END(NAME) trace_function_frame(#NAME, 'E')
62
63 #ifdef CONFIG_COMPAT
64 /* compat versions that happen to be the same size as the uapi version. */
65
66 struct tegra_dc_ext_lut32 {
67         __u32 win_index;        /* window index to set lut for */
68         __u32 flags;            /* Flag bitmask, see TEGRA_DC_EXT_LUT_FLAGS_* */
69         __u32 start;            /* start index to update lut from */
70         __u32 len;              /* number of valid lut entries */
71         __u32 r;                /* array of 16-bit red values, 0 to reset */
72         __u32 g;                /* array of 16-bit green values, 0 to reset */
73         __u32 b;                /* array of 16-bit blue values, 0 to reset */
74 };
75
76 #define TEGRA_DC_EXT_SET_LUT32 \
77                 _IOW('D', 0x0A, struct tegra_dc_ext_lut32)
78
79 struct tegra_dc_ext_feature32 {
80         __u32 length;
81         __u32 entries;          /* pointer to array of 32-bit entries */
82 };
83
84 #define TEGRA_DC_EXT_GET_FEATURES32 \
85                 _IOW('D', 0x0B, struct tegra_dc_ext_feature32)
86
87 struct tegra_dc_ext_flip_2_32 {
88         __u32 __user win;       /* struct tegra_dc_ext_flip_windowattr* */
89         __u8 win_num;
90         __u8 reserved1;         /* unused - must be 0 */
91         __u16 reserved2;        /* unused - must be 0 */
92         __u32 post_syncpt_id;
93         __u32 post_syncpt_val;
94         __u16 dirty_rect[4]; /* x,y,w,h for partial screen update. 0 ignores */
95 };
96
97 #define TEGRA_DC_EXT_FLIP2_32 \
98                 _IOWR('D', 0x0E, struct tegra_dc_ext_flip_2_32)
99
100 #define TEGRA_DC_EXT_SET_PROPOSED_BW32 \
101                 _IOR('D', 0x13, struct tegra_dc_ext_flip_2_32)
102
103 #endif
104
105 dev_t tegra_dc_ext_devno;
106 struct class *tegra_dc_ext_class;
107 static int head_count;
108
109 struct tegra_dc_ext_flip_win {
110         struct tegra_dc_ext_flip_windowattr     attr;
111         struct tegra_dc_dmabuf                  *handle[TEGRA_DC_NUM_PLANES];
112         dma_addr_t                              phys_addr;
113         dma_addr_t                              phys_addr_u;
114         dma_addr_t                              phys_addr_v;
115         dma_addr_t                              phys_addr_cde;
116         /* field 2 */
117         dma_addr_t                              phys_addr2;
118         dma_addr_t                              phys_addr_u2;
119         dma_addr_t                              phys_addr_v2;
120         u32                                     syncpt_max;
121 #ifdef CONFIG_TEGRA_GRHOST_SYNC
122         struct sync_fence                       *pre_syncpt_fence;
123 #endif
124 };
125
126 struct tegra_dc_ext_flip_data {
127         struct tegra_dc_ext             *ext;
128         struct kthread_work             work;
129         struct tegra_dc_ext_flip_win    win[DC_N_WINDOWS];
130         struct list_head                timestamp_node;
131         int act_window_num;
132         u16 dirty_rect[4];
133         bool dirty_rect_valid;
134         u8 flags;
135         struct tegra_dc_hdr hdr_data;
136         bool hdr_cache_dirty;
137 };
138
139 static int tegra_dc_ext_set_vblank(struct tegra_dc_ext *ext, bool enable);
140 static void tegra_dc_ext_unpin_window(struct tegra_dc_ext_win *win);
141
142 static inline s64 tegra_timespec_to_ns(const struct tegra_timespec *ts)
143 {
144         return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec;
145 }
146
147 static inline int test_bit_u32(int nr, const u32 *addr)
148 {
149         return 1UL & (addr[nr / 32] >> (nr & 31));
150 }
151
152 int tegra_dc_ext_get_num_outputs(void)
153 {
154         /* TODO: decouple output count from head count */
155         return head_count;
156 }
157
158 static int tegra_dc_ext_get_window(struct tegra_dc_ext_user *user,
159                                    unsigned int n)
160 {
161         struct tegra_dc_ext *ext = user->ext;
162         struct tegra_dc_ext_win *win;
163         int ret = 0;
164
165         if ((n >= DC_N_WINDOWS) || !(ext->dc->valid_windows & BIT(n)))
166                 return -EINVAL;
167
168         win = &ext->win[n];
169
170         mutex_lock(&win->lock);
171
172         if (!win->user) {
173                 win->user = user;
174                 win->enabled = false;
175         }
176         else if (win->user != user)
177                 ret = -EBUSY;
178
179         mutex_unlock(&win->lock);
180
181         return ret;
182 }
183
184 static int tegra_dc_ext_put_window(struct tegra_dc_ext_user *user,
185                                    unsigned int n)
186 {
187         struct tegra_dc_ext *ext = user->ext;
188         struct tegra_dc_ext_win *win;
189         int ret = 0;
190
191         if ((n >= DC_N_WINDOWS) || !(ext->dc->valid_windows & BIT(n)))
192                 return -EINVAL;
193
194         win = &ext->win[n];
195
196         mutex_lock(&win->lock);
197
198         if (win->user == user) {
199                 flush_kthread_worker(&win->flip_worker);
200                 win->user = NULL;
201                 win->enabled = false;
202         } else {
203                 ret = -EACCES;
204         }
205
206         mutex_unlock(&win->lock);
207
208         return ret;
209 }
210
211 int tegra_dc_ext_restore(struct tegra_dc_ext *ext)
212 {
213         struct tegra_dc_win *wins[DC_N_WINDOWS];
214         int i, nr_win = 0;
215
216         for_each_set_bit(i, &ext->dc->valid_windows, DC_N_WINDOWS)
217                 if (ext->win[i].enabled) {
218                         wins[nr_win] = tegra_dc_get_window(ext->dc, i);
219                         wins[nr_win++]->flags |= TEGRA_WIN_FLAG_ENABLED;
220                 }
221
222         if (nr_win) {
223                 tegra_dc_update_windows(&wins[0], nr_win, NULL, true);
224                 tegra_dc_sync_windows(&wins[0], nr_win);
225                 tegra_dc_program_bandwidth(ext->dc, true);
226         }
227
228         return nr_win;
229 }
230
231 static void set_enable(struct tegra_dc_ext *ext, bool en)
232 {
233         int i;
234
235         /*
236          * Take all locks to make sure any flip requests or cursor moves are
237          * out of their critical sections
238          */
239         for (i = 0; i < ext->dc->n_windows; i++)
240                 mutex_lock_nested(&ext->win[i].lock, i);
241         mutex_lock(&ext->cursor.lock);
242
243         ext->enabled = en;
244
245         mutex_unlock(&ext->cursor.lock);
246         for (i = ext->dc->n_windows - 1; i >= 0 ; i--)
247                 mutex_unlock(&ext->win[i].lock);
248 }
249
250 void tegra_dc_ext_enable(struct tegra_dc_ext *ext)
251 {
252         set_enable(ext, true);
253 }
254
255 int tegra_dc_ext_disable(struct tegra_dc_ext *ext)
256 {
257         int i;
258         unsigned long int windows = 0;
259
260         set_enable(ext, false);
261
262         /*
263          * Disable vblank requests
264          */
265         tegra_dc_ext_set_vblank(ext, false);
266
267         /*
268          * Flush the flip queue -- note that this must be called with dc->lock
269          * unlocked or else it will hang.
270          */
271         for (i = 0; i < ext->dc->n_windows; i++) {
272                 struct tegra_dc_ext_win *win = &ext->win[i];
273
274                 flush_kthread_worker(&win->flip_worker);
275         }
276
277         /*
278          * Blank all windows owned by dcext driver, unpin buffers that were
279          * removed from screen, and advance syncpt.
280          */
281         if (ext->dc->enabled) {
282                 for (i = 0; i < DC_N_WINDOWS; i++) {
283                         if (ext->win[i].user)
284                                 windows |= BIT(i);
285                 }
286
287                 tegra_dc_blank_wins(ext->dc, windows);
288                 for_each_set_bit(i, &windows, DC_N_WINDOWS) {
289                         tegra_dc_ext_unpin_window(&ext->win[i]);
290                 }
291         }
292
293         return !!windows;
294 }
295
296 static int tegra_dc_ext_check_windowattr(struct tegra_dc_ext *ext,
297                                                 struct tegra_dc_win *win)
298 {
299         u32 *addr;
300         struct tegra_dc *dc = ext->dc;
301
302         addr = tegra_dc_parse_feature(dc, win->idx, GET_WIN_FORMATS);
303         /* Check if the window exists */
304         if (!addr) {
305                 dev_err(&dc->ndev->dev, "window %d feature is not found.\n"
306                                                                 , win->idx);
307                 goto fail;
308         }
309         /* Check the window format */
310         if (!test_bit_u32(win->fmt, addr)) {
311                 dev_err(&dc->ndev->dev,
312                         "Color format of window %d is invalid.\n", win->idx);
313                 goto fail;
314         }
315
316         /* Check window size */
317         addr = tegra_dc_parse_feature(dc, win->idx, GET_WIN_SIZE);
318         if (CHECK_SIZE(win->out_w, addr[MIN_WIDTH], addr[MAX_WIDTH]) ||
319                 CHECK_SIZE(win->out_h, addr[MIN_HEIGHT], addr[MAX_HEIGHT])) {
320                 dev_err(&dc->ndev->dev,
321                         "Size of window %d is invalid with %d wide %d high.\n",
322                         win->idx, win->out_w, win->out_h);
323                 goto fail;
324         }
325
326         if (win->flags & TEGRA_DC_EXT_FLIP_FLAG_BLOCKLINEAR) {
327                 if (win->flags & TEGRA_DC_EXT_FLIP_FLAG_TILED) {
328                         dev_err(&dc->ndev->dev, "Layout cannot be both "
329                                 "blocklinear and tile for window %d.\n",
330                                 win->idx);
331                         goto fail;
332                 }
333
334                 /* TODO: also check current window blocklinear support */
335         }
336
337         if ((win->flags & TEGRA_DC_EXT_FLIP_FLAG_SCAN_COLUMN) &&
338                 !tegra_dc_feature_has_scan_column(dc, win->idx)) {
339                 dev_err(&dc->ndev->dev,
340                         "rotation not supported for window %d.\n", win->idx);
341                 goto fail;
342         }
343
344         /* our interface doesn't support both compression and interlace,
345          * even if the HW can do it. */
346         if ((win->flags & TEGRA_DC_EXT_FLIP_FLAG_COMPRESSED) &&
347                 (win->flags & TEGRA_DC_EXT_FLIP_FLAG_INTERLACE)) {
348                 dev_err(&dc->ndev->dev, "compression and interlace not supported for window %d.\n",
349                         win->idx);
350                 goto fail;
351         }
352
353         return 0;
354 fail:
355         return -EINVAL;
356 }
357
358 static void tegra_dc_ext_set_windowattr_basic(struct tegra_dc_win *win,
359                        const struct tegra_dc_ext_flip_windowattr *flip_win)
360 {
361         win->flags = TEGRA_WIN_FLAG_ENABLED;
362         if (flip_win->blend == TEGRA_DC_EXT_BLEND_PREMULT)
363                 win->flags |= TEGRA_WIN_FLAG_BLEND_PREMULT;
364         else if (flip_win->blend == TEGRA_DC_EXT_BLEND_COVERAGE)
365                 win->flags |= TEGRA_WIN_FLAG_BLEND_COVERAGE;
366         if (flip_win->flags & TEGRA_DC_EXT_FLIP_FLAG_TILED)
367                 win->flags |= TEGRA_WIN_FLAG_TILED;
368         if (flip_win->flags & TEGRA_DC_EXT_FLIP_FLAG_INVERT_H)
369                 win->flags |= TEGRA_WIN_FLAG_INVERT_H;
370         if (flip_win->flags & TEGRA_DC_EXT_FLIP_FLAG_INVERT_V)
371                 win->flags |= TEGRA_WIN_FLAG_INVERT_V;
372         if (flip_win->flags & TEGRA_DC_EXT_FLIP_FLAG_GLOBAL_ALPHA)
373                 win->global_alpha = flip_win->global_alpha;
374         else
375                 win->global_alpha = 255;
376 #if defined(CONFIG_TEGRA_DC_SCAN_COLUMN)
377         if (flip_win->flags & TEGRA_DC_EXT_FLIP_FLAG_SCAN_COLUMN)
378                 win->flags |= TEGRA_WIN_FLAG_SCAN_COLUMN;
379 #endif
380 #if defined(CONFIG_TEGRA_DC_BLOCK_LINEAR)
381         if (flip_win->flags & TEGRA_DC_EXT_FLIP_FLAG_BLOCKLINEAR) {
382                 win->flags |= TEGRA_WIN_FLAG_BLOCKLINEAR;
383                 win->block_height_log2 = flip_win->block_height_log2;
384         }
385 #endif
386 #if defined(CONFIG_TEGRA_DC_INTERLACE)
387         if (flip_win->flags & TEGRA_DC_EXT_FLIP_FLAG_INTERLACE)
388                 win->flags |= TEGRA_WIN_FLAG_INTERLACE;
389 #endif
390
391 #if defined(CONFIG_TEGRA_DC_CDE)
392         if (flip_win->flags & TEGRA_DC_EXT_FLIP_FLAG_COMPRESSED) {
393                 win->cde.zbc_color = flip_win->cde.zbc_color;
394                 win->cde.offset_x = flip_win->cde.offset_x;
395                 win->cde.offset_y = flip_win->cde.offset_y;
396                 win->cde.ctb_entry = 0x02;
397         }
398 #endif
399
400         win->fmt = flip_win->pixformat;
401         win->x.full = flip_win->x;
402         win->y.full = flip_win->y;
403         win->w.full = flip_win->w;
404         win->h.full = flip_win->h;
405         /* XXX verify that this doesn't go outside display's active region */
406         win->out_x = flip_win->out_x;
407         win->out_y = flip_win->out_y;
408         win->out_w = flip_win->out_w;
409         win->out_h = flip_win->out_h;
410         win->z = flip_win->z;
411
412         win->stride = flip_win->stride;
413         win->stride_uv = flip_win->stride_uv;
414 }
415
416
417
418 static int tegra_dc_ext_set_windowattr(struct tegra_dc_ext *ext,
419                                struct tegra_dc_win *win,
420                                const struct tegra_dc_ext_flip_win *flip_win)
421 {
422         int err = 0;
423         struct tegra_dc_ext_win *ext_win = &ext->win[win->idx];
424         s64 timestamp_ns;
425         struct tegra_vrr *vrr = ext->dc->out->vrr;
426
427         if (flip_win->handle[TEGRA_DC_Y] == NULL) {
428                 win->flags = 0;
429                 memset(ext_win->cur_handle, 0, sizeof(ext_win->cur_handle));
430                 return 0;
431         }
432
433         tegra_dc_ext_set_windowattr_basic(win, &flip_win->attr);
434
435         memcpy(ext_win->cur_handle, flip_win->handle,
436                sizeof(ext_win->cur_handle));
437
438         /* XXX verify that this won't read outside of the surface */
439         win->phys_addr = flip_win->phys_addr + flip_win->attr.offset;
440
441         win->phys_addr_u = flip_win->handle[TEGRA_DC_U] ?
442                 flip_win->phys_addr_u : flip_win->phys_addr;
443         win->phys_addr_u += flip_win->attr.offset_u;
444
445         win->phys_addr_v = flip_win->handle[TEGRA_DC_V] ?
446                 flip_win->phys_addr_v : flip_win->phys_addr;
447         win->phys_addr_v += flip_win->attr.offset_v;
448
449 #if defined(CONFIG_TEGRA_DC_INTERLACE)
450         if (ext->dc->mode.vmode == FB_VMODE_INTERLACED) {
451                 if (flip_win->attr.flags & TEGRA_DC_EXT_FLIP_FLAG_INTERLACE) {
452                         win->phys_addr2 = flip_win->phys_addr +
453                                 flip_win->attr.offset2;
454
455                         win->phys_addr_u2 = flip_win->handle[TEGRA_DC_U] ?
456                                 flip_win->phys_addr_u : flip_win->phys_addr;
457
458                         win->phys_addr_u2 += flip_win->attr.offset_u2;
459
460                         win->phys_addr_v2 = flip_win->handle[TEGRA_DC_V] ?
461                                 flip_win->phys_addr_v : flip_win->phys_addr;
462                         win->phys_addr_v2 += flip_win->attr.offset_v2;
463                 } else {
464                         win->phys_addr2 = flip_win->phys_addr;
465
466                         win->phys_addr_u2 = flip_win->handle[TEGRA_DC_U] ?
467                                 flip_win->phys_addr_u : flip_win->phys_addr;
468
469                         win->phys_addr_v2 = flip_win->handle[TEGRA_DC_V] ?
470                                 flip_win->phys_addr_v : flip_win->phys_addr;
471                 }
472         }
473 #endif
474
475 #if defined(CONFIG_TEGRA_DC_CDE)
476         if (flip_win->attr.flags & TEGRA_DC_EXT_FLIP_FLAG_COMPRESSED)
477                 win->cde.cde_addr =
478                         flip_win->phys_addr_cde + flip_win->attr.cde.offset;
479         else
480                 win->cde.cde_addr = 0;
481 #endif
482
483         err = tegra_dc_ext_check_windowattr(ext, win);
484         if (err < 0)
485                 dev_err(&ext->dc->ndev->dev,
486                                 "Window atrributes are invalid.\n");
487
488 #ifdef CONFIG_TEGRA_GRHOST_SYNC
489         if (flip_win->pre_syncpt_fence) {
490                 TRACE_NAME_BEGIN(pre_snycpt);
491                 sync_fence_wait(flip_win->pre_syncpt_fence, 5000);
492                 sync_fence_put(flip_win->pre_syncpt_fence);
493                 TRACE_NAME_END(pre_snycpt);
494         } else
495 #endif
496         if ((s32)flip_win->attr.pre_syncpt_id >= 0) {
497                 TRACE_NAME_BEGIN(snycpt_wait);
498                 nvhost_syncpt_wait_timeout_ext(ext->dc->ndev,
499                                 flip_win->attr.pre_syncpt_id,
500                                 flip_win->attr.pre_syncpt_val,
501                                 msecs_to_jiffies(5000), NULL, NULL);
502                 TRACE_NAME_END(snycpt_wait);
503         }
504
505         if (err < 0)
506                 return err;
507
508         if (tegra_platform_is_silicon()) {
509                 timestamp_ns = tegra_timespec_to_ns(&flip_win->attr.timestamp);
510
511                 if (timestamp_ns) {
512                         /* XXX: Should timestamping be overridden by "no_vsync"
513                          * flag */
514                         if (vrr && vrr->enable) {
515                                 struct timespec tm;
516                                 s64 now_ns = 0;
517                                 s32 sleep_us = 0;
518                                 ktime_get_ts(&tm);
519                                 now_ns = timespec_to_ns(&tm);
520                                 sleep_us = (s32)div_s64(timestamp_ns -
521                                         now_ns, 1000ll);
522
523                                 if (sleep_us > TEGRA_DC_TS_MAX_DELAY_US)
524                                         sleep_us = TEGRA_DC_TS_MAX_DELAY_US;
525
526                                 TRACE_NAME_BEGIN(ts_wait);
527                                 if (sleep_us > 0)
528                                         usleep_range(sleep_us, sleep_us +
529                                                 TEGRA_DC_TS_SLACK_US);
530                                 TRACE_NAME_END(ts_wait);
531                         } else {
532                                 tegra_dc_config_frame_end_intr(win->dc, true);
533                                 err = wait_event_interruptible(
534                                         win->dc->timestamp_wq,
535                                         tegra_dc_is_within_n_vsync(win->dc,
536                                                 timestamp_ns));
537                                 tegra_dc_config_frame_end_intr(win->dc, false);
538                         }
539                 }
540         }
541
542         return err;
543 }
544
545 static int tegra_dc_ext_should_show_background(
546                 struct tegra_dc_ext_flip_data *data,
547                 int win_num)
548 {
549         struct tegra_dc *dc = data->ext->dc;
550         int yuv_flag = dc->mode.vmode & FB_VMODE_YUV_MASK;
551         int i;
552
553         if (!dc->yuv_bypass || yuv_flag != (FB_VMODE_Y420 | FB_VMODE_Y30))
554                 return false;
555
556         for (i = 0; i < win_num; i++) {
557                 struct tegra_dc_ext_flip_win *flip_win = &data->win[i];
558                 int index = flip_win->attr.index;
559
560                 if (index < 0 || !test_bit(index, &dc->valid_windows))
561                         continue;
562
563                 if (flip_win->handle[TEGRA_DC_Y] == NULL)
564                         continue;
565
566                 /* Bypass expects only a single window, thus it is enough to
567                  * inspect the first enabled window.
568                  *
569                  * Full screen input surface for YUV420 10-bit 4k has 2400x2160
570                  * active area. dc->mode is already adjusted to this dimension.
571                  */
572                 if (flip_win->attr.out_x > 0 ||
573                     flip_win->attr.out_y > 0 ||
574                     flip_win->attr.out_w != dc->mode.h_active ||
575                     flip_win->attr.out_h != dc->mode.v_active)
576                         return true;
577         }
578
579         return false;
580 }
581
582 static int tegra_dc_ext_get_background(struct tegra_dc_ext *ext,
583                 struct tegra_dc_win *win)
584 {
585         struct tegra_dc *dc = ext->dc;
586         u32 active_width = dc->mode.h_active;
587         u32 active_height = dc->mode.v_active;
588
589         *win = *tegra_fb_get_blank_win(dc->fb);
590
591         win->flags |= TEGRA_WIN_FLAG_ENABLED;
592         win->fmt = TEGRA_WIN_FMT_B8G8R8A8;
593         win->x.full = dfixed_const(0);
594         win->y.full = dfixed_const(0);
595         win->h.full = dfixed_const(1);
596         win->w.full = dfixed_const(active_width);
597         win->out_x = 0;
598         win->out_y = 0;
599         win->out_w = active_width;
600         win->out_h = active_height;
601         win->z = 0xff;
602
603         return 0;
604 }
605
606 static int tegra_dc_ext_set_vblank(struct tegra_dc_ext *ext, bool enable)
607 {
608         struct tegra_dc *dc;
609         int ret = 0;
610
611         if (ext->vblank_enabled == enable)
612                 return 0;
613
614         dc = ext->dc;
615
616         if (enable)
617                 ret = tegra_dc_vsync_enable(dc);
618         else if (ext->vblank_enabled)
619                 tegra_dc_vsync_disable(dc);
620
621         if (!ret) {
622                 ext->vblank_enabled = enable;
623                 return 0;
624         }
625         return 1;
626 }
627
628 static void tegra_dc_ext_unpin_handles(struct tegra_dc_dmabuf *unpin_handles[],
629                                        int nr_unpin)
630 {
631         int i;
632
633         for (i = 0; i < nr_unpin; i++) {
634                 dma_buf_unmap_attachment(unpin_handles[i]->attach,
635                         unpin_handles[i]->sgt, DMA_TO_DEVICE);
636                 dma_buf_detach(unpin_handles[i]->buf,
637                                unpin_handles[i]->attach);
638                 dma_buf_put(unpin_handles[i]->buf);
639                 kfree(unpin_handles[i]);
640         }
641 }
642
643 static void tegra_dc_ext_smooth_apc(struct tegra_vrr *vrr)
644 {
645         /* Smooth actual present cadence when vrr is enabled
646          */
647         if (vrr && vrr->enable) {
648                 s32 sleep_us = TEGRA_DC_SMOOTHING_LATENCY_US;
649
650                 if (vrr->flip_interval_us > 0 &&
651                         vrr->flip_interval_us < TEGRA_DC_SMOOTHING_MAX_APC_US) {
652                         struct timespec tm;
653                         s64 now_us = 0;
654                         s64 next_desired_present = 0;
655
656                         getnstimeofday(&tm);
657                         now_us = (s64)tm.tv_sec * 1000000 + tm.tv_nsec / 1000;
658
659                         next_desired_present = vrr->last_flip_us +
660                                 vrr->flip_interval_us;
661                         sleep_us = next_desired_present - now_us;
662
663                         /* Smooth our sleep time towards 4ms.  This is required
664                          * to smoothly move us back to 4ms of latency added
665                          * when framerate is changing.
666                          */
667                         sleep_us = sleep_us * TEGRA_DC_SMOOTHING_CR_PC / 100 +
668                                 TEGRA_DC_SMOOTHING_LATENCY_US *
669                                 (100 - TEGRA_DC_SMOOTHING_CR_PC) / 100;
670
671                         if (sleep_us < 0)
672                                 sleep_us = 0;
673                         if (sleep_us > TEGRA_DC_SMOOTHING_LATENCY_US * 2)
674                                 sleep_us = TEGRA_DC_SMOOTHING_LATENCY_US * 2;
675                 }
676
677                 TRACE_NAME_BEGIN(smooth_wait);
678                 usleep_range(sleep_us, sleep_us + TEGRA_DC_SMOOTHING_SLACK_US);
679                 TRACE_NAME_END(smooth_wait);
680         }
681 }
682
683 static void tegra_dc_ext_flip_worker(struct kthread_work *work)
684 {
685         struct tegra_dc_ext_flip_data *data =
686                 container_of(work, struct tegra_dc_ext_flip_data, work);
687         int win_num = data->act_window_num;
688         struct tegra_dc_ext *ext = data->ext;
689         struct tegra_dc_win *wins[DC_N_WINDOWS];
690         struct tegra_dc_win *blank_win;
691         struct tegra_dc_dmabuf *unpin_handles[DC_N_WINDOWS *
692                                                TEGRA_DC_NUM_PLANES];
693         struct tegra_dc_dmabuf *old_handle;
694         struct tegra_dc *dc = ext->dc;
695         struct tegra_vrr *vrr = ext->dc->out->vrr;
696         int i, nr_unpin = 0, nr_win = 0;
697         bool skip_flip = false;
698         bool wait_for_vblank = false;
699         bool show_background =
700                 tegra_dc_ext_should_show_background(data, win_num);
701         BEGIN_TRACE();
702         blank_win = kzalloc(sizeof(*blank_win), GFP_KERNEL);
703         if (!blank_win)
704                 dev_err(&ext->dc->ndev->dev, "Failed to allocate blank_win.\n");
705
706         BUG_ON(win_num > DC_N_WINDOWS);
707         for (i = 0; i < win_num; i++) {
708                 struct tegra_dc_ext_flip_win *flip_win = &data->win[i];
709                 int index = flip_win->attr.index;
710                 struct tegra_dc_win *win;
711                 struct tegra_dc_ext_win *ext_win;
712                 struct tegra_dc_ext_flip_data *temp = NULL;
713                 s64 head_timestamp = 0;
714                 int j = 0;
715
716                 if (index < 0 || !test_bit(index, &dc->valid_windows))
717                         continue;
718
719                 win = tegra_dc_get_window(dc, index);
720                 if (!win)
721                         continue;
722                 ext_win = &ext->win[index];
723
724                 if (!(atomic_dec_and_test(&ext_win->nr_pending_flips)) &&
725                         (flip_win->attr.flags & TEGRA_DC_EXT_FLIP_FLAG_CURSOR))
726                         skip_flip = true;
727
728                 mutex_lock(&ext_win->queue_lock);
729                 list_for_each_entry(temp, &ext_win->timestamp_queue,
730                                 timestamp_node) {
731                         if (!tegra_platform_is_silicon())
732                                 continue;
733                         if (j == 0) {
734                                 if (unlikely(temp != data))
735                                         dev_err(&win->dc->ndev->dev,
736                                                         "kthread worker did NOT dequeue head!!!");
737                                 else
738                                         head_timestamp = tegra_timespec_to_ns(
739                                                 &flip_win->attr.timestamp);
740                         } else {
741                                 s64 timestamp = tegra_timespec_to_ns(
742                                         &temp->win[i].attr.timestamp);
743
744                                 skip_flip = !tegra_dc_does_vsync_separate(dc,
745                                                 timestamp, head_timestamp);
746                                 /* Look ahead only one flip */
747                                 break;
748                         }
749                         j++;
750                 }
751                 if (!list_empty(&ext_win->timestamp_queue))
752                         list_del(&data->timestamp_node);
753                 mutex_unlock(&ext_win->queue_lock);
754
755                 /* protect cur_handle from concurrent use */
756                 mutex_lock(&ext_win->unpin_dma_lock);
757                 if (skip_flip)
758                         old_handle = flip_win->handle[TEGRA_DC_Y];
759                 else
760                         old_handle = ext_win->cur_handle[TEGRA_DC_Y];
761
762                 if (old_handle) {
763                         int j;
764                         for (j = 0; j < TEGRA_DC_NUM_PLANES; j++) {
765                                 if (skip_flip)
766                                         old_handle = flip_win->handle[j];
767                                 else
768                                         old_handle = ext_win->cur_handle[j];
769
770                                 if (!old_handle)
771                                         continue;
772
773                                 unpin_handles[nr_unpin++] = old_handle;
774                         }
775                         /* before unpin, zero out the cur_handle */
776                         if (skip_flip)
777                                 memset(flip_win->handle, 0,
778                                                 sizeof(flip_win->handle));
779                         else
780                                 memset(ext_win->cur_handle, 0,
781                                                 sizeof(ext_win->cur_handle));
782                 }
783
784 #ifdef CONFIG_TEGRA_CSC
785                 if ((data->win[i].attr.flags & TEGRA_DC_EXT_FLIP_FLAG_UPDATE_CSC)
786                                 && !dc->yuv_bypass) {
787                         win->csc.yof = data->win[i].attr.csc.yof;
788                         win->csc.kyrgb = data->win[i].attr.csc.kyrgb;
789                         win->csc.kur = data->win[i].attr.csc.kur;
790                         win->csc.kug = data->win[i].attr.csc.kug;
791                         win->csc.kub = data->win[i].attr.csc.kub;
792                         win->csc.kvr = data->win[i].attr.csc.kvr;
793                         win->csc.kvg = data->win[i].attr.csc.kvg;
794                         win->csc.kvb = data->win[i].attr.csc.kvb;
795                         win->csc_dirty = true;
796                 }
797 #endif
798
799                 if (!skip_flip)
800                         tegra_dc_ext_set_windowattr(ext, win, &data->win[i]);
801
802                 mutex_unlock(&ext_win->unpin_dma_lock);
803
804                 if (flip_win->attr.swap_interval && !no_vsync)
805                         wait_for_vblank = true;
806
807                 ext_win->enabled = !!(win->flags & TEGRA_WIN_FLAG_ENABLED);
808
809                 /* Hijack first disabled, scaling capable window to host
810                  * the background pattern.
811                  */
812                 if (blank_win && !ext_win->enabled && show_background &&
813                         tegra_dc_feature_has_scaling(ext->dc, win->idx)) {
814                         tegra_dc_ext_get_background(ext, blank_win);
815                         blank_win->idx = win->idx;
816                         wins[nr_win++] = blank_win;
817                         show_background = false;
818                 } else {
819                         wins[nr_win++] = win;
820                 }
821         }
822
823         tegra_dc_ext_smooth_apc(vrr);
824
825         /* YUV packing consumes only one window, thus there must have been
826          * free window which can host background pattern.
827          */
828         BUG_ON(show_background);
829
830         trace_sync_wt_ovr_syncpt_upd((data->win[win_num-1]).syncpt_max);
831
832         if (dc->enabled && !skip_flip)
833                 tegra_dc_set_hdr(dc, &data->hdr_data, data->hdr_cache_dirty);
834
835         if (dc->enabled && !skip_flip) {
836                 dc->blanked = false;
837                 if (dc->out_ops && dc->out_ops->vrr_enable)
838                                 dc->out_ops->vrr_enable(dc,
839                                         data->flags &
840                                         TEGRA_DC_EXT_FLIP_HEAD_FLAG_VRR_MODE);
841
842                 TRACE_NAME_BEGIN(tegra_dc_update_windows);
843                 tegra_dc_update_windows(wins, nr_win,
844                         data->dirty_rect_valid ? data->dirty_rect : NULL,
845                         wait_for_vblank);
846                 TRACE_NAME_END(tegra_dc_update_windows);
847                 /* TODO: implement swapinterval here */
848                 TRACE_NAME_BEGIN(tegra_dc_sync_windows);
849                 tegra_dc_sync_windows(wins, nr_win);
850                 TRACE_NAME_END(tegra_dc_sync_windows);
851                 trace_scanout_syncpt_upd((data->win[win_num-1]).syncpt_max);
852                 if (dc->out->vrr)
853                         trace_scanout_vrr_stats((data->win[win_num-1]).syncpt_max
854                                                         , dc->out->vrr->dcb);
855                 tegra_dc_program_bandwidth(dc, true);
856                 if (!tegra_dc_has_multiple_dc())
857                         tegra_dc_call_flip_callback();
858         }
859
860         if (!skip_flip) {
861                 for (i = 0; i < win_num; i++) {
862                         struct tegra_dc_ext_flip_win *flip_win = &data->win[i];
863                         int index = flip_win->attr.index;
864
865                         if (index < 0 ||
866                                 !test_bit(index, &dc->valid_windows))
867                                 continue;
868
869                         tegra_dc_incr_syncpt_min(dc, index,
870                                         flip_win->syncpt_max);
871                 }
872         }
873
874         /* unpin and deref previous front buffers */
875         tegra_dc_ext_unpin_handles(unpin_handles, nr_unpin);
876 #ifdef CONFIG_ANDROID
877         /* now DC has submitted buffer for display, try to release fbmem */
878         tegra_fb_release_fbmem(ext->dc->fb);
879 #endif
880         kfree(data);
881         kfree(blank_win);
882         END_TRACE();
883 }
884
885 static int lock_windows_for_flip(struct tegra_dc_ext_user *user,
886                                  struct tegra_dc_ext_flip_windowattr *win,
887                                  int win_num)
888 {
889         struct tegra_dc_ext *ext = user->ext;
890         u8 idx_mask = 0;
891         int i;
892
893         BUG_ON(win_num > DC_N_WINDOWS);
894         for (i = 0; i < win_num; i++) {
895                 int index = win[i].index;
896
897                 if (index < 0 || !test_bit(index, &ext->dc->valid_windows))
898                         continue;
899
900                 idx_mask |= BIT(index);
901         }
902
903         for (i = 0; i < win_num; i++) {
904                 struct tegra_dc_ext_win *win;
905
906                 if (!(idx_mask & BIT(i)))
907                         continue;
908
909                 win = &ext->win[i];
910
911                 mutex_lock_nested(&win->lock, i);
912
913                 if (win->user != user)
914                         goto fail_unlock;
915         }
916
917         return 0;
918
919 fail_unlock:
920         do {
921                 if (!(idx_mask & BIT(i)))
922                         continue;
923
924                 mutex_unlock(&ext->win[i].lock);
925         } while (i--);
926
927         return -EACCES;
928 }
929
930 static void unlock_windows_for_flip(struct tegra_dc_ext_user *user,
931                                 struct tegra_dc_ext_flip_windowattr *win,
932                                 int win_num)
933 {
934         struct tegra_dc_ext *ext = user->ext;
935         u8 idx_mask = 0;
936         int i;
937
938         BUG_ON(win_num > DC_N_WINDOWS);
939         for (i = 0; i < win_num; i++) {
940                 int index = win[i].index;
941
942                 if (index < 0 || !test_bit(index, &ext->dc->valid_windows))
943                         continue;
944
945                 idx_mask |= BIT(index);
946         }
947         for (i = win_num - 1; i >= 0; i--) {
948                 if (!(idx_mask & BIT(i)))
949                         continue;
950
951                 mutex_unlock(&ext->win[i].lock);
952         }
953 }
954
955 static int sanitize_flip_args(struct tegra_dc_ext_user *user,
956                                 struct tegra_dc_ext_flip_windowattr *win,
957                                 int win_num, __u16 **dirty_rect)
958 {
959         int i, used_windows = 0;
960         struct tegra_dc *dc = user->ext->dc;
961
962         if (win_num > DC_N_WINDOWS)
963                 return -EINVAL;
964
965         for (i = 0; i < win_num; i++) {
966                 int index = win[i].index;
967
968                 if (index < 0)
969                         continue;
970
971                 if (index >= DC_N_WINDOWS ||
972                         !test_bit(index, &dc->valid_windows))
973                         return -EINVAL;
974
975                 if (used_windows & BIT(index))
976                         return -EINVAL;
977
978                 used_windows |= BIT(index);
979         }
980
981         if (!used_windows)
982                 return -EINVAL;
983
984         if (*dirty_rect) {
985                 unsigned int xoff = (*dirty_rect)[0];
986                 unsigned int yoff = (*dirty_rect)[1];
987                 unsigned int width = (*dirty_rect)[2];
988                 unsigned int height = (*dirty_rect)[3];
989
990                 if ((!width && !height) ||
991                         dc->mode.vmode == FB_VMODE_INTERLACED ||
992                         !dc->out_ops ||
993                         !dc->out_ops->partial_update ||
994                         (!xoff && !yoff &&
995                         (width == dc->mode.h_active) &&
996                         (height == dc->mode.v_active))) {
997                         /* Partial update undesired, unsupported,
998                          * or dirty_rect covers entire frame. */
999                         *dirty_rect = NULL;
1000                 } else {
1001                         if (!width || !height ||
1002                                 (xoff + width) > dc->mode.h_active ||
1003                                 (yoff + height) > dc->mode.v_active)
1004                                 return -EINVAL;
1005
1006                         /* Constraint 7: H/V_DISP_ACTIVE >= 16.
1007                          * Make sure the minimal size of dirty region is 16*16.
1008                          * If not, extend the dirty region. */
1009                         if (width < 16) {
1010                                 width = (*dirty_rect)[2] = 16;
1011                                 if (xoff + width > dc->mode.h_active)
1012                                         (*dirty_rect)[0] = dc->mode.h_active -
1013                                                 width;
1014                         }
1015                         if (height < 16) {
1016                                 height = (*dirty_rect)[3] = 16;
1017                                 if (yoff + height > dc->mode.v_active)
1018                                         (*dirty_rect)[1] = dc->mode.v_active -
1019                                                 height;
1020                         }
1021                 }
1022         }
1023
1024         return 0;
1025 }
1026
1027 static int tegra_dc_ext_pin_windows(struct tegra_dc_ext_user *user,
1028                                 struct tegra_dc_ext_flip_windowattr *wins,
1029                                 int win_num,
1030                                 struct tegra_dc_ext_flip_win *flip_wins,
1031                                 bool *has_timestamp,
1032                                 bool syncpt_fd)
1033 {
1034         int i, ret;
1035         struct tegra_dc *dc = user->ext->dc;
1036
1037         for (i = 0; i < win_num; i++) {
1038                 struct tegra_dc_ext_flip_win *flip_win = &flip_wins[i];
1039                 int index = wins[i].index;
1040
1041                 memcpy(&flip_win->attr, &wins[i], sizeof(flip_win->attr));
1042                 if (has_timestamp && tegra_timespec_to_ns(
1043                         &flip_win->attr.timestamp))
1044                         *has_timestamp = true;
1045
1046                 if (index < 0 || !test_bit(index, &dc->valid_windows))
1047                         continue;
1048
1049                 ret = tegra_dc_ext_pin_window(user, flip_win->attr.buff_id,
1050                                               &flip_win->handle[TEGRA_DC_Y],
1051                                               &flip_win->phys_addr);
1052                 if (ret)
1053                         return ret;
1054
1055                 if (flip_win->attr.buff_id_u) {
1056                         ret = tegra_dc_ext_pin_window(user,
1057                                               flip_win->attr.buff_id_u,
1058                                               &flip_win->handle[TEGRA_DC_U],
1059                                               &flip_win->phys_addr_u);
1060                         if (ret)
1061                                 return ret;
1062                 } else {
1063                         flip_win->handle[TEGRA_DC_U] = NULL;
1064                         flip_win->phys_addr_u = 0;
1065                 }
1066
1067                 if (flip_win->attr.buff_id_v) {
1068                         ret = tegra_dc_ext_pin_window(user,
1069                                               flip_win->attr.buff_id_v,
1070                                               &flip_win->handle[TEGRA_DC_V],
1071                                               &flip_win->phys_addr_v);
1072                         if (ret)
1073                                 return ret;
1074                 } else {
1075                         flip_win->handle[TEGRA_DC_V] = NULL;
1076                         flip_win->phys_addr_v = 0;
1077                 }
1078
1079                 if ((flip_win->attr.flags & TEGRA_DC_EXT_FLIP_FLAG_COMPRESSED)) {
1080 #if defined(CONFIG_TEGRA_DC_CDE)
1081                         /* use buff_id of the main surface when cde is 0 */
1082                         __u32 cde_buff_id = flip_win->attr.cde.buff_id;
1083                         if (!cde_buff_id)
1084                                 cde_buff_id = flip_win->attr.buff_id;
1085                         ret = tegra_dc_ext_pin_window(user,
1086                                               cde_buff_id,
1087                                               &flip_win->handle[TEGRA_DC_CDE],
1088                                               &flip_win->phys_addr_cde);
1089                         if (ret)
1090                                 return ret;
1091 #else
1092                         return -EINVAL; /* not supported */
1093 #endif
1094                 } else {
1095                         flip_win->handle[TEGRA_DC_CDE] = NULL;
1096                         flip_win->phys_addr_cde = 0;
1097                 }
1098
1099                 if (syncpt_fd) {
1100                         if (flip_win->attr.pre_syncpt_fd >= 0) {
1101 #ifdef CONFIG_TEGRA_GRHOST_SYNC
1102                                 flip_win->pre_syncpt_fence = sync_fence_fdget(
1103                                         flip_win->attr.pre_syncpt_fd);
1104 #else
1105                                 BUG();
1106 #endif
1107                         } else {
1108                                 flip_win->attr.pre_syncpt_id = NVSYNCPT_INVALID;
1109                         }
1110                 }
1111         }
1112
1113         return 0;
1114 }
1115
1116 static void tegra_dc_ext_unpin_window(struct tegra_dc_ext_win *win)
1117 {
1118         struct tegra_dc_dmabuf *unpin_handles[TEGRA_DC_NUM_PLANES];
1119         int nr_unpin = 0;
1120
1121         /* protect cur_handle from concurrent use */
1122         mutex_lock(&win->unpin_dma_lock);
1123         if (win->cur_handle[TEGRA_DC_Y]) {
1124                 int j;
1125                 for (j = 0; j < TEGRA_DC_NUM_PLANES; j++) {
1126                         if (win->cur_handle[j])
1127                                 unpin_handles[nr_unpin++] = win->cur_handle[j];
1128                 }
1129                 memset(win->cur_handle, 0, sizeof(win->cur_handle));
1130         }
1131         mutex_unlock(&win->unpin_dma_lock);
1132
1133         tegra_dc_ext_unpin_handles(unpin_handles, nr_unpin);
1134 }
1135
1136 static void tegra_dc_ext_read_user_data(struct tegra_dc_ext_flip_data *data,
1137                         struct tegra_dc_ext_flip_user_data *flip_user_data,
1138                         int nr_user_data)
1139 {
1140         int i = 0;
1141
1142         for (i = 0; i < nr_user_data; i++) {
1143                 struct tegra_dc_hdr *hdr;
1144                 struct tegra_dc_ext_hdr *info;
1145                 switch (flip_user_data[0].data_type) {
1146                 case TEGRA_DC_EXT_FLIP_USER_DATA_HDR_DATA:
1147                         hdr = &data->hdr_data;
1148                         info = &flip_user_data[i].hdr_info;
1149                         if (flip_user_data[i].flags &
1150                                 TEGRA_DC_EXT_FLIP_FLAG_HDR_ENABLE)
1151                                 hdr->enabled = true;
1152                         if (flip_user_data[i].flags &
1153                                 TEGRA_DC_EXT_FLIP_FLAG_HDR_DATA_UPDATED) {
1154                                 data->hdr_cache_dirty = true;
1155                                 hdr->eotf = info->eotf;
1156                                 hdr->static_metadata_id =
1157                                                 info->static_metadata_id;
1158                                 memcpy(hdr->static_metadata,
1159                                         info->static_metadata,
1160                                         sizeof(hdr->static_metadata));
1161                         }
1162                         break;
1163                 default:
1164                         dev_err(&data->ext->dc->ndev->dev,
1165                                 "Invalid FLIP_USER_DATA_TYPE\n");
1166                 }
1167         }
1168         return;
1169 }
1170
1171 static int tegra_dc_ext_flip(struct tegra_dc_ext_user *user,
1172                              struct tegra_dc_ext_flip_windowattr *win,
1173                              int win_num,
1174                              __u32 *syncpt_id, __u32 *syncpt_val,
1175                              int *syncpt_fd, __u16 *dirty_rect, u8 flip_flags,
1176                              struct tegra_dc_ext_flip_user_data *flip_user_data,
1177                              int nr_user_data)
1178 {
1179         struct tegra_dc_ext *ext = user->ext;
1180         struct tegra_dc_ext_flip_data *data;
1181         int work_index = -1;
1182         __u32 post_sync_val = 0, post_sync_id = NVSYNCPT_INVALID;
1183         int i, ret = 0;
1184         bool has_timestamp = false;
1185
1186         /* If display has been disconnected return with error. */
1187         if (!ext->dc->connected)
1188                 return -1;
1189
1190         ret = sanitize_flip_args(user, win, win_num, &dirty_rect);
1191         if (ret)
1192                 return ret;
1193
1194         data = kzalloc(sizeof(*data), GFP_KERNEL);
1195         if (!data)
1196                 return -ENOMEM;
1197
1198         init_kthread_work(&data->work, &tegra_dc_ext_flip_worker);
1199         data->ext = ext;
1200         data->act_window_num = win_num;
1201         if (dirty_rect) {
1202                 memcpy(data->dirty_rect, dirty_rect, sizeof(data->dirty_rect));
1203                 data->dirty_rect_valid = true;
1204         }
1205
1206         BUG_ON(win_num > DC_N_WINDOWS);
1207
1208         ret = tegra_dc_ext_pin_windows(user, win, win_num,
1209                                      data->win, &has_timestamp,
1210                                      syncpt_fd != NULL);
1211         if (ret)
1212                 goto fail_pin;
1213
1214         ret = lock_windows_for_flip(user, win, win_num);
1215         if (ret)
1216                 goto fail_pin;
1217
1218         if (!ext->enabled) {
1219                 ret = -ENXIO;
1220                 goto unlock;
1221         }
1222
1223         tegra_dc_ext_read_user_data(data, flip_user_data, nr_user_data);
1224
1225         BUG_ON(win_num > DC_N_WINDOWS);
1226         for (i = 0; i < win_num; i++) {
1227                 u32 syncpt_max;
1228                 int index = win[i].index;
1229                 struct tegra_dc_ext_win *ext_win;
1230
1231                 if (index < 0 || !test_bit(index, &ext->dc->valid_windows))
1232                         continue;
1233
1234                 ext_win = &ext->win[index];
1235
1236                 syncpt_max = tegra_dc_incr_syncpt_max(ext->dc, index);
1237
1238                 data->win[i].syncpt_max = syncpt_max;
1239
1240                 /*
1241                  * Any of these windows' syncpoints should be equivalent for
1242                  * the client, so we just send back an arbitrary one of them
1243                  */
1244                 post_sync_val = syncpt_max;
1245                 post_sync_id = tegra_dc_get_syncpt_id(ext->dc, index);
1246
1247                 work_index = index;
1248
1249                 atomic_inc(&ext->win[work_index].nr_pending_flips);
1250         }
1251         if (work_index < 0) {
1252                 ret = -EINVAL;
1253                 goto unlock;
1254         }
1255 #ifdef CONFIG_ANDROID
1256         work_index = 0;
1257 #endif
1258
1259         if (syncpt_fd) {
1260                 if (post_sync_id != NVSYNCPT_INVALID) {
1261                         ret = nvhost_syncpt_create_fence_single_ext(
1262                                         ext->dc->ndev, post_sync_id,
1263                                         post_sync_val + 1, "flip-fence",
1264                                         syncpt_fd);
1265                         if (ret) {
1266                                 dev_err(&ext->dc->ndev->dev,
1267                                         "Failed creating fence err:%d\n", ret);
1268                                 goto unlock;
1269                         }
1270                 }
1271         } else {
1272                 *syncpt_val = post_sync_val;
1273                 *syncpt_id = post_sync_id;
1274         }
1275
1276         trace_flip_rcvd_syncpt_upd(post_sync_val);
1277
1278         /* Avoid queueing timestamps on Android, to disable skipping flips */
1279 #ifndef CONFIG_ANDROID
1280         if (has_timestamp) {
1281                 mutex_lock(&ext->win[work_index].queue_lock);
1282                 list_add_tail(&data->timestamp_node, &ext->win[work_index].timestamp_queue);
1283                 mutex_unlock(&ext->win[work_index].queue_lock);
1284         }
1285 #endif
1286         data->flags = flip_flags;
1287         queue_kthread_work(&ext->win[work_index].flip_worker, &data->work);
1288
1289         unlock_windows_for_flip(user, win, win_num);
1290
1291         return 0;
1292
1293 unlock:
1294         unlock_windows_for_flip(user, win, win_num);
1295
1296 fail_pin:
1297
1298         for (i = 0; i < win_num; i++) {
1299                 int j;
1300                 for (j = 0; j < TEGRA_DC_NUM_PLANES; j++) {
1301                         if (!data->win[i].handle[j])
1302                                 continue;
1303
1304                         dma_buf_unmap_attachment(data->win[i].handle[j]->attach,
1305                                 data->win[i].handle[j]->sgt, DMA_TO_DEVICE);
1306                         dma_buf_detach(data->win[i].handle[j]->buf,
1307                                 data->win[i].handle[j]->attach);
1308                         dma_buf_put(data->win[i].handle[j]->buf);
1309                         kfree(data->win[i].handle[j]);
1310                 }
1311         }
1312         kfree(data);
1313
1314         return ret;
1315 }
1316
1317 #if defined(CONFIG_TEGRA_CSC)
1318 static int tegra_dc_ext_set_csc(struct tegra_dc_ext_user *user,
1319                                 struct tegra_dc_ext_csc *new_csc)
1320 {
1321         unsigned int index = new_csc->win_index;
1322         struct tegra_dc *dc = user->ext->dc;
1323         struct tegra_dc_ext_win *ext_win;
1324         struct tegra_dc_csc *csc;
1325         struct tegra_dc_win *win = tegra_dc_get_window(dc, index);
1326
1327         if (!win)
1328                 return -EINVAL;
1329
1330         ext_win = &user->ext->win[index];
1331         csc = &win->csc;
1332
1333         mutex_lock(&ext_win->lock);
1334
1335         if (ext_win->user != user) {
1336                 mutex_unlock(&ext_win->lock);
1337                 return -EACCES;
1338         }
1339
1340         csc->yof =   new_csc->yof;
1341         csc->kyrgb = new_csc->kyrgb;
1342         csc->kur =   new_csc->kur;
1343         csc->kvr =   new_csc->kvr;
1344         csc->kug =   new_csc->kug;
1345         csc->kvg =   new_csc->kvg;
1346         csc->kub =   new_csc->kub;
1347         csc->kvb =   new_csc->kvb;
1348
1349         tegra_dc_update_csc(dc, index);
1350
1351         mutex_unlock(&ext_win->lock);
1352
1353         return 0;
1354 }
1355 #endif
1356
1357 #if defined(CONFIG_TEGRA_CSC_V2)
1358 static int tegra_dc_ext_set_csc(struct tegra_dc_ext_user *user,
1359                                 struct tegra_dc_ext_csc_v2 *new_csc)
1360 {
1361         unsigned int index = new_csc->win_index;
1362         struct tegra_dc *dc = user->ext->dc;
1363         struct tegra_dc_ext_win *ext_win;
1364         struct tegra_dc_csc_v2 *csc;
1365         struct tegra_dc_win *win = tegra_dc_get_window(dc, index);
1366
1367         if (!win)
1368                 return -EINVAL;
1369
1370         ext_win = &user->ext->win[index];
1371         csc = &win->csc;
1372
1373         mutex_lock(&ext_win->lock);
1374
1375         if (ext_win->user != user) {
1376                 mutex_unlock(&ext_win->lock);
1377                 return -EACCES;
1378         }
1379
1380         csc->r2r = new_csc->r2r;
1381         csc->g2r = new_csc->g2r;
1382         csc->b2r = new_csc->b2r;
1383         csc->const2r = new_csc->const2r;
1384         csc->r2g = new_csc->r2g;
1385         csc->g2g = new_csc->g2g;
1386         csc->b2g = new_csc->b2g;
1387         csc->const2g = new_csc->const2g;
1388         csc->r2b = new_csc->r2b;
1389         csc->g2b = new_csc->g2b;
1390         csc->b2b = new_csc->b2b;
1391         csc->const2b = new_csc->const2b;
1392
1393         tegra_nvdisp_update_csc(dc, index);
1394
1395         mutex_unlock(&ext_win->lock);
1396
1397         return 0;
1398 }
1399 #endif
1400
1401 #if defined(CONFIG_TEGRA_LUT)
1402 static int set_lut_channel(u16 __user *channel_from_user,
1403                            u8 *channel_to,
1404                            u32 start,
1405                            u32 len)
1406 {
1407         int i;
1408         u16 lut16bpp[256];
1409
1410         if (channel_from_user) {
1411                 if (copy_from_user(lut16bpp, channel_from_user, len<<1))
1412                         return 1;
1413
1414                 for (i = 0; i < len; i++)
1415                         channel_to[start+i] = lut16bpp[i]>>8;
1416         } else {
1417                 for (i = 0; i < len; i++)
1418                         channel_to[start+i] = start+i;
1419         }
1420
1421         return 0;
1422 }
1423 #elif defined(CONFIG_TEGRA_LUT_V2)
1424 static int set_lut_channel(struct tegra_dc_ext_lut *new_lut,
1425                            u64 *channel_to)
1426 {
1427         int i, j;
1428         u16 lut16bpp[256];
1429         u64 inlut = 0;
1430         u16 __user *channel_from_user;
1431         u32 start = new_lut->start;
1432         u32 len = new_lut->len;
1433
1434         for (j = 0; j < 3; j++) {
1435
1436                 if (j == 0)
1437                         channel_from_user = new_lut->r;
1438                 else if (j == 1)
1439                         channel_from_user = new_lut->g;
1440                 else if (j == 2)
1441                         channel_from_user = new_lut->b;
1442
1443                 if (channel_from_user) {
1444                         if (copy_from_user(lut16bpp,
1445                                         channel_from_user, len<<1))
1446                                 return 1;
1447
1448                         for (i = 0; i < len; i++) {
1449                                 inlut = (u64)lut16bpp[i];
1450                                 /*16bit data in MSB format*/
1451                                 channel_to[start+i] |=
1452                                         ((inlut && 0xFF00) << (j * 16));
1453                         }
1454                 } else {
1455                         for (i = 0; i < len; i++) {
1456                                 inlut = (u64)(start+i);
1457                                 channel_to[start+i] |= (inlut << (j * 16));
1458                         }
1459                 }
1460         }
1461         return 0;
1462 }
1463 #endif
1464
1465 static int tegra_dc_ext_set_lut(struct tegra_dc_ext_user *user,
1466                                 struct tegra_dc_ext_lut *new_lut)
1467 {
1468         int err;
1469         unsigned int index = new_lut->win_index;
1470         u32 start = new_lut->start;
1471         u32 len = new_lut->len;
1472
1473         struct tegra_dc *dc = user->ext->dc;
1474         struct tegra_dc_ext_win *ext_win;
1475         struct tegra_dc_lut *lut;
1476         struct tegra_dc_win *win = tegra_dc_get_window(dc, index);
1477
1478         if (!win)
1479                 return -EINVAL;
1480
1481         if ((start >= 256) || (len > 256) || ((start + len) > 256))
1482                 return -EINVAL;
1483
1484         ext_win = &user->ext->win[index];
1485         lut = &win->lut;
1486
1487         mutex_lock(&ext_win->lock);
1488
1489         if (ext_win->user != user) {
1490                 mutex_unlock(&ext_win->lock);
1491                 return -EACCES;
1492         }
1493
1494 #if defined(CONFIG_TEGRA_LUT)
1495
1496         err = set_lut_channel(new_lut->r, lut->r, start, len) |
1497               set_lut_channel(new_lut->g, lut->g, start, len) |
1498               set_lut_channel(new_lut->b, lut->b, start, len);
1499
1500 #elif defined(CONFIG_TEGRA_LUT_V2)
1501         memset(lut->rgb, 0, sizeof(u64)* len);
1502         err = set_lut_channel(new_lut, lut->rgb);
1503
1504 #endif
1505         if (err) {
1506                 mutex_unlock(&ext_win->lock);
1507                 return -EFAULT;
1508         }
1509
1510         tegra_dc_update_lut(dc, index,
1511                         new_lut->flags & TEGRA_DC_EXT_LUT_FLAGS_FBOVERRIDE);
1512
1513         mutex_unlock(&ext_win->lock);
1514
1515         return 0;
1516 }
1517
1518 #if defined(CONFIG_TEGRA_DC_CMU_V2)
1519 static int tegra_dc_ext_get_cmu_v2(struct tegra_dc_ext_user *user,
1520                         struct tegra_dc_ext_cmu_v2 *args, bool custom_value)
1521 {
1522         int i;
1523         struct tegra_dc *dc = user->ext->dc;
1524         struct tegra_dc_cmu *cmu = dc->pdata->cmu;
1525         struct tegra_dc_lut *cmu_lut = &dc->cmu;
1526
1527         if (custom_value && !dc->pdata->cmu)
1528                 return -EACCES;
1529
1530         args->cmu_enable = dc->pdata->cmu_enable;
1531         for (i = 0; i < TEGRA_DC_EXT_LUT_SIZE_1025; i++) {
1532                 if (custom_value)
1533                         args->rgb[i] = cmu->rgb[i];
1534                 else
1535                         args->rgb[i] = cmu_lut->rgb[i];
1536         }
1537         return 0;
1538 }
1539
1540 static int tegra_dc_ext_set_cmu_v2(struct tegra_dc_ext_user *user,
1541                                 struct tegra_dc_ext_cmu_v2 *args)
1542 {
1543         int i, lut_size;
1544         struct tegra_dc_lut *cmu;
1545         struct tegra_dc *dc = user->ext->dc;
1546
1547         /* Directly copying the values to DC
1548          * output lut whose address is already
1549          * programmed to HW register.
1550          */
1551         cmu = &dc->cmu;
1552         if (!cmu)
1553                 return -ENOMEM;
1554
1555         dc->pdata->cmu_enable = args->cmu_enable;
1556         lut_size = args->lut_size;
1557         for (i = 0; i < lut_size; i++)
1558                 cmu->rgb[i] = args->rgb[i];
1559
1560         tegra_nvdisp_update_cmu(dc, cmu);
1561
1562         return 0;
1563 }
1564
1565 #elif defined(CONFIG_TEGRA_DC_CMU)
1566 static int tegra_dc_ext_get_cmu(struct tegra_dc_ext_user *user,
1567                         struct tegra_dc_ext_cmu *args, bool custom_value)
1568 {
1569         int i;
1570         struct tegra_dc *dc = user->ext->dc;
1571         struct tegra_dc_cmu *cmu;
1572
1573         if (custom_value && dc->pdata->cmu)
1574                 cmu = dc->pdata->cmu;
1575         else if (custom_value && !dc->pdata->cmu)
1576                 return -EACCES;
1577         else
1578                 cmu = &dc->cmu;
1579
1580         args->cmu_enable = dc->pdata->cmu_enable;
1581         for (i = 0; i < 256; i++)
1582                 args->lut1[i] = cmu->lut1[i];
1583
1584         args->csc[0] = cmu->csc.krr;
1585         args->csc[1] = cmu->csc.kgr;
1586         args->csc[2] = cmu->csc.kbr;
1587         args->csc[3] = cmu->csc.krg;
1588         args->csc[4] = cmu->csc.kgg;
1589         args->csc[5] = cmu->csc.kbg;
1590         args->csc[6] = cmu->csc.krb;
1591         args->csc[7] = cmu->csc.kgb;
1592         args->csc[8] = cmu->csc.kbb;
1593
1594         for (i = 0; i < 960; i++)
1595                 args->lut2[i] = cmu->lut2[i];
1596
1597         return 0;
1598 }
1599
1600 static int tegra_dc_ext_set_cmu(struct tegra_dc_ext_user *user,
1601                                 struct tegra_dc_ext_cmu *args)
1602 {
1603         int i;
1604         struct tegra_dc_cmu *cmu;
1605         struct tegra_dc *dc = user->ext->dc;
1606
1607         cmu = kzalloc(sizeof(*cmu), GFP_KERNEL);
1608         if (!cmu)
1609                 return -ENOMEM;
1610
1611         dc->pdata->cmu_enable = args->cmu_enable;
1612         for (i = 0; i < 256; i++)
1613                 cmu->lut1[i] = args->lut1[i];
1614
1615         cmu->csc.krr = args->csc[0];
1616         cmu->csc.kgr = args->csc[1];
1617         cmu->csc.kbr = args->csc[2];
1618         cmu->csc.krg = args->csc[3];
1619         cmu->csc.kgg = args->csc[4];
1620         cmu->csc.kbg = args->csc[5];
1621         cmu->csc.krb = args->csc[6];
1622         cmu->csc.kgb = args->csc[7];
1623         cmu->csc.kbb = args->csc[8];
1624
1625         for (i = 0; i < 960; i++)
1626                 cmu->lut2[i] = args->lut2[i];
1627
1628         tegra_dc_update_cmu(dc, cmu);
1629
1630         kfree(cmu);
1631         return 0;
1632 }
1633
1634 static int tegra_dc_ext_set_cmu_aligned(struct tegra_dc_ext_user *user,
1635                                 struct tegra_dc_ext_cmu *args)
1636 {
1637         int i;
1638         struct tegra_dc_cmu *cmu;
1639         struct tegra_dc *dc = user->ext->dc;
1640
1641         cmu = kzalloc(sizeof(*cmu), GFP_KERNEL);
1642         if (!cmu)
1643                 return -ENOMEM;
1644
1645         for (i = 0; i < 256; i++)
1646                 cmu->lut1[i] = args->lut1[i];
1647
1648         cmu->csc.krr = args->csc[0];
1649         cmu->csc.kgr = args->csc[1];
1650         cmu->csc.kbr = args->csc[2];
1651         cmu->csc.krg = args->csc[3];
1652         cmu->csc.kgg = args->csc[4];
1653         cmu->csc.kbg = args->csc[5];
1654         cmu->csc.krb = args->csc[6];
1655         cmu->csc.kgb = args->csc[7];
1656         cmu->csc.kbb = args->csc[8];
1657
1658         for (i = 0; i < 960; i++)
1659                 cmu->lut2[i] = args->lut2[i];
1660
1661         tegra_dc_update_cmu_aligned(dc, cmu);
1662
1663         kfree(cmu);
1664         return 0;
1665 }
1666 static int tegra_dc_ext_get_cmu_adbRGB(struct tegra_dc_ext_user *user,
1667                         struct tegra_dc_ext_cmu *args)
1668 {
1669         int i;
1670         struct tegra_dc *dc = user->ext->dc;
1671         struct tegra_dc_cmu *cmu;
1672
1673         if (dc->pdata->cmu_adbRGB)
1674                 cmu = dc->pdata->cmu_adbRGB;
1675         else
1676                 return -EACCES;
1677
1678         args->cmu_enable = dc->pdata->cmu_enable;
1679         for (i = 0; i < 256; i++)
1680                 args->lut1[i] = cmu->lut1[i];
1681
1682         args->csc[0] = cmu->csc.krr;
1683         args->csc[1] = cmu->csc.kgr;
1684         args->csc[2] = cmu->csc.kbr;
1685         args->csc[3] = cmu->csc.krg;
1686         args->csc[4] = cmu->csc.kgg;
1687         args->csc[5] = cmu->csc.kbg;
1688         args->csc[6] = cmu->csc.krb;
1689         args->csc[7] = cmu->csc.kgb;
1690         args->csc[8] = cmu->csc.kbb;
1691
1692         for (i = 0; i < 960; i++)
1693                 args->lut2[i] = cmu->lut2[i];
1694
1695         return 0;
1696 }
1697
1698 #endif
1699
1700 #ifdef CONFIG_TEGRA_ISOMGR
1701 static int tegra_dc_ext_negotiate_bw(struct tegra_dc_ext_user *user,
1702                         struct tegra_dc_ext_flip_windowattr *wins, int win_num)
1703 {
1704         int i;
1705         int ret;
1706         struct tegra_dc_win *dc_wins[DC_N_WINDOWS];
1707         struct tegra_dc *dc = user->ext->dc;
1708
1709         /* If display has been disconnected return with error. */
1710         if (!dc->connected)
1711                 return -1;
1712
1713         for (i = 0; i < win_num; i++) {
1714                 int idx = wins[i].index;
1715
1716                 if (wins[i].buff_id > 0) {
1717                         tegra_dc_ext_set_windowattr_basic(&dc->tmp_wins[idx],
1718                                                           &wins[i]);
1719                 }
1720                 else {
1721                         dc->tmp_wins[idx].flags = 0;
1722                 }
1723                 dc_wins[i] = &dc->tmp_wins[idx];
1724         }
1725
1726         ret = tegra_dc_bandwidth_negotiate_bw(dc, dc_wins, win_num);
1727
1728         return ret;
1729 }
1730 #endif
1731
1732 static u32 tegra_dc_ext_get_vblank_syncpt(struct tegra_dc_ext_user *user)
1733 {
1734         struct tegra_dc *dc = user->ext->dc;
1735
1736         return dc->vblank_syncpt;
1737 }
1738
1739 static int tegra_dc_ext_get_status(struct tegra_dc_ext_user *user,
1740                                    struct tegra_dc_ext_status *status)
1741 {
1742         struct tegra_dc *dc = user->ext->dc;
1743
1744         memset(status, 0, sizeof(*status));
1745
1746         if (dc->enabled)
1747                 status->flags |= TEGRA_DC_EXT_FLAGS_ENABLED;
1748
1749         return 0;
1750 }
1751
1752 static int tegra_dc_ext_get_feature(struct tegra_dc_ext_user *user,
1753                                    struct tegra_dc_ext_feature *feature)
1754 {
1755         struct tegra_dc *dc = user->ext->dc;
1756         struct tegra_dc_feature *table = dc->feature;
1757
1758         if (dc->enabled && feature->entries) {
1759                 feature->length = table->num_entries;
1760                 memcpy(feature->entries, table->entries, table->num_entries *
1761                                         sizeof(struct tegra_dc_feature_entry));
1762         }
1763
1764         return 0;
1765 }
1766
1767
1768 static int tegra_dc_get_cap_hdr_info(struct tegra_dc_ext_user *user,
1769                                 struct tegra_dc_ext_hdr_caps *hdr_cap_info)
1770 {
1771         int ret = 0;
1772         struct tegra_dc *dc = user->ext->dc;
1773         struct tegra_edid *dc_edid = dc->edid;
1774
1775         /* Currently only dc->edid has this info. In future,
1776          * we have to provide info for non-edid interfaces
1777          * in the device tree.
1778          */
1779         if (dc_edid)
1780                 ret = tegra_edid_get_ex_hdr_cap_info(dc_edid, hdr_cap_info);
1781
1782         return ret;
1783
1784 }
1785 static int tegra_dc_get_cap_info(struct tegra_dc_ext_user *user,
1786                                 struct tegra_dc_ext_caps *cap_info,
1787                                 int nr_elements)
1788 {
1789         int i, ret = 0;
1790         for (i = 0; i < nr_elements; i++) {
1791
1792                 switch (cap_info[i].data_type) {
1793
1794                 case TEGRA_DC_EXT_CAP_TYPE_HDR_SINK:
1795                 {
1796                         struct tegra_dc_ext_hdr_caps *hdr_cap_info;
1797
1798                         hdr_cap_info = kzalloc(sizeof(*hdr_cap_info),
1799                                 GFP_KERNEL);
1800
1801                         ret = tegra_dc_get_cap_hdr_info(user, hdr_cap_info);
1802
1803                         if (copy_to_user((void __user *)(uintptr_t)
1804                                 cap_info[i].data, hdr_cap_info,
1805                                 sizeof(*hdr_cap_info))) {
1806                                 kfree(hdr_cap_info);
1807                                 return -EFAULT;
1808                         }
1809                         kfree(hdr_cap_info);
1810                         break;
1811                 }
1812                 default:
1813                         return -EINVAL;
1814                 }
1815         }
1816
1817         return ret;
1818 }
1819
1820 static long tegra_dc_ioctl(struct file *filp, unsigned int cmd,
1821                            unsigned long arg)
1822 {
1823         void __user *user_arg = (void __user *)arg;
1824         struct tegra_dc_ext_user *user = filp->private_data;
1825         int ret;
1826
1827         switch (cmd) {
1828         case TEGRA_DC_EXT_SET_NVMAP_FD:
1829                 return 0;
1830
1831         case TEGRA_DC_EXT_GET_WINDOW:
1832                 return tegra_dc_ext_get_window(user, arg);
1833         case TEGRA_DC_EXT_PUT_WINDOW:
1834                 ret = tegra_dc_ext_put_window(user, arg);
1835                 if (!ret) {
1836                         ret = tegra_dc_blank_wins(user->ext->dc, BIT(arg));
1837                         if (ret < 0)
1838                                 return ret;
1839                         tegra_dc_ext_unpin_window(&user->ext->win[arg]);
1840                 }
1841                 return ret;
1842
1843         case TEGRA_DC_EXT_FLIP:
1844         {
1845                 struct tegra_dc_ext_flip args;
1846                 int ret;
1847
1848                 if (copy_from_user(&args, user_arg, sizeof(args)))
1849                         return -EFAULT;
1850
1851                 ret = tegra_dc_ext_flip(user, args.win,
1852                         TEGRA_DC_EXT_FLIP_N_WINDOWS,
1853                         &args.post_syncpt_id, &args.post_syncpt_val, NULL,
1854                         NULL, 0, NULL, 0);
1855
1856                 if (copy_to_user(user_arg, &args, sizeof(args)))
1857                         return -EFAULT;
1858
1859                 return ret;
1860         }
1861
1862 #ifdef CONFIG_COMPAT
1863         case TEGRA_DC_EXT_FLIP2_32:
1864         {
1865                 int ret;
1866                 int win_num;
1867                 struct tegra_dc_ext_flip_2_32 args;
1868                 struct tegra_dc_ext_flip_windowattr *win;
1869
1870                 if (copy_from_user(&args, user_arg, sizeof(args)))
1871                         return -EFAULT;
1872
1873                 win_num = args.win_num;
1874                 win = kzalloc(sizeof(*win) * win_num, GFP_KERNEL);
1875
1876                 if (copy_from_user(win, compat_ptr(args.win),
1877                         sizeof(*win) * win_num)) {
1878                         kfree(win);
1879                         return -EFAULT;
1880                 }
1881
1882                 ret = tegra_dc_ext_flip(user, win, win_num,
1883                         &args.post_syncpt_id, &args.post_syncpt_val, NULL,
1884                         args.dirty_rect, 0, NULL, 0);
1885
1886                 if (copy_to_user(compat_ptr(args.win), win,
1887                         sizeof(*win) * win_num) ||
1888                         copy_to_user(user_arg, &args, sizeof(args))) {
1889                         kfree(win);
1890                         return -EFAULT;
1891                 }
1892
1893                 kfree(win);
1894                 return ret;
1895         }
1896
1897 #endif
1898         case TEGRA_DC_EXT_FLIP2:
1899         {
1900                 int ret;
1901                 int win_num;
1902                 struct tegra_dc_ext_flip_2 args;
1903                 struct tegra_dc_ext_flip_windowattr *win;
1904
1905                 if (copy_from_user(&args, user_arg, sizeof(args)))
1906                         return -EFAULT;
1907
1908                 win_num = args.win_num;
1909                 win = kzalloc(sizeof(*win) * win_num, GFP_KERNEL);
1910
1911                 if (copy_from_user(win, args.win, sizeof(*win) * win_num)) {
1912                         kfree(win);
1913                         return -EFAULT;
1914                 }
1915
1916                 ret = tegra_dc_ext_flip(user, win, win_num,
1917                         &args.post_syncpt_id, &args.post_syncpt_val, NULL,
1918                         args.dirty_rect, 0, NULL, 0);
1919
1920                 if (copy_to_user(args.win, win, sizeof(*win) * win_num) ||
1921                         copy_to_user(user_arg, &args, sizeof(args))) {
1922                         kfree(win);
1923                         return -EFAULT;
1924                 }
1925
1926                 kfree(win);
1927                 return ret;
1928         }
1929
1930         case TEGRA_DC_EXT_FLIP3:
1931         {
1932                 int ret;
1933                 int win_num;
1934                 struct tegra_dc_ext_flip_3 args;
1935                 struct tegra_dc_ext_flip_windowattr *win;
1936                 bool bypass;
1937
1938                 if (copy_from_user(&args, user_arg, sizeof(args)))
1939                         return -EFAULT;
1940
1941                 bypass = !!(args.flags & TEGRA_DC_EXT_FLIP_HEAD_FLAG_YUVBYPASS);
1942
1943                 user->ext->dc->yuv_bypass = bypass;
1944                 win_num = args.win_num;
1945                 win = kzalloc(sizeof(*win) * win_num, GFP_KERNEL);
1946
1947                 if (copy_from_user(win,  (void __user *) (uintptr_t)args.win,
1948                                    sizeof(*win) * win_num)) {
1949                         kfree(win);
1950                         return -EFAULT;
1951                 }
1952
1953                 ret = tegra_dc_ext_flip(user, win, win_num,
1954                         NULL, NULL, &args.post_syncpt_fd, args.dirty_rect,
1955                         args.flags, NULL, 0);
1956
1957                 if (copy_to_user((void __user *)(uintptr_t)args.win, win,
1958                                  sizeof(*win) * win_num) ||
1959                         copy_to_user(user_arg, &args, sizeof(args))) {
1960                         kfree(win);
1961                         return -EFAULT;
1962                 }
1963
1964                 kfree(win);
1965                 return ret;
1966         }
1967         case TEGRA_DC_EXT_FLIP4:
1968         {
1969                 int ret;
1970                 int win_num;
1971                 int nr_user_data;
1972                 struct tegra_dc_ext_flip_4 args;
1973                 struct tegra_dc_ext_flip_windowattr *win;
1974                 struct tegra_dc_ext_flip_user_data *flip_user_data;
1975                 bool bypass;
1976
1977                 if (copy_from_user(&args, user_arg, sizeof(args)))
1978                         return -EFAULT;
1979
1980                 bypass = !!(args.flags & TEGRA_DC_EXT_FLIP_HEAD_FLAG_YUVBYPASS);
1981
1982                 user->ext->dc->yuv_bypass = bypass;
1983                 win_num = args.win_num;
1984                 win = kzalloc(sizeof(*win) * win_num, GFP_KERNEL);
1985
1986                 if (copy_from_user(win,  (void __user *) (uintptr_t)args.win,
1987                                    sizeof(*win) * win_num)) {
1988                         kfree(win);
1989                         return -EFAULT;
1990                 }
1991
1992                 nr_user_data = args.nr_elements;
1993                 flip_user_data = kzalloc(sizeof(*flip_user_data)
1994                                         * nr_user_data, GFP_KERNEL);
1995                 if (nr_user_data > 0) {
1996                         if (copy_from_user(flip_user_data,
1997                                 (void __user *) (uintptr_t)args.data,
1998                                 sizeof(*flip_user_data) * nr_user_data)) {
1999                                 kfree(win);
2000                                 return -EFAULT;
2001                         }
2002                 }
2003                 ret = tegra_dc_ext_flip(user, win, win_num,
2004                         NULL, NULL, &args.post_syncpt_fd, args.dirty_rect,
2005                         args.flags, flip_user_data, nr_user_data);
2006
2007                 if (nr_user_data > 0)
2008                         kfree(flip_user_data);
2009
2010                 if (copy_to_user((void __user *)(uintptr_t)args.win, win,
2011                                  sizeof(*win) * win_num) ||
2012                         copy_to_user(user_arg, &args, sizeof(args))) {
2013                         kfree(win);
2014                         return -EFAULT;
2015                 }
2016
2017                 kfree(win);
2018                 return ret;
2019         }
2020
2021 #ifdef CONFIG_TEGRA_ISOMGR
2022 #ifdef CONFIG_COMPAT
2023         case TEGRA_DC_EXT_SET_PROPOSED_BW32:
2024         {
2025                 int ret;
2026                 int win_num;
2027                 struct tegra_dc_ext_flip_2_32 args;
2028                 struct tegra_dc_ext_flip_windowattr *win;
2029
2030                 if (copy_from_user(&args, user_arg, sizeof(args)))
2031                         return -EFAULT;
2032
2033                 win_num = args.win_num;
2034                 win = kzalloc(sizeof(*win) * win_num, GFP_KERNEL);
2035
2036                 if (copy_from_user(win, compat_ptr(args.win),
2037                                 sizeof(*win) * win_num)) {
2038                         kfree(win);
2039                         return -EFAULT;
2040                 }
2041
2042                 ret = tegra_dc_ext_negotiate_bw(user, win, win_num);
2043
2044                 kfree(win);
2045
2046                 return ret;
2047         }
2048 #endif
2049         case TEGRA_DC_EXT_SET_PROPOSED_BW:
2050         {
2051                 int ret;
2052                 int win_num;
2053                 struct tegra_dc_ext_flip_2 args;
2054                 struct tegra_dc_ext_flip_windowattr *win;
2055
2056                 if (copy_from_user(&args, user_arg, sizeof(args)))
2057                         return -EFAULT;
2058
2059                 win_num = args.win_num;
2060                 win = kzalloc(sizeof(*win) * win_num, GFP_KERNEL);
2061
2062                 if (copy_from_user(win, args.win, sizeof(*win) * win_num)) {
2063                         kfree(win);
2064                         return -EFAULT;
2065                 }
2066
2067                 ret = tegra_dc_ext_negotiate_bw(user, win, win_num);
2068
2069                 kfree(win);
2070
2071                 return ret;
2072         }
2073         case TEGRA_DC_EXT_SET_PROPOSED_BW_3:
2074         {
2075                 int ret;
2076                 int win_num;
2077                 struct tegra_dc_ext_flip_3 args;
2078                 struct tegra_dc_ext_flip_windowattr *win;
2079
2080                 if (copy_from_user(&args, user_arg, sizeof(args)))
2081                         return -EFAULT;
2082
2083                 win_num = args.win_num;
2084                 win = kzalloc(sizeof(*win) * win_num, GFP_KERNEL);
2085
2086                 if (copy_from_user(win, (void *)(uintptr_t)args.win,
2087                                    sizeof(*win) * win_num)) {
2088                         kfree(win);
2089                         return -EFAULT;
2090                 }
2091
2092                 ret = tegra_dc_ext_negotiate_bw(user, win, win_num);
2093
2094                 kfree(win);
2095
2096                 return ret;
2097         }
2098 #else
2099 /* if isomgr is not present, allow any request to pass. */
2100 #ifdef CONFIG_COMPAT
2101         case TEGRA_DC_EXT_SET_PROPOSED_BW32:
2102                 return 0;
2103 #endif
2104         case TEGRA_DC_EXT_SET_PROPOSED_BW:
2105                 return 0;
2106         case TEGRA_DC_EXT_SET_PROPOSED_BW_3:
2107                 return 0;
2108 #endif
2109         case TEGRA_DC_EXT_GET_CURSOR:
2110                 return tegra_dc_ext_get_cursor(user);
2111         case TEGRA_DC_EXT_PUT_CURSOR:
2112                 return tegra_dc_ext_put_cursor(user);
2113         case TEGRA_DC_EXT_SET_CURSOR_IMAGE_LOW_LATENCY:
2114         case TEGRA_DC_EXT_SET_CURSOR_IMAGE:
2115         {
2116                 struct tegra_dc_ext_cursor_image args;
2117
2118                 if (copy_from_user(&args, user_arg, sizeof(args)))
2119                         return -EFAULT;
2120
2121                 return tegra_dc_ext_set_cursor_image(user, &args);
2122         }
2123         case TEGRA_DC_EXT_SET_CURSOR_LOW_LATENCY:
2124         case TEGRA_DC_EXT_SET_CURSOR:
2125         {
2126                 struct tegra_dc_ext_cursor args;
2127
2128                 if (copy_from_user(&args, user_arg, sizeof(args)))
2129                         return -EFAULT;
2130
2131                 return tegra_dc_ext_set_cursor(user, &args);
2132         }
2133 #ifdef CONFIG_TEGRA_CSC
2134         case TEGRA_DC_EXT_SET_CSC:
2135         {
2136                 struct tegra_dc_ext_csc args;
2137
2138                 if (copy_from_user(&args, user_arg, sizeof(args)))
2139                         return -EFAULT;
2140
2141                 return tegra_dc_ext_set_csc(user, &args);
2142         }
2143 #endif
2144
2145 #ifdef CONFIG_TEGRA_CSC_V2
2146         case TEGRA_DC_EXT_SET_CSC_V2:
2147         {
2148                 struct tegra_dc_ext_csc_v2 args;
2149
2150                 if (copy_from_user(&args, user_arg, sizeof(args)))
2151                         return -EFAULT;
2152
2153                 return tegra_dc_ext_set_csc(user, &args);
2154         }
2155 #endif
2156         case TEGRA_DC_EXT_GET_VBLANK_SYNCPT:
2157         {
2158                 u32 syncpt = tegra_dc_ext_get_vblank_syncpt(user);
2159
2160                 if (copy_to_user(user_arg, &syncpt, sizeof(syncpt)))
2161                         return -EFAULT;
2162
2163                 return 0;
2164         }
2165
2166         case TEGRA_DC_EXT_GET_STATUS:
2167         {
2168                 struct tegra_dc_ext_status args;
2169                 int ret;
2170
2171                 ret = tegra_dc_ext_get_status(user, &args);
2172
2173                 if (copy_to_user(user_arg, &args, sizeof(args)))
2174                         return -EFAULT;
2175
2176                 return ret;
2177         }
2178
2179 #ifdef CONFIG_COMPAT
2180         case TEGRA_DC_EXT_SET_LUT32:
2181         {
2182                 struct tegra_dc_ext_lut32 args;
2183                 struct tegra_dc_ext_lut tmp;
2184
2185                 if (copy_from_user(&args, user_arg, sizeof(args)))
2186                         return -EFAULT;
2187
2188                 /* translate 32-bit version to 64-bit */
2189                 tmp.win_index = args.win_index;
2190                 tmp.flags = args.flags;
2191                 tmp.start = args.start;
2192                 tmp.len = args.len;
2193                 tmp.r = compat_ptr(args.r);
2194                 tmp.g = compat_ptr(args.g);
2195                 tmp.b = compat_ptr(args.b);
2196
2197                 return tegra_dc_ext_set_lut(user, &tmp);
2198         }
2199 #endif
2200         case TEGRA_DC_EXT_SET_LUT:
2201         {
2202                 struct tegra_dc_ext_lut args;
2203
2204                 if (copy_from_user(&args, user_arg, sizeof(args)))
2205                         return -EFAULT;
2206
2207                 return tegra_dc_ext_set_lut(user, &args);
2208         }
2209
2210 #ifdef CONFIG_COMPAT
2211         case TEGRA_DC_EXT_GET_FEATURES32:
2212         {
2213                 struct tegra_dc_ext_feature32 args;
2214                 struct tegra_dc_ext_feature tmp;
2215                 int ret;
2216
2217                 if (copy_from_user(&args, user_arg, sizeof(args)))
2218                         return -EFAULT;
2219
2220                 /* convert 32-bit to 64-bit version */
2221                 tmp.length = args.length;
2222                 tmp.entries = compat_ptr(args.entries);
2223
2224                 ret = tegra_dc_ext_get_feature(user, &tmp);
2225
2226                 /* convert back to 32-bit version, tmp.entries not modified */
2227                 args.length = tmp.length;
2228
2229                 if (copy_to_user(user_arg, &args, sizeof(args)))
2230                         return -EFAULT;
2231
2232                 return ret;
2233         }
2234 #endif
2235         case TEGRA_DC_EXT_GET_FEATURES:
2236         {
2237                 struct tegra_dc_ext_feature args;
2238                 int ret;
2239
2240                 if (copy_from_user(&args, user_arg, sizeof(args)))
2241                         return -EFAULT;
2242
2243                 ret = tegra_dc_ext_get_feature(user, &args);
2244
2245                 if (copy_to_user(user_arg, &args, sizeof(args)))
2246                         return -EFAULT;
2247
2248                 return ret;
2249         }
2250
2251         case TEGRA_DC_EXT_CURSOR_CLIP:
2252         {
2253                 int args;
2254                 if (copy_from_user(&args, user_arg, sizeof(args)))
2255                         return -EFAULT;
2256
2257                 return tegra_dc_ext_cursor_clip(user, &args);
2258         }
2259
2260         case TEGRA_DC_EXT_GET_CMU:
2261         {
2262 #ifdef CONFIG_TEGRA_DC_CMU
2263                 struct tegra_dc_ext_cmu *args;
2264
2265                 args = kzalloc(sizeof(*args), GFP_KERNEL);
2266                 if (!args)
2267                         return -ENOMEM;
2268
2269                 tegra_dc_ext_get_cmu(user, args, 0);
2270
2271                 if (copy_to_user(user_arg, args, sizeof(*args))) {
2272                         kfree(args);
2273                         return -EFAULT;
2274                 }
2275
2276                 kfree(args);
2277                 return 0;
2278 #else
2279                 return -EACCES;
2280 #endif
2281         }
2282
2283         case TEGRA_DC_EXT_GET_CUSTOM_CMU:
2284         {
2285 #ifdef CONFIG_TEGRA_DC_CMU
2286                 struct tegra_dc_ext_cmu *args;
2287
2288                 args = kzalloc(sizeof(*args), GFP_KERNEL);
2289                 if (!args)
2290                         return -ENOMEM;
2291
2292                 if (tegra_dc_ext_get_cmu(user, args, 1)) {
2293                         kfree(args);
2294                         return -EACCES;
2295                 }
2296
2297                 if (copy_to_user(user_arg, args, sizeof(*args))) {
2298                         kfree(args);
2299                         return -EFAULT;
2300                 }
2301
2302                 kfree(args);
2303                 return 0;
2304 #else
2305                 return -EACCES;
2306 #endif
2307         }
2308
2309         case TEGRA_DC_EXT_GET_CMU_ADBRGB:
2310         {
2311 #ifdef CONFIG_TEGRA_DC_CMU
2312                 struct tegra_dc_ext_cmu *args;
2313
2314                 args = kzalloc(sizeof(*args), GFP_KERNEL);
2315                 if (!args)
2316                         return -ENOMEM;
2317
2318                 if (tegra_dc_ext_get_cmu_adbRGB(user, args)) {
2319                         kfree(args);
2320                         return -EACCES;
2321                 }
2322
2323                 if (copy_to_user(user_arg, args, sizeof(*args))) {
2324                         kfree(args);
2325                         return -EFAULT;
2326                 }
2327
2328                 kfree(args);
2329                 return 0;
2330 #else
2331                 return -EACCES;
2332 #endif
2333         }
2334
2335         case TEGRA_DC_EXT_SET_CMU:
2336         {
2337 #ifdef CONFIG_TEGRA_DC_CMU
2338                 int ret;
2339                 struct tegra_dc_ext_cmu *args;
2340
2341                 args = kzalloc(sizeof(*args), GFP_KERNEL);
2342                 if (!args)
2343                         return -ENOMEM;
2344
2345                 if (copy_from_user(args, user_arg, sizeof(*args))) {
2346                         kfree(args);
2347                         return -EFAULT;
2348                 }
2349
2350                 ret = tegra_dc_ext_set_cmu(user, args);
2351
2352                 kfree(args);
2353
2354                 return ret;
2355 #else
2356                 return -EACCES;
2357 #endif
2358         }
2359
2360         case TEGRA_DC_EXT_GET_CMU_V2:
2361         case TEGRA_DC_EXT_GET_CUSTOM_CMU_V2:
2362         {
2363 #ifdef CONFIG_TEGRA_DC_CMU_V2
2364                 struct tegra_dc_ext_cmu_v2 *args;
2365                 bool custom_value = false;
2366
2367                 if (TEGRA_DC_EXT_GET_CUSTOM_CMU_V2 == cmd)
2368                         custom_value = true;
2369
2370                 args = kzalloc(sizeof(*args), GFP_KERNEL);
2371                 if (!args)
2372                         return -ENOMEM;
2373
2374                 if (tegra_dc_ext_get_cmu_v2(user, args, custom_value)) {
2375                         kfree(args);
2376                         return -EACCES;
2377                 }
2378
2379                 if (copy_to_user(user_arg, args, sizeof(*args))) {
2380                         kfree(args);
2381                         return -EFAULT;
2382                 }
2383
2384                 kfree(args);
2385                 return 0;
2386 #else
2387                 return -EACCES;
2388 #endif
2389         }
2390
2391         case TEGRA_DC_EXT_SET_CMU_V2:
2392         {
2393 #ifdef CONFIG_TEGRA_DC_CMU_V2
2394                 int ret;
2395                 struct tegra_dc_ext_cmu_v2 *args;
2396
2397                 args = kzalloc(sizeof(*args), GFP_KERNEL);
2398                 if (!args)
2399                         return -ENOMEM;
2400
2401                 if (copy_from_user(args, user_arg, sizeof(*args))) {
2402                         kfree(args);
2403                         return -EFAULT;
2404                 }
2405
2406                 ret = tegra_dc_ext_set_cmu_v2(user, args);
2407
2408                 kfree(args);
2409
2410                 return ret;
2411 #else
2412                 return -EACCES;
2413 #endif
2414         }
2415
2416         case TEGRA_DC_EXT_SET_VBLANK:
2417         {
2418                 struct tegra_dc_ext_set_vblank args;
2419
2420                 if (copy_from_user(&args, user_arg, sizeof(args)))
2421                         return -EFAULT;
2422
2423                 return tegra_dc_ext_set_vblank(user->ext, args.enable);
2424         }
2425
2426         /* Update only modified elements in CSC and LUT2.
2427          * Align writes to FRAME_END_INT */
2428         case TEGRA_DC_EXT_SET_CMU_ALIGNED:
2429         {
2430 #ifdef CONFIG_TEGRA_DC_CMU
2431                 int ret;
2432                 struct tegra_dc_ext_cmu *args;
2433
2434                 args = kzalloc(sizeof(*args), GFP_KERNEL);
2435                 if (!args)
2436                         return -ENOMEM;
2437
2438                 if (copy_from_user(args, user_arg, sizeof(*args))) {
2439                         kfree(args);
2440                         return -EFAULT;
2441                 }
2442
2443                 ret = tegra_dc_ext_set_cmu_aligned(user, args);
2444
2445                 kfree(args);
2446
2447                 return ret;
2448 #else
2449                 return -EACCES;
2450 #endif
2451         }
2452         case TEGRA_DC_EXT_GET_CAP_INFO:
2453         {
2454                 int ret = 0;
2455                 int nr_elements;
2456                 struct tegra_dc_ext_get_cap_info *args;
2457                 struct tegra_dc_ext_caps *cap_info;
2458
2459
2460                 args = kzalloc(sizeof(*args), GFP_KERNEL);
2461                 if (!args)
2462                         return -ENOMEM;
2463
2464                 if (copy_from_user(args, user_arg, sizeof(*args))) {
2465                         kfree(args);
2466                         return -EFAULT;
2467                 }
2468
2469                 nr_elements = args->nr_elements;
2470                 cap_info = kzalloc(sizeof(*cap_info)
2471                                         * nr_elements, GFP_KERNEL);
2472
2473                 if (copy_from_user(cap_info,
2474                         (void __user *) (uintptr_t)args->data,
2475                         sizeof(*cap_info) * nr_elements)) {
2476                         kfree(cap_info);
2477                         kfree(args);
2478                         return -EFAULT;
2479                 }
2480
2481                 ret = tegra_dc_get_cap_info(user, cap_info, nr_elements);
2482
2483                 kfree(cap_info);
2484                 kfree(args);
2485
2486                 return ret;
2487         }
2488
2489         default:
2490                 return -EINVAL;
2491         }
2492 }
2493
2494 static int tegra_dc_open(struct inode *inode, struct file *filp)
2495 {
2496         struct tegra_dc_ext_user *user;
2497         struct tegra_dc_ext *ext;
2498
2499         user = kzalloc(sizeof(*user), GFP_KERNEL);
2500         if (!user)
2501                 return -ENOMEM;
2502
2503         ext = container_of(inode->i_cdev, struct tegra_dc_ext, cdev);
2504         user->ext = ext;
2505
2506         filp->private_data = user;
2507
2508         return 0;
2509 }
2510
2511 static int tegra_dc_release(struct inode *inode, struct file *filp)
2512 {
2513         struct tegra_dc_ext_user *user = filp->private_data;
2514         struct tegra_dc_ext *ext = user->ext;
2515         unsigned int i;
2516         unsigned long int windows = 0;
2517
2518         for (i = 0; i < DC_N_WINDOWS; i++) {
2519                 if (ext->win[i].user == user) {
2520                         tegra_dc_ext_put_window(user, i);
2521                         windows |= BIT(i);
2522                 }
2523         }
2524
2525         if (ext->dc->enabled) {
2526                 tegra_dc_blank_wins(ext->dc, windows);
2527                 for_each_set_bit(i, &windows, DC_N_WINDOWS) {
2528                         tegra_dc_ext_unpin_window(&ext->win[i]);
2529                         tegra_dc_disable_window(ext->dc, i);
2530                 }
2531         }
2532
2533         if (ext->cursor.user == user)
2534                 tegra_dc_ext_put_cursor(user);
2535
2536         kfree(user);
2537
2538         return 0;
2539 }
2540
2541 static int tegra_dc_ext_setup_windows(struct tegra_dc_ext *ext)
2542 {
2543         int i, ret;
2544         struct sched_param sparm = { .sched_priority = 1 };
2545
2546         for (i = 0; i < ext->dc->n_windows; i++) {
2547                 struct tegra_dc_ext_win *win = &ext->win[i];
2548                 char name[32];
2549
2550                 win->ext = ext;
2551                 win->idx = i;
2552
2553                 snprintf(name, sizeof(name), "tegradc.%d/%c",
2554                          ext->dc->ndev->id, 'a' + i);
2555                 init_kthread_worker(&win->flip_worker);
2556                 win->flip_kthread = kthread_run(&kthread_worker_fn,
2557                         &win->flip_worker, name);
2558                 if (!win->flip_kthread) {
2559                         ret = -ENOMEM;
2560                         goto cleanup;
2561                 }
2562
2563                 sched_setscheduler(win->flip_kthread, SCHED_FIFO, &sparm);
2564
2565                 mutex_init(&win->lock);
2566                 mutex_init(&win->queue_lock);
2567                 mutex_init(&win->unpin_dma_lock);
2568                 INIT_LIST_HEAD(&win->timestamp_queue);
2569         }
2570
2571         return 0;
2572
2573 cleanup:
2574         while (i--) {
2575                 struct tegra_dc_ext_win *win = &ext->win[i];
2576                 kthread_stop(win->flip_kthread);
2577         }
2578
2579         return ret;
2580 }
2581
2582 static const struct file_operations tegra_dc_devops = {
2583         .owner =                THIS_MODULE,
2584         .open =                 tegra_dc_open,
2585         .release =              tegra_dc_release,
2586         .unlocked_ioctl =       tegra_dc_ioctl,
2587 #ifdef CONFIG_COMPAT
2588         .compat_ioctl =         tegra_dc_ioctl,
2589 #endif
2590 };
2591
2592 struct tegra_dc_ext *tegra_dc_ext_register(struct platform_device *ndev,
2593                                            struct tegra_dc *dc)
2594 {
2595         int ret;
2596         struct tegra_dc_ext *ext;
2597         dev_t devno;
2598
2599         ext = kzalloc(sizeof(*ext), GFP_KERNEL);
2600         if (!ext)
2601                 return ERR_PTR(-ENOMEM);
2602
2603         BUG_ON(!tegra_dc_ext_devno);
2604         devno = tegra_dc_ext_devno + head_count + 1;
2605
2606         cdev_init(&ext->cdev, &tegra_dc_devops);
2607         ext->cdev.owner = THIS_MODULE;
2608         ret = cdev_add(&ext->cdev, devno, 1);
2609         if (ret) {
2610                 dev_err(&ndev->dev, "Failed to create character device\n");
2611                 goto cleanup_alloc;
2612         }
2613
2614         ext->dev = device_create(tegra_dc_ext_class,
2615                                  &ndev->dev,
2616                                  devno,
2617                                  NULL,
2618                                  "tegra_dc_%d",
2619                                  ndev->id);
2620
2621         if (IS_ERR(ext->dev)) {
2622                 ret = PTR_ERR(ext->dev);
2623                 goto cleanup_cdev;
2624         }
2625
2626         ext->dc = dc;
2627
2628         ret = tegra_dc_ext_setup_windows(ext);
2629         if (ret)
2630                 goto cleanup_device;
2631
2632         mutex_init(&ext->cursor.lock);
2633
2634         head_count++;
2635
2636         return ext;
2637
2638 cleanup_device:
2639         device_del(ext->dev);
2640
2641 cleanup_cdev:
2642         cdev_del(&ext->cdev);
2643
2644 cleanup_alloc:
2645         kfree(ext);
2646
2647         return ERR_PTR(ret);
2648 }
2649
2650 void tegra_dc_ext_unregister(struct tegra_dc_ext *ext)
2651 {
2652         int i;
2653
2654         for (i = 0; i < ext->dc->n_windows; i++) {
2655                 struct tegra_dc_ext_win *win = &ext->win[i];
2656
2657                 flush_kthread_worker(&win->flip_worker);
2658                 kthread_stop(win->flip_kthread);
2659         }
2660
2661         device_del(ext->dev);
2662         cdev_del(&ext->cdev);
2663
2664         kfree(ext);
2665
2666         head_count--;
2667 }
2668
2669 int __init tegra_dc_ext_module_init(void)
2670 {
2671         int ret;
2672
2673         tegra_dc_ext_class = class_create(THIS_MODULE, "tegra_dc_ext");
2674         if (!tegra_dc_ext_class) {
2675                 printk(KERN_ERR "tegra_dc_ext: failed to create class\n");
2676                 return -ENOMEM;
2677         }
2678
2679         /* Reserve one character device per head, plus the control device */
2680         ret = alloc_chrdev_region(&tegra_dc_ext_devno,
2681                                   0, TEGRA_MAX_DC + 1,
2682                                   "tegra_dc_ext");
2683         if (ret)
2684                 goto cleanup_class;
2685
2686         ret = tegra_dc_ext_control_init();
2687         if (ret)
2688                 goto cleanup_region;
2689
2690         return 0;
2691
2692 cleanup_region:
2693         unregister_chrdev_region(tegra_dc_ext_devno, TEGRA_MAX_DC);
2694
2695 cleanup_class:
2696         class_destroy(tegra_dc_ext_class);
2697
2698         return ret;
2699 }
2700
2701 void __exit tegra_dc_ext_module_exit(void)
2702 {
2703         unregister_chrdev_region(tegra_dc_ext_devno, TEGRA_MAX_DC);
2704         class_destroy(tegra_dc_ext_class);
2705 }