1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <common.h>
25#include <env.h>
26#include <watchdog.h>
27#include <malloc.h>
28#include <twl4030.h>
29#include <i2c.h>
30#include <video_fb.h>
31#include <asm/io.h>
32#include <asm/setup.h>
33#include <asm/bitops.h>
34#include <asm/mach-types.h>
35#include <asm/arch/mux.h>
36#include <asm/arch/sys_proto.h>
37#include <asm/arch/mmc_host_def.h>
38
39#include "rx51.h"
40#include "tag_omap.h"
41
42DECLARE_GLOBAL_DATA_PTR;
43
44GraphicDevice gdev;
45
46const omap3_sysinfo sysinfo = {
47 DDR_STACKED,
48 "Nokia RX-51",
49 "OneNAND"
50};
51
52
53static struct tag_omap omap[] = {
54 OMAP_TAG_UART_CONFIG(0x04),
55 OMAP_TAG_SERIAL_CONSOLE_CONFIG(0x03, 0x01C200),
56 OMAP_TAG_LCD_CONFIG("acx565akm", "internal", 90, 0x18),
57 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_focus", 0x44, 0x1, 0x2, 0x0),
58 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_launch", 0x45, 0x1, 0x2, 0x0),
59 OMAP_TAG_GPIO_SWITCH_CONFIG("cam_shutter", 0x6e, 0x1, 0x0, 0x0),
60 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_apeslpx", 0x46, 0x2, 0x2, 0x0),
61 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_bsi", 0x9d, 0x2, 0x2, 0x0),
62 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_en", 0x4a, 0x2, 0x2, 0x0),
63 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_rst", 0x4b, 0x6, 0x2, 0x0),
64 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_rst_rq", 0x49, 0x6, 0x2, 0x0),
65 OMAP_TAG_GPIO_SWITCH_CONFIG("cmt_wddis", 0x0d, 0x2, 0x2, 0x0),
66 OMAP_TAG_GPIO_SWITCH_CONFIG("headphone", 0xb1, 0x1, 0x1, 0x0),
67 OMAP_TAG_GPIO_SWITCH_CONFIG("kb_lock", 0x71, 0x1, 0x0, 0x0),
68 OMAP_TAG_GPIO_SWITCH_CONFIG("proximity", 0x59, 0x0, 0x0, 0x0),
69 OMAP_TAG_GPIO_SWITCH_CONFIG("sleep_ind", 0xa2, 0x2, 0x2, 0x0),
70 OMAP_TAG_GPIO_SWITCH_CONFIG("slide", GPIO_SLIDE, 0x0, 0x0, 0x0),
71 OMAP_TAG_WLAN_CX3110X_CONFIG(0x25, 0xff, 87, 42, -1),
72 OMAP_TAG_PARTITION_CONFIG(PART1_NAME, PART1_SIZE * PART1_MULL,
73 PART1_OFFS, PART1_MASK),
74 OMAP_TAG_PARTITION_CONFIG(PART2_NAME, PART2_SIZE * PART2_MULL,
75 PART2_OFFS, PART2_MASK),
76 OMAP_TAG_PARTITION_CONFIG(PART3_NAME, PART3_SIZE * PART3_MULL,
77 PART3_OFFS, PART3_MASK),
78 OMAP_TAG_PARTITION_CONFIG(PART4_NAME, PART4_SIZE * PART4_MULL,
79 PART4_OFFS, PART4_MASK),
80 OMAP_TAG_PARTITION_CONFIG(PART5_NAME, PART5_SIZE * PART5_MULL,
81 PART5_OFFS, PART5_MASK),
82 OMAP_TAG_PARTITION_CONFIG(PART6_NAME, PART6_SIZE * PART6_MULL,
83 PART6_OFFS, PART6_MASK),
84 OMAP_TAG_BOOT_REASON_CONFIG("pwr_key"),
85 OMAP_TAG_VERSION_STR_CONFIG("product", "RX-51"),
86 OMAP_TAG_VERSION_STR_CONFIG("hw-build", "2101"),
87 OMAP_TAG_VERSION_STR_CONFIG("nolo", "1.4.14"),
88 OMAP_TAG_VERSION_STR_CONFIG("boot-mode", "normal"),
89 { }
90};
91
92static char *boot_reason_ptr;
93static char *hw_build_ptr;
94static char *nolo_version_ptr;
95static char *boot_mode_ptr;
96
97
98
99
100
101static void init_omap_tags(void)
102{
103 char *component;
104 char *version;
105 int i = 0;
106 while (omap[i].hdr.tag) {
107 switch (omap[i].hdr.tag) {
108 case OMAP_TAG_BOOT_REASON:
109 boot_reason_ptr = omap[i].u.boot_reason.reason_str;
110 break;
111 case OMAP_TAG_VERSION_STR:
112 component = omap[i].u.version.component;
113 version = omap[i].u.version.version;
114 if (strcmp(component, "hw-build") == 0)
115 hw_build_ptr = version;
116 else if (strcmp(component, "nolo") == 0)
117 nolo_version_ptr = version;
118 else if (strcmp(component, "boot-mode") == 0)
119 boot_mode_ptr = version;
120 break;
121 default:
122 break;
123 }
124 i++;
125 }
126}
127
128static void reuse_omap_atags(struct tag_omap *t)
129{
130 char *component;
131 char *version;
132 while (t->hdr.tag) {
133 switch (t->hdr.tag) {
134 case OMAP_TAG_BOOT_REASON:
135 memset(boot_reason_ptr, 0, 12);
136 strcpy(boot_reason_ptr, t->u.boot_reason.reason_str);
137 break;
138 case OMAP_TAG_VERSION_STR:
139 component = t->u.version.component;
140 version = t->u.version.version;
141 if (strcmp(component, "hw-build") == 0) {
142 memset(hw_build_ptr, 0, 12);
143 strcpy(hw_build_ptr, version);
144 } else if (strcmp(component, "nolo") == 0) {
145 memset(nolo_version_ptr, 0, 12);
146 strcpy(nolo_version_ptr, version);
147 } else if (strcmp(component, "boot-mode") == 0) {
148 memset(boot_mode_ptr, 0, 12);
149 strcpy(boot_mode_ptr, version);
150 }
151 break;
152 default:
153 break;
154 }
155 t = tag_omap_next(t);
156 }
157}
158
159
160
161
162
163
164static void reuse_atags(void)
165{
166 struct tag *t = (struct tag *)gd->bd->bi_boot_params;
167
168
169 if (t->hdr.tag != ATAG_CORE)
170 return;
171
172 if (!boot_reason_ptr || !hw_build_ptr)
173 return;
174
175
176 while (t->hdr.tag != ATAG_NONE) {
177 switch (t->hdr.tag) {
178 case ATAG_REVISION:
179 memset(hw_build_ptr, 0, 12);
180 sprintf(hw_build_ptr, "%x", t->u.revision.rev);
181 break;
182 case ATAG_BOARD:
183 reuse_omap_atags((struct tag_omap *)&t->u);
184 break;
185 default:
186 break;
187 }
188 t = tag_next(t);
189 }
190}
191
192
193
194
195
196int board_init(void)
197{
198
199 gpmc_init();
200
201 gd->bd->bi_boot_params = OMAP34XX_SDRC_CS0 + 0x100;
202 return 0;
203}
204
205
206
207
208
209u32 get_board_rev(void)
210{
211 return simple_strtol(hw_build_ptr, NULL, 16);
212}
213
214
215
216
217
218void setup_board_tags(struct tag **in_params)
219{
220 int setup_console_atag;
221 char *setup_boot_reason_atag;
222 char *setup_boot_mode_atag;
223 char *str;
224 int i;
225 int size;
226 int total_size;
227 struct tag *params;
228 struct tag_omap *t;
229
230 params = (struct tag *)gd->bd->bi_boot_params;
231
232 params->u.core.flags = 0x0;
233 params->u.core.pagesize = 0x1000;
234 params->u.core.rootdev = 0x0;
235
236
237 str = env_get("setup_omap_atag");
238 if (!str || str[0] != '1')
239 return;
240
241 str = env_get("setup_console_atag");
242 if (str && str[0] == '1')
243 setup_console_atag = 1;
244 else
245 setup_console_atag = 0;
246
247 setup_boot_reason_atag = env_get("setup_boot_reason_atag");
248 setup_boot_mode_atag = env_get("setup_boot_mode_atag");
249
250 params = *in_params;
251 t = (struct tag_omap *)¶ms->u;
252 total_size = sizeof(struct tag_header);
253
254 for (i = 0; omap[i].hdr.tag; i++) {
255
256
257 if (!setup_console_atag &&
258 omap[i].hdr.tag == OMAP_TAG_SERIAL_CONSOLE)
259 continue;
260
261 size = omap[i].hdr.size + sizeof(struct tag_omap_header);
262 memcpy(t, &omap[i], size);
263
264
265 if (!setup_console_atag && omap[i].hdr.tag == OMAP_TAG_UART)
266 t->u.uart.enabled_uarts = 0;
267
268
269 if (setup_boot_reason_atag &&
270 omap[i].hdr.tag == OMAP_TAG_BOOT_REASON) {
271 memset(t->u.boot_reason.reason_str, 0, 12);
272 strcpy(t->u.boot_reason.reason_str,
273 setup_boot_reason_atag);
274 }
275
276
277 if (setup_boot_mode_atag &&
278 omap[i].hdr.tag == OMAP_TAG_VERSION_STR &&
279 strcmp(omap[i].u.version.component, "boot-mode") == 0) {
280 memset(t->u.version.version, 0, 12);
281 strcpy(t->u.version.version, setup_boot_mode_atag);
282 }
283
284 total_size += size;
285 t = tag_omap_next(t);
286
287 }
288
289 params->hdr.tag = ATAG_BOARD;
290 params->hdr.size = total_size >> 2;
291 params = tag_next(params);
292
293 *in_params = params;
294}
295
296
297
298
299
300void *video_hw_init(void)
301{
302
303 gdev.frameAdrs = 0x8f9c0000;
304 gdev.winSizeX = 800;
305 gdev.winSizeY = 480;
306 gdev.gdfBytesPP = 2;
307 gdev.gdfIndex = GDF_16BIT_565RGB;
308 memset((void *)gdev.frameAdrs, 0, 0xbb800);
309 return (void *) &gdev;
310}
311
312
313
314
315
316static void twl4030_regulator_set_mode(u8 id, u8 mode)
317{
318 u16 msg = MSG_SINGULAR(DEV_GRP_P1, id, mode);
319 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
320 TWL4030_PM_MASTER_PB_WORD_MSB, msg >> 8);
321 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
322 TWL4030_PM_MASTER_PB_WORD_LSB, msg & 0xff);
323}
324
325static void omap3_emu_romcode_call(u32 service_id, u32 *parameters)
326{
327 u32 i, num_params = *parameters;
328 u32 *sram_scratch_space = (u32 *)OMAP3_PUBLIC_SRAM_SCRATCH_AREA;
329
330
331
332
333
334 for (i = 0; i < num_params; i++) {
335 __raw_writel(*parameters, sram_scratch_space);
336 parameters++;
337 sram_scratch_space++;
338 }
339
340
341 do_omap3_emu_romcode_call(service_id, OMAP3_PUBLIC_SRAM_SCRATCH_AREA);
342}
343
344void omap3_set_aux_cr_secure(u32 acr)
345{
346 struct emu_hal_params_rx51 emu_romcode_params = { 0, };
347
348 emu_romcode_params.num_params = 2;
349 emu_romcode_params.param1 = acr;
350
351 omap3_emu_romcode_call(OMAP3_EMU_HAL_API_WRITE_ACR,
352 (u32 *)&emu_romcode_params);
353}
354
355
356
357
358
359
360
361
362static void omap3_update_aux_cr_secure_rx51(u32 set_bits, u32 clear_bits)
363{
364 u32 acr;
365
366
367 asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
368 acr &= ~clear_bits;
369 acr |= set_bits;
370 omap3_set_aux_cr_secure(acr);
371}
372
373
374
375
376
377int misc_init_r(void)
378{
379 char buf[12];
380 u8 state;
381
382
383 i2c_set_bus_num(1);
384 state = 0xff;
385 i2c_write(0x32, 0x3d, 1, &state, 1);
386 i2c_set_bus_num(0);
387
388
389 twl4030_power_init();
390
391
392 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VSIM_DEDICATED,
393 TWL4030_PM_RECEIVER_VSIM_VSEL_18,
394 TWL4030_PM_RECEIVER_VSIM_DEV_GRP,
395 TWL4030_PM_RECEIVER_DEV_GRP_P1);
396
397
398 twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
399 &state);
400
401
402 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
403 0x02);
404
405
406 twl4030_regulator_set_mode(RES_VAUX3, RES_STATE_ACTIVE);
407 twl4030_regulator_set_mode(RES_VSIM, RES_STATE_ACTIVE);
408 twl4030_regulator_set_mode(RES_VMMC1, RES_STATE_ACTIVE);
409
410
411 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, TWL4030_PM_MASTER_PB_CFG,
412 state);
413
414
415 sprintf(buf, "%#x", KERNEL_ADDRESS);
416 env_set("attkernaddr", buf);
417
418
419 init_omap_tags();
420
421
422 reuse_atags();
423
424 omap_die_id_display();
425 print_cpuinfo();
426
427
428
429
430
431
432
433
434 if (get_device_type() == HS_DEVICE)
435 omap3_update_aux_cr_secure_rx51(1 << 6, 0);
436
437 return 0;
438}
439
440
441
442
443
444
445
446void set_muxconf_regs(void)
447{
448 MUX_RX51();
449}
450
451static unsigned long int twl_wd_time;
452static unsigned long int twl_i2c_lock;
453
454
455
456
457
458void hw_watchdog_reset(void)
459{
460 u8 timeout = 0;
461
462
463 if (get_timer(twl_wd_time) < 4 * CONFIG_SYS_HZ)
464 return;
465
466
467 if (test_and_set_bit(0, &twl_i2c_lock))
468 return;
469
470
471 twl4030_i2c_read_u8(TWL4030_CHIP_PM_RECEIVER,
472 TWL4030_PM_RECEIVER_WATCHDOG_CFG, &timeout);
473
474
475
476 if (timeout != 0)
477 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER,
478 TWL4030_PM_RECEIVER_WATCHDOG_CFG, 31);
479
480
481 twl_wd_time = get_timer(0);
482
483
484 test_and_clear_bit(0, &twl_i2c_lock);
485}
486
487
488
489
490
491static const char keymap[] = {
492
493 'q', 'o', 'p', ',', '\b', 0, 'a', 's',
494 'w', 'd', 'f', 'g', 'h', 'j', 'k', 'l',
495 'e', '.', 0, '\r', 0, 'z', 'x', 'c',
496 'r', 'v', 'b', 'n', 'm', ' ', ' ', 0,
497 't', 0, 0, 0, 0, 0, 0, 0,
498 'y', 0, 0, 0, 0, 0, 0, 0,
499 'u', 0, 0, 0, 0, 0, 0, 0,
500 'i', 5, 6, 0, 0, 0, 0, 0,
501
502 '1', '9', '0', '=', '\b', 0, '*', '+',
503 '2', '#', '-', '_', '(', ')', '&', '!',
504 '3', '?', '^', '\r', 0, 156, '$', 238,
505 '4', '/', '\\', '"', '\'', '@', 0, '<',
506 '5', '|', '>', 0, 0, 0, 0, 0,
507 '6', 0, 0, 0, 0, 0, 0, 0,
508 '7', 0, 0, 0, 0, 0, 0, 0,
509 '8', 16, 17, 0, 0, 0, 0, 0,
510};
511
512static u8 keys[8];
513static u8 old_keys[8] = {0, 0, 0, 0, 0, 0, 0, 0};
514#define KEYBUF_SIZE 32
515static u8 keybuf[KEYBUF_SIZE];
516static u8 keybuf_head;
517static u8 keybuf_tail;
518
519
520
521
522
523int rx51_kp_init(void)
524{
525 int ret = 0;
526 u8 ctrl;
527 ret = twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD,
528 TWL4030_KEYPAD_KEYP_CTRL_REG, &ctrl);
529
530 if (ret)
531 return ret;
532
533
534 ctrl |= TWL4030_KEYPAD_CTRL_KBD_ON;
535 ctrl |= TWL4030_KEYPAD_CTRL_SOFT_NRST;
536 ctrl |= TWL4030_KEYPAD_CTRL_SOFTMODEN;
537 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
538 TWL4030_KEYPAD_KEYP_CTRL_REG, ctrl);
539
540 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
541 TWL4030_KEYPAD_KEYP_IMR1, 0xfe);
542
543
544 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
545 TWL4030_KEYPAD_KEYP_EDR, 0x57);
546
547 ret |= twl4030_i2c_write_u8(TWL4030_CHIP_KEYPAD,
548 TWL4030_KEYPAD_KEYP_SIH_CTRL, 0x05);
549 return 0;
550}
551
552static void rx51_kp_fill(u8 k, u8 mods)
553{
554
555 if (!(mods & 2) && (k == 18 || k == 31 || k == 33 || k == 34)) {
556 keybuf[keybuf_tail++] = '\e';
557 keybuf_tail %= KEYBUF_SIZE;
558 keybuf[keybuf_tail++] = '[';
559 keybuf_tail %= KEYBUF_SIZE;
560 if (k == 18)
561 keybuf[keybuf_tail++] = 'A';
562 else if (k == 31)
563 keybuf[keybuf_tail++] = 'D';
564 else if (k == 33)
565 keybuf[keybuf_tail++] = 'B';
566 else if (k == 34)
567 keybuf[keybuf_tail++] = 'C';
568 keybuf_tail %= KEYBUF_SIZE;
569 return;
570 }
571
572 if (mods & 2) {
573 k = keymap[k+64];
574 } else {
575 k = keymap[k];
576 if (mods & 1) {
577 if (k >= 'a' && k <= 'z')
578 k -= 'a' - 1;
579 }
580 if (mods & 4) {
581 if (k >= 'a' && k <= 'z')
582 k += 'A' - 'a';
583 else if (k == '.')
584 k = ':';
585 else if (k == ',')
586 k = ';';
587 }
588 }
589 keybuf[keybuf_tail++] = k;
590 keybuf_tail %= KEYBUF_SIZE;
591}
592
593
594
595
596
597int rx51_kp_tstc(struct stdio_dev *sdev)
598{
599 u8 c, r, dk, i;
600 u8 intr;
601 u8 mods;
602
603
604 if (test_and_set_bit(0, &twl_i2c_lock))
605 return 0;
606
607
608 for (i = 0; i < 2; i++) {
609
610
611 twl4030_i2c_read_u8(TWL4030_CHIP_KEYPAD,
612 TWL4030_KEYPAD_KEYP_ISR1 + (2 * i), &intr);
613
614
615 if (!(intr&1))
616 continue;
617
618
619 i2c_read(TWL4030_CHIP_KEYPAD,
620 TWL4030_KEYPAD_FULL_CODE_7_0, 1, keys, 8);
621
622
623 mods = keys[4] >> 4;
624 keys[4] &= 0x0f;
625
626 for (c = 0; c < 8; c++) {
627
628
629 dk = ((keys[c] ^ old_keys[c])&keys[c]);
630 old_keys[c] = keys[c];
631
632
633 for (r = 0; r < 8; r++) {
634 if (dk&1)
635 rx51_kp_fill((c*8)+r, mods);
636 dk = dk >> 1;
637 }
638
639 }
640
641 }
642
643
644 test_and_clear_bit(0, &twl_i2c_lock);
645
646 return (KEYBUF_SIZE + keybuf_tail - keybuf_head)%KEYBUF_SIZE;
647}
648
649
650
651
652
653int rx51_kp_getc(struct stdio_dev *sdev)
654{
655 keybuf_head %= KEYBUF_SIZE;
656 while (!rx51_kp_tstc(sdev))
657 WATCHDOG_RESET();
658 return keybuf[keybuf_head++];
659}
660
661
662
663
664
665int board_mmc_init(bd_t *bis)
666{
667 omap_mmc_init(0, 0, 0, -1, -1);
668 omap_mmc_init(1, 0, 0, -1, -1);
669 return 0;
670}
671
672void board_mmc_power_init(void)
673{
674 twl4030_power_mmc_init(0);
675 twl4030_power_mmc_init(1);
676}
677