summaryrefslogtreecommitdiffstats
path: root/include/linux/reset
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2015-04-17 13:45:55 -0400
committerFlorian Fainelli <f.fainelli@gmail.com>2015-05-20 18:05:39 -0400
commit6e844b035360294636271f4f0fd4a5a685e03c06 (patch)
treef52f307fc943f197b7bced1dd1d3d8f115b96c14 /include/linux/reset
parent7eb68a2a0519a77b93184c695d4d293c92dc2286 (diff)
ARM: BCM63xx: Add Broadcom BCM63xx PMB controller helpers
This patch adds both common register definitions and helper functions used to issue read/write commands to the Broadcom BCM63xx PMB controller which is used to power on and release from reset internal on-chip peripherals such as the integrated Ethernet switch, AHCI, USB, as well as the secondary CPU core. This is going to be utilized by the BCM63138 SMP code, as well as by the BCM63138 reset controller later. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Diffstat (limited to 'include/linux/reset')
-rw-r--r--include/linux/reset/bcm63xx_pmb.h88
1 files changed, 88 insertions, 0 deletions
diff --git a/include/linux/reset/bcm63xx_pmb.h b/include/linux/reset/bcm63xx_pmb.h
new file mode 100644
index 000000000000..bb4af7b5eb36
--- /dev/null
+++ b/include/linux/reset/bcm63xx_pmb.h
@@ -0,0 +1,88 @@
1/*
2 * Broadcom BCM63xx Processor Monitor Bus shared routines (SMP and reset)
3 *
4 * Copyright (C) 2015, Broadcom Corporation
5 * Author: Florian Fainelli <f.fainelli@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation version 2.
10 *
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifndef __BCM63XX_PMB_H
17#define __BCM63XX_PMB_H
18
19#include <linux/io.h>
20#include <linux/types.h>
21#include <linux/delay.h>
22#include <linux/err.h>
23
24/* PMB Master controller register */
25#define PMB_CTRL 0x00
26#define PMC_PMBM_START (1 << 31)
27#define PMC_PMBM_TIMEOUT (1 << 30)
28#define PMC_PMBM_SLAVE_ERR (1 << 29)
29#define PMC_PMBM_BUSY (1 << 28)
30#define PMC_PMBM_READ (0 << 20)
31#define PMC_PMBM_WRITE (1 << 20)
32#define PMB_WR_DATA 0x04
33#define PMB_TIMEOUT 0x08
34#define PMB_RD_DATA 0x0C
35
36#define PMB_BUS_ID_SHIFT 8
37
38/* Perform the low-level PMB master operation, shared between reads and
39 * writes.
40 */
41static inline int __bpcm_do_op(void __iomem *master, unsigned int addr,
42 u32 off, u32 op)
43{
44 unsigned int timeout = 1000;
45 u32 cmd;
46
47 cmd = (PMC_PMBM_START | op | (addr & 0xff) << 12 | off);
48 writel(cmd, master + PMB_CTRL);
49 do {
50 cmd = readl(master + PMB_CTRL);
51 if (!(cmd & PMC_PMBM_START))
52 return 0;
53
54 if (cmd & PMC_PMBM_SLAVE_ERR)
55 return -EIO;
56
57 if (cmd & PMC_PMBM_TIMEOUT)
58 return -ETIMEDOUT;
59
60 udelay(1);
61 } while (timeout-- > 0);
62
63 return -ETIMEDOUT;
64}
65
66static inline int bpcm_rd(void __iomem *master, unsigned int addr,
67 u32 off, u32 *val)
68{
69 int ret = 0;
70
71 ret = __bpcm_do_op(master, addr, off >> 2, PMC_PMBM_READ);
72 *val = readl(master + PMB_RD_DATA);
73
74 return ret;
75}
76
77static inline int bpcm_wr(void __iomem *master, unsigned int addr,
78 u32 off, u32 val)
79{
80 int ret = 0;
81
82 writel(val, master + PMB_WR_DATA);
83 ret = __bpcm_do_op(master, addr, off >> 2, PMC_PMBM_WRITE);
84
85 return ret;
86}
87
88#endif /* __BCM63XX_PMB_H */