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 --- |