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 | |
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')
-rw-r--r-- | drivers/gpu/drm/radeon/atom.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/atom.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 40 |
4 files changed, 68 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index bded8704326..8e421f644a5 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -108,12 +108,11 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
108 | base++; | 108 | base++; |
109 | break; | 109 | break; |
110 | case ATOM_IIO_READ: | 110 | case ATOM_IIO_READ: |
111 | temp = ctx->card->reg_read(ctx->card, CU16(base + 1)); | 111 | temp = ctx->card->ioreg_read(ctx->card, CU16(base + 1)); |
112 | base += 3; | 112 | base += 3; |
113 | break; | 113 | break; |
114 | case ATOM_IIO_WRITE: | 114 | case ATOM_IIO_WRITE: |
115 | (void)ctx->card->reg_read(ctx->card, CU16(base + 1)); | 115 | ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp); |
116 | ctx->card->reg_write(ctx->card, CU16(base + 1), temp); | ||
117 | base += 3; | 116 | base += 3; |
118 | break; | 117 | break; |
119 | case ATOM_IIO_CLEAR: | 118 | case ATOM_IIO_CLEAR: |
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index cd1b64ab5ca..a589a55b223 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h | |||
@@ -113,6 +113,8 @@ struct card_info { | |||
113 | struct drm_device *dev; | 113 | struct drm_device *dev; |
114 | void (* reg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ | 114 | void (* reg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ |
115 | uint32_t (* reg_read)(struct card_info *, uint32_t); /* filled by driver */ | 115 | uint32_t (* reg_read)(struct card_info *, uint32_t); /* filled by driver */ |
116 | void (* ioreg_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ | ||
117 | uint32_t (* ioreg_read)(struct card_info *, uint32_t); /* filled by driver */ | ||
116 | void (* mc_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ | 118 | void (* mc_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ |
117 | uint32_t (* mc_read)(struct card_info *, uint32_t); /* filled by driver */ | 119 | uint32_t (* mc_read)(struct card_info *, uint32_t); /* filled by driver */ |
118 | void (* pll_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ | 120 | void (* pll_write)(struct card_info *, uint32_t, uint32_t); /* filled by driver */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 03141755c2e..966ba0751fe 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1048,6 +1048,9 @@ struct radeon_device { | |||
1048 | uint32_t pcie_reg_mask; | 1048 | uint32_t pcie_reg_mask; |
1049 | radeon_rreg_t pciep_rreg; | 1049 | radeon_rreg_t pciep_rreg; |
1050 | radeon_wreg_t pciep_wreg; | 1050 | radeon_wreg_t pciep_wreg; |
1051 | /* io port */ | ||
1052 | void __iomem *rio_mem; | ||
1053 | resource_size_t rio_mem_size; | ||
1051 | struct radeon_clock clock; | 1054 | struct radeon_clock clock; |
1052 | struct radeon_mc mc; | 1055 | struct radeon_mc mc; |
1053 | struct radeon_gart gart; | 1056 | struct radeon_gart gart; |
@@ -1130,6 +1133,26 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 | |||
1130 | } | 1133 | } |
1131 | } | 1134 | } |
1132 | 1135 | ||
1136 | static inline u32 r100_io_rreg(struct radeon_device *rdev, u32 reg) | ||
1137 | { | ||
1138 | if (reg < rdev->rio_mem_size) | ||
1139 | return ioread32(rdev->rio_mem + reg); | ||
1140 | else { | ||
1141 | iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); | ||
1142 | return ioread32(rdev->rio_mem + RADEON_MM_DATA); | ||
1143 | } | ||
1144 | } | ||
1145 | |||
1146 | static inline void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v) | ||
1147 | { | ||
1148 | if (reg < rdev->rio_mem_size) | ||
1149 | iowrite32(v, rdev->rio_mem + reg); | ||
1150 | else { | ||
1151 | iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); | ||
1152 | iowrite32(v, rdev->rio_mem + RADEON_MM_DATA); | ||
1153 | } | ||
1154 | } | ||
1155 | |||
1133 | /* | 1156 | /* |
1134 | * Cast helper | 1157 | * Cast helper |
1135 | */ | 1158 | */ |
@@ -1168,6 +1191,8 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 | |||
1168 | WREG32_PLL(reg, tmp_); \ | 1191 | WREG32_PLL(reg, tmp_); \ |
1169 | } while (0) | 1192 | } while (0) |
1170 | #define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg))) | 1193 | #define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg))) |
1194 | #define RREG32_IO(reg) r100_io_rreg(rdev, (reg)) | ||
1195 | #define WREG32_IO(reg, v) r100_io_wreg(rdev, (reg), (v)) | ||
1171 | 1196 | ||
1172 | /* | 1197 | /* |
1173 | * Indirect registers accessor | 1198 | * Indirect registers accessor |
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 | } |