These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / include / linux / reset / bcm63xx_pmb.h
diff --git a/kernel/include/linux/reset/bcm63xx_pmb.h b/kernel/include/linux/reset/bcm63xx_pmb.h
new file mode 100644 (file)
index 0000000..bb4af7b
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Broadcom BCM63xx Processor Monitor Bus shared routines (SMP and reset)
+ *
+ * Copyright (C) 2015, Broadcom Corporation
+ * Author: Florian Fainelli <f.fainelli@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __BCM63XX_PMB_H
+#define __BCM63XX_PMB_H
+
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+/* PMB Master controller register */
+#define PMB_CTRL               0x00
+#define  PMC_PMBM_START                (1 << 31)
+#define  PMC_PMBM_TIMEOUT      (1 << 30)
+#define  PMC_PMBM_SLAVE_ERR    (1 << 29)
+#define  PMC_PMBM_BUSY         (1 << 28)
+#define  PMC_PMBM_READ         (0 << 20)
+#define  PMC_PMBM_WRITE                (1 << 20)
+#define PMB_WR_DATA            0x04
+#define PMB_TIMEOUT            0x08
+#define PMB_RD_DATA            0x0C
+
+#define PMB_BUS_ID_SHIFT       8
+
+/* Perform the low-level PMB master operation, shared between reads and
+ * writes.
+ */
+static inline int __bpcm_do_op(void __iomem *master, unsigned int addr,
+                              u32 off, u32 op)
+{
+       unsigned int timeout = 1000;
+       u32 cmd;
+
+       cmd = (PMC_PMBM_START | op | (addr & 0xff) << 12 | off);
+       writel(cmd, master + PMB_CTRL);
+       do {
+               cmd = readl(master + PMB_CTRL);
+               if (!(cmd & PMC_PMBM_START))
+                       return 0;
+
+               if (cmd & PMC_PMBM_SLAVE_ERR)
+                       return -EIO;
+
+               if (cmd & PMC_PMBM_TIMEOUT)
+                       return -ETIMEDOUT;
+
+               udelay(1);
+       } while (timeout-- > 0);
+
+       return -ETIMEDOUT;
+}
+
+static inline int bpcm_rd(void __iomem *master, unsigned int addr,
+                         u32 off, u32 *val)
+{
+       int ret = 0;
+
+       ret = __bpcm_do_op(master, addr, off >> 2, PMC_PMBM_READ);
+       *val = readl(master + PMB_RD_DATA);
+
+       return ret;
+}
+
+static inline int bpcm_wr(void __iomem *master, unsigned int addr,
+                         u32 off, u32 val)
+{
+       int ret = 0;
+
+       writel(val, master + PMB_WR_DATA);
+       ret = __bpcm_do_op(master, addr, off >> 2, PMC_PMBM_WRITE);
+
+       return ret;
+}
+
+#endif /* __BCM63XX_PMB_H */