viafb: use proper pci config API

This patch alters viafb to use the proper Linux in-kernel API to access
PCI configuration space, rather than poking at I/O ports by itself.

Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Signed-off-by: Harald Welte <HaraldWelte@viatech.com>
This commit is contained in:
Harald Welte 2009-05-19 15:50:58 +08:00 committed by Jonathan Corbet
parent 109771a68b
commit b72a5070c7
3 changed files with 42 additions and 24 deletions

View File

@ -2473,24 +2473,37 @@ static void disable_second_display_channel(void)
viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
}
static u_int16_t via_function3[] = {
CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_FUNCTION3,
CX700_FUNCTION3, KM800_FUNCTION3, KM890_FUNCTION3, P4M890_FUNCTION3,
P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3,
};
/* Get the BIOS-configured framebuffer size from PCI configuration space
* of function 3 in the respective chipset */
int viafb_get_fb_size_from_pci(void)
{
unsigned long configid, deviceid, FBSize = 0;
int VideoMemSize;
int DeviceFound = false;
int i;
u_int8_t offset = 0;
u_int32_t FBSize;
u_int32_t VideoMemSize;
for (configid = 0x80000000; configid < 0x80010800; configid += 0x100) {
outl(configid, (unsigned long)0xCF8);
deviceid = (inl((unsigned long)0xCFC) >> 16) & 0xffff;
/* search for the "FUNCTION3" device in this chipset */
for (i = 0; i < ARRAY_SIZE(via_function3); i++) {
struct pci_dev *pdev;
switch (deviceid) {
case CLE266:
case KM400:
outl(configid + 0xE0, (unsigned long)0xCF8);
FBSize = inl((unsigned long)0xCFC);
DeviceFound = true; /* Found device id */
pdev = pci_get_device(PCI_VENDOR_ID_VIA, via_function3[i],
NULL);
if (!pdev)
continue;
DEBUG_MSG(KERN_INFO "Device ID = %x\n", pdev->device);
switch (pdev->device) {
case CLE266_FUNCTION3:
case KM400_FUNCTION3:
offset = 0xE0;
break;
case CN400_FUNCTION3:
case CN700_FUNCTION3:
case CX700_FUNCTION3:
@ -2500,21 +2513,22 @@ int viafb_get_fb_size_from_pci(void)
case P4M900_FUNCTION3:
case VX800_FUNCTION3:
case VX855_FUNCTION3:
/*case CN750_FUNCTION3: */
outl(configid + 0xA0, (unsigned long)0xCF8);
FBSize = inl((unsigned long)0xCFC);
DeviceFound = true; /* Found device id */
break;
default:
/*case CN750_FUNCTION3: */
offset = 0xA0;
break;
}
if (DeviceFound)
if (!offset)
break;
pci_read_config_dword(pdev, offset, &FBSize);
pci_dev_put(pdev);
}
DEBUG_MSG(KERN_INFO "Device ID = %lx\n", deviceid);
if (!offset) {
printk(KERN_ERR "cannot determine framebuffer size\n");
return -EIO;
}
FBSize = FBSize & 0x00007000;
DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize);

View File

@ -823,8 +823,8 @@ struct iga2_crtc_timing {
};
/* device ID */
#define CLE266 0x3123
#define KM400 0x3205
#define CLE266_FUNCTION3 0x3123
#define KM400_FUNCTION3 0x3205
#define CN400_FUNCTION2 0x2259
#define CN400_FUNCTION3 0x3259
/* support VT3314 chipset */

View File

@ -1782,6 +1782,10 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
viafb_init_chip_info(pdev, ent);
viaparinfo->fbmem = pci_resource_start(pdev, 0);
viaparinfo->memsize = viafb_get_fb_size_from_pci();
if (viaparinfo->memsize < 0) {
rc = viaparinfo->memsize;
goto out_delete_i2c;
}
viaparinfo->fbmem_free = viaparinfo->memsize;
viaparinfo->fbmem_used = 0;
viafbinfo->screen_base = ioremap_nocache(viaparinfo->fbmem,