aboutsummaryrefslogtreecommitdiff
path: root/drivers/bcma/driver_chipcommon_pmu.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 13:43:21 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-20 13:43:21 -0700
commit06f4e926d256d902dd9a53dcb400fd74974ce087 (patch)
tree0b438b67f5f0eff6fd617bc497a9dace6164a488 /drivers/bcma/driver_chipcommon_pmu.c
parent8e7bfcbab3825d1b404d615cb1b54f44ff81f981 (diff)
parentd93515611bbc70c2fe4db232e5feb448ed8e4cc9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1446 commits) macvlan: fix panic if lowerdev in a bond tg3: Add braces around 5906 workaround. tg3: Fix NETIF_F_LOOPBACK error macvlan: remove one synchronize_rcu() call networking: NET_CLS_ROUTE4 depends on INET irda: Fix error propagation in ircomm_lmp_connect_response() irda: Kill set but unused variable 'bytes' in irlan_check_command_param() irda: Kill set but unused variable 'clen' in ircomm_connect_indication() rxrpc: Fix set but unused variable 'usage' in rxrpc_get_transport() be2net: Kill set but unused variable 'req' in lancer_fw_download() irda: Kill set but unused vars 'saddr' and 'daddr' in irlan_provider_connect_indication() atl1c: atl1c_resume() is only used when CONFIG_PM_SLEEP is defined. rxrpc: Fix set but unused variable 'usage' in rxrpc_get_peer(). rxrpc: Kill set but unused variable 'local' in rxrpc_UDP_error_handler() rxrpc: Kill set but unused variable 'sp' in rxrpc_process_connection() rxrpc: Kill set but unused variable 'sp' in rxrpc_rotate_tx_window() pkt_sched: Kill set but unused variable 'protocol' in tc_classify() isdn: capi: Use pr_debug() instead of ifdefs. tg3: Update version to 3.119 tg3: Apply rx_discards fix to 5719/5720 ... Fix up trivial conflicts in arch/x86/Kconfig and net/mac80211/agg-tx.c as per Davem.
Diffstat (limited to 'drivers/bcma/driver_chipcommon_pmu.c')
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
new file mode 100644
index 00000000000..f44177a644c
--- /dev/null
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -0,0 +1,134 @@
+/*
+ * Broadcom specific AMBA
+ * ChipCommon Power Management Unit driver
+ *
+ * Copyright 2009, Michael Buesch <mb@bu3sch.de>
+ * Copyright 2007, Broadcom Corporation
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
+ u32 offset, u32 mask, u32 set)
+{
+ u32 value;
+
+ bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
+ bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
+ bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
+ value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
+ value &= mask;
+ value |= set;
+ bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
+ bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
+}
+
+static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
+{
+ struct bcma_bus *bus = cc->core->bus;
+
+ switch (bus->chipinfo.id) {
+ case 0x4313:
+ case 0x4331:
+ case 43224:
+ case 43225:
+ break;
+ default:
+ pr_err("PLL init unknown for device 0x%04X\n",
+ bus->chipinfo.id);
+ }
+}
+
+static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
+{
+ struct bcma_bus *bus = cc->core->bus;
+ u32 min_msk = 0, max_msk = 0;
+
+ switch (bus->chipinfo.id) {
+ case 0x4313:
+ min_msk = 0x200D;
+ max_msk = 0xFFFF;
+ break;
+ case 43224:
+ break;
+ default:
+ pr_err("PMU resource config unknown for device 0x%04X\n",
+ bus->chipinfo.id);
+ }
+
+ /* Set the resource masks. */
+ if (min_msk)
+ bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
+ if (max_msk)
+ bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
+}
+
+void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
+{
+ struct bcma_bus *bus = cc->core->bus;
+
+ switch (bus->chipinfo.id) {
+ case 0x4313:
+ case 0x4331:
+ case 43224:
+ break;
+ default:
+ pr_err("PMU switch/regulators init unknown for device "
+ "0x%04X\n", bus->chipinfo.id);
+ }
+}
+
+void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
+{
+ struct bcma_bus *bus = cc->core->bus;
+
+ switch (bus->chipinfo.id) {
+ case 0x4313:
+ bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
+ break;
+ case 0x4331:
+ pr_err("Enabling Ext PA lines not implemented\n");
+ break;
+ case 43224:
+ if (bus->chipinfo.rev == 0) {
+ pr_err("Workarounds for 43224 rev 0 not fully "
+ "implemented\n");
+ bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
+ } else {
+ bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
+ }
+ break;
+ default:
+ pr_err("Workarounds unknown for device 0x%04X\n",
+ bus->chipinfo.id);
+ }
+}
+
+void bcma_pmu_init(struct bcma_drv_cc *cc)
+{
+ u32 pmucap;
+
+ pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP);
+ cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
+
+ pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev,
+ pmucap);
+
+ if (cc->pmu.rev == 1)
+ bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
+ ~BCMA_CC_PMU_CTL_NOILPONW);
+ else
+ bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
+ BCMA_CC_PMU_CTL_NOILPONW);
+
+ if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2)
+ pr_err("Fix for 4329b0 bad LPOM state not implemented!\n");
+
+ bcma_pmu_pll_init(cc);
+ bcma_pmu_resources_init(cc);
+ bcma_pmu_swreg_init(cc);
+ bcma_pmu_workarounds(cc);
+}