bcm63xx_pmb.h 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Broadcom BCM63xx Processor Monitor Bus shared routines (SMP and reset)
  4. *
  5. * Copyright (C) 2015, Broadcom Corporation
  6. * Author: Florian Fainelli <[email protected]>
  7. */
  8. #ifndef __BCM63XX_PMB_H
  9. #define __BCM63XX_PMB_H
  10. #include <linux/io.h>
  11. #include <linux/types.h>
  12. #include <linux/delay.h>
  13. #include <linux/err.h>
  14. /* PMB Master controller register */
  15. #define PMB_CTRL 0x00
  16. #define PMC_PMBM_START (1 << 31)
  17. #define PMC_PMBM_TIMEOUT (1 << 30)
  18. #define PMC_PMBM_SLAVE_ERR (1 << 29)
  19. #define PMC_PMBM_BUSY (1 << 28)
  20. #define PMC_PMBM_READ (0 << 20)
  21. #define PMC_PMBM_WRITE (1 << 20)
  22. #define PMB_WR_DATA 0x04
  23. #define PMB_TIMEOUT 0x08
  24. #define PMB_RD_DATA 0x0C
  25. #define PMB_BUS_ID_SHIFT 8
  26. /* Perform the low-level PMB master operation, shared between reads and
  27. * writes.
  28. */
  29. static inline int __bpcm_do_op(void __iomem *master, unsigned int addr,
  30. u32 off, u32 op)
  31. {
  32. unsigned int timeout = 1000;
  33. u32 cmd;
  34. cmd = (PMC_PMBM_START | op | (addr & 0xff) << 12 | off);
  35. writel(cmd, master + PMB_CTRL);
  36. do {
  37. cmd = readl(master + PMB_CTRL);
  38. if (!(cmd & PMC_PMBM_START))
  39. return 0;
  40. if (cmd & PMC_PMBM_SLAVE_ERR)
  41. return -EIO;
  42. if (cmd & PMC_PMBM_TIMEOUT)
  43. return -ETIMEDOUT;
  44. udelay(1);
  45. } while (timeout-- > 0);
  46. return -ETIMEDOUT;
  47. }
  48. static inline int bpcm_rd(void __iomem *master, unsigned int addr,
  49. u32 off, u32 *val)
  50. {
  51. int ret = 0;
  52. ret = __bpcm_do_op(master, addr, off >> 2, PMC_PMBM_READ);
  53. *val = readl(master + PMB_RD_DATA);
  54. return ret;
  55. }
  56. static inline int bpcm_wr(void __iomem *master, unsigned int addr,
  57. u32 off, u32 val)
  58. {
  59. int ret = 0;
  60. writel(val, master + PMB_WR_DATA);
  61. ret = __bpcm_do_op(master, addr, off >> 2, PMC_PMBM_WRITE);
  62. return ret;
  63. }
  64. #endif /* __BCM63XX_PMB_H */