pci.c (9095bf25ea08135a5b74875dd0e3eeaddc4218a0) | pci.c (b8b6069cf2087545fe53ec920e8353133e9a70bf) |
---|---|
1/* 2 * Sonics Silicon Backplane PCI-Hostbus related functions. 3 * 4 * Copyright (C) 2005-2006 Michael Buesch <m@bues.ch> 5 * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de> 6 * Copyright (C) 2005 Stefano Brivio <st3@riseup.net> 7 * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org> 8 * Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> 9 * 10 * Derived from the Broadcom 4400 device driver. 11 * Copyright (C) 2002 David S. Miller (davem@redhat.com) 12 * Fixed by Pekka Pietikainen (pp@ee.oulu.fi) 13 * Copyright (C) 2006 Broadcom Corporation. 14 * 15 * Licensed under the GNU/GPL. See COPYING for details. 16 */ 17 | 1/* 2 * Sonics Silicon Backplane PCI-Hostbus related functions. 3 * 4 * Copyright (C) 2005-2006 Michael Buesch <m@bues.ch> 5 * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de> 6 * Copyright (C) 2005 Stefano Brivio <st3@riseup.net> 7 * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org> 8 * Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> 9 * 10 * Derived from the Broadcom 4400 device driver. 11 * Copyright (C) 2002 David S. Miller (davem@redhat.com) 12 * Fixed by Pekka Pietikainen (pp@ee.oulu.fi) 13 * Copyright (C) 2006 Broadcom Corporation. 14 * 15 * Licensed under the GNU/GPL. See COPYING for details. 16 */ 17 |
18#include "ssb_private.h" 19 |
|
18#include <linux/ssb/ssb.h> 19#include <linux/ssb/ssb_regs.h> 20#include <linux/slab.h> 21#include <linux/pci.h> 22#include <linux/delay.h> 23 | 20#include <linux/ssb/ssb.h> 21#include <linux/ssb/ssb_regs.h> 22#include <linux/slab.h> 23#include <linux/pci.h> 24#include <linux/delay.h> 25 |
24#include "ssb_private.h" | |
25 | 26 |
26 | |
27/* Define the following to 1 to enable a printk on each coreswitch. */ 28#define SSB_VERBOSE_PCICORESWITCH_DEBUG 0 29 30 31/* Lowlevel coreswitching */ 32int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx) 33{ 34 int err; --- 16 unchanged lines hidden (view full) --- 51 break; 52 53 if (attempts++ > SSB_BAR0_MAX_RETRIES) 54 goto error; 55 udelay(10); 56 } 57 return 0; 58error: | 27/* Define the following to 1 to enable a printk on each coreswitch. */ 28#define SSB_VERBOSE_PCICORESWITCH_DEBUG 0 29 30 31/* Lowlevel coreswitching */ 32int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx) 33{ 34 int err; --- 16 unchanged lines hidden (view full) --- 51 break; 52 53 if (attempts++ > SSB_BAR0_MAX_RETRIES) 54 goto error; 55 udelay(10); 56 } 57 return 0; 58error: |
59 ssb_err("Failed to switch to core %u\n", coreidx); | 59 pr_err("Failed to switch to core %u\n", coreidx); |
60 return -ENODEV; 61} 62 63int ssb_pci_switch_core(struct ssb_bus *bus, 64 struct ssb_device *dev) 65{ 66 int err; 67 unsigned long flags; 68 69#if SSB_VERBOSE_PCICORESWITCH_DEBUG | 60 return -ENODEV; 61} 62 63int ssb_pci_switch_core(struct ssb_bus *bus, 64 struct ssb_device *dev) 65{ 66 int err; 67 unsigned long flags; 68 69#if SSB_VERBOSE_PCICORESWITCH_DEBUG |
70 ssb_info("Switching to %s core, index %d\n", 71 ssb_core_name(dev->id.coreid), 72 dev->core_index); | 70 pr_info("Switching to %s core, index %d\n", 71 ssb_core_name(dev->id.coreid), dev->core_index); |
73#endif 74 75 spin_lock_irqsave(&bus->bar_lock, flags); 76 err = ssb_pci_switch_coreidx(bus, dev->core_index); 77 if (!err) 78 bus->mapped_device = dev; 79 spin_unlock_irqrestore(&bus->bar_lock, flags); 80 --- 75 unchanged lines hidden (view full) --- 156 if (err) 157 goto err_pci; 158 } 159 160out: 161 return err; 162 163err_pci: | 72#endif 73 74 spin_lock_irqsave(&bus->bar_lock, flags); 75 err = ssb_pci_switch_coreidx(bus, dev->core_index); 76 if (!err) 77 bus->mapped_device = dev; 78 spin_unlock_irqrestore(&bus->bar_lock, flags); 79 --- 75 unchanged lines hidden (view full) --- 155 if (err) 156 goto err_pci; 157 } 158 159out: 160 return err; 161 162err_pci: |
164 printk(KERN_ERR PFX "Error: ssb_pci_xtal() could not access PCI config space!\n"); | 163 pr_err("Error: ssb_pci_xtal() could not access PCI config space!\n"); |
165 err = -EBUSY; 166 goto out; 167} 168 169/* Get the word-offset for a SSB_SPROM_XXX define. */ 170#define SPOFF(offset) ((offset) / sizeof(u16)) 171/* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */ 172#define SPEX16(_outvar, _offset, _mask, _shift) \ --- 108 unchanged lines hidden (view full) --- 281 282static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) 283{ 284 struct pci_dev *pdev = bus->host_pci; 285 int i, err; 286 u32 spromctl; 287 u16 size = bus->sprom_size; 288 | 164 err = -EBUSY; 165 goto out; 166} 167 168/* Get the word-offset for a SSB_SPROM_XXX define. */ 169#define SPOFF(offset) ((offset) / sizeof(u16)) 170/* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */ 171#define SPEX16(_outvar, _offset, _mask, _shift) \ --- 108 unchanged lines hidden (view full) --- 280 281static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) 282{ 283 struct pci_dev *pdev = bus->host_pci; 284 int i, err; 285 u32 spromctl; 286 u16 size = bus->sprom_size; 287 |
289 ssb_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n"); | 288 pr_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n"); |
290 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl); 291 if (err) 292 goto err_ctlreg; 293 spromctl |= SSB_SPROMCTL_WE; 294 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl); 295 if (err) 296 goto err_ctlreg; | 289 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl); 290 if (err) 291 goto err_ctlreg; 292 spromctl |= SSB_SPROMCTL_WE; 293 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl); 294 if (err) 295 goto err_ctlreg; |
297 ssb_notice("[ 0%%"); | 296 pr_notice("[ 0%%"); |
298 msleep(500); 299 for (i = 0; i < size; i++) { 300 if (i == size / 4) | 297 msleep(500); 298 for (i = 0; i < size; i++) { 299 if (i == size / 4) |
301 ssb_cont("25%%"); | 300 pr_cont("25%%"); |
302 else if (i == size / 2) | 301 else if (i == size / 2) |
303 ssb_cont("50%%"); | 302 pr_cont("50%%"); |
304 else if (i == (size * 3) / 4) | 303 else if (i == (size * 3) / 4) |
305 ssb_cont("75%%"); | 304 pr_cont("75%%"); |
306 else if (i % 2) | 305 else if (i % 2) |
307 ssb_cont("."); | 306 pr_cont("."); |
308 writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2)); 309 mmiowb(); 310 msleep(20); 311 } 312 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl); 313 if (err) 314 goto err_ctlreg; 315 spromctl &= ~SSB_SPROMCTL_WE; 316 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl); 317 if (err) 318 goto err_ctlreg; 319 msleep(500); | 307 writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2)); 308 mmiowb(); 309 msleep(20); 310 } 311 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl); 312 if (err) 313 goto err_ctlreg; 314 spromctl &= ~SSB_SPROMCTL_WE; 315 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl); 316 if (err) 317 goto err_ctlreg; 318 msleep(500); |
320 ssb_cont("100%% ]\n"); 321 ssb_notice("SPROM written\n"); | 319 pr_cont("100%% ]\n"); 320 pr_notice("SPROM written\n"); |
322 323 return 0; 324err_ctlreg: | 321 322 return 0; 323err_ctlreg: |
325 ssb_err("Could not access SPROM control register.\n"); | 324 pr_err("Could not access SPROM control register.\n"); |
326 return err; 327} 328 329static s8 sprom_extract_antgain(u8 sprom_revision, const u16 *in, u16 offset, 330 u16 mask, u16 shift) 331{ 332 u16 v; 333 u8 gain; --- 477 unchanged lines hidden (view full) --- 811} 812 813static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, 814 const u16 *in, u16 size) 815{ 816 memset(out, 0, sizeof(*out)); 817 818 out->revision = in[size - 1] & 0x00FF; | 325 return err; 326} 327 328static s8 sprom_extract_antgain(u8 sprom_revision, const u16 *in, u16 offset, 329 u16 mask, u16 shift) 330{ 331 u16 v; 332 u8 gain; --- 477 unchanged lines hidden (view full) --- 810} 811 812static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, 813 const u16 *in, u16 size) 814{ 815 memset(out, 0, sizeof(*out)); 816 817 out->revision = in[size - 1] & 0x00FF; |
819 ssb_dbg("SPROM revision %d detected\n", out->revision); | 818 pr_debug("SPROM revision %d detected\n", out->revision); |
820 memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */ 821 memset(out->et1mac, 0xFF, 6); 822 823 if ((bus->chip_id & 0xFF00) == 0x4400) { 824 /* Workaround: The BCM44XX chip has a stupid revision 825 * number stored in the SPROM. 826 * Always extract r1. */ 827 out->revision = 1; | 819 memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */ 820 memset(out->et1mac, 0xFF, 6); 821 822 if ((bus->chip_id & 0xFF00) == 0x4400) { 823 /* Workaround: The BCM44XX chip has a stupid revision 824 * number stored in the SPROM. 825 * Always extract r1. */ 826 out->revision = 1; |
828 ssb_dbg("SPROM treated as revision %d\n", out->revision); | 827 pr_debug("SPROM treated as revision %d\n", out->revision); |
829 } 830 831 switch (out->revision) { 832 case 1: 833 case 2: 834 case 3: 835 sprom_extract_r123(out, in); 836 break; 837 case 4: 838 case 5: 839 sprom_extract_r45(out, in); 840 break; 841 case 8: 842 sprom_extract_r8(out, in); 843 break; 844 default: | 828 } 829 830 switch (out->revision) { 831 case 1: 832 case 2: 833 case 3: 834 sprom_extract_r123(out, in); 835 break; 836 case 4: 837 case 5: 838 sprom_extract_r45(out, in); 839 break; 840 case 8: 841 sprom_extract_r8(out, in); 842 break; 843 default: |
845 ssb_warn("Unsupported SPROM revision %d detected. Will extract v1\n", 846 out->revision); | 844 pr_warn("Unsupported SPROM revision %d detected. Will extract v1\n", 845 out->revision); |
847 out->revision = 1; 848 sprom_extract_r123(out, in); 849 } 850 851 if (out->boardflags_lo == 0xFFFF) 852 out->boardflags_lo = 0; /* per specs */ 853 if (out->boardflags_hi == 0xFFFF) 854 out->boardflags_hi = 0; /* per specs */ 855 856 return 0; 857} 858 859static int ssb_pci_sprom_get(struct ssb_bus *bus, 860 struct ssb_sprom *sprom) 861{ 862 int err; 863 u16 *buf; 864 865 if (!ssb_is_sprom_available(bus)) { | 846 out->revision = 1; 847 sprom_extract_r123(out, in); 848 } 849 850 if (out->boardflags_lo == 0xFFFF) 851 out->boardflags_lo = 0; /* per specs */ 852 if (out->boardflags_hi == 0xFFFF) 853 out->boardflags_hi = 0; /* per specs */ 854 855 return 0; 856} 857 858static int ssb_pci_sprom_get(struct ssb_bus *bus, 859 struct ssb_sprom *sprom) 860{ 861 int err; 862 u16 *buf; 863 864 if (!ssb_is_sprom_available(bus)) { |
866 ssb_err("No SPROM available!\n"); | 865 pr_err("No SPROM available!\n"); |
867 return -ENODEV; 868 } 869 if (bus->chipco.dev) { /* can be unavailable! */ 870 /* 871 * get SPROM offset: SSB_SPROM_BASE1 except for 872 * chipcommon rev >= 31 or chip ID is 0x4312 and 873 * chipcommon status & 3 == 2 874 */ 875 if (bus->chipco.dev->id.revision >= 31) 876 bus->sprom_offset = SSB_SPROM_BASE31; 877 else if (bus->chip_id == 0x4312 && 878 (bus->chipco.status & 0x03) == 2) 879 bus->sprom_offset = SSB_SPROM_BASE31; 880 else 881 bus->sprom_offset = SSB_SPROM_BASE1; 882 } else { 883 bus->sprom_offset = SSB_SPROM_BASE1; 884 } | 866 return -ENODEV; 867 } 868 if (bus->chipco.dev) { /* can be unavailable! */ 869 /* 870 * get SPROM offset: SSB_SPROM_BASE1 except for 871 * chipcommon rev >= 31 or chip ID is 0x4312 and 872 * chipcommon status & 3 == 2 873 */ 874 if (bus->chipco.dev->id.revision >= 31) 875 bus->sprom_offset = SSB_SPROM_BASE31; 876 else if (bus->chip_id == 0x4312 && 877 (bus->chipco.status & 0x03) == 2) 878 bus->sprom_offset = SSB_SPROM_BASE31; 879 else 880 bus->sprom_offset = SSB_SPROM_BASE1; 881 } else { 882 bus->sprom_offset = SSB_SPROM_BASE1; 883 } |
885 ssb_dbg("SPROM offset is 0x%x\n", bus->sprom_offset); | 884 pr_debug("SPROM offset is 0x%x\n", bus->sprom_offset); |
886 887 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); 888 if (!buf) 889 return -ENOMEM; 890 bus->sprom_size = SSB_SPROMSIZE_WORDS_R123; 891 sprom_do_read(bus, buf); 892 err = sprom_check_crc(buf, bus->sprom_size); 893 if (err) { --- 8 unchanged lines hidden (view full) --- 902 err = sprom_check_crc(buf, bus->sprom_size); 903 if (err) { 904 /* All CRC attempts failed. 905 * Maybe there is no SPROM on the device? 906 * Now we ask the arch code if there is some sprom 907 * available for this device in some other storage */ 908 err = ssb_fill_sprom_with_fallback(bus, sprom); 909 if (err) { | 885 886 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); 887 if (!buf) 888 return -ENOMEM; 889 bus->sprom_size = SSB_SPROMSIZE_WORDS_R123; 890 sprom_do_read(bus, buf); 891 err = sprom_check_crc(buf, bus->sprom_size); 892 if (err) { --- 8 unchanged lines hidden (view full) --- 901 err = sprom_check_crc(buf, bus->sprom_size); 902 if (err) { 903 /* All CRC attempts failed. 904 * Maybe there is no SPROM on the device? 905 * Now we ask the arch code if there is some sprom 906 * available for this device in some other storage */ 907 err = ssb_fill_sprom_with_fallback(bus, sprom); 908 if (err) { |
910 ssb_warn("WARNING: Using fallback SPROM failed (err %d)\n", 911 err); | 909 pr_warn("WARNING: Using fallback SPROM failed (err %d)\n", 910 err); |
912 goto out_free; 913 } else { | 911 goto out_free; 912 } else { |
914 ssb_dbg("Using SPROM revision %d provided by platform\n", 915 sprom->revision); | 913 pr_debug("Using SPROM revision %d provided by platform\n", 914 sprom->revision); |
916 err = 0; 917 goto out_free; 918 } | 915 err = 0; 916 goto out_free; 917 } |
919 ssb_warn("WARNING: Invalid SPROM CRC (corrupt SPROM)\n"); | 918 pr_warn("WARNING: Invalid SPROM CRC (corrupt SPROM)\n"); |
920 } 921 } 922 err = sprom_extract(bus, sprom, buf, bus->sprom_size); 923 924out_free: 925 kfree(buf); 926 return err; 927} --- 20 unchanged lines hidden (view full) --- 948} 949 950#ifdef CONFIG_SSB_DEBUG 951static int ssb_pci_assert_buspower(struct ssb_bus *bus) 952{ 953 if (likely(bus->powered_up)) 954 return 0; 955 | 919 } 920 } 921 err = sprom_extract(bus, sprom, buf, bus->sprom_size); 922 923out_free: 924 kfree(buf); 925 return err; 926} --- 20 unchanged lines hidden (view full) --- 947} 948 949#ifdef CONFIG_SSB_DEBUG 950static int ssb_pci_assert_buspower(struct ssb_bus *bus) 951{ 952 if (likely(bus->powered_up)) 953 return 0; 954 |
956 printk(KERN_ERR PFX "FATAL ERROR: Bus powered down " 957 "while accessing PCI MMIO space\n"); | 955 pr_err("FATAL ERROR: Bus powered down while accessing PCI MMIO space\n"); |
958 if (bus->power_warn_count <= 10) { 959 bus->power_warn_count++; 960 dump_stack(); 961 } 962 963 return -ENODEV; 964} 965#else /* DEBUG */ --- 225 unchanged lines hidden --- | 956 if (bus->power_warn_count <= 10) { 957 bus->power_warn_count++; 958 dump_stack(); 959 } 960 961 return -ENODEV; 962} 963#else /* DEBUG */ --- 225 unchanged lines hidden --- |