416-BCM63XX-add-a-fixup-for-ath9k-devices.patch 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. From bbebbf735a02b6d044ed928978ab4bd5f1833364 Mon Sep 17 00:00:00 2001
  2. From: Jonas Gorski <jonas.gorski@gmail.com>
  3. Date: Thu, 3 May 2012 14:36:11 +0200
  4. Subject: [PATCH 61/72] BCM63XX: add a fixup for ath9k devices
  5. ---
  6. arch/mips/bcm63xx/Makefile | 3 +-
  7. arch/mips/bcm63xx/pci-ath9k-fixup.c | 190 ++++++++++++++++++++
  8. .../include/asm/mach-bcm63xx/pci_ath9k_fixup.h | 7 +
  9. 3 files changed, 199 insertions(+), 1 deletion(-)
  10. create mode 100644 arch/mips/bcm63xx/pci-ath9k-fixup.c
  11. create mode 100644 arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h
  12. --- a/arch/mips/bcm63xx/Makefile
  13. +++ b/arch/mips/bcm63xx/Makefile
  14. @@ -2,7 +2,7 @@ obj-y += clk.o cpu.o cs.o gpio.o irq.o
  15. setup.o timer.o dev-dsp.o dev-enet.o dev-flash.o \
  16. dev-pcmcia.o dev-rng.o dev-spi.o dev-hsspi.o dev-uart.o \
  17. dev-wdt.o dev-usb-ehci.o dev-usb-ohci.o dev-usb-usbd.o \
  18. - usb-common.o sprom.o
  19. + pci-ath9k-fixup.o usb-common.o sprom.o
  20. obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
  21. obj-y += boards/
  22. --- /dev/null
  23. +++ b/arch/mips/bcm63xx/pci-ath9k-fixup.c
  24. @@ -0,0 +1,199 @@
  25. +/*
  26. + * Broadcom BCM63XX Ath9k EEPROM fixup helper.
  27. + *
  28. + * Copytight (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
  29. + *
  30. + * Based on
  31. + *
  32. + * Atheros AP94 reference board PCI initialization
  33. + *
  34. + * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
  35. + *
  36. + * This program is free software; you can redistribute it and/or modify it
  37. + * under the terms of the GNU General Public License version 2 as published
  38. + * by the Free Software Foundation.
  39. + */
  40. +
  41. +#include <linux/pci.h>
  42. +#include <linux/delay.h>
  43. +#include <linux/ath9k_platform.h>
  44. +
  45. +#include <bcm63xx_cpu.h>
  46. +#include <bcm63xx_io.h>
  47. +#include <bcm63xx_nvram.h>
  48. +#include <bcm63xx_dev_pci.h>
  49. +#include <bcm63xx_dev_flash.h>
  50. +#include <bcm63xx_dev_hsspi.h>
  51. +#include <pci_ath9k_fixup.h>
  52. +
  53. +#define bcm_hsspi_writel(v, o) bcm_rset_writel(RSET_HSSPI, (v), (o))
  54. +
  55. +struct ath9k_fixup {
  56. + unsigned slot;
  57. + u8 mac[ETH_ALEN];
  58. + struct ath9k_platform_data pdata;
  59. +};
  60. +
  61. +static int ath9k_num_fixups;
  62. +static struct ath9k_fixup ath9k_fixups[2] = {
  63. + {
  64. + .slot = 255,
  65. + .pdata = {
  66. + .led_pin = -1,
  67. + },
  68. + },
  69. + {
  70. + .slot = 255,
  71. + .pdata = {
  72. + .led_pin = -1,
  73. + },
  74. + },
  75. +};
  76. +
  77. +static u16 *bcm63xx_read_eeprom(u16 *eeprom, u32 offset)
  78. +{
  79. + u32 addr;
  80. +
  81. + if (BCMCPU_IS_6328()) {
  82. + addr = 0x18000000;
  83. + } else {
  84. + addr = bcm_mpi_readl(MPI_CSBASE_REG(0));
  85. + addr &= MPI_CSBASE_BASE_MASK;
  86. + }
  87. +
  88. + switch (bcm63xx_flash_get_type()) {
  89. + case BCM63XX_FLASH_TYPE_PARALLEL:
  90. + memcpy(eeprom, (void *)KSEG1ADDR(addr + offset), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16));
  91. + return eeprom;
  92. + case BCM63XX_FLASH_TYPE_SERIAL:
  93. + /* the first megabyte is memory mapped */
  94. + if (offset < 0x100000) {
  95. + memcpy(eeprom, (void *)KSEG1ADDR(addr + offset), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16));
  96. + return eeprom;
  97. + }
  98. +
  99. + if (BCMCPU_IS_6328()) {
  100. + /* we can change the memory mapped megabyte */
  101. + bcm_hsspi_writel(offset & 0xf00000, 0x18);
  102. + memcpy(eeprom, (void *)KSEG1ADDR(addr + (offset & 0xfffff)), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16));
  103. + bcm_hsspi_writel(0, 0x18);
  104. + return eeprom;
  105. + }
  106. + /* can't do anything here without talking to the SPI controller. */
  107. + case BCM63XX_FLASH_TYPE_NAND:
  108. + default:
  109. + return NULL;
  110. + }
  111. +}
  112. +
  113. +static void ath9k_pci_fixup(struct pci_dev *dev)
  114. +{
  115. + void __iomem *mem;
  116. + struct ath9k_platform_data *pdata = NULL;
  117. + struct pci_dev *bridge = pci_upstream_bridge(dev);
  118. + u16 *cal_data = NULL;
  119. + u16 cmd;
  120. + u32 bar0;
  121. + u32 val;
  122. + unsigned i;
  123. +
  124. + for (i = 0; i < ath9k_num_fixups; i++) {
  125. + if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn))
  126. + continue;
  127. +
  128. + cal_data = ath9k_fixups[i].pdata.eeprom_data;
  129. + pdata = &ath9k_fixups[i].pdata;
  130. + break;
  131. + }
  132. +
  133. + if (cal_data == NULL)
  134. + return;
  135. +
  136. + if (*cal_data != 0xa55a) {
  137. + pr_err("pci %s: invalid calibration data\n", pci_name(dev));
  138. + return;
  139. + }
  140. +
  141. + pr_info("pci %s: fixup device configuration\n", pci_name(dev));
  142. +
  143. + switch (bcm63xx_get_cpu_id()) {
  144. + case BCM6328_CPU_ID:
  145. + val = BCM_PCIE_MEM_BASE_PA_6328;
  146. + break;
  147. + case BCM6348_CPU_ID:
  148. + case BCM6358_CPU_ID:
  149. + case BCM6368_CPU_ID:
  150. + val = BCM_PCI_MEM_BASE_PA;
  151. + break;
  152. + default:
  153. + BUG();
  154. + }
  155. +
  156. + mem = ioremap(val, 0x10000);
  157. + if (!mem) {
  158. + pr_err("pci %s: ioremap error\n", pci_name(dev));
  159. + return;
  160. + }
  161. +
  162. + if (bridge)
  163. + pci_enable_device(bridge);
  164. +
  165. + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
  166. + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0);
  167. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, val);
  168. +
  169. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  170. + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
  171. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  172. +
  173. + /* set offset to first reg address */
  174. + cal_data += 3;
  175. + while(*cal_data != 0xffff) {
  176. + u32 reg;
  177. + reg = *cal_data++;
  178. + val = *cal_data++;
  179. + val |= (*cal_data++) << 16;
  180. +
  181. + writel(val, mem + reg);
  182. + udelay(100);
  183. + }
  184. +
  185. + pci_read_config_dword(dev, PCI_VENDOR_ID, &val);
  186. + dev->vendor = val & 0xffff;
  187. + dev->device = (val >> 16) & 0xffff;
  188. +
  189. + pci_read_config_dword(dev, PCI_CLASS_REVISION, &val);
  190. + dev->revision = val & 0xff;
  191. + dev->class = val >> 8; /* upper 3 bytes */
  192. +
  193. + pci_read_config_word(dev, PCI_COMMAND, &cmd);
  194. + cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
  195. + pci_write_config_word(dev, PCI_COMMAND, cmd);
  196. +
  197. + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0);
  198. +
  199. + if (bridge)
  200. + pci_disable_device(bridge);
  201. +
  202. + iounmap(mem);
  203. +
  204. + dev->dev.platform_data = pdata;
  205. +}
  206. +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup);
  207. +
  208. +void __init pci_enable_ath9k_fixup(unsigned slot, u32 offset)
  209. +{
  210. + if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups))
  211. + return;
  212. +
  213. + ath9k_fixups[ath9k_num_fixups].slot = slot;
  214. +
  215. + if (!bcm63xx_read_eeprom(ath9k_fixups[ath9k_num_fixups].pdata.eeprom_data, offset))
  216. + return;
  217. +
  218. + if (bcm63xx_nvram_get_mac_address(ath9k_fixups[ath9k_num_fixups].mac))
  219. + return;
  220. +
  221. + ath9k_fixups[ath9k_num_fixups].pdata.macaddr = ath9k_fixups[ath9k_num_fixups].mac;
  222. + ath9k_num_fixups++;
  223. +}
  224. --- /dev/null
  225. +++ b/arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h
  226. @@ -0,0 +1,7 @@
  227. +#ifndef _PCI_ATH9K_FIXUP
  228. +#define _PCI_ATH9K_FIXUP
  229. +
  230. +
  231. +void pci_enable_ath9k_fixup(unsigned slot, u32 offset) __init;
  232. +
  233. +#endif /* _PCI_ATH9K_FIXUP */