ac14xx.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. /*
  2. * (C) Copyright 2009 Wolfgang Denk <wd@denx.de>
  3. * (C) Copyright 2009 Dave Srl www.dave.eu
  4. * (C) Copyright 2010 ifm ecomatic GmbH
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * project.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. */
  14. #include <common.h>
  15. #include <asm/bitops.h>
  16. #include <command.h>
  17. #include <asm/io.h>
  18. #include <asm/processor.h>
  19. #include <asm/mpc512x.h>
  20. #include <fdt_support.h>
  21. #ifdef CONFIG_MISC_INIT_R
  22. #include <i2c.h>
  23. #endif
  24. static int eeprom_diag;
  25. static int mac_diag;
  26. static int gpio_diag;
  27. DECLARE_GLOBAL_DATA_PTR;
  28. static void gpio_configure(void)
  29. {
  30. immap_t *im;
  31. gpio512x_t *gpioregs;
  32. im = (immap_t *) CONFIG_SYS_IMMR;
  33. gpioregs = &im->gpio;
  34. out_be32(&gpioregs->gpodr, 0x00290000); /* open drain */
  35. out_be32(&gpioregs->gpdat, 0x80001040); /* data (when output) */
  36. /*
  37. * out_be32(&gpioregs->gpdir, 0xC2293020);
  38. * workaround for a hardware effect: configure direction in pieces,
  39. * setting all outputs at once drops the reset line too low and
  40. * makes us lose the MII connection (breaks ethernet for us)
  41. */
  42. out_be32(&gpioregs->gpdir, 0x02003060); /* direction */
  43. setbits_be32(&gpioregs->gpdir, 0x00200000); /* += reset asi */
  44. udelay(10);
  45. setbits_be32(&gpioregs->gpdir, 0x00080000); /* += reset safety */
  46. udelay(10);
  47. setbits_be32(&gpioregs->gpdir, 0x00010000); /* += reset comm */
  48. udelay(10);
  49. setbits_be32(&gpioregs->gpdir, 0xC0000000); /* += backlight, KB sel */
  50. /* to turn from red to yellow when U-Boot runs */
  51. setbits_be32(&gpioregs->gpdat, 0x00002020);
  52. out_be32(&gpioregs->gpimr, 0x00000000); /* interrupt mask */
  53. out_be32(&gpioregs->gpicr1, 0x00000004); /* interrupt sense part 1 */
  54. out_be32(&gpioregs->gpicr2, 0x00A80000); /* interrupt sense part 2 */
  55. out_be32(&gpioregs->gpier, 0xFFFFFFFF); /* interrupt events, clear */
  56. }
  57. /* the physical location of the pins */
  58. #define GPIOKEY_ROW_BITMASK 0x40000000
  59. #define GPIOKEY_ROW_UPPER 0
  60. #define GPIOKEY_ROW_LOWER 1
  61. #define GPIOKEY_COL0_BITMASK 0x20000000
  62. #define GPIOKEY_COL1_BITMASK 0x10000000
  63. #define GPIOKEY_COL2_BITMASK 0x08000000
  64. /* the logical presentation of pressed keys */
  65. #define GPIOKEY_BIT_FNLEFT (1 << 5)
  66. #define GPIOKEY_BIT_FNRIGHT (1 << 4)
  67. #define GPIOKEY_BIT_DIRUP (1 << 3)
  68. #define GPIOKEY_BIT_DIRLEFT (1 << 2)
  69. #define GPIOKEY_BIT_DIRRIGHT (1 << 1)
  70. #define GPIOKEY_BIT_DIRDOWN (1 << 0)
  71. /* the hotkey combination which starts recovery */
  72. #define GPIOKEY_BITS_RECOVERY (GPIOKEY_BIT_FNLEFT | GPIOKEY_BIT_DIRUP | \
  73. GPIOKEY_BIT_DIRDOWN)
  74. static void gpio_selectrow(gpio512x_t *gpioregs, u32 row)
  75. {
  76. if (row)
  77. setbits_be32(&gpioregs->gpdat, GPIOKEY_ROW_BITMASK);
  78. else
  79. clrbits_be32(&gpioregs->gpdat, GPIOKEY_ROW_BITMASK);
  80. udelay(10);
  81. }
  82. static u32 gpio_querykbd(void)
  83. {
  84. immap_t *im;
  85. gpio512x_t *gpioregs;
  86. u32 keybits;
  87. u32 input;
  88. im = (immap_t *)CONFIG_SYS_IMMR;
  89. gpioregs = &im->gpio;
  90. keybits = 0;
  91. /* query upper row */
  92. gpio_selectrow(gpioregs, GPIOKEY_ROW_UPPER);
  93. input = in_be32(&gpioregs->gpdat);
  94. if ((input & GPIOKEY_COL0_BITMASK) == 0)
  95. keybits |= GPIOKEY_BIT_FNLEFT;
  96. if ((input & GPIOKEY_COL1_BITMASK) == 0)
  97. keybits |= GPIOKEY_BIT_DIRUP;
  98. if ((input & GPIOKEY_COL2_BITMASK) == 0)
  99. keybits |= GPIOKEY_BIT_FNRIGHT;
  100. /* query lower row */
  101. gpio_selectrow(gpioregs, GPIOKEY_ROW_LOWER);
  102. input = in_be32(&gpioregs->gpdat);
  103. if ((input & GPIOKEY_COL0_BITMASK) == 0)
  104. keybits |= GPIOKEY_BIT_DIRLEFT;
  105. if ((input & GPIOKEY_COL1_BITMASK) == 0)
  106. keybits |= GPIOKEY_BIT_DIRRIGHT;
  107. if ((input & GPIOKEY_COL2_BITMASK) == 0)
  108. keybits |= GPIOKEY_BIT_DIRDOWN;
  109. /* return bit pattern for keys */
  110. return keybits;
  111. }
  112. /* excerpt from the recovery's hw_info.h */
  113. struct __attribute__ ((__packed__)) eeprom_layout {
  114. char magic[3]; /** 'ifm' */
  115. u8 len[2]; /** content length without magic/len fields */
  116. u8 version[3]; /** structure version */
  117. u8 type; /** type of PCB */
  118. u8 reserved[0x37]; /** padding up to offset 0x40 */
  119. u8 macaddress[6]; /** ethernet MAC (for the mainboard) @0x40 */
  120. };
  121. #define HW_COMP_MAINCPU 2
  122. static struct eeprom_layout eeprom_content;
  123. static int eeprom_was_read; /* has_been_read */
  124. static int eeprom_is_valid;
  125. static int eeprom_version;
  126. #define get_eeprom_field_int(name) ({ \
  127. int value; \
  128. int idx; \
  129. value = 0; \
  130. for (idx = 0; idx < sizeof(name); idx++) { \
  131. value <<= 8; \
  132. value |= name[idx]; \
  133. } \
  134. value; \
  135. })
  136. static int read_eeprom(void)
  137. {
  138. int eeprom_datalen;
  139. int ret;
  140. if (eeprom_was_read)
  141. return 0;
  142. eeprom_is_valid = 0;
  143. ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0,
  144. CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
  145. (uchar *)&eeprom_content, sizeof(eeprom_content));
  146. if (eeprom_diag) {
  147. printf("DIAG: %s() read rc[%d], size[%d]\n",
  148. __func__, ret, sizeof(eeprom_content));
  149. }
  150. if (ret != 0)
  151. return -1;
  152. eeprom_was_read = 1;
  153. /*
  154. * check validity of EEPROM content
  155. * (check version, length, optionally checksum)
  156. */
  157. eeprom_is_valid = 1;
  158. eeprom_datalen = get_eeprom_field_int(eeprom_content.len);
  159. eeprom_version = get_eeprom_field_int(eeprom_content.version);
  160. if (eeprom_diag) {
  161. printf("DIAG: %s() magic[%c%c%c] len[%d] ver[%d] type[%d]\n",
  162. __func__, eeprom_content.magic[0],
  163. eeprom_content.magic[1], eeprom_content.magic[2],
  164. eeprom_datalen, eeprom_version, eeprom_content.type);
  165. }
  166. if (strncmp(eeprom_content.magic, "ifm", strlen("ifm")) != 0)
  167. eeprom_is_valid = 0;
  168. if (eeprom_datalen < sizeof(struct eeprom_layout) - 5)
  169. eeprom_is_valid = 0;
  170. if ((eeprom_version != 1) && (eeprom_version != 2))
  171. eeprom_is_valid = 0;
  172. if (eeprom_content.type != HW_COMP_MAINCPU)
  173. eeprom_is_valid = 0;
  174. if (eeprom_diag)
  175. printf("DIAG: %s() valid[%d]\n", __func__, eeprom_is_valid);
  176. return ret;
  177. }
  178. int mac_read_from_eeprom(void)
  179. {
  180. const u8 *mac;
  181. const char *mac_txt;
  182. if (read_eeprom()) {
  183. printf("I2C EEPROM read failed.\n");
  184. return -1;
  185. }
  186. if (!eeprom_is_valid) {
  187. printf("I2C EEPROM content not valid\n");
  188. return -1;
  189. }
  190. mac = NULL;
  191. switch (eeprom_version) {
  192. case 1:
  193. case 2:
  194. mac = (const u8 *)&eeprom_content.macaddress;
  195. break;
  196. }
  197. if (mac && is_valid_ether_addr(mac)) {
  198. eth_setenv_enetaddr("ethaddr", mac);
  199. if (mac_diag) {
  200. mac_txt = getenv("ethaddr");
  201. if (mac_txt)
  202. printf("DIAG: MAC value [%s]\n", mac_txt);
  203. else
  204. printf("DIAG: failed to setup MAC env\n");
  205. }
  206. }
  207. return 0;
  208. }
  209. /*
  210. * BEWARE!
  211. * this board uses DDR1(!) Micron SDRAM, *NOT* the DDR2
  212. * which the ADS, Aria or PDM360NG boards are using
  213. * (the steps outlined here refer to the Micron datasheet)
  214. */
  215. u32 sdram_init_seq[] = {
  216. /* item 6, at least one NOP after CKE went high */
  217. CONFIG_SYS_DDRCMD_NOP,
  218. CONFIG_SYS_DDRCMD_NOP,
  219. CONFIG_SYS_DDRCMD_NOP,
  220. CONFIG_SYS_DDRCMD_NOP,
  221. CONFIG_SYS_DDRCMD_NOP,
  222. CONFIG_SYS_DDRCMD_NOP,
  223. CONFIG_SYS_DDRCMD_NOP,
  224. CONFIG_SYS_DDRCMD_NOP,
  225. CONFIG_SYS_DDRCMD_NOP,
  226. CONFIG_SYS_DDRCMD_NOP,
  227. /* item 7, precharge all; item 8, tRP (20ns) */
  228. CONFIG_SYS_DDRCMD_PCHG_ALL,
  229. CONFIG_SYS_DDRCMD_NOP,
  230. /* item 9, extended mode register; item 10, tMRD 10ns) */
  231. CONFIG_SYS_MICRON_EMODE | CONFIG_SYS_MICRON_EMODE_PARAM,
  232. CONFIG_SYS_DDRCMD_NOP,
  233. /*
  234. * item 11, (base) mode register _with_ reset DLL;
  235. * item 12, tMRD (10ns)
  236. */
  237. CONFIG_SYS_MICRON_BMODE | CONFIG_SYS_MICRON_BMODE_RSTDLL |
  238. CONFIG_SYS_MICRON_BMODE_PARAM,
  239. CONFIG_SYS_DDRCMD_NOP,
  240. /* item 13, precharge all; item 14, tRP (20ns) */
  241. CONFIG_SYS_DDRCMD_PCHG_ALL,
  242. CONFIG_SYS_DDRCMD_NOP,
  243. /*
  244. * item 15, auto refresh (i.e. refresh with CKE held high);
  245. * item 16, tRFC (70ns)
  246. */
  247. CONFIG_SYS_DDRCMD_RFSH,
  248. CONFIG_SYS_DDRCMD_NOP,
  249. CONFIG_SYS_DDRCMD_NOP,
  250. CONFIG_SYS_DDRCMD_NOP,
  251. CONFIG_SYS_DDRCMD_NOP,
  252. CONFIG_SYS_DDRCMD_NOP,
  253. CONFIG_SYS_DDRCMD_NOP,
  254. CONFIG_SYS_DDRCMD_NOP,
  255. CONFIG_SYS_DDRCMD_NOP,
  256. /*
  257. * item 17, auto refresh (i.e. refresh with CKE held high);
  258. * item 18, tRFC (70ns)
  259. */
  260. CONFIG_SYS_DDRCMD_RFSH,
  261. CONFIG_SYS_DDRCMD_NOP,
  262. CONFIG_SYS_DDRCMD_NOP,
  263. CONFIG_SYS_DDRCMD_NOP,
  264. CONFIG_SYS_DDRCMD_NOP,
  265. CONFIG_SYS_DDRCMD_NOP,
  266. CONFIG_SYS_DDRCMD_NOP,
  267. CONFIG_SYS_DDRCMD_NOP,
  268. CONFIG_SYS_DDRCMD_NOP,
  269. /* item 19, optional, unassert DLL reset; item 20, tMRD (20ns) */
  270. CONFIG_SYS_MICRON_BMODE | CONFIG_SYS_MICRON_BMODE_PARAM,
  271. CONFIG_SYS_DDRCMD_NOP,
  272. /*
  273. * item 21, "actually done", but make sure 200 DRAM clock cycles
  274. * have passed after DLL reset before READ requests are issued
  275. * (200 cycles at 160MHz -> 1.25 usec)
  276. */
  277. /* EMPTY, optional, we don't do it */
  278. };
  279. phys_size_t initdram(int board_type)
  280. {
  281. return fixed_sdram(NULL, sdram_init_seq, ARRAY_SIZE(sdram_init_seq));
  282. }
  283. int misc_init_r(void)
  284. {
  285. u32 keys;
  286. char *s;
  287. int want_recovery;
  288. /* we use bus I2C-0 for the on-board eeprom */
  289. i2c_set_bus_num(0);
  290. /* setup GPIO directions and initial values */
  291. gpio_configure();
  292. /*
  293. * enforce the start of the recovery system when
  294. * - the appropriate keys were pressed
  295. * - a previous installation was aborted or has failed
  296. * - "some" external software told us to
  297. */
  298. want_recovery = 0;
  299. keys = gpio_querykbd();
  300. if (gpio_diag)
  301. printf("GPIO keyboard status [0x%02X]\n", keys);
  302. if ((keys & GPIOKEY_BITS_RECOVERY) == GPIOKEY_BITS_RECOVERY) {
  303. printf("detected recovery request (keyboard)\n");
  304. want_recovery = 1;
  305. }
  306. s = getenv("install_in_progress");
  307. if ((s != NULL) && (*s != '\0')) {
  308. printf("previous installation has not completed\n");
  309. want_recovery = 1;
  310. }
  311. s = getenv("install_failed");
  312. if ((s != NULL) && (*s != '\0')) {
  313. printf("previous installation has failed\n");
  314. want_recovery = 1;
  315. }
  316. s = getenv("want_recovery");
  317. if ((s != NULL) && (*s != '\0')) {
  318. printf("detected recovery request (environment)\n");
  319. want_recovery = 1;
  320. }
  321. if (want_recovery) {
  322. printf("enforced start of the recovery system\n");
  323. setenv("bootcmd", "run recovery");
  324. }
  325. /*
  326. * boot the recovery system without waiting; boot the
  327. * production system without waiting by default, only
  328. * insert a pause (to provide a chance to get a prompt)
  329. * when GPIO keys were pressed during power on
  330. */
  331. if (want_recovery)
  332. setenv("bootdelay", "0");
  333. else if (!keys)
  334. setenv("bootdelay", "0");
  335. else
  336. setenv("bootdelay", "2");
  337. /* get the ethernet MAC from I2C EEPROM */
  338. mac_read_from_eeprom();
  339. return 0;
  340. }
  341. /* setup specific IO pad configuration */
  342. static iopin_t ioregs_init[] = {
  343. { /* LPC CS3 */
  344. offsetof(struct ioctrl512x, io_control_nfc_ce0), 1,
  345. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  346. IO_PIN_FMUX(1) | IO_PIN_DS(2),
  347. },
  348. { /* LPC CS1 */
  349. offsetof(struct ioctrl512x, io_control_lpc_cs1), 1,
  350. IO_PIN_OVER_DRVSTR,
  351. IO_PIN_DS(2),
  352. },
  353. { /* LPC CS2 */
  354. offsetof(struct ioctrl512x, io_control_lpc_cs2), 1,
  355. IO_PIN_OVER_DRVSTR,
  356. IO_PIN_DS(2),
  357. },
  358. { /* LPC CS4, CS5 */
  359. offsetof(struct ioctrl512x, io_control_pata_ce1), 2,
  360. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  361. IO_PIN_FMUX(1) | IO_PIN_DS(2),
  362. },
  363. { /* SDHC CLK, CMD, D0, D1, D2, D3 */
  364. offsetof(struct ioctrl512x, io_control_pata_ior), 6,
  365. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  366. IO_PIN_FMUX(1) | IO_PIN_DS(2),
  367. },
  368. { /* GPIO keyboard */
  369. offsetof(struct ioctrl512x, io_control_pci_ad30), 4,
  370. IO_PIN_OVER_FMUX,
  371. IO_PIN_FMUX(3),
  372. },
  373. { /* GPIO DN1 PF, LCD power, DN2 PF */
  374. offsetof(struct ioctrl512x, io_control_pci_ad26), 3,
  375. IO_PIN_OVER_FMUX,
  376. IO_PIN_FMUX(3),
  377. },
  378. { /* GPIO reset AS-i */
  379. offsetof(struct ioctrl512x, io_control_pci_ad21), 1,
  380. IO_PIN_OVER_FMUX,
  381. IO_PIN_FMUX(3),
  382. },
  383. { /* GPIO reset safety */
  384. offsetof(struct ioctrl512x, io_control_pci_ad19), 1,
  385. IO_PIN_OVER_FMUX,
  386. IO_PIN_FMUX(3),
  387. },
  388. { /* GPIO reset netX */
  389. offsetof(struct ioctrl512x, io_control_pci_ad16), 1,
  390. IO_PIN_OVER_FMUX,
  391. IO_PIN_FMUX(3),
  392. },
  393. { /* GPIO ma2 en */
  394. offsetof(struct ioctrl512x, io_control_pci_ad15), 1,
  395. IO_PIN_OVER_FMUX,
  396. IO_PIN_FMUX(3),
  397. },
  398. { /* GPIO SD CD, SD WP */
  399. offsetof(struct ioctrl512x, io_control_pci_ad08), 2,
  400. IO_PIN_OVER_FMUX,
  401. IO_PIN_FMUX(3),
  402. },
  403. { /* FEC RX DV */
  404. offsetof(struct ioctrl512x, io_control_pci_ad06), 1,
  405. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  406. IO_PIN_FMUX(2) | IO_PIN_DS(2),
  407. },
  408. { /* GPIO AS-i prog, AS-i done, LCD backlight */
  409. offsetof(struct ioctrl512x, io_control_pci_ad05), 3,
  410. IO_PIN_OVER_FMUX,
  411. IO_PIN_FMUX(3),
  412. },
  413. { /* GPIO AS-i wdg */
  414. offsetof(struct ioctrl512x, io_control_pci_req2), 1,
  415. IO_PIN_OVER_FMUX,
  416. IO_PIN_FMUX(3),
  417. },
  418. { /* GPIO safety wdg */
  419. offsetof(struct ioctrl512x, io_control_pci_req1), 1,
  420. IO_PIN_OVER_FMUX,
  421. IO_PIN_FMUX(3),
  422. },
  423. { /* GPIO netX wdg */
  424. offsetof(struct ioctrl512x, io_control_pci_req0), 1,
  425. IO_PIN_OVER_FMUX,
  426. IO_PIN_FMUX(3),
  427. },
  428. { /* GPIO IRQ powerfail */
  429. offsetof(struct ioctrl512x, io_control_pci_inta), 1,
  430. IO_PIN_OVER_FMUX,
  431. IO_PIN_FMUX(3),
  432. },
  433. { /* GPIO AS-i PWRD */
  434. offsetof(struct ioctrl512x, io_control_pci_frame), 1,
  435. IO_PIN_OVER_FMUX,
  436. IO_PIN_FMUX(3),
  437. },
  438. { /* GPIO LED0, LED1 */
  439. offsetof(struct ioctrl512x, io_control_pci_idsel), 2,
  440. IO_PIN_OVER_FMUX,
  441. IO_PIN_FMUX(3),
  442. },
  443. { /* GPIO IRQ AS-i 1, IRQ AS-i 2, IRQ safety */
  444. offsetof(struct ioctrl512x, io_control_pci_irdy), 3,
  445. IO_PIN_OVER_FMUX,
  446. IO_PIN_FMUX(3),
  447. },
  448. { /* DIU clk */
  449. offsetof(struct ioctrl512x, io_control_spdif_txclk), 1,
  450. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  451. IO_PIN_FMUX(2) | IO_PIN_DS(2),
  452. },
  453. { /* FEC TX ER, CRS */
  454. offsetof(struct ioctrl512x, io_control_spdif_tx), 2,
  455. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  456. IO_PIN_FMUX(1) | IO_PIN_DS(2),
  457. },
  458. { /* GPIO/GPT */ /* to *NOT* have the EXT IRQ0 float */
  459. offsetof(struct ioctrl512x, io_control_irq0), 1,
  460. IO_PIN_OVER_FMUX,
  461. IO_PIN_FMUX(3),
  462. },
  463. { /*
  464. * FEC col, tx en, tx clk, txd 0-3, mdc, rx er,
  465. * rdx 3-0, mdio, rx clk
  466. */
  467. offsetof(struct ioctrl512x, io_control_psc0_0), 15,
  468. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  469. IO_PIN_FMUX(1) | IO_PIN_DS(2),
  470. },
  471. /* optional: make sure PSC3 remains the serial console */
  472. { /* LPC CS6 */
  473. offsetof(struct ioctrl512x, io_control_psc3_4), 1,
  474. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  475. IO_PIN_FMUX(1) | IO_PIN_DS(2),
  476. },
  477. /* make sure PSC4 remains available for SPI,
  478. *BUT* PSC4_1 is a GPIO kind of SS! */
  479. { /* enforce drive strength on the SPI pin */
  480. offsetof(struct ioctrl512x, io_control_psc4_0), 5,
  481. IO_PIN_OVER_DRVSTR,
  482. IO_PIN_DS(2),
  483. },
  484. {
  485. offsetof(struct ioctrl512x, io_control_psc4_1), 1,
  486. IO_PIN_OVER_FMUX,
  487. IO_PIN_FMUX(3),
  488. },
  489. /* optional: make sure PSC5 remains available for SPI */
  490. { /* enforce drive strength on the SPI pin */
  491. offsetof(struct ioctrl512x, io_control_psc5_0), 5,
  492. IO_PIN_OVER_DRVSTR,
  493. IO_PIN_DS(1),
  494. },
  495. { /* LPC TSIZ1 */
  496. offsetof(struct ioctrl512x, io_control_psc6_0), 1,
  497. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  498. IO_PIN_FMUX(1) | IO_PIN_DS(2),
  499. },
  500. { /* DIU hsync */
  501. offsetof(struct ioctrl512x, io_control_psc6_1), 1,
  502. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  503. IO_PIN_FMUX(2) | IO_PIN_DS(1),
  504. },
  505. { /* DIU vsync */
  506. offsetof(struct ioctrl512x, io_control_psc6_4), 1,
  507. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  508. IO_PIN_FMUX(2) | IO_PIN_DS(1),
  509. },
  510. { /* PSC7, part of DIU RGB */
  511. offsetof(struct ioctrl512x, io_control_psc7_0), 2,
  512. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  513. IO_PIN_FMUX(2) | IO_PIN_DS(1),
  514. },
  515. { /* PSC7, safety UART */
  516. offsetof(struct ioctrl512x, io_control_psc7_2), 2,
  517. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  518. IO_PIN_FMUX(0) | IO_PIN_DS(1),
  519. },
  520. { /* DIU (part of) RGB[] */
  521. offsetof(struct ioctrl512x, io_control_psc8_3), 16,
  522. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  523. IO_PIN_FMUX(2) | IO_PIN_DS(1),
  524. },
  525. { /* DIU data enable */
  526. offsetof(struct ioctrl512x, io_control_psc11_4), 1,
  527. IO_PIN_OVER_FMUX | IO_PIN_OVER_DRVSTR,
  528. IO_PIN_FMUX(2) | IO_PIN_DS(1),
  529. },
  530. /* reduce LPB drive strength for improved EMI */
  531. { /* LPC OE, LPC RW */
  532. offsetof(struct ioctrl512x, io_control_lpc_oe), 2,
  533. IO_PIN_OVER_DRVSTR,
  534. IO_PIN_DS(2),
  535. },
  536. { /* LPC AX03 through LPC AD00 */
  537. offsetof(struct ioctrl512x, io_control_lpc_ax03), 36,
  538. IO_PIN_OVER_DRVSTR,
  539. IO_PIN_DS(2),
  540. },
  541. { /* LPC CS5 */
  542. offsetof(struct ioctrl512x, io_control_pata_ce2), 1,
  543. IO_PIN_OVER_DRVSTR,
  544. IO_PIN_DS(2),
  545. },
  546. { /* SDHC CLK */
  547. offsetof(struct ioctrl512x, io_control_nfc_wp), 1,
  548. IO_PIN_OVER_DRVSTR,
  549. IO_PIN_DS(2),
  550. },
  551. { /* SDHC DATA */
  552. offsetof(struct ioctrl512x, io_control_nfc_ale), 4,
  553. IO_PIN_OVER_DRVSTR,
  554. IO_PIN_DS(2),
  555. },
  556. };
  557. int checkboard(void)
  558. {
  559. puts("Board: ifm AC14xx\n");
  560. /* initialize function mux & slew rate IO inter alia on IO Pins */
  561. iopin_initialize_bits(ioregs_init, ARRAY_SIZE(ioregs_init));
  562. return 0;
  563. }
  564. #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
  565. void ft_board_setup(void *blob, bd_t *bd)
  566. {
  567. ft_cpu_setup(blob, bd);
  568. }
  569. #endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */