video: tegra: dc: rename tegra_dc_blank
[linux-3.10.git] / drivers / video / tegra / tegra_adf.c
1 /*
2  * Copyright (C) 2013 Google, Inc.
3  * Copyright (c) 2014-2017, NVIDIA CORPORATION, All rights reserved.
4  *
5  * modified from drivers/video/tegra/dc/{mode.c,ext/dev.c}
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <linux/memblock.h>
19 #include <linux/gfp.h>
20 #include <media/videobuf2-dma-contig.h>
21 #include <video/adf.h>
22 #include <video/adf_client.h>
23 #include <video/adf_fbdev.h>
24 #include <video/adf_format.h>
25 #include <video/adf_memblock.h>
26
27 #include "dc/dc_config.h"
28 #include "dc/dc_priv.h"
29 #include "tegra_adf.h"
30
31 struct tegra_adf_info {
32         struct adf_device               base;
33         struct adf_interface            intf;
34         struct adf_overlay_engine       eng;
35 #if IS_ENABLED(CONFIG_ADF_TEGRA_FBDEV)
36         struct adf_fbdev                fbdev;
37 #endif
38         struct tegra_dc                 *dc;
39         struct tegra_fb_data            *fb_data;
40         void                            *vb2_dma_conf;
41 };
42
43 struct tegra_adf_flip_data {
44         u32 syncpt_max[DC_N_WINDOWS];
45         __u16 dirty_rect[4];
46         bool dirty_rect_valid;
47 };
48
49 #define adf_dev_to_tegra(p) \
50         container_of(p, struct tegra_adf_info, base)
51
52 #define adf_intf_to_tegra(p) \
53         container_of(p, struct tegra_adf_info, intf)
54
55 const u8 tegra_adf_fourcc_to_dc_fmt(u32 fourcc)
56 {
57         switch (fourcc) {
58         case TEGRA_ADF_FORMAT_P1:
59                 return TEGRA_WIN_FMT_P1;
60         case TEGRA_ADF_FORMAT_P2:
61                 return TEGRA_WIN_FMT_P2;
62         case TEGRA_ADF_FORMAT_P4:
63                 return TEGRA_WIN_FMT_P4;
64         case TEGRA_ADF_FORMAT_P8:
65                 return TEGRA_WIN_FMT_P8;
66         case DRM_FORMAT_BGRA4444:
67                 return TEGRA_WIN_FMT_B4G4R4A4;
68         case DRM_FORMAT_BGRA5551:
69                 return TEGRA_WIN_FMT_B5G5R5A;
70         case DRM_FORMAT_BGR565:
71                 return TEGRA_WIN_FMT_B5G6R5;
72         case DRM_FORMAT_BGRA8888:
73         case DRM_FORMAT_BGRX8888:
74                 return TEGRA_WIN_FMT_B8G8R8A8;
75         case DRM_FORMAT_RGBA8888:
76         case DRM_FORMAT_RGBX8888:
77                 return TEGRA_WIN_FMT_R8G8B8A8;
78         case TEGRA_ADF_FORMAT_B6x2G6x2R6x2A8:
79                 return TEGRA_WIN_FMT_B6x2G6x2R6x2A8;
80         case TEGRA_ADF_FORMAT_R6x2G6x2B6x2A8:
81                 return TEGRA_WIN_FMT_R6x2G6x2B6x2A8;
82         case DRM_FORMAT_YUV420:
83                 return TEGRA_WIN_FMT_YCbCr420P;
84         case DRM_FORMAT_YUV422:
85                 return TEGRA_WIN_FMT_YCbCr422P;
86         case TEGRA_ADF_FORMAT_YCbCr422R:
87                 return TEGRA_WIN_FMT_YCbCr422R;
88         case DRM_FORMAT_UYVY:
89                 return TEGRA_WIN_FMT_YCbCr422;
90         case DRM_FORMAT_NV12:
91                 return TEGRA_WIN_FMT_YCbCr420SP;
92         case DRM_FORMAT_NV21:
93                 return TEGRA_WIN_FMT_YCrCb420SP;
94         case DRM_FORMAT_NV16:
95                 return TEGRA_WIN_FMT_YCbCr422SP;
96         default:
97                 BUG();
98         }
99 }
100
101 static int tegra_dc_to_drm_modeinfo(struct drm_mode_modeinfo *dmode,
102         const struct tegra_dc_mode *mode)
103 {
104         long mode_pclk;
105
106         if (!dmode || !mode || !mode->pclk)
107                 return -EINVAL;
108         if (mode->rated_pclk >= 1000) /* handle DSI one-shot modes */
109                 mode_pclk = mode->rated_pclk;
110         else if (mode->pclk >= 1000) /* normal continous modes */
111                 mode_pclk = mode->pclk;
112         else
113                 mode_pclk = 0;
114         memset(dmode, 0, sizeof(*dmode));
115         dmode->hdisplay = mode->h_active;
116         dmode->vdisplay = mode->v_active;
117         dmode->hsync_start = dmode->hdisplay + mode->h_front_porch;
118         dmode->vsync_start = dmode->vdisplay + mode->v_front_porch;
119         dmode->hsync_end = dmode->hsync_start + mode->h_sync_width;
120         dmode->vsync_end = dmode->vsync_start + mode->v_sync_width;
121         dmode->htotal = dmode->hsync_end + mode->h_back_porch;
122         dmode->vtotal = dmode->vsync_end + mode->v_back_porch;
123 #if 0
124         if (mode->stereo_mode) {
125 #ifndef CONFIG_TEGRA_HDMI_74MHZ_LIMIT
126                 /* Double the pixel clock and update v_active only for
127                  * frame packed mode */
128                 mode_pclk /= 2;
129                 /* total v_active = yres*2 + activespace */
130                 fbmode->vdisplay = (mode->v_active - mode->v_sync_width -
131                         mode->v_back_porch - mode->v_front_porch) / 2;
132                 fbmode->vmode |= FB_VMODE_STEREO_FRAME_PACK;
133 #else
134                 fbmode->vmode |= FB_VMODE_STEREO_LEFT_RIGHT;
135 #endif
136         }
137 #endif
138
139         if (mode->flags & FB_VMODE_INTERLACED)
140                 dmode->flags |= DRM_MODE_FLAG_INTERLACE;
141
142         if ((mode->flags & TEGRA_DC_MODE_FLAG_NEG_H_SYNC))
143                 dmode->flags |= DRM_MODE_FLAG_NHSYNC;
144         else
145                 dmode->flags |= DRM_MODE_FLAG_PHSYNC;
146         if ((mode->flags & TEGRA_DC_MODE_FLAG_NEG_V_SYNC))
147                 dmode->flags |= DRM_MODE_FLAG_NVSYNC;
148         else
149                 dmode->flags |= DRM_MODE_FLAG_PVSYNC;
150 #if 0
151         if (mode->avi_m == TEGRA_DC_MODE_AVI_M_16_9)
152                 fbmode->flag |= FB_FLAG_RATIO_16_9;
153         else if (mode->avi_m == TEGRA_DC_MODE_AVI_M_4_3)
154                 fbmode->flag |= FB_FLAG_RATIO_4_3;
155 #endif
156
157         dmode->clock = mode_pclk / 1000;
158         dmode->vrefresh = tegra_dc_calc_refresh(mode) / 1000;
159
160         adf_modeinfo_set_name(dmode);
161
162         return 0;
163 }
164
165 static int tegra_adf_convert_monspecs(struct tegra_adf_info *adf_info,
166                 struct fb_monspecs *specs, struct drm_mode_modeinfo **modelist,
167                 size_t *n_modes)
168 {
169         struct tegra_dc *dc = adf_info->dc;
170         struct drm_mode_modeinfo *modes;
171         size_t n = 0;
172         u32 i;
173
174         modes = kmalloc(specs->modedb_len * sizeof(modes[0]), GFP_KERNEL);
175         if (!modes)
176                 return -ENOMEM;
177
178         for (i = 0; i < specs->modedb_len; i++) {
179                 struct fb_videomode *fb_mode = &specs->modedb[i];
180                 if (dc->out_ops->mode_filter &&
181                                 !dc->out_ops->mode_filter(dc, fb_mode))
182                         continue;
183                 adf_modeinfo_from_fb_videomode(fb_mode, &modes[n]);
184                 n++;
185         }
186
187         *modelist = modes;
188         *n_modes = n;
189         return 0;
190 }
191
192 static int tegra_adf_convert_builtin_modes(struct tegra_adf_info *adf_info,
193                 struct drm_mode_modeinfo **modelist, size_t *n_modes)
194 {
195         struct tegra_dc *dc = adf_info->dc;
196         struct drm_mode_modeinfo *modes;
197         u32 i;
198
199         modes = kmalloc(dc->out->n_modes * sizeof(modes[0]), GFP_KERNEL);
200         if (!modes)
201                 return -ENOMEM;
202
203         for (i = 0; i < dc->out->n_modes; i++) {
204                 int err = tegra_dc_to_drm_modeinfo(&modes[i],
205                                 &dc->out->modes[i]);
206                 if (err < 0)
207                         return err;
208         }
209
210         *modelist = modes;
211         *n_modes = dc->out->n_modes;
212         return 0;
213 }
214
215 static int tegra_adf_do_hotplug(struct tegra_adf_info *adf_info,
216                 struct drm_mode_modeinfo *modelist, size_t n_modes)
217 {
218         int err = tegra_dc_set_drm_mode(adf_info->dc, modelist, false);
219         if (err < 0)
220                 return err;
221         memcpy(&adf_info->intf.current_mode, &modelist[0], sizeof(modelist[0]));
222
223         return adf_hotplug_notify_connected(&adf_info->intf, modelist, n_modes);
224 }
225
226 int tegra_adf_process_hotplug_connected(struct tegra_adf_info *adf_info,
227                 struct fb_monspecs *specs)
228 {
229         struct tegra_dc_out *out = adf_info->dc->out;
230         struct drm_mode_modeinfo *modes;
231         size_t n_modes;
232         int err;
233
234         if (!specs && !out->modes) {
235                 struct drm_mode_modeinfo reset_mode = {0};
236                 return tegra_adf_do_hotplug(adf_info, &reset_mode, 1);
237         }
238
239         if (specs)
240                 err = tegra_adf_convert_monspecs(adf_info, specs, &modes,
241                                 &n_modes);
242         else
243                 err = tegra_adf_convert_builtin_modes(adf_info, &modes,
244                                 &n_modes);
245
246         if (err < 0)
247                 return err;
248
249         err = tegra_adf_do_hotplug(adf_info, modes, n_modes);
250         kfree(modes);
251         return err;
252 }
253
254 void tegra_adf_process_hotplug_disconnected(struct tegra_adf_info *adf_info)
255 {
256         adf_interface_blank(&adf_info->intf, DRM_MODE_DPMS_OFF);
257         adf_hotplug_notify_disconnected(&adf_info->intf);
258 }
259
260 static int tegra_adf_dev_custom_data(struct adf_obj *obj, void *data,
261                 size_t *size)
262 {
263         struct tegra_adf_capabilities *caps = data;
264
265         caps->caps = TEGRA_ADF_CAPABILITIES_CURSOR_MODE |
266                         TEGRA_ADF_CAPABILITIES_BLOCKLINEAR;
267         *size = sizeof(*caps);
268         return 0;
269 }
270
271 static int tegra_adf_dev_validate_custom_format(struct adf_device *dev,
272                 struct adf_buffer *buf)
273 {
274         u8 dc_fmt = tegra_adf_fourcc_to_dc_fmt(buf->format);
275
276         if (tegra_dc_is_yuv(dc_fmt)) {
277                 u8 cpp[3] = { 1, 1, 1 };
278                 return adf_format_validate_yuv(dev, buf, ARRAY_SIZE(cpp), 1, 2,
279                                 cpp);
280         } else {
281                 u8 cpp = tegra_dc_fmt_bpp(dc_fmt) / 8;
282                 return adf_format_validate_rgb(dev, buf, cpp);
283         }
284
285         return 0;
286 }
287
288 const u32 tegra_adf_formats[] = {
289         TEGRA_ADF_FORMAT_P1,
290         TEGRA_ADF_FORMAT_P2,
291         TEGRA_ADF_FORMAT_P4,
292         TEGRA_ADF_FORMAT_P8,
293         DRM_FORMAT_BGRA4444,
294         DRM_FORMAT_BGRA5551,
295         DRM_FORMAT_BGR565,
296         DRM_FORMAT_ABGR1555,
297         DRM_FORMAT_BGRA8888,
298         DRM_FORMAT_BGRX8888,
299         DRM_FORMAT_RGBA8888,
300         DRM_FORMAT_RGBX8888,
301         TEGRA_ADF_FORMAT_B6x2G6x2R6x2A8,
302         TEGRA_ADF_FORMAT_R6x2G6x2B6x2A8,
303         TEGRA_ADF_FORMAT_R6x2G6x2B6x2A8,
304         DRM_FORMAT_YUV420,
305         DRM_FORMAT_YUV422,
306         TEGRA_ADF_FORMAT_YCbCr422R,
307         DRM_FORMAT_UYVY,
308         DRM_FORMAT_NV12,
309         DRM_FORMAT_NV21,
310         DRM_FORMAT_NV16,
311 };
312
313 static inline int test_bit_u32(int nr, const u32 *addr)
314 {
315         return 1UL & (addr[nr / 32] >> (nr & 31));
316 }
317
318 static int tegra_adf_check_windowattr(struct tegra_adf_info *adf_info,
319                 const struct tegra_adf_flip_windowattr *attr, u32 fourcc)
320 {
321         u32 *addr;
322         struct tegra_dc *dc = adf_info->dc;
323         struct device *dev = &adf_info->base.base.dev;
324         u8 fmt = tegra_adf_fourcc_to_dc_fmt(fourcc);
325
326         addr = tegra_dc_parse_feature(dc, attr->win_index, GET_WIN_FORMATS);
327         /* Check if the window exists */
328         if (!addr) {
329                 dev_err(dev, "window %d feature is not found.\n",
330                                 attr->win_index);
331                 goto fail;
332         }
333         /* Check the window format */
334         if (!test_bit_u32(fmt, addr)) {
335                 dev_err(dev,
336                         "Color format of window %d is invalid.\n",
337                         attr->win_index);
338                 goto fail;
339         }
340
341         /* Check window size */
342         addr = tegra_dc_parse_feature(dc, attr->win_index, GET_WIN_SIZE);
343         if (CHECK_SIZE(attr->out_w, addr[MIN_WIDTH], addr[MAX_WIDTH]) ||
344                 CHECK_SIZE(attr->out_h, addr[MIN_HEIGHT], addr[MAX_HEIGHT])) {
345                 dev_err(dev,
346                         "Size of window %d is invalid with %d wide %d high.\n",
347                         attr->win_index, attr->out_w, attr->out_h);
348                 goto fail;
349         }
350
351         if (attr->flags & TEGRA_ADF_FLIP_FLAG_BLOCKLINEAR) {
352                 if (attr->flags & TEGRA_ADF_FLIP_FLAG_TILED) {
353                         dev_err(&dc->ndev->dev, "Layout cannot be both blocklinear and tile for window %d.\n",
354                                 attr->win_index);
355                         goto fail;
356                 }
357
358                 /* TODO: also check current window blocklinear support */
359         }
360
361         if ((attr->flags & TEGRA_ADF_FLIP_FLAG_SCAN_COLUMN) &&
362                         !tegra_dc_feature_has_scan_column(dc,
363                                         attr->win_index)) {
364                 dev_err(&dc->ndev->dev, "rotation not supported for window %d.\n",
365                                 attr->win_index);
366                 goto fail;
367         }
368
369         return 0;
370 fail:
371         return -EINVAL;
372 }
373
374 static int tegra_adf_sanitize_flip_args(struct tegra_adf_info *adf_info,
375                 struct adf_post *cfg,
376                 struct tegra_adf_flip_windowattr *win, int win_num,
377                 __u16 *dirty_rect[4])
378 {
379         struct device *dev = &adf_info->base.base.dev;
380         struct tegra_dc *dc = adf_info->dc;
381         int i, used_windows = 0;
382
383         if (win_num > DC_N_WINDOWS) {
384                 dev_err(dev, "too many windows (%u > %u)\n", win_num,
385                                 DC_N_WINDOWS);
386                 return -EINVAL;
387         }
388
389         for (i = 0; i < win_num; i++) {
390                 int index = win[i].win_index;
391                 int buf_index = win[i].buf_index;
392                 int err;
393
394                 if (index < 0)
395                         continue;
396
397                 if (index >= DC_N_WINDOWS ||
398                                 !test_bit(index, &dc->valid_windows)) {
399                         dev_err(dev, "invalid window index %u\n", index);
400                         return -EINVAL;
401                 }
402
403                 if (used_windows & BIT(index)) {
404                         dev_err(dev, "window index %u already used\n", index);
405                         return -EINVAL;
406                 }
407
408                 if (buf_index >= 0) {
409                         if (buf_index >= cfg->n_bufs) {
410                                 dev_err(dev, "invalid buffer index %d (n_bufs = %zu)\n",
411                                                 buf_index, cfg->n_bufs);
412                                 return -EINVAL;
413                         }
414
415                         err = tegra_adf_check_windowattr(adf_info, &win[i],
416                                         cfg->bufs[buf_index].format);
417                         if (err < 0)
418                                 return err;
419                 }
420
421                 used_windows |= BIT(index);
422         }
423
424         if (!used_windows) {
425                 dev_err(dev, "no windows used\n");
426                 return -EINVAL;
427         }
428
429         if (*dirty_rect) {
430                 unsigned int xoff = (*dirty_rect)[0];
431                 unsigned int yoff = (*dirty_rect)[1];
432                 unsigned int width = (*dirty_rect)[2];
433                 unsigned int height = (*dirty_rect)[3];
434                 struct tegra_dc *dc = adf_info->dc;
435
436                 if ((!width && !height) || dc->mode.vmode == FB_VMODE_INTERLACED
437                                 || !dc->out_ops || !dc->out_ops->partial_update
438                                 || (!xoff && !yoff
439                                                 && (width == dc->mode.h_active)
440                                                 && (height == dc->mode.v_active))) {
441                         /* Partial update undesired, unsupported,
442                          * or dirty_rect covers entire frame. */
443                         *dirty_rect = 0;
444                 } else {
445                         if (!width || !height
446                                         || (xoff + width) > dc->mode.h_active
447                                         || (yoff + height) > dc->mode.v_active)
448                                 return -EINVAL;
449
450                         /* Constraint 7: H/V_DISP_ACTIVE >= 16.
451                          * Make sure the minimal size of dirty region is 16*16.
452                          * If not, extend the dirty region. */
453                         if (width < 16) {
454                                 width = (*dirty_rect)[2] = 16;
455                                 if (xoff + width > dc->mode.h_active)
456                                         (*dirty_rect)[0] = dc->mode.h_active
457                                                         - width;
458                         }
459                         if (height < 16) {
460                                 height = (*dirty_rect)[3] = 16;
461                                 if (yoff + height > dc->mode.v_active)
462                                         (*dirty_rect)[1] = dc->mode.v_active
463                                                         - height;
464                         }
465                 }
466         }
467
468         return 0;
469 }
470
471 int tegra_adf_dev_validate(struct adf_device *dev, struct adf_post *cfg,
472                 void **driver_state)
473 {
474         struct tegra_adf_flip *args = cfg->custom_data;
475         struct tegra_adf_info *adf_info = adf_dev_to_tegra(dev);
476         struct tegra_adf_flip_windowattr *win;
477         struct tegra_adf_flip_data *data;
478         unsigned int win_num;
479         size_t custom_data_size = sizeof(*args);
480         __u16 *dirty_rect;
481         int ret = 0;
482
483         if (cfg->custom_data_size < custom_data_size) {
484                 dev_err(dev->dev, "custom data size too small (%zu < %zu)\n",
485                                 cfg->custom_data_size, custom_data_size);
486                 return -EINVAL;
487         }
488
489         win = args->win;
490         win_num = args->win_num;
491
492         custom_data_size += win_num * sizeof(win[0]);
493         if (cfg->custom_data_size != custom_data_size) {
494                 dev_err(dev->dev, "expected %zu bytes of custom data for %u windows, received %zu\n",
495                                 custom_data_size, args->win_num,
496                                 cfg->custom_data_size);
497                 return -EINVAL;
498         }
499
500         data = kzalloc(sizeof(*data), GFP_KERNEL);
501         if (!data) {
502                 dev_err(dev->dev, "failed to allocate driver state\n");
503                 return -ENOMEM;
504         }
505
506         dirty_rect = args->dirty_rect;
507         ret = tegra_adf_sanitize_flip_args(adf_info, cfg, win, win_num,
508                         &dirty_rect);
509         if (ret < 0)
510                 goto done;
511
512         if (dirty_rect) {
513                 memcpy(data->dirty_rect, dirty_rect, sizeof(data->dirty_rect));
514                 data->dirty_rect_valid = true;
515         }
516
517         BUG_ON(win_num > DC_N_WINDOWS);
518
519 done:
520         if (ret < 0)
521                 kfree(data);
522         else
523                 *driver_state = data;
524         return ret;
525 }
526
527 static inline dma_addr_t tegra_adf_phys_addr(struct adf_buffer *buf,
528                 struct adf_buffer_mapping *mapping,
529                 size_t plane)
530 {
531         struct scatterlist *sgl = buf->dma_bufs[plane] ?
532                         mapping->sg_tables[plane]->sgl :
533                         mapping->sg_tables[TEGRA_DC_Y]->sgl;
534
535         dma_addr_t addr = sg_dma_address(sgl);
536         if (!addr)
537                 addr = sg_phys(sgl);
538         addr += buf->offset[plane];
539         return addr;
540 }
541
542 static void tegra_adf_set_windowattr_basic(struct tegra_dc_win *win,
543                 const struct tegra_adf_flip_windowattr *attr,
544                 u32 format)
545 {
546         win->flags = TEGRA_WIN_FLAG_ENABLED;
547         if (attr->blend == TEGRA_ADF_BLEND_PREMULT)
548                 win->flags |= TEGRA_WIN_FLAG_BLEND_PREMULT;
549         else if (attr->blend == TEGRA_ADF_BLEND_COVERAGE)
550                 win->flags |= TEGRA_WIN_FLAG_BLEND_COVERAGE;
551         if (attr->flags & TEGRA_ADF_FLIP_FLAG_TILED)
552                 win->flags |= TEGRA_WIN_FLAG_TILED;
553         if (attr->flags & TEGRA_ADF_FLIP_FLAG_INVERT_H)
554                 win->flags |= TEGRA_WIN_FLAG_INVERT_H;
555         if (attr->flags & TEGRA_ADF_FLIP_FLAG_INVERT_V)
556                 win->flags |= TEGRA_WIN_FLAG_INVERT_V;
557         if (attr->flags & TEGRA_ADF_FLIP_FLAG_GLOBAL_ALPHA)
558                 win->global_alpha = attr->global_alpha;
559         else
560                 win->global_alpha = 255;
561 #if defined(CONFIG_TEGRA_DC_SCAN_COLUMN)
562         if (attr->flags & TEGRA_ADF_FLIP_FLAG_SCAN_COLUMN)
563                 win->flags |= TEGRA_WIN_FLAG_SCAN_COLUMN;
564 #endif
565 #if defined(CONFIG_TEGRA_DC_BLOCK_LINEAR)
566         if (attr->flags & TEGRA_ADF_FLIP_FLAG_BLOCKLINEAR) {
567                 win->flags |= TEGRA_WIN_FLAG_BLOCKLINEAR;
568                 win->block_height_log2 = attr->block_height_log2;
569         }
570 #endif
571 #if defined(CONFIG_TEGRA_DC_CDE)
572         if (attr->flags & TEGRA_ADF_FLIP_FLAG_COMPRESSED) {
573                 win->cde.offset_x = attr->cde.offset_x;
574                 win->cde.offset_y = attr->cde.offset_y;
575                 win->cde.zbc_color = attr->cde.zbc_color;
576                 win->cde.ctb_entry = 0x02;
577         }
578 #endif
579 #if defined(CONFIG_TEGRA_DC_INTERLACE)
580         if (attr->flags & TEGRA_ADF_FLIP_FLAG_INTERLACE)
581                 win->flags |= TEGRA_WIN_FLAG_INTERLACE;
582 #endif
583
584         win->fmt = tegra_adf_fourcc_to_dc_fmt(format);
585         win->x.full = attr->x;
586         win->y.full = attr->y;
587         win->w.full = attr->w;
588         win->h.full = attr->h;
589         /* XXX verify that this doesn't go outside display's active region */
590         win->out_x = attr->out_x;
591         win->out_y = attr->out_y;
592         win->out_w = attr->out_w;
593         win->out_h = attr->out_h;
594         win->z = attr->z;
595 }
596
597 static void tegra_adf_set_windowattr(struct tegra_adf_info *adf_info,
598                 struct tegra_dc_win *win,
599                 const struct tegra_adf_flip_windowattr *attr,
600                 struct adf_buffer *buf, struct adf_buffer_mapping *mapping)
601 {
602         if (!buf) {
603                 win->flags = 0;
604                 return;
605         }
606
607         tegra_adf_set_windowattr_basic(win, attr, buf->format);
608
609         win->stride = buf->pitch[0];
610         win->stride_uv = buf->pitch[1];
611
612         /* XXX verify that this won't read outside of the surface */
613         win->phys_addr = tegra_adf_phys_addr(buf, mapping, TEGRA_DC_Y);
614         win->phys_addr_u = tegra_adf_phys_addr(buf, mapping, TEGRA_DC_U);
615         win->phys_addr_v = tegra_adf_phys_addr(buf, mapping, TEGRA_DC_V);
616
617 #if defined(CONFIG_TEGRA_DC_INTERLACE)
618         if (adf_info->dc->mode.vmode == FB_VMODE_INTERLACED) {
619                 if (attr->flags & TEGRA_ADF_FLIP_FLAG_INTERLACE) {
620                         win->phys_addr2 = win->phys_addr + attr->offset2;
621                         win->phys_addr_u2 = win->phys_addr_u + attr->offset_u2;
622                         win->phys_addr_v2 = win->phys_addr_v + attr->offset_v2;
623                 } else {
624                         win->phys_addr2 = win->phys_addr;
625                         win->phys_addr_u2 = win->phys_addr_u;
626                         win->phys_addr_v2 = win->phys_addr_v;
627                 }
628         }
629 #endif
630
631 #if defined(CONFIG_TEGRA_DC_CDE)
632         if (attr->flags & TEGRA_DC_EXT_FLIP_FLAG_COMPRESSED) {
633                 win->cde.cde_addr = win->phys_addr + attr->cde.offset;
634         } else {
635                 win->cde.cde_addr = 0;
636         }
637 #endif
638
639         if (attr->flags & TEGRA_ADF_FLIP_FLAG_UPDATE_CSC) {
640                 win->csc.yof = attr->csc.yof;
641                 win->csc.kyrgb = attr->csc.kyrgb;
642                 win->csc.kur = attr->csc.kur;
643                 win->csc.kug = attr->csc.kug;
644                 win->csc.kub = attr->csc.kub;
645                 win->csc.kvr = attr->csc.kvr;
646                 win->csc.kvg = attr->csc.kvg;
647                 win->csc.kvb = attr->csc.kvb;
648                 win->csc_dirty = true;
649         }
650
651         if (tegra_platform_is_silicon()) {
652                 dev_WARN_ONCE(&adf_info->base.base.dev, attr->timestamp_ns,
653                                 "timestamping not implemented\n");
654                 /* TODO: implement timestamping */
655 #if 0
656                 if (timestamp_ns) {
657                         /* XXX: Should timestamping be overridden by "no_vsync"
658                          * flag */
659                         tegra_dc_config_frame_end_intr(win->dc, true);
660                         err = wait_event_interruptible(win->dc->timestamp_wq,
661                                 tegra_dc_is_within_n_vsync(win->dc,
662                                                 timestamp_ns));
663                         tegra_dc_config_frame_end_intr(win->dc, false);
664                 }
665 #endif
666         }
667 }
668
669 static void tegra_adf_dev_post(struct adf_device *dev, struct adf_post *cfg,
670                 void *driver_state)
671 {
672         struct tegra_adf_info *adf_info = adf_dev_to_tegra(dev);
673         struct tegra_adf_flip *args = cfg->custom_data;
674         struct tegra_adf_flip_data *data = driver_state;
675         int win_num = args->win_num;
676         struct tegra_dc_win *wins[DC_N_WINDOWS];
677         int i, nr_win = 0;
678         bool skip_flip = false;
679
680         BUG_ON(win_num > DC_N_WINDOWS);
681         for (i = 0; i < win_num; i++) {
682                 struct tegra_adf_flip_windowattr *attr = &args->win[i];
683                 int index = attr->win_index;
684                 struct adf_buffer *buf;
685                 struct adf_buffer_mapping *mapping;
686                 struct tegra_dc_win *win;
687
688                 if (index < 0)
689                         continue;
690
691                 if (attr->buf_index < 0) {
692                         buf = NULL;
693                         mapping = NULL;
694                 } else {
695                         buf = &cfg->bufs[attr->buf_index];
696                         mapping = &cfg->mappings[attr->buf_index];
697                 }
698
699                 win = tegra_dc_get_window(adf_info->dc, index);
700
701 #if 0
702                 if (flip_win->flags & TEGRA_ADF_FLIP_FLAG_CURSOR)
703                         skip_flip = true;
704
705                 mutex_lock(&ext_win->queue_lock);
706                 list_for_each_entry(temp, &ext_win->timestamp_queue,
707                                 timestamp_node) {
708                         if (!tegra_platform_is_silicon())
709                                 continue;
710                         if (j == 0) {
711                                 if (unlikely(temp != data))
712                                         dev_err(&win->dc->ndev->dev,
713                                                         "work queue did NOT dequeue head!!!");
714                                 else
715                                         head_timestamp =
716                                                 timespec_to_ns(&flip_win->attr.timestamp);
717                         } else {
718                                 s64 timestamp =
719                                         timespec_to_ns(&temp->win[i].attr.timestamp);
720
721                                 skip_flip = !tegra_dc_does_vsync_separate(ext->dc,
722                                                 timestamp, head_timestamp);
723                                 /* Look ahead only one flip */
724                                 break;
725                         }
726                         j++;
727                 }
728                 if (!list_empty(&ext_win->timestamp_queue))
729                         list_del(&data->timestamp_node);
730                 mutex_unlock(&ext_win->queue_lock);
731
732                 if (skip_flip)
733                         old_handle = flip_win->handle[TEGRA_DC_Y];
734                 else
735                         old_handle = ext_win->cur_handle[TEGRA_DC_Y];
736
737                 if (old_handle) {
738                         int j;
739                         for (j = 0; j < TEGRA_DC_NUM_PLANES; j++) {
740                                 if (skip_flip)
741                                         old_handle = flip_win->handle[j];
742                                 else
743                                         old_handle = ext_win->cur_handle[j];
744
745                                 if (!old_handle)
746                                         continue;
747
748                                 unpin_handles[nr_unpin++] = old_handle;
749                         }
750                 }
751
752                 if (!skip_flip)
753 #endif
754                         tegra_adf_set_windowattr(adf_info, win, attr, buf,
755                                         mapping);
756
757                 wins[nr_win++] = win;
758         }
759
760         if (!skip_flip) {
761                 tegra_dc_update_windows(wins, nr_win,
762                         data->dirty_rect_valid ? data->dirty_rect : NULL, true);
763                 /* TODO: implement swapinterval here */
764                 tegra_dc_sync_windows(wins, nr_win);
765                 tegra_dc_program_bandwidth(adf_info->dc, true);
766                 if (!tegra_dc_has_multiple_dc())
767                         tegra_dc_call_flip_callback();
768         }
769 }
770
771 static struct sync_fence *tegra_adf_dev_complete_fence(struct adf_device *dev,
772                 struct adf_post *cfg, void *driver_state)
773 {
774         struct tegra_adf_info *adf_info = adf_dev_to_tegra(dev);
775         struct tegra_adf_flip *args = cfg->custom_data;
776         struct tegra_adf_flip_windowattr *win = args->win;
777         struct tegra_adf_flip_data *data = driver_state;
778         u32 syncpt_val;
779         int work_index = -1;
780         unsigned int win_num = args->win_num, i;
781
782         for (i = 0; i < win_num; i++) {
783                 int index = win[i].win_index;
784
785                 if (index < 0)
786                         continue;
787
788                 data->syncpt_max[i] = tegra_dc_incr_syncpt_max(adf_info->dc,
789                                 index);
790
791                 /*
792                  * Any of these windows' syncpoints should be equivalent for
793                  * the client, so we just send back an arbitrary one of them
794                  */
795                 syncpt_val = data->syncpt_max[i];
796                 work_index = index;
797         }
798         if (work_index < 0)
799                 return ERR_PTR(-EINVAL);
800
801         return tegra_dc_create_fence(adf_info->dc, work_index, syncpt_val + 1);
802 }
803
804 static void tegra_adf_dev_advance_timeline(struct adf_device *dev,
805                 struct adf_post *cfg, void *driver_state)
806 {
807         struct tegra_adf_info *adf_info = adf_dev_to_tegra(dev);
808         struct tegra_adf_flip *args = cfg->custom_data;
809         struct tegra_adf_flip_windowattr *win = args->win;
810         u32 *syncpt_max = driver_state;
811         unsigned int win_num = args->win_num, i;
812
813         for (i = 0; i < win_num; i++) {
814                 int index = win[i].win_index;
815
816                 if (index < 0)
817                         continue;
818
819                 tegra_dc_incr_syncpt_min(adf_info->dc, index, syncpt_max[i]);
820         }
821 }
822
823 static void tegra_adf_dev_state_free(struct adf_device *dev, void *driver_state)
824 {
825         kfree(driver_state);
826 }
827
828 static int tegra_adf_negotiate_bw(struct tegra_adf_info *adf_info,
829                         struct tegra_adf_proposed_bw *bw)
830 {
831 #ifdef CONFIG_TEGRA_ISOMGR
832         struct tegra_dc_win *dc_wins[DC_N_WINDOWS];
833         struct tegra_dc *dc = adf_info->dc;
834         struct adf_overlay_engine *eng = &adf_info->eng;
835         u8 i;
836
837         /* If display has been disconnected return with error. */
838         if (!dc->connected)
839                 return -1;
840
841         for (i = 0; i < bw->win_num; i++) {
842                 struct tegra_adf_flip_windowattr *attr = &bw->win[i].attr;
843                 s32 idx = attr->win_index;
844
845                 if (attr->buf_index >= 0) {
846                         u32 fourcc = bw->win[i].format;
847                         if (!adf_overlay_engine_supports_format(eng, fourcc)) {
848                                 char format_str[ADF_FORMAT_STR_SIZE];
849                                 adf_format_str(fourcc, format_str);
850                                 dev_err(&eng->base.dev, "%s: unsupported format %s\n",
851                                                 __func__, format_str);
852                                 return -EINVAL;
853                         }
854
855                         tegra_adf_set_windowattr_basic(&dc->tmp_wins[idx],
856                                         attr, fourcc);
857                 } else {
858                         dc->tmp_wins[i].flags = 0;
859                 }
860
861                 dc_wins[i] = &dc->tmp_wins[idx];
862         }
863
864         return tegra_dc_bandwidth_negotiate_bw(dc, dc_wins, bw->win_num);
865 #else
866         return -EINVAL;
867 #endif
868 }
869
870 static int tegra_adf_set_proposed_bw(struct tegra_adf_info *adf_info,
871                         struct tegra_adf_proposed_bw __user *arg)
872 {
873         u8 win_num;
874         size_t bw_size;
875         struct tegra_adf_proposed_bw *bw;
876         int ret;
877
878         if (get_user(win_num, &arg->win_num))
879                 return -EFAULT;
880
881         bw_size = sizeof(*bw) + sizeof(bw->win[0]) * win_num;
882         bw = kmalloc(bw_size, GFP_KERNEL);
883         if (!bw)
884                 return -ENOMEM;
885
886         if (copy_from_user(bw, arg, bw_size)) {
887                 ret = -EFAULT;
888                 goto done;
889         }
890
891         ret = tegra_adf_negotiate_bw(adf_info, bw);
892 done:
893         kfree(bw);
894         return ret;
895 }
896
897 static long tegra_adf_dev_ioctl(struct adf_obj *obj, unsigned int cmd,
898                 unsigned long arg)
899 {
900         struct adf_device *dev = adf_obj_to_device(obj);
901         struct tegra_adf_info *adf_info = adf_dev_to_tegra(dev);
902
903         switch (cmd) {
904         case TEGRA_ADF_SET_PROPOSED_BW:
905                 return tegra_adf_set_proposed_bw(adf_info,
906                                 (struct tegra_adf_proposed_bw __user *)arg);
907
908         default:
909                 return -ENOTTY;
910         }
911 }
912
913
914 void tegra_adf_process_vblank(struct tegra_adf_info *adf_info,
915                 ktime_t timestamp)
916 {
917         if (unlikely(!adf_info))
918                 pr_debug("%s: suppressing vblank event since ADF is not finished probing\n",
919                                 __func__);
920         else
921                 adf_vsync_notify(&adf_info->intf, timestamp);
922 }
923
924 static bool tegra_adf_intf_supports_event(struct adf_obj *obj,
925                 enum adf_event_type type)
926 {
927         struct adf_interface *intf = adf_obj_to_interface(obj);
928         struct tegra_adf_info *tegra_adf = adf_intf_to_tegra(intf);
929
930         switch (type) {
931         case ADF_EVENT_VSYNC:
932                 return true;
933         case ADF_EVENT_HOTPLUG:
934                 return tegra_dc_get_out(tegra_adf->dc) == TEGRA_DC_OUT_HDMI;
935         default:
936                 return false;
937         }
938 }
939
940 static void tegra_adf_set_vsync(struct tegra_adf_info *tegra_adf, bool enabled)
941 {
942         if (enabled) {
943                 tegra_dc_hold_dc_out(tegra_adf->dc);
944                 tegra_dc_vsync_enable(tegra_adf->dc);
945         } else {
946                 tegra_dc_vsync_disable(tegra_adf->dc);
947                 tegra_dc_release_dc_out(tegra_adf->dc);
948         }
949 }
950
951 static void tegra_adf_intf_set_event(struct adf_obj *obj,
952                 enum adf_event_type type, bool enabled)
953 {
954         struct adf_interface *intf = adf_obj_to_interface(obj);
955         struct tegra_adf_info *tegra_adf = adf_intf_to_tegra(intf);
956
957         switch (type) {
958         case ADF_EVENT_VSYNC:
959                 tegra_adf_set_vsync(tegra_adf, enabled);
960                 return;
961
962         case ADF_EVENT_HOTPLUG:
963                 return;
964
965         default:
966                 BUG();
967         }
968 }
969
970 static enum adf_interface_type tegra_adf_interface_type(struct tegra_dc *dc)
971 {
972         /* TODO: can RGB and LVDS be mapped to existing ADF_INTF types?
973          * Should they be added to ADF's list? */
974         switch (tegra_dc_get_out(dc)) {
975         case TEGRA_DC_OUT_RGB:
976                 return TEGRA_ADF_INTF_RGB;
977         case TEGRA_DC_OUT_HDMI:
978                 return ADF_INTF_HDMI;
979         case TEGRA_DC_OUT_DSI:
980                 return ADF_INTF_DSI;
981         case TEGRA_DC_OUT_DP:
982                 return ADF_INTF_eDP;
983         case TEGRA_DC_OUT_LVDS:
984                 return TEGRA_ADF_INTF_LVDS;
985         default:
986                 BUG();
987         }
988 }
989
990 static const char *tegra_adf_intf_type_str(struct adf_interface *intf)
991 {
992         switch ((enum tegra_adf_interface_type)intf->type) {
993         case TEGRA_ADF_INTF_RGB:
994                 return "RGB";
995         case TEGRA_ADF_INTF_LVDS:
996                 return "LVDS";
997         default:
998                 BUG();
999         }
1000 }
1001
1002 #if IS_ENABLED(CONFIG_ADF_TEGRA_FBDEV)
1003 static int tegra_adf_dpms_to_fb_blank(u8 dpms_state)
1004 {
1005         switch (dpms_state) {
1006         case DRM_MODE_DPMS_ON:
1007                 return FB_BLANK_UNBLANK;
1008         case DRM_MODE_DPMS_STANDBY:
1009                 return FB_BLANK_HSYNC_SUSPEND;
1010         case DRM_MODE_DPMS_SUSPEND:
1011                 return FB_BLANK_VSYNC_SUSPEND;
1012         case DRM_MODE_DPMS_OFF:
1013                 return FB_BLANK_POWERDOWN;
1014         default:
1015                 BUG();
1016         }
1017 }
1018 #endif
1019
1020 static int tegra_adf_intf_blank(struct adf_interface *intf, u8 state)
1021 {
1022         struct tegra_adf_info *adf_info = adf_intf_to_tegra(intf);
1023
1024         switch (state) {
1025         case DRM_MODE_DPMS_ON:
1026                 tegra_dc_enable(adf_info->dc);
1027                 break;
1028
1029         case DRM_MODE_DPMS_STANDBY:
1030                 tegra_dc_blank_wins(adf_info->dc, BLANK_ALL);
1031                 break;
1032
1033         case DRM_MODE_DPMS_SUSPEND:
1034         case DRM_MODE_DPMS_OFF:
1035                 tegra_dc_disable(adf_info->dc);
1036                 break;
1037
1038         default:
1039                 return -ENOTTY;
1040         }
1041
1042 #if IS_ENABLED(CONFIG_ADF_TEGRA_FBDEV)
1043         if (intf->flags & ADF_INTF_FLAG_PRIMARY) {
1044                 struct fb_event event;
1045                 int fb_state = tegra_adf_dpms_to_fb_blank(state);
1046
1047                 event.info = adf_info->fbdev.info;
1048                 event.data = &fb_state;
1049                 fb_notifier_call_chain(FB_EVENT_BLANK, &event);
1050         }
1051 #endif
1052
1053         return 0;
1054 }
1055
1056 static int tegra_adf_intf_alloc_simple_buffer(struct adf_interface *intf,
1057                 u16 w, u16 h, u32 format,
1058                 struct dma_buf **dma_buf, u32 *offset, u32 *pitch)
1059 {
1060         size_t i;
1061         struct tegra_adf_info *adf_info = adf_intf_to_tegra(intf);
1062         const struct vb2_mem_ops *mem_ops = &vb2_dma_contig_memops;
1063         void *vb2_buf;
1064         bool format_valid = false;
1065
1066         for (i = 0; i < ARRAY_SIZE(tegra_adf_formats); i++) {
1067                 if (tegra_adf_formats[i] == format) {
1068                         format_valid = true;
1069                         break;
1070                 }
1071         }
1072
1073         if (!format_valid)
1074                 return -EINVAL;
1075
1076         *offset = 0;
1077         *pitch = ALIGN(w * adf_format_bpp(format) / 8, 64);
1078
1079         vb2_buf = mem_ops->alloc(adf_info->vb2_dma_conf,
1080                                  h * *pitch, __GFP_HIGHMEM);
1081         if (IS_ERR(vb2_buf))
1082                 return PTR_ERR(vb2_buf);
1083
1084         *dma_buf = mem_ops->get_dmabuf(vb2_buf);
1085         mem_ops->put(vb2_buf);
1086         if (!*dma_buf)
1087                 return -ENOMEM;
1088
1089         return 0;
1090 }
1091
1092 static int tegra_adf_intf_describe_simple_post(struct adf_interface *intf,
1093                 struct adf_buffer *fb, void *data, size_t *size)
1094 {
1095         struct tegra_adf_info *adf_info = adf_intf_to_tegra(intf);
1096         struct tegra_adf_flip *args = data;
1097         int i;
1098
1099         args->win_num = 0;
1100         for_each_set_bit(i, &adf_info->dc->valid_windows, DC_N_WINDOWS) {
1101                 struct tegra_adf_flip_windowattr *win =
1102                                 &args->win[args->win_num];
1103                 win->win_index = i;
1104                 if (i == adf_info->fb_data->win) {
1105                         win->buf_index = 0;
1106                         win->out_w = intf->current_mode.hdisplay;
1107                         win->out_h = intf->current_mode.vdisplay;
1108                 } else {
1109                         win->buf_index = -1;
1110                 }
1111                 args->win_num++;
1112         }
1113
1114         *size = sizeof(*args) + args->win_num * sizeof(args->win[0]);
1115         return 0;
1116 }
1117
1118 static int tegra_adf_intf_modeset(struct adf_interface *intf,
1119                 struct drm_mode_modeinfo *mode)
1120 {
1121         struct tegra_adf_info *adf_info = adf_intf_to_tegra(intf);
1122         return tegra_dc_set_drm_mode(adf_info->dc, mode, false);
1123 }
1124
1125 static int tegra_adf_intf_screen_size(struct adf_interface *intf, u16 *width_mm,
1126                 u16 *height_mm)
1127 {
1128         struct tegra_adf_info *adf_info = adf_intf_to_tegra(intf);
1129         struct tegra_dc_out *out = adf_info->dc->out;
1130
1131         if (!out->height)
1132                 return -EINVAL;
1133
1134         *width_mm = out->width;
1135         *height_mm = out->height;
1136         return 0;
1137 }
1138
1139 struct adf_device_ops tegra_adf_dev_ops = {
1140         .owner = THIS_MODULE,
1141         .base = {
1142                 .custom_data = tegra_adf_dev_custom_data,
1143                 .ioctl = tegra_adf_dev_ioctl,
1144         },
1145         .validate_custom_format = tegra_adf_dev_validate_custom_format,
1146         .validate = tegra_adf_dev_validate,
1147         .complete_fence = tegra_adf_dev_complete_fence,
1148         .post = tegra_adf_dev_post,
1149         .advance_timeline = tegra_adf_dev_advance_timeline,
1150         .state_free = tegra_adf_dev_state_free,
1151 };
1152
1153 struct adf_interface_ops tegra_adf_intf_ops = {
1154         .base = {
1155                 .supports_event = tegra_adf_intf_supports_event,
1156                 .set_event = tegra_adf_intf_set_event,
1157         },
1158         .blank = tegra_adf_intf_blank,
1159         .alloc_simple_buffer = tegra_adf_intf_alloc_simple_buffer,
1160         .describe_simple_post = tegra_adf_intf_describe_simple_post,
1161         .modeset = tegra_adf_intf_modeset,
1162         .screen_size = tegra_adf_intf_screen_size,
1163         .type_str = tegra_adf_intf_type_str,
1164 };
1165
1166 struct adf_overlay_engine_ops tegra_adf_eng_ops = {
1167         .supported_formats = tegra_adf_formats,
1168         .n_supported_formats = ARRAY_SIZE(tegra_adf_formats),
1169 };
1170
1171 int tegra_adf_process_bandwidth_renegotiate(struct tegra_adf_info *adf_info,
1172                                                 struct tegra_dc_bw_data *bw)
1173 {
1174         struct tegra_adf_event_bandwidth event;
1175         event.base.type = TEGRA_ADF_EVENT_BANDWIDTH_RENEGOTIATE;
1176         event.base.length = sizeof(event);
1177         event.total_bw = bw->total_bw;
1178         event.avail_bw = bw->avail_bw;
1179         event.resvd_bw = bw->resvd_bw;
1180         return adf_event_notify(&adf_info->base.base, &event.base);
1181 }
1182
1183 struct fb_ops tegra_adf_fb_ops = {
1184         .owner = THIS_MODULE,
1185         .fb_open = adf_fbdev_open,
1186         .fb_release = adf_fbdev_release,
1187         .fb_check_var = adf_fbdev_check_var,
1188         .fb_set_par = adf_fbdev_set_par,
1189         .fb_blank = adf_fbdev_blank,
1190         .fb_pan_display = adf_fbdev_pan_display,
1191         .fb_mmap = adf_fbdev_mmap,
1192 };
1193
1194 static void tegra_adf_save_bootloader_logo(struct tegra_adf_info *adf_info,
1195             struct resource *fb_mem)
1196 {
1197         struct device *dev = adf_info->base.dev;
1198         struct adf_buffer logo;
1199         struct sync_fence *fence;
1200
1201         memset(&logo, 0, sizeof(logo));
1202         logo.dma_bufs[0] = adf_memblock_export(fb_mem->start,
1203                         resource_size(fb_mem), 0);
1204         if (IS_ERR(logo.dma_bufs[0])) {
1205                 dev_warn(dev, "failed to export bootloader logo: %ld\n",
1206                                 PTR_ERR(logo.dma_bufs[0]));
1207                 return;
1208         }
1209
1210         logo.overlay_engine = &adf_info->eng;
1211         logo.w = adf_info->fb_data->xres;
1212         logo.h = adf_info->fb_data->yres;
1213         logo.format = adf_info->fb_data->bits_per_pixel == 16 ?
1214                         DRM_FORMAT_RGB565 :
1215                         DRM_FORMAT_RGBA8888;
1216         logo.pitch[0] = logo.w * adf_info->fb_data->bits_per_pixel / 8;
1217         logo.n_planes = 1;
1218
1219         fence = adf_interface_simple_post(&adf_info->intf, &logo);
1220         if (IS_ERR(fence))
1221                 dev_warn(dev, "failed to post bootloader logo: %ld\n",
1222                                 PTR_ERR(fence));
1223         else
1224                 sync_fence_put(fence);
1225
1226         dma_buf_put(logo.dma_bufs[0]);
1227 }
1228
1229 struct tegra_adf_info *tegra_adf_init(struct platform_device *ndev,
1230                 struct tegra_dc *dc,
1231                 struct tegra_fb_data *fb_data,
1232                 struct resource *fb_mem)
1233 {
1234         struct tegra_adf_info *adf_info;
1235         int err;
1236         enum adf_interface_type intf_type;
1237         u32 intf_flags = 0;
1238 #if IS_ENABLED(CONFIG_ADF_TEGRA_FBDEV)
1239         u32 fb_format;
1240 #endif
1241
1242         adf_info = kzalloc(sizeof(*adf_info), GFP_KERNEL);
1243         if (!adf_info)
1244                 return ERR_PTR(-ENOMEM);
1245
1246         adf_info->dc = dc;
1247         adf_info->fb_data = fb_data;
1248
1249         err = adf_device_init(&adf_info->base, &ndev->dev,
1250                         &tegra_adf_dev_ops, "%s", dev_name(&ndev->dev));
1251         if (err < 0)
1252                 goto err_dev_init;
1253
1254         intf_type = tegra_adf_interface_type(dc);
1255
1256         if (ndev->id == 0)
1257                 intf_flags |= ADF_INTF_FLAG_PRIMARY;
1258
1259         if (intf_type == ADF_INTF_HDMI)
1260                 intf_flags |= ADF_INTF_FLAG_EXTERNAL;
1261
1262         err = adf_interface_init(&adf_info->intf, &adf_info->base,
1263                         intf_type, 0, intf_flags,
1264                         &tegra_adf_intf_ops, "%s", dev_name(&ndev->dev));
1265         if (err < 0)
1266                 goto err_intf_init;
1267
1268         err = adf_overlay_engine_init(&adf_info->eng, &adf_info->base,
1269                         &tegra_adf_eng_ops, "%s", dev_name(&ndev->dev));
1270         if (err < 0)
1271                 goto err_eng_init;
1272
1273 #if IS_ENABLED(CONFIG_ADF_TEGRA_FBDEV)
1274         fb_format = fb_data->bits_per_pixel == 16 ? DRM_FORMAT_RGB565 :
1275                         DRM_FORMAT_RGBA8888;
1276         err = adf_fbdev_init(&adf_info->fbdev, &adf_info->intf,
1277                 &adf_info->eng, fb_data->xres, fb_data->yres * 2, fb_format,
1278                 &tegra_adf_fb_ops, "%s", dev_name(&ndev->dev));
1279         if (err < 0)
1280                 goto err_fbdev;
1281 #endif
1282
1283         err = adf_attachment_allow(&adf_info->base, &adf_info->eng,
1284                         &adf_info->intf);
1285         if (err < 0)
1286                 goto err_attach;
1287
1288         adf_info->vb2_dma_conf = vb2_dma_contig_init_ctx(&ndev->dev);
1289         if ((err = IS_ERR(adf_info->vb2_dma_conf)))
1290                 goto err_attach;
1291
1292         if (dc->out->n_modes) {
1293                 err = tegra_adf_process_hotplug_connected(adf_info, NULL);
1294                 if (err < 0)
1295                         goto err_attach;
1296         }
1297
1298         if (dc->enabled)
1299                 adf_info->intf.dpms_state = DRM_MODE_DPMS_ON;
1300
1301         if (fb_data->flags & TEGRA_FB_FLIP_ON_PROBE)
1302                 tegra_adf_save_bootloader_logo(adf_info, fb_mem);
1303         else
1304                 memblock_free(fb_mem->start, resource_size(fb_mem));
1305
1306         dev_info(&ndev->dev, "ADF initialized\n");
1307
1308         return adf_info;
1309
1310 err_attach:
1311 #if IS_ENABLED(CONFIG_ADF_TEGRA_FBDEV)
1312         adf_fbdev_destroy(&adf_info->fbdev);
1313
1314 err_fbdev:
1315 #endif
1316         adf_overlay_engine_destroy(&adf_info->eng);
1317
1318 err_eng_init:
1319         adf_interface_destroy(&adf_info->intf);
1320
1321 err_intf_init:
1322         adf_device_destroy(&adf_info->base);
1323
1324 err_dev_init:
1325         kfree(adf_info);
1326         return ERR_PTR(err);
1327 }
1328
1329 void tegra_adf_unregister(struct tegra_adf_info *adf_info)
1330 {
1331 #if IS_ENABLED(CONFIG_ADF_TEGRA_FBDEV)
1332         adf_fbdev_destroy(&adf_info->fbdev);
1333 #endif
1334         adf_overlay_engine_destroy(&adf_info->eng);
1335         adf_interface_destroy(&adf_info->intf);
1336         adf_device_destroy(&adf_info->base);
1337         kfree(adf_info);
1338 }