diff options
Diffstat (limited to 'arch/x86_64/kernel/pci-calgary.c')
-rw-r--r-- | arch/x86_64/kernel/pci-calgary.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index b3296cc2f2f2..37a770859e71 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c | |||
@@ -52,7 +52,8 @@ | |||
52 | #define ONE_BASED_CHASSIS_NUM 1 | 52 | #define ONE_BASED_CHASSIS_NUM 1 |
53 | 53 | ||
54 | /* register offsets inside the host bridge space */ | 54 | /* register offsets inside the host bridge space */ |
55 | #define PHB_CSR_OFFSET 0x0110 | 55 | #define CALGARY_CONFIG_REG 0x0108 |
56 | #define PHB_CSR_OFFSET 0x0110 /* Channel Status */ | ||
56 | #define PHB_PLSSR_OFFSET 0x0120 | 57 | #define PHB_PLSSR_OFFSET 0x0120 |
57 | #define PHB_CONFIG_RW_OFFSET 0x0160 | 58 | #define PHB_CONFIG_RW_OFFSET 0x0160 |
58 | #define PHB_IOBASE_BAR_LOW 0x0170 | 59 | #define PHB_IOBASE_BAR_LOW 0x0170 |
@@ -83,6 +84,8 @@ | |||
83 | #define TAR_VALID 0x0000000000000008UL | 84 | #define TAR_VALID 0x0000000000000008UL |
84 | /* CSR (Channel/DMA Status Register) */ | 85 | /* CSR (Channel/DMA Status Register) */ |
85 | #define CSR_AGENT_MASK 0xffe0ffff | 86 | #define CSR_AGENT_MASK 0xffe0ffff |
87 | /* CCR (Calgary Configuration Register) */ | ||
88 | #define CCR_2SEC_TIMEOUT 0x000000000000000EUL | ||
86 | 89 | ||
87 | #define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ | 90 | #define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ |
88 | #define MAX_NUM_CHASSIS 8 /* max number of chassis */ | 91 | #define MAX_NUM_CHASSIS 8 /* max number of chassis */ |
@@ -732,6 +735,38 @@ static void calgary_watchdog(unsigned long data) | |||
732 | } | 735 | } |
733 | } | 736 | } |
734 | 737 | ||
738 | static void __init calgary_increase_split_completion_timeout(void __iomem *bbar, | ||
739 | unsigned char busnum) | ||
740 | { | ||
741 | u64 val64; | ||
742 | void __iomem *target; | ||
743 | unsigned long phb_shift = -1; | ||
744 | u64 mask; | ||
745 | |||
746 | switch (busno_to_phbid(busnum)) { | ||
747 | case 0: phb_shift = (63 - 19); | ||
748 | break; | ||
749 | case 1: phb_shift = (63 - 23); | ||
750 | break; | ||
751 | case 2: phb_shift = (63 - 27); | ||
752 | break; | ||
753 | case 3: phb_shift = (63 - 35); | ||
754 | break; | ||
755 | default: | ||
756 | BUG_ON(busno_to_phbid(busnum)); | ||
757 | } | ||
758 | |||
759 | target = calgary_reg(bbar, CALGARY_CONFIG_REG); | ||
760 | val64 = be64_to_cpu(readq(target)); | ||
761 | |||
762 | /* zero out this PHB's timer bits */ | ||
763 | mask = ~(0xFUL << phb_shift); | ||
764 | val64 &= mask; | ||
765 | val64 |= (CCR_2SEC_TIMEOUT << phb_shift); | ||
766 | writeq(cpu_to_be64(val64), target); | ||
767 | readq(target); /* flush */ | ||
768 | } | ||
769 | |||
735 | static void __init calgary_enable_translation(struct pci_dev *dev) | 770 | static void __init calgary_enable_translation(struct pci_dev *dev) |
736 | { | 771 | { |
737 | u32 val32; | 772 | u32 val32; |
@@ -756,6 +791,13 @@ static void __init calgary_enable_translation(struct pci_dev *dev) | |||
756 | writel(cpu_to_be32(val32), target); | 791 | writel(cpu_to_be32(val32), target); |
757 | readl(target); /* flush */ | 792 | readl(target); /* flush */ |
758 | 793 | ||
794 | /* | ||
795 | * Give split completion a longer timeout on bus 1 for aic94xx | ||
796 | * http://bugzilla.kernel.org/show_bug.cgi?id=7180 | ||
797 | */ | ||
798 | if (busnum == 1) | ||
799 | calgary_increase_split_completion_timeout(bbar, busnum); | ||
800 | |||
759 | init_timer(&tbl->watchdog_timer); | 801 | init_timer(&tbl->watchdog_timer); |
760 | tbl->watchdog_timer.function = &calgary_watchdog; | 802 | tbl->watchdog_timer.function = &calgary_watchdog; |
761 | tbl->watchdog_timer.data = (unsigned long)dev; | 803 | tbl->watchdog_timer.data = (unsigned long)dev; |