mpp.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * arch/arm/mach-dove/mpp.c
  3. *
  4. * MPP functions for Marvell Dove 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/gpio.h>
  12. #include <linux/io.h>
  13. #include <plat/mpp.h>
  14. #include <mach/dove.h>
  15. #include "mpp.h"
  16. struct dove_mpp_grp {
  17. int start;
  18. int end;
  19. };
  20. /* Map a group to a range of GPIO pins in that group */
  21. static const struct dove_mpp_grp dove_mpp_grp[] = {
  22. [MPP_24_39] = {
  23. .start = 24,
  24. .end = 39,
  25. },
  26. [MPP_40_45] = {
  27. .start = 40,
  28. .end = 45,
  29. },
  30. [MPP_46_51] = {
  31. .start = 46,
  32. .end = 51,
  33. },
  34. [MPP_58_61] = {
  35. .start = 58,
  36. .end = 61,
  37. },
  38. [MPP_62_63] = {
  39. .start = 62,
  40. .end = 63,
  41. },
  42. };
  43. /* Enable gpio for a range of pins. mode should be a combination of
  44. GPIO_OUTPUT_OK | GPIO_INPUT_OK */
  45. static void dove_mpp_gpio_mode(int start, int end, int gpio_mode)
  46. {
  47. int i;
  48. for (i = start; i <= end; i++)
  49. orion_gpio_set_valid(i, gpio_mode);
  50. }
  51. /* Dump all the extra MPP registers. The platform code will dump the
  52. registers for pins 0-23. */
  53. static void dove_mpp_dump_regs(void)
  54. {
  55. pr_debug("PMU_CTRL4_CTRL: %08x\n",
  56. readl(DOVE_MPP_CTRL4_VIRT_BASE));
  57. pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n",
  58. readl(DOVE_PMU_MPP_GENERAL_CTRL));
  59. pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE));
  60. }
  61. static void dove_mpp_cfg_nfc(int sel)
  62. {
  63. u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE);
  64. mpp_gen_cfg &= ~0x1;
  65. mpp_gen_cfg |= sel;
  66. writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE);
  67. dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK);
  68. }
  69. static void dove_mpp_cfg_au1(int sel)
  70. {
  71. u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
  72. u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1);
  73. u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE);
  74. u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2);
  75. mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL);
  76. ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1);
  77. mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN);
  78. global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO);
  79. if (!sel || sel == 0x2)
  80. dove_mpp_gpio_mode(52, 57, 0);
  81. else
  82. dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
  83. if (sel & 0x1) {
  84. global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO;
  85. dove_mpp_gpio_mode(56, 57, 0);
  86. }
  87. if (sel & 0x2) {
  88. mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN;
  89. dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
  90. }
  91. if (sel & 0x4) {
  92. ssp_ctrl1 |= DOVE_SSP_ON_AU1;
  93. dove_mpp_gpio_mode(52, 55, 0);
  94. }
  95. if (sel & 0x8)
  96. mpp_ctrl4 |= DOVE_AU1_GPIO_SEL;
  97. writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
  98. writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1);
  99. writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE);
  100. writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2);
  101. }
  102. /* Configure the group registers, enabling GPIO if sel indicates the
  103. pin is to be used for GPIO */
  104. static void dove_mpp_conf_grp(unsigned int *mpp_grp_list)
  105. {
  106. u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
  107. int gpio_mode;
  108. for ( ; *mpp_grp_list; mpp_grp_list++) {
  109. unsigned int num = MPP_NUM(*mpp_grp_list);
  110. unsigned int sel = MPP_SEL(*mpp_grp_list);
  111. if (num > MPP_GRP_MAX) {
  112. pr_err("dove: invalid MPP GRP number (%u)\n", num);
  113. continue;
  114. }
  115. mpp_ctrl4 &= ~(0x1 << num);
  116. mpp_ctrl4 |= sel << num;
  117. gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0;
  118. dove_mpp_gpio_mode(dove_mpp_grp[num].start,
  119. dove_mpp_grp[num].end, gpio_mode);
  120. }
  121. writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
  122. }
  123. /* Configure the various MPP pins on Dove */
  124. void __init dove_mpp_conf(unsigned int *mpp_list,
  125. unsigned int *mpp_grp_list,
  126. unsigned int grp_au1_52_57,
  127. unsigned int grp_nfc_64_71)
  128. {
  129. dove_mpp_dump_regs();
  130. /* Use platform code for pins 0-23 */
  131. orion_mpp_conf(mpp_list, 0, MPP_MAX, DOVE_MPP_VIRT_BASE);
  132. dove_mpp_conf_grp(mpp_grp_list);
  133. dove_mpp_cfg_au1(grp_au1_52_57);
  134. dove_mpp_cfg_nfc(grp_nfc_64_71);
  135. dove_mpp_dump_regs();
  136. }