external/drm_gralloc
Revision | ec1214bdb07d56f12a12f1d487f1da5e80340389 (tree) |
---|---|
Zeit | 2013-03-29 16:09:13 |
Autor | Somebody <definesinsanity@gmai...> |
Commiter | Chih-Wei Huang |
allow to force graphics mode
This patch adds in a system property "debug.drm.mode.force", which works
*similarly* to "debug.drm.mode". XRESxYRES[@REFRESHRATE].
@@ -30,6 +30,7 @@ | ||
30 | 30 | #include <signal.h> |
31 | 31 | #include <stdlib.h> |
32 | 32 | #include <stdio.h> |
33 | +#include <math.h> | |
33 | 34 | #include "gralloc_drm.h" |
34 | 35 | #include "gralloc_drm_priv.h" |
35 | 36 |
@@ -360,12 +361,104 @@ static void drm_kms_init_features(struct gralloc_drm_t *drm) | ||
360 | 361 | LOGD("will use %s for fb posting", swap_mode); |
361 | 362 | } |
362 | 363 | |
364 | +#define MARGIN_PERCENT 1.8 /* % of active vertical image*/ | |
365 | +#define CELL_GRAN 8.0 /* assumed character cell granularity*/ | |
366 | +#define MIN_PORCH 1 /* minimum front porch */ | |
367 | +#define V_SYNC_RQD 3 /* width of vsync in lines */ | |
368 | +#define H_SYNC_PERCENT 8.0 /* width of hsync as % of total line */ | |
369 | +#define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */ | |
370 | +#define M 600.0 /* blanking formula gradient */ | |
371 | +#define C 40.0 /* blanking formula offset */ | |
372 | +#define K 128.0 /* blanking formula scaling factor */ | |
373 | +#define J 20.0 /* blanking formula scaling factor */ | |
374 | +/* C' and M' are part of the Blanking Duty Cycle computation */ | |
375 | +#define C_PRIME (((C - J) * K / 256.0) + J) | |
376 | +#define M_PRIME (K / 256.0 * M) | |
377 | + | |
378 | +static drmModeModeInfoPtr generate_mode(int h_pixels, int v_lines, float freq) | |
379 | +{ | |
380 | + float h_pixels_rnd; | |
381 | + float v_lines_rnd; | |
382 | + float v_field_rate_rqd; | |
383 | + float top_margin; | |
384 | + float bottom_margin; | |
385 | + float interlace; | |
386 | + float h_period_est; | |
387 | + float vsync_plus_bp; | |
388 | + float v_back_porch; | |
389 | + float total_v_lines; | |
390 | + float v_field_rate_est; | |
391 | + float h_period; | |
392 | + float v_field_rate; | |
393 | + float v_frame_rate; | |
394 | + float left_margin; | |
395 | + float right_margin; | |
396 | + float total_active_pixels; | |
397 | + float ideal_duty_cycle; | |
398 | + float h_blank; | |
399 | + float total_pixels; | |
400 | + float pixel_freq; | |
401 | + float h_freq; | |
402 | + | |
403 | + float h_sync; | |
404 | + float h_front_porch; | |
405 | + float v_odd_front_porch_lines; | |
406 | + int interlaced = 0; | |
407 | + int margins = 0; | |
408 | + | |
409 | + drmModeModeInfoPtr m = malloc(sizeof(drmModeModeInfo)); | |
410 | + | |
411 | + h_pixels_rnd = rint((float) h_pixels / CELL_GRAN) * CELL_GRAN; | |
412 | + v_lines_rnd = interlaced ? rint((float) v_lines) / 2.0 : rint((float) v_lines); | |
413 | + v_field_rate_rqd = interlaced ? (freq * 2.0) : (freq); | |
414 | + top_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0); | |
415 | + bottom_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0); | |
416 | + interlace = interlaced ? 0.5 : 0.0; | |
417 | + h_period_est = (((1.0 / v_field_rate_rqd) - (MIN_VSYNC_PLUS_BP / 1000000.0)) / (v_lines_rnd + (2 * top_margin) + MIN_PORCH + interlace) * 1000000.0); | |
418 | + vsync_plus_bp = rint(MIN_VSYNC_PLUS_BP / h_period_est); | |
419 | + v_back_porch = vsync_plus_bp - V_SYNC_RQD; | |
420 | + total_v_lines = v_lines_rnd + top_margin + bottom_margin + vsync_plus_bp + interlace + MIN_PORCH; | |
421 | + v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0; | |
422 | + h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est); | |
423 | + v_field_rate = 1.0 / h_period / total_v_lines * 1000000.0; | |
424 | + v_frame_rate = interlaced ? v_field_rate / 2.0 : v_field_rate; | |
425 | + left_margin = margins ? rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN : 0.0; | |
426 | + right_margin = margins ? rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN : 0.0; | |
427 | + total_active_pixels = h_pixels_rnd + left_margin + right_margin; | |
428 | + ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0); | |
429 | + h_blank = rint(total_active_pixels * ideal_duty_cycle / (100.0 - ideal_duty_cycle) / (2.0 * CELL_GRAN)) * (2.0 * CELL_GRAN); | |
430 | + total_pixels = total_active_pixels + h_blank; | |
431 | + pixel_freq = total_pixels / h_period; | |
432 | + h_freq = 1000.0 / h_period; | |
433 | + h_sync = rint(H_SYNC_PERCENT / 100.0 * total_pixels / CELL_GRAN) * CELL_GRAN; | |
434 | + h_front_porch = (h_blank / 2.0) - h_sync; | |
435 | + v_odd_front_porch_lines = MIN_PORCH + interlace; | |
436 | + | |
437 | + m->clock = ceil(pixel_freq) * 1000; | |
438 | + m->hdisplay = (int) (h_pixels_rnd); | |
439 | + m->hsync_start = (int) (h_pixels_rnd + h_front_porch); | |
440 | + m->hsync_end = (int) (h_pixels_rnd + h_front_porch + h_sync); | |
441 | + m->htotal = (int) (total_pixels); | |
442 | + m->hskew = 0; | |
443 | + m->vdisplay = (int) (v_lines_rnd); | |
444 | + m->vsync_start = (int) (v_lines_rnd + v_odd_front_porch_lines); | |
445 | + m->vsync_end = (int) (int) (v_lines_rnd + v_odd_front_porch_lines + V_SYNC_RQD); | |
446 | + m->vtotal = (int) (total_v_lines); | |
447 | + m->vscan = 0; | |
448 | + m->vrefresh = freq; | |
449 | + m->flags = 10; | |
450 | + m->type = 64; | |
451 | + | |
452 | + return (m); | |
453 | +} | |
454 | + | |
363 | 455 | static drmModeModeInfoPtr find_mode(drmModeConnectorPtr connector, int *bpp) |
364 | 456 | { |
365 | 457 | char value[PROPERTY_VALUE_MAX]; |
366 | 458 | drmModeModeInfoPtr mode; |
367 | 459 | int dist, i; |
368 | - int xres = 0, yres = 0; | |
460 | + int xres = 0, yres = 0, rate = 0; | |
461 | + int forcemode = 0; | |
369 | 462 | |
370 | 463 | if (property_get("debug.drm.mode", value, NULL)) { |
371 | 464 | char *p = value, *end; |
@@ -381,31 +474,50 @@ static drmModeModeInfoPtr find_mode(drmModeConnectorPtr connector, int *bpp) | ||
381 | 474 | LOGI("will find the closest match for %dx%d@%d", |
382 | 475 | xres, yres, *bpp); |
383 | 476 | } |
384 | - } | |
385 | - else { | |
477 | + } else if (property_get("debug.drm.mode.force", value, NULL)) { | |
478 | + char *p = value, *end; | |
479 | + *bpp = 0; | |
480 | + | |
481 | + /* parse <xres>x<yres>[@<refreshrate>] */ | |
482 | + if (sscanf(value, "%dx%d@%d", &xres, &yres, &rate) != 3) { | |
483 | + rate = 60; | |
484 | + if (sscanf(value, "%dx%d", &xres, &yres) != 2) | |
485 | + xres = yres = 0; | |
486 | + } | |
487 | + | |
488 | + if (xres && yres && rate) { | |
489 | + LOGI("will use %dx%d@%dHz", xres, yres, rate); | |
490 | + forcemode = 1; | |
491 | + } | |
492 | + } else { | |
386 | 493 | *bpp = 0; |
387 | 494 | } |
388 | 495 | |
389 | - mode = NULL; | |
390 | 496 | dist = INT_MAX; |
391 | - for (i = 0; i < connector->count_modes; i++) { | |
392 | - drmModeModeInfoPtr m = &connector->modes[i]; | |
393 | - int tmp; | |
394 | 497 | |
395 | - if (xres && yres) { | |
396 | - tmp = (m->hdisplay - xres) * (m->hdisplay - xres) + | |
397 | - (m->vdisplay - yres) * (m->vdisplay - yres); | |
398 | - } | |
399 | - else { | |
400 | - /* use the first preferred mode */ | |
401 | - tmp = (m->type & DRM_MODE_TYPE_PREFERRED) ? 0 : dist; | |
402 | - } | |
498 | + if (forcemode) | |
499 | + mode = generate_mode(xres, yres, rate); | |
500 | + else { | |
501 | + mode = NULL; | |
502 | + for (i = 0; i < connector->count_modes; i++) { | |
503 | + drmModeModeInfoPtr m = &connector->modes[i]; | |
504 | + int tmp; | |
505 | + | |
506 | + if (xres && yres) { | |
507 | + tmp = (m->hdisplay - xres) * (m->hdisplay - xres) + | |
508 | + (m->vdisplay - yres) * (m->vdisplay - yres); | |
509 | + } | |
510 | + else { | |
511 | + /* use the first preferred mode */ | |
512 | + tmp = (m->type & DRM_MODE_TYPE_PREFERRED) ? 0 : dist; | |
513 | + } | |
403 | 514 | |
404 | - if (tmp < dist) { | |
405 | - mode = m; | |
406 | - dist = tmp; | |
407 | - if (!dist) | |
408 | - break; | |
515 | + if (tmp < dist) { | |
516 | + mode = m; | |
517 | + dist = tmp; | |
518 | + if (!dist) | |
519 | + break; | |
520 | + } | |
409 | 521 | } |
410 | 522 | } |
411 | 523 |
@@ -413,6 +525,11 @@ static drmModeModeInfoPtr find_mode(drmModeConnectorPtr connector, int *bpp) | ||
413 | 525 | if (!mode) |
414 | 526 | mode = &connector->modes[0]; |
415 | 527 | |
528 | + LOGI("Established mode:"); | |
529 | + LOGI("clock: %d, hdisplay: %d, hsync_start: %d, hsync_end: %d, htotal: %d, hskew: %d", mode->clock, mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal, mode->hskew); | |
530 | + LOGI("vdisplay: %d, vsync_start: %d, vsync_end: %d, vtotal: %d, vscan: %d, vrefresh: %d", mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal, mode->vscan, mode->vrefresh); | |
531 | + LOGI("flags: %d, type: %d, name %s", mode->flags, mode->type, mode->name); | |
532 | + | |
416 | 533 | *bpp /= 8; |
417 | 534 | |
418 | 535 | return mode; |