aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-03-12 01:55:43 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-03-13 03:15:07 -0400
commit2f5394c3ed573de2ab18cdac503b8045cd16ac5e (patch)
tree012cc19b8f0052f452097a633e8fde9224d405b6 /drivers/gpu
parent4cbb0f8d2b06c72aae3552ff1a0a57814c6ce7d2 (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.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c121
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
697enum nouveau_card_type { 697enum 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
708struct drm_nouveau_private { 708struct 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)
993int nouveau_load(struct drm_device *dev, unsigned long flags) 993int 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 ||