239
239
* "mode_name" dot_clock timings flags
242
static nvModeLinePtr modeline_parse(const char *modeline_str,
242
static nvModeLinePtr modeline_parse(nvDisplayPtr display,
243
const char *modeline_str,
243
244
const int broken_doublescan_modelines)
245
246
nvModeLinePtr modeline = NULL;
361
* Calculate the vertical refresh rate of the modeline in Hz;
362
* divide by two for double scan modes (if the double scan
363
* modeline isn't broken; i.e., already has a correct vtotal), and
364
* multiply by two for interlaced modes (so that we report the
365
* field rate, rather than the frame rate)
368
htotal = (double) modeline->data.htotal;
369
vtotal = (double) modeline->data.vtotal;
371
pclk = strtod(modeline->data.clock, &nptr);
373
if ((pclk == 0.0) || !nptr || *nptr != '\0' || ((htotal * vtotal) == 0)) {
374
nv_warning_msg("Failed to compute the refresh rate "
375
"for the modeline '%s'", str);
379
modeline->refresh_rate = (pclk * 1000000.0) / (htotal * vtotal);
383
if ((modeline->data.flags & V_DBLSCAN) && !broken_doublescan_modelines) {
387
if (modeline->data.flags & V_INTERLACE) {
391
modeline->refresh_rate *= factor;
360
modeline->refresh_rate = 0;
361
if (display->is_sdi && display->gpu->num_gvo_modes) {
362
/* Fetch the SDI refresh rate of the mode from the gvo mode table */
364
for (i = 0; i < display->gpu->num_gvo_modes; i++) {
365
if (display->gpu->gvo_mode_data[i].id &&
366
display->gpu->gvo_mode_data[i].name &&
367
!strcmp(display->gpu->gvo_mode_data[i].name,
368
modeline->data.identifier)) {
369
modeline->refresh_rate = display->gpu->gvo_mode_data[i].rate;
370
modeline->refresh_rate /= 1000.0;
376
if (modeline->refresh_rate == 0) {
378
* Calculate the vertical refresh rate of the modeline in Hz;
379
* divide by two for double scan modes (if the double scan
380
* modeline isn't broken; i.e., already has a correct vtotal), and
381
* multiply by two for interlaced modes (so that we report the
382
* field rate, rather than the frame rate)
385
htotal = (double) modeline->data.htotal;
386
vtotal = (double) modeline->data.vtotal;
388
pclk = strtod(modeline->data.clock, &nptr);
390
if ((pclk == 0.0) || !nptr || *nptr != '\0' || ((htotal * vtotal) == 0)) {
391
nv_warning_msg("Failed to compute the refresh rate "
392
"for the modeline '%s'", str);
396
modeline->refresh_rate = (pclk * 1000000.0) / (htotal * vtotal);
400
if ((modeline->data.flags & V_DBLSCAN) && !broken_doublescan_modelines) {
404
if (modeline->data.flags & V_INTERLACE) {
408
modeline->refresh_rate *= factor;
393
411
/* Restore the locale */
394
412
if (old_locale) {
939
957
/* Add the modeline at the end of the display's modeline list */
940
display->modelines = (nvModeLinePtr)xconfigAddListItem
941
((GenericListPtr)display->modelines, (GenericListPtr)modeline);
958
xconfigAddListItem((GenericListPtr *)(&display->modelines),
959
(GenericListPtr)modeline);
942
960
display->num_modelines++;
944
962
/* Get next modeline string */
1245
1263
/* Add the metamode at the end of the screen's metamode list */
1247
(nvMetaModePtr)xconfigAddListItem((GenericListPtr)screen->metamodes,
1248
(GenericListPtr)metamode);
1264
xconfigAddListItem((GenericListPtr *)(&screen->metamodes),
1265
(GenericListPtr)metamode);
1251
1268
/* Split up the metamode into separate modes */
1653
1668
/* Remove the display from the GPU */
1655
(nvDisplayPtr)xconfigRemoveListItem((GenericListPtr)gpu->displays,
1656
(GenericListPtr)display);
1669
xconfigRemoveListItem((GenericListPtr *)(&gpu->displays),
1670
(GenericListPtr)display);
1657
1671
gpu->connected_displays &= ~(display->device_mask);
1658
1672
gpu->num_displays--;
1705
/** gpu_query_gvo_mode_info() ****************************************
1707
* Adds GVO mode information to the GPU's gvo mode data table at
1708
* the given table index.
1711
static Bool gpu_query_gvo_mode_info(nvGpuPtr gpu, int mode_id, int table_idx)
1713
ReturnStatus ret1, ret2;
1719
if (!gpu || table_idx >= gpu->num_gvo_modes) {
1723
data = &(gpu->gvo_mode_data[table_idx]);
1725
ret1 = NvCtrlGetDisplayAttribute(gpu->handle,
1727
NV_CTRL_GVO_VIDEO_FORMAT_REFRESH_RATE,
1730
ret2 = NvCtrlGetStringDisplayAttribute(gpu->handle,
1732
NV_CTRL_STRING_GVO_VIDEO_FORMAT_NAME,
1735
if ((ret1 == NvCtrlSuccess) && (ret2 == NvCtrlSuccess)) {
1691
1747
/** gpu_add_display_from_server() ************************************
1693
1749
* Adds the display with the device mask given to the GPU structure.
1785
/* Query if this display is an SDI display */
1786
ret = NvCtrlGetDisplayAttribute(gpu->handle, device_mask,
1787
NV_CTRL_IS_GVO_DISPLAY,
1788
&(display->is_sdi));
1789
if (ret != NvCtrlSuccess) {
1790
nv_warning_msg("Failed to query if display device\n"
1791
"0x%08x connected to GPU-%d '%s' is an\n"
1793
device_mask, NvCtrlGetTargetId(gpu->handle),
1795
display->is_sdi = FALSE;
1799
/* Load the SDI mode table so we can report accurate refresh rates. */
1800
if (display->is_sdi && !gpu->gvo_mode_data) {
1801
unsigned int valid1 = 0;
1802
unsigned int valid2 = 0;
1803
NVCTRLAttributeValidValuesRec valid;
1805
ret = NvCtrlGetValidAttributeValues(gpu->handle,
1806
NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT,
1808
if ((ret != NvCtrlSuccess) ||
1809
(valid.type != ATTRIBUTE_TYPE_INT_BITS)) {
1812
valid1 = valid.u.bits.ints;
1815
ret = NvCtrlGetValidAttributeValues(gpu->handle,
1816
NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT2,
1818
if ((ret != NvCtrlSuccess) ||
1819
(valid.type != ATTRIBUTE_TYPE_INT_BITS)) {
1822
valid2 = valid.u.bits.ints;
1825
/* Count the number of valid modes there are */
1826
gpu->num_gvo_modes = count_number_of_bits(valid1);
1827
gpu->num_gvo_modes += count_number_of_bits(valid2);
1828
if (gpu->num_gvo_modes > 0) {
1829
gpu->gvo_mode_data = (GvoModeData *)calloc(gpu->num_gvo_modes,
1830
sizeof(GvoModeData));
1832
if (!gpu->gvo_mode_data) {
1833
gpu->num_gvo_modes = 0;
1835
// Gather all the bits and dump them into the array
1836
int idx = 0; // Index into gvo_mode_data.
1837
int id = 0; // Mode ID
1840
if (gpu_query_gvo_mode_info(gpu, id, idx)) {
1849
if (gpu_query_gvo_mode_info(gpu, id, idx)) {
1729
1860
/* Query the modelines for the display device */
1730
1861
if (!display_add_modelines_from_server(display, err_str)) {
1731
1862
nv_warning_msg("Failed to add modelines to display device 0x%08x "
1739
1870
/* Add the display at the end of gpu's display list */
1741
(nvDisplayPtr)xconfigAddListItem((GenericListPtr)gpu->displays,
1742
(GenericListPtr)display);
1871
xconfigAddListItem((GenericListPtr *)(&gpu->displays),
1872
(GenericListPtr)display);
1743
1873
gpu->connected_displays |= device_mask;
1744
1874
gpu->num_displays++;
1745
1875
return display;