pinmux.c 12 KB

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