195009aeeSAxel Dörfler /*
295009aeeSAxel Dörfler * Copyright 2011, Axel Dörfler, axeld@pinc-software.de.
395009aeeSAxel Dörfler * Distributed under the terms of the MIT License.
495009aeeSAxel Dörfler */
595009aeeSAxel Dörfler
695009aeeSAxel Dörfler /* Generate mode timings using the GTF Timing Standard
795009aeeSAxel Dörfler *
895009aeeSAxel Dörfler * Copyright (c) 2001, Andy Ritger aritger@nvidia.com
995009aeeSAxel Dörfler * All rights reserved.
1095009aeeSAxel Dörfler *
1195009aeeSAxel Dörfler * Redistribution and use in source and binary forms, with or without
1295009aeeSAxel Dörfler * modification, are permitted provided that the following conditions
1395009aeeSAxel Dörfler * are met:
1495009aeeSAxel Dörfler *
1595009aeeSAxel Dörfler * o Redistributions of source code must retain the above copyright
1695009aeeSAxel Dörfler * notice, this list of conditions and the following disclaimer.
1795009aeeSAxel Dörfler * o Redistributions in binary form must reproduce the above copyright
1895009aeeSAxel Dörfler * notice, this list of conditions and the following disclaimer
1995009aeeSAxel Dörfler * in the documentation and/or other materials provided with the
2095009aeeSAxel Dörfler * distribution.
2195009aeeSAxel Dörfler * o Neither the name of NVIDIA nor the names of its contributors
2295009aeeSAxel Dörfler * may be used to endorse or promote products derived from this
2395009aeeSAxel Dörfler * software without specific prior written permission.
2495009aeeSAxel Dörfler *
2595009aeeSAxel Dörfler *
2695009aeeSAxel Dörfler * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2795009aeeSAxel Dörfler * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
2895009aeeSAxel Dörfler * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
2995009aeeSAxel Dörfler * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
3095009aeeSAxel Dörfler * THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
3195009aeeSAxel Dörfler * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
3295009aeeSAxel Dörfler * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3395009aeeSAxel Dörfler * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3495009aeeSAxel Dörfler * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3595009aeeSAxel Dörfler * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
3695009aeeSAxel Dörfler * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3795009aeeSAxel Dörfler * POSSIBILITY OF SUCH DAMAGE.
3895009aeeSAxel Dörfler *
3995009aeeSAxel Dörfler *
4095009aeeSAxel Dörfler *
4195009aeeSAxel Dörfler * This program is based on the Generalized Timing Formula(GTF TM)
4295009aeeSAxel Dörfler * Standard Version: 1.0, Revision: 1.0
4395009aeeSAxel Dörfler *
4495009aeeSAxel Dörfler * The GTF Document contains the following Copyright information:
4595009aeeSAxel Dörfler *
4695009aeeSAxel Dörfler * Copyright (c) 1994, 1995, 1996 - Video Electronics Standards
4795009aeeSAxel Dörfler * Association. Duplication of this document within VESA member
4895009aeeSAxel Dörfler * companies for review purposes is permitted. All other rights
4995009aeeSAxel Dörfler * reserved.
5095009aeeSAxel Dörfler *
5195009aeeSAxel Dörfler * While every precaution has been taken in the preparation
5295009aeeSAxel Dörfler * of this standard, the Video Electronics Standards Association and
5395009aeeSAxel Dörfler * its contributors assume no responsibility for errors or omissions,
5495009aeeSAxel Dörfler * and make no warranties, expressed or implied, of functionality
5595009aeeSAxel Dörfler * of suitability for any purpose. The sample code contained within
5695009aeeSAxel Dörfler * this standard may be used without restriction.
5795009aeeSAxel Dörfler *
5895009aeeSAxel Dörfler *
5995009aeeSAxel Dörfler *
6095009aeeSAxel Dörfler * The GTF EXCEL(TM) SPREADSHEET, a sample (and the definitive)
6195009aeeSAxel Dörfler * implementation of the GTF Timing Standard, is available at:
6295009aeeSAxel Dörfler *
6395009aeeSAxel Dörfler * ftp://ftp.vesa.org/pub/GTF/GTF_V1R1.xls
6495009aeeSAxel Dörfler *
6595009aeeSAxel Dörfler *
6695009aeeSAxel Dörfler *
6795009aeeSAxel Dörfler * This program takes a desired resolution and vertical refresh rate,
6895009aeeSAxel Dörfler * and computes mode timings according to the GTF Timing Standard.
6995009aeeSAxel Dörfler * These mode timings can then be formatted as an XFree86 modeline
7095009aeeSAxel Dörfler * or a mode description for use by fbset(8).
7195009aeeSAxel Dörfler *
7295009aeeSAxel Dörfler * NOTES:
7395009aeeSAxel Dörfler *
7495009aeeSAxel Dörfler * The GTF allows for computation of "margins" (the visible border
7595009aeeSAxel Dörfler * surrounding the addressable video); on most non-overscan type
7695009aeeSAxel Dörfler * systems, the margin period is zero. I've implemented the margin
7795009aeeSAxel Dörfler * computations but not enabled it because 1) I don't really have
7895009aeeSAxel Dörfler * any experience with this, and 2) neither XFree86 modelines nor
7995009aeeSAxel Dörfler * fbset fb.modes provide an obvious way for margin timings to be
8095009aeeSAxel Dörfler * included in their mode descriptions (needs more investigation).
8195009aeeSAxel Dörfler *
8295009aeeSAxel Dörfler * The GTF provides for computation of interlaced mode timings;
8395009aeeSAxel Dörfler * I've implemented the computations but not enabled them, yet.
8495009aeeSAxel Dörfler * I should probably enable and test this at some point.
8595009aeeSAxel Dörfler *
8695009aeeSAxel Dörfler * TODO:
8795009aeeSAxel Dörfler *
8895009aeeSAxel Dörfler * o Add support for interlaced modes.
8995009aeeSAxel Dörfler *
9095009aeeSAxel Dörfler * o Implement the other portions of the GTF: compute mode timings
9195009aeeSAxel Dörfler * given either the desired pixel clock or the desired horizontal
9295009aeeSAxel Dörfler * frequency.
9395009aeeSAxel Dörfler *
9495009aeeSAxel Dörfler * o It would be nice if this were more general purpose to do things
9595009aeeSAxel Dörfler * outside the scope of the GTF: like generate double scan mode
9695009aeeSAxel Dörfler * timings, for example.
9795009aeeSAxel Dörfler *
9895009aeeSAxel Dörfler * o Error checking.
9995009aeeSAxel Dörfler *
10095009aeeSAxel Dörfler */
10195009aeeSAxel Dörfler
10295009aeeSAxel Dörfler
10395009aeeSAxel Dörfler #include <compute_display_timing.h>
10495009aeeSAxel Dörfler
10595009aeeSAxel Dörfler #include <math.h>
10695009aeeSAxel Dörfler #include <stdarg.h>
10795009aeeSAxel Dörfler
10895009aeeSAxel Dörfler
10995009aeeSAxel Dörfler //#define TRACE_COMPUTE
11095009aeeSAxel Dörfler #ifdef TRACE_COMPUTE
11195009aeeSAxel Dörfler # define TRACE(x, ...) debug_printf(x, __VA_ARGS__)
11295009aeeSAxel Dörfler #else
11395009aeeSAxel Dörfler # define TRACE(x, ...) ;
11495009aeeSAxel Dörfler #endif
11595009aeeSAxel Dörfler
11695009aeeSAxel Dörfler
11795009aeeSAxel Dörfler #define MARGIN_PERCENT 1.8 // % of active vertical image
118*c97f0d47SAxel Dörfler #define CELL_GRANULARITY 8.0
119*c97f0d47SAxel Dörfler // assumed character cell granularity
12095009aeeSAxel Dörfler #define MIN_PORCH 1 // minimum front porch
121*c97f0d47SAxel Dörfler #define V_SYNC_WIDTH 3 // width of vsync in lines
12295009aeeSAxel Dörfler #define H_SYNC_PERCENT 8.0 // width of hsync as % of total line
123*c97f0d47SAxel Dörfler #define MIN_VSYNC_PLUS_BACK_PORCH 550.0 // time in microsec
124*c97f0d47SAxel Dörfler
125*c97f0d47SAxel Dörfler // C' and M' are part of the Blanking Duty Cycle computation
126*c97f0d47SAxel Dörfler
12795009aeeSAxel Dörfler #define M 600.0 // blanking formula gradient
12895009aeeSAxel Dörfler #define C 40.0 // blanking formula offset
12995009aeeSAxel Dörfler #define K 128.0 // blanking formula scaling factor
13095009aeeSAxel Dörfler #define J 20.0 // blanking formula scaling factor
13195009aeeSAxel Dörfler #define C_PRIME (((C - J) * K / 256.0) + J)
13295009aeeSAxel Dörfler #define M_PRIME (K / 256.0 * M)
13395009aeeSAxel Dörfler
13495009aeeSAxel Dörfler
13595009aeeSAxel Dörfler /*! As defined by the GTF Timing Standard, compute the Stage 1 Parameters
13695009aeeSAxel Dörfler using the vertical refresh frequency. In other words: input a desired
13795009aeeSAxel Dörfler resolution and desired refresh rate, and output the GTF mode timings.
13895009aeeSAxel Dörfler */
13995009aeeSAxel Dörfler status_t
compute_display_timing(uint32 width,uint32 height,float refresh,bool interlaced,display_timing * timing)14095009aeeSAxel Dörfler compute_display_timing(uint32 width, uint32 height, float refresh,
14195009aeeSAxel Dörfler bool interlaced, display_timing* timing)
14295009aeeSAxel Dörfler {
14395009aeeSAxel Dörfler if (width < 320 || height < 200 || width > 65536 || height > 65536
14495009aeeSAxel Dörfler || refresh < 25 || refresh > 1000)
14595009aeeSAxel Dörfler return B_BAD_VALUE;
14695009aeeSAxel Dörfler
147*c97f0d47SAxel Dörfler bool margins = false;
14895009aeeSAxel Dörfler
14995009aeeSAxel Dörfler // 1. In order to give correct results, the number of horizontal
15095009aeeSAxel Dörfler // pixels requested is first processed to ensure that it is divisible
15195009aeeSAxel Dörfler // by the character size, by rounding it to the nearest character
15295009aeeSAxel Dörfler // cell boundary:
15395009aeeSAxel Dörfler // [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND])
154*c97f0d47SAxel Dörfler width = (uint32)(rint(width / CELL_GRANULARITY) * CELL_GRANULARITY);
15595009aeeSAxel Dörfler
15695009aeeSAxel Dörfler // 2. If interlace is requested, the number of vertical lines assumed
15795009aeeSAxel Dörfler // by the calculation must be halved, as the computation calculates
15895009aeeSAxel Dörfler // the number of vertical lines per field. In either case, the
15995009aeeSAxel Dörfler // number of lines is rounded to the nearest integer.
16095009aeeSAxel Dörfler // [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0),
16195009aeeSAxel Dörfler // ROUND([V LINES],0))
162*c97f0d47SAxel Dörfler float verticalLines = interlaced ? (double)height / 2.0 : (double)height;
16395009aeeSAxel Dörfler
16495009aeeSAxel Dörfler // 3. Find the frame rate required:
16595009aeeSAxel Dörfler // [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2,
16695009aeeSAxel Dörfler // [I/P FREQ RQD])
167*c97f0d47SAxel Dörfler float verticalFieldRate = interlaced ? refresh * 2.0 : refresh;
16895009aeeSAxel Dörfler
16995009aeeSAxel Dörfler // 4. Find number of lines in Top margin:
17095009aeeSAxel Dörfler // [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
17195009aeeSAxel Dörfler // ROUND(([MARGIN%]/100*[V LINES RND]),0), 0)
172*c97f0d47SAxel Dörfler float topMargin = margins ? rint(MARGIN_PERCENT / 100.0 * verticalLines)
173*c97f0d47SAxel Dörfler : 0.0;
17495009aeeSAxel Dörfler
17595009aeeSAxel Dörfler // 5. Find number of lines in Bottom margin:
17695009aeeSAxel Dörfler // [BOT MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
17795009aeeSAxel Dörfler // ROUND(([MARGIN%]/100*[V LINES RND]),0), 0)
178*c97f0d47SAxel Dörfler float bottomMargin = margins ? rint(MARGIN_PERCENT / 100.0 * verticalLines)
179*c97f0d47SAxel Dörfler : 0.0;
18095009aeeSAxel Dörfler
18195009aeeSAxel Dörfler // 6. If interlace is required, then set variable [INTERLACE]=0.5:
18295009aeeSAxel Dörfler // [INTERLACE]=(IF([INT RQD?]="y",0.5,0))
183*c97f0d47SAxel Dörfler float interlace = interlaced ? 0.5 : 0.0;
18495009aeeSAxel Dörfler
18595009aeeSAxel Dörfler // 7. Estimate the Horizontal period
18695009aeeSAxel Dörfler // [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000)
18795009aeeSAxel Dörfler // / ([V LINES RND] + (2*[TOP MARGIN (LINES)])
18895009aeeSAxel Dörfler // + [MIN PORCH RND]+[INTERLACE]) * 1000000
189*c97f0d47SAxel Dörfler float horizontalPeriodEstimate = (1.0 / verticalFieldRate
190*c97f0d47SAxel Dörfler - MIN_VSYNC_PLUS_BACK_PORCH / 1000000.0)
191*c97f0d47SAxel Dörfler / (verticalLines + (2 * topMargin) + MIN_PORCH + interlace) * 1000000.0;
19295009aeeSAxel Dörfler
19395009aeeSAxel Dörfler // 8. Find the number of lines in V sync + back porch:
19495009aeeSAxel Dörfler // [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0)
195*c97f0d47SAxel Dörfler float verticalSyncPlusBackPorch = rint(MIN_VSYNC_PLUS_BACK_PORCH
196*c97f0d47SAxel Dörfler / horizontalPeriodEstimate);
19795009aeeSAxel Dörfler
19895009aeeSAxel Dörfler // 10. Find the total number of lines in Vertical field period:
19995009aeeSAxel Dörfler // [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)]
20095009aeeSAxel Dörfler // + [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] + [MIN PORCH RND]
201*c97f0d47SAxel Dörfler float totalVerticalLines = verticalLines + topMargin + bottomMargin
202*c97f0d47SAxel Dörfler + verticalSyncPlusBackPorch + interlace + MIN_PORCH;
20395009aeeSAxel Dörfler
20495009aeeSAxel Dörfler // 11. Estimate the Vertical field frequency:
20595009aeeSAxel Dörfler // [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000
206*c97f0d47SAxel Dörfler float verticalFieldRateEstimate = 1.0 / horizontalPeriodEstimate
207*c97f0d47SAxel Dörfler / totalVerticalLines * 1000000.0;
20895009aeeSAxel Dörfler
20995009aeeSAxel Dörfler // 12. Find the actual horizontal period:
21095009aeeSAxel Dörfler // [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST])
211*c97f0d47SAxel Dörfler float horizontalPeriod = horizontalPeriodEstimate
212*c97f0d47SAxel Dörfler / (verticalFieldRate / verticalFieldRateEstimate);
21395009aeeSAxel Dörfler
21495009aeeSAxel Dörfler // 15. Find number of pixels in left margin:
21595009aeeSAxel Dörfler // [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
21695009aeeSAxel Dörfler // (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
21795009aeeSAxel Dörfler // [CELL GRAN RND]),0)) * [CELL GRAN RND], 0))
218*c97f0d47SAxel Dörfler float leftMargin = margins ? rint(width * MARGIN_PERCENT / 100.0
219*c97f0d47SAxel Dörfler / CELL_GRANULARITY) * CELL_GRANULARITY : 0.0;
22095009aeeSAxel Dörfler
22195009aeeSAxel Dörfler // 16. Find number of pixels in right margin:
22295009aeeSAxel Dörfler // [RIGHT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
22395009aeeSAxel Dörfler // (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
22495009aeeSAxel Dörfler // [CELL GRAN RND]),0)) * [CELL GRAN RND], 0))
225*c97f0d47SAxel Dörfler float rightMargin = margins ? rint(width * MARGIN_PERCENT / 100.0
226*c97f0d47SAxel Dörfler / CELL_GRANULARITY) * CELL_GRANULARITY : 0.0;
22795009aeeSAxel Dörfler
22895009aeeSAxel Dörfler // 17. Find total number of active pixels in image and left and right
22995009aeeSAxel Dörfler // margins:
23095009aeeSAxel Dörfler // [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)]
23195009aeeSAxel Dörfler // + [RIGHT MARGIN (PIXELS)]
232*c97f0d47SAxel Dörfler float totalActivePixels = width + leftMargin + rightMargin;
23395009aeeSAxel Dörfler
23495009aeeSAxel Dörfler // 18. Find the ideal blanking duty cycle from the blanking duty cycle
23595009aeeSAxel Dörfler // equation:
23695009aeeSAxel Dörfler // [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000)
237*c97f0d47SAxel Dörfler float idealDutyCycle = C_PRIME - (M_PRIME * horizontalPeriod / 1000.0);
23895009aeeSAxel Dörfler
23995009aeeSAxel Dörfler // 19. Find the number of pixels in the blanking time to the nearest
24095009aeeSAxel Dörfler // double character cell:
24195009aeeSAxel Dörfler // [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS]
24295009aeeSAxel Dörfler // * [IDEAL DUTY CYCLE] / (100-[IDEAL DUTY CYCLE])
24395009aeeSAxel Dörfler // / (2*[CELL GRAN RND])), 0)) * (2*[CELL GRAN RND])
244*c97f0d47SAxel Dörfler float horizontalBlank = rint(totalActivePixels * idealDutyCycle
245*c97f0d47SAxel Dörfler / (100.0 - idealDutyCycle) / (2.0 * CELL_GRANULARITY))
246*c97f0d47SAxel Dörfler * (2.0 * CELL_GRANULARITY);
24795009aeeSAxel Dörfler
24895009aeeSAxel Dörfler // 20. Find total number of pixels:
24995009aeeSAxel Dörfler // [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)]
250*c97f0d47SAxel Dörfler float totalPixels = totalActivePixels + horizontalBlank;
25195009aeeSAxel Dörfler
25295009aeeSAxel Dörfler // 21. Find pixel clock frequency:
25395009aeeSAxel Dörfler // [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD]
254*c97f0d47SAxel Dörfler float pixelFrequency = totalPixels / horizontalPeriod;
25595009aeeSAxel Dörfler
25695009aeeSAxel Dörfler // Stage 1 computations are now complete; I should really pass
25795009aeeSAxel Dörfler // the results to another function and do the Stage 2
25895009aeeSAxel Dörfler // computations, but I only need a few more values so I'll just
25995009aeeSAxel Dörfler // append the computations here for now */
26095009aeeSAxel Dörfler
26195009aeeSAxel Dörfler // 17. Find the number of pixels in the horizontal sync period:
26295009aeeSAxel Dörfler // [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS]
26395009aeeSAxel Dörfler // / [CELL GRAN RND]),0))*[CELL GRAN RND]
264*c97f0d47SAxel Dörfler float horizontalSync = rint(H_SYNC_PERCENT / 100.0 * totalPixels
265*c97f0d47SAxel Dörfler / CELL_GRANULARITY) * CELL_GRANULARITY;
26695009aeeSAxel Dörfler
26795009aeeSAxel Dörfler // 18. Find the number of pixels in the horizontal front porch period:
26895009aeeSAxel Dörfler // [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)]
269*c97f0d47SAxel Dörfler float horizontalFrontPorch = (horizontalBlank / 2.0) - horizontalSync;
27095009aeeSAxel Dörfler
27195009aeeSAxel Dörfler // 36. Find the number of lines in the odd front porch period:
27295009aeeSAxel Dörfler // [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE])
273*c97f0d47SAxel Dörfler float verticalOddFrontPorchLines = MIN_PORCH + interlace;
27495009aeeSAxel Dörfler
27595009aeeSAxel Dörfler // finally, pack the results in the mode struct
27695009aeeSAxel Dörfler
277*c97f0d47SAxel Dörfler timing->pixel_clock = uint32(pixelFrequency * 1000);
278*c97f0d47SAxel Dörfler timing->h_display = (uint16)width;
279*c97f0d47SAxel Dörfler timing->h_sync_start = (uint16)(width + horizontalFrontPorch);
280*c97f0d47SAxel Dörfler timing->h_sync_end
281*c97f0d47SAxel Dörfler = (uint16)(width + horizontalFrontPorch + horizontalSync);
282*c97f0d47SAxel Dörfler timing->h_total = (uint16)totalPixels;
283*c97f0d47SAxel Dörfler timing->v_display = (uint16)verticalLines;
284*c97f0d47SAxel Dörfler timing->v_sync_start = (uint16)(verticalLines + verticalOddFrontPorchLines);
285*c97f0d47SAxel Dörfler timing->v_sync_end
286*c97f0d47SAxel Dörfler = (uint16)(verticalLines + verticalOddFrontPorchLines + V_SYNC_WIDTH);
287*c97f0d47SAxel Dörfler timing->v_total = (uint16)totalVerticalLines;
28895009aeeSAxel Dörfler timing->flags = B_POSITIVE_HSYNC | B_POSITIVE_VSYNC
28995009aeeSAxel Dörfler | (interlace ? B_TIMING_INTERLACED : 0);
29095009aeeSAxel Dörfler
29195009aeeSAxel Dörfler TRACE("GTF TIMING: %lu kHz, (%u, %u, %u, %u), (%u, %u, %u, %u)\n",
29295009aeeSAxel Dörfler timing->pixel_clock, timing->h_display, timing->h_sync_start,
29395009aeeSAxel Dörfler timing->h_sync_end, timing->h_total, timing->v_display,
29495009aeeSAxel Dörfler timing->v_sync_start, timing->v_sync_end, timing->v_total);
29595009aeeSAxel Dörfler
29695009aeeSAxel Dörfler return B_OK;
29795009aeeSAxel Dörfler }
298