mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.1 KiB
88 lines
2.1 KiB
/* |
|
* Broadcom BCM63xx Processor Monitor Bus shared routines (SMP and reset) |
|
* |
|
* Copyright (C) 2015, Broadcom Corporation |
|
* Author: Florian Fainelli <[email protected]> |
|
* |
|
* 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 */
|
|
|