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