mpp.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * arch/arm/mach-orion5x/mpp.c
  3. *
  4. * MPP functions for Marvell Orion 5x SoCs
  5. *
  6. * This file is licensed under the terms of the GNU General Public
  7. * License version 2. This program is licensed "as is" without any
  8. * warranty of any kind, whether express or implied.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/init.h>
  12. #include <linux/mbus.h>
  13. #include <asm/hardware.h>
  14. #include <asm/io.h>
  15. #include "common.h"
  16. #include "mpp.h"
  17. static int is_5181l(void)
  18. {
  19. u32 dev;
  20. u32 rev;
  21. orion5x_pcie_id(&dev, &rev);
  22. return !!(dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0);
  23. }
  24. static int is_5182(void)
  25. {
  26. u32 dev;
  27. u32 rev;
  28. orion5x_pcie_id(&dev, &rev);
  29. return !!(dev == MV88F5182_DEV_ID);
  30. }
  31. static int is_5281(void)
  32. {
  33. u32 dev;
  34. u32 rev;
  35. orion5x_pcie_id(&dev, &rev);
  36. return !!(dev == MV88F5281_DEV_ID);
  37. }
  38. static int __init determine_type_encoding(int mpp, enum orion5x_mpp_type type)
  39. {
  40. switch (type) {
  41. case MPP_UNUSED:
  42. case MPP_GPIO:
  43. if (mpp == 0)
  44. return 3;
  45. if (mpp >= 1 && mpp <= 15)
  46. return 0;
  47. if (mpp >= 16 && mpp <= 19) {
  48. if (is_5182())
  49. return 5;
  50. if (type == MPP_UNUSED)
  51. return 0;
  52. }
  53. return -1;
  54. case MPP_PCIE_RST_OUTn:
  55. if (mpp == 0)
  56. return 0;
  57. return -1;
  58. case MPP_PCI_ARB:
  59. if (mpp >= 0 && mpp <= 7)
  60. return 2;
  61. return -1;
  62. case MPP_PCI_PMEn:
  63. if (mpp == 2)
  64. return 3;
  65. return -1;
  66. case MPP_GIGE:
  67. if (mpp >= 8 && mpp <= 19)
  68. return 1;
  69. return -1;
  70. case MPP_NAND:
  71. if (is_5182() || is_5281()) {
  72. if (mpp >= 4 && mpp <= 7)
  73. return 4;
  74. if (mpp >= 12 && mpp <= 17)
  75. return 4;
  76. }
  77. return -1;
  78. case MPP_PCI_CLK:
  79. if (is_5181l() && mpp >= 6 && mpp <= 7)
  80. return 5;
  81. return -1;
  82. case MPP_SATA_LED:
  83. if (is_5182()) {
  84. if (mpp >= 4 && mpp <= 7)
  85. return 5;
  86. if (mpp >= 12 && mpp <= 15)
  87. return 5;
  88. }
  89. return -1;
  90. case MPP_UART:
  91. if (mpp >= 16 && mpp <= 19)
  92. return 0;
  93. return -1;
  94. }
  95. printk(KERN_INFO "unknown MPP type %d\n", type);
  96. return -1;
  97. }
  98. void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode)
  99. {
  100. u32 mpp_0_7_ctrl = readl(MPP_0_7_CTRL);
  101. u32 mpp_8_15_ctrl = readl(MPP_8_15_CTRL);
  102. u32 mpp_16_19_ctrl = readl(MPP_16_19_CTRL);
  103. while (mode->mpp >= 0) {
  104. u32 *reg;
  105. int num_type;
  106. int shift;
  107. if (mode->mpp >= 0 && mode->mpp <= 7)
  108. reg = &mpp_0_7_ctrl;
  109. else if (mode->mpp >= 8 && mode->mpp <= 15)
  110. reg = &mpp_8_15_ctrl;
  111. else if (mode->mpp >= 16 && mode->mpp <= 19)
  112. reg = &mpp_16_19_ctrl;
  113. else {
  114. printk(KERN_ERR "orion5x_mpp_conf: invalid MPP "
  115. "(%d)\n", mode->mpp);
  116. continue;
  117. }
  118. num_type = determine_type_encoding(mode->mpp, mode->type);
  119. if (num_type < 0) {
  120. printk(KERN_ERR "orion5x_mpp_conf: invalid MPP "
  121. "combination (%d, %d)\n", mode->mpp,
  122. mode->type);
  123. continue;
  124. }
  125. shift = (mode->mpp & 7) << 2;
  126. *reg &= ~(0xf << shift);
  127. *reg |= (num_type & 0xf) << shift;
  128. orion5x_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO));
  129. mode++;
  130. }
  131. writel(mpp_0_7_ctrl, MPP_0_7_CTRL);
  132. writel(mpp_8_15_ctrl, MPP_8_15_CTRL);
  133. writel(mpp_16_19_ctrl, MPP_16_19_CTRL);
  134. }