pinmux.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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 <asm/arch/gpio.h>
  25. #include <asm/arch/pinmux.h>
  26. #include <asm/arch/sromc.h>
  27. static void exynos5_uart_config(int peripheral)
  28. {
  29. struct exynos5_gpio_part1 *gpio1 =
  30. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  31. struct s5p_gpio_bank *bank;
  32. int i, start, count;
  33. switch (peripheral) {
  34. case PERIPH_ID_UART0:
  35. bank = &gpio1->a0;
  36. start = 0;
  37. count = 4;
  38. break;
  39. case PERIPH_ID_UART1:
  40. bank = &gpio1->d0;
  41. start = 0;
  42. count = 4;
  43. break;
  44. case PERIPH_ID_UART2:
  45. bank = &gpio1->a1;
  46. start = 0;
  47. count = 4;
  48. break;
  49. case PERIPH_ID_UART3:
  50. bank = &gpio1->a1;
  51. start = 4;
  52. count = 2;
  53. break;
  54. }
  55. for (i = start; i < start + count; i++) {
  56. s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
  57. s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
  58. }
  59. }
  60. static int exynos5_mmc_config(int peripheral, int flags)
  61. {
  62. struct exynos5_gpio_part1 *gpio1 =
  63. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  64. struct s5p_gpio_bank *bank, *bank_ext;
  65. int i, start = 0, gpio_func = 0;
  66. switch (peripheral) {
  67. case PERIPH_ID_SDMMC0:
  68. bank = &gpio1->c0;
  69. bank_ext = &gpio1->c1;
  70. start = 0;
  71. gpio_func = GPIO_FUNC(0x2);
  72. break;
  73. case PERIPH_ID_SDMMC1:
  74. bank = &gpio1->c2;
  75. bank_ext = NULL;
  76. break;
  77. case PERIPH_ID_SDMMC2:
  78. bank = &gpio1->c3;
  79. bank_ext = &gpio1->c4;
  80. start = 3;
  81. gpio_func = GPIO_FUNC(0x3);
  82. break;
  83. case PERIPH_ID_SDMMC3:
  84. bank = &gpio1->c4;
  85. bank_ext = NULL;
  86. break;
  87. }
  88. if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) {
  89. debug("SDMMC device %d does not support 8bit mode",
  90. peripheral);
  91. return -1;
  92. }
  93. if (flags & PINMUX_FLAG_8BIT_MODE) {
  94. for (i = start; i <= (start + 3); i++) {
  95. s5p_gpio_cfg_pin(bank_ext, i, gpio_func);
  96. s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP);
  97. s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
  98. }
  99. }
  100. for (i = 0; i < 2; i++) {
  101. s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
  102. s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
  103. s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
  104. }
  105. for (i = 3; i <= 6; i++) {
  106. s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
  107. s5p_gpio_set_pull(bank, i, GPIO_PULL_UP);
  108. s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
  109. }
  110. return 0;
  111. }
  112. static void exynos5_sromc_config(int flags)
  113. {
  114. struct exynos5_gpio_part1 *gpio1 =
  115. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  116. int i;
  117. /*
  118. * SROM:CS1 and EBI
  119. *
  120. * GPY0[0] SROM_CSn[0]
  121. * GPY0[1] SROM_CSn[1](2)
  122. * GPY0[2] SROM_CSn[2]
  123. * GPY0[3] SROM_CSn[3]
  124. * GPY0[4] EBI_OEn(2)
  125. * GPY0[5] EBI_EEn(2)
  126. *
  127. * GPY1[0] EBI_BEn[0](2)
  128. * GPY1[1] EBI_BEn[1](2)
  129. * GPY1[2] SROM_WAIT(2)
  130. * GPY1[3] EBI_DATA_RDn(2)
  131. */
  132. s5p_gpio_cfg_pin(&gpio1->y0, (flags & PINMUX_FLAG_BANK),
  133. GPIO_FUNC(2));
  134. s5p_gpio_cfg_pin(&gpio1->y0, 4, GPIO_FUNC(2));
  135. s5p_gpio_cfg_pin(&gpio1->y0, 5, GPIO_FUNC(2));
  136. for (i = 0; i < 4; i++)
  137. s5p_gpio_cfg_pin(&gpio1->y1, i, GPIO_FUNC(2));
  138. /*
  139. * EBI: 8 Addrss Lines
  140. *
  141. * GPY3[0] EBI_ADDR[0](2)
  142. * GPY3[1] EBI_ADDR[1](2)
  143. * GPY3[2] EBI_ADDR[2](2)
  144. * GPY3[3] EBI_ADDR[3](2)
  145. * GPY3[4] EBI_ADDR[4](2)
  146. * GPY3[5] EBI_ADDR[5](2)
  147. * GPY3[6] EBI_ADDR[6](2)
  148. * GPY3[7] EBI_ADDR[7](2)
  149. *
  150. * EBI: 16 Data Lines
  151. *
  152. * GPY5[0] EBI_DATA[0](2)
  153. * GPY5[1] EBI_DATA[1](2)
  154. * GPY5[2] EBI_DATA[2](2)
  155. * GPY5[3] EBI_DATA[3](2)
  156. * GPY5[4] EBI_DATA[4](2)
  157. * GPY5[5] EBI_DATA[5](2)
  158. * GPY5[6] EBI_DATA[6](2)
  159. * GPY5[7] EBI_DATA[7](2)
  160. *
  161. * GPY6[0] EBI_DATA[8](2)
  162. * GPY6[1] EBI_DATA[9](2)
  163. * GPY6[2] EBI_DATA[10](2)
  164. * GPY6[3] EBI_DATA[11](2)
  165. * GPY6[4] EBI_DATA[12](2)
  166. * GPY6[5] EBI_DATA[13](2)
  167. * GPY6[6] EBI_DATA[14](2)
  168. * GPY6[7] EBI_DATA[15](2)
  169. */
  170. for (i = 0; i < 8; i++) {
  171. s5p_gpio_cfg_pin(&gpio1->y3, i, GPIO_FUNC(2));
  172. s5p_gpio_set_pull(&gpio1->y3, i, GPIO_PULL_UP);
  173. s5p_gpio_cfg_pin(&gpio1->y5, i, GPIO_FUNC(2));
  174. s5p_gpio_set_pull(&gpio1->y5, i, GPIO_PULL_UP);
  175. s5p_gpio_cfg_pin(&gpio1->y6, i, GPIO_FUNC(2));
  176. s5p_gpio_set_pull(&gpio1->y6, i, GPIO_PULL_UP);
  177. }
  178. }
  179. static void exynos5_i2c_config(int peripheral, int flags)
  180. {
  181. struct exynos5_gpio_part1 *gpio1 =
  182. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  183. switch (peripheral) {
  184. case PERIPH_ID_I2C0:
  185. s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2));
  186. s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2));
  187. break;
  188. case PERIPH_ID_I2C1:
  189. s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2));
  190. s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2));
  191. break;
  192. case PERIPH_ID_I2C2:
  193. s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
  194. s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
  195. break;
  196. case PERIPH_ID_I2C3:
  197. s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
  198. s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
  199. break;
  200. case PERIPH_ID_I2C4:
  201. s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3));
  202. s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3));
  203. break;
  204. case PERIPH_ID_I2C5:
  205. s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3));
  206. s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3));
  207. break;
  208. case PERIPH_ID_I2C6:
  209. s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4));
  210. s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4));
  211. break;
  212. case PERIPH_ID_I2C7:
  213. s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3));
  214. s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3));
  215. break;
  216. }
  217. }
  218. static void exynos5_i2s_config(int peripheral)
  219. {
  220. int i;
  221. struct exynos5_gpio_part1 *gpio1 =
  222. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  223. for (i = 0; i < 5; i++)
  224. s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
  225. }
  226. void exynos5_spi_config(int peripheral)
  227. {
  228. int cfg = 0, pin = 0, i;
  229. struct s5p_gpio_bank *bank = NULL;
  230. struct exynos5_gpio_part1 *gpio1 =
  231. (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
  232. struct exynos5_gpio_part2 *gpio2 =
  233. (struct exynos5_gpio_part2 *) samsung_get_base_gpio_part2();
  234. switch (peripheral) {
  235. case PERIPH_ID_SPI0:
  236. bank = &gpio1->a2;
  237. cfg = GPIO_FUNC(0x2);
  238. pin = 0;
  239. break;
  240. case PERIPH_ID_SPI1:
  241. bank = &gpio1->a2;
  242. cfg = GPIO_FUNC(0x2);
  243. pin = 4;
  244. break;
  245. case PERIPH_ID_SPI2:
  246. bank = &gpio1->b1;
  247. cfg = GPIO_FUNC(0x5);
  248. pin = 1;
  249. break;
  250. case PERIPH_ID_SPI3:
  251. bank = &gpio2->f1;
  252. cfg = GPIO_FUNC(0x2);
  253. pin = 0;
  254. break;
  255. case PERIPH_ID_SPI4:
  256. for (i = 0; i < 2; i++) {
  257. s5p_gpio_cfg_pin(&gpio2->f0, i + 2, GPIO_FUNC(0x4));
  258. s5p_gpio_cfg_pin(&gpio2->e0, i + 4, GPIO_FUNC(0x4));
  259. }
  260. break;
  261. }
  262. if (peripheral != PERIPH_ID_SPI4) {
  263. for (i = pin; i < pin + 4; i++)
  264. s5p_gpio_cfg_pin(bank, i, cfg);
  265. }
  266. }
  267. static int exynos5_pinmux_config(int peripheral, int flags)
  268. {
  269. switch (peripheral) {
  270. case PERIPH_ID_UART0:
  271. case PERIPH_ID_UART1:
  272. case PERIPH_ID_UART2:
  273. case PERIPH_ID_UART3:
  274. exynos5_uart_config(peripheral);
  275. break;
  276. case PERIPH_ID_SDMMC0:
  277. case PERIPH_ID_SDMMC1:
  278. case PERIPH_ID_SDMMC2:
  279. case PERIPH_ID_SDMMC3:
  280. return exynos5_mmc_config(peripheral, flags);
  281. case PERIPH_ID_SROMC:
  282. exynos5_sromc_config(flags);
  283. break;
  284. case PERIPH_ID_I2C0:
  285. case PERIPH_ID_I2C1:
  286. case PERIPH_ID_I2C2:
  287. case PERIPH_ID_I2C3:
  288. case PERIPH_ID_I2C4:
  289. case PERIPH_ID_I2C5:
  290. case PERIPH_ID_I2C6:
  291. case PERIPH_ID_I2C7:
  292. exynos5_i2c_config(peripheral, flags);
  293. break;
  294. case PERIPH_ID_I2S1:
  295. exynos5_i2s_config(peripheral);
  296. break;
  297. case PERIPH_ID_SPI0:
  298. case PERIPH_ID_SPI1:
  299. case PERIPH_ID_SPI2:
  300. case PERIPH_ID_SPI3:
  301. case PERIPH_ID_SPI4:
  302. exynos5_spi_config(peripheral);
  303. break;
  304. default:
  305. debug("%s: invalid peripheral %d", __func__, peripheral);
  306. return -1;
  307. }
  308. return 0;
  309. }
  310. static int exynos4_mmc_config(int peripheral, int flags)
  311. {
  312. struct exynos4_gpio_part2 *gpio2 =
  313. (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
  314. struct s5p_gpio_bank *bank, *bank_ext;
  315. int i;
  316. switch (peripheral) {
  317. case PERIPH_ID_SDMMC0:
  318. bank = &gpio2->k0;
  319. bank_ext = &gpio2->k1;
  320. break;
  321. case PERIPH_ID_SDMMC2:
  322. bank = &gpio2->k2;
  323. bank_ext = &gpio2->k3;
  324. break;
  325. default:
  326. return -1;
  327. }
  328. for (i = 0; i < 7; i++) {
  329. if (i == 2)
  330. continue;
  331. s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
  332. s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
  333. s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
  334. }
  335. if (flags & PINMUX_FLAG_8BIT_MODE) {
  336. for (i = 3; i < 7; i++) {
  337. s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3));
  338. s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_NONE);
  339. s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
  340. }
  341. }
  342. return 0;
  343. }
  344. static int exynos4_pinmux_config(int peripheral, int flags)
  345. {
  346. switch (peripheral) {
  347. case PERIPH_ID_SDMMC0:
  348. case PERIPH_ID_SDMMC2:
  349. return exynos4_mmc_config(peripheral, flags);
  350. case PERIPH_ID_SDMMC1:
  351. case PERIPH_ID_SDMMC3:
  352. case PERIPH_ID_SDMMC4:
  353. printf("SDMMC device %d not implemented\n", peripheral);
  354. return -1;
  355. default:
  356. debug("%s: invalid peripheral %d", __func__, peripheral);
  357. return -1;
  358. }
  359. return 0;
  360. }
  361. int exynos_pinmux_config(int peripheral, int flags)
  362. {
  363. if (cpu_is_exynos5())
  364. return exynos5_pinmux_config(peripheral, flags);
  365. else if (cpu_is_exynos4())
  366. return exynos4_pinmux_config(peripheral, flags);
  367. else {
  368. debug("pinmux functionality not supported\n");
  369. return -1;
  370. }
  371. }