aboutsummaryrefslogtreecommitdiffhomepage
path: root/drivers/radeon
diff options
context:
space:
mode:
authorGravatar nick <nick@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-10-08 09:23:33 +0000
committerGravatar nick <nick@b3059339-0415-0410-9bf9-f77b7e298cf2>2001-10-08 09:23:33 +0000
commit45f05a3fb52406c556751e60ec15fa7d4f118793 (patch)
treec8a2b5d3b0fd62402d4076b2ff19c44cb4b5b51e /drivers/radeon
parentb53efbb2200f7f075316335012c61ae9a46556ad (diff)
Better DFP support
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2136 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'drivers/radeon')
-rw-r--r--drivers/radeon/radeonfb.c87
1 files changed, 86 insertions, 1 deletions
diff --git a/drivers/radeon/radeonfb.c b/drivers/radeon/radeonfb.c
index c1b050dae0..1760f30f09 100644
--- a/drivers/radeon/radeonfb.c
+++ b/drivers/radeon/radeonfb.c
@@ -943,6 +943,73 @@ static char * GET_MON_NAME(int type)
return pret;
}
+/*This funtion is used to reverse calculate
+ panel information from register settings in VGA mode.
+ More graceful way is to use EDID information... if it can be detected.
+ This way may be better than directly probing BIOS image. Because
+ BIOS image could change from version to version, while the
+ registers should always(?) contain right information, otherwise
+ the VGA mode display will not be correct. Well, if someone
+ messes up these registers before our driver is loaded, we'll be in
+ trouble...*/
+static int radeon_get_dfp_info(struct radeonfb_info *rinfo)
+{
+ unsigned long r;
+ unsigned short a, b;
+
+ r = INREG(FP_VERT_STRETCH);
+ r &= 0x00fff000;
+ rinfo->PanelYRes = (unsigned short)(r >> 0x0c) + 1;
+
+ switch(rinfo->PanelYRes)
+ {
+ case 480: rinfo->PanelXRes = 640;
+ break;
+ case 600: rinfo->PanelXRes = 800;
+ break;
+ case 768: rinfo->PanelXRes = 1024;
+ break;
+ case 1024: rinfo->PanelXRes = 1280;
+ break;
+ case 1050: rinfo->PanelXRes = 1400;
+ break;
+ case 1200: rinfo->PanelXRes = 1600;
+ break;
+ default:
+ printk("radeonfb: Failed to detect the DFP panel size.\n");
+ return 0;
+
+ }
+
+ printk("Detected DFP panel size: %dx%d\n", rinfo->PanelXRes, rinfo->PanelYRes);
+
+ r = INREG(FP_CRTC_H_TOTAL_DISP);
+ a = (r & FP_CRTC_H_TOTAL_MASK) + 4;
+ b = (r & 0x01FF0000) >> FP_CRTC_H_DISP_SHIFT;
+ rinfo->HBlank = (a - b + 1) * 8;
+
+ r = INREG(FP_H_SYNC_STRT_WID);
+ rinfo->HOverPlus =
+ (unsigned short)((r & FP_H_SYNC_STRT_CHAR_MASK)
+ >> FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
+ rinfo->HOverPlus *= 8;
+ rinfo->HSyncWidth =
+ (unsigned short)((r & FP_H_SYNC_WID_MASK)
+ >> FP_H_SYNC_WID_SHIFT);
+ rinfo->HSyncWidth *= 8;
+ r = INREG(FP_CRTC_V_TOTAL_DISP);
+ a = (r & FP_CRTC_V_TOTAL_MASK) + 1;
+ b = (r & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
+ rinfo->VBlank = a - b /*+ 24*/;
+
+ r = INREG(FP_V_SYNC_STRT_WID);
+ rinfo->VOverPlus = (unsigned short)(r & FP_V_SYNC_STRT_MASK)
+ - b + 1;
+ rinfo->VSyncWidth = (unsigned short)((r & FP_V_SYNC_WID_MASK)
+ >> FP_V_SYNC_WID_SHIFT);
+
+ return 1;
+}
static int radeonfb_pci_register (struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -1180,10 +1247,14 @@ static int radeonfb_pci_register (struct pci_dev *pdev,
rinfo->hasTVout = readw(bios_ptr+0x32);
}
+ if((rinfo->dviDispType == MT_DFP || rinfo->dviDispType == MT_LCD ||
+ rinfo->crtDispType == MT_DFP))
+ if(!radeon_get_dfp_info(rinfo)) goto reg_err;
rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys,
rinfo->video_ram);
if (!rinfo->fb_base) {
printk ("radeonfb: cannot map FB\n");
+ reg_err:
iounmap ((void*)rinfo->mmio_base);
release_mem_region (rinfo->mmio_base_phys,
pci_resource_len(pdev, 2));
@@ -1580,6 +1651,20 @@ static int radeon_init_crtc_regs(struct radeonfb_info *rinfo,
vSyncEnd = vSyncStart + mode->vsync_len;
vTotal = vSyncEnd + mode->upper_margin;
+ if(((prim_mon == MT_DFP) || (prim_mon == MT_LCD)))
+ {
+ if(rinfo->PanelXRes < mode->xres)
+ rinfo->xres = mode->xres = rinfo->PanelXRes;
+ if(rinfo->PanelYRes < mode->yres)
+ rinfo->yres = mode->yres = rinfo->PanelYRes;
+ hTotal = mode->xres + rinfo->HBlank + mode->left_margin;
+ hSyncStart = mode->xres + rinfo->HOverPlus + mode->right_margin;
+ hSyncEnd = hSyncStart + rinfo->HSyncWidth + mode->hsync_len;
+ vTotal = mode->yres + rinfo->VBlank + mode->upper_margin;
+ vSyncStart = mode->yres + rinfo->VOverPlus + mode->lower_margin;
+ vSyncEnd = vSyncStart + rinfo->VSyncWidth + mode->vsync_len;
+ }
+
sync = mode->sync;
h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
@@ -2055,7 +2140,7 @@ RTRACE("radeonfb: radeon_init_mode is called\n");
prim_mon = PRIMARY_MONITOR(rinfo);
if (((prim_mon == MT_DFP) || (prim_mon == MT_LCD)))
{
-/* radeon_init_fp_regs(rinfo, save, mode);*/
+ radeon_init_fp_regs(rinfo, save, mode);
}
RTRACE("radeonfb: radeon_init_mode returns SUCCESS\n");