enbw_cmc.c 13 KB

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