ecd177c216
This patch adds support for using bcma on a Broadcom SoC as the system bus. An SoC like the bcm4716 could register this bus and use it to searches for the bcma cores and register the devices on this bus. BCMA_HOSTTYPE_NONE was intended for SoCs at first but BCMA_HOSTTYPE_SOC is a better name. Acked-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Acked-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
127 lines
2.8 KiB
C
127 lines
2.8 KiB
C
/*
|
|
* 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);
|
|
|
|
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);
|
|
}
|
|
EXPORT_SYMBOL_GPL(bcma_core_disable);
|
|
|
|
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);
|
|
|
|
void bcma_core_set_clockmode(struct bcma_device *core,
|
|
enum bcma_clkmode clkmode)
|
|
{
|
|
u16 i;
|
|
|
|
WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
|
|
core->id.id != BCMA_CORE_PCIE &&
|
|
core->id.id != BCMA_CORE_80211);
|
|
|
|
switch (clkmode) {
|
|
case BCMA_CLKMODE_FAST:
|
|
bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
|
|
udelay(64);
|
|
for (i = 0; i < 1500; i++) {
|
|
if (bcma_read32(core, BCMA_CLKCTLST) &
|
|
BCMA_CLKCTLST_HAVEHT) {
|
|
i = 0;
|
|
break;
|
|
}
|
|
udelay(10);
|
|
}
|
|
if (i)
|
|
pr_err("HT force timeout\n");
|
|
break;
|
|
case BCMA_CLKMODE_DYNAMIC:
|
|
pr_warn("Dynamic clockmode not supported yet!\n");
|
|
break;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
|
|
|
|
void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
|
|
{
|
|
u16 i;
|
|
|
|
WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
|
|
WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
|
|
|
|
if (on) {
|
|
bcma_set32(core, BCMA_CLKCTLST, req);
|
|
for (i = 0; i < 10000; i++) {
|
|
if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
|
|
status) {
|
|
i = 0;
|
|
break;
|
|
}
|
|
udelay(10);
|
|
}
|
|
if (i)
|
|
pr_err("PLL enable timeout\n");
|
|
} else {
|
|
pr_warn("Disabling PLL not supported yet!\n");
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
|
|
|
|
u32 bcma_core_dma_translation(struct bcma_device *core)
|
|
{
|
|
switch (core->bus->hosttype) {
|
|
case BCMA_HOSTTYPE_SOC:
|
|
return 0;
|
|
case BCMA_HOSTTYPE_PCI:
|
|
if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
|
|
return BCMA_DMA_TRANSLATION_DMA64_CMT;
|
|
else
|
|
return BCMA_DMA_TRANSLATION_DMA32_CMT;
|
|
default:
|
|
pr_err("DMA translation unknown for host %d\n",
|
|
core->bus->hosttype);
|
|
}
|
|
return BCMA_DMA_TRANSLATION_NONE;
|
|
}
|
|
EXPORT_SYMBOL(bcma_core_dma_translation);
|