xref: /linux/arch/arm/mach-dove/mpp.c (revision 664cee46e755b37204f1731cb8726db610f3486d)
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