1 /* 2 * The list_sort function is (presumably) licensed under the GPL (see the 3 * top level "COPYING" file for details). 4 * 5 * The remainder of this file is: 6 * 7 * Copyright © 1997-2003 by The XFree86 Project, Inc. 8 * Copyright © 2007 Dave Airlie 9 * Copyright © 2007-2008 Intel Corporation 10 * Jesse Barnes <jesse.barnes@intel.com> 11 * Copyright 2005-2006 Luc Verhaegen 12 * Copyright (c) 2001, Andy Ritger aritger@nvidia.com 13 * 14 * Permission is hereby granted, free of charge, to any person obtaining a 15 * copy of this software and associated documentation files (the "Software"), 16 * to deal in the Software without restriction, including without limitation 17 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 18 * and/or sell copies of the Software, and to permit persons to whom the 19 * Software is furnished to do so, subject to the following conditions: 20 * 21 * The above copyright notice and this permission notice shall be included in 22 * all copies or substantial portions of the Software. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 27 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 28 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 29 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 30 * OTHER DEALINGS IN THE SOFTWARE. 31 * 32 * Except as contained in this notice, the name of the copyright holder(s) 33 * and author(s) shall not be used in advertising or otherwise to promote 34 * the sale, use or other dealings in this Software without prior written 35 * authorization from the copyright holder(s) and author(s). 36 */ 37 38 #include <linux/list.h> 39 #include "drmP.h" 40 #include "drm.h" 41 #include "drm_crtc.h" 42 43 /** 44 * drm_mode_debug_printmodeline - debug print a mode 45 * @dev: DRM device 46 * @mode: mode to print 47 * 48 * LOCKING: 49 * None. 50 * 51 * Describe @mode using DRM_DEBUG. 52 */ 53 void drm_mode_debug_printmodeline(struct drm_display_mode *mode) 54 { 55 DRM_DEBUG_KMS("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d " 56 "0x%x 0x%x\n", 57 mode->base.id, mode->name, mode->vrefresh, mode->clock, 58 mode->hdisplay, mode->hsync_start, 59 mode->hsync_end, mode->htotal, 60 mode->vdisplay, mode->vsync_start, 61 mode->vsync_end, mode->vtotal, mode->type, mode->flags); 62 } 63 EXPORT_SYMBOL(drm_mode_debug_printmodeline); 64 65 /** 66 * drm_cvt_mode -create a modeline based on CVT algorithm 67 * @dev: DRM device 68 * @hdisplay: hdisplay size 69 * @vdisplay: vdisplay size 70 * @vrefresh : vrefresh rate 71 * @reduced : Whether the GTF calculation is simplified 72 * @interlaced:Whether the interlace is supported 73 * 74 * LOCKING: 75 * none. 76 * 77 * return the modeline based on CVT algorithm 78 * 79 * This function is called to generate the modeline based on CVT algorithm 80 * according to the hdisplay, vdisplay, vrefresh. 81 * It is based from the VESA(TM) Coordinated Video Timing Generator by 82 * Graham Loveridge April 9, 2003 available at 83 * http://www.vesa.org/public/CVT/CVTd6r1.xls 84 * 85 * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c. 86 * What I have done is to translate it by using integer calculation. 87 */ 88 #define HV_FACTOR 1000 89 struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, 90 int vdisplay, int vrefresh, 91 bool reduced, bool interlaced) 92 { 93 /* 1) top/bottom margin size (% of height) - default: 1.8, */ 94 #define CVT_MARGIN_PERCENTAGE 18 95 /* 2) character cell horizontal granularity (pixels) - default 8 */ 96 #define CVT_H_GRANULARITY 8 97 /* 3) Minimum vertical porch (lines) - default 3 */ 98 #define CVT_MIN_V_PORCH 3 99 /* 4) Minimum number of vertical back porch lines - default 6 */ 100 #define CVT_MIN_V_BPORCH 6 101 /* Pixel Clock step (kHz) */ 102 #define CVT_CLOCK_STEP 250 103 struct drm_display_mode *drm_mode; 104 bool margins = false; 105 unsigned int vfieldrate, hperiod; 106 int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync; 107 int interlace; 108 109 /* allocate the drm_display_mode structure. If failure, we will 110 * return directly 111 */ 112 drm_mode = drm_mode_create(dev); 113 if (!drm_mode) 114 return NULL; 115 116 /* the CVT default refresh rate is 60Hz */ 117 if (!vrefresh) 118 vrefresh = 60; 119 120 /* the required field fresh rate */ 121 if (interlaced) 122 vfieldrate = vrefresh * 2; 123 else 124 vfieldrate = vrefresh; 125 126 /* horizontal pixels */ 127 hdisplay_rnd = hdisplay - (hdisplay % CVT_H_GRANULARITY); 128 129 /* determine the left&right borders */ 130 hmargin = 0; 131 if (margins) { 132 hmargin = hdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000; 133 hmargin -= hmargin % CVT_H_GRANULARITY; 134 } 135 /* find the total active pixels */ 136 drm_mode->hdisplay = hdisplay_rnd + 2 * hmargin; 137 138 /* find the number of lines per field */ 139 if (interlaced) 140 vdisplay_rnd = vdisplay / 2; 141 else 142 vdisplay_rnd = vdisplay; 143 144 /* find the top & bottom borders */ 145 vmargin = 0; 146 if (margins) 147 vmargin = vdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000; 148 149 drm_mode->vdisplay = vdisplay + 2 * vmargin; 150 151 /* Interlaced */ 152 if (interlaced) 153 interlace = 1; 154 else 155 interlace = 0; 156 157 /* Determine VSync Width from aspect ratio */ 158 if (!(vdisplay % 3) && ((vdisplay * 4 / 3) == hdisplay)) 159 vsync = 4; 160 else if (!(vdisplay % 9) && ((vdisplay * 16 / 9) == hdisplay)) 161 vsync = 5; 162 else if (!(vdisplay % 10) && ((vdisplay * 16 / 10) == hdisplay)) 163 vsync = 6; 164 else if (!(vdisplay % 4) && ((vdisplay * 5 / 4) == hdisplay)) 165 vsync = 7; 166 else if (!(vdisplay % 9) && ((vdisplay * 15 / 9) == hdisplay)) 167 vsync = 7; 168 else /* custom */ 169 vsync = 10; 170 171 if (!reduced) { 172 /* simplify the GTF calculation */ 173 /* 4) Minimum time of vertical sync + back porch interval (µs) 174 * default 550.0 175 */ 176 int tmp1, tmp2; 177 #define CVT_MIN_VSYNC_BP 550 178 /* 3) Nominal HSync width (% of line period) - default 8 */ 179 #define CVT_HSYNC_PERCENTAGE 8 180 unsigned int hblank_percentage; 181 int vsyncandback_porch, vback_porch, hblank; 182 183 /* estimated the horizontal period */ 184 tmp1 = HV_FACTOR * 1000000 - 185 CVT_MIN_VSYNC_BP * HV_FACTOR * vfieldrate; 186 tmp2 = (vdisplay_rnd + 2 * vmargin + CVT_MIN_V_PORCH) * 2 + 187 interlace; 188 hperiod = tmp1 * 2 / (tmp2 * vfieldrate); 189 190 tmp1 = CVT_MIN_VSYNC_BP * HV_FACTOR / hperiod + 1; 191 /* 9. Find number of lines in sync + backporch */ 192 if (tmp1 < (vsync + CVT_MIN_V_PORCH)) 193 vsyncandback_porch = vsync + CVT_MIN_V_PORCH; 194 else 195 vsyncandback_porch = tmp1; 196 /* 10. Find number of lines in back porch */ 197 vback_porch = vsyncandback_porch - vsync; 198 drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + 199 vsyncandback_porch + CVT_MIN_V_PORCH; 200 /* 5) Definition of Horizontal blanking time limitation */ 201 /* Gradient (%/kHz) - default 600 */ 202 #define CVT_M_FACTOR 600 203 /* Offset (%) - default 40 */ 204 #define CVT_C_FACTOR 40 205 /* Blanking time scaling factor - default 128 */ 206 #define CVT_K_FACTOR 128 207 /* Scaling factor weighting - default 20 */ 208 #define CVT_J_FACTOR 20 209 #define CVT_M_PRIME (CVT_M_FACTOR * CVT_K_FACTOR / 256) 210 #define CVT_C_PRIME ((CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ 211 CVT_J_FACTOR) 212 /* 12. Find ideal blanking duty cycle from formula */ 213 hblank_percentage = CVT_C_PRIME * HV_FACTOR - CVT_M_PRIME * 214 hperiod / 1000; 215 /* 13. Blanking time */ 216 if (hblank_percentage < 20 * HV_FACTOR) 217 hblank_percentage = 20 * HV_FACTOR; 218 hblank = drm_mode->hdisplay * hblank_percentage / 219 (100 * HV_FACTOR - hblank_percentage); 220 hblank -= hblank % (2 * CVT_H_GRANULARITY); 221 /* 14. find the total pixes per line */ 222 drm_mode->htotal = drm_mode->hdisplay + hblank; 223 drm_mode->hsync_end = drm_mode->hdisplay + hblank / 2; 224 drm_mode->hsync_start = drm_mode->hsync_end - 225 (drm_mode->htotal * CVT_HSYNC_PERCENTAGE) / 100; 226 drm_mode->hsync_start += CVT_H_GRANULARITY - 227 drm_mode->hsync_start % CVT_H_GRANULARITY; 228 /* fill the Vsync values */ 229 drm_mode->vsync_start = drm_mode->vdisplay + CVT_MIN_V_PORCH; 230 drm_mode->vsync_end = drm_mode->vsync_start + vsync; 231 } else { 232 /* Reduced blanking */ 233 /* Minimum vertical blanking interval time (µs)- default 460 */ 234 #define CVT_RB_MIN_VBLANK 460 235 /* Fixed number of clocks for horizontal sync */ 236 #define CVT_RB_H_SYNC 32 237 /* Fixed number of clocks for horizontal blanking */ 238 #define CVT_RB_H_BLANK 160 239 /* Fixed number of lines for vertical front porch - default 3*/ 240 #define CVT_RB_VFPORCH 3 241 int vbilines; 242 int tmp1, tmp2; 243 /* 8. Estimate Horizontal period. */ 244 tmp1 = HV_FACTOR * 1000000 - 245 CVT_RB_MIN_VBLANK * HV_FACTOR * vfieldrate; 246 tmp2 = vdisplay_rnd + 2 * vmargin; 247 hperiod = tmp1 / (tmp2 * vfieldrate); 248 /* 9. Find number of lines in vertical blanking */ 249 vbilines = CVT_RB_MIN_VBLANK * HV_FACTOR / hperiod + 1; 250 /* 10. Check if vertical blanking is sufficient */ 251 if (vbilines < (CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH)) 252 vbilines = CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH; 253 /* 11. Find total number of lines in vertical field */ 254 drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + vbilines; 255 /* 12. Find total number of pixels in a line */ 256 drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; 257 /* Fill in HSync values */ 258 drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; 259 drm_mode->hsync_start = drm_mode->hsync_end = CVT_RB_H_SYNC; 260 } 261 /* 15/13. Find pixel clock frequency (kHz for xf86) */ 262 drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; 263 drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP; 264 /* 18/16. Find actual vertical frame frequency */ 265 /* ignore - just set the mode flag for interlaced */ 266 if (interlaced) 267 drm_mode->vtotal *= 2; 268 /* Fill the mode line name */ 269 drm_mode_set_name(drm_mode); 270 if (reduced) 271 drm_mode->flags |= (DRM_MODE_FLAG_PHSYNC | 272 DRM_MODE_FLAG_NVSYNC); 273 else 274 drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC | 275 DRM_MODE_FLAG_NHSYNC); 276 if (interlaced) 277 drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; 278 279 return drm_mode; 280 } 281 EXPORT_SYMBOL(drm_cvt_mode); 282 283 /** 284 * drm_gtf_mode - create the modeline based on GTF algorithm 285 * 286 * @dev :drm device 287 * @hdisplay :hdisplay size 288 * @vdisplay :vdisplay size 289 * @vrefresh :vrefresh rate. 290 * @interlaced :whether the interlace is supported 291 * @margins :whether the margin is supported 292 * 293 * LOCKING. 294 * none. 295 * 296 * return the modeline based on GTF algorithm 297 * 298 * This function is to create the modeline based on the GTF algorithm. 299 * Generalized Timing Formula is derived from: 300 * GTF Spreadsheet by Andy Morrish (1/5/97) 301 * available at http://www.vesa.org 302 * 303 * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c. 304 * What I have done is to translate it by using integer calculation. 305 * I also refer to the function of fb_get_mode in the file of 306 * drivers/video/fbmon.c 307 */ 308 struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay, 309 int vdisplay, int vrefresh, 310 bool interlaced, int margins) 311 { 312 /* 1) top/bottom margin size (% of height) - default: 1.8, */ 313 #define GTF_MARGIN_PERCENTAGE 18 314 /* 2) character cell horizontal granularity (pixels) - default 8 */ 315 #define GTF_CELL_GRAN 8 316 /* 3) Minimum vertical porch (lines) - default 3 */ 317 #define GTF_MIN_V_PORCH 1 318 /* width of vsync in lines */ 319 #define V_SYNC_RQD 3 320 /* width of hsync as % of total line */ 321 #define H_SYNC_PERCENT 8 322 /* min time of vsync + back porch (microsec) */ 323 #define MIN_VSYNC_PLUS_BP 550 324 /* blanking formula gradient */ 325 #define GTF_M 600 326 /* blanking formula offset */ 327 #define GTF_C 40 328 /* blanking formula scaling factor */ 329 #define GTF_K 128 330 /* blanking formula scaling factor */ 331 #define GTF_J 20 332 /* C' and M' are part of the Blanking Duty Cycle computation */ 333 #define GTF_C_PRIME (((GTF_C - GTF_J) * GTF_K / 256) + GTF_J) 334 #define GTF_M_PRIME (GTF_K * GTF_M / 256) 335 struct drm_display_mode *drm_mode; 336 unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd; 337 int top_margin, bottom_margin; 338 int interlace; 339 unsigned int hfreq_est; 340 int vsync_plus_bp, vback_porch; 341 unsigned int vtotal_lines, vfieldrate_est, hperiod; 342 unsigned int vfield_rate, vframe_rate; 343 int left_margin, right_margin; 344 unsigned int total_active_pixels, ideal_duty_cycle; 345 unsigned int hblank, total_pixels, pixel_freq; 346 int hsync, hfront_porch, vodd_front_porch_lines; 347 unsigned int tmp1, tmp2; 348 349 drm_mode = drm_mode_create(dev); 350 if (!drm_mode) 351 return NULL; 352 353 /* 1. In order to give correct results, the number of horizontal 354 * pixels requested is first processed to ensure that it is divisible 355 * by the character size, by rounding it to the nearest character 356 * cell boundary: 357 */ 358 hdisplay_rnd = (hdisplay + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN; 359 hdisplay_rnd = hdisplay_rnd * GTF_CELL_GRAN; 360 361 /* 2. If interlace is requested, the number of vertical lines assumed 362 * by the calculation must be halved, as the computation calculates 363 * the number of vertical lines per field. 364 */ 365 if (interlaced) 366 vdisplay_rnd = vdisplay / 2; 367 else 368 vdisplay_rnd = vdisplay; 369 370 /* 3. Find the frame rate required: */ 371 if (interlaced) 372 vfieldrate_rqd = vrefresh * 2; 373 else 374 vfieldrate_rqd = vrefresh; 375 376 /* 4. Find number of lines in Top margin: */ 377 top_margin = 0; 378 if (margins) 379 top_margin = (vdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) / 380 1000; 381 /* 5. Find number of lines in bottom margin: */ 382 bottom_margin = top_margin; 383 384 /* 6. If interlace is required, then set variable interlace: */ 385 if (interlaced) 386 interlace = 1; 387 else 388 interlace = 0; 389 390 /* 7. Estimate the Horizontal frequency */ 391 { 392 tmp1 = (1000000 - MIN_VSYNC_PLUS_BP * vfieldrate_rqd) / 500; 393 tmp2 = (vdisplay_rnd + 2 * top_margin + GTF_MIN_V_PORCH) * 394 2 + interlace; 395 hfreq_est = (tmp2 * 1000 * vfieldrate_rqd) / tmp1; 396 } 397 398 /* 8. Find the number of lines in V sync + back porch */ 399 /* [V SYNC+BP] = RINT(([MIN VSYNC+BP] * hfreq_est / 1000000)) */ 400 vsync_plus_bp = MIN_VSYNC_PLUS_BP * hfreq_est / 1000; 401 vsync_plus_bp = (vsync_plus_bp + 500) / 1000; 402 /* 9. Find the number of lines in V back porch alone: */ 403 vback_porch = vsync_plus_bp - V_SYNC_RQD; 404 /* 10. Find the total number of lines in Vertical field period: */ 405 vtotal_lines = vdisplay_rnd + top_margin + bottom_margin + 406 vsync_plus_bp + GTF_MIN_V_PORCH; 407 /* 11. Estimate the Vertical field frequency: */ 408 vfieldrate_est = hfreq_est / vtotal_lines; 409 /* 12. Find the actual horizontal period: */ 410 hperiod = 1000000 / (vfieldrate_rqd * vtotal_lines); 411 412 /* 13. Find the actual Vertical field frequency: */ 413 vfield_rate = hfreq_est / vtotal_lines; 414 /* 14. Find the Vertical frame frequency: */ 415 if (interlaced) 416 vframe_rate = vfield_rate / 2; 417 else 418 vframe_rate = vfield_rate; 419 /* 15. Find number of pixels in left margin: */ 420 if (margins) 421 left_margin = (hdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) / 422 1000; 423 else 424 left_margin = 0; 425 426 /* 16.Find number of pixels in right margin: */ 427 right_margin = left_margin; 428 /* 17.Find total number of active pixels in image and left and right */ 429 total_active_pixels = hdisplay_rnd + left_margin + right_margin; 430 /* 18.Find the ideal blanking duty cycle from blanking duty cycle */ 431 ideal_duty_cycle = GTF_C_PRIME * 1000 - 432 (GTF_M_PRIME * 1000000 / hfreq_est); 433 /* 19.Find the number of pixels in the blanking time to the nearest 434 * double character cell: */ 435 hblank = total_active_pixels * ideal_duty_cycle / 436 (100000 - ideal_duty_cycle); 437 hblank = (hblank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN); 438 hblank = hblank * 2 * GTF_CELL_GRAN; 439 /* 20.Find total number of pixels: */ 440 total_pixels = total_active_pixels + hblank; 441 /* 21.Find pixel clock frequency: */ 442 pixel_freq = total_pixels * hfreq_est / 1000; 443 /* Stage 1 computations are now complete; I should really pass 444 * the results to another function and do the Stage 2 computations, 445 * but I only need a few more values so I'll just append the 446 * computations here for now */ 447 /* 17. Find the number of pixels in the horizontal sync period: */ 448 hsync = H_SYNC_PERCENT * total_pixels / 100; 449 hsync = (hsync + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN; 450 hsync = hsync * GTF_CELL_GRAN; 451 /* 18. Find the number of pixels in horizontal front porch period */ 452 hfront_porch = hblank / 2 - hsync; 453 /* 36. Find the number of lines in the odd front porch period: */ 454 vodd_front_porch_lines = GTF_MIN_V_PORCH ; 455 456 /* finally, pack the results in the mode struct */ 457 drm_mode->hdisplay = hdisplay_rnd; 458 drm_mode->hsync_start = hdisplay_rnd + hfront_porch; 459 drm_mode->hsync_end = drm_mode->hsync_start + hsync; 460 drm_mode->htotal = total_pixels; 461 drm_mode->vdisplay = vdisplay_rnd; 462 drm_mode->vsync_start = vdisplay_rnd + vodd_front_porch_lines; 463 drm_mode->vsync_end = drm_mode->vsync_start + V_SYNC_RQD; 464 drm_mode->vtotal = vtotal_lines; 465 466 drm_mode->clock = pixel_freq; 467 468 drm_mode_set_name(drm_mode); 469 drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC; 470 471 if (interlaced) { 472 drm_mode->vtotal *= 2; 473 drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; 474 } 475 476 return drm_mode; 477 } 478 EXPORT_SYMBOL(drm_gtf_mode); 479 /** 480 * drm_mode_set_name - set the name on a mode 481 * @mode: name will be set in this mode 482 * 483 * LOCKING: 484 * None. 485 * 486 * Set the name of @mode to a standard format. 487 */ 488 void drm_mode_set_name(struct drm_display_mode *mode) 489 { 490 snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d", mode->hdisplay, 491 mode->vdisplay); 492 } 493 EXPORT_SYMBOL(drm_mode_set_name); 494 495 /** 496 * drm_mode_list_concat - move modes from one list to another 497 * @head: source list 498 * @new: dst list 499 * 500 * LOCKING: 501 * Caller must ensure both lists are locked. 502 * 503 * Move all the modes from @head to @new. 504 */ 505 void drm_mode_list_concat(struct list_head *head, struct list_head *new) 506 { 507 508 struct list_head *entry, *tmp; 509 510 list_for_each_safe(entry, tmp, head) { 511 list_move_tail(entry, new); 512 } 513 } 514 EXPORT_SYMBOL(drm_mode_list_concat); 515 516 /** 517 * drm_mode_width - get the width of a mode 518 * @mode: mode 519 * 520 * LOCKING: 521 * None. 522 * 523 * Return @mode's width (hdisplay) value. 524 * 525 * FIXME: is this needed? 526 * 527 * RETURNS: 528 * @mode->hdisplay 529 */ 530 int drm_mode_width(struct drm_display_mode *mode) 531 { 532 return mode->hdisplay; 533 534 } 535 EXPORT_SYMBOL(drm_mode_width); 536 537 /** 538 * drm_mode_height - get the height of a mode 539 * @mode: mode 540 * 541 * LOCKING: 542 * None. 543 * 544 * Return @mode's height (vdisplay) value. 545 * 546 * FIXME: is this needed? 547 * 548 * RETURNS: 549 * @mode->vdisplay 550 */ 551 int drm_mode_height(struct drm_display_mode *mode) 552 { 553 return mode->vdisplay; 554 } 555 EXPORT_SYMBOL(drm_mode_height); 556 557 /** 558 * drm_mode_vrefresh - get the vrefresh of a mode 559 * @mode: mode 560 * 561 * LOCKING: 562 * None. 563 * 564 * Return @mode's vrefresh rate or calculate it if necessary. 565 * 566 * FIXME: why is this needed? shouldn't vrefresh be set already? 567 * 568 * RETURNS: 569 * Vertical refresh rate. It will be the result of actual value plus 0.5. 570 * If it is 70.288, it will return 70Hz. 571 * If it is 59.6, it will return 60Hz. 572 */ 573 int drm_mode_vrefresh(struct drm_display_mode *mode) 574 { 575 int refresh = 0; 576 unsigned int calc_val; 577 578 if (mode->vrefresh > 0) 579 refresh = mode->vrefresh; 580 else if (mode->htotal > 0 && mode->vtotal > 0) { 581 int vtotal; 582 vtotal = mode->vtotal; 583 /* work out vrefresh the value will be x1000 */ 584 calc_val = (mode->clock * 1000); 585 calc_val /= mode->htotal; 586 refresh = (calc_val + vtotal / 2) / vtotal; 587 588 if (mode->flags & DRM_MODE_FLAG_INTERLACE) 589 refresh *= 2; 590 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 591 refresh /= 2; 592 if (mode->vscan > 1) 593 refresh /= mode->vscan; 594 } 595 return refresh; 596 } 597 EXPORT_SYMBOL(drm_mode_vrefresh); 598 599 /** 600 * drm_mode_set_crtcinfo - set CRTC modesetting parameters 601 * @p: mode 602 * @adjust_flags: unused? (FIXME) 603 * 604 * LOCKING: 605 * None. 606 * 607 * Setup the CRTC modesetting parameters for @p, adjusting if necessary. 608 */ 609 void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) 610 { 611 if ((p == NULL) || ((p->type & DRM_MODE_TYPE_CRTC_C) == DRM_MODE_TYPE_BUILTIN)) 612 return; 613 614 p->crtc_hdisplay = p->hdisplay; 615 p->crtc_hsync_start = p->hsync_start; 616 p->crtc_hsync_end = p->hsync_end; 617 p->crtc_htotal = p->htotal; 618 p->crtc_hskew = p->hskew; 619 p->crtc_vdisplay = p->vdisplay; 620 p->crtc_vsync_start = p->vsync_start; 621 p->crtc_vsync_end = p->vsync_end; 622 p->crtc_vtotal = p->vtotal; 623 624 if (p->flags & DRM_MODE_FLAG_INTERLACE) { 625 if (adjust_flags & CRTC_INTERLACE_HALVE_V) { 626 p->crtc_vdisplay /= 2; 627 p->crtc_vsync_start /= 2; 628 p->crtc_vsync_end /= 2; 629 p->crtc_vtotal /= 2; 630 } 631 632 p->crtc_vtotal |= 1; 633 } 634 635 if (p->flags & DRM_MODE_FLAG_DBLSCAN) { 636 p->crtc_vdisplay *= 2; 637 p->crtc_vsync_start *= 2; 638 p->crtc_vsync_end *= 2; 639 p->crtc_vtotal *= 2; 640 } 641 642 if (p->vscan > 1) { 643 p->crtc_vdisplay *= p->vscan; 644 p->crtc_vsync_start *= p->vscan; 645 p->crtc_vsync_end *= p->vscan; 646 p->crtc_vtotal *= p->vscan; 647 } 648 649 p->crtc_vblank_start = min(p->crtc_vsync_start, p->crtc_vdisplay); 650 p->crtc_vblank_end = max(p->crtc_vsync_end, p->crtc_vtotal); 651 p->crtc_hblank_start = min(p->crtc_hsync_start, p->crtc_hdisplay); 652 p->crtc_hblank_end = max(p->crtc_hsync_end, p->crtc_htotal); 653 654 p->crtc_hadjusted = false; 655 p->crtc_vadjusted = false; 656 } 657 EXPORT_SYMBOL(drm_mode_set_crtcinfo); 658 659 660 /** 661 * drm_mode_duplicate - allocate and duplicate an existing mode 662 * @m: mode to duplicate 663 * 664 * LOCKING: 665 * None. 666 * 667 * Just allocate a new mode, copy the existing mode into it, and return 668 * a pointer to it. Used to create new instances of established modes. 669 */ 670 struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, 671 struct drm_display_mode *mode) 672 { 673 struct drm_display_mode *nmode; 674 int new_id; 675 676 nmode = drm_mode_create(dev); 677 if (!nmode) 678 return NULL; 679 680 new_id = nmode->base.id; 681 *nmode = *mode; 682 nmode->base.id = new_id; 683 INIT_LIST_HEAD(&nmode->head); 684 return nmode; 685 } 686 EXPORT_SYMBOL(drm_mode_duplicate); 687 688 /** 689 * drm_mode_equal - test modes for equality 690 * @mode1: first mode 691 * @mode2: second mode 692 * 693 * LOCKING: 694 * None. 695 * 696 * Check to see if @mode1 and @mode2 are equivalent. 697 * 698 * RETURNS: 699 * True if the modes are equal, false otherwise. 700 */ 701 bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2) 702 { 703 /* do clock check convert to PICOS so fb modes get matched 704 * the same */ 705 if (mode1->clock && mode2->clock) { 706 if (KHZ2PICOS(mode1->clock) != KHZ2PICOS(mode2->clock)) 707 return false; 708 } else if (mode1->clock != mode2->clock) 709 return false; 710 711 if (mode1->hdisplay == mode2->hdisplay && 712 mode1->hsync_start == mode2->hsync_start && 713 mode1->hsync_end == mode2->hsync_end && 714 mode1->htotal == mode2->htotal && 715 mode1->hskew == mode2->hskew && 716 mode1->vdisplay == mode2->vdisplay && 717 mode1->vsync_start == mode2->vsync_start && 718 mode1->vsync_end == mode2->vsync_end && 719 mode1->vtotal == mode2->vtotal && 720 mode1->vscan == mode2->vscan && 721 mode1->flags == mode2->flags) 722 return true; 723 724 return false; 725 } 726 EXPORT_SYMBOL(drm_mode_equal); 727 728 /** 729 * drm_mode_validate_size - make sure modes adhere to size constraints 730 * @dev: DRM device 731 * @mode_list: list of modes to check 732 * @maxX: maximum width 733 * @maxY: maximum height 734 * @maxPitch: max pitch 735 * 736 * LOCKING: 737 * Caller must hold a lock protecting @mode_list. 738 * 739 * The DRM device (@dev) has size and pitch limits. Here we validate the 740 * modes we probed for @dev against those limits and set their status as 741 * necessary. 742 */ 743 void drm_mode_validate_size(struct drm_device *dev, 744 struct list_head *mode_list, 745 int maxX, int maxY, int maxPitch) 746 { 747 struct drm_display_mode *mode; 748 749 list_for_each_entry(mode, mode_list, head) { 750 if (maxPitch > 0 && mode->hdisplay > maxPitch) 751 mode->status = MODE_BAD_WIDTH; 752 753 if (maxX > 0 && mode->hdisplay > maxX) 754 mode->status = MODE_VIRTUAL_X; 755 756 if (maxY > 0 && mode->vdisplay > maxY) 757 mode->status = MODE_VIRTUAL_Y; 758 } 759 } 760 EXPORT_SYMBOL(drm_mode_validate_size); 761 762 /** 763 * drm_mode_validate_clocks - validate modes against clock limits 764 * @dev: DRM device 765 * @mode_list: list of modes to check 766 * @min: minimum clock rate array 767 * @max: maximum clock rate array 768 * @n_ranges: number of clock ranges (size of arrays) 769 * 770 * LOCKING: 771 * Caller must hold a lock protecting @mode_list. 772 * 773 * Some code may need to check a mode list against the clock limits of the 774 * device in question. This function walks the mode list, testing to make 775 * sure each mode falls within a given range (defined by @min and @max 776 * arrays) and sets @mode->status as needed. 777 */ 778 void drm_mode_validate_clocks(struct drm_device *dev, 779 struct list_head *mode_list, 780 int *min, int *max, int n_ranges) 781 { 782 struct drm_display_mode *mode; 783 int i; 784 785 list_for_each_entry(mode, mode_list, head) { 786 bool good = false; 787 for (i = 0; i < n_ranges; i++) { 788 if (mode->clock >= min[i] && mode->clock <= max[i]) { 789 good = true; 790 break; 791 } 792 } 793 if (!good) 794 mode->status = MODE_CLOCK_RANGE; 795 } 796 } 797 EXPORT_SYMBOL(drm_mode_validate_clocks); 798 799 /** 800 * drm_mode_prune_invalid - remove invalid modes from mode list 801 * @dev: DRM device 802 * @mode_list: list of modes to check 803 * @verbose: be verbose about it 804 * 805 * LOCKING: 806 * Caller must hold a lock protecting @mode_list. 807 * 808 * Once mode list generation is complete, a caller can use this routine to 809 * remove invalid modes from a mode list. If any of the modes have a 810 * status other than %MODE_OK, they are removed from @mode_list and freed. 811 */ 812 void drm_mode_prune_invalid(struct drm_device *dev, 813 struct list_head *mode_list, bool verbose) 814 { 815 struct drm_display_mode *mode, *t; 816 817 list_for_each_entry_safe(mode, t, mode_list, head) { 818 if (mode->status != MODE_OK) { 819 list_del(&mode->head); 820 if (verbose) { 821 drm_mode_debug_printmodeline(mode); 822 DRM_DEBUG_KMS("Not using %s mode %d\n", 823 mode->name, mode->status); 824 } 825 drm_mode_destroy(dev, mode); 826 } 827 } 828 } 829 EXPORT_SYMBOL(drm_mode_prune_invalid); 830 831 /** 832 * drm_mode_compare - compare modes for favorability 833 * @lh_a: list_head for first mode 834 * @lh_b: list_head for second mode 835 * 836 * LOCKING: 837 * None. 838 * 839 * Compare two modes, given by @lh_a and @lh_b, returning a value indicating 840 * which is better. 841 * 842 * RETURNS: 843 * Negative if @lh_a is better than @lh_b, zero if they're equivalent, or 844 * positive if @lh_b is better than @lh_a. 845 */ 846 static int drm_mode_compare(struct list_head *lh_a, struct list_head *lh_b) 847 { 848 struct drm_display_mode *a = list_entry(lh_a, struct drm_display_mode, head); 849 struct drm_display_mode *b = list_entry(lh_b, struct drm_display_mode, head); 850 int diff; 851 852 diff = ((b->type & DRM_MODE_TYPE_PREFERRED) != 0) - 853 ((a->type & DRM_MODE_TYPE_PREFERRED) != 0); 854 if (diff) 855 return diff; 856 diff = b->hdisplay * b->vdisplay - a->hdisplay * a->vdisplay; 857 if (diff) 858 return diff; 859 diff = b->clock - a->clock; 860 return diff; 861 } 862 863 /* FIXME: what we don't have a list sort function? */ 864 /* list sort from Mark J Roberts (mjr@znex.org) */ 865 void list_sort(struct list_head *head, 866 int (*cmp)(struct list_head *a, struct list_head *b)) 867 { 868 struct list_head *p, *q, *e, *list, *tail, *oldhead; 869 int insize, nmerges, psize, qsize, i; 870 871 list = head->next; 872 list_del(head); 873 insize = 1; 874 for (;;) { 875 p = oldhead = list; 876 list = tail = NULL; 877 nmerges = 0; 878 879 while (p) { 880 nmerges++; 881 q = p; 882 psize = 0; 883 for (i = 0; i < insize; i++) { 884 psize++; 885 q = q->next == oldhead ? NULL : q->next; 886 if (!q) 887 break; 888 } 889 890 qsize = insize; 891 while (psize > 0 || (qsize > 0 && q)) { 892 if (!psize) { 893 e = q; 894 q = q->next; 895 qsize--; 896 if (q == oldhead) 897 q = NULL; 898 } else if (!qsize || !q) { 899 e = p; 900 p = p->next; 901 psize--; 902 if (p == oldhead) 903 p = NULL; 904 } else if (cmp(p, q) <= 0) { 905 e = p; 906 p = p->next; 907 psize--; 908 if (p == oldhead) 909 p = NULL; 910 } else { 911 e = q; 912 q = q->next; 913 qsize--; 914 if (q == oldhead) 915 q = NULL; 916 } 917 if (tail) 918 tail->next = e; 919 else 920 list = e; 921 e->prev = tail; 922 tail = e; 923 } 924 p = q; 925 } 926 927 tail->next = list; 928 list->prev = tail; 929 930 if (nmerges <= 1) 931 break; 932 933 insize *= 2; 934 } 935 936 head->next = list; 937 head->prev = list->prev; 938 list->prev->next = head; 939 list->prev = head; 940 } 941 942 /** 943 * drm_mode_sort - sort mode list 944 * @mode_list: list to sort 945 * 946 * LOCKING: 947 * Caller must hold a lock protecting @mode_list. 948 * 949 * Sort @mode_list by favorability, putting good modes first. 950 */ 951 void drm_mode_sort(struct list_head *mode_list) 952 { 953 list_sort(mode_list, drm_mode_compare); 954 } 955 EXPORT_SYMBOL(drm_mode_sort); 956 957 /** 958 * drm_mode_connector_list_update - update the mode list for the connector 959 * @connector: the connector to update 960 * 961 * LOCKING: 962 * Caller must hold a lock protecting @mode_list. 963 * 964 * This moves the modes from the @connector probed_modes list 965 * to the actual mode list. It compares the probed mode against the current 966 * list and only adds different modes. All modes unverified after this point 967 * will be removed by the prune invalid modes. 968 */ 969 void drm_mode_connector_list_update(struct drm_connector *connector) 970 { 971 struct drm_display_mode *mode; 972 struct drm_display_mode *pmode, *pt; 973 int found_it; 974 975 list_for_each_entry_safe(pmode, pt, &connector->probed_modes, 976 head) { 977 found_it = 0; 978 /* go through current modes checking for the new probed mode */ 979 list_for_each_entry(mode, &connector->modes, head) { 980 if (drm_mode_equal(pmode, mode)) { 981 found_it = 1; 982 /* if equal delete the probed mode */ 983 mode->status = pmode->status; 984 /* Merge type bits together */ 985 mode->type |= pmode->type; 986 list_del(&pmode->head); 987 drm_mode_destroy(connector->dev, pmode); 988 break; 989 } 990 } 991 992 if (!found_it) { 993 list_move_tail(&pmode->head, &connector->modes); 994 } 995 } 996 } 997 EXPORT_SYMBOL(drm_mode_connector_list_update); 998