diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2010-06-30 11:52:50 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-08-01 20:00:07 -0400 |
commit | 351a52a2414d2b104269755c86b476863c248034 (patch) | |
tree | 71e25c5cceab9235e5bca4a8d521f73b3adf3fa6 /drivers/gpu/drm/radeon/radeon_device.c | |
parent | fe50ac78a6ec20db267b32e27a1d191128eaaa46 (diff) |
drm/radeon/kms: add ioport register access
This is required for the NB_MISC regs on rs780/rs880 which
means HDMI/DVI/DP ports using PCIEPHY won't work without
it. It might also help with s/r (asic init) issues on other
atombios cards.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=28774
and similar issues reported by Alberto Milone.
[airlied: Squash io fix patch]
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Tested-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_device.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 37533bec1f2..fefeb0f958b 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -415,6 +415,22 @@ static uint32_t cail_reg_read(struct card_info *info, uint32_t reg) | |||
415 | return r; | 415 | return r; |
416 | } | 416 | } |
417 | 417 | ||
418 | static void cail_ioreg_write(struct card_info *info, uint32_t reg, uint32_t val) | ||
419 | { | ||
420 | struct radeon_device *rdev = info->dev->dev_private; | ||
421 | |||
422 | WREG32_IO(reg*4, val); | ||
423 | } | ||
424 | |||
425 | static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) | ||
426 | { | ||
427 | struct radeon_device *rdev = info->dev->dev_private; | ||
428 | uint32_t r; | ||
429 | |||
430 | r = RREG32_IO(reg*4); | ||
431 | return r; | ||
432 | } | ||
433 | |||
418 | int radeon_atombios_init(struct radeon_device *rdev) | 434 | int radeon_atombios_init(struct radeon_device *rdev) |
419 | { | 435 | { |
420 | struct card_info *atom_card_info = | 436 | struct card_info *atom_card_info = |
@@ -427,6 +443,15 @@ int radeon_atombios_init(struct radeon_device *rdev) | |||
427 | atom_card_info->dev = rdev->ddev; | 443 | atom_card_info->dev = rdev->ddev; |
428 | atom_card_info->reg_read = cail_reg_read; | 444 | atom_card_info->reg_read = cail_reg_read; |
429 | atom_card_info->reg_write = cail_reg_write; | 445 | atom_card_info->reg_write = cail_reg_write; |
446 | /* needed for iio ops */ | ||
447 | if (rdev->rio_mem) { | ||
448 | atom_card_info->ioreg_read = cail_ioreg_read; | ||
449 | atom_card_info->ioreg_write = cail_ioreg_write; | ||
450 | } else { | ||
451 | DRM_ERROR("Unable to find PCI I/O BAR; using MMIO for ATOM IIO\n"); | ||
452 | atom_card_info->ioreg_read = cail_reg_read; | ||
453 | atom_card_info->ioreg_write = cail_reg_write; | ||
454 | } | ||
430 | atom_card_info->mc_read = cail_mc_read; | 455 | atom_card_info->mc_read = cail_mc_read; |
431 | atom_card_info->mc_write = cail_mc_write; | 456 | atom_card_info->mc_write = cail_mc_write; |
432 | atom_card_info->pll_read = cail_pll_read; | 457 | atom_card_info->pll_read = cail_pll_read; |
@@ -573,7 +598,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
573 | struct pci_dev *pdev, | 598 | struct pci_dev *pdev, |
574 | uint32_t flags) | 599 | uint32_t flags) |
575 | { | 600 | { |
576 | int r; | 601 | int r, i; |
577 | int dma_bits; | 602 | int dma_bits; |
578 | 603 | ||
579 | rdev->shutdown = false; | 604 | rdev->shutdown = false; |
@@ -659,6 +684,17 @@ int radeon_device_init(struct radeon_device *rdev, | |||
659 | DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); | 684 | DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); |
660 | DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); | 685 | DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); |
661 | 686 | ||
687 | /* io port mapping */ | ||
688 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
689 | if (pci_resource_flags(rdev->pdev, i) & IORESOURCE_IO) { | ||
690 | rdev->rio_mem_size = pci_resource_len(rdev->pdev, i); | ||
691 | rdev->rio_mem = pci_iomap(rdev->pdev, i, rdev->rio_mem_size); | ||
692 | break; | ||
693 | } | ||
694 | } | ||
695 | if (rdev->rio_mem == NULL) | ||
696 | DRM_ERROR("Unable to find PCI I/O BAR\n"); | ||
697 | |||
662 | /* if we have > 1 VGA cards, then disable the radeon VGA resources */ | 698 | /* if we have > 1 VGA cards, then disable the radeon VGA resources */ |
663 | /* this will fail for cards that aren't VGA class devices, just | 699 | /* this will fail for cards that aren't VGA class devices, just |
664 | * ignore it */ | 700 | * ignore it */ |
@@ -701,6 +737,8 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
701 | destroy_workqueue(rdev->wq); | 737 | destroy_workqueue(rdev->wq); |
702 | vga_switcheroo_unregister_client(rdev->pdev); | 738 | vga_switcheroo_unregister_client(rdev->pdev); |
703 | vga_client_register(rdev->pdev, NULL, NULL, NULL); | 739 | vga_client_register(rdev->pdev, NULL, NULL, NULL); |
740 | pci_iounmap(rdev->pdev, rdev->rio_mem); | ||
741 | rdev->rio_mem = NULL; | ||
704 | iounmap(rdev->rmmio); | 742 | iounmap(rdev->rmmio); |
705 | rdev->rmmio = NULL; | 743 | rdev->rmmio = NULL; |
706 | } | 744 | } |