enbw_cmc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. /*
  2. * (C) Copyright 2011
  3. * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  4. *
  5. * Based on:
  6. * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
  7. *
  8. * Based on da830evm.c. Original Copyrights follow:
  9. *
  10. * Copyright (C) 2009 Nick Thompson, GE Fanuc, Ltd. <nick.thompson@gefanuc.com>
  11. * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License as published by
  15. * the Free Software Foundation; either version 2 of the License, or
  16. * (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26. */
  27. #include <common.h>
  28. #include <command.h>
  29. #include <environment.h>
  30. #include <hwconfig.h>
  31. #include <i2c.h>
  32. #include <malloc.h>
  33. #include <miiphy.h>
  34. #include <mmc.h>
  35. #include <net.h>
  36. #include <netdev.h>
  37. #include <asm/gpio.h>
  38. #include <asm/io.h>
  39. #include <asm/arch/da850_lowlevel.h>
  40. #include <asm/arch/davinci_misc.h>
  41. #include <asm/arch/emif_defs.h>
  42. #include <asm/arch/emac_defs.h>
  43. #include <asm/arch/gpio.h>
  44. #include <asm/arch/pinmux_defs.h>
  45. #include <asm/arch/hardware.h>
  46. #include <asm/arch/sdmmc_defs.h>
  47. #include <asm/arch/timer_defs.h>
  48. DECLARE_GLOBAL_DATA_PTR;
  49. static const struct lpsc_resource lpsc[] = {
  50. { DAVINCI_LPSC_AEMIF },
  51. { DAVINCI_LPSC_SPI1 },
  52. { DAVINCI_LPSC_ARM_RAM_ROM },
  53. { DAVINCI_LPSC_UART0 },
  54. { DAVINCI_LPSC_EMAC },
  55. { DAVINCI_LPSC_UART0 },
  56. { DAVINCI_LPSC_GPIO },
  57. { DAVINCI_LPSC_DDR_EMIF },
  58. { DAVINCI_LPSC_UART1 },
  59. { DAVINCI_LPSC_UART2 },
  60. { DAVINCI_LPSC_MMC_SD1 },
  61. { DAVINCI_LPSC_USB20 },
  62. { DAVINCI_LPSC_USB11 },
  63. };
  64. static const struct pinmux_config enbw_pins[] = {
  65. { pinmux(0), 8, 0 },
  66. { pinmux(0), 8, 1 },
  67. { pinmux(0), 8, 2 },
  68. { pinmux(0), 8, 3 },
  69. { pinmux(0), 8, 4 },
  70. { pinmux(0), 8, 5 },
  71. { pinmux(1), 4, 0 },
  72. { pinmux(1), 8, 1 },
  73. { pinmux(1), 8, 2 },
  74. { pinmux(1), 8, 3 },
  75. { pinmux(1), 8, 4 },
  76. { pinmux(1), 8, 5 },
  77. { pinmux(1), 8, 6 },
  78. { pinmux(1), 4, 7 },
  79. { pinmux(2), 8, 0 },
  80. { pinmux(5), 1, 0 },
  81. { pinmux(5), 1, 3 },
  82. { pinmux(5), 1, 7 },
  83. { pinmux(6), 1, 0 },
  84. { pinmux(6), 1, 1 },
  85. { pinmux(6), 8, 2 },
  86. { pinmux(6), 8, 3 },
  87. { pinmux(6), 1, 4 },
  88. { pinmux(6), 8, 5 },
  89. { pinmux(6), 1, 7 },
  90. { pinmux(7), 8, 2 },
  91. { pinmux(7), 1, 3 },
  92. { pinmux(7), 1, 6 },
  93. { pinmux(7), 1, 7 },
  94. { pinmux(13), 8, 2 },
  95. { pinmux(13), 8, 3 },
  96. { pinmux(13), 8, 4 },
  97. { pinmux(13), 8, 5 },
  98. { pinmux(13), 8, 6 },
  99. { pinmux(13), 8, 7 },
  100. { pinmux(14), 8, 0 },
  101. { pinmux(14), 8, 1 },
  102. { pinmux(16), 8, 1 },
  103. { pinmux(16), 8, 2 },
  104. { pinmux(16), 8, 3 },
  105. { pinmux(16), 8, 4 },
  106. { pinmux(16), 8, 5 },
  107. { pinmux(16), 8, 6 },
  108. { pinmux(16), 8, 7 },
  109. { pinmux(17), 1, 0 },
  110. { pinmux(17), 1, 1 },
  111. { pinmux(17), 1, 2 },
  112. { pinmux(17), 8, 3 },
  113. { pinmux(17), 8, 4 },
  114. { pinmux(17), 8, 5 },
  115. { pinmux(17), 8, 6 },
  116. { pinmux(17), 8, 7 },
  117. { pinmux(18), 8, 0 },
  118. { pinmux(18), 8, 1 },
  119. { pinmux(18), 2, 2 },
  120. { pinmux(18), 2, 3 },
  121. { pinmux(18), 2, 4 },
  122. { pinmux(18), 8, 6 },
  123. { pinmux(18), 8, 7 },
  124. { pinmux(19), 8, 0 },
  125. { pinmux(19), 2, 1 },
  126. { pinmux(19), 2, 2 },
  127. { pinmux(19), 2, 3 },
  128. { pinmux(19), 2, 4 },
  129. { pinmux(19), 8, 5 },
  130. { pinmux(19), 8, 6 },
  131. };
  132. const struct pinmux_resource pinmuxes[] = {
  133. PINMUX_ITEM(emac_pins_mii),
  134. PINMUX_ITEM(emac_pins_mdio),
  135. PINMUX_ITEM(i2c0_pins),
  136. PINMUX_ITEM(emifa_pins_cs2),
  137. PINMUX_ITEM(emifa_pins_cs3),
  138. PINMUX_ITEM(emifa_pins_cs4),
  139. PINMUX_ITEM(emifa_pins_nand),
  140. PINMUX_ITEM(emifa_pins_nor),
  141. PINMUX_ITEM(spi1_pins_base),
  142. PINMUX_ITEM(spi1_pins_scs0),
  143. PINMUX_ITEM(uart1_pins_txrx),
  144. PINMUX_ITEM(uart2_pins_txrx),
  145. PINMUX_ITEM(uart2_pins_rtscts),
  146. PINMUX_ITEM(enbw_pins),
  147. };
  148. const int pinmuxes_size = ARRAY_SIZE(pinmuxes);
  149. struct gpio_config {
  150. char name[GPIO_NAME_SIZE];
  151. unsigned char bank;
  152. unsigned char gpio;
  153. unsigned char out;
  154. unsigned char value;
  155. };
  156. static const struct gpio_config enbw_gpio_config[] = {
  157. { "RS485 enable", 8, 11, 1, 0 },
  158. { "RS485 iso", 8, 10, 1, 0 },
  159. { "W2HUT RS485 Rx ena", 8, 9, 1, 0 },
  160. { "W2HUT RS485 iso", 8, 8, 1, 0 },
  161. { "LAN reset", 7, 15, 1, 1 },
  162. { "ena 11V PLC", 7, 14, 1, 0 },
  163. { "ena 1.5V PLC", 7, 13, 1, 0 },
  164. { "disable VBUS", 7, 12, 1, 1 },
  165. { "PLC reset", 6, 13, 1, 1 },
  166. { "LCM RS", 6, 12, 1, 0 },
  167. { "LCM R/W", 6, 11, 1, 0 },
  168. { "PLC pairing", 6, 10, 1, 1 },
  169. { "PLC MDIO CLK", 6, 9, 1, 0 },
  170. { "HK218", 6, 8, 1, 0 },
  171. { "HK218 Rx", 6, 1, 1, 1 },
  172. { "TPM reset", 6, 0, 1, 1 },
  173. { "LCM E", 2, 2, 1, 1 },
  174. { "PV-IF RxD ena", 0, 15, 1, 1 },
  175. { "LED1", 1, 15, 1, 1 },
  176. { "LED2", 0, 1, 1, 1 },
  177. { "LED3", 0, 2, 1, 1 },
  178. { "LED4", 0, 3, 1, 1 },
  179. { "LED5", 0, 4, 1, 1 },
  180. { "LED6", 0, 5, 1, 0 },
  181. { "LED7", 0, 6, 1, 0 },
  182. { "LED8", 0, 14, 1, 0 },
  183. { "USER1", 0, 12, 0, 0 },
  184. { "USER2", 0, 13, 0, 0 },
  185. };
  186. #define PHY_POWER 0x0800
  187. static void enbw_cmc_switch(int port, int on)
  188. {
  189. const char *devname;
  190. unsigned char phyaddr = 3;
  191. unsigned char reg = 0;
  192. unsigned short data;
  193. if (port == 1)
  194. phyaddr = 2;
  195. devname = miiphy_get_current_dev();
  196. if (!devname) {
  197. printf("Error: no mii device\n");
  198. return;
  199. }
  200. if (miiphy_read(devname, phyaddr, reg, &data) != 0) {
  201. printf("Error reading from the PHY addr=%02x reg=%02x\n",
  202. phyaddr, reg);
  203. return;
  204. }
  205. if (on)
  206. data &= ~PHY_POWER;
  207. else
  208. data |= PHY_POWER;
  209. if (miiphy_write(devname, phyaddr, reg, data) != 0) {
  210. printf("Error writing to the PHY addr=%02x reg=%02x\n",
  211. phyaddr, reg);
  212. return;
  213. }
  214. }
  215. int board_init(void)
  216. {
  217. int i, ret;
  218. #ifndef CONFIG_USE_IRQ
  219. irq_init();
  220. #endif
  221. /* address of boot parameters, not used as booting with DTT */
  222. gd->bd->bi_boot_params = 0;
  223. for (i = 0; i < ARRAY_SIZE(enbw_gpio_config); i++) {
  224. int gpio = enbw_gpio_config[i].bank * 16 +
  225. enbw_gpio_config[i].gpio;
  226. ret = gpio_request(gpio, enbw_gpio_config[i].name);
  227. if (ret) {
  228. printf("%s: Could not get %s gpio\n", __func__,
  229. enbw_gpio_config[i].name);
  230. return -1;
  231. }
  232. if (enbw_gpio_config[i].out)
  233. gpio_direction_output(gpio,
  234. enbw_gpio_config[i].value);
  235. else
  236. gpio_direction_input(gpio);
  237. }
  238. /* setup the SUSPSRC for ARM to control emulation suspend */
  239. clrbits_le32(&davinci_syscfg_regs->suspsrc,
  240. (DAVINCI_SYSCFG_SUSPSRC_EMAC | DAVINCI_SYSCFG_SUSPSRC_I2C |
  241. DAVINCI_SYSCFG_SUSPSRC_SPI1 | DAVINCI_SYSCFG_SUSPSRC_TIMER0 |
  242. DAVINCI_SYSCFG_SUSPSRC_UART2));
  243. return 0;
  244. }
  245. #ifdef CONFIG_DRIVER_TI_EMAC
  246. /*
  247. * Initializes on-board ethernet controllers.
  248. */
  249. int board_eth_init(bd_t *bis)
  250. {
  251. #ifdef CONFIG_DRIVER_TI_EMAC
  252. davinci_emac_mii_mode_sel(0);
  253. #endif /* CONFIG_DRIVER_TI_EMAC */
  254. if (!davinci_emac_initialize()) {
  255. printf("Error: Ethernet init failed!\n");
  256. return -1;
  257. }
  258. if (hwconfig_subarg_cmp("switch", "lan", "on"))
  259. /* Switch port lan on */
  260. enbw_cmc_switch(1, 1);
  261. else
  262. enbw_cmc_switch(1, 0);
  263. if (hwconfig_subarg_cmp("switch", "pwl", "on"))
  264. /* Switch port pwl on */
  265. enbw_cmc_switch(2, 1);
  266. else
  267. enbw_cmc_switch(2, 0);
  268. return 0;
  269. }
  270. #endif /* CONFIG_DRIVER_TI_EMAC */
  271. #ifdef CONFIG_PREBOOT
  272. static uchar kbd_magic_prefix[] = "key_magic_";
  273. static uchar kbd_command_prefix[] = "key_cmd_";
  274. struct kbd_data_t {
  275. char s1;
  276. };
  277. struct kbd_data_t *get_keys(struct kbd_data_t *kbd_data)
  278. {
  279. /* read SW1 + SW2 */
  280. kbd_data->s1 = gpio_get_value(12) +
  281. (gpio_get_value(13) << 1);
  282. return kbd_data;
  283. }
  284. static int compare_magic(const struct kbd_data_t *kbd_data, char *str)
  285. {
  286. char s1 = str[0];
  287. if (s1 >= '0' && s1 <= '9')
  288. s1 -= '0';
  289. else if (s1 >= 'a' && s1 <= 'f')
  290. s1 = s1 - 'a' + 10;
  291. else if (s1 >= 'A' && s1 <= 'F')
  292. s1 = s1 - 'A' + 10;
  293. else
  294. return -1;
  295. if (s1 != kbd_data->s1)
  296. return -1;
  297. return 0;
  298. }
  299. static char *key_match(const struct kbd_data_t *kbd_data)
  300. {
  301. char magic[sizeof(kbd_magic_prefix) + 1];
  302. char *suffix;
  303. char *kbd_magic_keys;
  304. /*
  305. * The following string defines the characters that can be appended
  306. * to "key_magic" to form the names of environment variables that
  307. * hold "magic" key codes, i. e. such key codes that can cause
  308. * pre-boot actions. If the string is empty (""), then only
  309. * "key_magic" is checked (old behaviour); the string "125" causes
  310. * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
  311. */
  312. kbd_magic_keys = getenv("magic_keys");
  313. if (kbd_magic_keys == NULL)
  314. kbd_magic_keys = "";
  315. /*
  316. * loop over all magic keys;
  317. * use '\0' suffix in case of empty string
  318. */
  319. for (suffix = kbd_magic_keys; *suffix ||
  320. suffix == kbd_magic_keys; ++suffix) {
  321. sprintf(magic, "%s%c", kbd_magic_prefix, *suffix);
  322. if (compare_magic(kbd_data, getenv(magic)) == 0) {
  323. char cmd_name[sizeof(kbd_command_prefix) + 1];
  324. char *cmd;
  325. sprintf(cmd_name, "%s%c", kbd_command_prefix, *suffix);
  326. cmd = getenv(cmd_name);
  327. return cmd;
  328. }
  329. }
  330. return NULL;
  331. }
  332. #endif /* CONFIG_PREBOOT */
  333. int misc_init_r(void)
  334. {
  335. char *s, buf[32];
  336. #ifdef CONFIG_PREBOOT
  337. struct kbd_data_t kbd_data;
  338. /* Decode keys */
  339. char *str = strdup(key_match(get_keys(&kbd_data)));
  340. /* Set or delete definition */
  341. setenv("preboot", str);
  342. free(str);
  343. #endif /* CONFIG_PREBOOT */
  344. /* count all restarts, and save this in an environment var */
  345. s = getenv("restartcount");
  346. if (s)
  347. sprintf(buf, "%ld", simple_strtoul(s, NULL, 10) + 1);
  348. else
  349. strcpy(buf, "1");
  350. setenv("restartcount", buf);
  351. saveenv();
  352. #ifdef CONFIG_HW_WATCHDOG
  353. davinci_hw_watchdog_enable();
  354. #endif
  355. return 0;
  356. }
  357. struct cmc_led {
  358. char name[20];
  359. unsigned char bank;
  360. unsigned char gpio;
  361. };
  362. struct cmc_led led_table[] = {
  363. {"led1", 1, 15},
  364. {"led2", 0, 1},
  365. {"led3", 0, 2},
  366. {"led4", 0, 3},
  367. {"led5", 0, 4},
  368. {"led6", 0, 5},
  369. {"led7", 0, 6},
  370. {"led8", 0, 14},
  371. };
  372. static int cmc_get_led_state(struct cmc_led *led)
  373. {
  374. int value;
  375. int gpio = led->bank * 16 + led->gpio;
  376. value = gpio_get_value(gpio);
  377. return value;
  378. }
  379. static int cmc_set_led_state(struct cmc_led *led, int state)
  380. {
  381. int gpio = led->bank * 16 + led->gpio;
  382. gpio_set_value(gpio, state);
  383. return 0;
  384. }
  385. static int do_led(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  386. {
  387. struct cmc_led *led;
  388. int found = 0;
  389. int i = 0;
  390. int only_print = 0;
  391. int len = ARRAY_SIZE(led_table);
  392. if (argc < 2)
  393. return cmd_usage(cmdtp);
  394. if (argc < 3)
  395. only_print = 1;
  396. led = led_table;
  397. while ((!found) && (i < len)) {
  398. if (strcmp(argv[1], led->name) == 0) {
  399. found = 1;
  400. } else {
  401. led++;
  402. i++;
  403. }
  404. }
  405. if (!found)
  406. return cmd_usage(cmdtp);
  407. if (only_print) {
  408. if (cmc_get_led_state(led))
  409. printf("on\n");
  410. else
  411. printf("off\n");
  412. return 0;
  413. }
  414. if (strcmp(argv[2], "on") == 0)
  415. cmc_set_led_state(led, 1);
  416. else
  417. cmc_set_led_state(led, 0);
  418. return 0;
  419. }
  420. U_BOOT_CMD(led, 3, 1, do_led,
  421. "switch on/off board led",
  422. "[name] [on/off]"
  423. );
  424. #ifdef CONFIG_HW_WATCHDOG
  425. void hw_watchdog_reset(void)
  426. {
  427. davinci_hw_watchdog_reset();
  428. }
  429. #endif
  430. #if defined(CONFIG_POST)
  431. void arch_memory_failure_handle(void)
  432. {
  433. struct davinci_gpio *gpio = davinci_gpio_bank01;
  434. int state = 1;
  435. /*
  436. * if memor< failure blink with the LED 1,2 and 3
  437. * as we running from flash, we cannot use the gpio
  438. * api here, so access the gpio pin direct through
  439. * the gpio register.
  440. */
  441. while (1) {
  442. if (state) {
  443. clrbits_le32(&gpio->out_data, 0x80000006);
  444. state = 0;
  445. } else {
  446. setbits_le32(&gpio->out_data, 0x80000006);
  447. state = 1;
  448. }
  449. udelay(500);
  450. }
  451. }
  452. #endif
  453. #if defined(CONFIG_BOOTCOUNT_LIMIT)
  454. void bootcount_store(ulong a)
  455. {
  456. struct davinci_rtc *reg =
  457. (struct davinci_rtc *)CONFIG_SYS_BOOTCOUNT_ADDR;
  458. /*
  459. * write RTC kick register to enable write
  460. * for RTC Scratch registers. Cratch0 and 1 are
  461. * used for bootcount values.
  462. */
  463. out_be32(&reg->kick0r, RTC_KICK0R_WE);
  464. out_be32(&reg->kick1r, RTC_KICK1R_WE);
  465. out_be32(&reg->scratch0, a);
  466. out_be32(&reg->scratch1, BOOTCOUNT_MAGIC);
  467. }
  468. ulong bootcount_load(void)
  469. {
  470. struct davinci_rtc *reg =
  471. (struct davinci_rtc *)CONFIG_SYS_BOOTCOUNT_ADDR;
  472. if (in_be32(&reg->scratch1) != BOOTCOUNT_MAGIC)
  473. return 0;
  474. else
  475. return in_be32(&reg->scratch0);
  476. }
  477. #endif
  478. void board_gpio_init(void)
  479. {
  480. struct davinci_gpio *gpio = davinci_gpio_bank01;
  481. /*
  482. * Power on required peripherals
  483. * ARM does not have access by default to PSC0 and PSC1
  484. * assuming here that the DSP bootloader has set the IOPU
  485. * such that PSC access is available to ARM
  486. */
  487. if (da8xx_configure_lpsc_items(lpsc, ARRAY_SIZE(lpsc)))
  488. return;
  489. /*
  490. * set LED (gpio Interface not usable here)
  491. * set LED pins to output and state 0
  492. */
  493. clrbits_le32(&gpio->dir, 0x8000407e);
  494. clrbits_le32(&gpio->out_data, 0x8000407e);
  495. /* set LED 1 - 5 to state on */
  496. setbits_le32(&gpio->out_data, 0x8000001e);
  497. }
  498. int board_late_init(void)
  499. {
  500. cmc_set_led_state(&led_table[4], 0);
  501. return 0;
  502. }
  503. void show_boot_progress(int val)
  504. {
  505. switch (val) {
  506. case 1:
  507. cmc_set_led_state(&led_table[4], 1);
  508. break;
  509. case 4:
  510. cmc_set_led_state(&led_table[4], 0);
  511. break;
  512. case 15:
  513. cmc_set_led_state(&led_table[4], 1);
  514. break;
  515. }
  516. }
  517. #ifdef CONFIG_DAVINCI_MMC
  518. static struct davinci_mmc mmc_sd1 = {
  519. .reg_base = (struct davinci_mmc_regs *)DAVINCI_MMC_SD1_BASE,
  520. .input_clk = 228000000,
  521. .host_caps = MMC_MODE_4BIT,
  522. .voltages = MMC_VDD_32_33 | MMC_VDD_33_34,
  523. .version = MMC_CTLR_VERSION_2,
  524. };
  525. int board_mmc_init(bd_t *bis)
  526. {
  527. mmc_sd1.input_clk = clk_get(DAVINCI_MMC_CLKID);
  528. /* Add slot-0 to mmc subsystem */
  529. return davinci_mmc_init(bis, &mmc_sd1);
  530. }
  531. #endif