mtgpio.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /*
  2. * Copyright (c) 2019, MediaTek Inc. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <common/debug.h>
  8. #include <drivers/delay_timer.h>
  9. #include <gpio/mtgpio.h>
  10. #include <gpio/mtgpio_cfg.h>
  11. #include <drivers/gpio.h>
  12. #include <mcucfg.h>
  13. #include <lib/mmio.h>
  14. #include <platform_def.h>
  15. #include <spm.h>
  16. #include <stdbool.h>
  17. /******************************************************************************
  18. *Macro Definition
  19. ******************************************************************************/
  20. #define GPIO_MODE_BITS 4
  21. #define MAX_GPIO_MODE_PER_REG 8
  22. #define MAX_GPIO_REG_BITS 32
  23. #define DIR_BASE (GPIO_BASE + 0x000)
  24. #define DOUT_BASE (GPIO_BASE + 0x100)
  25. #define DIN_BASE (GPIO_BASE + 0x200)
  26. #define MODE_BASE (GPIO_BASE + 0x300)
  27. #define SET 0x4
  28. #define CLR 0x8
  29. #define PULLEN_ADDR_OFFSET 0x060
  30. #define PULLSEL_ADDR_OFFSET 0x080
  31. void mt_set_gpio_dir_chip(uint32_t pin, int dir)
  32. {
  33. uint32_t pos, bit;
  34. assert(pin < MAX_GPIO_PIN);
  35. assert(dir < GPIO_DIR_MAX);
  36. pos = pin / MAX_GPIO_REG_BITS;
  37. bit = pin % MAX_GPIO_REG_BITS;
  38. if (dir == GPIO_DIR_IN)
  39. mmio_write_32(DIR_BASE + 0x10 * pos + CLR, 1U << bit);
  40. else
  41. mmio_write_32(DIR_BASE + 0x10 * pos + SET, 1U << bit);
  42. }
  43. int mt_get_gpio_dir_chip(uint32_t pin)
  44. {
  45. uint32_t pos, bit;
  46. uint32_t reg;
  47. assert(pin < MAX_GPIO_PIN);
  48. pos = pin / MAX_GPIO_REG_BITS;
  49. bit = pin % MAX_GPIO_REG_BITS;
  50. reg = mmio_read_32(DIR_BASE + 0x10 * pos);
  51. return (((reg & (1U << bit)) != 0) ? GPIO_DIR_OUT : GPIO_DIR_IN);
  52. }
  53. void mt_set_gpio_out_chip(uint32_t pin, int output)
  54. {
  55. uint32_t pos, bit;
  56. assert(pin < MAX_GPIO_PIN);
  57. assert(output < GPIO_OUT_MAX);
  58. pos = pin / MAX_GPIO_REG_BITS;
  59. bit = pin % MAX_GPIO_REG_BITS;
  60. if (output == GPIO_OUT_ZERO)
  61. mmio_write_32(DOUT_BASE + 0x10 * pos + CLR, 1U << bit);
  62. else
  63. mmio_write_32(DOUT_BASE + 0x10 * pos + SET, 1U << bit);
  64. }
  65. int mt_get_gpio_out_chip(uint32_t pin)
  66. {
  67. uint32_t pos, bit;
  68. uint32_t reg;
  69. assert(pin < MAX_GPIO_PIN);
  70. pos = pin / MAX_GPIO_REG_BITS;
  71. bit = pin % MAX_GPIO_REG_BITS;
  72. reg = mmio_read_32(DOUT_BASE + 0x10 * pos);
  73. return (((reg & (1U << bit)) != 0) ? 1 : 0);
  74. }
  75. int mt_get_gpio_in_chip(uint32_t pin)
  76. {
  77. uint32_t pos, bit;
  78. uint32_t reg;
  79. assert(pin < MAX_GPIO_PIN);
  80. pos = pin / MAX_GPIO_REG_BITS;
  81. bit = pin % MAX_GPIO_REG_BITS;
  82. reg = mmio_read_32(DIN_BASE + 0x10 * pos);
  83. return (((reg & (1U << bit)) != 0) ? 1 : 0);
  84. }
  85. void mt_set_gpio_mode_chip(uint32_t pin, int mode)
  86. {
  87. uint32_t pos, bit;
  88. uint32_t data;
  89. uint32_t mask;
  90. assert(pin < MAX_GPIO_PIN);
  91. assert(mode < GPIO_MODE_MAX);
  92. mask = (1U << GPIO_MODE_BITS) - 1;
  93. mode = mode & mask;
  94. pos = pin / MAX_GPIO_MODE_PER_REG;
  95. bit = (pin % MAX_GPIO_MODE_PER_REG) * GPIO_MODE_BITS;
  96. data = mmio_read_32(MODE_BASE + 0x10 * pos);
  97. data &= (~(mask << bit));
  98. data |= (mode << bit);
  99. mmio_write_32(MODE_BASE + 0x10 * pos, data);
  100. }
  101. int mt_get_gpio_mode_chip(uint32_t pin)
  102. {
  103. uint32_t pos, bit;
  104. uint32_t data;
  105. uint32_t mask;
  106. assert(pin < MAX_GPIO_PIN);
  107. mask = (1U << GPIO_MODE_BITS) - 1;
  108. pos = pin / MAX_GPIO_MODE_PER_REG;
  109. bit = (pin % MAX_GPIO_MODE_PER_REG) * GPIO_MODE_BITS;
  110. data = mmio_read_32(MODE_BASE + 0x10 * pos);
  111. return (data >> bit) & mask;
  112. }
  113. int32_t gpio_get_pull_iocfg(uint32_t pin)
  114. {
  115. switch (pin) {
  116. case 0 ... 10:
  117. return IOCFG_5_BASE;
  118. case 11 ... 12:
  119. return IOCFG_0_BASE;
  120. case 13 ... 28:
  121. return IOCFG_1_BASE;
  122. case 43 ... 49:
  123. return IOCFG_2_BASE;
  124. case 50 ... 60:
  125. return IOCFG_3_BASE;
  126. case 61 ... 88:
  127. return IOCFG_4_BASE;
  128. case 89 ... 90:
  129. return IOCFG_5_BASE;
  130. case 95 ... 106:
  131. return IOCFG_5_BASE;
  132. case 107 ... 121:
  133. return IOCFG_6_BASE;
  134. case 134 ... 160:
  135. return IOCFG_0_BASE;
  136. case 161 ... 166:
  137. return IOCFG_1_BASE;
  138. case 167 ... 176:
  139. return IOCFG_3_BASE;
  140. case 177 ... 179:
  141. return IOCFG_5_BASE;
  142. default:
  143. return -1;
  144. }
  145. }
  146. int32_t gpio_get_pupd_iocfg(uint32_t pin)
  147. {
  148. const int32_t offset = 0x0c0;
  149. switch (pin) {
  150. case 29 ... 34:
  151. return IOCFG_1_BASE + offset;
  152. case 35 ... 42:
  153. return IOCFG_2_BASE + offset;
  154. case 91 ... 94:
  155. return IOCFG_5_BASE + offset;
  156. case 122 ... 133:
  157. return IOCFG_7_BASE + offset;
  158. default:
  159. return -1;
  160. }
  161. }
  162. int gpio_get_pupd_offset(uint32_t pin)
  163. {
  164. switch (pin) {
  165. case 29 ... 34:
  166. return (pin - 29) * 4 % 32;
  167. case 35 ... 42:
  168. return (pin - 35) * 4 % 32;
  169. case 91 ... 94:
  170. return (pin - 91) * 4 % 32;
  171. case 122 ... 129:
  172. return (pin - 122) * 4 % 32;
  173. case 130 ... 133:
  174. return (pin - 130) * 4 % 32;
  175. default:
  176. return -1;
  177. }
  178. }
  179. void mt_set_gpio_pull_enable_chip(uint32_t pin, int en)
  180. {
  181. int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET;
  182. int pupd_addr = gpio_get_pupd_iocfg(pin);
  183. int pupd_offset = gpio_get_pupd_offset(pin);
  184. assert(pin < MAX_GPIO_PIN);
  185. assert(!((PULL_offset[pin].offset == (int8_t)-1) &&
  186. (pupd_offset == (int8_t)-1)));
  187. if (en == GPIO_PULL_DISABLE) {
  188. if (PULL_offset[pin].offset == (int8_t)-1)
  189. mmio_clrbits_32(pupd_addr, 3U << pupd_offset);
  190. else
  191. mmio_clrbits_32(pullen_addr,
  192. 1U << PULL_offset[pin].offset);
  193. } else if (en == GPIO_PULL_ENABLE) {
  194. if (PULL_offset[pin].offset == (int8_t)-1) {
  195. /* For PUPD+R0+R1 Type, mt_set_gpio_pull_enable
  196. * does not know
  197. * which one between PU and PD shall be enabled.
  198. * Use R0 to guarantee at one resistor is set when lk
  199. * apply default setting
  200. */
  201. mmio_setbits_32(pupd_addr, 1U << pupd_offset);
  202. mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 1));
  203. } else {
  204. /* For PULLEN + PULLSEL Type */
  205. mmio_setbits_32(pullen_addr,
  206. 1U << PULL_offset[pin].offset);
  207. }
  208. } else if (en == GPIO_PULL_ENABLE_R0) {
  209. assert(!(pupd_offset == (int8_t)-1));
  210. mmio_setbits_32(pupd_addr, 1U << pupd_offset);
  211. mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 1));
  212. } else if (en == GPIO_PULL_ENABLE_R1) {
  213. assert(!(pupd_offset == (int8_t)-1));
  214. mmio_clrbits_32(pupd_addr, 1U << pupd_offset);
  215. mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 1));
  216. } else if (en == GPIO_PULL_ENABLE_R0R1) {
  217. assert(!(pupd_offset == (int8_t)-1));
  218. mmio_setbits_32(pupd_addr, 3U << pupd_offset);
  219. }
  220. }
  221. int mt_get_gpio_pull_enable_chip(uint32_t pin)
  222. {
  223. uint32_t reg;
  224. int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET;
  225. int pupd_addr = gpio_get_pupd_iocfg(pin);
  226. int pupd_offset = gpio_get_pupd_offset(pin);
  227. assert(pin < MAX_GPIO_PIN);
  228. assert(!((PULL_offset[pin].offset == (int8_t)-1) &&
  229. (pupd_offset == (int8_t)-1)));
  230. if (PULL_offset[pin].offset == (int8_t)-1) {
  231. reg = mmio_read_32(pupd_addr);
  232. return ((reg & (3U << pupd_offset)) ? 1 : 0);
  233. } else if (pupd_offset == (int8_t)-1) {
  234. reg = mmio_read_32(pullen_addr);
  235. return ((reg & (1U << PULL_offset[pin].offset)) ? 1 : 0);
  236. }
  237. return -ERINVAL;
  238. }
  239. void mt_set_gpio_pull_select_chip(uint32_t pin, int sel)
  240. {
  241. int pullsel_addr = gpio_get_pull_iocfg(pin) + PULLSEL_ADDR_OFFSET;
  242. int pupd_addr = gpio_get_pupd_iocfg(pin);
  243. int pupd_offset = gpio_get_pupd_offset(pin);
  244. assert(pin < MAX_GPIO_PIN);
  245. assert(!((PULL_offset[pin].offset == (int8_t) -1) &&
  246. (pupd_offset == (int8_t)-1)));
  247. if (sel == GPIO_PULL_NONE) {
  248. /* Regard No PULL as PULL disable + pull down */
  249. mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_DISABLE);
  250. if (PULL_offset[pin].offset == (int8_t)-1)
  251. mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 2));
  252. else
  253. mmio_clrbits_32(pullsel_addr,
  254. 1U << PULL_offset[pin].offset);
  255. } else if (sel == GPIO_PULL_UP) {
  256. mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_ENABLE);
  257. if (PULL_offset[pin].offset == (int8_t)-1)
  258. mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 2));
  259. else
  260. mmio_setbits_32(pullsel_addr,
  261. 1U << PULL_offset[pin].offset);
  262. } else if (sel == GPIO_PULL_DOWN) {
  263. mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_ENABLE);
  264. if (PULL_offset[pin].offset == -1)
  265. mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 2));
  266. else
  267. mmio_clrbits_32(pullsel_addr,
  268. 1U << PULL_offset[pin].offset);
  269. }
  270. }
  271. /* get pull-up or pull-down, regardless of resistor value */
  272. int mt_get_gpio_pull_select_chip(uint32_t pin)
  273. {
  274. uint32_t reg;
  275. int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET;
  276. int pullsel_addr = gpio_get_pull_iocfg(pin) + PULLSEL_ADDR_OFFSET;
  277. int pupd_addr = gpio_get_pupd_iocfg(pin);
  278. int pupd_offset = gpio_get_pupd_offset(pin);
  279. assert(pin < MAX_GPIO_PIN);
  280. assert(!((PULL_offset[pin].offset == (int8_t)-1) &&
  281. (pupd_offset == (int8_t)-1)));
  282. if (PULL_offset[pin].offset == (int8_t)-1) {
  283. reg = mmio_read_32(pupd_addr);
  284. if (reg & (3U << pupd_offset)) {
  285. reg = mmio_read_32(pupd_addr);
  286. /* Reg value: 0 for PU, 1 for PD -->
  287. * reverse return value */
  288. return ((reg & (1U << (pupd_offset + 2))) ?
  289. GPIO_PULL_DOWN : GPIO_PULL_UP);
  290. } else {
  291. return GPIO_PULL_NONE;
  292. }
  293. } else if (pupd_offset == (int8_t)-1) {
  294. reg = mmio_read_32(pullen_addr);
  295. if ((reg & (1U << PULL_offset[pin].offset))) {
  296. reg = mmio_read_32(pullsel_addr);
  297. return ((reg & (1U << PULL_offset[pin].offset)) ?
  298. GPIO_PULL_UP : GPIO_PULL_DOWN);
  299. } else {
  300. return GPIO_PULL_NONE;
  301. }
  302. }
  303. return -ERINVAL;
  304. }
  305. void mt_set_gpio_dir(int gpio, int direction)
  306. {
  307. mt_set_gpio_dir_chip((uint32_t)gpio, direction);
  308. }
  309. int mt_get_gpio_dir(int gpio)
  310. {
  311. uint32_t pin;
  312. pin = (uint32_t)gpio;
  313. return mt_get_gpio_dir_chip(pin);
  314. }
  315. void mt_set_gpio_pull(int gpio, int pull)
  316. {
  317. uint32_t pin;
  318. pin = (uint32_t)gpio;
  319. mt_set_gpio_pull_select_chip(pin, pull);
  320. }
  321. int mt_get_gpio_pull(int gpio)
  322. {
  323. uint32_t pin;
  324. pin = (uint32_t)gpio;
  325. return mt_get_gpio_pull_select_chip(pin);
  326. }
  327. void mt_set_gpio_out(int gpio, int value)
  328. {
  329. uint32_t pin;
  330. pin = (uint32_t)gpio;
  331. mt_set_gpio_out_chip(pin, value);
  332. }
  333. int mt_get_gpio_out(int gpio)
  334. {
  335. uint32_t pin;
  336. pin = (uint32_t)gpio;
  337. return mt_get_gpio_out_chip(pin);
  338. }
  339. int mt_get_gpio_in(int gpio)
  340. {
  341. uint32_t pin;
  342. pin = (uint32_t)gpio;
  343. return mt_get_gpio_in_chip(pin);
  344. }
  345. void mt_set_gpio_mode(int gpio, int mode)
  346. {
  347. uint32_t pin;
  348. pin = (uint32_t)gpio;
  349. mt_set_gpio_mode_chip(pin, mode);
  350. }
  351. int mt_get_gpio_mode(int gpio)
  352. {
  353. uint32_t pin;
  354. pin = (uint32_t)gpio;
  355. return mt_get_gpio_mode_chip(pin);
  356. }
  357. const gpio_ops_t mtgpio_ops = {
  358. .get_direction = mt_get_gpio_dir,
  359. .set_direction = mt_set_gpio_dir,
  360. .get_value = mt_get_gpio_in,
  361. .set_value = mt_set_gpio_out,
  362. .set_pull = mt_set_gpio_pull,
  363. .get_pull = mt_get_gpio_pull,
  364. };