comparison drivers/radeon/radeonfb.c @ 2135:fcf5bd49c68f

Better DFP support
author nick
date Mon, 08 Oct 2001 09:23:33 +0000
parents 27bfb445ca85
children f13d61fde30d
comparison
equal deleted inserted replaced
2134:27bfb445ca85 2135:fcf5bd49c68f
941 default: pret = "Unknown"; 941 default: pret = "Unknown";
942 } 942 }
943 return pret; 943 return pret;
944 } 944 }
945 945
946 /*This funtion is used to reverse calculate
947 panel information from register settings in VGA mode.
948 More graceful way is to use EDID information... if it can be detected.
949 This way may be better than directly probing BIOS image. Because
950 BIOS image could change from version to version, while the
951 registers should always(?) contain right information, otherwise
952 the VGA mode display will not be correct. Well, if someone
953 messes up these registers before our driver is loaded, we'll be in
954 trouble...*/
955 static int radeon_get_dfp_info(struct radeonfb_info *rinfo)
956 {
957 unsigned long r;
958 unsigned short a, b;
959
960 r = INREG(FP_VERT_STRETCH);
961 r &= 0x00fff000;
962 rinfo->PanelYRes = (unsigned short)(r >> 0x0c) + 1;
963
964 switch(rinfo->PanelYRes)
965 {
966 case 480: rinfo->PanelXRes = 640;
967 break;
968 case 600: rinfo->PanelXRes = 800;
969 break;
970 case 768: rinfo->PanelXRes = 1024;
971 break;
972 case 1024: rinfo->PanelXRes = 1280;
973 break;
974 case 1050: rinfo->PanelXRes = 1400;
975 break;
976 case 1200: rinfo->PanelXRes = 1600;
977 break;
978 default:
979 printk("radeonfb: Failed to detect the DFP panel size.\n");
980 return 0;
981
982 }
983
984 printk("Detected DFP panel size: %dx%d\n", rinfo->PanelXRes, rinfo->PanelYRes);
985
986 r = INREG(FP_CRTC_H_TOTAL_DISP);
987 a = (r & FP_CRTC_H_TOTAL_MASK) + 4;
988 b = (r & 0x01FF0000) >> FP_CRTC_H_DISP_SHIFT;
989 rinfo->HBlank = (a - b + 1) * 8;
990
991 r = INREG(FP_H_SYNC_STRT_WID);
992 rinfo->HOverPlus =
993 (unsigned short)((r & FP_H_SYNC_STRT_CHAR_MASK)
994 >> FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
995 rinfo->HOverPlus *= 8;
996 rinfo->HSyncWidth =
997 (unsigned short)((r & FP_H_SYNC_WID_MASK)
998 >> FP_H_SYNC_WID_SHIFT);
999 rinfo->HSyncWidth *= 8;
1000 r = INREG(FP_CRTC_V_TOTAL_DISP);
1001 a = (r & FP_CRTC_V_TOTAL_MASK) + 1;
1002 b = (r & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
1003 rinfo->VBlank = a - b /*+ 24*/;
1004
1005 r = INREG(FP_V_SYNC_STRT_WID);
1006 rinfo->VOverPlus = (unsigned short)(r & FP_V_SYNC_STRT_MASK)
1007 - b + 1;
1008 rinfo->VSyncWidth = (unsigned short)((r & FP_V_SYNC_WID_MASK)
1009 >> FP_V_SYNC_WID_SHIFT);
1010
1011 return 1;
1012 }
946 1013
947 static int radeonfb_pci_register (struct pci_dev *pdev, 1014 static int radeonfb_pci_register (struct pci_dev *pdev,
948 const struct pci_device_id *ent) 1015 const struct pci_device_id *ent)
949 { 1016 {
950 struct radeonfb_info *rinfo; 1017 struct radeonfb_info *rinfo;
1178 */ 1245 */
1179 char * bios_ptr = bios_seg + 0x48L; 1246 char * bios_ptr = bios_seg + 0x48L;
1180 rinfo->hasTVout = readw(bios_ptr+0x32); 1247 rinfo->hasTVout = readw(bios_ptr+0x32);
1181 } 1248 }
1182 1249
1250 if((rinfo->dviDispType == MT_DFP || rinfo->dviDispType == MT_LCD ||
1251 rinfo->crtDispType == MT_DFP))
1252 if(!radeon_get_dfp_info(rinfo)) goto reg_err;
1183 rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys, 1253 rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys,
1184 rinfo->video_ram); 1254 rinfo->video_ram);
1185 if (!rinfo->fb_base) { 1255 if (!rinfo->fb_base) {
1186 printk ("radeonfb: cannot map FB\n"); 1256 printk ("radeonfb: cannot map FB\n");
1257 reg_err:
1187 iounmap ((void*)rinfo->mmio_base); 1258 iounmap ((void*)rinfo->mmio_base);
1188 release_mem_region (rinfo->mmio_base_phys, 1259 release_mem_region (rinfo->mmio_base_phys,
1189 pci_resource_len(pdev, 2)); 1260 pci_resource_len(pdev, 2));
1190 release_mem_region (rinfo->fb_base_phys, 1261 release_mem_region (rinfo->fb_base_phys,
1191 pci_resource_len(pdev, 0)); 1262 pci_resource_len(pdev, 0));
1578 1649
1579 vSyncStart = mode->yres + mode->lower_margin; 1650 vSyncStart = mode->yres + mode->lower_margin;
1580 vSyncEnd = vSyncStart + mode->vsync_len; 1651 vSyncEnd = vSyncStart + mode->vsync_len;
1581 vTotal = vSyncEnd + mode->upper_margin; 1652 vTotal = vSyncEnd + mode->upper_margin;
1582 1653
1654 if(((prim_mon == MT_DFP) || (prim_mon == MT_LCD)))
1655 {
1656 if(rinfo->PanelXRes < mode->xres)
1657 rinfo->xres = mode->xres = rinfo->PanelXRes;
1658 if(rinfo->PanelYRes < mode->yres)
1659 rinfo->yres = mode->yres = rinfo->PanelYRes;
1660 hTotal = mode->xres + rinfo->HBlank + mode->left_margin;
1661 hSyncStart = mode->xres + rinfo->HOverPlus + mode->right_margin;
1662 hSyncEnd = hSyncStart + rinfo->HSyncWidth + mode->hsync_len;
1663 vTotal = mode->yres + rinfo->VBlank + mode->upper_margin;
1664 vSyncStart = mode->yres + rinfo->VOverPlus + mode->lower_margin;
1665 vSyncEnd = vSyncStart + rinfo->VSyncWidth + mode->vsync_len;
1666 }
1667
1583 sync = mode->sync; 1668 sync = mode->sync;
1584 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; 1669 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
1585 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; 1670 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
1586 1671
1587 RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n", 1672 RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n",
2053 } 2138 }
2054 /* radeon_init_palete here */ 2139 /* radeon_init_palete here */
2055 prim_mon = PRIMARY_MONITOR(rinfo); 2140 prim_mon = PRIMARY_MONITOR(rinfo);
2056 if (((prim_mon == MT_DFP) || (prim_mon == MT_LCD))) 2141 if (((prim_mon == MT_DFP) || (prim_mon == MT_LCD)))
2057 { 2142 {
2058 /* radeon_init_fp_regs(rinfo, save, mode);*/ 2143 radeon_init_fp_regs(rinfo, save, mode);
2059 } 2144 }
2060 2145
2061 RTRACE("radeonfb: radeon_init_mode returns SUCCESS\n"); 2146 RTRACE("radeonfb: radeon_init_mode returns SUCCESS\n");
2062 return 1; 2147 return 1;
2063 } 2148 }