OpenWrt – Blame information for rev 2
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * Atheros AP94 reference board PCI initialization |
||
3 | * |
||
4 | * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org> |
||
5 | * |
||
6 | * This program is free software; you can redistribute it and/or modify it |
||
7 | * under the terms of the GNU General Public License version 2 as published |
||
8 | * by the Free Software Foundation. |
||
9 | */ |
||
10 | |||
11 | #include <linux/pci.h> |
||
12 | #include <linux/delay.h> |
||
13 | |||
14 | #include <asm/mach-ath79/ar71xx_regs.h> |
||
15 | #include <asm/mach-ath79/ath79.h> |
||
16 | |||
17 | struct ath9k_fixup { |
||
18 | u16 *cal_data; |
||
19 | unsigned slot; |
||
20 | }; |
||
21 | |||
22 | static int ath9k_num_fixups; |
||
23 | static struct ath9k_fixup ath9k_fixups[2]; |
||
24 | |||
25 | static void ath9k_pci_fixup(struct pci_dev *dev) |
||
26 | { |
||
27 | void __iomem *mem; |
||
28 | u16 *cal_data = NULL; |
||
29 | u16 cmd; |
||
30 | u32 bar0; |
||
31 | u32 val; |
||
32 | unsigned i; |
||
33 | |||
34 | for (i = 0; i < ath9k_num_fixups; i++) { |
||
35 | if (ath9k_fixups[i].cal_data == NULL) |
||
36 | continue; |
||
37 | |||
38 | if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn)) |
||
39 | continue; |
||
40 | |||
41 | cal_data = ath9k_fixups[i].cal_data; |
||
42 | break; |
||
43 | } |
||
44 | |||
45 | if (cal_data == NULL) |
||
46 | return; |
||
47 | |||
48 | if (*cal_data != 0xa55a) { |
||
49 | pr_err("pci %s: invalid calibration data\n", pci_name(dev)); |
||
50 | return; |
||
51 | } |
||
52 | |||
53 | pr_info("pci %s: fixup device configuration\n", pci_name(dev)); |
||
54 | |||
55 | mem = ioremap(AR71XX_PCI_MEM_BASE, 0x10000); |
||
56 | if (!mem) { |
||
57 | pr_err("pci %s: ioremap error\n", pci_name(dev)); |
||
58 | return; |
||
59 | } |
||
60 | |||
61 | pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); |
||
62 | |||
63 | switch (ath79_soc) { |
||
64 | case ATH79_SOC_AR7161: |
||
65 | pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, |
||
66 | AR71XX_PCI_MEM_BASE); |
||
67 | break; |
||
68 | case ATH79_SOC_AR7240: |
||
69 | pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0xffff); |
||
70 | break; |
||
71 | |||
72 | case ATH79_SOC_AR7241: |
||
73 | case ATH79_SOC_AR7242: |
||
74 | pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff); |
||
75 | break; |
||
76 | case ATH79_SOC_AR9344: |
||
77 | pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0x1000ffff); |
||
78 | break; |
||
79 | |||
80 | default: |
||
81 | BUG(); |
||
82 | } |
||
83 | |||
84 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
||
85 | cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; |
||
86 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
||
87 | |||
88 | /* set pointer to first reg address */ |
||
89 | cal_data += 3; |
||
90 | while (*cal_data != 0xffff) { |
||
91 | u32 reg; |
||
92 | reg = *cal_data++; |
||
93 | val = *cal_data++; |
||
94 | val |= (*cal_data++) << 16; |
||
95 | |||
96 | __raw_writel(val, mem + reg); |
||
97 | udelay(100); |
||
98 | } |
||
99 | |||
100 | pci_read_config_dword(dev, PCI_VENDOR_ID, &val); |
||
101 | dev->vendor = val & 0xffff; |
||
102 | dev->device = (val >> 16) & 0xffff; |
||
103 | |||
104 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); |
||
105 | dev->revision = val & 0xff; |
||
106 | dev->class = val >> 8; /* upper 3 bytes */ |
||
107 | |||
108 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
||
109 | cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); |
||
110 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
||
111 | |||
112 | pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); |
||
113 | |||
114 | iounmap(mem); |
||
115 | } |
||
116 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup); |
||
117 | |||
118 | void __init pci_enable_ath9k_fixup(unsigned slot, u16 *cal_data) |
||
119 | { |
||
120 | if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups)) |
||
121 | return; |
||
122 | |||
123 | ath9k_fixups[ath9k_num_fixups].slot = slot; |
||
124 | ath9k_fixups[ath9k_num_fixups].cal_data = cal_data; |
||
125 | ath9k_num_fixups++; |
||
126 | } |