Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
      3  *                VA Linux Systems Inc., Fremont, California.
      4  *
      5  * All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining
      8  * a copy of this software and associated documentation files (the
      9  * "Software"), to deal in the Software without restriction, including
     10  * without limitation on the rights to use, copy, modify, merge,
     11  * publish, distribute, sublicense, and/or sell copies of the Software,
     12  * and to permit persons to whom the Software is furnished to do so,
     13  * subject to the following conditions:
     14  *
     15  * The above copyright notice and this permission notice (including the
     16  * next paragraph) shall be included in all copies or substantial
     17  * portions of the Software.
     18  *
     19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     22  * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
     23  * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     24  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     26  * DEALINGS IN THE SOFTWARE.
     27  */
     28 
     29 #ifdef HAVE_CONFIG_H
     30 #include "config.h"
     31 #endif
     32 
     33 /*
     34  * Authors:
     35  *   Kevin E. Martin <martin (at) xfree86.org>
     36  *   Rickard E. Faith <faith (at) valinux.com>
     37  *   Alan Hourihane <alanh (at) fairlite.demon.co.uk>
     38  */
     39 
     40 #include <string.h>
     41 #include <stdio.h>
     42 
     43 #include "xf86.h"
     44 				/* Driver data structures */
     45 #include "randrstr.h"
     46 #include "radeon_probe.h"
     47 #include "radeon.h"
     48 #include "radeon_reg.h"
     49 #include "radeon_macros.h"
     50 #include "radeon_version.h"
     51 #include "radeon_atombios.h"
     52 
     53 #include "xf86Modes.h"
     54 				/* DDC support */
     55 #include "xf86DDC.h"
     56 #include <randrstr.h>
     57 
     58 void RADEONSetPitch (ScrnInfoPtr pScrn)
     59 {
     60     int  dummy = pScrn->virtualX;
     61     RADEONInfoPtr info = RADEONPTR(pScrn);
     62     int pitch_mask = 0;
     63     int align_large;
     64 
     65     align_large = info->allowColorTiling || IS_AVIVO_VARIANT;
     66 
     67     /* FIXME: May need to validate line pitch here */
     68     if (info->ChipFamily < CHIP_FAMILY_R600) {
     69 	switch (pScrn->depth / 8) {
     70 	case 1: pitch_mask = align_large ? 256 : 128;
     71 	    break;
     72 	case 2: pitch_mask = align_large ? 128 : 32;
     73 	    break;
     74 	case 3:
     75 	case 4: pitch_mask = align_large ? 64 : 16;
     76 	    break;
     77 	}
     78     } else
     79 	pitch_mask = 256; /* r6xx/r7xx need 256B alignment for accel */
     80 
     81     dummy = RADEON_ALIGN(pScrn->virtualX, pitch_mask);
     82     pScrn->displayWidth = dummy;
     83     info->CurrentLayout.displayWidth = pScrn->displayWidth;
     84 
     85 }
     86 
     87 static DisplayModePtr
     88 RADEONTVModes(xf86OutputPtr output)
     89 {
     90     DisplayModePtr new  = NULL;
     91 
     92     /* just a place holder */
     93     new = xf86CVTMode(800, 600, 60.00, FALSE, FALSE);
     94     xf86SetModeDefaultName(new);
     95     new->type = M_T_DRIVER | M_T_PREFERRED;
     96 
     97     return new;
     98 }
     99 
    100 static DisplayModePtr
    101 RADEONATOMTVModes(xf86OutputPtr output)
    102 {
    103     DisplayModePtr  last       = NULL;
    104     DisplayModePtr  new        = NULL;
    105     DisplayModePtr  first      = NULL;
    106     int i;
    107     /* Add some common sizes */
    108     int widths[5] =  {640, 720, 800, 848, 1024};
    109     int heights[5] = {480, 480, 600, 480,  768};
    110 
    111     for (i = 0; i < 5; i++) {
    112 	new = xf86CVTMode(widths[i], heights[i], 60.0, FALSE, FALSE);
    113 	xf86SetModeDefaultName(new);
    114 
    115 	new->type       = M_T_DRIVER;
    116 
    117 	new->next       = NULL;
    118 	new->prev       = last;
    119 
    120 	if (last) last->next = new;
    121 	last = new;
    122 	if (!first) first = new;
    123     }
    124 
    125     if (last) {
    126 	last->next   = NULL; //first;
    127 	first->prev  = NULL; //last;
    128     }
    129 
    130     return first;
    131 }
    132 
    133 /* This is used only when no mode is specified for FP and no ddc is
    134  * available.  We force it to native mode, if possible.
    135  */
    136 static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
    137 {
    138     ScrnInfoPtr pScrn = output->scrn;
    139     RADEONOutputPrivatePtr radeon_output = output->driver_private;
    140     radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
    141     DisplayModePtr  new   = NULL;
    142     char            stmp[32];
    143 
    144     if (native_mode->PanelXRes != 0 &&
    145 	native_mode->PanelYRes != 0 &&
    146 	native_mode->DotClock != 0) {
    147 
    148 	new             = xnfcalloc(1, sizeof (DisplayModeRec));
    149 	sprintf(stmp, "%dx%d", native_mode->PanelXRes, native_mode->PanelYRes);
    150 	new->name       = xnfalloc(strlen(stmp) + 1);
    151 	/*
    152 	 * XXX - expanded __UNCONST() version, new->name became const in
    153 	 * xorg-server 21.*
    154 	 */
    155 	strcpy((void *)(unsigned long)(const void *)new->name, stmp);
    156 	new->HDisplay   = native_mode->PanelXRes;
    157 	new->VDisplay   = native_mode->PanelYRes;
    158 
    159 	new->HTotal     = new->HDisplay + native_mode->HBlank;
    160 	new->HSyncStart = new->HDisplay + native_mode->HOverPlus;
    161 	new->HSyncEnd   = new->HSyncStart + native_mode->HSyncWidth;
    162 	new->VTotal     = new->VDisplay + native_mode->VBlank;
    163 	new->VSyncStart = new->VDisplay + native_mode->VOverPlus;
    164 	new->VSyncEnd   = new->VSyncStart + native_mode->VSyncWidth;
    165 
    166 	new->Clock      = native_mode->DotClock;
    167 	new->Flags      = native_mode->Flags;
    168 
    169 	if (new) {
    170 	    new->type       = M_T_DRIVER | M_T_PREFERRED;
    171 
    172 	    new->next       = NULL;
    173 	    new->prev       = NULL;
    174 	}
    175 
    176 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Added native panel mode: %dx%d\n",
    177 		   native_mode->PanelXRes, native_mode->PanelYRes);
    178     } else if (native_mode->PanelXRes != 0 &&
    179 	       native_mode->PanelYRes != 0) {
    180 
    181 	new = xf86CVTMode(native_mode->PanelXRes, native_mode->PanelYRes, 60.0, TRUE, FALSE);
    182 
    183 	if (new) {
    184 	    new->type       = M_T_DRIVER | M_T_PREFERRED;
    185 	    xf86SetModeDefaultName(new);
    186 
    187 	    new->next       = NULL;
    188 	    new->prev       = NULL;
    189 	}
    190 
    191 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Added native panel mode using CVT: %dx%d\n",
    192 		   native_mode->PanelXRes, native_mode->PanelYRes);
    193     }
    194 
    195     return new;
    196 }
    197 
    198 #if defined(__powerpc__)
    199 /* Apple eMacs need special modes for the internal CRT, e.g.,
    200  * Modeline "640x480"    62.12   640  680  752  864  480 481 484  521 +HSync +Vsync
    201  * Modeline "800x600"    76.84   800  848  936 1072  600 601 604  640 +HSync +Vsync
    202  * Modeline "1024x768"   99.07  1024 1088 1200 1376  768 769 772  809 +HSync +Vsync
    203  * Modeline "1152x864"  112.36  1152 1224 1352 1552  864 865 868  905 +HSync +Vsync
    204  * Modeline "1280x960"  124.54  1280 1368 1504 1728  960 961 964 1001 +HSync +Vsync
    205  */
    206 static DisplayModePtr RADEONeMacModes(xf86OutputPtr output)
    207 {
    208     ScrnInfoPtr pScrn = output->scrn;
    209     DisplayModePtr last=NULL, new=NULL, first=NULL;
    210     int i, *modep;
    211     static const char *modenames[5] = {
    212 	"640x480", "800x600", "1024x768", "1152x864", "1280x960"
    213     };
    214     static int modes[9*5] = {
    215 	 62120,  640,  680,  752,  864, 480, 481, 484,  521,
    216 	 76840,  800,  848,  936, 1072, 600, 601, 604,  640,
    217 	 99070, 1024, 1088, 1200, 1376, 768, 769, 772,  809,
    218 	112360, 1152, 1224, 1352, 1552, 864, 865, 868,  905,
    219 	124540, 1280, 1368, 1504, 1728, 960, 961, 964, 1001
    220     };
    221     modep = modes;
    222 
    223     for (i=0; i<5; i++) {
    224 	new = xnfcalloc(1, sizeof (DisplayModeRec));
    225 	if (new) {
    226 	    new->name       = xnfalloc(strlen(modenames[i]) + 1);
    227 	    strcpy(new->name, modenames[i]);
    228 	    new->Clock      = *modep++;
    229 
    230 	    new->HDisplay   = *modep++;
    231 	    new->HSyncStart = *modep++;
    232 	    new->HSyncEnd   = *modep++;
    233 	    new->HTotal     = *modep++;
    234 
    235 	    new->VDisplay   = *modep++;
    236 	    new->VSyncStart = *modep++;
    237 	    new->VSyncEnd   = *modep++;
    238 	    new->VTotal     = *modep++;
    239 
    240 	    new->Flags      = 0;
    241 	    new->type       = M_T_DRIVER;
    242 	    if (i==2)
    243 		new->type |= M_T_PREFERRED;
    244 	    new->next       = NULL;
    245 	    new->prev       = last;
    246 	    if (last) last->next = new;
    247 	    last = new;
    248 	    if (!first) first = new;
    249 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Added eMac mode %s\n", modenames[i]);
    250 	}
    251     }
    252 
    253     return first;
    254 }
    255 #endif
    256 
    257 /* this function is basically a hack to add the screen modes */
    258 static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList)
    259 {
    260     ScrnInfoPtr pScrn = output->scrn;
    261     RADEONOutputPrivatePtr radeon_output = output->driver_private;
    262     radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
    263     DisplayModePtr  last       = NULL;
    264     DisplayModePtr  new        = NULL;
    265     DisplayModePtr  first      = NULL;
    266     int             count      = 0;
    267     int             i, width, height;
    268     const char **ppModeName = pScrn->display->modes;
    269 
    270     first = last = *modeList;
    271 
    272     /* We have a flat panel connected to the primary display, and we
    273      * don't have any DDC info.
    274      */
    275     for (i = 0; ppModeName[i] != NULL; i++) {
    276 
    277 	if (sscanf(ppModeName[i], "%dx%d", &width, &height) != 2) continue;
    278 
    279 	if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
    280 	    /* already added the native mode */
    281 	    if (width == native_mode->PanelXRes && height == native_mode->PanelYRes)
    282 		continue;
    283 
    284 	    /* Note: We allow all non-standard modes as long as they do not
    285 	     * exceed the native resolution of the panel.  Since these modes
    286 	     * need the internal RMX unit in the video chips (and there is
    287 	     * only one per card), this will only apply to the primary head.
    288 	     */
    289 	    if (width < 320 || width > native_mode->PanelXRes ||
    290 		height < 200 || height > native_mode->PanelYRes) {
    291 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
    292 			   "Mode %s is out of range.\n", ppModeName[i]);
    293 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
    294 			   "Valid FP modes must be between 320x200-%dx%d\n",
    295 			   native_mode->PanelXRes, native_mode->PanelYRes);
    296 		continue;
    297 	    }
    298 	}
    299 
    300 	new = xf86CVTMode(width, height, 60.0, FALSE, FALSE);
    301 	xf86SetModeDefaultName(new);
    302 
    303 	new->type      |= M_T_USERDEF;
    304 
    305 	new->next       = NULL;
    306 	new->prev       = last;
    307 
    308 	if (last) last->next = new;
    309 	last = new;
    310 	if (!first) first = new;
    311 
    312 	count++;
    313 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    314 		   "Adding Screen mode: %s\n", new->name);
    315     }
    316 
    317 
    318     /* Close the doubly-linked mode list, if we found any usable modes */
    319     if (last) {
    320 	last->next   = NULL; //first;
    321 	first->prev  = NULL; //last;
    322 	*modeList = first;
    323     }
    324 
    325     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    326 	       "Total number of valid Screen mode(s) added: %d\n", count);
    327 
    328 }
    329 
    330 /* BIOS may not have right panel size, we search through all supported
    331  * DDC modes looking for the maximum panel size.
    332  */
    333 static void
    334 RADEONUpdatePanelSize(xf86OutputPtr output)
    335 {
    336     ScrnInfoPtr pScrn = output->scrn;
    337     RADEONInfoPtr  info       = RADEONPTR(pScrn);
    338     RADEONOutputPrivatePtr radeon_output = output->driver_private;
    339     radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
    340     int             j;
    341     xf86MonPtr ddc = output->MonInfo;
    342     DisplayModePtr  p;
    343 
    344     // update output's native mode
    345     if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
    346 	radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
    347 	if (radeon_encoder) {
    348 	    radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv;
    349 	    if (lvds)
    350 		radeon_output->native_mode = lvds->native_mode;
    351 	}
    352     }
    353 
    354     // crtc should handle?
    355     if ((info->UseBiosDividers && native_mode->DotClock != 0) || (ddc == NULL))
    356        return;
    357 
    358     /* Go thru detailed timing table first */
    359     for (j = 0; j < 4; j++) {
    360 	if (ddc->det_mon[j].type == 0) {
    361 	    struct detailed_timings *d_timings =
    362 		&ddc->det_mon[j].section.d_timings;
    363            int match = 0;
    364 
    365            /* If we didn't get a panel clock or guessed one, try to match the
    366             * mode with the panel size. We do that because we _need_ a panel
    367             * clock, or ValidateFPModes will fail, even when UseBiosDividers
    368             * is set.
    369             */
    370            if (native_mode->DotClock == 0 &&
    371                native_mode->PanelXRes == d_timings->h_active &&
    372                native_mode->PanelYRes == d_timings->v_active)
    373                match = 1;
    374 
    375            /* If we don't have a BIOS provided panel data with fixed dividers,
    376             * check for a larger panel size
    377             */
    378 	    if (native_mode->PanelXRes < d_timings->h_active &&
    379 		native_mode->PanelYRes < d_timings->v_active &&
    380 		!info->UseBiosDividers)
    381 		match = 1;
    382 
    383              if (match) {
    384 		native_mode->PanelXRes  = d_timings->h_active;
    385 		native_mode->PanelYRes  = d_timings->v_active;
    386 		native_mode->DotClock   = d_timings->clock / 1000;
    387 		native_mode->HOverPlus  = d_timings->h_sync_off;
    388 		native_mode->HSyncWidth = d_timings->h_sync_width;
    389 		native_mode->HBlank     = d_timings->h_blanking;
    390 		native_mode->VOverPlus  = d_timings->v_sync_off;
    391 		native_mode->VSyncWidth = d_timings->v_sync_width;
    392 		native_mode->VBlank     = d_timings->v_blanking;
    393                 native_mode->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
    394                 switch (d_timings->misc) {
    395                 case 0: native_mode->Flags |= V_NHSYNC | V_NVSYNC; break;
    396                 case 1: native_mode->Flags |= V_PHSYNC | V_NVSYNC; break;
    397                 case 2: native_mode->Flags |= V_NHSYNC | V_PVSYNC; break;
    398                 case 3: native_mode->Flags |= V_PHSYNC | V_PVSYNC; break;
    399                 }
    400                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
    401                            native_mode->PanelXRes, native_mode->PanelYRes);
    402 	    }
    403 	}
    404     }
    405 
    406     if (info->UseBiosDividers && native_mode->DotClock != 0)
    407        return;
    408 
    409     /* Search thru standard VESA modes from EDID */
    410     for (j = 0; j < 8; j++) {
    411 	if ((native_mode->PanelXRes < ddc->timings2[j].hsize) &&
    412 	    (native_mode->PanelYRes < ddc->timings2[j].vsize)) {
    413 	    for (p = pScrn->monitor->Modes; p; p = p->next) {
    414 		if ((ddc->timings2[j].hsize == p->HDisplay) &&
    415 		    (ddc->timings2[j].vsize == p->VDisplay)) {
    416 		    float  refresh =
    417 			(float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
    418 
    419 		    if (fabsf((float)ddc->timings2[j].refresh - refresh) < 1.0) {
    420 			/* Is this good enough? */
    421 			native_mode->PanelXRes  = ddc->timings2[j].hsize;
    422 			native_mode->PanelYRes  = ddc->timings2[j].vsize;
    423 			native_mode->HBlank     = p->HTotal - p->HDisplay;
    424 			native_mode->HOverPlus  = p->HSyncStart - p->HDisplay;
    425 			native_mode->HSyncWidth = p->HSyncEnd - p->HSyncStart;
    426 			native_mode->VBlank     = p->VTotal - p->VDisplay;
    427 			native_mode->VOverPlus  = p->VSyncStart - p->VDisplay;
    428 			native_mode->VSyncWidth = p->VSyncEnd - p->VSyncStart;
    429 			native_mode->DotClock   = p->Clock;
    430                         native_mode->Flags      = p->Flags;
    431                         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n",
    432                                    native_mode->PanelXRes, native_mode->PanelYRes);
    433 		    }
    434 		}
    435 	    }
    436 	}
    437     }
    438 }
    439 
    440 static void
    441 radeon_add_common_modes(xf86OutputPtr output, DisplayModePtr modes)
    442 {
    443     RADEONOutputPrivatePtr radeon_output = output->driver_private;
    444     radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
    445     DisplayModePtr  last       = NULL;
    446     DisplayModePtr  new        = NULL;
    447     DisplayModePtr  first      = NULL;
    448     int i;
    449     /* Add some common sizes */
    450     int widths[15]  = {640, 800, 1024, 1152, 1280, 1280, 1280, 1280, 1280, 1440, 1400, 1680, 1600, 1920, 1920};
    451     int heights[15] = {480, 600,  768,  768,  720,  800,  854,  960, 1024,  900, 1050, 1050, 1200, 1080, 1200};
    452 
    453     for (i = 0; i < 15; i++) {
    454 	if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
    455 	    /* already added the native mode */
    456 	    if (widths[i] == native_mode->PanelXRes && heights[i] == native_mode->PanelYRes)
    457 		continue;
    458 
    459 	    /* Note: We allow all non-standard modes as long as they do not
    460 	     * exceed the native resolution of the panel.  Since these modes
    461 	     * need the internal RMX unit in the video chips (and there is
    462 	     * only one per card), this will only apply to the primary head.
    463 	     */
    464 	    if (widths[i] < 320 || widths[i] > native_mode->PanelXRes ||
    465 		heights[i] < 200 || heights[i] > native_mode->PanelYRes)
    466 		continue;
    467 	}
    468 
    469 	new = xf86CVTMode(widths[i], heights[i], 60.0, FALSE, FALSE);
    470 	xf86SetModeDefaultName(new);
    471 
    472 	new->type       = M_T_DRIVER;
    473 
    474 	new->next       = NULL;
    475 	new->prev       = last;
    476 
    477 	if (last) last->next = new;
    478 	last = new;
    479 	if (!first) first = new;
    480     }
    481 
    482     if (last) {
    483 	last->next   = NULL; //first;
    484 	first->prev  = NULL; //last;
    485     }
    486 
    487     xf86ModesAdd(modes, first);
    488 
    489 }
    490 
    491 DisplayModePtr
    492 RADEONProbeOutputModes(xf86OutputPtr output)
    493 {
    494     RADEONOutputPrivatePtr radeon_output = output->driver_private;
    495     ScrnInfoPtr pScrn = output->scrn;
    496     RADEONInfoPtr info = RADEONPTR(pScrn);
    497     DisplayModePtr	    modes = NULL;
    498     AtomBiosArgRec atomBiosArg;
    499     AtomBiosResult atomBiosResult;
    500 
    501     if (output->status == XF86OutputStatusConnected) {
    502 	if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
    503 	    if (IS_AVIVO_VARIANT)
    504 		modes = RADEONATOMTVModes(output);
    505 	    else
    506 		modes = RADEONTVModes(output);
    507 	} else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) {
    508 	    atomBiosResult = RHDAtomBiosFunc(pScrn, info->atomBIOS,
    509 					     ATOMBIOS_GET_CV_MODES, &atomBiosArg);
    510 	    if (atomBiosResult == ATOM_SUCCESS) {
    511 		modes = atomBiosArg.modes;
    512 	    }
    513 	} else {
    514 	    if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT))
    515 		RADEONUpdatePanelSize(output);
    516 	    if (output->MonInfo)
    517 		modes = xf86OutputGetEDIDModes (output);
    518 #if defined(__powerpc__)
    519 	    if ((info->MacModel == RADEON_MAC_EMAC) &&
    520 		(radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) &&
    521 		(modes == NULL))
    522 		modes = RADEONeMacModes(output);
    523 #endif
    524 	    if (modes == NULL) {
    525 		if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) && info->IsAtomBios) {
    526 		    atomBiosResult = RHDAtomBiosFunc(pScrn,
    527 						     info->atomBIOS,
    528 						     ATOMBIOS_GET_PANEL_EDID, &atomBiosArg);
    529 		    if (atomBiosResult == ATOM_SUCCESS) {
    530 			output->MonInfo = xf86InterpretEDID(pScrn->scrnIndex,
    531 							    atomBiosArg.EDIDBlock);
    532 			modes = xf86OutputGetEDIDModes(output);
    533 		    }
    534 		}
    535 		if (modes == NULL) {
    536 		    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
    537 			modes = RADEONFPNativeMode(output);
    538 		    /* add the screen modes */
    539 		    if (modes == NULL)
    540 			RADEONAddScreenModes(output, &modes);
    541 		}
    542 	    }
    543 	}
    544     }
    545 
    546     if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
    547 	radeon_add_common_modes(output, modes);
    548 
    549     return modes;
    550 }
    551 
    552