| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 |
- --- a/drivers/ssb/Kconfig
- +++ b/drivers/ssb/Kconfig
- @@ -136,6 +136,11 @@ config SSB_DRIVER_MIPS
-
- If unsure, say N
-
- +config SSB_SFLASH
- + bool "SSB serial flash support"
- + depends on SSB_DRIVER_MIPS && BROKEN
- + default y
- +
- # Assumption: We are on embedded, if we compile the MIPS core.
- config SSB_EMBEDDED
- bool
- --- a/drivers/ssb/Makefile
- +++ b/drivers/ssb/Makefile
- @@ -11,6 +11,7 @@ ssb-$(CONFIG_SSB_SDIOHOST) += sdio.o
- # built-in drivers
- ssb-y += driver_chipcommon.o
- ssb-y += driver_chipcommon_pmu.o
- +ssb-$(CONFIG_SSB_SFLASH) += driver_chipcommon_sflash.o
- ssb-$(CONFIG_SSB_DRIVER_MIPS) += driver_mipscore.o
- ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o
- ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o
- --- /dev/null
- +++ b/drivers/ssb/driver_chipcommon_sflash.c
- @@ -0,0 +1,140 @@
- +/*
- + * Sonics Silicon Backplane
- + * ChipCommon serial flash interface
- + *
- + * Licensed under the GNU/GPL. See COPYING for details.
- + */
- +
- +#include <linux/ssb/ssb.h>
- +
- +#include "ssb_private.h"
- +
- +struct ssb_sflash_tbl_e {
- + char *name;
- + u32 id;
- + u32 blocksize;
- + u16 numblocks;
- +};
- +
- +static struct ssb_sflash_tbl_e ssb_sflash_st_tbl[] = {
- + { "M25P20", 0x11, 0x10000, 4, },
- + { "M25P40", 0x12, 0x10000, 8, },
- +
- + { "M25P16", 0x14, 0x10000, 32, },
- + { "M25P32", 0x15, 0x10000, 64, },
- + { "M25P64", 0x16, 0x10000, 128, },
- + { "M25FL128", 0x17, 0x10000, 256, },
- + { 0 },
- +};
- +
- +static struct ssb_sflash_tbl_e ssb_sflash_sst_tbl[] = {
- + { "SST25WF512", 1, 0x1000, 16, },
- + { "SST25VF512", 0x48, 0x1000, 16, },
- + { "SST25WF010", 2, 0x1000, 32, },
- + { "SST25VF010", 0x49, 0x1000, 32, },
- + { "SST25WF020", 3, 0x1000, 64, },
- + { "SST25VF020", 0x43, 0x1000, 64, },
- + { "SST25WF040", 4, 0x1000, 128, },
- + { "SST25VF040", 0x44, 0x1000, 128, },
- + { "SST25VF040B", 0x8d, 0x1000, 128, },
- + { "SST25WF080", 5, 0x1000, 256, },
- + { "SST25VF080B", 0x8e, 0x1000, 256, },
- + { "SST25VF016", 0x41, 0x1000, 512, },
- + { "SST25VF032", 0x4a, 0x1000, 1024, },
- + { "SST25VF064", 0x4b, 0x1000, 2048, },
- + { 0 },
- +};
- +
- +static struct ssb_sflash_tbl_e ssb_sflash_at_tbl[] = {
- + { "AT45DB011", 0xc, 256, 512, },
- + { "AT45DB021", 0x14, 256, 1024, },
- + { "AT45DB041", 0x1c, 256, 2048, },
- + { "AT45DB081", 0x24, 256, 4096, },
- + { "AT45DB161", 0x2c, 512, 4096, },
- + { "AT45DB321", 0x34, 512, 8192, },
- + { "AT45DB642", 0x3c, 1024, 8192, },
- + { 0 },
- +};
- +
- +static void ssb_sflash_cmd(struct ssb_chipcommon *cc, u32 opcode)
- +{
- + int i;
- + chipco_write32(cc, SSB_CHIPCO_FLASHCTL,
- + SSB_CHIPCO_FLASHCTL_START | opcode);
- + for (i = 0; i < 1000; i++) {
- + if (!(chipco_read32(cc, SSB_CHIPCO_FLASHCTL) &
- + SSB_CHIPCO_FLASHCTL_BUSY))
- + return;
- + cpu_relax();
- + }
- + pr_err("SFLASH control command failed (timeout)!\n");
- +}
- +
- +/* Initialize serial flash access */
- +int ssb_sflash_init(struct ssb_chipcommon *cc)
- +{
- + struct ssb_sflash_tbl_e *e;
- + u32 id, id2;
- +
- + switch (cc->capabilities & SSB_CHIPCO_CAP_FLASHT) {
- + case SSB_CHIPCO_FLASHT_STSER:
- + ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_DP);
- +
- + chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 0);
- + ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES);
- + id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA);
- +
- + chipco_write32(cc, SSB_CHIPCO_FLASHADDR, 1);
- + ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_ST_RES);
- + id2 = chipco_read32(cc, SSB_CHIPCO_FLASHDATA);
- +
- + switch (id) {
- + case 0xbf:
- + for (e = ssb_sflash_sst_tbl; e->name; e++) {
- + if (e->id == id2)
- + break;
- + }
- + break;
- + case 0x13:
- + return -ENOTSUPP;
- + default:
- + for (e = ssb_sflash_st_tbl; e->name; e++) {
- + if (e->id == id)
- + break;
- + }
- + break;
- + }
- + if (!e->name) {
- + pr_err("Unsupported ST serial flash (id: 0x%X, id2: 0x%X)\n",
- + id, id2);
- + return -ENOTSUPP;
- + }
- +
- + break;
- + case SSB_CHIPCO_FLASHT_ATSER:
- + ssb_sflash_cmd(cc, SSB_CHIPCO_FLASHCTL_AT_STATUS);
- + id = chipco_read32(cc, SSB_CHIPCO_FLASHDATA) & 0x3c;
- +
- + for (e = ssb_sflash_at_tbl; e->name; e++) {
- + if (e->id == id)
- + break;
- + }
- + if (!e->name) {
- + pr_err("Unsupported Atmel serial flash (id: 0x%X)\n",
- + id);
- + return -ENOTSUPP;
- + }
- +
- + break;
- + default:
- + pr_err("Unsupported flash type\n");
- + return -ENOTSUPP;
- + }
- +
- + pr_info("Found %s serial flash (blocksize: 0x%X, blocks: %d)\n",
- + e->name, e->blocksize, e->numblocks);
- +
- + pr_err("Serial flash support is not implemented yet!\n");
- +
- + return -ENOTSUPP;
- +}
- --- a/drivers/ssb/driver_gpio.c
- +++ b/drivers/ssb/driver_gpio.c
- @@ -74,6 +74,16 @@ static void ssb_gpio_chipco_free(struct
- ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0);
- }
-
- +static int ssb_gpio_chipco_to_irq(struct gpio_chip *chip, unsigned gpio)
- +{
- + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
- +
- + if (bus->bustype == SSB_BUSTYPE_SSB)
- + return ssb_mips_irq(bus->chipco.dev) + 2;
- + else
- + return -EINVAL;
- +}
- +
- static int ssb_gpio_chipco_init(struct ssb_bus *bus)
- {
- struct gpio_chip *chip = &bus->gpio;
- @@ -86,6 +96,7 @@ static int ssb_gpio_chipco_init(struct s
- chip->set = ssb_gpio_chipco_set_value;
- chip->direction_input = ssb_gpio_chipco_direction_input;
- chip->direction_output = ssb_gpio_chipco_direction_output;
- + chip->to_irq = ssb_gpio_chipco_to_irq;
- chip->ngpio = 16;
- /* There is just one SoC in one device and its GPIO addresses should be
- * deterministic to address them more easily. The other buses could get
- @@ -134,6 +145,16 @@ static int ssb_gpio_extif_direction_outp
- return 0;
- }
-
- +static int ssb_gpio_extif_to_irq(struct gpio_chip *chip, unsigned gpio)
- +{
- + struct ssb_bus *bus = ssb_gpio_get_bus(chip);
- +
- + if (bus->bustype == SSB_BUSTYPE_SSB)
- + return ssb_mips_irq(bus->extif.dev) + 2;
- + else
- + return -EINVAL;
- +}
- +
- static int ssb_gpio_extif_init(struct ssb_bus *bus)
- {
- struct gpio_chip *chip = &bus->gpio;
- @@ -144,6 +165,7 @@ static int ssb_gpio_extif_init(struct ss
- chip->set = ssb_gpio_extif_set_value;
- chip->direction_input = ssb_gpio_extif_direction_input;
- chip->direction_output = ssb_gpio_extif_direction_output;
- + chip->to_irq = ssb_gpio_extif_to_irq;
- chip->ngpio = 5;
- /* There is just one SoC in one device and its GPIO addresses should be
- * deterministic to address them more easily. The other buses could get
- --- a/drivers/ssb/driver_mipscore.c
- +++ b/drivers/ssb/driver_mipscore.c
- @@ -10,6 +10,7 @@
-
- #include <linux/ssb/ssb.h>
-
- +#include <linux/mtd/physmap.h>
- #include <linux/serial.h>
- #include <linux/serial_core.h>
- #include <linux/serial_reg.h>
- @@ -17,6 +18,25 @@
-
- #include "ssb_private.h"
-
- +static const char *part_probes[] = { "bcm47xxpart", NULL };
- +
- +static struct physmap_flash_data ssb_pflash_data = {
- + .part_probe_types = part_probes,
- +};
- +
- +static struct resource ssb_pflash_resource = {
- + .name = "ssb_pflash",
- + .flags = IORESOURCE_MEM,
- +};
- +
- +struct platform_device ssb_pflash_dev = {
- + .name = "physmap-flash",
- + .dev = {
- + .platform_data = &ssb_pflash_data,
- + },
- + .resource = &ssb_pflash_resource,
- + .num_resources = 1,
- +};
-
- static inline u32 mips_read32(struct ssb_mipscore *mcore,
- u16 offset)
- @@ -189,34 +209,43 @@ static void ssb_mips_serial_init(struct
- static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
- {
- struct ssb_bus *bus = mcore->dev->bus;
- + struct ssb_pflash *pflash = &mcore->pflash;
-
- /* When there is no chipcommon on the bus there is 4MB flash */
- if (!ssb_chipco_available(&bus->chipco)) {
- - mcore->pflash.present = true;
- - mcore->pflash.buswidth = 2;
- - mcore->pflash.window = SSB_FLASH1;
- - mcore->pflash.window_size = SSB_FLASH1_SZ;
- - return;
- + pflash->present = true;
- + pflash->buswidth = 2;
- + pflash->window = SSB_FLASH1;
- + pflash->window_size = SSB_FLASH1_SZ;
- + goto ssb_pflash;
- }
-
- /* There is ChipCommon, so use it to read info about flash */
- switch (bus->chipco.capabilities & SSB_CHIPCO_CAP_FLASHT) {
- case SSB_CHIPCO_FLASHT_STSER:
- case SSB_CHIPCO_FLASHT_ATSER:
- - pr_err("Serial flash not supported\n");
- + pr_debug("Found serial flash\n");
- + ssb_sflash_init(&bus->chipco);
- break;
- case SSB_CHIPCO_FLASHT_PARA:
- pr_debug("Found parallel flash\n");
- - mcore->pflash.present = true;
- - mcore->pflash.window = SSB_FLASH2;
- - mcore->pflash.window_size = SSB_FLASH2_SZ;
- + pflash->present = true;
- + pflash->window = SSB_FLASH2;
- + pflash->window_size = SSB_FLASH2_SZ;
- if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG)
- & SSB_CHIPCO_CFG_DS16) == 0)
- - mcore->pflash.buswidth = 1;
- + pflash->buswidth = 1;
- else
- - mcore->pflash.buswidth = 2;
- + pflash->buswidth = 2;
- break;
- }
- +
- +ssb_pflash:
- + if (pflash->present) {
- + ssb_pflash_data.width = pflash->buswidth;
- + ssb_pflash_resource.start = pflash->window;
- + ssb_pflash_resource.end = pflash->window + pflash->window_size;
- + }
- }
-
- u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
- --- a/drivers/ssb/main.c
- +++ b/drivers/ssb/main.c
- @@ -549,6 +549,14 @@ static int ssb_devices_register(struct s
- dev_idx++;
- }
-
- +#ifdef CONFIG_SSB_DRIVER_MIPS
- + if (bus->mipscore.pflash.present) {
- + err = platform_device_register(&ssb_pflash_dev);
- + if (err)
- + pr_err("Error registering parallel flash\n");
- + }
- +#endif
- +
- return 0;
- error:
- /* Unwind the already registered devices. */
- --- a/drivers/ssb/ssb_private.h
- +++ b/drivers/ssb/ssb_private.h
- @@ -217,6 +217,21 @@ extern u32 ssb_chipco_watchdog_timer_set
- u32 ticks);
- extern u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
-
- +/* driver_chipcommon_sflash.c */
- +#ifdef CONFIG_SSB_SFLASH
- +int ssb_sflash_init(struct ssb_chipcommon *cc);
- +#else
- +static inline int ssb_sflash_init(struct ssb_chipcommon *cc)
- +{
- + pr_err("Serial flash not supported\n");
- + return 0;
- +}
- +#endif /* CONFIG_SSB_SFLASH */
- +
- +#ifdef CONFIG_SSB_DRIVER_MIPS
- +extern struct platform_device ssb_pflash_dev;
- +#endif
- +
- #ifdef CONFIG_SSB_DRIVER_EXTIF
- extern u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks);
- extern u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
- --- a/include/linux/ssb/ssb_driver_mips.h
- +++ b/include/linux/ssb/ssb_driver_mips.h
- @@ -45,6 +45,11 @@ void ssb_mipscore_init(struct ssb_mipsco
- {
- }
-
- +static inline unsigned int ssb_mips_irq(struct ssb_device *dev)
- +{
- + return 0;
- +}
- +
- #endif /* CONFIG_SSB_DRIVER_MIPS */
-
- #endif /* LINUX_SSB_MIPSCORE_H_ */
- --- a/drivers/net/wireless/b43/phy_n.c
- +++ b/drivers/net/wireless/b43/phy_n.c
- @@ -5165,7 +5165,8 @@ static void b43_nphy_pmu_spur_avoid(stru
- #endif
- #ifdef CONFIG_B43_SSB
- case B43_BUS_SSB:
- - /* FIXME */
- + ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco,
- + avoid);
- break;
- #endif
- }
- --- a/drivers/ssb/driver_chipcommon_pmu.c
- +++ b/drivers/ssb/driver_chipcommon_pmu.c
- @@ -675,3 +675,32 @@ u32 ssb_pmu_get_controlclock(struct ssb_
- return 0;
- }
- }
- +
- +void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid)
- +{
- + u32 pmu_ctl = 0;
- +
- + switch (cc->dev->bus->chip_id) {
- + case 0x4322:
- + ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070);
- + ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a);
- + ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854);
- + if (spuravoid == 1)
- + ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828);
- + else
- + ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828);
- + pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD;
- + break;
- + case 43222:
- + /* TODO: BCM43222 requires updating PLLs too */
- + return;
- + default:
- + ssb_printk(KERN_ERR PFX
- + "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n",
- + cc->dev->bus->chip_id);
- + return;
- + }
- +
- + chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl);
- +}
- +EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate);
- --- a/drivers/ssb/pci.c
- +++ b/drivers/ssb/pci.c
- @@ -339,6 +339,21 @@ static s8 r123_extract_antgain(u8 sprom_
- return (s8)gain;
- }
-
- +static void sprom_extract_r23(struct ssb_sprom *out, const u16 *in)
- +{
- + SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
- + SPEX(opo, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0);
- + SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0);
- + SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0);
- + SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0);
- + SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0);
- + SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0);
- + SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0);
- + SPEX(maxpwr_ah, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0);
- + SPEX(maxpwr_al, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO,
- + SSB_SPROM2_MAXP_A_LO_SHIFT);
- +}
- +
- static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
- {
- int i;
- @@ -398,8 +413,7 @@ static void sprom_extract_r123(struct ss
- SSB_SPROM1_ITSSI_A_SHIFT);
- SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
- SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
- - if (out->revision >= 2)
- - SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
- +
- SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8);
- SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
-
- @@ -410,6 +424,8 @@ static void sprom_extract_r123(struct ss
- out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
- SSB_SPROM1_AGAIN_A,
- SSB_SPROM1_AGAIN_A_SHIFT);
- + if (out->revision >= 2)
- + sprom_extract_r23(out, in);
- }
-
- /* Revs 4 5 and 8 have partially shared layout */
- --- a/include/linux/ssb/ssb_driver_chipcommon.h
- +++ b/include/linux/ssb/ssb_driver_chipcommon.h
- @@ -219,6 +219,7 @@
- #define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */
- #define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
- #define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16
- +#define SSB_CHIPCO_PMU_CTL_PLL_UPD 0x00000400
- #define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
- #define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
- #define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
- @@ -667,5 +668,6 @@ enum ssb_pmu_ldo_volt_id {
- void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
- enum ssb_pmu_ldo_volt_id id, u32 voltage);
- void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on);
- +void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid);
-
- #endif /* LINUX_SSB_CHIPCO_H_ */
- --- a/include/linux/ssb/ssb_regs.h
- +++ b/include/linux/ssb/ssb_regs.h
- @@ -289,11 +289,11 @@
- #define SSB_SPROM4_ETHPHY_ET1A_SHIFT 5
- #define SSB_SPROM4_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */
- #define SSB_SPROM4_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */
- -#define SSB_SPROM4_ANTAVAIL 0x005D /* Antenna available bitfields */
- -#define SSB_SPROM4_ANTAVAIL_A 0x00FF /* A-PHY bitfield */
- -#define SSB_SPROM4_ANTAVAIL_A_SHIFT 0
- -#define SSB_SPROM4_ANTAVAIL_BG 0xFF00 /* B-PHY and G-PHY bitfield */
- -#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 8
- +#define SSB_SPROM4_ANTAVAIL 0x005C /* Antenna available bitfields */
- +#define SSB_SPROM4_ANTAVAIL_BG 0x00FF /* B-PHY and G-PHY bitfield */
- +#define SSB_SPROM4_ANTAVAIL_BG_SHIFT 0
- +#define SSB_SPROM4_ANTAVAIL_A 0xFF00 /* A-PHY bitfield */
- +#define SSB_SPROM4_ANTAVAIL_A_SHIFT 8
- #define SSB_SPROM4_AGAIN01 0x005E /* Antenna Gain (in dBm Q5.2) */
- #define SSB_SPROM4_AGAIN0 0x00FF /* Antenna 0 */
- #define SSB_SPROM4_AGAIN0_SHIFT 0
|