diff options
| -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 bded8704326e..8e421f644a54 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 cd1b64ab5ca7..a589a55b223e 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 03141755c2ea..966ba0751feb 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 37533bec1f25..fefeb0f958bf 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 | } |
