2 * Atheros AP94 reference board PCI initialization
4 * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
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.
11 #include <linux/pci.h>
12 #include <linux/ath9k_platform.h>
13 #include <linux/delay.h>
15 #include <asm/mach-ar71xx/ar71xx.h>
16 #include <asm/mach-ar71xx/pci.h>
18 #include "dev-ap94-pci.h"
20 static struct ath9k_platform_data ap94_wmac0_data
;
21 static struct ath9k_platform_data ap94_wmac1_data
;
22 static char ap94_wmac0_mac
[6];
23 static char ap94_wmac1_mac
[6];
24 static int ap94_pci_fixup_enabled
;
26 static struct ar71xx_pci_irq ap94_pci_irqs
[] __initdata
= {
30 .irq
= AR71XX_PCI_IRQ_DEV0
,
34 .irq
= AR71XX_PCI_IRQ_DEV1
,
38 static int ap94_pci_plat_dev_init(struct pci_dev
*dev
)
40 switch(PCI_SLOT(dev
->devfn
)) {
42 dev
->dev
.platform_data
= &ap94_wmac0_data
;
46 dev
->dev
.platform_data
= &ap94_wmac1_data
;
53 static void ap94_pci_fixup(struct pci_dev
*dev
)
61 if (!ap94_pci_fixup_enabled
)
64 switch (PCI_SLOT(dev
->devfn
)) {
66 cal_data
= ap94_wmac0_data
.eeprom_data
;
69 cal_data
= ap94_wmac1_data
.eeprom_data
;
75 if (*cal_data
!= 0xa55a) {
76 printk(KERN_ERR
"PCI: no calibration data found for %s\n",
81 mem
= ioremap(AR71XX_PCI_MEM_BASE
, 0x10000);
83 printk(KERN_ERR
"PCI: ioremap error for device %s\n",
88 printk(KERN_INFO
"PCI: fixup device %s\n", pci_name(dev
));
90 pci_read_config_dword(dev
, PCI_BASE_ADDRESS_0
, &bar0
);
92 /* Setup the PCI device to allow access to the internal registers */
93 pci_write_config_dword(dev
, PCI_BASE_ADDRESS_0
, AR71XX_PCI_MEM_BASE
);
94 pci_read_config_word(dev
, PCI_COMMAND
, &cmd
);
95 cmd
|= PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
;
96 pci_write_config_word(dev
, PCI_COMMAND
, cmd
);
98 /* set pointer to first reg address */
100 while (*cal_data
!= 0xffff) {
104 val
|= (*cal_data
++) << 16;
106 __raw_writel(val
, mem
+ reg
);
110 pci_read_config_dword(dev
, PCI_VENDOR_ID
, &val
);
111 dev
->vendor
= val
& 0xffff;
112 dev
->device
= (val
>> 16) & 0xffff;
114 pci_read_config_dword(dev
, PCI_CLASS_REVISION
, &val
);
115 dev
->revision
= val
& 0xff;
116 dev
->class = val
>> 8; /* upper 3 bytes */
118 pci_read_config_word(dev
, PCI_COMMAND
, &cmd
);
119 cmd
&= ~(PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
);
120 pci_write_config_word(dev
, PCI_COMMAND
, cmd
);
122 pci_write_config_dword(dev
, PCI_BASE_ADDRESS_0
, bar0
);
126 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS
, PCI_ANY_ID
, ap94_pci_fixup
);
128 void __init
ap94_pci_enable_quirk_wndr3700(void)
130 ap94_wmac0_data
.quirk_wndr3700
= 1;
131 ap94_wmac1_data
.quirk_wndr3700
= 1;
134 void __init
ap94_pci_init(u8
*cal_data0
, u8
*mac_addr0
,
135 u8
*cal_data1
, u8
*mac_addr1
)
138 memcpy(ap94_wmac0_data
.eeprom_data
, cal_data0
,
139 sizeof(ap94_wmac0_data
.eeprom_data
));
142 memcpy(ap94_wmac1_data
.eeprom_data
, cal_data1
,
143 sizeof(ap94_wmac1_data
.eeprom_data
));
146 memcpy(ap94_wmac0_mac
, mac_addr0
, sizeof(ap94_wmac0_mac
));
147 ap94_wmac0_data
.macaddr
= ap94_wmac0_mac
;
151 memcpy(ap94_wmac1_mac
, mac_addr1
, sizeof(ap94_wmac1_mac
));
152 ap94_wmac1_data
.macaddr
= ap94_wmac1_mac
;
155 ar71xx_pci_plat_dev_init
= ap94_pci_plat_dev_init
;
156 ar71xx_pci_init(ARRAY_SIZE(ap94_pci_irqs
), ap94_pci_irqs
);
158 ap94_pci_fixup_enabled
= 1;