dc.c (c4755fb9064f64083fe559e92a46df817fc5e07b) dc.c (473079549f27eab5ad449f2c4f079014f0fe74a5)
1/*
2 * Copyright (C) 2012 Avionic Design GmbH
3 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */

--- 5 unchanged lines hidden (view full) ---

14#include <linux/pm_runtime.h>
15#include <linux/reset.h>
16
17#include <soc/tegra/pmc.h>
18
19#include "dc.h"
20#include "drm.h"
21#include "gem.h"
1/*
2 * Copyright (C) 2012 Avionic Design GmbH
3 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */

--- 5 unchanged lines hidden (view full) ---

14#include <linux/pm_runtime.h>
15#include <linux/reset.h>
16
17#include <soc/tegra/pmc.h>
18
19#include "dc.h"
20#include "drm.h"
21#include "gem.h"
22#include "hub.h"
22#include "plane.h"
23
24#include <drm/drm_atomic.h>
25#include <drm/drm_atomic_helper.h>
26#include <drm/drm_plane_helper.h>
27
28static void tegra_dc_stats_reset(struct tegra_dc_stats *stats)
29{

--- 384 unchanged lines hidden (view full) ---

414}
415
416static const struct drm_plane_helper_funcs tegra_plane_helper_funcs = {
417 .atomic_check = tegra_plane_atomic_check,
418 .atomic_disable = tegra_plane_atomic_disable,
419 .atomic_update = tegra_plane_atomic_update,
420};
421
23#include "plane.h"
24
25#include <drm/drm_atomic.h>
26#include <drm/drm_atomic_helper.h>
27#include <drm/drm_plane_helper.h>
28
29static void tegra_dc_stats_reset(struct tegra_dc_stats *stats)
30{

--- 384 unchanged lines hidden (view full) ---

415}
416
417static const struct drm_plane_helper_funcs tegra_plane_helper_funcs = {
418 .atomic_check = tegra_plane_atomic_check,
419 .atomic_disable = tegra_plane_atomic_disable,
420 .atomic_update = tegra_plane_atomic_update,
421};
422
422static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm,
423 struct tegra_dc *dc)
423static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
424 struct tegra_dc *dc)
424{
425 /*
426 * Ideally this would use drm_crtc_mask(), but that would require the
427 * CRTC to already be in the mode_config's list of CRTCs. However, it
428 * will only be added to that list in the drm_crtc_init_with_planes()
429 * (in tegra_dc_init()), which in turn requires registration of these
430 * planes. So we have ourselves a nice little chicken and egg problem
431 * here.
432 *
433 * We work around this by manually creating the mask from the number
434 * of CRTCs that have been registered, and should therefore always be
435 * the same as drm_crtc_index() after registration.
436 */
437 unsigned long possible_crtcs = 1 << drm->mode_config.num_crtc;
425{
426 /*
427 * Ideally this would use drm_crtc_mask(), but that would require the
428 * CRTC to already be in the mode_config's list of CRTCs. However, it
429 * will only be added to that list in the drm_crtc_init_with_planes()
430 * (in tegra_dc_init()), which in turn requires registration of these
431 * planes. So we have ourselves a nice little chicken and egg problem
432 * here.
433 *
434 * We work around this by manually creating the mask from the number
435 * of CRTCs that have been registered, and should therefore always be
436 * the same as drm_crtc_index() after registration.
437 */
438 unsigned long possible_crtcs = 1 << drm->mode_config.num_crtc;
439 enum drm_plane_type type = DRM_PLANE_TYPE_PRIMARY;
438 struct tegra_plane *plane;
439 unsigned int num_formats;
440 const u32 *formats;
441 int err;
442
443 plane = kzalloc(sizeof(*plane), GFP_KERNEL);
444 if (!plane)
445 return ERR_PTR(-ENOMEM);

--- 7 unchanged lines hidden (view full) ---

453 * Always use window A as primary window.
454 */
455 plane->offset = 0;
456 plane->index = 0;
457 plane->depth = 255;
458
459 err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
460 &tegra_plane_funcs, formats,
440 struct tegra_plane *plane;
441 unsigned int num_formats;
442 const u32 *formats;
443 int err;
444
445 plane = kzalloc(sizeof(*plane), GFP_KERNEL);
446 if (!plane)
447 return ERR_PTR(-ENOMEM);

--- 7 unchanged lines hidden (view full) ---

455 * Always use window A as primary window.
456 */
457 plane->offset = 0;
458 plane->index = 0;
459 plane->depth = 255;
460
461 err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
462 &tegra_plane_funcs, formats,
461 num_formats, NULL,
462 DRM_PLANE_TYPE_PRIMARY, NULL);
463 num_formats, NULL, type, NULL);
463 if (err < 0) {
464 kfree(plane);
465 return ERR_PTR(err);
466 }
467
468 drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs);
469
470 return &plane->base;

--- 196 unchanged lines hidden (view full) ---

667 return ERR_PTR(err);
668 }
669
670 drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs);
671
672 return &plane->base;
673}
674
464 if (err < 0) {
465 kfree(plane);
466 return ERR_PTR(err);
467 }
468
469 drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs);
470
471 return &plane->base;

--- 196 unchanged lines hidden (view full) ---

668 return ERR_PTR(err);
669 }
670
671 drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs);
672
673 return &plane->base;
674}
675
675static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc)
676static struct drm_plane *tegra_dc_add_shared_planes(struct drm_device *drm,
677 struct tegra_dc *dc)
676{
678{
677 struct drm_plane *plane;
679 struct drm_plane *plane, *primary = NULL;
680 unsigned int i, j;
681
682 for (i = 0; i < dc->soc->num_wgrps; i++) {
683 const struct tegra_windowgroup_soc *wgrp = &dc->soc->wgrps[i];
684
685 if (wgrp->dc == dc->pipe) {
686 for (j = 0; j < wgrp->num_windows; j++) {
687 unsigned int index = wgrp->windows[j];
688
689 plane = tegra_shared_plane_create(drm, dc,
690 wgrp->index,
691 index);
692 if (IS_ERR(plane))
693 return plane;
694
695 /*
696 * Choose the first shared plane owned by this
697 * head as the primary plane.
698 */
699 if (!primary) {
700 plane->type = DRM_PLANE_TYPE_PRIMARY;
701 primary = plane;
702 }
703 }
704 }
705 }
706
707 return primary;
708}
709
710static struct drm_plane *tegra_dc_add_planes(struct drm_device *drm,
711 struct tegra_dc *dc)
712{
713 struct drm_plane *plane, *primary;
678 unsigned int i;
679
714 unsigned int i;
715
716 primary = tegra_primary_plane_create(drm, dc);
717 if (IS_ERR(primary))
718 return primary;
719
680 for (i = 0; i < 2; i++) {
681 plane = tegra_dc_overlay_plane_create(drm, dc, 1 + i);
720 for (i = 0; i < 2; i++) {
721 plane = tegra_dc_overlay_plane_create(drm, dc, 1 + i);
682 if (IS_ERR(plane))
683 return PTR_ERR(plane);
722 if (IS_ERR(plane)) {
723 /* XXX tegra_plane_destroy() */
724 drm_plane_cleanup(primary);
725 kfree(primary);
726 return plane;
727 }
684 }
685
728 }
729
686 return 0;
730 return primary;
687}
688
689static void tegra_dc_destroy(struct drm_crtc *crtc)
690{
691 drm_crtc_cleanup(crtc);
692}
693
694static void tegra_crtc_reset(struct drm_crtc *crtc)

--- 373 unchanged lines hidden (view full) ---

1068 kfree(dc->debugfs_files);
1069 dc->debugfs_files = NULL;
1070}
1071
1072static u32 tegra_dc_get_vblank_counter(struct drm_crtc *crtc)
1073{
1074 struct tegra_dc *dc = to_tegra_dc(crtc);
1075
731}
732
733static void tegra_dc_destroy(struct drm_crtc *crtc)
734{
735 drm_crtc_cleanup(crtc);
736}
737
738static void tegra_crtc_reset(struct drm_crtc *crtc)

--- 373 unchanged lines hidden (view full) ---

1112 kfree(dc->debugfs_files);
1113 dc->debugfs_files = NULL;
1114}
1115
1116static u32 tegra_dc_get_vblank_counter(struct drm_crtc *crtc)
1117{
1118 struct tegra_dc *dc = to_tegra_dc(crtc);
1119
1076 if (dc->syncpt)
1120 /* XXX vblank syncpoints don't work with nvdisplay yet */
1121 if (dc->syncpt && !dc->soc->has_nvdisplay)
1077 return host1x_syncpt_read(dc->syncpt);
1078
1079 /* fallback to software emulated VBLANK counter */
1080 return drm_crtc_vblank_count(&dc->base);
1081}
1082
1083static int tegra_dc_enable_vblank(struct drm_crtc *crtc)
1084{

--- 41 unchanged lines hidden (view full) ---

1126
1127static int tegra_dc_set_timings(struct tegra_dc *dc,
1128 struct drm_display_mode *mode)
1129{
1130 unsigned int h_ref_to_sync = 1;
1131 unsigned int v_ref_to_sync = 1;
1132 unsigned long value;
1133
1122 return host1x_syncpt_read(dc->syncpt);
1123
1124 /* fallback to software emulated VBLANK counter */
1125 return drm_crtc_vblank_count(&dc->base);
1126}
1127
1128static int tegra_dc_enable_vblank(struct drm_crtc *crtc)
1129{

--- 41 unchanged lines hidden (view full) ---

1171
1172static int tegra_dc_set_timings(struct tegra_dc *dc,
1173 struct drm_display_mode *mode)
1174{
1175 unsigned int h_ref_to_sync = 1;
1176 unsigned int v_ref_to_sync = 1;
1177 unsigned long value;
1178
1134 tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS);
1179 if (!dc->soc->has_nvdisplay) {
1180 tegra_dc_writel(dc, 0x0, DC_DISP_DISP_TIMING_OPTIONS);
1135
1181
1136 value = (v_ref_to_sync << 16) | h_ref_to_sync;
1137 tegra_dc_writel(dc, value, DC_DISP_REF_TO_SYNC);
1182 value = (v_ref_to_sync << 16) | h_ref_to_sync;
1183 tegra_dc_writel(dc, value, DC_DISP_REF_TO_SYNC);
1184 }
1138
1139 value = ((mode->vsync_end - mode->vsync_start) << 16) |
1140 ((mode->hsync_end - mode->hsync_start) << 0);
1141 tegra_dc_writel(dc, value, DC_DISP_SYNC_WIDTH);
1142
1143 value = ((mode->vtotal - mode->vsync_end) << 16) |
1144 ((mode->htotal - mode->hsync_end) << 0);
1145 tegra_dc_writel(dc, value, DC_DISP_BACK_PORCH);

--- 62 unchanged lines hidden (view full) ---

1208 "failed to set clock rate to %lu Hz\n",
1209 state->pclk);
1210 }
1211
1212 DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk),
1213 state->div);
1214 DRM_DEBUG_KMS("pclk: %lu\n", state->pclk);
1215
1185
1186 value = ((mode->vsync_end - mode->vsync_start) << 16) |
1187 ((mode->hsync_end - mode->hsync_start) << 0);
1188 tegra_dc_writel(dc, value, DC_DISP_SYNC_WIDTH);
1189
1190 value = ((mode->vtotal - mode->vsync_end) << 16) |
1191 ((mode->htotal - mode->hsync_end) << 0);
1192 tegra_dc_writel(dc, value, DC_DISP_BACK_PORCH);

--- 62 unchanged lines hidden (view full) ---

1255 "failed to set clock rate to %lu Hz\n",
1256 state->pclk);
1257 }
1258
1259 DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk),
1260 state->div);
1261 DRM_DEBUG_KMS("pclk: %lu\n", state->pclk);
1262
1216 value = SHIFT_CLK_DIVIDER(state->div) | PIXEL_CLK_DIVIDER_PCD1;
1217 tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
1263 if (!dc->soc->has_nvdisplay) {
1264 value = SHIFT_CLK_DIVIDER(state->div) | PIXEL_CLK_DIVIDER_PCD1;
1265 tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
1266 }
1218
1219 err = clk_set_rate(dc->clk, state->pclk);
1220 if (err < 0)
1221 dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n",
1222 dc->clk, state->pclk, err);
1223}
1224
1225static void tegra_dc_stop(struct tegra_dc *dc)

--- 93 unchanged lines hidden (view full) ---

1319 struct tegra_dc_state *state = to_dc_state(crtc->state);
1320 struct tegra_dc *dc = to_tegra_dc(crtc);
1321 u32 value;
1322
1323 pm_runtime_get_sync(dc->dev);
1324
1325 /* initialize display controller */
1326 if (dc->syncpt) {
1267
1268 err = clk_set_rate(dc->clk, state->pclk);
1269 if (err < 0)
1270 dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n",
1271 dc->clk, state->pclk, err);
1272}
1273
1274static void tegra_dc_stop(struct tegra_dc *dc)

--- 93 unchanged lines hidden (view full) ---

1368 struct tegra_dc_state *state = to_dc_state(crtc->state);
1369 struct tegra_dc *dc = to_tegra_dc(crtc);
1370 u32 value;
1371
1372 pm_runtime_get_sync(dc->dev);
1373
1374 /* initialize display controller */
1375 if (dc->syncpt) {
1327 u32 syncpt = host1x_syncpt_id(dc->syncpt);
1376 u32 syncpt = host1x_syncpt_id(dc->syncpt), enable;
1328
1377
1378 if (dc->soc->has_nvdisplay)
1379 enable = 1 << 31;
1380 else
1381 enable = 1 << 8;
1382
1329 value = SYNCPT_CNTRL_NO_STALL;
1330 tegra_dc_writel(dc, value, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
1331
1383 value = SYNCPT_CNTRL_NO_STALL;
1384 tegra_dc_writel(dc, value, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
1385
1332 value = SYNCPT_VSYNC_ENABLE | syncpt;
1386 value = enable | syncpt;
1333 tegra_dc_writel(dc, value, DC_CMD_CONT_SYNCPT_VSYNC);
1334 }
1335
1387 tegra_dc_writel(dc, value, DC_CMD_CONT_SYNCPT_VSYNC);
1388 }
1389
1336 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1337 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
1338 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE);
1390 if (dc->soc->has_nvdisplay) {
1391 value = DSC_TO_UF_INT | DSC_BBUF_UF_INT | DSC_RBUF_UF_INT |
1392 DSC_OBUF_UF_INT;
1393 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE);
1339
1394
1340 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1341 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
1342 tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY);
1395 value = DSC_TO_UF_INT | DSC_BBUF_UF_INT | DSC_RBUF_UF_INT |
1396 DSC_OBUF_UF_INT | SD3_BUCKET_WALK_DONE_INT |
1397 HEAD_UF_INT | MSF_INT | REG_TMOUT_INT |
1398 REGION_CRC_INT | V_PULSE2_INT | V_PULSE3_INT |
1399 VBLANK_INT | FRAME_END_INT;
1400 tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY);
1343
1401
1344 /* initialize timer */
1345 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
1346 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
1347 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY);
1402 value = SD3_BUCKET_WALK_DONE_INT | HEAD_UF_INT | VBLANK_INT |
1403 FRAME_END_INT;
1404 tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
1348
1405
1349 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) |
1350 WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1);
1351 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
1406 value = HEAD_UF_INT | REG_TMOUT_INT | FRAME_END_INT;
1407 tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
1352
1408
1353 value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1354 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
1355 tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
1409 tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
1410 } else {
1411 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1412 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
1413 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE);
1356
1414
1357 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1358 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
1359 tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
1415 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1416 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
1417 tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY);
1360
1418
1419 /* initialize timer */
1420 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
1421 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
1422 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY);
1423
1424 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) |
1425 WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1);
1426 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
1427
1428 value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1429 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
1430 tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
1431
1432 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1433 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
1434 tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
1435 }
1436
1361 if (dc->soc->supports_background_color)
1362 tegra_dc_writel(dc, 0, DC_DISP_BLEND_BACKGROUND_COLOR);
1363 else
1364 tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR);
1365
1366 /* apply PLL and pixel clock changes */
1367 tegra_dc_commit_state(dc, state);
1368

--- 7 unchanged lines hidden (view full) ---

1376 tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL);
1377 }
1378
1379 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
1380 value &= ~DISP_CTRL_MODE_MASK;
1381 value |= DISP_CTRL_MODE_C_DISPLAY;
1382 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
1383
1437 if (dc->soc->supports_background_color)
1438 tegra_dc_writel(dc, 0, DC_DISP_BLEND_BACKGROUND_COLOR);
1439 else
1440 tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR);
1441
1442 /* apply PLL and pixel clock changes */
1443 tegra_dc_commit_state(dc, state);
1444

--- 7 unchanged lines hidden (view full) ---

1452 tegra_dc_writel(dc, value, DC_DISP_INTERLACE_CONTROL);
1453 }
1454
1455 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
1456 value &= ~DISP_CTRL_MODE_MASK;
1457 value |= DISP_CTRL_MODE_C_DISPLAY;
1458 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
1459
1384 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
1385 value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
1386 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
1387 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
1460 if (!dc->soc->has_nvdisplay) {
1461 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
1462 value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
1463 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
1464 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
1465 }
1388
1466
1467 /* enable underflow reporting and display red for missing pixels */
1468 if (dc->soc->has_nvdisplay) {
1469 value = UNDERFLOW_MODE_RED | UNDERFLOW_REPORT_ENABLE;
1470 tegra_dc_writel(dc, value, DC_COM_RG_UNDERFLOW);
1471 }
1472
1389 tegra_dc_commit(dc);
1390
1391 drm_crtc_vblank_on(crtc);
1392}
1393
1394static int tegra_crtc_atomic_check(struct drm_crtc *crtc,
1395 struct drm_crtc_state *state)
1396{

--- 38 unchanged lines hidden (view full) ---

1435 }
1436}
1437
1438static void tegra_crtc_atomic_flush(struct drm_crtc *crtc,
1439 struct drm_crtc_state *old_crtc_state)
1440{
1441 struct tegra_dc_state *state = to_dc_state(crtc->state);
1442 struct tegra_dc *dc = to_tegra_dc(crtc);
1473 tegra_dc_commit(dc);
1474
1475 drm_crtc_vblank_on(crtc);
1476}
1477
1478static int tegra_crtc_atomic_check(struct drm_crtc *crtc,
1479 struct drm_crtc_state *state)
1480{

--- 38 unchanged lines hidden (view full) ---

1519 }
1520}
1521
1522static void tegra_crtc_atomic_flush(struct drm_crtc *crtc,
1523 struct drm_crtc_state *old_crtc_state)
1524{
1525 struct tegra_dc_state *state = to_dc_state(crtc->state);
1526 struct tegra_dc *dc = to_tegra_dc(crtc);
1527 u32 value;
1443
1528
1444 tegra_dc_writel(dc, state->planes << 8, DC_CMD_STATE_CONTROL);
1445 tegra_dc_writel(dc, state->planes, DC_CMD_STATE_CONTROL);
1529 value = state->planes << 8 | GENERAL_UPDATE;
1530 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
1531 value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
1532
1533 value = state->planes | GENERAL_ACT_REQ;
1534 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
1535 value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
1446}
1447
1448static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
1449 .atomic_check = tegra_crtc_atomic_check,
1450 .atomic_begin = tegra_crtc_atomic_begin,
1451 .atomic_flush = tegra_crtc_atomic_flush,
1452 .atomic_enable = tegra_crtc_atomic_enable,
1453 .atomic_disable = tegra_crtc_atomic_disable,

--- 31 unchanged lines hidden (view full) ---

1485
1486 if (status & (WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT)) {
1487 /*
1488 dev_dbg(dc->dev, "%s(): overflow\n", __func__);
1489 */
1490 dc->stats.overflow++;
1491 }
1492
1536}
1537
1538static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
1539 .atomic_check = tegra_crtc_atomic_check,
1540 .atomic_begin = tegra_crtc_atomic_begin,
1541 .atomic_flush = tegra_crtc_atomic_flush,
1542 .atomic_enable = tegra_crtc_atomic_enable,
1543 .atomic_disable = tegra_crtc_atomic_disable,

--- 31 unchanged lines hidden (view full) ---

1575
1576 if (status & (WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT)) {
1577 /*
1578 dev_dbg(dc->dev, "%s(): overflow\n", __func__);
1579 */
1580 dc->stats.overflow++;
1581 }
1582
1583 if (status & HEAD_UF_INT) {
1584 dev_dbg_ratelimited(dc->dev, "%s(): head underflow\n", __func__);
1585 dc->stats.underflow++;
1586 }
1587
1493 return IRQ_HANDLED;
1494}
1495
1496static int tegra_dc_init(struct host1x_client *client)
1497{
1498 struct drm_device *drm = dev_get_drvdata(client->parent);
1499 unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
1500 struct tegra_dc *dc = host1x_client_to_dc(client);

--- 12 unchanged lines hidden (view full) ---

1513 dev_err(dc->dev, "failed to attach to domain: %d\n",
1514 err);
1515 return err;
1516 }
1517
1518 dc->domain = tegra->domain;
1519 }
1520
1588 return IRQ_HANDLED;
1589}
1590
1591static int tegra_dc_init(struct host1x_client *client)
1592{
1593 struct drm_device *drm = dev_get_drvdata(client->parent);
1594 unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
1595 struct tegra_dc *dc = host1x_client_to_dc(client);

--- 12 unchanged lines hidden (view full) ---

1608 dev_err(dc->dev, "failed to attach to domain: %d\n",
1609 err);
1610 return err;
1611 }
1612
1613 dc->domain = tegra->domain;
1614 }
1615
1521 primary = tegra_dc_primary_plane_create(drm, dc);
1616 if (dc->soc->wgrps)
1617 primary = tegra_dc_add_shared_planes(drm, dc);
1618 else
1619 primary = tegra_dc_add_planes(drm, dc);
1620
1522 if (IS_ERR(primary)) {
1523 err = PTR_ERR(primary);
1524 goto cleanup;
1525 }
1526
1527 if (dc->soc->supports_cursor) {
1528 cursor = tegra_dc_cursor_plane_create(drm, dc);
1529 if (IS_ERR(cursor)) {

--- 17 unchanged lines hidden (view full) ---

1547 tegra->pitch_align = dc->soc->pitch_align;
1548
1549 err = tegra_dc_rgb_init(drm, dc);
1550 if (err < 0 && err != -ENODEV) {
1551 dev_err(dc->dev, "failed to initialize RGB output: %d\n", err);
1552 goto cleanup;
1553 }
1554
1621 if (IS_ERR(primary)) {
1622 err = PTR_ERR(primary);
1623 goto cleanup;
1624 }
1625
1626 if (dc->soc->supports_cursor) {
1627 cursor = tegra_dc_cursor_plane_create(drm, dc);
1628 if (IS_ERR(cursor)) {

--- 17 unchanged lines hidden (view full) ---

1646 tegra->pitch_align = dc->soc->pitch_align;
1647
1648 err = tegra_dc_rgb_init(drm, dc);
1649 if (err < 0 && err != -ENODEV) {
1650 dev_err(dc->dev, "failed to initialize RGB output: %d\n", err);
1651 goto cleanup;
1652 }
1653
1555 err = tegra_dc_add_planes(drm, dc);
1556 if (err < 0)
1557 goto cleanup;
1558
1559 err = devm_request_irq(dc->dev, dc->irq, tegra_dc_irq, 0,
1560 dev_name(dc->dev), dc);
1561 if (err < 0) {
1562 dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq,
1563 err);
1564 goto cleanup;
1565 }
1566
1567 return 0;
1568
1569cleanup:
1654 err = devm_request_irq(dc->dev, dc->irq, tegra_dc_irq, 0,
1655 dev_name(dc->dev), dc);
1656 if (err < 0) {
1657 dev_err(dc->dev, "failed to request IRQ#%u: %d\n", dc->irq,
1658 err);
1659 goto cleanup;
1660 }
1661
1662 return 0;
1663
1664cleanup:
1570 if (cursor)
1665 if (!IS_ERR_OR_NULL(cursor))
1571 drm_plane_cleanup(cursor);
1572
1666 drm_plane_cleanup(cursor);
1667
1573 if (primary)
1668 if (!IS_ERR(primary))
1574 drm_plane_cleanup(primary);
1575
1576 if (tegra->domain) {
1577 iommu_detach_device(tegra->domain, dc->dev);
1578 dc->domain = NULL;
1579 }
1580
1581 return err;

--- 30 unchanged lines hidden (view full) ---

1612static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
1613 .supports_background_color = false,
1614 .supports_interlacing = false,
1615 .supports_cursor = false,
1616 .supports_block_linear = false,
1617 .pitch_align = 8,
1618 .has_powergate = false,
1619 .broken_reset = true,
1669 drm_plane_cleanup(primary);
1670
1671 if (tegra->domain) {
1672 iommu_detach_device(tegra->domain, dc->dev);
1673 dc->domain = NULL;
1674 }
1675
1676 return err;

--- 30 unchanged lines hidden (view full) ---

1707static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
1708 .supports_background_color = false,
1709 .supports_interlacing = false,
1710 .supports_cursor = false,
1711 .supports_block_linear = false,
1712 .pitch_align = 8,
1713 .has_powergate = false,
1714 .broken_reset = true,
1715 .has_nvdisplay = false,
1620};
1621
1622static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
1623 .supports_background_color = false,
1624 .supports_interlacing = false,
1625 .supports_cursor = false,
1626 .supports_block_linear = false,
1627 .pitch_align = 8,
1628 .has_powergate = false,
1629 .broken_reset = false,
1716};
1717
1718static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
1719 .supports_background_color = false,
1720 .supports_interlacing = false,
1721 .supports_cursor = false,
1722 .supports_block_linear = false,
1723 .pitch_align = 8,
1724 .has_powergate = false,
1725 .broken_reset = false,
1726 .has_nvdisplay = false,
1630};
1631
1632static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
1633 .supports_background_color = false,
1634 .supports_interlacing = false,
1635 .supports_cursor = false,
1636 .supports_block_linear = false,
1637 .pitch_align = 64,
1638 .has_powergate = true,
1639 .broken_reset = false,
1727};
1728
1729static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
1730 .supports_background_color = false,
1731 .supports_interlacing = false,
1732 .supports_cursor = false,
1733 .supports_block_linear = false,
1734 .pitch_align = 64,
1735 .has_powergate = true,
1736 .broken_reset = false,
1737 .has_nvdisplay = false,
1640};
1641
1642static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
1643 .supports_background_color = true,
1644 .supports_interlacing = true,
1645 .supports_cursor = true,
1646 .supports_block_linear = true,
1647 .pitch_align = 64,
1648 .has_powergate = true,
1649 .broken_reset = false,
1738};
1739
1740static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
1741 .supports_background_color = true,
1742 .supports_interlacing = true,
1743 .supports_cursor = true,
1744 .supports_block_linear = true,
1745 .pitch_align = 64,
1746 .has_powergate = true,
1747 .broken_reset = false,
1748 .has_nvdisplay = false,
1650};
1651
1652static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
1653 .supports_background_color = true,
1654 .supports_interlacing = true,
1655 .supports_cursor = true,
1656 .supports_block_linear = true,
1657 .pitch_align = 64,
1658 .has_powergate = true,
1659 .broken_reset = false,
1749};
1750
1751static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
1752 .supports_background_color = true,
1753 .supports_interlacing = true,
1754 .supports_cursor = true,
1755 .supports_block_linear = true,
1756 .pitch_align = 64,
1757 .has_powergate = true,
1758 .broken_reset = false,
1759 .has_nvdisplay = false,
1660};
1661
1760};
1761
1762static const struct tegra_windowgroup_soc tegra186_dc_wgrps[] = {
1763 {
1764 .index = 0,
1765 .dc = 0,
1766 .windows = (const unsigned int[]) { 0 },
1767 .num_windows = 1,
1768 }, {
1769 .index = 1,
1770 .dc = 1,
1771 .windows = (const unsigned int[]) { 1 },
1772 .num_windows = 1,
1773 }, {
1774 .index = 2,
1775 .dc = 1,
1776 .windows = (const unsigned int[]) { 2 },
1777 .num_windows = 1,
1778 }, {
1779 .index = 3,
1780 .dc = 2,
1781 .windows = (const unsigned int[]) { 3 },
1782 .num_windows = 1,
1783 }, {
1784 .index = 4,
1785 .dc = 2,
1786 .windows = (const unsigned int[]) { 4 },
1787 .num_windows = 1,
1788 }, {
1789 .index = 5,
1790 .dc = 2,
1791 .windows = (const unsigned int[]) { 5 },
1792 .num_windows = 1,
1793 },
1794};
1795
1796static const struct tegra_dc_soc_info tegra186_dc_soc_info = {
1797 .supports_background_color = true,
1798 .supports_interlacing = true,
1799 .supports_cursor = true,
1800 .supports_block_linear = true,
1801 .pitch_align = 64,
1802 .has_powergate = false,
1803 .broken_reset = false,
1804 .has_nvdisplay = true,
1805 .wgrps = tegra186_dc_wgrps,
1806 .num_wgrps = ARRAY_SIZE(tegra186_dc_wgrps),
1807};
1808
1662static const struct of_device_id tegra_dc_of_match[] = {
1663 {
1809static const struct of_device_id tegra_dc_of_match[] = {
1810 {
1811 .compatible = "nvidia,tegra186-dc",
1812 .data = &tegra186_dc_soc_info,
1813 }, {
1664 .compatible = "nvidia,tegra210-dc",
1665 .data = &tegra210_dc_soc_info,
1666 }, {
1667 .compatible = "nvidia,tegra124-dc",
1668 .data = &tegra124_dc_soc_info,
1669 }, {
1670 .compatible = "nvidia,tegra114-dc",
1671 .data = &tegra114_dc_soc_info,

--- 232 unchanged lines hidden ---
1814 .compatible = "nvidia,tegra210-dc",
1815 .data = &tegra210_dc_soc_info,
1816 }, {
1817 .compatible = "nvidia,tegra124-dc",
1818 .data = &tegra124_dc_soc_info,
1819 }, {
1820 .compatible = "nvidia,tegra114-dc",
1821 .data = &tegra114_dc_soc_info,

--- 232 unchanged lines hidden ---