in fbdev/aty/radeon_base.c [2258:2516]
static int radeonfb_pci_register(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct fb_info *info;
struct radeonfb_info *rinfo;
int ret;
unsigned char c1, c2;
int err = 0;
pr_debug("radeonfb_pci_register BEGIN\n");
/* Enable device in PCI config */
ret = pci_enable_device(pdev);
if (ret < 0) {
printk(KERN_ERR "radeonfb (%s): Cannot enable PCI device\n",
pci_name(pdev));
goto err_out;
}
info = framebuffer_alloc(sizeof(struct radeonfb_info), &pdev->dev);
if (!info) {
ret = -ENOMEM;
goto err_disable;
}
rinfo = info->par;
rinfo->info = info;
rinfo->pdev = pdev;
spin_lock_init(&rinfo->reg_lock);
timer_setup(&rinfo->lvds_timer, radeon_lvds_timer_func, 0);
c1 = ent->device >> 8;
c2 = ent->device & 0xff;
if (isprint(c1) && isprint(c2))
snprintf(rinfo->name, sizeof(rinfo->name),
"ATI Radeon %x \"%c%c\"", ent->device & 0xffff, c1, c2);
else
snprintf(rinfo->name, sizeof(rinfo->name),
"ATI Radeon %x", ent->device & 0xffff);
rinfo->family = ent->driver_data & CHIP_FAMILY_MASK;
rinfo->chipset = pdev->device;
rinfo->has_CRTC2 = (ent->driver_data & CHIP_HAS_CRTC2) != 0;
rinfo->is_mobility = (ent->driver_data & CHIP_IS_MOBILITY) != 0;
rinfo->is_IGP = (ent->driver_data & CHIP_IS_IGP) != 0;
/* Set base addrs */
rinfo->fb_base_phys = pci_resource_start (pdev, 0);
rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
ret = radeon_kick_out_firmware_fb(pdev);
if (ret)
goto err_release_fb;
/* request the mem regions */
ret = pci_request_region(pdev, 0, "radeonfb framebuffer");
if (ret < 0) {
printk( KERN_ERR "radeonfb (%s): cannot request region 0.\n",
pci_name(rinfo->pdev));
goto err_release_fb;
}
ret = pci_request_region(pdev, 2, "radeonfb mmio");
if (ret < 0) {
printk( KERN_ERR "radeonfb (%s): cannot request region 2.\n",
pci_name(rinfo->pdev));
goto err_release_pci0;
}
/* map the regions */
rinfo->mmio_base = ioremap(rinfo->mmio_base_phys, RADEON_REGSIZE);
if (!rinfo->mmio_base) {
printk(KERN_ERR "radeonfb (%s): cannot map MMIO\n",
pci_name(rinfo->pdev));
ret = -EIO;
goto err_release_pci2;
}
rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
/*
* Check for errata
*/
rinfo->errata = 0;
if (rinfo->family == CHIP_FAMILY_R300 &&
(INREG(CNFG_CNTL) & CFG_ATI_REV_ID_MASK)
== CFG_ATI_REV_A11)
rinfo->errata |= CHIP_ERRATA_R300_CG;
if (rinfo->family == CHIP_FAMILY_RV200 ||
rinfo->family == CHIP_FAMILY_RS200)
rinfo->errata |= CHIP_ERRATA_PLL_DUMMYREADS;
if (rinfo->family == CHIP_FAMILY_RV100 ||
rinfo->family == CHIP_FAMILY_RS100 ||
rinfo->family == CHIP_FAMILY_RS200)
rinfo->errata |= CHIP_ERRATA_PLL_DELAY;
#if defined(CONFIG_PPC) || defined(CONFIG_SPARC)
/* On PPC, we obtain the OF device-node pointer to the firmware
* data for this chip
*/
rinfo->of_node = pci_device_to_OF_node(pdev);
if (rinfo->of_node == NULL)
printk(KERN_WARNING "radeonfb (%s): Cannot match card to OF node !\n",
pci_name(rinfo->pdev));
#endif /* CONFIG_PPC || CONFIG_SPARC */
#ifdef CONFIG_PPC
/* On PPC, the firmware sets up a memory mapping that tends
* to cause lockups when enabling the engine. We reconfigure
* the card internal memory mappings properly
*/
fixup_memory_mappings(rinfo);
#endif /* CONFIG_PPC */
/* Get VRAM size and type */
radeon_identify_vram(rinfo);
rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, rinfo->video_ram);
do {
rinfo->fb_base = ioremap_wc(rinfo->fb_base_phys,
rinfo->mapped_vram);
} while (rinfo->fb_base == NULL &&
((rinfo->mapped_vram /= 2) >= MIN_MAPPED_VRAM));
if (rinfo->fb_base == NULL) {
printk (KERN_ERR "radeonfb (%s): cannot map FB\n",
pci_name(rinfo->pdev));
ret = -EIO;
goto err_unmap_rom;
}
pr_debug("radeonfb (%s): mapped %ldk videoram\n", pci_name(rinfo->pdev),
rinfo->mapped_vram/1024);
/*
* Map the BIOS ROM if any and retrieve PLL parameters from
* the BIOS. We skip that on mobility chips as the real panel
* values we need aren't in the ROM but in the BIOS image in
* memory. This is definitely not the best meacnism though,
* we really need the arch code to tell us which is the "primary"
* video adapter to use the memory image (or better, the arch
* should provide us a copy of the BIOS image to shield us from
* archs who would store that elsewhere and/or could initialize
* more than one adapter during boot).
*/
if (!rinfo->is_mobility)
radeon_map_ROM(rinfo, pdev);
/*
* On x86, the primary display on laptop may have it's BIOS
* ROM elsewhere, try to locate it at the legacy memory hole.
* We probably need to make sure this is the primary display,
* but that is difficult without some arch support.
*/
#ifdef CONFIG_X86
if (rinfo->bios_seg == NULL)
radeon_find_mem_vbios(rinfo);
#endif
/* If both above failed, try the BIOS ROM again for mobility
* chips
*/
if (rinfo->bios_seg == NULL && rinfo->is_mobility)
radeon_map_ROM(rinfo, pdev);
/* Get informations about the board's PLL */
radeon_get_pllinfo(rinfo);
#ifdef CONFIG_FB_RADEON_I2C
/* Register I2C bus */
radeon_create_i2c_busses(rinfo);
#endif
/* set all the vital stuff */
radeon_set_fbinfo (rinfo);
/* Probe screen types */
radeon_probe_screens(rinfo, monitor_layout, ignore_edid);
/* Build mode list, check out panel native model */
radeon_check_modes(rinfo, mode_option);
/* Register some sysfs stuff (should be done better) */
if (rinfo->mon1_EDID)
err |= sysfs_create_bin_file(&rinfo->pdev->dev.kobj,
&edid1_attr);
if (rinfo->mon2_EDID)
err |= sysfs_create_bin_file(&rinfo->pdev->dev.kobj,
&edid2_attr);
if (err)
pr_warn("%s() Creating sysfs files failed, continuing\n",
__func__);
/* save current mode regs before we switch into the new one
* so we can restore this upon __exit
*/
radeon_save_state (rinfo, &rinfo->init_state);
memcpy(&rinfo->state, &rinfo->init_state, sizeof(struct radeon_regs));
/* Setup Power Management capabilities */
if (default_dynclk < -1) {
/* -2 is special: means ON on mobility chips and do not
* change on others
*/
radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1, ignore_devlist, force_sleep);
} else
radeonfb_pm_init(rinfo, default_dynclk, ignore_devlist, force_sleep);
pci_set_drvdata(pdev, info);
/* Register with fbdev layer */
ret = register_framebuffer(info);
if (ret < 0) {
printk (KERN_ERR "radeonfb (%s): could not register framebuffer\n",
pci_name(rinfo->pdev));
goto err_unmap_fb;
}
if (!nomtrr)
rinfo->wc_cookie = arch_phys_wc_add(rinfo->fb_base_phys,
rinfo->video_ram);
if (backlight)
radeonfb_bl_init(rinfo);
printk ("radeonfb (%s): %s\n", pci_name(rinfo->pdev), rinfo->name);
if (rinfo->bios_seg)
radeon_unmap_ROM(rinfo, pdev);
pr_debug("radeonfb_pci_register END\n");
return 0;
err_unmap_fb:
iounmap(rinfo->fb_base);
err_unmap_rom:
kfree(rinfo->mon1_EDID);
kfree(rinfo->mon2_EDID);
if (rinfo->mon1_modedb)
fb_destroy_modedb(rinfo->mon1_modedb);
fb_dealloc_cmap(&info->cmap);
#ifdef CONFIG_FB_RADEON_I2C
radeon_delete_i2c_busses(rinfo);
#endif
if (rinfo->bios_seg)
radeon_unmap_ROM(rinfo, pdev);
iounmap(rinfo->mmio_base);
err_release_pci2:
pci_release_region(pdev, 2);
err_release_pci0:
pci_release_region(pdev, 0);
err_release_fb:
framebuffer_release(info);
err_disable:
err_out:
return ret;
}