qrio.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2013 Keymile AG
  4. * Valentin Longchamp <valentin.longchamp@keymile.com>
  5. */
  6. #include <common.h>
  7. #include "../common/common.h"
  8. #include "kmp204x.h"
  9. /* QRIO GPIO register offsets */
  10. #define DIRECT_OFF 0x18
  11. #define GPRT_OFF 0x1c
  12. int qrio_get_gpio(u8 port_off, u8 gpio_nr)
  13. {
  14. u32 gprt;
  15. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  16. gprt = in_be32(qrio_base + port_off + GPRT_OFF);
  17. return (gprt >> gpio_nr) & 1U;
  18. }
  19. void qrio_set_gpio(u8 port_off, u8 gpio_nr, bool value)
  20. {
  21. u32 gprt, mask;
  22. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  23. mask = 1U << gpio_nr;
  24. gprt = in_be32(qrio_base + port_off + GPRT_OFF);
  25. if (value)
  26. gprt |= mask;
  27. else
  28. gprt &= ~mask;
  29. out_be32(qrio_base + port_off + GPRT_OFF, gprt);
  30. }
  31. void qrio_gpio_direction_output(u8 port_off, u8 gpio_nr, bool value)
  32. {
  33. u32 direct, mask;
  34. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  35. mask = 1U << gpio_nr;
  36. direct = in_be32(qrio_base + port_off + DIRECT_OFF);
  37. direct |= mask;
  38. out_be32(qrio_base + port_off + DIRECT_OFF, direct);
  39. qrio_set_gpio(port_off, gpio_nr, value);
  40. }
  41. void qrio_gpio_direction_input(u8 port_off, u8 gpio_nr)
  42. {
  43. u32 direct, mask;
  44. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  45. mask = 1U << gpio_nr;
  46. direct = in_be32(qrio_base + port_off + DIRECT_OFF);
  47. direct &= ~mask;
  48. out_be32(qrio_base + port_off + DIRECT_OFF, direct);
  49. }
  50. void qrio_set_opendrain_gpio(u8 port_off, u8 gpio_nr, u8 val)
  51. {
  52. u32 direct, mask;
  53. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  54. mask = 1U << gpio_nr;
  55. direct = in_be32(qrio_base + port_off + DIRECT_OFF);
  56. if (val == 0)
  57. /* set to output -> GPIO drives low */
  58. direct |= mask;
  59. else
  60. /* set to input -> GPIO floating */
  61. direct &= ~mask;
  62. out_be32(qrio_base + port_off + DIRECT_OFF, direct);
  63. }
  64. #define WDMASK_OFF 0x16
  65. void qrio_wdmask(u8 bit, bool wden)
  66. {
  67. u16 wdmask;
  68. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  69. wdmask = in_be16(qrio_base + WDMASK_OFF);
  70. if (wden)
  71. wdmask |= (1 << bit);
  72. else
  73. wdmask &= ~(1 << bit);
  74. out_be16(qrio_base + WDMASK_OFF, wdmask);
  75. }
  76. #define PRST_OFF 0x1a
  77. void qrio_prst(u8 bit, bool en, bool wden)
  78. {
  79. u16 prst;
  80. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  81. qrio_wdmask(bit, wden);
  82. prst = in_be16(qrio_base + PRST_OFF);
  83. if (en)
  84. prst &= ~(1 << bit);
  85. else
  86. prst |= (1 << bit);
  87. out_be16(qrio_base + PRST_OFF, prst);
  88. }
  89. #define PRSTCFG_OFF 0x1c
  90. void qrio_prstcfg(u8 bit, u8 mode)
  91. {
  92. u32 prstcfg;
  93. u8 i;
  94. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  95. prstcfg = in_be32(qrio_base + PRSTCFG_OFF);
  96. for (i = 0; i < 2; i++) {
  97. if (mode & (1<<i))
  98. set_bit(2*bit+i, &prstcfg);
  99. else
  100. clear_bit(2*bit+i, &prstcfg);
  101. }
  102. out_be32(qrio_base + PRSTCFG_OFF, prstcfg);
  103. }
  104. #define CTRLH_OFF 0x02
  105. #define CTRLH_WRL_BOOT 0x01
  106. #define CTRLH_WRL_UNITRUN 0x02
  107. void qrio_set_leds(void)
  108. {
  109. u8 ctrlh;
  110. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  111. /* set UNIT LED to RED and BOOT LED to ON */
  112. ctrlh = in_8(qrio_base + CTRLH_OFF);
  113. ctrlh |= (CTRLH_WRL_BOOT | CTRLH_WRL_UNITRUN);
  114. out_8(qrio_base + CTRLH_OFF, ctrlh);
  115. }
  116. #define CTRLL_OFF 0x03
  117. #define CTRLL_WRB_BUFENA 0x20
  118. void qrio_enable_app_buffer(void)
  119. {
  120. u8 ctrll;
  121. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  122. /* enable application buffer */
  123. ctrll = in_8(qrio_base + CTRLL_OFF);
  124. ctrll |= (CTRLL_WRB_BUFENA);
  125. out_8(qrio_base + CTRLL_OFF, ctrll);
  126. }
  127. #define REASON1_OFF 0x12
  128. #define REASON1_CPUWD 0x01
  129. void qrio_cpuwd_flag(bool flag)
  130. {
  131. u8 reason1;
  132. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  133. reason1 = in_8(qrio_base + REASON1_OFF);
  134. if (flag)
  135. reason1 |= REASON1_CPUWD;
  136. else
  137. reason1 &= ~REASON1_CPUWD;
  138. out_8(qrio_base + REASON1_OFF, reason1);
  139. }
  140. #define RSTCFG_OFF 0x11
  141. void qrio_uprstreq(u8 mode)
  142. {
  143. u32 rstcfg;
  144. void __iomem *qrio_base = (void *)CONFIG_SYS_QRIO_BASE;
  145. rstcfg = in_8(qrio_base + RSTCFG_OFF);
  146. if (mode & UPREQ_CORE_RST)
  147. rstcfg |= UPREQ_CORE_RST;
  148. else
  149. rstcfg &= ~UPREQ_CORE_RST;
  150. out_8(qrio_base + RSTCFG_OFF, rstcfg);
  151. }