Skip to content

Commit

Permalink
bcma: add Broadcom specific AMBA bus driver
Browse files Browse the repository at this point in the history
Broadcom has released cards based on a new AMBA-based bus type. From a
programming point of view, this new bus type differs from AMBA and does
not use AMBA common registers. It also differs enough from SSB. We
decided that a new bus driver is needed to keep the code clean.

In its current form, the driver detects devices present on the bus and
registers them in the system. It allows registering BCMA drivers for
specified bus devices and provides them basic operations. The bus driver
itself includes two important bus managing drivers: ChipCommon core
driver and PCI(c) core driver. They are early used to allow correct
initialization.

Currently code is limited to supporting buses on PCI(e) devices, however
the driver is designed to be used also on other hosts. The host
abstraction layer is implemented and already used for PCI(e).

Support for PCI(e) hosts is working and seems to be stable (access to
80211 core was tested successfully on a few devices). We can still
optimize it by using some fixed windows, but this can be done later
without affecting any external code. Windows are just ranges in MMIO
used for accessing cores on the bus.

Cc: Greg KH <[email protected]>
Cc: Michael Büsch <[email protected]>
Cc: Larry Finger <[email protected]>
Cc: George Kashperko <[email protected]>
Cc: Arend van Spriel <[email protected]>
Cc: [email protected]
Cc: Russell King <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Andy Botting <[email protected]>
Cc: linuxdriverproject <[email protected]>
Cc: [email protected] <[email protected]>
Signed-off-by: Rafał Miłecki <[email protected]>
Signed-off-by: John W. Linville <[email protected]>
  • Loading branch information
rmilecki authored and linvjw committed May 10, 2011
1 parent 306fe93 commit 8369ae3
Show file tree
Hide file tree
Showing 23 changed files with 2,108 additions and 0 deletions.
31 changes: 31 additions & 0 deletions Documentation/ABI/testing/sysfs-bus-bcma
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
What: /sys/bus/bcma/devices/.../manuf
Date: May 2011
KernelVersion: 2.6.40
Contact: Rafał Miłecki <[email protected]>
Description:
Each BCMA core has it's manufacturer id. See
include/linux/bcma/bcma.h for possible values.

What: /sys/bus/bcma/devices/.../id
Date: May 2011
KernelVersion: 2.6.40
Contact: Rafał Miłecki <[email protected]>
Description:
There are a few types of BCMA cores, they can be identified by
id field.

What: /sys/bus/bcma/devices/.../rev
Date: May 2011
KernelVersion: 2.6.40
Contact: Rafał Miłecki <[email protected]>
Description:
BCMA cores of the same type can still slightly differ depending
on their revision. Use it for detailed programming.

What: /sys/bus/bcma/devices/.../class
Date: May 2011
KernelVersion: 2.6.40
Contact: Rafał Miłecki <[email protected]>
Description:
Each BCMA core is identified by few fields, including class it
belongs to. See include/linux/bcma/bcma.h for possible values.
7 changes: 7 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -5810,6 +5810,13 @@ S: Maintained
F: drivers/ssb/
F: include/linux/ssb/

BROADCOM SPECIFIC AMBA DRIVER (BCMA)
M: Rafał Miłecki <[email protected]>
L: [email protected]
S: Maintained
F: drivers/bcma/
F: include/linux/bcma/

SONY VAIO CONTROL DEVICE DRIVER
M: Mattia Dongili <[email protected]>
L: [email protected]
Expand Down
2 changes: 2 additions & 0 deletions drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ source "drivers/watchdog/Kconfig"

source "drivers/ssb/Kconfig"

source "drivers/bcma/Kconfig"

source "drivers/mfd/Kconfig"

source "drivers/regulator/Kconfig"
Expand Down
1 change: 1 addition & 0 deletions drivers/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ obj-$(CONFIG_HID) += hid/
obj-$(CONFIG_PPC_PS3) += ps3/
obj-$(CONFIG_OF) += of/
obj-$(CONFIG_SSB) += ssb/
obj-$(CONFIG_BCMA) += bcma/
obj-$(CONFIG_VHOST_NET) += vhost/
obj-$(CONFIG_VLYNQ) += vlynq/
obj-$(CONFIG_STAGING) += staging/
Expand Down
33 changes: 33 additions & 0 deletions drivers/bcma/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
config BCMA_POSSIBLE
bool
depends on HAS_IOMEM && HAS_DMA
default y

menu "Broadcom specific AMBA"
depends on BCMA_POSSIBLE

config BCMA
tristate "BCMA support"
depends on BCMA_POSSIBLE
help
Bus driver for Broadcom specific Advanced Microcontroller Bus
Architecture.

config BCMA_HOST_PCI_POSSIBLE
bool
depends on BCMA && PCI = y
default y

config BCMA_HOST_PCI
bool "Support for BCMA on PCI-host bus"
depends on BCMA_HOST_PCI_POSSIBLE

config BCMA_DEBUG
bool "BCMA debugging"
depends on BCMA
help
This turns on additional debugging messages.

If unsure, say N

endmenu
7 changes: 7 additions & 0 deletions drivers/bcma/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bcma-y += main.o scan.o core.o
bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
bcma-y += driver_pci.o
bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
obj-$(CONFIG_BCMA) += bcma.o

ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
19 changes: 19 additions & 0 deletions drivers/bcma/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Broadcom introduced new bus as replacement for older SSB. It is based on AMBA,
however from programming point of view there is nothing AMBA specific we use.

Standard AMBA drivers are platform specific, have hardcoded addresses and use
AMBA standard fields like CID and PID.

In case of Broadcom's cards every device consists of:
1) Broadcom specific AMBA device. It is put on AMBA bus, but can not be treated
as standard AMBA device. Reading it's CID or PID can cause machine lockup.
2) AMBA standard devices called ports or wrappers. They have CIDs (AMBA_CID)
and PIDs (0x103BB369), but we do not use that info for anything. One of that
devices is used for managing Broadcom specific core.

Addresses of AMBA devices are not hardcoded in driver and have to be read from
EPROM.

In this situation we decided to introduce separated bus. It can contain up to
16 devices identified by Broadcom specific fields: manufacturer, id, revision
and class.
3 changes: 3 additions & 0 deletions drivers/bcma/TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Interrupts
- Defines for PCI core driver
- Create kernel Documentation (use info from README)
28 changes: 28 additions & 0 deletions drivers/bcma/bcma_private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef LINUX_BCMA_PRIVATE_H_
#define LINUX_BCMA_PRIVATE_H_

#ifndef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#endif

#include <linux/bcma/bcma.h>
#include <linux/delay.h>

#define BCMA_CORE_SIZE 0x1000

struct bcma_bus;

/* main.c */
extern int bcma_bus_register(struct bcma_bus *bus);
extern void bcma_bus_unregister(struct bcma_bus *bus);

/* scan.c */
int bcma_bus_scan(struct bcma_bus *bus);

#ifdef CONFIG_BCMA_HOST_PCI
/* host_pci.c */
extern int __init bcma_host_pci_init(void);
extern void __exit bcma_host_pci_exit(void);
#endif /* CONFIG_BCMA_HOST_PCI */

#endif
51 changes: 51 additions & 0 deletions drivers/bcma/core.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Broadcom specific AMBA
* Core ops
*
* Licensed under the GNU/GPL. See COPYING for details.
*/

#include "bcma_private.h"
#include <linux/bcma/bcma.h>

bool bcma_core_is_enabled(struct bcma_device *core)
{
if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
!= BCMA_IOCTL_CLK)
return false;
if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
return false;
return true;
}
EXPORT_SYMBOL_GPL(bcma_core_is_enabled);

static void bcma_core_disable(struct bcma_device *core, u32 flags)
{
if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
return;

bcma_awrite32(core, BCMA_IOCTL, flags);
bcma_aread32(core, BCMA_IOCTL);
udelay(10);

bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
udelay(1);
}

int bcma_core_enable(struct bcma_device *core, u32 flags)
{
bcma_core_disable(core, flags);

bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags));
bcma_aread32(core, BCMA_IOCTL);

bcma_awrite32(core, BCMA_RESET_CTL, 0);
udelay(1);

bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
bcma_aread32(core, BCMA_IOCTL);
udelay(1);

return 0;
}
EXPORT_SYMBOL_GPL(bcma_core_enable);
87 changes: 87 additions & 0 deletions drivers/bcma/driver_chipcommon.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Broadcom specific AMBA
* ChipCommon core driver
*
* Copyright 2005, Broadcom Corporation
* Copyright 2006, 2007, Michael Buesch <[email protected]>
*
* Licensed under the GNU/GPL. See COPYING for details.
*/

#include "bcma_private.h"
#include <linux/bcma/bcma.h>

static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
u32 mask, u32 value)
{
value &= mask;
value |= bcma_cc_read32(cc, offset) & ~mask;
bcma_cc_write32(cc, offset, value);

return value;
}

void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
{
if (cc->core->id.rev >= 11)
cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
if (cc->core->id.rev >= 35)
cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);

bcma_cc_write32(cc, 0x58, 0);
bcma_cc_write32(cc, 0x5C, 0);

if (cc->capabilities & BCMA_CC_CAP_PMU)
bcma_pmu_init(cc);
if (cc->capabilities & BCMA_CC_CAP_PCTL)
pr_err("Power control not implemented!\n");
}

/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
{
/* instant NMI */
bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
}

void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
}

u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
{
return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
}

u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
{
return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
}

u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
}

u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
}

u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
}
EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);

u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
}

u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
{
return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
}
Loading

0 comments on commit 8369ae3

Please sign in to comment.