CTC++ Coverage Report - Execution Profile    #810/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/video/aty/radeon_monitor.c
Instrumentation mode: function-decision-multicondition
TER: 31 % (117/375)

Start/ End/    
True False - Line Source

  1 #include "radeonfb.h"
  2 #include "../edid.h"
  3 
  4 static struct fb_var_screeninfo radeonfb_default_var = {
  5    .xres      = 640,
  6    .yres      = 480,
  7    .xres_virtual   = 640,
  8    .yres_virtual   = 480,
  9    .bits_per_pixel = 8,
  10    .red      = { .length = 8 },
  11    .green      = { .length = 8 },
  12    .blue      = { .length = 8 },
  13    .activate   = FB_ACTIVATE_NOW,
  14    .height      = -1,
  15    .width      = -1,
  16    .pixclock   = 39721,
  17    .left_margin   = 40,
  18    .right_margin   = 24,
  19    .upper_margin   = 32,
  20    .lower_margin   = 11,
  21    .hsync_len   = 96,
  22    .vsync_len   = 2,
  23    .vmode      = FB_VMODE_NONINTERLACED
  24 };
  25 
 
12   26 static char *radeon_get_mon_name(int type)
  27 {
  28    char *pret = NULL;
  29 
    30    switch (type) {
   31       case MT_NONE:
  32          pret = "no";
   33          break;
 - 34       case MT_CRT:
  35          pret = "CRT";
 - 36          break;
 - 37       case MT_DFP:
  38          pret = "DFP";
 - 39          break;
   40       case MT_LCD:
  41          pret = "LCD";
   42          break;
 - 43       case MT_CTV:
  44          pret = "CTV";
 - 45          break;
 - 46       case MT_STV:
  47          pret = "STV";
 - 48          break;
  49    }
  50 
12    51    return pret;
  52 }
  53 
  54 
  55 #ifdef CONFIG_PPC_OF
  56 /*
  57  * Try to find monitor informations & EDID data out of the Open Firmware
  58  * device-tree. This also contains some "hacks" to work around a few machine
  59  * models with broken OF probing by hard-coding known EDIDs for some Mac
  60  * laptops internal LVDS panel. (XXX: not done yet)
  61  */
  62 static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_EDID,
  63                       int hdno)
  64 {
  65         static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID",
  66                  "EDID1", "EDID2",  NULL };
  67    u8 *pedid = NULL;
  68    u8 *pmt = NULL;
  69    u8 *tmp;
  70         int i, mt = MT_NONE;  
  71    
  72    RTRACE("analyzing OF properties...\n");
  73    pmt = (u8 *)get_property(dp, "display-type", NULL);
  74    if (!pmt)
  75       return MT_NONE;
  76    RTRACE("display-type: %s\n", pmt);
  77    /* OF says "LCD" for DFP as well, we discriminate from the caller of this
  78     * function
  79     */
  80    if (!strcmp(pmt, "LCD") || !strcmp(pmt, "DFP"))
  81       mt = MT_DFP;
  82    else if (!strcmp(pmt, "CRT"))
  83       mt = MT_CRT;
  84    else {
  85       if (strcmp(pmt, "NONE") != 0)
  86          printk(KERN_WARNING "radeonfb: Unknown OF display-type: %s\n",
  87                 pmt);
  88       return MT_NONE;
  89    }
  90 
  91    for (i = 0; propnames[i] != NULL; ++i) {
  92       pedid = (u8 *)get_property(dp, propnames[i], NULL);
  93       if (pedid != NULL)
  94          break;
  95    }
  96    /* We didn't find the EDID in the leaf node, some cards will actually
  97     * put EDID1/EDID2 in the parent, look for these (typically M6 tipb).
  98     * single-head cards have hdno == -1 and skip this step
  99     */
  100    if (pedid == NULL && dp->parent && (hdno != -1))
  101       pedid = get_property(dp->parent, (hdno == 0) ? "EDID1" : "EDID2", NULL);
  102    if (pedid == NULL && dp->parent && (hdno == 0))
  103       pedid = get_property(dp->parent, "EDID", NULL);
  104    if (pedid == NULL)
  105       return mt;
  106 
  107    tmp = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL);
  108    if (!tmp)
  109       return mt;
  110    memcpy(tmp, pedid, EDID_LENGTH);
  111    *out_EDID = tmp;
  112    return mt;
  113 }
  114 
  115 static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no,
  116                  u8 **out_EDID)
  117 {
  118         struct device_node *dp;
  119 
  120    RTRACE("radeon_probe_OF_head\n");
  121 
  122         dp = rinfo->of_node;
  123         while (dp == NULL)
  124       return MT_NONE;
  125 
  126    if (rinfo->has_CRTC2) {
  127       char *pname;
  128       int len, second = 0;
  129 
  130       dp = dp->child;
  131       do {
  132          if (!dp)
  133             return MT_NONE;
  134          pname = (char *)get_property(dp, "name", NULL);
  135          if (!pname)
  136             return MT_NONE;
  137          len = strlen(pname);
  138          RTRACE("head: %s (letter: %c, head_no: %d)\n",
  139                 pname, pname[len-1], head_no);
  140          if (pname[len-1] == 'A' && head_no == 0) {
  141             int mt = radeon_parse_montype_prop(dp, out_EDID, 0);
  142             /* Maybe check for LVDS_GEN_CNTL here ? I need to check out
  143              * what OF does when booting with lid closed
  144              */
  145             if (mt == MT_DFP && rinfo->is_mobility)
  146                mt = MT_LCD;
  147             return mt;
  148          } else if (pname[len-1] == 'B' && head_no == 1)
  149             return radeon_parse_montype_prop(dp, out_EDID, 1);
  150          second = 1;
  151          dp = dp->sibling;
  152       } while(!second);
  153    } else {
  154       if (head_no > 0)
  155          return MT_NONE;
  156       return radeon_parse_montype_prop(dp, out_EDID, -1);
  157    }
  158         return MT_NONE;
  159 }
  160 #endif /* CONFIG_PPC_OF */
  161 
  162 
 
  163 static int __devinit radeon_get_panel_info_BIOS(struct radeonfb_info *rinfo)
  164 {
  165    unsigned long tmp, tmp0;
  166    char stmp[30];
  167    int i;
  168 
- 169    if (!rinfo->bios_seg)
 - 170       return 0;
  171 
- 172    if (!(tmp = BIOS_IN16(rinfo->fp_bios_start + 0x40))) {
  173       printk(KERN_ERR "radeonfb: Failed to detect DFP panel info using BIOS\n");
  174       rinfo->panel_info.pwr_delay = 200;
 - 175       return 0;
  176    }
  177 
144   178    for(i=0; i<24; i++)
  179       stmp[i] = BIOS_IN8(tmp+i+1);
  180    stmp[24] = 0;
  181    printk("radeonfb: panel ID string: %s\n", stmp);
  182    rinfo->panel_info.xres = BIOS_IN16(tmp + 25);
  183    rinfo->panel_info.yres = BIOS_IN16(tmp + 27);
  184    printk("radeonfb: detected LVDS panel size from BIOS: %dx%d\n",
  185       rinfo->panel_info.xres, rinfo->panel_info.yres);
  186 
  187    rinfo->panel_info.pwr_delay = BIOS_IN16(tmp + 44);
- 188    RTRACE("BIOS provided panel power delay: %d\n", rinfo->panel_info.pwr_delay);
- 189    if (rinfo->panel_info.pwr_delay > 2000 || rinfo->panel_info.pwr_delay <= 0)
 - 189   T || _
 - 189   F || T
   189   F || F
  190       rinfo->panel_info.pwr_delay = 2000;
  191 
  192    /*
  193     * Some panels only work properly with some divider combinations
  194     */
  195    rinfo->panel_info.ref_divider = BIOS_IN16(tmp + 46);
  196    rinfo->panel_info.post_divider = BIOS_IN8(tmp + 48);
  197    rinfo->panel_info.fbk_divider = BIOS_IN16(tmp + 49);
  198    if (rinfo->panel_info.ref_divider != 0 &&
- 199        rinfo->panel_info.fbk_divider > 3) {
   199   T && T
 - 199   T && F
 - 199   F && _
  200       rinfo->panel_info.use_bios_dividers = 1;
  201       printk(KERN_INFO "radeondb: BIOS provided dividers will be used\n");
- 202       RTRACE("ref_divider = %x\n", rinfo->panel_info.ref_divider);
- 203       RTRACE("post_divider = %x\n", rinfo->panel_info.post_divider);
- 204       RTRACE("fbk_divider = %x\n", rinfo->panel_info.fbk_divider);
  205    }
- 206    RTRACE("Scanning BIOS table ...\n");
102 - 207    for(i=0; i<32; i++) {
  208       tmp0 = BIOS_IN16(tmp+64+i*2);
102 - 209       if (tmp0 == 0)
 - 210          break;
102 - 211       RTRACE(" %d x %d\n", BIOS_IN16(tmp0), BIOS_IN16(tmp0+2));
  212       if ((BIOS_IN16(tmp0) == rinfo->panel_info.xres) &&
96   213           (BIOS_IN16(tmp0+2) == rinfo->panel_info.yres)) {
   213     (T) && (T)
 - 213     (T) && (F)
 96   213     (F) && (_)
  214          rinfo->panel_info.hblank = (BIOS_IN16(tmp0+17) - BIOS_IN16(tmp0+19)) * 8;
  215          rinfo->panel_info.hOver_plus = ((BIOS_IN16(tmp0+21) -
  216                       BIOS_IN16(tmp0+19) -1) * 8) & 0x7fff;
  217          rinfo->panel_info.hSync_width = BIOS_IN8(tmp0+23) * 8;
  218          rinfo->panel_info.vblank = BIOS_IN16(tmp0+24) - BIOS_IN16(tmp0+26);
  219          rinfo->panel_info.vOver_plus = (BIOS_IN16(tmp0+28) & 0x7ff) - BIOS_IN16(tmp0+26);
  220          rinfo->panel_info.vSync_width = (BIOS_IN16(tmp0+28) & 0xf800) >> 11;
  221          rinfo->panel_info.clock = BIOS_IN16(tmp0+9);
  222          /* Assume high active syncs for now until ATI tells me more... maybe we
  223           * can probe register values here ?
  224           */
  225          rinfo->panel_info.hAct_high = 1;
  226          rinfo->panel_info.vAct_high = 1;
  227          /* Mark panel infos valid */
  228          rinfo->panel_info.valid = 1;
  229 
- 230          RTRACE("Found panel in BIOS table:\n");
- 231          RTRACE("  hblank: %d\n", rinfo->panel_info.hblank);
- 232          RTRACE("  hOver_plus: %d\n", rinfo->panel_info.hOver_plus);
- 233          RTRACE("  hSync_width: %d\n", rinfo->panel_info.hSync_width);
- 234          RTRACE("  vblank: %d\n", rinfo->panel_info.vblank);
- 235          RTRACE("  vOver_plus: %d\n", rinfo->panel_info.vOver_plus);
- 236          RTRACE("  vSync_width: %d\n", rinfo->panel_info.vSync_width);
- 237          RTRACE("  clock: %d\n", rinfo->panel_info.clock);
  238             
   239          return 1;
  240       }
  241    }
- 242    RTRACE("Didn't find panel in BIOS table !\n");
  243 
 - 244    return 0;
  245 }
  246 
  247 /* Try to extract the connector informations from the BIOS. This
  248  * doesn't quite work yet, but it's output is still useful for
  249  * debugging
  250  */
 
  251 static void __devinit radeon_parse_connector_info(struct radeonfb_info *rinfo)
  252 {
  253    int offset, chips, connectors, tmp, i, conn, type;
  254 
  255    static char* __conn_type_table[16] = {
  256       "NONE", "Proprietary", "CRT", "DVI-I", "DVI-D", "Unknown", "Unknown",
  257       "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown",
  258       "Unknown", "Unknown", "Unknown"
  259    };
  260 
- 261    if (!rinfo->bios_seg)
 - 262       return;
  263 
  264    offset = BIOS_IN16(rinfo->fp_bios_start + 0x50);
- 265    if (offset == 0) {
  266       printk(KERN_WARNING "radeonfb: No connector info table detected\n");
 - 267       return;
  268    }
  269 
  270    /* Don't do much more at this point but displaying the data if
  271     * DEBUG is enabled
  272     */
  273    chips = BIOS_IN8(offset++) >> 4;
- 274    RTRACE("%d chips in connector info\n", chips);
  275    for (i = 0; i < chips; i++) {
  276       tmp = BIOS_IN8(offset++);
  277       connectors = tmp & 0x0f;
- 278       RTRACE(" - chip %d has %d connectors\n", tmp >> 4, connectors);
12 - 279       for (conn = 0; ; conn++) {
  280          tmp = BIOS_IN16(offset);
  281          if (tmp == 0)
   282             break;
  283          offset += 2;
  284          type = (tmp >> 12) & 0x0f;
- 285          RTRACE("  * connector %d of type %d (%s) : %04x\n",
  286                 conn, type, __conn_type_table[type], tmp);
  287       }
  288    }
  289 }
  290 
  291 
  292 /*
  293  * Probe physical connection of a CRT. This code comes from XFree
  294  * as well and currently is only implemented for the CRT DAC, the
  295  * code for the TVDAC is commented out in XFree as "non working"
  296  */
 
  297 static int __devinit radeon_crt_is_connected(struct radeonfb_info *rinfo, int is_crt_dac)
  298 {
  299     int             connected = 0;
  300 
  301     /* the monitor either wasn't connected or it is a non-DDC CRT.
  302      * try to probe it
  303      */
- 304     if (is_crt_dac) {
  305    unsigned long ulOrigVCLK_ECP_CNTL;
  306    unsigned long ulOrigDAC_CNTL;
  307    unsigned long ulOrigDAC_EXT_CNTL;
  308    unsigned long ulOrigCRTC_EXT_CNTL;
  309    unsigned long ulData;
  310    unsigned long ulMask;
  311 
  312    ulOrigVCLK_ECP_CNTL = INPLL(VCLK_ECP_CNTL);
  313 
  314    ulData              = ulOrigVCLK_ECP_CNTL;
  315    ulData             &= ~(PIXCLK_ALWAYS_ONb
  316             | PIXCLK_DAC_ALWAYS_ONb);
  317    ulMask              = ~(PIXCLK_ALWAYS_ONb
  318             | PIXCLK_DAC_ALWAYS_ONb);
  319    OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
  320 
  321    ulOrigCRTC_EXT_CNTL = INREG(CRTC_EXT_CNTL);
  322    ulData              = ulOrigCRTC_EXT_CNTL;
  323    ulData             |= CRTC_CRT_ON;
  324    OUTREG(CRTC_EXT_CNTL, ulData);
  325    
  326    ulOrigDAC_EXT_CNTL = INREG(DAC_EXT_CNTL);
  327    ulData             = ulOrigDAC_EXT_CNTL;
  328    ulData            &= ~DAC_FORCE_DATA_MASK;
  329    ulData            |=  (DAC_FORCE_BLANK_OFF_EN
  330                 |DAC_FORCE_DATA_EN
  331                 |DAC_FORCE_DATA_SEL_MASK);
  332    if ((rinfo->family == CHIP_FAMILY_RV250) ||
- 333        (rinfo->family == CHIP_FAMILY_RV280))
 - 333     (T) || (_)
 - 333     (F) || (T)
   333     (F) || (F)
  334        ulData |= (0x01b6 << DAC_FORCE_DATA_SHIFT);
    335    else
  336        ulData |= (0x01ac << DAC_FORCE_DATA_SHIFT);
  337 
  338    OUTREG(DAC_EXT_CNTL, ulData);
  339 
  340    ulOrigDAC_CNTL     = INREG(DAC_CNTL);
  341    ulData             = ulOrigDAC_CNTL;
  342    ulData            |= DAC_CMP_EN;
  343    ulData            &= ~(DAC_RANGE_CNTL_MASK
  344                 | DAC_PDWN);
  345    ulData            |= 0x2;
  346    OUTREG(DAC_CNTL, ulData);
  347 
    348    mdelay(1);
- 348   ternary-?: ( __builtin_constant_p ( 1 ) && (..
- 348   ternary-?: __builtin_constant_p ( ( 1 ) * 10..
- 348   ternary-?: ( ( 1 ) * 1000 ) > 20000
  349 
  350    ulData     = INREG(DAC_CNTL);
    351    connected =  (DAC_CMP_OUTPUT & ulData) ? 1 : 0;
- 351   ternary-?: ( ( 1 << 7 ) & ulData )
  352   
  353    ulData    = ulOrigVCLK_ECP_CNTL;
  354    ulMask    = 0xFFFFFFFFL;
  355    OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
  356 
  357    OUTREG(DAC_CNTL,      ulOrigDAC_CNTL     );
  358    OUTREG(DAC_EXT_CNTL,  ulOrigDAC_EXT_CNTL );
  359    OUTREG(CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
  360     }
  361 
    362     return connected ? MT_CRT : MT_NONE;
- 362 ternary-?: connected
   362 return connected ? MT_CRT : MT_NONE
  363 }
  364 
  365 /*
  366  * Parse the "monitor_layout" string if any. This code is mostly
  367  * copied from XFree's radeon driver
  368  */
 
  369 static int __devinit radeon_parse_monitor_layout(struct radeonfb_info *rinfo,
  370                    const char *monitor_layout)
  371 {
  372    char s1[5], s2[5];
  373    int i = 0, second = 0;
  374    const char *s;
  375 
- 376    if (!monitor_layout)
   377       return 0;
  378 
  379    s = monitor_layout;
    380    do {
    381       switch(*s) {
 - 382       case ',':
  383          s1[i] = '\0';
  384          i = 0;
  385          second = 1;
 - 386          break;
 - 387       case ' ':
 - 388       case '\0':
 - 389          break;
 - 390       default:
- 391          if (i > 4)
 - 392             break;
- 393          if (second)
  394             s2[i] = *s;
    395          else
  396             s1[i] = *s;
  397          i++;
  398       }
  399 
- 400       if (i > 4)
  401          i = 4;
  402 
- 403    } while (*s++);
- 404    if (second)
  405       s2[i] = 0;
    406    else {
  407       s1[i] = 0;
  408       s2[0] = 0;
  409    }
- 410    if (strcmp(s1, "CRT") == 0)
  411       rinfo->mon1_type = MT_CRT;
- 412    else if (strcmp(s1, "TMDS") == 0)
  413       rinfo->mon1_type = MT_DFP;
- 414    else if (strcmp(s1, "LVDS") == 0)
  415       rinfo->mon1_type = MT_LCD;
  416 
- 417    if (strcmp(s2, "CRT") == 0)
  418       rinfo->mon2_type = MT_CRT;
- 419    else if (strcmp(s2, "TMDS") == 0)
  420       rinfo->mon2_type = MT_DFP;
- 421    else if (strcmp(s2, "LVDS") == 0)
  422       rinfo->mon2_type = MT_LCD;
  423 
 - 424    return 1;
  425 }
  426 
  427 /*
  428  * Probe display on both primary and secondary card's connector (if any)
  429  * by various available techniques (i2c, OF device tree, BIOS, ...) and
  430  * try to retrieve EDID. The algorithm here comes from XFree's radeon
  431  * driver
  432  */
 
  433 void __devinit radeon_probe_screens(struct radeonfb_info *rinfo,
  434                 const char *monitor_layout, int ignore_edid)
  435 {
  436 #ifdef CONFIG_FB_RADEON_I2C
  437    int ddc_crt2_used = 0;   
  438 #endif
  439    int tmp, i;
  440 
  441    radeon_parse_connector_info(rinfo);
  442 
- 443    if (radeon_parse_monitor_layout(rinfo, monitor_layout)) {
  444 
  445       /*
  446        * If user specified a monitor_layout option, use it instead
  447        * of auto-detecting. Maybe we should only use this argument
  448        * on the first radeon card probed or provide a way to specify
  449        * a layout for each card ?
  450        */
  451 
- 452       RTRACE("Using specified monitor layout: %s", monitor_layout);
  453 #ifdef CONFIG_FB_RADEON_I2C
- 454       if (!ignore_edid) {
- 455          if (rinfo->mon1_type != MT_NONE)
- 456             if (!radeon_probe_i2c_connector(rinfo, ddc_dvi, &rinfo->mon1_EDID)) {
  457                radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon1_EDID);
  458                ddc_crt2_used = 1;
  459             }
- 460          if (rinfo->mon2_type != MT_NONE)
  461             if (!radeon_probe_i2c_connector(rinfo, ddc_vga, &rinfo->mon2_EDID) &&
- 462                 !ddc_crt2_used)
 - 462         T && T
 - 462         T && F
 - 462         F && _
  463                radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon2_EDID);
  464       }
  465 #endif /* CONFIG_FB_RADEON_I2C */
- 466       if (rinfo->mon1_type == MT_NONE) {
- 467          if (rinfo->mon2_type != MT_NONE) {
  468             rinfo->mon1_type = rinfo->mon2_type;
  469             rinfo->mon1_EDID = rinfo->mon2_EDID;
    470          } else {
  471             rinfo->mon1_type = MT_CRT;
  472             printk(KERN_INFO "radeonfb: No valid monitor, assuming CRT on first port\n");
  473          }
  474          rinfo->mon2_type = MT_NONE;
  475          rinfo->mon2_EDID = NULL;
  476       }
    477    } else {
  478       /*
  479        * Auto-detecting display type (well... trying to ...)
  480        */
  481       
- 482       RTRACE("Starting monitor auto detection...\n");
  483 
  484 #if DEBUG && defined(CONFIG_FB_RADEON_I2C)
  485       {
  486          u8 *EDIDs[4] = { NULL, NULL, NULL, NULL };
  487          int mon_types[4] = {MT_NONE, MT_NONE, MT_NONE, MT_NONE};
  488          int i;
  489 
  490          for (i = 0; i < 4; i++)
  491             mon_types[i] = radeon_probe_i2c_connector(rinfo,
  492                              i+1, &EDIDs[i]);
  493       }