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 15 #include <mach/dove.h> 16 17 #include "mpp.h" 18 19 #define MPP_NR_REGS 4 20 #define MPP_CTRL(i) ((i) == 3 ? \ 21 DOVE_MPP_CTRL4_VIRT_BASE : \ 22 DOVE_MPP_VIRT_BASE + (i) * 4) 23 #define PMU_SIG_REGS 2 24 #define PMU_SIG_CTRL(i) (DOVE_PMU_SIG_CTRL + (i) * 4) 25 26 struct dove_mpp_grp { 27 int start; 28 int end; 29 }; 30 31 static struct dove_mpp_grp dove_mpp_grp[] = { 32 [MPP_24_39] = { 33 .start = 24, 34 .end = 39, 35 }, 36 [MPP_40_45] = { 37 .start = 40, 38 .end = 45, 39 }, 40 [MPP_46_51] = { 41 .start = 40, 42 .end = 45, 43 }, 44 [MPP_58_61] = { 45 .start = 58, 46 .end = 61, 47 }, 48 [MPP_62_63] = { 49 .start = 62, 50 .end = 63, 51 }, 52 }; 53 54 static void dove_mpp_gpio_mode(int start, int end, int gpio_mode) 55 { 56 int i; 57 58 for (i = start; i <= end; i++) 59 orion_gpio_set_valid(i, gpio_mode); 60 } 61 62 static void dove_mpp_dump_regs(void) 63 { 64 #ifdef DEBUG 65 int i; 66 67 pr_debug("MPP_CTRL regs:"); 68 for (i = 0; i < MPP_NR_REGS; i++) 69 printk(" %08x", readl(MPP_CTRL(i))); 70 printk("\n"); 71 72 pr_debug("PMU_SIG_CTRL regs:"); 73 for (i = 0; i < PMU_SIG_REGS; i++) 74 printk(" %08x", readl(PMU_SIG_CTRL(i))); 75 printk("\n"); 76 77 pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n", readl(DOVE_PMU_MPP_GENERAL_CTRL)); 78 pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE)); 79 #endif 80 } 81 82 static void dove_mpp_cfg_nfc(int sel) 83 { 84 u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE); 85 86 mpp_gen_cfg &= ~0x1; 87 mpp_gen_cfg |= sel; 88 writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE); 89 90 dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK); 91 } 92 93 static void dove_mpp_cfg_au1(int sel) 94 { 95 u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); 96 u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1); 97 u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE); 98 u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2); 99 100 mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL); 101 ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1); 102 mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN); 103 global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO); 104 105 if (!sel || sel == 0x2) 106 dove_mpp_gpio_mode(52, 57, 0); 107 else 108 dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK); 109 110 if (sel & 0x1) { 111 global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO; 112 dove_mpp_gpio_mode(56, 57, 0); 113 } 114 if (sel & 0x2) { 115 mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN; 116 dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK); 117 } 118 if (sel & 0x4) { 119 ssp_ctrl1 |= DOVE_SSP_ON_AU1; 120 dove_mpp_gpio_mode(52, 55, 0); 121 } 122 if (sel & 0x8) 123 mpp_ctrl4 |= DOVE_AU1_GPIO_SEL; 124 125 writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE); 126 writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1); 127 writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE); 128 writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2); 129 } 130 131 static void dove_mpp_conf_grp(int num, int sel, u32 *mpp_ctrl) 132 { 133 int start = dove_mpp_grp[num].start; 134 int end = dove_mpp_grp[num].end; 135 int gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0; 136 137 *mpp_ctrl &= ~(0x1 << num); 138 *mpp_ctrl |= sel << num; 139 140 dove_mpp_gpio_mode(start, end, gpio_mode); 141 } 142 143 void __init dove_mpp_conf(unsigned int *mpp_list) 144 { 145 u32 mpp_ctrl[MPP_NR_REGS]; 146 u32 pmu_mpp_ctrl = 0; 147 u32 pmu_sig_ctrl[PMU_SIG_REGS]; 148 int i; 149 150 for (i = 0; i < MPP_NR_REGS; i++) 151 mpp_ctrl[i] = readl(MPP_CTRL(i)); 152 153 for (i = 0; i < PMU_SIG_REGS; i++) 154 pmu_sig_ctrl[i] = readl(PMU_SIG_CTRL(i)); 155 156 pmu_mpp_ctrl = readl(DOVE_PMU_MPP_GENERAL_CTRL); 157 158 dove_mpp_dump_regs(); 159 160 for ( ; *mpp_list != MPP_END; mpp_list++) { 161 unsigned int num = MPP_NUM(*mpp_list); 162 unsigned int sel = MPP_SEL(*mpp_list); 163 int shift, gpio_mode; 164 165 if (num > MPP_MAX) { 166 pr_err("dove: invalid MPP number (%u)\n", num); 167 continue; 168 } 169 170 if (*mpp_list & MPP_NFC_MASK) { 171 dove_mpp_cfg_nfc(sel); 172 continue; 173 } 174 175 if (*mpp_list & MPP_AU1_MASK) { 176 dove_mpp_cfg_au1(sel); 177 continue; 178 } 179 180 if (*mpp_list & MPP_GRP_MASK) { 181 dove_mpp_conf_grp(num, sel, &mpp_ctrl[3]); 182 continue; 183 } 184 185 shift = (num & 7) << 2; 186 if (*mpp_list & MPP_PMU_MASK) { 187 pmu_mpp_ctrl |= (0x1 << num); 188 pmu_sig_ctrl[num / 8] &= ~(0xf << shift); 189 pmu_sig_ctrl[num / 8] |= 0xf << shift; 190 gpio_mode = 0; 191 } else { 192 mpp_ctrl[num / 8] &= ~(0xf << shift); 193 mpp_ctrl[num / 8] |= sel << shift; 194 gpio_mode = GPIO_OUTPUT_OK | GPIO_INPUT_OK; 195 } 196 197 orion_gpio_set_valid(num, gpio_mode); 198 } 199 200 for (i = 0; i < MPP_NR_REGS; i++) 201 writel(mpp_ctrl[i], MPP_CTRL(i)); 202 203 for (i = 0; i < PMU_SIG_REGS; i++) 204 writel(pmu_sig_ctrl[i], PMU_SIG_CTRL(i)); 205 206 writel(pmu_mpp_ctrl, DOVE_PMU_MPP_GENERAL_CTRL); 207 208 dove_mpp_dump_regs(); 209 } 210