diff options
Diffstat (limited to 'arch/x86_64/kernel/pci-calgary.c')
-rw-r--r-- | arch/x86_64/kernel/pci-calgary.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index 558e68aa6b05..68634f192de8 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c | |||
@@ -79,6 +79,9 @@ int use_calgary __read_mostly = 0; | |||
79 | #define PHB_MEM_2_SIZE_LOW 0x02E0 | 79 | #define PHB_MEM_2_SIZE_LOW 0x02E0 |
80 | #define PHB_DOSHOLE_OFFSET 0x08E0 | 80 | #define PHB_DOSHOLE_OFFSET 0x08E0 |
81 | 81 | ||
82 | /* CalIOC2 specific */ | ||
83 | #define PHB_SAVIOR_L2 0x0DB0 | ||
84 | |||
82 | /* PHB_CONFIG_RW */ | 85 | /* PHB_CONFIG_RW */ |
83 | #define PHB_TCE_ENABLE 0x20000000 | 86 | #define PHB_TCE_ENABLE 0x20000000 |
84 | #define PHB_SLOT_DISABLE 0x1C000000 | 87 | #define PHB_SLOT_DISABLE 0x1C000000 |
@@ -156,12 +159,18 @@ struct calgary_bus_info { | |||
156 | 159 | ||
157 | static void calgary_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev); | 160 | static void calgary_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev); |
158 | static void calgary_tce_cache_blast(struct iommu_table *tbl); | 161 | static void calgary_tce_cache_blast(struct iommu_table *tbl); |
162 | static void calioc2_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev); | ||
159 | 163 | ||
160 | static struct cal_chipset_ops calgary_chip_ops = { | 164 | static struct cal_chipset_ops calgary_chip_ops = { |
161 | .handle_quirks = calgary_handle_quirks, | 165 | .handle_quirks = calgary_handle_quirks, |
162 | .tce_cache_blast = calgary_tce_cache_blast | 166 | .tce_cache_blast = calgary_tce_cache_blast |
163 | }; | 167 | }; |
164 | 168 | ||
169 | static struct cal_chipset_ops calioc2_chip_ops = { | ||
170 | .handle_quirks = calioc2_handle_quirks, | ||
171 | .tce_cache_blast = NULL | ||
172 | }; | ||
173 | |||
165 | static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; | 174 | static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; |
166 | 175 | ||
167 | /* enable this to stress test the chip's TCE cache */ | 176 | /* enable this to stress test the chip's TCE cache */ |
@@ -743,7 +752,12 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar) | |||
743 | tbl->it_base = (unsigned long)bus_info[dev->bus->number].tce_space; | 752 | tbl->it_base = (unsigned long)bus_info[dev->bus->number].tce_space; |
744 | tce_free(tbl, 0, tbl->it_size); | 753 | tce_free(tbl, 0, tbl->it_size); |
745 | 754 | ||
746 | tbl->chip_ops = &calgary_chip_ops; | 755 | if (is_calgary(dev->device)) |
756 | tbl->chip_ops = &calgary_chip_ops; | ||
757 | else if (is_calioc2(dev->device)) | ||
758 | tbl->chip_ops = &calioc2_chip_ops; | ||
759 | else | ||
760 | BUG(); | ||
747 | 761 | ||
748 | calgary_reserve_regions(dev); | 762 | calgary_reserve_regions(dev); |
749 | 763 | ||
@@ -894,8 +908,23 @@ static void __init calgary_set_split_completion_timeout(void __iomem *bbar, | |||
894 | readq(target); /* flush */ | 908 | readq(target); /* flush */ |
895 | } | 909 | } |
896 | 910 | ||
897 | static void __init calgary_handle_quirks(struct iommu_table *tbl, | 911 | static void calioc2_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev) |
898 | struct pci_dev *dev) | 912 | { |
913 | unsigned char busnum = dev->bus->number; | ||
914 | void __iomem *bbar = tbl->bbar; | ||
915 | void __iomem *target; | ||
916 | u32 val; | ||
917 | |||
918 | /* | ||
919 | * CalIOC2 designers recommend setting bit 8 in 0xnDB0 to 1 | ||
920 | */ | ||
921 | target = calgary_reg(bbar, phb_offset(busnum) | PHB_SAVIOR_L2); | ||
922 | val = cpu_to_be32(readl(target)); | ||
923 | val |= 0x00800000; | ||
924 | writel(cpu_to_be32(val), target); | ||
925 | } | ||
926 | |||
927 | static void calgary_handle_quirks(struct iommu_table *tbl, struct pci_dev *dev) | ||
899 | { | 928 | { |
900 | unsigned char busnum = dev->bus->number; | 929 | unsigned char busnum = dev->bus->number; |
901 | 930 | ||
@@ -903,7 +932,7 @@ static void __init calgary_handle_quirks(struct iommu_table *tbl, | |||
903 | * Give split completion a longer timeout on bus 1 for aic94xx | 932 | * Give split completion a longer timeout on bus 1 for aic94xx |
904 | * http://bugzilla.kernel.org/show_bug.cgi?id=7180 | 933 | * http://bugzilla.kernel.org/show_bug.cgi?id=7180 |
905 | */ | 934 | */ |
906 | if (busnum == 1) | 935 | if (is_calgary(dev->device) && (busnum == 1)) |
907 | calgary_set_split_completion_timeout(tbl->bbar, busnum, | 936 | calgary_set_split_completion_timeout(tbl->bbar, busnum, |
908 | CCR_2SEC_TIMEOUT); | 937 | CCR_2SEC_TIMEOUT); |
909 | } | 938 | } |