diff options
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0052-Implemented-Bone-Cape-configuration-from-EEPROM.-Onl.patch')
-rw-r--r-- | recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0052-Implemented-Bone-Cape-configuration-from-EEPROM.-Onl.patch | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0052-Implemented-Bone-Cape-configuration-from-EEPROM.-Onl.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0052-Implemented-Bone-Cape-configuration-from-EEPROM.-Onl.patch new file mode 100644 index 00000000..f0a3b770 --- /dev/null +++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/beaglebone/0052-Implemented-Bone-Cape-configuration-from-EEPROM.-Onl.patch | |||
@@ -0,0 +1,363 @@ | |||
1 | From ef6c0767e7c4337f45080906cda46a2c05e000f8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Bas Laarhoven <sjml@xs4all.nl> | ||
3 | Date: Sun, 13 May 2012 18:14:22 +0200 | ||
4 | Subject: [PATCH 52/56] Implemented Bone Cape configuration from EEPROM. Only | ||
5 | used for BEBOPR cape for now. | ||
6 | |||
7 | Signed-off-by: Bas Laarhoven <sjml@xs4all.nl> | ||
8 | Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> | ||
9 | --- | ||
10 | arch/arm/mach-omap2/board-am335xevm.c | 304 +++++++++++++++++++++++++++++++++ | ||
11 | arch/arm/mach-omap2/mux33xx.c | 14 ++ | ||
12 | 2 files changed, 318 insertions(+), 0 deletions(-) | ||
13 | |||
14 | diff --git a/arch/arm/mach-omap2/board-am335xevm.c b/arch/arm/mach-omap2/board-am335xevm.c | ||
15 | index c6ec997..7fb8295 100644 | ||
16 | --- a/arch/arm/mach-omap2/board-am335xevm.c | ||
17 | +++ b/arch/arm/mach-omap2/board-am335xevm.c | ||
18 | @@ -2231,6 +2231,304 @@ static void tt3201_init(int evm_id, int profile) | ||
19 | |||
20 | am33xx_d_can_init(1); | ||
21 | } | ||
22 | + | ||
23 | +static const char* cape_pins[] = { | ||
24 | +/* | ||
25 | + From SRM RevA5.0.1: | ||
26 | +*/ | ||
27 | + /* offset 88 - P9-22 */ "uart2_rxd", | ||
28 | + /* offset 90 - P9-21 */ "uart2_txd", | ||
29 | + /* offset 92 - P9-18 */ "spi0_d1", | ||
30 | + /* offset 94 - P9-17 */ "spi0_cs0", | ||
31 | + /* offset 96 - P9-42 */ "ecap0_in_pwm0_out", | ||
32 | + /* offset 98 - P8-35 */ "lcd_data12", | ||
33 | + /* offset 100 - P8-33 */ "lcd_data13", | ||
34 | + /* offset 102 - P8-31 */ "lcd_data14", | ||
35 | + /* offset 104 - P8-32 */ "lcd_data15", | ||
36 | + /* offset 106 - P9-19 */ "uart1_rtsn", | ||
37 | + /* offset 108 - P9-20 */ "uart1_ctsn", | ||
38 | + /* offset 110 - P9-26 */ "uart1_rxd", | ||
39 | + /* offset 112 - P9-24 */ "uart1_txd", | ||
40 | + /* offset 114 - P9-41 */ "xdma_event_intr1", | ||
41 | + /* offset 116 - P8-19 */ "gpmc_ad8", | ||
42 | + /* offset 118 - P8-13 */ "gpmc_ad9", | ||
43 | + /* offset 120 - P8-14 */ "gpmc_ad10", | ||
44 | + /* offset 122 - P8-17 */ "gpmc_ad12", | ||
45 | + /* offset 124 - P9-11 */ "gpmc_wait0", | ||
46 | + /* offset 126 - P9-13 */ "gpmc_wpn", | ||
47 | + /* offset 128 - P8-25 */ "gpmc_ad0", | ||
48 | + /* offset 130 - P8-24 */ "gpmc_ad1", | ||
49 | + /* offset 132 - P8- 5 */ "gpmc_ad2", | ||
50 | + /* offset 134 - P8- 6 */ "gpmc_ad3", | ||
51 | + /* offset 136 - P8-23 */ "gpmc_ad4", | ||
52 | + /* offset 138 - P8-22 */ "gpmc_ad5", | ||
53 | + /* offset 140 - P8- 3 */ "gpmc_ad6", | ||
54 | + /* offset 142 - P8- 4 */ "gpmc_ad7", | ||
55 | + /* offset 144 - P8-12 */ "gpmc_ad12", | ||
56 | + /* offset 146 - P8-11 */ "gpmc_ad13", | ||
57 | + /* offset 148 - P8-16 */ "gpmc_ad14", | ||
58 | + /* offset 150 - P8-15 */ "gpmc_ad15", | ||
59 | + /* offset 152 - P9-15 */ "gpmc_a0", | ||
60 | + /* offset 154 - P9-23 */ "gpmc_a1", | ||
61 | + /* offset 156 - P9-14 */ "gpmc_a2", | ||
62 | + /* offset 158 - P9-16 */ "gpmc_a3", | ||
63 | + /* offset 160 - P9-12 */ "gpmc_be1n", | ||
64 | + /* offset 162 - P8-26 */ "gpmc_csn0", | ||
65 | + /* offset 164 - P8-21 */ "gpmc_csn1", | ||
66 | + /* offset 166 - P8-20 */ "gpmc_csn2", | ||
67 | + /* offset 168 - P8-18 */ "gpmc_clk", | ||
68 | + /* offset 170 - P8-7 */ "gpmc_advn_ale", | ||
69 | + /* offset 172 - P8-9 */ "gpmc_ben0_cle", | ||
70 | + /* offset 174 - P8-10 */ "gpmc_wen", | ||
71 | + /* offset 176 - P8-8 */ "gpmc_csn3", | ||
72 | + /* offset 178 - P8-45 */ "lcd_data0", | ||
73 | + /* offset 180 - P8-46 */ "lcd_data1", | ||
74 | + /* offset 182 - P8-43 */ "lcd_data2", | ||
75 | + /* offset 184 - P8-44 */ "lcd_data3", | ||
76 | + /* offset 186 - P8-41 */ "lcd_data4", | ||
77 | + /* offset 188 - P8-42 */ "lcd_data5", | ||
78 | + /* offset 190 - P8-39 */ "lcd_data6", | ||
79 | + /* offset 192 - P8-40 */ "lcd_data7", | ||
80 | + /* offset 194 - P8-37 */ "lcd_data8", | ||
81 | + /* offset 196 - P8-38 */ "lcd_data9", | ||
82 | + /* offset 198 - P8-36 */ "lcd_data10", | ||
83 | + /* offset 200 - P8-34 */ "lcd_data11", | ||
84 | + /* offset 202 - P8-27 */ "lcd_vsync", | ||
85 | + /* offset 204 - P8-29 */ "lcd_hsync", | ||
86 | + /* offset 206 - P8-28 */ "lcd_pclk", | ||
87 | + /* offset 208 - P8-30 */ "lcd_ac_bias_en", | ||
88 | + /* offset 210 - P9-29 */ "mcasp0_fsx", | ||
89 | + /* offset 212 - P9-30 */ "mcasp0_axr0", | ||
90 | + /* offset 214 - P9-28 */ "mcasp0_ahclkr", | ||
91 | + /* offset 216 - P9-27 */ "mcasp0_fsr", | ||
92 | + /* offset 218 - P9-31 */ "mcasp0_aclkx", | ||
93 | + /* offset 220 - P9-25 */ "mcasp0_ahclkx", | ||
94 | + /* offset 222 - P9-39 */ "ain0", | ||
95 | + /* offset 224 - P9-40 */ "ain1", | ||
96 | + /* offset 226 - P9-37 */ "ain2", | ||
97 | + /* offset 228 - P9-38 */ "ain3", | ||
98 | + /* offset 230 - P9-33 */ "ain4", | ||
99 | + /* offset 232 - P9-36 */ "ain5", | ||
100 | + /* offset 234 - P9-35 */ "ain6", | ||
101 | +}; | ||
102 | + | ||
103 | +#define BIG_ENDIAN_16( i) ( ((i & 255) << 8) | ((i >> 8) & 255) ) | ||
104 | +#define NR_ITEMS( x) (sizeof( (x)) / sizeof( *(x))) | ||
105 | + | ||
106 | +extern int am33xx_mux_get_entry( int index, struct omap_mux** mux); | ||
107 | + | ||
108 | +typedef union { | ||
109 | +/* | ||
110 | + From SRM RevA5.0.1: | ||
111 | + Bit 15 Pin is used or not: 0=Unused by Cape 1=Used by Cape | ||
112 | + Bit 14-13 Pin Direction: 10=Output 01=Input 11=BDIR | ||
113 | + Bit 12-7 Reserved | ||
114 | + Bit 6 Slew Rate: 0=Fast 1=Slow | ||
115 | + Bit 5 Rx Enable: 0=Disabled 1=Enabled | ||
116 | + Bit 4 Pull Up/Dn Select: 0=Pulldown 1=PullUp | ||
117 | + Bit 3 Pull Up/DN enabled: 0=Enabled 1=Disabled | ||
118 | + Bit 2-0 Mux Mode Selection: Mode 0-7 | ||
119 | +*/ | ||
120 | + struct { | ||
121 | + uint16_t mux : 3; | ||
122 | + uint16_t pull_enable : 1; | ||
123 | + uint16_t pull_up : 1; | ||
124 | + uint16_t rx_enable : 1; | ||
125 | + uint16_t slew_rate : 1; | ||
126 | + uint16_t reserved : 6; | ||
127 | + uint16_t direction : 2; | ||
128 | + uint16_t used : 1; | ||
129 | + }; | ||
130 | + uint16_t value; | ||
131 | +} pin_def; | ||
132 | + | ||
133 | +#define DEBUG_EEPROM_CONFIG 0 | ||
134 | + | ||
135 | +static int bone_io_get_mux_setting( pin_def setting) | ||
136 | +{ | ||
137 | + int pin_setting; | ||
138 | + | ||
139 | + switch (setting.direction) { | ||
140 | + case 1: | ||
141 | + /* input */ | ||
142 | + if (setting.pull_enable) { | ||
143 | + if (setting.pull_up) { | ||
144 | + pin_setting = AM33XX_PIN_INPUT_PULLUP; | ||
145 | + } else { | ||
146 | + pin_setting = AM33XX_PIN_INPUT_PULLDOWN; | ||
147 | + } | ||
148 | + } else { | ||
149 | + pin_setting = AM33XX_PIN_INPUT; | ||
150 | + } | ||
151 | + if (!setting.rx_enable) { | ||
152 | +#if DEBUG_EEPROM_CONFIG | ||
153 | + pr_warning( " pin is set as input but the receiver is not enabled!\n"); | ||
154 | +#endif | ||
155 | + } | ||
156 | + break; | ||
157 | + case 2: | ||
158 | + /* output */ | ||
159 | + pin_setting = AM33XX_PIN_OUTPUT; | ||
160 | + break; | ||
161 | + case 3: | ||
162 | + /* bi-dir */ | ||
163 | + default: | ||
164 | + /* reserved */ | ||
165 | +#if DEBUG_EEPROM_CONFIG | ||
166 | + pr_warning( " pin ignored because it uses an unsupported mode: 0x%04x\n", | ||
167 | + setting.direction); | ||
168 | +#endif | ||
169 | + return -1; | ||
170 | + } | ||
171 | +#if DEBUG_EEPROM_CONFIG | ||
172 | + pr_info(" pin is configured as %s\n", | ||
173 | + (pin_setting & AM33XX_PIN_INPUT) ? "input" : "output"); | ||
174 | +#endif | ||
175 | + switch (setting.mux) { | ||
176 | + case 0: pin_setting |= OMAP_MUX_MODE0; break; | ||
177 | + case 1: pin_setting |= OMAP_MUX_MODE1; break; | ||
178 | + case 2: pin_setting |= OMAP_MUX_MODE2; break; | ||
179 | + case 3: pin_setting |= OMAP_MUX_MODE3; break; | ||
180 | + case 4: pin_setting |= OMAP_MUX_MODE4; break; | ||
181 | + case 5: pin_setting |= OMAP_MUX_MODE5; break; | ||
182 | + case 6: pin_setting |= OMAP_MUX_MODE6; break; | ||
183 | + case 7: pin_setting |= OMAP_MUX_MODE7; break; | ||
184 | + } | ||
185 | + return pin_setting; | ||
186 | +} | ||
187 | + | ||
188 | +static struct omap_mux* bone_io_pin_lookup( const char* pin_name) | ||
189 | +{ | ||
190 | + int index = 0; | ||
191 | + struct omap_mux* mux; | ||
192 | + | ||
193 | + for (;;) { | ||
194 | + if (am33xx_mux_get_entry( index, &mux) < 0) { | ||
195 | + /* no more entries */ | ||
196 | +#if DEBUG_EEPROM_CONFIG | ||
197 | + pr_warning( " configuration error, pin '%s' not found in mux database\n", | ||
198 | + pin_name); | ||
199 | +#endif | ||
200 | + return NULL; | ||
201 | + } | ||
202 | + if (mux != NULL && | ||
203 | + mux->muxnames[ 0] != NULL && | ||
204 | + strcmp( mux->muxnames[ 0], pin_name) == 0) | ||
205 | + { | ||
206 | + /* entry found */ | ||
207 | +#if DEBUG_EEPROM_CONFIG | ||
208 | + pr_info( " found pin '%s' at index %d in mux database'\n", | ||
209 | + pin_name, index); | ||
210 | +#endif | ||
211 | + return mux; | ||
212 | + } | ||
213 | + ++index; | ||
214 | + } | ||
215 | +} | ||
216 | + | ||
217 | +static int bone_io_config_pin( const char* pin_name, pin_def eeprom_setting) | ||
218 | +{ | ||
219 | + struct omap_mux* mux; | ||
220 | + char* signal_name; | ||
221 | + int pin_setting = bone_io_get_mux_setting( eeprom_setting); | ||
222 | + int l1, l2; | ||
223 | + char full_name[ 50]; | ||
224 | + | ||
225 | + if (pin_setting < 0) { | ||
226 | + return -1; | ||
227 | + } | ||
228 | + | ||
229 | + mux = bone_io_pin_lookup( pin_name); | ||
230 | + | ||
231 | + if (mux == NULL) { | ||
232 | + return -1; | ||
233 | + } | ||
234 | + | ||
235 | + signal_name = mux->muxnames[ eeprom_setting.mux]; | ||
236 | + | ||
237 | + if (signal_name == NULL) { | ||
238 | +#if DEBUG_EEPROM_CONFIG | ||
239 | + pr_warning( " Configuration error, no signal found for pin '%s' in mode %d\n", | ||
240 | + pin_name, eeprom_setting.mux); | ||
241 | +#endif | ||
242 | + return -1; | ||
243 | + } | ||
244 | + | ||
245 | +#if DEBUG_EEPROM_CONFIG | ||
246 | + pr_info( " setting pin '%s' to signal '%s'\n", | ||
247 | + pin_name, signal_name); | ||
248 | +#endif | ||
249 | + l1 = strlen( pin_name); | ||
250 | + l2 = strlen( signal_name); | ||
251 | + | ||
252 | + if (l1 + 1 + l2 + 1 > sizeof( full_name)) { | ||
253 | +#if DEBUG_EEPROM_CONFIG | ||
254 | + pr_warning( " Internal error, combined signal name too long\n"); | ||
255 | +#endif | ||
256 | + return -1; | ||
257 | + } else { | ||
258 | + memcpy( full_name, pin_name, l1); | ||
259 | + full_name[ l1] = '.'; | ||
260 | + memcpy( full_name + l1 + 1, signal_name, l2); | ||
261 | + full_name[ l1 + 1 + l2] = '\0'; | ||
262 | + if (omap_mux_init_signal( full_name, pin_setting) < 0) { | ||
263 | + return -1; | ||
264 | + } | ||
265 | +#if DEBUG_EEPROM_CONFIG | ||
266 | + pr_info( " mux '%s' was set to mode 0x%04x\n", | ||
267 | + full_name, pin_setting); | ||
268 | +#endif | ||
269 | + } | ||
270 | + // return 0 for input, 1 for output | ||
271 | + return (pin_setting & AM33XX_PIN_INPUT) ? 0 : 1; | ||
272 | +} | ||
273 | + | ||
274 | +#define RULER( x) \ | ||
275 | + do { \ | ||
276 | + char* p = status; \ | ||
277 | + int i = 0; \ | ||
278 | + int cnt = x; \ | ||
279 | + status[ cnt] = '\0'; \ | ||
280 | + while (cnt--) { \ | ||
281 | + if (++i == 10) { \ | ||
282 | + *p++ = '+'; \ | ||
283 | + i = 0; \ | ||
284 | + } else { \ | ||
285 | + *p++ = '-'; \ | ||
286 | + } \ | ||
287 | + } \ | ||
288 | + pr_info( "+%s+\n", status); \ | ||
289 | + } while (0) | ||
290 | + | ||
291 | +static void bone_io_config_from_cape_eeprom( void) | ||
292 | +{ | ||
293 | + int i; | ||
294 | + int cnt = BIG_ENDIAN_16( cape_config.numpins); | ||
295 | + u16* pmuxdata; | ||
296 | + char status[ NR_ITEMS( cape_config.muxdata) + 1]; | ||
297 | + | ||
298 | + pr_info( "BeagleBone cape: configuring %2d out of %2d signals:\n", | ||
299 | + cnt, NR_ITEMS( cape_config.muxdata)); | ||
300 | + RULER( NR_ITEMS( cape_config.muxdata)); | ||
301 | + for (i = 0, pmuxdata = cape_config.muxdata ; i < NR_ITEMS( cape_config.muxdata) ; ++i, ++pmuxdata) { | ||
302 | + const char* pin_name = cape_pins[ i]; | ||
303 | + pin_def pin_setting = { .value = BIG_ENDIAN_16( *pmuxdata) }; | ||
304 | + | ||
305 | + if (pin_setting.used) { | ||
306 | + switch (bone_io_config_pin( pin_name, pin_setting)) { | ||
307 | + case 0: status[ i] = 'i'; break; | ||
308 | + case 1: status[ i] = 'o'; break; | ||
309 | + default: status[ i] = '#'; break; | ||
310 | + } | ||
311 | + } else { | ||
312 | + status[ i] = ' '; | ||
313 | + } | ||
314 | + } | ||
315 | + status[ NR_ITEMS( cape_config.muxdata)] = '\0'; | ||
316 | + pr_info( "|%s|\n", status); | ||
317 | + RULER( NR_ITEMS( cape_config.muxdata)); | ||
318 | +} | ||
319 | + | ||
320 | static void beaglebone_cape_setup(struct memory_accessor *mem_acc, void *context) | ||
321 | { | ||
322 | int ret; | ||
323 | @@ -2280,6 +2578,12 @@ static void beaglebone_cape_setup(struct memory_accessor *mem_acc, void *context | ||
324 | snprintf(tmp, sizeof(cape_config.partnumber) + 1, "%s", cape_config.partnumber); | ||
325 | pr_info("BeagleBone cape partnumber: %s\n", tmp); | ||
326 | |||
327 | + if (!strncmp( "BEBOPR", cape_config.name, 6)) { | ||
328 | + pr_info( "BeagleBone cape: initializing BEBOPR cape\n"); | ||
329 | + bone_io_config_from_cape_eeprom(); | ||
330 | + return; // if configured from eeprom, skip all other initialization | ||
331 | + } | ||
332 | + | ||
333 | if (!strncmp("BB-BONE-DVID-01", cape_config.partnumber, 15)) { | ||
334 | pr_info("BeagleBone cape: initializing DVI cape\n"); | ||
335 | |||
336 | diff --git a/arch/arm/mach-omap2/mux33xx.c b/arch/arm/mach-omap2/mux33xx.c | ||
337 | index 72ac899..43c8989 100644 | ||
338 | --- a/arch/arm/mach-omap2/mux33xx.c | ||
339 | +++ b/arch/arm/mach-omap2/mux33xx.c | ||
340 | @@ -616,6 +616,20 @@ int __init am33xx_mux_init(struct omap_board_mux *board_subset) | ||
341 | AM33XX_CONTROL_PADCONF_MUX_SIZE, am33xx_muxmodes, | ||
342 | NULL, board_subset, NULL); | ||
343 | } | ||
344 | + | ||
345 | +#define NR_ITEMS( x) (sizeof( (x)) / sizeof( *(x))) | ||
346 | + | ||
347 | +int am33xx_mux_get_entry( int index, struct omap_mux** mux) | ||
348 | +{ | ||
349 | + if (index >= 0 && index < NR_ITEMS( am33xx_muxmodes)) { | ||
350 | + *mux = &am33xx_muxmodes[ index]; | ||
351 | + return 0; | ||
352 | + } else { | ||
353 | + *mux = NULL; | ||
354 | + return -1; | ||
355 | + } | ||
356 | +} | ||
357 | + | ||
358 | #else | ||
359 | int __init am33xx_mux_init(struct omap_board_mux *board_subset) | ||
360 | { | ||
361 | -- | ||
362 | 1.7.7.6 | ||
363 | |||