1/* 2 * Copyright (C) 2008 Maarten Maathuis. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 */ 26 27#include "drmP.h" 28#include "drm_mode.h" 29#include "drm_crtc_helper.h" 30 31#define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO) 32#include "nouveau_reg.h" 33#include "nouveau_drv.h" 34#include "nouveau_hw.h" 35#include "nouveau_encoder.h" 36#include "nouveau_crtc.h" 37#include "nouveau_fb.h" 38#include "nouveau_connector.h" 39#include "nv50_display.h" 40 41static void 42nv50_crtc_lut_load(struct drm_crtc *crtc) 43{ 44 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 45 void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo); 46 int i; 47 48 NV_DEBUG_KMS(crtc->dev, "\n"); 49 50 for (i = 0; i < 256; i++) { 51 writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0); 52 writew(nv_crtc->lut.g[i] >> 2, lut + 8*i + 2); 53 writew(nv_crtc->lut.b[i] >> 2, lut + 8*i + 4); 54 } 55 56 if (nv_crtc->lut.depth == 30) { 57 writew(nv_crtc->lut.r[i - 1] >> 2, lut + 8*i + 0); 58 writew(nv_crtc->lut.g[i - 1] >> 2, lut + 8*i + 2); 59 writew(nv_crtc->lut.b[i - 1] >> 2, lut + 8*i + 4); 60 } 61} 62 63int 64nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked) 65{ 66 struct drm_device *dev = nv_crtc->base.dev; 67 struct drm_nouveau_private *dev_priv = dev->dev_private; 68 struct nouveau_channel *evo = dev_priv->evo; 69 int index = nv_crtc->index, ret; 70 71 NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); 72 NV_DEBUG_KMS(dev, "%s\n", blanked ? "blanked" : "unblanked"); 73 74 if (blanked) { 75 nv_crtc->cursor.hide(nv_crtc, false); 76 77 ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 7 : 5); 78 if (ret) { 79 NV_ERROR(dev, "no space while blanking crtc\n"); 80 return ret; 81 } 82 BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2); 83 OUT_RING(evo, NV50_EVO_CRTC_CLUT_MODE_BLANK); 84 OUT_RING(evo, 0); 85 if (dev_priv->chipset != 0x50) { 86 BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1); 87 OUT_RING(evo, NV84_EVO_CRTC_CLUT_DMA_HANDLE_NONE); 88 } 89 90 BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1); 91 OUT_RING(evo, NV50_EVO_CRTC_FB_DMA_HANDLE_NONE); 92 } else { 93 if (nv_crtc->cursor.visible) 94 nv_crtc->cursor.show(nv_crtc, false); 95 else 96 nv_crtc->cursor.hide(nv_crtc, false); 97 98 ret = RING_SPACE(evo, dev_priv->chipset != 0x50 ? 10 : 8); 99 if (ret) { 100 NV_ERROR(dev, "no space while unblanking crtc\n"); 101 return ret; 102 } 103 BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, CLUT_MODE), 2); 104 OUT_RING(evo, nv_crtc->lut.depth == 8 ? 105 NV50_EVO_CRTC_CLUT_MODE_OFF : 106 NV50_EVO_CRTC_CLUT_MODE_ON); 107 OUT_RING(evo, (nv_crtc->lut.nvbo->bo.mem.mm_node->start << 108 PAGE_SHIFT) >> 8); 109 if (dev_priv->chipset != 0x50) { 110 BEGIN_RING(evo, 0, NV84_EVO_CRTC(index, CLUT_DMA), 1); 111 OUT_RING(evo, NvEvoVRAM); 112 } 113 114 BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_OFFSET), 2); 115 OUT_RING(evo, nv_crtc->fb.offset >> 8); 116 OUT_RING(evo, 0); 117 BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1); 118 if (dev_priv->chipset != 0x50) 119 if (nv_crtc->fb.tile_flags == 0x7a00) 120 OUT_RING(evo, NvEvoFB32); 121 else 122 if (nv_crtc->fb.tile_flags == 0x7000) 123 OUT_RING(evo, NvEvoFB16); 124 else 125 OUT_RING(evo, NvEvoVRAM); 126 else 127 OUT_RING(evo, NvEvoVRAM); 128 } 129 130 nv_crtc->fb.blanked = blanked; 131 return 0; 132} 133 134static int 135nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool on, bool update) 136{ 137 struct drm_device *dev = nv_crtc->base.dev; 138 struct drm_nouveau_private *dev_priv = dev->dev_private; 139 struct nouveau_channel *evo = dev_priv->evo; 140 int ret; 141 142 NV_DEBUG_KMS(dev, "\n"); 143 144 ret = RING_SPACE(evo, 2 + (update ? 2 : 0)); 145 if (ret) { 146 NV_ERROR(dev, "no space while setting dither\n"); 147 return ret; 148 } 149 150 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, DITHER_CTRL), 1); 151 if (on) 152 OUT_RING(evo, NV50_EVO_CRTC_DITHER_CTRL_ON); 153 else 154 OUT_RING(evo, NV50_EVO_CRTC_DITHER_CTRL_OFF); 155 156 if (update) { 157 BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); 158 OUT_RING(evo, 0); 159 FIRE_RING(evo); 160 } 161 162 return 0; 163} 164 165struct nouveau_connector * 166nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc) 167{ 168 struct drm_device *dev = nv_crtc->base.dev; 169 struct drm_connector *connector; 170 struct drm_crtc *crtc = to_drm_crtc(nv_crtc); 171 172 /* The safest approach is to find an encoder with the right crtc, that 173 * is also linked to a connector. */ 174 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 175 if (connector->encoder) 176 if (connector->encoder->crtc == crtc) 177 return nouveau_connector(connector); 178 } 179 180 return NULL; 181} 182 183static int 184nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, int scaling_mode, bool update) 185{ 186 struct nouveau_connector *nv_connector = 187 nouveau_crtc_connector_get(nv_crtc); 188 struct drm_device *dev = nv_crtc->base.dev; 189 struct drm_nouveau_private *dev_priv = dev->dev_private; 190 struct nouveau_channel *evo = dev_priv->evo; 191 struct drm_display_mode *native_mode = NULL; 192 struct drm_display_mode *mode = &nv_crtc->base.mode; 193 uint32_t outX, outY, horiz, vert; 194 int ret; 195 196 NV_DEBUG_KMS(dev, "\n"); 197 198 switch (scaling_mode) { 199 case DRM_MODE_SCALE_NONE: 200 break; 201 default: 202 if (!nv_connector || !nv_connector->native_mode) { 203 NV_ERROR(dev, "No native mode, forcing panel scaling\n"); 204 scaling_mode = DRM_MODE_SCALE_NONE; 205 } else { 206 native_mode = nv_connector->native_mode; 207 } 208 break; 209 } 210 211 switch (scaling_mode) { 212 case DRM_MODE_SCALE_ASPECT: 213 horiz = (native_mode->hdisplay << 19) / mode->hdisplay; 214 vert = (native_mode->vdisplay << 19) / mode->vdisplay; 215 216 if (vert > horiz) { 217 outX = (mode->hdisplay * horiz) >> 19; 218 outY = (mode->vdisplay * horiz) >> 19; 219 } else { 220 outX = (mode->hdisplay * vert) >> 19; 221 outY = (mode->vdisplay * vert) >> 19; 222 } 223 break; 224 case DRM_MODE_SCALE_FULLSCREEN: 225 outX = native_mode->hdisplay; 226 outY = native_mode->vdisplay; 227 break; 228 case DRM_MODE_SCALE_CENTER: 229 case DRM_MODE_SCALE_NONE: 230 default: 231 outX = mode->hdisplay; 232 outY = mode->vdisplay; 233 break; 234 } 235 236 ret = RING_SPACE(evo, update ? 7 : 5); 237 if (ret) 238 return ret; 239 240 /* Got a better name for SCALER_ACTIVE? */ 241 /* One day i've got to really figure out why this is needed. */ 242 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_CTRL), 1); 243 if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) || 244 (mode->flags & DRM_MODE_FLAG_INTERLACE) || 245 mode->hdisplay != outX || mode->vdisplay != outY) { 246 OUT_RING(evo, NV50_EVO_CRTC_SCALE_CTRL_ACTIVE); 247 } else { 248 OUT_RING(evo, NV50_EVO_CRTC_SCALE_CTRL_INACTIVE); 249 } 250 251 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_RES1), 2); 252 OUT_RING(evo, outY << 16 | outX); 253 OUT_RING(evo, outY << 16 | outX); 254 255 if (update) { 256 BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); 257 OUT_RING(evo, 0); 258 FIRE_RING(evo); 259 } 260 261 return 0; 262} 263 264int 265nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) 266{ 267 struct drm_nouveau_private *dev_priv = dev->dev_private; 268 struct pll_lims pll; 269 uint32_t reg, reg1, reg2; 270 int ret, N1, M1, N2, M2, P; 271 272 if (dev_priv->chipset < NV_C0) 273 reg = NV50_PDISPLAY_CRTC_CLK_CTRL1(head); 274 else 275 reg = 0x614140 + (head * 0x800); 276 277 ret = get_pll_limits(dev, reg, &pll); 278 if (ret) 279 return ret; 280 281 if (pll.vco2.maxfreq) { 282 ret = nv50_calc_pll(dev, &pll, pclk, &N1, &M1, &N2, &M2, &P); 283 if (ret <= 0) 284 return 0; 285 286 NV_DEBUG(dev, "pclk %d out %d NM1 %d %d NM2 %d %d P %d\n", 287 pclk, ret, N1, M1, N2, M2, P); 288 289 reg1 = nv_rd32(dev, reg + 4) & 0xff00ff00; 290 reg2 = nv_rd32(dev, reg + 8) & 0x8000ff00; 291 nv_wr32(dev, reg, 0x10000611); 292 nv_wr32(dev, reg + 4, reg1 | (M1 << 16) | N1); 293 nv_wr32(dev, reg + 8, reg2 | (P << 28) | (M2 << 16) | N2); 294 } else 295 if (dev_priv->chipset < NV_C0) { 296 ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P); 297 if (ret <= 0) 298 return 0; 299 300 NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n", 301 pclk, ret, N1, N2, M1, P); 302 303 reg1 = nv_rd32(dev, reg + 4) & 0xffc00000; 304 nv_wr32(dev, reg, 0x50000610); 305 nv_wr32(dev, reg + 4, reg1 | (P << 16) | (M1 << 8) | N1); 306 nv_wr32(dev, reg + 8, N2); 307 } else { 308 ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P); 309 if (ret <= 0) 310 return 0; 311 312 NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n", 313 pclk, ret, N1, N2, M1, P); 314 315 nv_mask(dev, reg + 0x0c, 0x00000000, 0x00000100); 316 nv_wr32(dev, reg + 0x04, (P << 16) | (N1 << 8) | M1); 317 nv_wr32(dev, reg + 0x10, N2 << 16); 318 } 319 320 return 0; 321} 322 323static void 324nv50_crtc_destroy(struct drm_crtc *crtc) 325{ 326 struct drm_device *dev; 327 struct nouveau_crtc *nv_crtc; 328 329 if (!crtc) 330 return; 331 332 dev = crtc->dev; 333 nv_crtc = nouveau_crtc(crtc); 334 335 NV_DEBUG_KMS(dev, "\n"); 336 337 drm_crtc_cleanup(&nv_crtc->base); 338 339 nv50_cursor_fini(nv_crtc); 340 341 nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo); 342 nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); 343 kfree(nv_crtc->mode); 344 kfree(nv_crtc); 345} 346 347int 348nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, 349 uint32_t buffer_handle, uint32_t width, uint32_t height) 350{ 351 struct drm_device *dev = crtc->dev; 352 struct drm_nouveau_private *dev_priv = dev->dev_private; 353 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 354 struct nouveau_bo *cursor = NULL; 355 struct drm_gem_object *gem; 356 int ret = 0, i; 357 358 if (width != 64 || height != 64) 359 return -EINVAL; 360 361 if (!buffer_handle) { 362 nv_crtc->cursor.hide(nv_crtc, true); 363 return 0; 364 } 365 366 gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); 367 if (!gem) 368 return -ENOENT; 369 cursor = nouveau_gem_object(gem); 370 371 ret = nouveau_bo_map(cursor); 372 if (ret) 373 goto out; 374 375 /* The simple will do for now. */ 376 for (i = 0; i < 64 * 64; i++) 377 nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, nouveau_bo_rd32(cursor, i)); 378 379 nouveau_bo_unmap(cursor); 380 381 nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset - 382 dev_priv->vm_vram_base); 383 nv_crtc->cursor.show(nv_crtc, true); 384 385out: 386 drm_gem_object_unreference_unlocked(gem); 387 return ret; 388} 389 390int 391nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) 392{ 393 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 394 395 nv_crtc->cursor.set_pos(nv_crtc, x, y); 396 return 0; 397} 398 399static void 400nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, 401 uint32_t start, uint32_t size) 402{ 403 int end = (start + size > 256) ? 256 : start + size, i; 404 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 405 406 for (i = start; i < end; i++) { 407 nv_crtc->lut.r[i] = r[i]; 408 nv_crtc->lut.g[i] = g[i]; 409 nv_crtc->lut.b[i] = b[i]; 410 } 411 412 /* We need to know the depth before we upload, but it's possible to 413 * get called before a framebuffer is bound. If this is the case, 414 * mark the lut values as dirty by setting depth==0, and it'll be 415 * uploaded on the first mode_set_base() 416 */ 417 if (!nv_crtc->base.fb) { 418 nv_crtc->lut.depth = 0; 419 return; 420 } 421 422 nv50_crtc_lut_load(crtc); 423} 424 425static void 426nv50_crtc_save(struct drm_crtc *crtc) 427{ 428 NV_ERROR(crtc->dev, "!!\n"); 429} 430 431static void 432nv50_crtc_restore(struct drm_crtc *crtc) 433{ 434 NV_ERROR(crtc->dev, "!!\n"); 435} 436 437static const struct drm_crtc_funcs nv50_crtc_funcs = { 438 .save = nv50_crtc_save, 439 .restore = nv50_crtc_restore, 440 .cursor_set = nv50_crtc_cursor_set, 441 .cursor_move = nv50_crtc_cursor_move, 442 .gamma_set = nv50_crtc_gamma_set, 443 .set_config = drm_crtc_helper_set_config, 444 .destroy = nv50_crtc_destroy, 445}; 446 447static void 448nv50_crtc_dpms(struct drm_crtc *crtc, int mode) 449{ 450} 451 452static void 453nv50_crtc_prepare(struct drm_crtc *crtc) 454{ 455 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 456 struct drm_device *dev = crtc->dev; 457 458 NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); 459 460 nv50_crtc_blank(nv_crtc, true); 461} 462 463static void 464nv50_crtc_commit(struct drm_crtc *crtc) 465{ 466 struct drm_device *dev = crtc->dev; 467 struct drm_nouveau_private *dev_priv = dev->dev_private; 468 struct nouveau_channel *evo = dev_priv->evo; 469 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 470 int ret; 471 472 NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); 473 474 nv50_crtc_blank(nv_crtc, false); 475 476 ret = RING_SPACE(evo, 2); 477 if (ret) { 478 NV_ERROR(dev, "no space while committing crtc\n"); 479 return; 480 } 481 BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); 482 OUT_RING (evo, 0); 483 FIRE_RING (evo); 484} 485 486static bool 487nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, 488 struct drm_display_mode *adjusted_mode) 489{ 490 return true; 491} 492 493static int 494nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y, 495 struct drm_framebuffer *old_fb, bool update) 496{ 497 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 498 struct drm_device *dev = nv_crtc->base.dev; 499 struct drm_nouveau_private *dev_priv = dev->dev_private; 500 struct nouveau_channel *evo = dev_priv->evo; 501 struct drm_framebuffer *drm_fb = nv_crtc->base.fb; 502 struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 503 int ret, format; 504 505 NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); 506 507 switch (drm_fb->depth) { 508 case 8: 509 format = NV50_EVO_CRTC_FB_DEPTH_8; 510 break; 511 case 15: 512 format = NV50_EVO_CRTC_FB_DEPTH_15; 513 break; 514 case 16: 515 format = NV50_EVO_CRTC_FB_DEPTH_16; 516 break; 517 case 24: 518 case 32: 519 format = NV50_EVO_CRTC_FB_DEPTH_24; 520 break; 521 case 30: 522 format = NV50_EVO_CRTC_FB_DEPTH_30; 523 break; 524 default: 525 NV_ERROR(dev, "unknown depth %d\n", drm_fb->depth); 526 return -EINVAL; 527 } 528 529 ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM); 530 if (ret) 531 return ret; 532 533 if (old_fb) { 534 struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb); 535 nouveau_bo_unpin(ofb->nvbo); 536 } 537 538 nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base; 539 nv_crtc->fb.tile_flags = fb->nvbo->tile_flags; 540 nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; 541 if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) { 542 ret = RING_SPACE(evo, 2); 543 if (ret) 544 return ret; 545 546 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1); 547 if (nv_crtc->fb.tile_flags == 0x7a00) 548 OUT_RING(evo, NvEvoFB32); 549 else 550 if (nv_crtc->fb.tile_flags == 0x7000) 551 OUT_RING(evo, NvEvoFB16); 552 else 553 OUT_RING(evo, NvEvoVRAM); 554 } 555 556 ret = RING_SPACE(evo, 12); 557 if (ret) 558 return ret; 559 560 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5); 561 OUT_RING(evo, nv_crtc->fb.offset >> 8); 562 OUT_RING(evo, 0); 563 OUT_RING(evo, (drm_fb->height << 16) | drm_fb->width); 564 if (!nv_crtc->fb.tile_flags) { 565 OUT_RING(evo, drm_fb->pitch | (1 << 20)); 566 } else { 567 OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | 568 fb->nvbo->tile_mode); 569 } 570 if (dev_priv->chipset == 0x50) 571 OUT_RING(evo, (fb->nvbo->tile_flags << 8) | format); 572 else 573 OUT_RING(evo, format); 574 575 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1); 576 OUT_RING(evo, fb->base.depth == 8 ? 577 NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON); 578 579 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1); 580 OUT_RING(evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR); 581 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1); 582 OUT_RING(evo, (y << 16) | x); 583 584 if (nv_crtc->lut.depth != fb->base.depth) { 585 nv_crtc->lut.depth = fb->base.depth; 586 nv50_crtc_lut_load(crtc); 587 } 588 589 if (update) { 590 ret = RING_SPACE(evo, 2); 591 if (ret) 592 return ret; 593 BEGIN_RING(evo, 0, NV50_EVO_UPDATE, 1); 594 OUT_RING(evo, 0); 595 FIRE_RING(evo); 596 } 597 598 return 0; 599} 600 601static int 602nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, 603 struct drm_display_mode *adjusted_mode, int x, int y, 604 struct drm_framebuffer *old_fb) 605{ 606 struct drm_device *dev = crtc->dev; 607 struct drm_nouveau_private *dev_priv = dev->dev_private; 608 struct nouveau_channel *evo = dev_priv->evo; 609 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 610 struct nouveau_connector *nv_connector = NULL; 611 uint32_t hsync_dur, vsync_dur, hsync_start_to_end, vsync_start_to_end; 612 uint32_t hunk1, vunk1, vunk2a, vunk2b; 613 int ret; 614 615 /* Find the connector attached to this CRTC */ 616 nv_connector = nouveau_crtc_connector_get(nv_crtc); 617 618 *nv_crtc->mode = *adjusted_mode; 619 620 NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); 621 622 hsync_dur = adjusted_mode->hsync_end - adjusted_mode->hsync_start; 623 vsync_dur = adjusted_mode->vsync_end - adjusted_mode->vsync_start; 624 hsync_start_to_end = adjusted_mode->htotal - adjusted_mode->hsync_start; 625 vsync_start_to_end = adjusted_mode->vtotal - adjusted_mode->vsync_start; 626 /* I can't give this a proper name, anyone else can? */ 627 hunk1 = adjusted_mode->htotal - 628 adjusted_mode->hsync_start + adjusted_mode->hdisplay; 629 vunk1 = adjusted_mode->vtotal - 630 adjusted_mode->vsync_start + adjusted_mode->vdisplay; 631 /* Another strange value, this time only for interlaced adjusted_modes. */ 632 vunk2a = 2 * adjusted_mode->vtotal - 633 adjusted_mode->vsync_start + adjusted_mode->vdisplay; 634 vunk2b = adjusted_mode->vtotal - 635 adjusted_mode->vsync_start + adjusted_mode->vtotal; 636 637 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { 638 vsync_dur /= 2; 639 vsync_start_to_end /= 2; 640 vunk1 /= 2; 641 vunk2a /= 2; 642 vunk2b /= 2; 643 /* magic */ 644 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) { 645 vsync_start_to_end -= 1; 646 vunk1 -= 1; 647 vunk2a -= 1; 648 vunk2b -= 1; 649 } 650 } 651 652 ret = RING_SPACE(evo, 17); 653 if (ret) 654 return ret; 655 656 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLOCK), 2); 657 OUT_RING(evo, adjusted_mode->clock | 0x800000); 658 OUT_RING(evo, (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 0); 659 660 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, DISPLAY_START), 5); 661 OUT_RING(evo, 0); 662 OUT_RING(evo, (adjusted_mode->vtotal << 16) | adjusted_mode->htotal); 663 OUT_RING(evo, (vsync_dur - 1) << 16 | (hsync_dur - 1)); 664 OUT_RING(evo, (vsync_start_to_end - 1) << 16 | 665 (hsync_start_to_end - 1)); 666 OUT_RING(evo, (vunk1 - 1) << 16 | (hunk1 - 1)); 667 668 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { 669 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, UNK0824), 1); 670 OUT_RING(evo, (vunk2b - 1) << 16 | (vunk2a - 1)); 671 } else { 672 OUT_RING(evo, 0); 673 OUT_RING(evo, 0); 674 } 675 676 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, UNK082C), 1); 677 OUT_RING(evo, 0); 678 679 /* This is the actual resolution of the mode. */ 680 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, REAL_RES), 1); 681 OUT_RING(evo, (mode->vdisplay << 16) | mode->hdisplay); 682 BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, SCALE_CENTER_OFFSET), 1); 683 OUT_RING(evo, NV50_EVO_CRTC_SCALE_CENTER_OFFSET_VAL(0, 0)); 684 685 nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false); 686 nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false); 687 688 return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, false); 689} 690 691static int 692nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, 693 struct drm_framebuffer *old_fb) 694{ 695 return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, true); 696} 697 698static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = { 699 .dpms = nv50_crtc_dpms, 700 .prepare = nv50_crtc_prepare, 701 .commit = nv50_crtc_commit, 702 .mode_fixup = nv50_crtc_mode_fixup, 703 .mode_set = nv50_crtc_mode_set, 704 .mode_set_base = nv50_crtc_mode_set_base, 705 .load_lut = nv50_crtc_lut_load, 706}; 707 708int 709nv50_crtc_create(struct drm_device *dev, int index) 710{ 711 struct nouveau_crtc *nv_crtc = NULL; 712 int ret, i; 713 714 NV_DEBUG_KMS(dev, "\n"); 715 716 nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); 717 if (!nv_crtc) 718 return -ENOMEM; 719 720 nv_crtc->mode = kzalloc(sizeof(*nv_crtc->mode), GFP_KERNEL); 721 if (!nv_crtc->mode) { 722 kfree(nv_crtc); 723 return -ENOMEM; 724 } 725 726 /* Default CLUT parameters, will be activated on the hw upon 727 * first mode set. 728 */ 729 for (i = 0; i < 256; i++) { 730 nv_crtc->lut.r[i] = i << 8; 731 nv_crtc->lut.g[i] = i << 8; 732 nv_crtc->lut.b[i] = i << 8; 733 } 734 nv_crtc->lut.depth = 0; 735 736 ret = nouveau_bo_new(dev, NULL, 4096, 0x100, TTM_PL_FLAG_VRAM, 737 0, 0x0000, false, true, &nv_crtc->lut.nvbo); 738 if (!ret) { 739 ret = nouveau_bo_pin(nv_crtc->lut.nvbo, TTM_PL_FLAG_VRAM); 740 if (!ret) 741 ret = nouveau_bo_map(nv_crtc->lut.nvbo); 742 if (ret) 743 nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo); 744 } 745 746 if (ret) { 747 kfree(nv_crtc->mode); 748 kfree(nv_crtc); 749 return ret; 750 } 751 752 nv_crtc->index = index; 753 754 /* set function pointers */ 755 nv_crtc->set_dither = nv50_crtc_set_dither; 756 nv_crtc->set_scale = nv50_crtc_set_scale; 757 758 drm_crtc_init(dev, &nv_crtc->base, &nv50_crtc_funcs); 759 drm_crtc_helper_add(&nv_crtc->base, &nv50_crtc_helper_funcs); 760 drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); 761 762 ret = nouveau_bo_new(dev, NULL, 64*64*4, 0x100, TTM_PL_FLAG_VRAM, 763 0, 0x0000, false, true, &nv_crtc->cursor.nvbo); 764 if (!ret) { 765 ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM); 766 if (!ret) 767 ret = nouveau_bo_map(nv_crtc->cursor.nvbo); 768 if (ret) 769 nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); 770 } 771 772 nv50_cursor_init(nv_crtc); 773 return 0; 774} 775