diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-03-12 01:55:43 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-03-13 03:15:07 -0400 |
commit | 2f5394c3ed573de2ab18cdac503b8045cd16ac5e (patch) | |
tree | 012cc19b8f0052f452097a633e8fde9224d405b6 /drivers/gpu | |
parent | 4cbb0f8d2b06c72aae3552ff1a0a57814c6ce7d2 (diff) |
drm/nouveau: map first page of mmio early and determine chipset earlier
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 121 |
2 files changed, 62 insertions, 63 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index cf0e74a2c667..a184ba331273 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -695,14 +695,14 @@ struct nv04_mode_state { | |||
695 | }; | 695 | }; |
696 | 696 | ||
697 | enum nouveau_card_type { | 697 | enum nouveau_card_type { |
698 | NV_04 = 0x00, | 698 | NV_04 = 0x04, |
699 | NV_10 = 0x10, | 699 | NV_10 = 0x10, |
700 | NV_20 = 0x20, | 700 | NV_20 = 0x20, |
701 | NV_30 = 0x30, | 701 | NV_30 = 0x30, |
702 | NV_40 = 0x40, | 702 | NV_40 = 0x40, |
703 | NV_50 = 0x50, | 703 | NV_50 = 0x50, |
704 | NV_C0 = 0xc0, | 704 | NV_C0 = 0xc0, |
705 | NV_D0 = 0xd0 | 705 | NV_D0 = 0xd0, |
706 | }; | 706 | }; |
707 | 707 | ||
708 | struct drm_nouveau_private { | 708 | struct drm_nouveau_private { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 9d6c3ff22e81..9c144fb8bbba 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -993,7 +993,7 @@ static int nouveau_remove_conflicting_drivers(struct drm_device *dev) | |||
993 | int nouveau_load(struct drm_device *dev, unsigned long flags) | 993 | int nouveau_load(struct drm_device *dev, unsigned long flags) |
994 | { | 994 | { |
995 | struct drm_nouveau_private *dev_priv; | 995 | struct drm_nouveau_private *dev_priv; |
996 | uint32_t reg0, strap; | 996 | uint32_t reg0 = ~0, strap; |
997 | resource_size_t mmio_start_offs; | 997 | resource_size_t mmio_start_offs; |
998 | int ret; | 998 | int ret; |
999 | 999 | ||
@@ -1012,10 +1012,65 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) | |||
1012 | NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", | 1012 | NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", |
1013 | dev->pci_vendor, dev->pci_device, dev->pdev->class); | 1013 | dev->pci_vendor, dev->pci_device, dev->pdev->class); |
1014 | 1014 | ||
1015 | /* resource 0 is mmio regs */ | 1015 | /* first up, map the start of mmio and determine the chipset */ |
1016 | /* resource 1 is linear FB */ | 1016 | dev_priv->mmio = ioremap(pci_resource_start(dev->pdev, 0), PAGE_SIZE); |
1017 | /* resource 2 is RAMIN (mmio regs + 0x1000000) */ | 1017 | if (dev_priv->mmio) { |
1018 | /* resource 6 is bios */ | 1018 | #ifdef __BIG_ENDIAN |
1019 | /* put the card into big-endian mode if it's not */ | ||
1020 | if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001) | ||
1021 | nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001); | ||
1022 | DRM_MEMORYBARRIER(); | ||
1023 | #endif | ||
1024 | |||
1025 | /* determine chipset and derive architecture from it */ | ||
1026 | reg0 = nv_rd32(dev, NV03_PMC_BOOT_0); | ||
1027 | if ((reg0 & 0x0f000000) > 0) { | ||
1028 | dev_priv->chipset = (reg0 & 0xff00000) >> 20; | ||
1029 | switch (dev_priv->chipset & 0xf0) { | ||
1030 | case 0x10: | ||
1031 | case 0x20: | ||
1032 | case 0x30: | ||
1033 | dev_priv->card_type = dev_priv->chipset & 0xf0; | ||
1034 | break; | ||
1035 | case 0x40: | ||
1036 | case 0x60: | ||
1037 | dev_priv->card_type = NV_40; | ||
1038 | break; | ||
1039 | case 0x50: | ||
1040 | case 0x80: | ||
1041 | case 0x90: | ||
1042 | case 0xa0: | ||
1043 | dev_priv->card_type = NV_50; | ||
1044 | break; | ||
1045 | case 0xc0: | ||
1046 | dev_priv->card_type = NV_C0; | ||
1047 | break; | ||
1048 | case 0xd0: | ||
1049 | dev_priv->card_type = NV_D0; | ||
1050 | break; | ||
1051 | default: | ||
1052 | break; | ||
1053 | } | ||
1054 | } else | ||
1055 | if ((reg0 & 0xff00fff0) == 0x20004000) { | ||
1056 | if (reg0 & 0x00f00000) | ||
1057 | dev_priv->chipset = 0x05; | ||
1058 | else | ||
1059 | dev_priv->chipset = 0x04; | ||
1060 | dev_priv->card_type = NV_04; | ||
1061 | } | ||
1062 | |||
1063 | iounmap(dev_priv->mmio); | ||
1064 | } | ||
1065 | |||
1066 | if (!dev_priv->card_type) { | ||
1067 | NV_ERROR(dev, "unsupported chipset 0x%08x\n", reg0); | ||
1068 | ret = -EINVAL; | ||
1069 | goto err_priv; | ||
1070 | } | ||
1071 | |||
1072 | NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", | ||
1073 | dev_priv->card_type, reg0); | ||
1019 | 1074 | ||
1020 | /* map the mmio regs */ | 1075 | /* map the mmio regs */ |
1021 | mmio_start_offs = pci_resource_start(dev->pdev, 0); | 1076 | mmio_start_offs = pci_resource_start(dev->pdev, 0); |
@@ -1029,62 +1084,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) | |||
1029 | NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", | 1084 | NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", |
1030 | (unsigned long long)mmio_start_offs); | 1085 | (unsigned long long)mmio_start_offs); |
1031 | 1086 | ||
1032 | #ifdef __BIG_ENDIAN | ||
1033 | /* Put the card in BE mode if it's not */ | ||
1034 | if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001) | ||
1035 | nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001); | ||
1036 | |||
1037 | DRM_MEMORYBARRIER(); | ||
1038 | #endif | ||
1039 | |||
1040 | /* Time to determine the card architecture */ | ||
1041 | reg0 = nv_rd32(dev, NV03_PMC_BOOT_0); | ||
1042 | |||
1043 | /* We're dealing with >=NV10 */ | ||
1044 | if ((reg0 & 0x0f000000) > 0) { | ||
1045 | /* Bit 27-20 contain the architecture in hex */ | ||
1046 | dev_priv->chipset = (reg0 & 0xff00000) >> 20; | ||
1047 | /* NV04 or NV05 */ | ||
1048 | } else if ((reg0 & 0xff00fff0) == 0x20004000) { | ||
1049 | if (reg0 & 0x00f00000) | ||
1050 | dev_priv->chipset = 0x05; | ||
1051 | else | ||
1052 | dev_priv->chipset = 0x04; | ||
1053 | } else | ||
1054 | dev_priv->chipset = 0xff; | ||
1055 | |||
1056 | switch (dev_priv->chipset & 0xf0) { | ||
1057 | case 0x00: | ||
1058 | case 0x10: | ||
1059 | case 0x20: | ||
1060 | case 0x30: | ||
1061 | dev_priv->card_type = dev_priv->chipset & 0xf0; | ||
1062 | break; | ||
1063 | case 0x40: | ||
1064 | case 0x60: | ||
1065 | dev_priv->card_type = NV_40; | ||
1066 | break; | ||
1067 | case 0x50: | ||
1068 | case 0x80: | ||
1069 | case 0x90: | ||
1070 | case 0xa0: | ||
1071 | dev_priv->card_type = NV_50; | ||
1072 | break; | ||
1073 | case 0xc0: | ||
1074 | dev_priv->card_type = NV_C0; | ||
1075 | break; | ||
1076 | case 0xd0: | ||
1077 | dev_priv->card_type = NV_D0; | ||
1078 | break; | ||
1079 | default: | ||
1080 | NV_INFO(dev, "Unsupported chipset 0x%08x\n", reg0); | ||
1081 | ret = -EINVAL; | ||
1082 | goto err_mmio; | ||
1083 | } | ||
1084 | |||
1085 | NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", | ||
1086 | dev_priv->card_type, reg0); | ||
1087 | |||
1088 | /* determine frequency of timing crystal */ | 1087 | /* determine frequency of timing crystal */ |
1089 | strap = nv_rd32(dev, 0x101000); | 1088 | strap = nv_rd32(dev, 0x101000); |
1090 | if ( dev_priv->chipset < 0x17 || | 1089 | if ( dev_priv->chipset < 0x17 || |