Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include "radeonfb.h"
0003 
0004 #include <linux/slab.h>
0005 
0006 #include "../edid.h"
0007 
0008 static const struct fb_var_screeninfo radeonfb_default_var = {
0009     .xres       = 640,
0010     .yres       = 480,
0011     .xres_virtual   = 640,
0012     .yres_virtual   = 480,
0013     .bits_per_pixel = 8,
0014     .red        = { .length = 8 },
0015     .green      = { .length = 8 },
0016     .blue       = { .length = 8 },
0017     .activate   = FB_ACTIVATE_NOW,
0018     .height     = -1,
0019     .width      = -1,
0020     .pixclock   = 39721,
0021     .left_margin    = 40,
0022     .right_margin   = 24,
0023     .upper_margin   = 32,
0024     .lower_margin   = 11,
0025     .hsync_len  = 96,
0026     .vsync_len  = 2,
0027     .vmode      = FB_VMODE_NONINTERLACED
0028 };
0029 
0030 static char *radeon_get_mon_name(int type)
0031 {
0032     char *pret = NULL;
0033 
0034     switch (type) {
0035         case MT_NONE:
0036             pret = "no";
0037             break;
0038         case MT_CRT:
0039             pret = "CRT";
0040             break;
0041         case MT_DFP:
0042             pret = "DFP";
0043             break;
0044         case MT_LCD:
0045             pret = "LCD";
0046             break;
0047         case MT_CTV:
0048             pret = "CTV";
0049             break;
0050         case MT_STV:
0051             pret = "STV";
0052             break;
0053     }
0054 
0055     return pret;
0056 }
0057 
0058 
0059 #if defined(CONFIG_PPC) || defined(CONFIG_SPARC)
0060 /*
0061  * Try to find monitor informations & EDID data out of the Open Firmware
0062  * device-tree. This also contains some "hacks" to work around a few machine
0063  * models with broken OF probing by hard-coding known EDIDs for some Mac
0064  * laptops internal LVDS panel. (XXX: not done yet)
0065  */
0066 static int radeon_parse_montype_prop(struct device_node *dp, u8 **out_EDID,
0067                      int hdno)
0068 {
0069         static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID",
0070                      "EDID1", "EDID2",  NULL };
0071     const u8 *pedid = NULL;
0072     const u8 *pmt = NULL;
0073     u8 *tmp;
0074         int i, mt = MT_NONE;  
0075     
0076     pr_debug("analyzing OF properties...\n");
0077     pmt = of_get_property(dp, "display-type", NULL);
0078     if (!pmt)
0079         return MT_NONE;
0080     pr_debug("display-type: %s\n", pmt);
0081     /* OF says "LCD" for DFP as well, we discriminate from the caller of this
0082      * function
0083      */
0084     if (!strcmp(pmt, "LCD") || !strcmp(pmt, "DFP"))
0085         mt = MT_DFP;
0086     else if (!strcmp(pmt, "CRT"))
0087         mt = MT_CRT;
0088     else {
0089         if (strcmp(pmt, "NONE") != 0)
0090             printk(KERN_WARNING "radeonfb: Unknown OF display-type: %s\n",
0091                    pmt);
0092         return MT_NONE;
0093     }
0094 
0095     for (i = 0; propnames[i] != NULL; ++i) {
0096         pedid = of_get_property(dp, propnames[i], NULL);
0097         if (pedid != NULL)
0098             break;
0099     }
0100     /* We didn't find the EDID in the leaf node, some cards will actually
0101      * put EDID1/EDID2 in the parent, look for these (typically M6 tipb).
0102      * single-head cards have hdno == -1 and skip this step
0103      */
0104     if (pedid == NULL && dp->parent && (hdno != -1))
0105         pedid = of_get_property(dp->parent,
0106                 (hdno == 0) ? "EDID1" : "EDID2", NULL);
0107     if (pedid == NULL && dp->parent && (hdno == 0))
0108         pedid = of_get_property(dp->parent, "EDID", NULL);
0109     if (pedid == NULL)
0110         return mt;
0111 
0112     tmp = kmemdup(pedid, EDID_LENGTH, GFP_KERNEL);
0113     if (!tmp)
0114         return mt;
0115     *out_EDID = tmp;
0116     return mt;
0117 }
0118 
0119 static int radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no,
0120                 u8 **out_EDID)
0121 {
0122         struct device_node *dp;
0123 
0124     pr_debug("radeon_probe_OF_head\n");
0125 
0126         dp = rinfo->of_node;
0127         while (dp == NULL)
0128         return MT_NONE;
0129 
0130     if (rinfo->has_CRTC2) {
0131         const char *pname;
0132         int len, second = 0;
0133 
0134         dp = dp->child;
0135         do {
0136             if (!dp)
0137                 return MT_NONE;
0138             pname = of_get_property(dp, "name", NULL);
0139             if (!pname)
0140                 return MT_NONE;
0141             len = strlen(pname);
0142             pr_debug("head: %s (letter: %c, head_no: %d)\n",
0143                    pname, pname[len-1], head_no);
0144             if (pname[len-1] == 'A' && head_no == 0) {
0145                 int mt = radeon_parse_montype_prop(dp, out_EDID, 0);
0146                 /* Maybe check for LVDS_GEN_CNTL here ? I need to check out
0147                  * what OF does when booting with lid closed
0148                  */
0149                 if (mt == MT_DFP && rinfo->is_mobility)
0150                     mt = MT_LCD;
0151                 return mt;
0152             } else if (pname[len-1] == 'B' && head_no == 1)
0153                 return radeon_parse_montype_prop(dp, out_EDID, 1);
0154             second = 1;
0155             dp = dp->sibling;
0156         } while(!second);
0157     } else {
0158         if (head_no > 0)
0159             return MT_NONE;
0160         return radeon_parse_montype_prop(dp, out_EDID, -1);
0161     }
0162         return MT_NONE;
0163 }
0164 #endif /* CONFIG_PPC || CONFIG_SPARC */
0165 
0166 
0167 static int radeon_get_panel_info_BIOS(struct radeonfb_info *rinfo)
0168 {
0169     unsigned long tmp, tmp0;
0170     char stmp[30];
0171     int i;
0172 
0173     if (!rinfo->bios_seg)
0174         return 0;
0175 
0176     if (!(tmp = BIOS_IN16(rinfo->fp_bios_start + 0x40))) {
0177         printk(KERN_ERR "radeonfb: Failed to detect DFP panel info using BIOS\n");
0178         rinfo->panel_info.pwr_delay = 200;
0179         return 0;
0180     }
0181 
0182     for(i=0; i<24; i++)
0183         stmp[i] = BIOS_IN8(tmp+i+1);
0184     stmp[24] = 0;
0185     printk("radeonfb: panel ID string: %s\n", stmp);
0186     rinfo->panel_info.xres = BIOS_IN16(tmp + 25);
0187     rinfo->panel_info.yres = BIOS_IN16(tmp + 27);
0188     printk("radeonfb: detected LVDS panel size from BIOS: %dx%d\n",
0189         rinfo->panel_info.xres, rinfo->panel_info.yres);
0190 
0191     rinfo->panel_info.pwr_delay = BIOS_IN16(tmp + 44);
0192     pr_debug("BIOS provided panel power delay: %d\n", rinfo->panel_info.pwr_delay);
0193     if (rinfo->panel_info.pwr_delay > 2000 || rinfo->panel_info.pwr_delay <= 0)
0194         rinfo->panel_info.pwr_delay = 2000;
0195 
0196     /*
0197      * Some panels only work properly with some divider combinations
0198      */
0199     rinfo->panel_info.ref_divider = BIOS_IN16(tmp + 46);
0200     rinfo->panel_info.post_divider = BIOS_IN8(tmp + 48);
0201     rinfo->panel_info.fbk_divider = BIOS_IN16(tmp + 49);
0202     if (rinfo->panel_info.ref_divider != 0 &&
0203         rinfo->panel_info.fbk_divider > 3) {
0204         rinfo->panel_info.use_bios_dividers = 1;
0205         printk(KERN_INFO "radeondb: BIOS provided dividers will be used\n");
0206         pr_debug("ref_divider = %x\n", rinfo->panel_info.ref_divider);
0207         pr_debug("post_divider = %x\n", rinfo->panel_info.post_divider);
0208         pr_debug("fbk_divider = %x\n", rinfo->panel_info.fbk_divider);
0209     }
0210     pr_debug("Scanning BIOS table ...\n");
0211     for(i=0; i<32; i++) {
0212         tmp0 = BIOS_IN16(tmp+64+i*2);
0213         if (tmp0 == 0)
0214             break;
0215         pr_debug(" %d x %d\n", BIOS_IN16(tmp0), BIOS_IN16(tmp0+2));
0216         if ((BIOS_IN16(tmp0) == rinfo->panel_info.xres) &&
0217             (BIOS_IN16(tmp0+2) == rinfo->panel_info.yres)) {
0218             rinfo->panel_info.hblank = (BIOS_IN16(tmp0+17) - BIOS_IN16(tmp0+19)) * 8;
0219             rinfo->panel_info.hOver_plus = ((BIOS_IN16(tmp0+21) -
0220                              BIOS_IN16(tmp0+19) -1) * 8) & 0x7fff;
0221             rinfo->panel_info.hSync_width = BIOS_IN8(tmp0+23) * 8;
0222             rinfo->panel_info.vblank = BIOS_IN16(tmp0+24) - BIOS_IN16(tmp0+26);
0223             rinfo->panel_info.vOver_plus = (BIOS_IN16(tmp0+28) & 0x7ff) - BIOS_IN16(tmp0+26);
0224             rinfo->panel_info.vSync_width = (BIOS_IN16(tmp0+28) & 0xf800) >> 11;
0225             rinfo->panel_info.clock = BIOS_IN16(tmp0+9);
0226             /* Assume high active syncs for now until ATI tells me more... maybe we
0227              * can probe register values here ?
0228              */
0229             rinfo->panel_info.hAct_high = 1;
0230             rinfo->panel_info.vAct_high = 1;
0231             /* Mark panel infos valid */
0232             rinfo->panel_info.valid = 1;
0233 
0234             pr_debug("Found panel in BIOS table:\n");
0235             pr_debug("  hblank: %d\n", rinfo->panel_info.hblank);
0236             pr_debug("  hOver_plus: %d\n", rinfo->panel_info.hOver_plus);
0237             pr_debug("  hSync_width: %d\n", rinfo->panel_info.hSync_width);
0238             pr_debug("  vblank: %d\n", rinfo->panel_info.vblank);
0239             pr_debug("  vOver_plus: %d\n", rinfo->panel_info.vOver_plus);
0240             pr_debug("  vSync_width: %d\n", rinfo->panel_info.vSync_width);
0241             pr_debug("  clock: %d\n", rinfo->panel_info.clock);
0242                 
0243             return 1;
0244         }
0245     }
0246     pr_debug("Didn't find panel in BIOS table !\n");
0247 
0248     return 0;
0249 }
0250 
0251 /* Try to extract the connector informations from the BIOS. This
0252  * doesn't quite work yet, but it's output is still useful for
0253  * debugging
0254  */
0255 static void radeon_parse_connector_info(struct radeonfb_info *rinfo)
0256 {
0257     int offset, chips, connectors, tmp, i, conn, type;
0258 
0259     static char* __conn_type_table[16] = {
0260         "NONE", "Proprietary", "CRT", "DVI-I", "DVI-D", "Unknown", "Unknown",
0261         "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown",
0262         "Unknown", "Unknown", "Unknown"
0263     };
0264 
0265     if (!rinfo->bios_seg)
0266         return;
0267 
0268     offset = BIOS_IN16(rinfo->fp_bios_start + 0x50);
0269     if (offset == 0) {
0270         printk(KERN_WARNING "radeonfb: No connector info table detected\n");
0271         return;
0272     }
0273 
0274     /* Don't do much more at this point but displaying the data if
0275      * DEBUG is enabled
0276      */
0277     chips = BIOS_IN8(offset++) >> 4;
0278     pr_debug("%d chips in connector info\n", chips);
0279     for (i = 0; i < chips; i++) {
0280         tmp = BIOS_IN8(offset++);
0281         connectors = tmp & 0x0f;
0282         pr_debug(" - chip %d has %d connectors\n", tmp >> 4, connectors);
0283         for (conn = 0; ; conn++) {
0284             tmp = BIOS_IN16(offset);
0285             if (tmp == 0)
0286                 break;
0287             offset += 2;
0288             type = (tmp >> 12) & 0x0f;
0289             pr_debug("  * connector %d of type %d (%s) : %04x\n",
0290                    conn, type, __conn_type_table[type], tmp);
0291         }
0292     }
0293 }
0294 
0295 
0296 /*
0297  * Probe physical connection of a CRT. This code comes from XFree
0298  * as well and currently is only implemented for the CRT DAC, the
0299  * code for the TVDAC is commented out in XFree as "non working"
0300  */
0301 static int radeon_crt_is_connected(struct radeonfb_info *rinfo, int is_crt_dac)
0302 {
0303     int           connected = 0;
0304 
0305     /* the monitor either wasn't connected or it is a non-DDC CRT.
0306      * try to probe it
0307      */
0308     if (is_crt_dac) {
0309     unsigned long ulOrigVCLK_ECP_CNTL;
0310     unsigned long ulOrigDAC_CNTL;
0311     unsigned long ulOrigDAC_EXT_CNTL;
0312     unsigned long ulOrigCRTC_EXT_CNTL;
0313     unsigned long ulData;
0314     unsigned long ulMask;
0315 
0316     ulOrigVCLK_ECP_CNTL = INPLL(VCLK_ECP_CNTL);
0317 
0318     ulData              = ulOrigVCLK_ECP_CNTL;
0319     ulData             &= ~(PIXCLK_ALWAYS_ONb
0320                 | PIXCLK_DAC_ALWAYS_ONb);
0321     ulMask              = ~(PIXCLK_ALWAYS_ONb
0322                 | PIXCLK_DAC_ALWAYS_ONb);
0323     OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
0324 
0325     ulOrigCRTC_EXT_CNTL = INREG(CRTC_EXT_CNTL);
0326     ulData              = ulOrigCRTC_EXT_CNTL;
0327     ulData             |= CRTC_CRT_ON;
0328     OUTREG(CRTC_EXT_CNTL, ulData);
0329    
0330     ulOrigDAC_EXT_CNTL = INREG(DAC_EXT_CNTL);
0331     ulData             = ulOrigDAC_EXT_CNTL;
0332     ulData            &= ~DAC_FORCE_DATA_MASK;
0333     ulData            |=  (DAC_FORCE_BLANK_OFF_EN
0334                    |DAC_FORCE_DATA_EN
0335                    |DAC_FORCE_DATA_SEL_MASK);
0336     if ((rinfo->family == CHIP_FAMILY_RV250) ||
0337         (rinfo->family == CHIP_FAMILY_RV280))
0338         ulData |= (0x01b6 << DAC_FORCE_DATA_SHIFT);
0339     else
0340         ulData |= (0x01ac << DAC_FORCE_DATA_SHIFT);
0341 
0342     OUTREG(DAC_EXT_CNTL, ulData);
0343 
0344     ulOrigDAC_CNTL     = INREG(DAC_CNTL);
0345     ulData             = ulOrigDAC_CNTL;
0346     ulData            |= DAC_CMP_EN;
0347     ulData            &= ~(DAC_RANGE_CNTL_MASK
0348                    | DAC_PDWN);
0349     ulData            |= 0x2;
0350     OUTREG(DAC_CNTL, ulData);
0351 
0352     mdelay(1);
0353 
0354     ulData     = INREG(DAC_CNTL);
0355     connected =  (DAC_CMP_OUTPUT & ulData) ? 1 : 0;
0356   
0357     ulData    = ulOrigVCLK_ECP_CNTL;
0358     ulMask    = 0xFFFFFFFFL;
0359     OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
0360 
0361     OUTREG(DAC_CNTL,      ulOrigDAC_CNTL     );
0362     OUTREG(DAC_EXT_CNTL,  ulOrigDAC_EXT_CNTL );
0363     OUTREG(CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
0364     }
0365 
0366     return connected ? MT_CRT : MT_NONE;
0367 }
0368 
0369 /*
0370  * Parse the "monitor_layout" string if any. This code is mostly
0371  * copied from XFree's radeon driver
0372  */
0373 static int radeon_parse_monitor_layout(struct radeonfb_info *rinfo,
0374                        const char *monitor_layout)
0375 {
0376     char s1[5], s2[5];
0377     int i = 0, second = 0;
0378     const char *s;
0379 
0380     if (!monitor_layout)
0381         return 0;
0382 
0383     s = monitor_layout;
0384     do {
0385         switch(*s) {
0386         case ',':
0387             s1[i] = '\0';
0388             i = 0;
0389             second = 1;
0390             break;
0391         case ' ':
0392         case '\0':
0393             break;
0394         default:
0395             if (i > 4)
0396                 break;
0397             if (second)
0398                 s2[i] = *s;
0399             else
0400                 s1[i] = *s;
0401             i++;
0402         }
0403 
0404         if (i > 4)
0405             i = 4;
0406 
0407     } while (*s++);
0408     if (second)
0409         s2[i] = 0;
0410     else {
0411         s1[i] = 0;
0412         s2[0] = 0;
0413     }
0414     if (strcmp(s1, "CRT") == 0)
0415         rinfo->mon1_type = MT_CRT;
0416     else if (strcmp(s1, "TMDS") == 0)
0417         rinfo->mon1_type = MT_DFP;
0418     else if (strcmp(s1, "LVDS") == 0)
0419         rinfo->mon1_type = MT_LCD;
0420 
0421     if (strcmp(s2, "CRT") == 0)
0422         rinfo->mon2_type = MT_CRT;
0423     else if (strcmp(s2, "TMDS") == 0)
0424         rinfo->mon2_type = MT_DFP;
0425     else if (strcmp(s2, "LVDS") == 0)
0426         rinfo->mon2_type = MT_LCD;
0427 
0428     return 1;
0429 }
0430 
0431 /*
0432  * Probe display on both primary and secondary card's connector (if any)
0433  * by various available techniques (i2c, OF device tree, BIOS, ...) and
0434  * try to retrieve EDID. The algorithm here comes from XFree's radeon
0435  * driver
0436  */
0437 void radeon_probe_screens(struct radeonfb_info *rinfo,
0438               const char *monitor_layout, int ignore_edid)
0439 {
0440 #ifdef CONFIG_FB_RADEON_I2C
0441     int ddc_crt2_used = 0;  
0442 #endif
0443     int tmp, i;
0444 
0445     radeon_parse_connector_info(rinfo);
0446 
0447     if (radeon_parse_monitor_layout(rinfo, monitor_layout)) {
0448 
0449         /*
0450          * If user specified a monitor_layout option, use it instead
0451          * of auto-detecting. Maybe we should only use this argument
0452          * on the first radeon card probed or provide a way to specify
0453          * a layout for each card ?
0454          */
0455 
0456         pr_debug("Using specified monitor layout: %s", monitor_layout);
0457 #ifdef CONFIG_FB_RADEON_I2C
0458         if (!ignore_edid) {
0459             if (rinfo->mon1_type != MT_NONE)
0460                 if (!radeon_probe_i2c_connector(rinfo, ddc_dvi, &rinfo->mon1_EDID)) {
0461                     radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon1_EDID);
0462                     ddc_crt2_used = 1;
0463                 }
0464             if (rinfo->mon2_type != MT_NONE)
0465                 if (!radeon_probe_i2c_connector(rinfo, ddc_vga, &rinfo->mon2_EDID) &&
0466                     !ddc_crt2_used)
0467                     radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon2_EDID);
0468         }
0469 #endif /* CONFIG_FB_RADEON_I2C */
0470         if (rinfo->mon1_type == MT_NONE) {
0471             if (rinfo->mon2_type != MT_NONE) {
0472                 rinfo->mon1_type = rinfo->mon2_type;
0473                 rinfo->mon1_EDID = rinfo->mon2_EDID;
0474             } else {
0475                 rinfo->mon1_type = MT_CRT;
0476                 printk(KERN_INFO "radeonfb: No valid monitor, assuming CRT on first port\n");
0477             }
0478             rinfo->mon2_type = MT_NONE;
0479             rinfo->mon2_EDID = NULL;
0480         }
0481     } else {
0482         /*
0483          * Auto-detecting display type (well... trying to ...)
0484          */
0485         
0486         pr_debug("Starting monitor auto detection...\n");
0487 
0488 #if defined(DEBUG) && defined(CONFIG_FB_RADEON_I2C)
0489         {
0490             u8 *EDIDs[4] = { NULL, NULL, NULL, NULL };
0491             int i;
0492 
0493             for (i = 0; i < 4; i++)
0494                 radeon_probe_i2c_connector(rinfo, i + 1, &EDIDs[i]);
0495         }
0496 #endif /* DEBUG */
0497         /*
0498          * Old single head cards
0499          */
0500         if (!rinfo->has_CRTC2) {
0501 #if defined(CONFIG_PPC) || defined(CONFIG_SPARC)
0502             if (rinfo->mon1_type == MT_NONE)
0503                 rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0,
0504                                     &rinfo->mon1_EDID);
0505 #endif /* CONFIG_PPC || CONFIG_SPARC */
0506 #ifdef CONFIG_FB_RADEON_I2C
0507             if (rinfo->mon1_type == MT_NONE)
0508                 rinfo->mon1_type =
0509                     radeon_probe_i2c_connector(rinfo, ddc_dvi,
0510                                    &rinfo->mon1_EDID);
0511             if (rinfo->mon1_type == MT_NONE)
0512                 rinfo->mon1_type =
0513                     radeon_probe_i2c_connector(rinfo, ddc_vga,
0514                                    &rinfo->mon1_EDID);
0515             if (rinfo->mon1_type == MT_NONE)
0516                 rinfo->mon1_type =
0517                     radeon_probe_i2c_connector(rinfo, ddc_crt2,
0518                                    &rinfo->mon1_EDID);  
0519 #endif /* CONFIG_FB_RADEON_I2C */
0520             if (rinfo->mon1_type == MT_NONE)
0521                 rinfo->mon1_type = MT_CRT;
0522             goto bail;
0523         }
0524 
0525         /*
0526          * Check for cards with reversed DACs or TMDS controllers using BIOS
0527          */
0528         if (rinfo->bios_seg &&
0529             (tmp = BIOS_IN16(rinfo->fp_bios_start + 0x50))) {
0530             for (i = 1; i < 4; i++) {
0531                 unsigned int tmp0;
0532 
0533                 if (!BIOS_IN8(tmp + i*2) && i > 1)
0534                     break;
0535                 tmp0 = BIOS_IN16(tmp + i*2);
0536                 if ((!(tmp0 & 0x01)) && (((tmp0 >> 8) & 0x0f) == ddc_dvi)) {
0537                     rinfo->reversed_DAC = 1;
0538                     printk(KERN_INFO "radeonfb: Reversed DACs detected\n");
0539                 }
0540                 if ((((tmp0 >> 8) & 0x0f) == ddc_dvi) && ((tmp0 >> 4) & 0x01)) {
0541                     rinfo->reversed_TMDS = 1;
0542                     printk(KERN_INFO "radeonfb: Reversed TMDS detected\n");
0543                 }
0544             }
0545         }
0546 
0547         /*
0548          * Probe primary head (DVI or laptop internal panel)
0549          */
0550 #if defined(CONFIG_PPC) || defined(CONFIG_SPARC)
0551         if (rinfo->mon1_type == MT_NONE)
0552             rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0,
0553                                 &rinfo->mon1_EDID);
0554 #endif /* CONFIG_PPC || CONFIG_SPARC */
0555 #ifdef CONFIG_FB_RADEON_I2C
0556         if (rinfo->mon1_type == MT_NONE)
0557             rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi,
0558                                       &rinfo->mon1_EDID);
0559         if (rinfo->mon1_type == MT_NONE) {
0560             rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_crt2,
0561                                       &rinfo->mon1_EDID);
0562             if (rinfo->mon1_type != MT_NONE)
0563                 ddc_crt2_used = 1;
0564         }
0565 #endif /* CONFIG_FB_RADEON_I2C */
0566         if (rinfo->mon1_type == MT_NONE && rinfo->is_mobility &&
0567             ((rinfo->bios_seg && (INREG(BIOS_4_SCRATCH) & 4))
0568              || (INREG(LVDS_GEN_CNTL) & LVDS_ON))) {
0569             rinfo->mon1_type = MT_LCD;
0570             printk("Non-DDC laptop panel detected\n");
0571         }
0572         if (rinfo->mon1_type == MT_NONE)
0573             rinfo->mon1_type = radeon_crt_is_connected(rinfo, rinfo->reversed_DAC);
0574 
0575         /*
0576          * Probe secondary head (mostly VGA, can be DVI)
0577          */
0578 #if defined(CONFIG_PPC) || defined(CONFIG_SPARC)
0579         if (rinfo->mon2_type == MT_NONE)
0580             rinfo->mon2_type = radeon_probe_OF_head(rinfo, 1,
0581                                 &rinfo->mon2_EDID);
0582 #endif /* CONFIG_PPC || defined(CONFIG_SPARC) */
0583 #ifdef CONFIG_FB_RADEON_I2C
0584         if (rinfo->mon2_type == MT_NONE)
0585             rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_vga,
0586                                       &rinfo->mon2_EDID);
0587         if (rinfo->mon2_type == MT_NONE && !ddc_crt2_used)
0588             rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_crt2,
0589                                       &rinfo->mon2_EDID);
0590 #endif /* CONFIG_FB_RADEON_I2C */
0591         if (rinfo->mon2_type == MT_NONE)
0592             rinfo->mon2_type = radeon_crt_is_connected(rinfo, !rinfo->reversed_DAC);
0593 
0594         /*
0595          * If we only detected port 2, we swap them, if none detected,
0596          * assume CRT (maybe fallback to old BIOS_SCRATCH stuff ? or look
0597          * at FP registers ?)
0598          */
0599         if (rinfo->mon1_type == MT_NONE) {
0600             if (rinfo->mon2_type != MT_NONE) {
0601                 rinfo->mon1_type = rinfo->mon2_type;
0602                 rinfo->mon1_EDID = rinfo->mon2_EDID;
0603             } else
0604                 rinfo->mon1_type = MT_CRT;
0605             rinfo->mon2_type = MT_NONE;
0606             rinfo->mon2_EDID = NULL;
0607         }
0608 
0609         /*
0610          * Deal with reversed TMDS
0611          */
0612         if (rinfo->reversed_TMDS) {
0613             /* Always keep internal TMDS as primary head */
0614             if (rinfo->mon1_type == MT_DFP || rinfo->mon2_type == MT_DFP) {
0615                 int tmp_type = rinfo->mon1_type;
0616                 u8 *tmp_EDID = rinfo->mon1_EDID;
0617                 rinfo->mon1_type = rinfo->mon2_type;
0618                 rinfo->mon1_EDID = rinfo->mon2_EDID;
0619                 rinfo->mon2_type = tmp_type;
0620                 rinfo->mon2_EDID = tmp_EDID;
0621                 if (rinfo->mon1_type == MT_CRT || rinfo->mon2_type == MT_CRT)
0622                     rinfo->reversed_DAC ^= 1;
0623             }
0624         }
0625     }
0626     if (ignore_edid) {
0627         kfree(rinfo->mon1_EDID);
0628         rinfo->mon1_EDID = NULL;
0629         kfree(rinfo->mon2_EDID);
0630         rinfo->mon2_EDID = NULL;
0631     }
0632 
0633  bail:
0634     printk(KERN_INFO "radeonfb: Monitor 1 type %s found\n",
0635            radeon_get_mon_name(rinfo->mon1_type));
0636     if (rinfo->mon1_EDID)
0637         printk(KERN_INFO "radeonfb: EDID probed\n");
0638     if (!rinfo->has_CRTC2)
0639         return;
0640     printk(KERN_INFO "radeonfb: Monitor 2 type %s found\n",
0641            radeon_get_mon_name(rinfo->mon2_type));
0642     if (rinfo->mon2_EDID)
0643         printk(KERN_INFO "radeonfb: EDID probed\n");
0644 }
0645 
0646 
0647 /*
0648  * This function applies any arch/model/machine specific fixups
0649  * to the panel info. It may eventually alter EDID block as
0650  * well or whatever is specific to a given model and not probed
0651  * properly by the default code
0652  */
0653 static void radeon_fixup_panel_info(struct radeonfb_info *rinfo)
0654 {
0655 #ifdef CONFIG_PPC
0656     /*
0657      * LCD Flat panels should use fixed dividers, we enfore that on
0658      * PPC only for now...
0659      */
0660     if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type == MT_LCD
0661         && rinfo->is_mobility) {
0662         int ppll_div_sel;
0663         u32 ppll_divn;
0664         ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3;
0665         radeon_pll_errata_after_index(rinfo);
0666         ppll_divn = INPLL(PPLL_DIV_0 + ppll_div_sel);
0667         rinfo->panel_info.ref_divider = rinfo->pll.ref_div;
0668         rinfo->panel_info.fbk_divider = ppll_divn & 0x7ff;
0669         rinfo->panel_info.post_divider = (ppll_divn >> 16) & 0x7;
0670         rinfo->panel_info.use_bios_dividers = 1;
0671 
0672         printk(KERN_DEBUG "radeonfb: Using Firmware dividers 0x%08x "
0673                "from PPLL %d\n",
0674                rinfo->panel_info.fbk_divider |
0675                (rinfo->panel_info.post_divider << 16),
0676                ppll_div_sel);
0677     }
0678 #endif /* CONFIG_PPC */
0679 }
0680 
0681 
0682 /*
0683  * Fill up panel infos from a mode definition, either returned by the EDID
0684  * or from the default mode when we can't do any better
0685  */
0686 static void radeon_var_to_panel_info(struct radeonfb_info *rinfo, struct fb_var_screeninfo *var)
0687 {
0688     rinfo->panel_info.xres = var->xres;
0689     rinfo->panel_info.yres = var->yres;
0690     rinfo->panel_info.clock = 100000000 / var->pixclock;
0691     rinfo->panel_info.hOver_plus = var->right_margin;
0692     rinfo->panel_info.hSync_width = var->hsync_len;
0693         rinfo->panel_info.hblank = var->left_margin +
0694         (var->right_margin + var->hsync_len);
0695     rinfo->panel_info.vOver_plus = var->lower_margin;
0696     rinfo->panel_info.vSync_width = var->vsync_len;
0697         rinfo->panel_info.vblank = var->upper_margin +
0698         (var->lower_margin + var->vsync_len);
0699     rinfo->panel_info.hAct_high =
0700         (var->sync & FB_SYNC_HOR_HIGH_ACT) != 0;
0701     rinfo->panel_info.vAct_high =
0702         (var->sync & FB_SYNC_VERT_HIGH_ACT) != 0;
0703     rinfo->panel_info.valid = 1;
0704     /* We use a default of 200ms for the panel power delay, 
0705      * I need to have a real schedule() instead of mdelay's in the panel code.
0706      * we might be possible to figure out a better power delay either from
0707      * MacOS OF tree or from the EDID block (proprietary extensions ?)
0708      */
0709     rinfo->panel_info.pwr_delay = 200;
0710 }
0711 
0712 static void radeon_videomode_to_var(struct fb_var_screeninfo *var,
0713                     const struct fb_videomode *mode)
0714 {
0715     var->xres = mode->xres;
0716     var->yres = mode->yres;
0717     var->xres_virtual = mode->xres;
0718     var->yres_virtual = mode->yres;
0719     var->xoffset = 0;
0720     var->yoffset = 0;
0721     var->pixclock = mode->pixclock;
0722     var->left_margin = mode->left_margin;
0723     var->right_margin = mode->right_margin;
0724     var->upper_margin = mode->upper_margin;
0725     var->lower_margin = mode->lower_margin;
0726     var->hsync_len = mode->hsync_len;
0727     var->vsync_len = mode->vsync_len;
0728     var->sync = mode->sync;
0729     var->vmode = mode->vmode;
0730 }
0731 
0732 #ifdef CONFIG_PPC_PSERIES
0733 static int is_powerblade(const char *model)
0734 {
0735     struct device_node *root;
0736     const char* cp;
0737     int len, l, rc = 0;
0738 
0739     root = of_find_node_by_path("/");
0740     if (root && model) {
0741         l = strlen(model);
0742         cp = of_get_property(root, "model", &len);
0743         if (cp)
0744             rc = memcmp(model, cp, min(len, l)) == 0;
0745         of_node_put(root);
0746     }
0747     return rc;
0748 }
0749 #endif
0750 
0751 /*
0752  * Build the modedb for head 1 (head 2 will come later), check panel infos
0753  * from either BIOS or EDID, and pick up the default mode
0754  */
0755 void radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_option)
0756 {
0757     struct fb_info * info = rinfo->info;
0758     int has_default_mode = 0;
0759 
0760     /*
0761      * Fill default var first
0762      */
0763     info->var = radeonfb_default_var;
0764     INIT_LIST_HEAD(&info->modelist);
0765 
0766     /*
0767      * First check out what BIOS has to say
0768      */
0769     if (rinfo->mon1_type == MT_LCD)
0770         radeon_get_panel_info_BIOS(rinfo);
0771 
0772     /*
0773      * Parse EDID detailed timings and deduce panel infos if any. Right now
0774      * we only deal with first entry returned by parse_EDID, we may do better
0775      * some day...
0776      */
0777     if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type != MT_CRT
0778         && rinfo->mon1_EDID) {
0779         struct fb_var_screeninfo var;
0780         pr_debug("Parsing EDID data for panel info\n");
0781         if (fb_parse_edid(rinfo->mon1_EDID, &var) == 0) {
0782             if (var.xres >= rinfo->panel_info.xres &&
0783                 var.yres >= rinfo->panel_info.yres)
0784                 radeon_var_to_panel_info(rinfo, &var);
0785         }
0786     }
0787 
0788     /*
0789      * Do any additional platform/arch fixups to the panel infos
0790      */
0791     radeon_fixup_panel_info(rinfo);
0792 
0793     /*
0794      * If we have some valid panel infos, we setup the default mode based on
0795      * those
0796      */
0797     if (rinfo->mon1_type != MT_CRT && rinfo->panel_info.valid) {
0798         struct fb_var_screeninfo *var = &info->var;
0799 
0800         pr_debug("Setting up default mode based on panel info\n");
0801         var->xres = rinfo->panel_info.xres;
0802         var->yres = rinfo->panel_info.yres;
0803         var->xres_virtual = rinfo->panel_info.xres;
0804         var->yres_virtual = rinfo->panel_info.yres;
0805         var->xoffset = var->yoffset = 0;
0806         var->bits_per_pixel = 8;
0807         var->pixclock = 100000000 / rinfo->panel_info.clock;
0808         var->left_margin = (rinfo->panel_info.hblank - rinfo->panel_info.hOver_plus
0809                     - rinfo->panel_info.hSync_width);
0810         var->right_margin = rinfo->panel_info.hOver_plus;
0811         var->upper_margin = (rinfo->panel_info.vblank - rinfo->panel_info.vOver_plus
0812                      - rinfo->panel_info.vSync_width);
0813         var->lower_margin = rinfo->panel_info.vOver_plus;
0814         var->hsync_len = rinfo->panel_info.hSync_width;
0815         var->vsync_len = rinfo->panel_info.vSync_width;
0816         var->sync = 0;
0817         if (rinfo->panel_info.hAct_high)
0818             var->sync |= FB_SYNC_HOR_HIGH_ACT;
0819         if (rinfo->panel_info.vAct_high)
0820             var->sync |= FB_SYNC_VERT_HIGH_ACT;
0821         var->vmode = 0;
0822         has_default_mode = 1;
0823     }
0824 
0825     /*
0826      * Now build modedb from EDID
0827      */
0828     if (rinfo->mon1_EDID) {
0829         fb_edid_to_monspecs(rinfo->mon1_EDID, &info->monspecs);
0830         fb_videomode_to_modelist(info->monspecs.modedb,
0831                      info->monspecs.modedb_len,
0832                      &info->modelist);
0833         rinfo->mon1_modedb = info->monspecs.modedb;
0834         rinfo->mon1_dbsize = info->monspecs.modedb_len;
0835     }
0836 
0837     
0838     /*
0839      * Finally, if we don't have panel infos we need to figure some (or
0840      * we try to read it from card), we try to pick a default mode
0841      * and create some panel infos. Whatever...
0842      */
0843     if (rinfo->mon1_type != MT_CRT && !rinfo->panel_info.valid) {
0844         struct fb_videomode *modedb;
0845         int         dbsize;
0846         char            modename[32];
0847 
0848         pr_debug("Guessing panel info...\n");
0849         if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) {
0850             u32 tmp = INREG(FP_HORZ_STRETCH) & HORZ_PANEL_SIZE;
0851             rinfo->panel_info.xres = ((tmp >> HORZ_PANEL_SHIFT) + 1) * 8;
0852             tmp = INREG(FP_VERT_STRETCH) & VERT_PANEL_SIZE;
0853             rinfo->panel_info.yres = (tmp >> VERT_PANEL_SHIFT) + 1;
0854         }
0855         if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) {
0856             printk(KERN_WARNING "radeonfb: Can't find panel size, going back to CRT\n");
0857             rinfo->mon1_type = MT_CRT;
0858             goto pickup_default;
0859         }
0860         printk(KERN_WARNING "radeonfb: Assuming panel size %dx%d\n",
0861                rinfo->panel_info.xres, rinfo->panel_info.yres);
0862         modedb = rinfo->mon1_modedb;
0863         dbsize = rinfo->mon1_dbsize;
0864         snprintf(modename, 31, "%dx%d", rinfo->panel_info.xres, rinfo->panel_info.yres);
0865         if (fb_find_mode(&info->var, info, modename,
0866                  modedb, dbsize, NULL, 8) == 0) {
0867             printk(KERN_WARNING "radeonfb: Can't find mode for panel size, going back to CRT\n");
0868             rinfo->mon1_type = MT_CRT;
0869             goto pickup_default;
0870         }
0871         has_default_mode = 1;
0872         radeon_var_to_panel_info(rinfo, &info->var);
0873     }
0874 
0875  pickup_default:
0876     /*
0877      * Apply passed-in mode option if any
0878      */
0879     if (mode_option) {
0880         if (fb_find_mode(&info->var, info, mode_option,
0881                  info->monspecs.modedb,
0882                  info->monspecs.modedb_len, NULL, 8) != 0)
0883             has_default_mode = 1;
0884     }
0885 
0886 #ifdef CONFIG_PPC_PSERIES
0887     if (!has_default_mode && (
0888         is_powerblade("IBM,8842") || /* JS20 */
0889         is_powerblade("IBM,8844") || /* JS21 */
0890         is_powerblade("IBM,7998") || /* JS12/JS21/JS22 */
0891         is_powerblade("IBM,0792") || /* QS21 */
0892         is_powerblade("IBM,0793")    /* QS22 */
0893         )) {
0894         printk("Falling back to 800x600 on JSxx hardware\n");
0895         if (fb_find_mode(&info->var, info, "800x600@60",
0896                  info->monspecs.modedb,
0897                  info->monspecs.modedb_len, NULL, 8) != 0)
0898             has_default_mode = 1;
0899     }
0900 #endif
0901 
0902     /*
0903      * Still no mode, let's pick up a default from the db
0904      */
0905     if (!has_default_mode && info->monspecs.modedb != NULL) {
0906         struct fb_monspecs *specs = &info->monspecs;
0907         struct fb_videomode *modedb = NULL;
0908 
0909         /* get preferred timing */
0910         if (specs->misc & FB_MISC_1ST_DETAIL) {
0911             int i;
0912 
0913             for (i = 0; i < specs->modedb_len; i++) {
0914                 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
0915                     modedb = &specs->modedb[i];
0916                     break;
0917                 }
0918             }
0919         } else {
0920             /* otherwise, get first mode in database */
0921             modedb = &specs->modedb[0];
0922         }
0923         if (modedb != NULL) {
0924             info->var.bits_per_pixel = 8;
0925             radeon_videomode_to_var(&info->var, modedb);
0926             has_default_mode = 1;
0927         }
0928     }
0929     if (1) {
0930         struct fb_videomode mode;
0931         /* Make sure that whatever mode got selected is actually in the
0932          * modelist or the kernel may die
0933          */
0934         fb_var_to_videomode(&mode, &info->var);
0935         fb_add_videomode(&mode, &info->modelist);
0936     }
0937 }
0938 
0939 /*
0940  * The code below is used to pick up a mode in check_var and
0941  * set_var. It should be made generic
0942  */
0943 
0944 /*
0945  * This is used when looking for modes. We assign a "distance" value
0946  * to a mode in the modedb depending how "close" it is from what we
0947  * are looking for.
0948  * Currently, we don't compare that much, we could do better but
0949  * the current fbcon doesn't quite mind ;)
0950  */
0951 static int radeon_compare_modes(const struct fb_var_screeninfo *var,
0952                 const struct fb_videomode *mode)
0953 {
0954     int distance = 0;
0955 
0956     distance = mode->yres - var->yres;
0957     distance += (mode->xres - var->xres)/2;
0958     return distance;
0959 }
0960 
0961 /*
0962  * This function is called by check_var, it gets the passed in mode parameter, and
0963  * outputs a valid mode matching the passed-in one as closely as possible.
0964  * We need something better ultimately. Things like fbcon basically pass us out
0965  * current mode with xres/yres hacked, while things like XFree will actually
0966  * produce a full timing that we should respect as much as possible.
0967  *
0968  * This is why I added the FB_ACTIVATE_FIND that is used by fbcon. Without this,
0969  * we do a simple spec match, that's all. With it, we actually look for a mode in
0970  * either our monitor modedb or the vesa one if none
0971  *
0972  */
0973 int  radeon_match_mode(struct radeonfb_info *rinfo,
0974                struct fb_var_screeninfo *dest,
0975                const struct fb_var_screeninfo *src)
0976 {
0977     const struct fb_videomode   *db = vesa_modes;
0978     int             i, dbsize = 34;
0979     int             has_rmx, native_db = 0;
0980     int             distance = INT_MAX;
0981     const struct fb_videomode   *candidate = NULL;
0982 
0983     /* Start with a copy of the requested mode */
0984     memcpy(dest, src, sizeof(struct fb_var_screeninfo));
0985 
0986     /* Check if we have a modedb built from EDID */
0987     if (rinfo->mon1_modedb) {
0988         db = rinfo->mon1_modedb;
0989         dbsize = rinfo->mon1_dbsize;
0990         native_db = 1;
0991     }
0992 
0993     /* Check if we have a scaler allowing any fancy mode */
0994     has_rmx = rinfo->mon1_type == MT_LCD || rinfo->mon1_type == MT_DFP;
0995 
0996     /* If we have a scaler and are passed FB_ACTIVATE_TEST or
0997      * FB_ACTIVATE_NOW, just do basic checking and return if the
0998      * mode match
0999      */
1000     if ((src->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST ||
1001         (src->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
1002         /* We don't have an RMX, validate timings. If we don't have
1003          * monspecs, we should be paranoid and not let use go above
1004          * 640x480-60, but I assume userland knows what it's doing here
1005          * (though I may be proven wrong...)
1006          */
1007         if (has_rmx == 0 && rinfo->mon1_modedb)
1008             if (fb_validate_mode((struct fb_var_screeninfo *)src, rinfo->info))
1009                 return -EINVAL;
1010         return 0;
1011     }
1012 
1013     /* Now look for a mode in the database */
1014     while (db) {
1015         for (i = 0; i < dbsize; i++) {
1016             int d;
1017 
1018             if (db[i].yres < src->yres)
1019                 continue;   
1020             if (db[i].xres < src->xres)
1021                 continue;
1022             d = radeon_compare_modes(src, &db[i]);
1023             /* If the new mode is at least as good as the previous one,
1024              * then it's our new candidate
1025              */
1026             if (d < distance) {
1027                 candidate = &db[i];
1028                 distance = d;
1029             }
1030         }
1031         db = NULL;
1032         /* If we have a scaler, we allow any mode from the database */
1033         if (native_db && has_rmx) {
1034             db = vesa_modes;
1035             dbsize = 34;
1036             native_db = 0;
1037         }
1038     }
1039 
1040     /* If we have found a match, return it */
1041     if (candidate != NULL) {
1042         radeon_videomode_to_var(dest, candidate);
1043         return 0;
1044     }
1045 
1046     /* If we haven't and don't have a scaler, fail */
1047     if (!has_rmx)
1048         return -EINVAL;
1049 
1050     return 0;
1051 }