pinmux.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. /*
  2. * Copyright (c) 2012 Samsung Electronics.
  3. * Abhilash Kesavan <a.kesavan@samsung.com>
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <fdtdec.h>
  25. #include <asm/arch/gpio.h>
  26. #include <asm/arch/pinmux.h>
  27. #include <asm/arch/sromc.h>
  28. static void exynos5_uart_config(int peripheral)
  29. {
  30. struct exynos5_gpio_part1 *gpio1 =
  31. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  32. struct s5p_gpio_bank *bank;
  33. int i, start, count;
  34. switch (peripheral) {
  35. case PERIPH_ID_UART0:
  36. bank = &gpio1->a0;
  37. start = 0;
  38. count = 4;
  39. break;
  40. case PERIPH_ID_UART1:
  41. bank = &gpio1->d0;
  42. start = 0;
  43. count = 4;
  44. break;
  45. case PERIPH_ID_UART2:
  46. bank = &gpio1->a1;
  47. start = 0;
  48. count = 4;
  49. break;
  50. case PERIPH_ID_UART3:
  51. bank = &gpio1->a1;
  52. start = 4;
  53. count = 2;
  54. break;
  55. }
  56. for (i = start; i < start + count; i++) {
  57. s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
  58. s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
  59. }
  60. }
  61. static int exynos5_mmc_config(int peripheral, int flags)
  62. {
  63. struct exynos5_gpio_part1 *gpio1 =
  64. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  65. struct s5p_gpio_bank *bank, *bank_ext;
  66. int i, start = 0, gpio_func = 0;
  67. switch (peripheral) {
  68. case PERIPH_ID_SDMMC0:
  69. bank = &gpio1->c0;
  70. bank_ext = &gpio1->c1;
  71. start = 0;
  72. gpio_func = GPIO_FUNC(0x2);
  73. break;
  74. case PERIPH_ID_SDMMC1:
  75. bank = &gpio1->c2;
  76. bank_ext = NULL;
  77. break;
  78. case PERIPH_ID_SDMMC2:
  79. bank = &gpio1->c3;
  80. bank_ext = &gpio1->c4;
  81. start = 3;
  82. gpio_func = GPIO_FUNC(0x3);
  83. break;
  84. case PERIPH_ID_SDMMC3:
  85. bank = &gpio1->c4;
  86. bank_ext = NULL;
  87. break;
  88. }
  89. if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) {
  90. debug("SDMMC device %d does not support 8bit mode",
  91. peripheral);
  92. return -1;
  93. }
  94. if (flags & PINMUX_FLAG_8BIT_MODE) {
  95. for (i = start; i <= (start + 3); i++) {
  96. s5p_gpio_cfg_pin(bank_ext, i, gpio_func);
  97. s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP);
  98. s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
  99. }
  100. }
  101. for (i = 0; i < 2; i++) {
  102. s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
  103. s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
  104. s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
  105. }
  106. for (i = 3; i <= 6; i++) {
  107. s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
  108. s5p_gpio_set_pull(bank, i, GPIO_PULL_UP);
  109. s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
  110. }
  111. return 0;
  112. }
  113. static void exynos5_sromc_config(int flags)
  114. {
  115. struct exynos5_gpio_part1 *gpio1 =
  116. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  117. int i;
  118. /*
  119. * SROM:CS1 and EBI
  120. *
  121. * GPY0[0] SROM_CSn[0]
  122. * GPY0[1] SROM_CSn[1](2)
  123. * GPY0[2] SROM_CSn[2]
  124. * GPY0[3] SROM_CSn[3]
  125. * GPY0[4] EBI_OEn(2)
  126. * GPY0[5] EBI_EEn(2)
  127. *
  128. * GPY1[0] EBI_BEn[0](2)
  129. * GPY1[1] EBI_BEn[1](2)
  130. * GPY1[2] SROM_WAIT(2)
  131. * GPY1[3] EBI_DATA_RDn(2)
  132. */
  133. s5p_gpio_cfg_pin(&gpio1->y0, (flags & PINMUX_FLAG_BANK),
  134. GPIO_FUNC(2));
  135. s5p_gpio_cfg_pin(&gpio1->y0, 4, GPIO_FUNC(2));
  136. s5p_gpio_cfg_pin(&gpio1->y0, 5, GPIO_FUNC(2));
  137. for (i = 0; i < 4; i++)
  138. s5p_gpio_cfg_pin(&gpio1->y1, i, GPIO_FUNC(2));
  139. /*
  140. * EBI: 8 Addrss Lines
  141. *
  142. * GPY3[0] EBI_ADDR[0](2)
  143. * GPY3[1] EBI_ADDR[1](2)
  144. * GPY3[2] EBI_ADDR[2](2)
  145. * GPY3[3] EBI_ADDR[3](2)
  146. * GPY3[4] EBI_ADDR[4](2)
  147. * GPY3[5] EBI_ADDR[5](2)
  148. * GPY3[6] EBI_ADDR[6](2)
  149. * GPY3[7] EBI_ADDR[7](2)
  150. *
  151. * EBI: 16 Data Lines
  152. *
  153. * GPY5[0] EBI_DATA[0](2)
  154. * GPY5[1] EBI_DATA[1](2)
  155. * GPY5[2] EBI_DATA[2](2)
  156. * GPY5[3] EBI_DATA[3](2)
  157. * GPY5[4] EBI_DATA[4](2)
  158. * GPY5[5] EBI_DATA[5](2)
  159. * GPY5[6] EBI_DATA[6](2)
  160. * GPY5[7] EBI_DATA[7](2)
  161. *
  162. * GPY6[0] EBI_DATA[8](2)
  163. * GPY6[1] EBI_DATA[9](2)
  164. * GPY6[2] EBI_DATA[10](2)
  165. * GPY6[3] EBI_DATA[11](2)
  166. * GPY6[4] EBI_DATA[12](2)
  167. * GPY6[5] EBI_DATA[13](2)
  168. * GPY6[6] EBI_DATA[14](2)
  169. * GPY6[7] EBI_DATA[15](2)
  170. */
  171. for (i = 0; i < 8; i++) {
  172. s5p_gpio_cfg_pin(&gpio1->y3, i, GPIO_FUNC(2));
  173. s5p_gpio_set_pull(&gpio1->y3, i, GPIO_PULL_UP);
  174. s5p_gpio_cfg_pin(&gpio1->y5, i, GPIO_FUNC(2));
  175. s5p_gpio_set_pull(&gpio1->y5, i, GPIO_PULL_UP);
  176. s5p_gpio_cfg_pin(&gpio1->y6, i, GPIO_FUNC(2));
  177. s5p_gpio_set_pull(&gpio1->y6, i, GPIO_PULL_UP);
  178. }
  179. }
  180. static void exynos5_i2c_config(int peripheral, int flags)
  181. {
  182. struct exynos5_gpio_part1 *gpio1 =
  183. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  184. switch (peripheral) {
  185. case PERIPH_ID_I2C0:
  186. s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2));
  187. s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2));
  188. break;
  189. case PERIPH_ID_I2C1:
  190. s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2));
  191. s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2));
  192. break;
  193. case PERIPH_ID_I2C2:
  194. s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
  195. s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
  196. break;
  197. case PERIPH_ID_I2C3:
  198. s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
  199. s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
  200. break;
  201. case PERIPH_ID_I2C4:
  202. s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3));
  203. s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3));
  204. break;
  205. case PERIPH_ID_I2C5:
  206. s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3));
  207. s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3));
  208. break;
  209. case PERIPH_ID_I2C6:
  210. s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4));
  211. s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4));
  212. break;
  213. case PERIPH_ID_I2C7:
  214. s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3));
  215. s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3));
  216. break;
  217. }
  218. }
  219. static void exynos5_i2s_config(int peripheral)
  220. {
  221. int i;
  222. struct exynos5_gpio_part1 *gpio1 =
  223. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  224. for (i = 0; i < 5; i++)
  225. s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
  226. }
  227. void exynos5_spi_config(int peripheral)
  228. {
  229. int cfg = 0, pin = 0, i;
  230. struct s5p_gpio_bank *bank = NULL;
  231. struct exynos5_gpio_part1 *gpio1 =
  232. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  233. struct exynos5_gpio_part2 *gpio2 =
  234. (struct exynos5_gpio_part2 *) samsung_get_base_gpio_part2();
  235. switch (peripheral) {
  236. case PERIPH_ID_SPI0:
  237. bank = &gpio1->a2;
  238. cfg = GPIO_FUNC(0x2);
  239. pin = 0;
  240. break;
  241. case PERIPH_ID_SPI1:
  242. bank = &gpio1->a2;
  243. cfg = GPIO_FUNC(0x2);
  244. pin = 4;
  245. break;
  246. case PERIPH_ID_SPI2:
  247. bank = &gpio1->b1;
  248. cfg = GPIO_FUNC(0x5);
  249. pin = 1;
  250. break;
  251. case PERIPH_ID_SPI3:
  252. bank = &gpio2->f1;
  253. cfg = GPIO_FUNC(0x2);
  254. pin = 0;
  255. break;
  256. case PERIPH_ID_SPI4:
  257. for (i = 0; i < 2; i++) {
  258. s5p_gpio_cfg_pin(&gpio2->f0, i + 2, GPIO_FUNC(0x4));
  259. s5p_gpio_cfg_pin(&gpio2->e0, i + 4, GPIO_FUNC(0x4));
  260. }
  261. break;
  262. }
  263. if (peripheral != PERIPH_ID_SPI4) {
  264. for (i = pin; i < pin + 4; i++)
  265. s5p_gpio_cfg_pin(bank, i, cfg);
  266. }
  267. }
  268. static int exynos5_pinmux_config(int peripheral, int flags)
  269. {
  270. switch (peripheral) {
  271. case PERIPH_ID_UART0:
  272. case PERIPH_ID_UART1:
  273. case PERIPH_ID_UART2:
  274. case PERIPH_ID_UART3:
  275. exynos5_uart_config(peripheral);
  276. break;
  277. case PERIPH_ID_SDMMC0:
  278. case PERIPH_ID_SDMMC1:
  279. case PERIPH_ID_SDMMC2:
  280. case PERIPH_ID_SDMMC3:
  281. return exynos5_mmc_config(peripheral, flags);
  282. case PERIPH_ID_SROMC:
  283. exynos5_sromc_config(flags);
  284. break;
  285. case PERIPH_ID_I2C0:
  286. case PERIPH_ID_I2C1:
  287. case PERIPH_ID_I2C2:
  288. case PERIPH_ID_I2C3:
  289. case PERIPH_ID_I2C4:
  290. case PERIPH_ID_I2C5:
  291. case PERIPH_ID_I2C6:
  292. case PERIPH_ID_I2C7:
  293. exynos5_i2c_config(peripheral, flags);
  294. break;
  295. case PERIPH_ID_I2S1:
  296. exynos5_i2s_config(peripheral);
  297. break;
  298. case PERIPH_ID_SPI0:
  299. case PERIPH_ID_SPI1:
  300. case PERIPH_ID_SPI2:
  301. case PERIPH_ID_SPI3:
  302. case PERIPH_ID_SPI4:
  303. exynos5_spi_config(peripheral);
  304. break;
  305. default:
  306. debug("%s: invalid peripheral %d", __func__, peripheral);
  307. return -1;
  308. }
  309. return 0;
  310. }
  311. static void exynos4_i2c_config(int peripheral, int flags)
  312. {
  313. struct exynos4_gpio_part1 *gpio1 =
  314. (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1();
  315. switch (peripheral) {
  316. case PERIPH_ID_I2C0:
  317. s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2));
  318. s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2));
  319. break;
  320. case PERIPH_ID_I2C1:
  321. s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2));
  322. s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2));
  323. break;
  324. case PERIPH_ID_I2C2:
  325. s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
  326. s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
  327. break;
  328. case PERIPH_ID_I2C3:
  329. s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
  330. s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
  331. break;
  332. case PERIPH_ID_I2C4:
  333. s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3));
  334. s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3));
  335. break;
  336. case PERIPH_ID_I2C5:
  337. s5p_gpio_cfg_pin(&gpio1->b, 6, GPIO_FUNC(0x3));
  338. s5p_gpio_cfg_pin(&gpio1->b, 7, GPIO_FUNC(0x3));
  339. break;
  340. case PERIPH_ID_I2C6:
  341. s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4));
  342. s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4));
  343. break;
  344. case PERIPH_ID_I2C7:
  345. s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3));
  346. s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3));
  347. break;
  348. }
  349. }
  350. static int exynos4_mmc_config(int peripheral, int flags)
  351. {
  352. struct exynos4_gpio_part2 *gpio2 =
  353. (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
  354. struct s5p_gpio_bank *bank, *bank_ext;
  355. int i;
  356. switch (peripheral) {
  357. case PERIPH_ID_SDMMC0:
  358. bank = &gpio2->k0;
  359. bank_ext = &gpio2->k1;
  360. break;
  361. case PERIPH_ID_SDMMC2:
  362. bank = &gpio2->k2;
  363. bank_ext = &gpio2->k3;
  364. break;
  365. default:
  366. return -1;
  367. }
  368. for (i = 0; i < 7; i++) {
  369. if (i == 2)
  370. continue;
  371. s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
  372. s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
  373. s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
  374. }
  375. if (flags & PINMUX_FLAG_8BIT_MODE) {
  376. for (i = 3; i < 7; i++) {
  377. s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3));
  378. s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_NONE);
  379. s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
  380. }
  381. }
  382. return 0;
  383. }
  384. static void exynos4_uart_config(int peripheral)
  385. {
  386. struct exynos4_gpio_part1 *gpio1 =
  387. (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1();
  388. struct s5p_gpio_bank *bank;
  389. int i, start, count;
  390. switch (peripheral) {
  391. case PERIPH_ID_UART0:
  392. bank = &gpio1->a0;
  393. start = 0;
  394. count = 4;
  395. break;
  396. case PERIPH_ID_UART1:
  397. bank = &gpio1->a0;
  398. start = 4;
  399. count = 4;
  400. break;
  401. case PERIPH_ID_UART2:
  402. bank = &gpio1->a1;
  403. start = 0;
  404. count = 4;
  405. break;
  406. case PERIPH_ID_UART3:
  407. bank = &gpio1->a1;
  408. start = 4;
  409. count = 2;
  410. break;
  411. }
  412. for (i = start; i < start + count; i++) {
  413. s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
  414. s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
  415. }
  416. }
  417. static int exynos4_pinmux_config(int peripheral, int flags)
  418. {
  419. switch (peripheral) {
  420. case PERIPH_ID_UART0:
  421. case PERIPH_ID_UART1:
  422. case PERIPH_ID_UART2:
  423. case PERIPH_ID_UART3:
  424. exynos4_uart_config(peripheral);
  425. break;
  426. case PERIPH_ID_I2C0:
  427. case PERIPH_ID_I2C1:
  428. case PERIPH_ID_I2C2:
  429. case PERIPH_ID_I2C3:
  430. case PERIPH_ID_I2C4:
  431. case PERIPH_ID_I2C5:
  432. case PERIPH_ID_I2C6:
  433. case PERIPH_ID_I2C7:
  434. exynos4_i2c_config(peripheral, flags);
  435. break;
  436. case PERIPH_ID_SDMMC0:
  437. case PERIPH_ID_SDMMC2:
  438. return exynos4_mmc_config(peripheral, flags);
  439. case PERIPH_ID_SDMMC1:
  440. case PERIPH_ID_SDMMC3:
  441. case PERIPH_ID_SDMMC4:
  442. printf("SDMMC device %d not implemented\n", peripheral);
  443. return -1;
  444. default:
  445. debug("%s: invalid peripheral %d", __func__, peripheral);
  446. return -1;
  447. }
  448. return 0;
  449. }
  450. int exynos_pinmux_config(int peripheral, int flags)
  451. {
  452. if (cpu_is_exynos5())
  453. return exynos5_pinmux_config(peripheral, flags);
  454. else if (cpu_is_exynos4())
  455. return exynos4_pinmux_config(peripheral, flags);
  456. else {
  457. debug("pinmux functionality not supported\n");
  458. return -1;
  459. }
  460. }
  461. #ifdef CONFIG_OF_CONTROL
  462. static int exynos5_pinmux_decode_periph_id(const void *blob, int node)
  463. {
  464. int err;
  465. u32 cell[3];
  466. err = fdtdec_get_int_array(blob, node, "interrupts", cell,
  467. ARRAY_SIZE(cell));
  468. if (err)
  469. return PERIPH_ID_NONE;
  470. /* check for invalid peripheral id */
  471. if ((PERIPH_ID_SDMMC4 > cell[1]) || (cell[1] < PERIPH_ID_UART0))
  472. return cell[1];
  473. debug(" invalid peripheral id\n");
  474. return PERIPH_ID_NONE;
  475. }
  476. int pinmux_decode_periph_id(const void *blob, int node)
  477. {
  478. if (cpu_is_exynos5())
  479. return exynos5_pinmux_decode_periph_id(blob, node);
  480. else
  481. return PERIPH_ID_NONE;
  482. }
  483. #endif