diff options
author | Anthony Koo <Anthony.Koo@amd.com> | 2018-02-22 09:50:25 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-03-14 16:08:47 -0400 |
commit | a3e1737ed61c8b6ea078f477eee612e26f9d2561 (patch) | |
tree | 479253ee203048b79487c05160626b6277241eb3 /drivers/gpu/drm/amd/display/modules/freesync/freesync.c | |
parent | e18d3086733bd150f87594a754ae983329fb0ba1 (diff) |
drm/amd/display: Implement stats logging
Stats will be used for debug purposes
Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules/freesync/freesync.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 129 |
1 files changed, 99 insertions, 30 deletions
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index b4723af368a5..e849b704f2f6 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c | |||
@@ -33,7 +33,7 @@ | |||
33 | /* Refresh rate ramp at a fixed rate of 65 Hz/second */ | 33 | /* Refresh rate ramp at a fixed rate of 65 Hz/second */ |
34 | #define STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME ((1000 / 60) * 65) | 34 | #define STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME ((1000 / 60) * 65) |
35 | /* Number of elements in the render times cache array */ | 35 | /* Number of elements in the render times cache array */ |
36 | #define RENDER_TIMES_MAX_COUNT 20 | 36 | #define RENDER_TIMES_MAX_COUNT 10 |
37 | /* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */ | 37 | /* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */ |
38 | #define BTR_EXIT_MARGIN 2000 | 38 | #define BTR_EXIT_MARGIN 2000 |
39 | /* Number of consecutive frames to check before entering/exiting fixed refresh*/ | 39 | /* Number of consecutive frames to check before entering/exiting fixed refresh*/ |
@@ -52,7 +52,7 @@ struct gradual_static_ramp { | |||
52 | unsigned int ramp_current_frame_duration_in_ns; | 52 | unsigned int ramp_current_frame_duration_in_ns; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | struct time_cache { | 55 | struct freesync_time { |
56 | /* video (48Hz feature) related */ | 56 | /* video (48Hz feature) related */ |
57 | unsigned int update_duration_in_ns; | 57 | unsigned int update_duration_in_ns; |
58 | 58 | ||
@@ -64,6 +64,9 @@ struct time_cache { | |||
64 | 64 | ||
65 | unsigned int render_times_index; | 65 | unsigned int render_times_index; |
66 | unsigned int render_times[RENDER_TIMES_MAX_COUNT]; | 66 | unsigned int render_times[RENDER_TIMES_MAX_COUNT]; |
67 | |||
68 | unsigned int min_window; | ||
69 | unsigned int max_window; | ||
67 | }; | 70 | }; |
68 | 71 | ||
69 | struct below_the_range { | 72 | struct below_the_range { |
@@ -98,11 +101,14 @@ struct freesync_state { | |||
98 | bool static_screen; | 101 | bool static_screen; |
99 | bool video; | 102 | bool video; |
100 | 103 | ||
104 | unsigned int vmin; | ||
105 | unsigned int vmax; | ||
106 | |||
107 | struct freesync_time time; | ||
108 | |||
101 | unsigned int nominal_refresh_rate_in_micro_hz; | 109 | unsigned int nominal_refresh_rate_in_micro_hz; |
102 | bool windowed_fullscreen; | 110 | bool windowed_fullscreen; |
103 | 111 | ||
104 | struct time_cache time; | ||
105 | |||
106 | struct gradual_static_ramp static_ramp; | 112 | struct gradual_static_ramp static_ramp; |
107 | struct below_the_range btr; | 113 | struct below_the_range btr; |
108 | struct fixed_refresh fixed_refresh; | 114 | struct fixed_refresh fixed_refresh; |
@@ -124,9 +130,9 @@ struct freesync_registry_options { | |||
124 | struct core_freesync { | 130 | struct core_freesync { |
125 | struct mod_freesync public; | 131 | struct mod_freesync public; |
126 | struct dc *dc; | 132 | struct dc *dc; |
133 | struct freesync_registry_options opts; | ||
127 | struct freesync_entity *map; | 134 | struct freesync_entity *map; |
128 | int num_entities; | 135 | int num_entities; |
129 | struct freesync_registry_options opts; | ||
130 | }; | 136 | }; |
131 | 137 | ||
132 | #define MOD_FREESYNC_TO_CORE(mod_freesync)\ | 138 | #define MOD_FREESYNC_TO_CORE(mod_freesync)\ |
@@ -146,7 +152,7 @@ struct mod_freesync *mod_freesync_create(struct dc *dc) | |||
146 | goto fail_alloc_context; | 152 | goto fail_alloc_context; |
147 | 153 | ||
148 | core_freesync->map = kzalloc(sizeof(struct freesync_entity) * MOD_FREESYNC_MAX_CONCURRENT_STREAMS, | 154 | core_freesync->map = kzalloc(sizeof(struct freesync_entity) * MOD_FREESYNC_MAX_CONCURRENT_STREAMS, |
149 | GFP_KERNEL); | 155 | GFP_KERNEL); |
150 | 156 | ||
151 | if (core_freesync->map == NULL) | 157 | if (core_freesync->map == NULL) |
152 | goto fail_alloc_map; | 158 | goto fail_alloc_map; |
@@ -330,6 +336,25 @@ bool mod_freesync_remove_stream(struct mod_freesync *mod_freesync, | |||
330 | return true; | 336 | return true; |
331 | } | 337 | } |
332 | 338 | ||
339 | static void adjust_vmin_vmax(struct core_freesync *core_freesync, | ||
340 | struct dc_stream_state **streams, | ||
341 | int num_streams, | ||
342 | int map_index, | ||
343 | unsigned int v_total_min, | ||
344 | unsigned int v_total_max) | ||
345 | { | ||
346 | if (num_streams == 0 || streams == NULL || num_streams > 1) | ||
347 | return; | ||
348 | |||
349 | core_freesync->map[map_index].state.vmin = v_total_min; | ||
350 | core_freesync->map[map_index].state.vmax = v_total_max; | ||
351 | |||
352 | dc_stream_adjust_vmin_vmax(core_freesync->dc, streams, | ||
353 | num_streams, v_total_min, | ||
354 | v_total_max); | ||
355 | } | ||
356 | |||
357 | |||
333 | static void update_stream_freesync_context(struct core_freesync *core_freesync, | 358 | static void update_stream_freesync_context(struct core_freesync *core_freesync, |
334 | struct dc_stream_state *stream) | 359 | struct dc_stream_state *stream) |
335 | { | 360 | { |
@@ -588,9 +613,10 @@ static bool set_freesync_on_streams(struct core_freesync *core_freesync, | |||
588 | update_stream_freesync_context(core_freesync, | 613 | update_stream_freesync_context(core_freesync, |
589 | streams[stream_idx]); | 614 | streams[stream_idx]); |
590 | 615 | ||
591 | dc_stream_adjust_vmin_vmax(core_freesync->dc, streams, | 616 | adjust_vmin_vmax(core_freesync, streams, |
592 | num_streams, v_total_min, | 617 | num_streams, map_index, |
593 | v_total_max); | 618 | v_total_min, |
619 | v_total_max); | ||
594 | 620 | ||
595 | return true; | 621 | return true; |
596 | 622 | ||
@@ -613,9 +639,10 @@ static bool set_freesync_on_streams(struct core_freesync *core_freesync, | |||
613 | core_freesync, | 639 | core_freesync, |
614 | streams[stream_idx]); | 640 | streams[stream_idx]); |
615 | 641 | ||
616 | dc_stream_adjust_vmin_vmax( | 642 | adjust_vmin_vmax( |
617 | core_freesync->dc, streams, | 643 | core_freesync, streams, |
618 | num_streams, v_total_nominal, | 644 | num_streams, map_index, |
645 | v_total_nominal, | ||
619 | v_total_nominal); | 646 | v_total_nominal); |
620 | } | 647 | } |
621 | return true; | 648 | return true; |
@@ -632,9 +659,10 @@ static bool set_freesync_on_streams(struct core_freesync *core_freesync, | |||
632 | core_freesync, | 659 | core_freesync, |
633 | streams[stream_idx]); | 660 | streams[stream_idx]); |
634 | 661 | ||
635 | dc_stream_adjust_vmin_vmax(core_freesync->dc, streams, | 662 | adjust_vmin_vmax(core_freesync, streams, |
636 | num_streams, v_total_nominal, | 663 | num_streams, map_index, |
637 | v_total_nominal); | 664 | v_total_nominal, |
665 | v_total_nominal); | ||
638 | 666 | ||
639 | /* Reset the cached variables */ | 667 | /* Reset the cached variables */ |
640 | reset_freesync_state_variables(state); | 668 | reset_freesync_state_variables(state); |
@@ -650,9 +678,10 @@ static bool set_freesync_on_streams(struct core_freesync *core_freesync, | |||
650 | * not support freesync because a former stream has | 678 | * not support freesync because a former stream has |
651 | * be programmed | 679 | * be programmed |
652 | */ | 680 | */ |
653 | dc_stream_adjust_vmin_vmax(core_freesync->dc, streams, | 681 | adjust_vmin_vmax(core_freesync, streams, |
654 | num_streams, v_total_nominal, | 682 | num_streams, map_index, |
655 | v_total_nominal); | 683 | v_total_nominal, |
684 | v_total_nominal); | ||
656 | /* Reset the cached variables */ | 685 | /* Reset the cached variables */ |
657 | reset_freesync_state_variables(state); | 686 | reset_freesync_state_variables(state); |
658 | } | 687 | } |
@@ -769,8 +798,9 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync, | |||
769 | vmin = inserted_frame_v_total; | 798 | vmin = inserted_frame_v_total; |
770 | 799 | ||
771 | /* Program V_TOTAL */ | 800 | /* Program V_TOTAL */ |
772 | dc_stream_adjust_vmin_vmax(core_freesync->dc, streams, | 801 | adjust_vmin_vmax(core_freesync, streams, |
773 | num_streams, vmin, vmax); | 802 | num_streams, index, |
803 | vmin, vmax); | ||
774 | } | 804 | } |
775 | 805 | ||
776 | if (state->btr.frame_counter > 0) | 806 | if (state->btr.frame_counter > 0) |
@@ -804,9 +834,10 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync, | |||
804 | update_stream_freesync_context(core_freesync, streams[0]); | 834 | update_stream_freesync_context(core_freesync, streams[0]); |
805 | 835 | ||
806 | /* Program static screen ramp values */ | 836 | /* Program static screen ramp values */ |
807 | dc_stream_adjust_vmin_vmax(core_freesync->dc, streams, | 837 | adjust_vmin_vmax(core_freesync, streams, |
808 | num_streams, v_total, | 838 | num_streams, index, |
809 | v_total); | 839 | v_total, |
840 | v_total); | ||
810 | 841 | ||
811 | triggers.overlay_update = true; | 842 | triggers.overlay_update = true; |
812 | triggers.surface_update = true; | 843 | triggers.surface_update = true; |
@@ -1063,9 +1094,9 @@ bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync, | |||
1063 | max_refresh); | 1094 | max_refresh); |
1064 | 1095 | ||
1065 | /* Program vtotal min/max */ | 1096 | /* Program vtotal min/max */ |
1066 | dc_stream_adjust_vmin_vmax(core_freesync->dc, &streams, 1, | 1097 | adjust_vmin_vmax(core_freesync, &streams, 1, index, |
1067 | state->freesync_range.vmin, | 1098 | state->freesync_range.vmin, |
1068 | state->freesync_range.vmax); | 1099 | state->freesync_range.vmax); |
1069 | } | 1100 | } |
1070 | 1101 | ||
1071 | if (min_refresh != 0 && | 1102 | if (min_refresh != 0 && |
@@ -1399,11 +1430,9 @@ static void apply_fixed_refresh(struct core_freesync *core_freesync, | |||
1399 | } else { | 1430 | } else { |
1400 | 1431 | ||
1401 | vmin = state->freesync_range.vmin; | 1432 | vmin = state->freesync_range.vmin; |
1402 | |||
1403 | vmax = vmin; | 1433 | vmax = vmin; |
1404 | 1434 | adjust_vmin_vmax(core_freesync, &stream, map_index, | |
1405 | dc_stream_adjust_vmin_vmax(core_freesync->dc, &stream, | 1435 | 1, vmin, vmax); |
1406 | 1, vmin, vmax); | ||
1407 | } | 1436 | } |
1408 | } | 1437 | } |
1409 | 1438 | ||
@@ -1457,3 +1486,43 @@ void mod_freesync_pre_update_plane_addresses(struct mod_freesync *mod_freesync, | |||
1457 | 1486 | ||
1458 | } | 1487 | } |
1459 | } | 1488 | } |
1489 | |||
1490 | void mod_freesync_get_settings(struct mod_freesync *mod_freesync, | ||
1491 | struct dc_stream_state **streams, int num_streams, | ||
1492 | unsigned int *v_total_min, unsigned int *v_total_max, | ||
1493 | unsigned int *event_triggers, | ||
1494 | unsigned int *window_min, unsigned int *window_max, | ||
1495 | unsigned int *lfc_mid_point_in_us, | ||
1496 | unsigned int *inserted_frames, | ||
1497 | unsigned int *inserted_duration_in_us) | ||
1498 | { | ||
1499 | unsigned int stream_index, map_index; | ||
1500 | struct core_freesync *core_freesync = NULL; | ||
1501 | |||
1502 | if (mod_freesync == NULL) | ||
1503 | return; | ||
1504 | |||
1505 | core_freesync = MOD_FREESYNC_TO_CORE(mod_freesync); | ||
1506 | |||
1507 | for (stream_index = 0; stream_index < num_streams; stream_index++) { | ||
1508 | |||
1509 | map_index = map_index_from_stream(core_freesync, | ||
1510 | streams[stream_index]); | ||
1511 | |||
1512 | if (core_freesync->map[map_index].caps->supported) { | ||
1513 | struct freesync_state state = | ||
1514 | core_freesync->map[map_index].state; | ||
1515 | *v_total_min = state.vmin; | ||
1516 | *v_total_max = state.vmax; | ||
1517 | *event_triggers = 0; | ||
1518 | *window_min = state.time.min_window; | ||
1519 | *window_max = state.time.max_window; | ||
1520 | *lfc_mid_point_in_us = state.btr.mid_point_in_us; | ||
1521 | *inserted_frames = state.btr.frames_to_insert; | ||
1522 | *inserted_duration_in_us = | ||
1523 | state.btr.inserted_frame_duration_in_us; | ||
1524 | } | ||
1525 | |||
1526 | } | ||
1527 | } | ||
1528 | |||