gpio_init.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein is
  5. * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
  6. * the prior written permission of MediaTek inc. and/or its licensors, any
  7. * reproduction, modification, use or disclosure of MediaTek Software, and
  8. * information contained herein, in whole or in part, shall be strictly
  9. * prohibited.
  10. *
  11. * MediaTek Inc. (C) 2017. All rights reserved.
  12. *
  13. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  14. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  15. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
  16. * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
  17. * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  19. * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
  20. * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
  21. * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
  22. * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
  23. * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
  24. * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
  25. * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
  26. * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  27. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
  28. * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
  29. * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
  30. * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
  31. * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  32. *
  33. * The following software/firmware and/or related documentation ("MediaTek
  34. * Software") have been modified by MediaTek Inc. All revisions are subject to
  35. * any receiver's applicable license agreements with MediaTek Inc.
  36. */
  37. #include <platform/mt_gpio.h>
  38. #if !defined(FPGA_PLATFORM) && !defined(USE_DTB_NO_DWS)
  39. #include <cust_power.h>
  40. #include <cust_gpio_boot.h>
  41. #endif
  42. #include <platform/mt_reg_base.h>
  43. #include <debug.h>
  44. #define GPIO_INIT_DEBUG
  45. /*----------------------------------------------------------------------------*/
  46. #define GPIOTAG "[GPIO] "
  47. #define GPIODBG(fmt, arg...) dprintf(INFO, GPIOTAG "%s: " fmt, __FUNCTION__ ,##arg)
  48. #define GPIOERR(fmt, arg...) dprintf(INFO, GPIOTAG "%s: " fmt, __FUNCTION__ ,##arg)
  49. #define GPIOVER(fmt, arg...) dprintf(INFO, GPIOTAG "%s: " fmt, __FUNCTION__ ,##arg)
  50. #define GPIO_WR32(addr, data) DRV_WriteReg32(addr,data)
  51. #define GPIO_RD32(addr) DRV_Reg32(addr)
  52. #define ADDR_BIT 0
  53. #define VAL_BIT 1
  54. #define MASK_BIT 2
  55. //#define GPIO_SET_DEFAULT_DBG
  56. /*----------------------------------------------------------------------------*/
  57. #ifdef FPGA_PLATFORM
  58. void mt_gpio_set_default(void)
  59. {
  60. return;
  61. }
  62. #else
  63. #include <platform/gpio_init.h>
  64. #ifdef USE_DTB_NO_DWS
  65. #include <libfdt.h>
  66. #include <lk_builtin_dtb.h>
  67. extern void msdc_gpio_and_pad_init_by_id(int id);
  68. #define ELEMENTS_PER_GPIO 7
  69. #define GPIO_DT_NODE_NAME "/gpio@10005000"
  70. #define GPIO_DT_NODE_PROP_NAME "gpio_init_default"
  71. int mt_gpio_get_default_chip_from_dtb(void)
  72. {
  73. void *lk_drv_fdt = get_lk_overlayed_dtb();
  74. if (lk_drv_fdt == NULL)
  75. panic("lk driver fdt is NULL!\n");
  76. int off = fdt_path_offset(lk_drv_fdt, GPIO_DT_NODE_NAME);
  77. unsigned int *data;
  78. int len = 0, pin, j;
  79. dprintf(INFO, "[GPIO] Found " GPIO_DT_NODE_NAME "at offset %d\n", off);
  80. if (off < 0) {
  81. dprintf(CRITICAL, "[GPIO] Failed to find " GPIO_DT_NODE_NAME " in dtb\n");
  82. return -1;
  83. } else {
  84. data = (unsigned int *)fdt_getprop(lk_drv_fdt, off, GPIO_DT_NODE_PROP_NAME, &len);
  85. if (len <= 0 || !data) {
  86. dprintf(CRITICAL, "[GPIO] Fail to found property " GPIO_DT_NODE_PROP_NAME "\n");
  87. return -1;
  88. }
  89. dprintf(INFO, "[GPIO] Found perperty at 0x%08x, len %d\n", (unsigned int)data, len);
  90. }
  91. if ((len > 0) && ((len % ELEMENTS_PER_GPIO) == 0)) {
  92. len /= (ELEMENTS_PER_GPIO * 4); //Per element use 4 bytes */
  93. for (j = 0; j < len; j++) {
  94. pin = fdt32_to_cpu(*data);
  95. if (pin >= MT_GPIO_BASE_MAX) {
  96. data += 7;
  97. continue;
  98. }
  99. data++;
  100. gpio_array[pin].mode = (unsigned char) fdt32_to_cpu(*data);
  101. data++;
  102. gpio_array[pin].dir = (unsigned char) fdt32_to_cpu(*data);
  103. data++;
  104. gpio_array[pin].dataout = (unsigned char) fdt32_to_cpu(*data);
  105. data++;
  106. gpio_array[pin].pullen = (unsigned char) fdt32_to_cpu(*data);
  107. data++;
  108. gpio_array[pin].pull = (unsigned char) fdt32_to_cpu(*data);
  109. data++;
  110. gpio_array[pin].smt = (unsigned char) fdt32_to_cpu(*data);
  111. data++;
  112. }
  113. }
  114. return 0;
  115. }
  116. #endif
  117. void mt_gpio_set_default_chip(void)
  118. {
  119. unsigned pin = 0;
  120. #ifdef USE_DTB_NO_DWS
  121. /*
  122. * Pins set as GPIO_INIT_NO_COVER,
  123. * mode setting will not override in
  124. * mt_gpio_get_default_chip_from_dtb()
  125. */
  126. /* Init pin mode as 0xFF */
  127. for (pin = 0; pin < MT_GPIO_BASE_MAX; pin++)
  128. gpio_array[pin].mode = 0xFF;
  129. if (mt_gpio_get_default_chip_from_dtb() < 0)
  130. return;
  131. #endif
  132. for (pin = 0; pin < MT_GPIO_BASE_MAX; pin++) {
  133. /* Skip pins which is set as GPIO_INIT_NO_COVER */
  134. if (gpio_array[pin].mode == 0xFF)
  135. continue;
  136. /* set GPIOx_MODE*/
  137. mt_set_gpio_mode(0x80000000 + pin , gpio_array[pin].mode);
  138. /* set GPIOx_DIR*/
  139. if (gpio_array[pin].dir != 0xFF)
  140. mt_set_gpio_dir(0x80000000 + pin, gpio_array[pin].dir);
  141. /* set GPIOx_PULL*/
  142. if (gpio_array[pin].pullen == 0)
  143. gpio_array[pin].pull = GPIO_NO_PULL;
  144. if (gpio_array[pin].pull != 0xFF)
  145. mt_set_gpio_pull_select(0x80000000 + pin, gpio_array[pin].pull);
  146. /* set GPIOx_PULLEN*/
  147. if (gpio_array[pin].pullen != 0xFF)
  148. mt_set_gpio_pull_enable(0x80000000 + pin , gpio_array[pin].pullen);
  149. /* set GPIOx_DATAOUT*/
  150. if (gpio_array[pin].dataout != 0xFF)
  151. mt_set_gpio_out(0x80000000 + pin, gpio_array[pin].dataout);
  152. /* set GPIO0_SMT */
  153. if (gpio_array[pin].smt != 0xFF)
  154. mt_set_gpio_smt(0x80000000 + pin, gpio_array[pin].smt);
  155. #ifdef GPIO_SET_DEFAULT_DBG
  156. dprintf(CRITICAL, "GPIO%d desired: %d %d %d %d %d %d\n",
  157. pin,
  158. gpio_array[pin].mode,
  159. gpio_array[pin].dir,
  160. gpio_array[pin].pull,
  161. gpio_array[pin].pullen,
  162. gpio_array[pin].dataout,
  163. gpio_array[pin].smt);
  164. /* set GPIOx_MODE*/
  165. dprintf(CRITICAL, "GPIO%d modified: %d %d %d %d %d %d\n",
  166. pin,
  167. mt_get_gpio_mode(0x80000000 + pin),
  168. mt_get_gpio_dir(0x80000000 + pin),
  169. mt_get_gpio_pull_select(0x80000000 + pin),
  170. mt_get_gpio_pull_enable(0x80000000 + pin),
  171. mt_get_gpio_out(0x80000000 + pin),
  172. mt_get_gpio_smt(0x80000000 + pin));
  173. #endif
  174. }
  175. }
  176. void mt_gpio_set_default(void)
  177. {
  178. mt_gpio_set_default_chip();
  179. return;
  180. }
  181. /*----------------------------------------------------------------------------*/
  182. #if CHECK_POINT_TEST
  183. #if defined(GPIO_INIT_DEBUG)
  184. static GPIO_REGS saved;
  185. #endif
  186. void mt_gpio_checkpoint_save(void)
  187. {
  188. #if defined(GPIO_INIT_DEBUG)
  189. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  190. GPIO_REGS *cur = &saved;
  191. int idx;
  192. memset(cur, 0x00, sizeof(*cur));
  193. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++)
  194. cur->dir[idx].val = GPIO_RD32(&pReg->dir[idx]);
  195. #if 0
  196. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++)
  197. cur->pullen[idx].val = GPIO_RD32(&pReg->pullen[idx]);
  198. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++)
  199. cur->pullsel[idx].val =GPIO_RD32(&pReg->pullsel[idx]);
  200. #endif
  201. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++)
  202. cur->dout[idx].val = GPIO_RD32(&pReg->dout[idx]);
  203. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++)
  204. cur->mode[idx].val = GPIO_RD32(&pReg->mode[idx]);
  205. #endif
  206. }
  207. /*----------------------------------------------------------------------------*/
  208. EXPORT_SYMBOL(mt_gpio_checkpoint_save);
  209. /*----------------------------------------------------------------------------*/
  210. void mt_gpio_dump_diff(GPIO_REGS* pre, GPIO_REGS* cur)
  211. {
  212. #if defined(GPIO_INIT_DEBUG)
  213. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  214. int idx;
  215. unsigned char* p = (unsigned char*)pre;
  216. unsigned char* q = (unsigned char*)cur;
  217. GPIOVER("------ dumping difference between %p and %p ------\n", pre, cur);
  218. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++) {
  219. if (pre->dir[idx].val != cur->dir[idx].val)
  220. GPIOVER("diff: dir[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->dir[idx].val, cur->dir[idx].val);
  221. }
  222. #if 0
  223. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++) {
  224. if (pre->pullen[idx].val != cur->pullen[idx].val)
  225. GPIOVER("diff: pullen[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->pullen[idx].val, cur->pullen[idx].val);
  226. }
  227. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++) {
  228. if (pre->pullsel[idx].val != cur->pullsel[idx].val)
  229. GPIOVER("diff: pullsel[%2d]: 0x%08X <=> 0x%08X\n", idx, pre->pullsel[idx].val, cur->pullsel[idx].val);
  230. }
  231. #endif
  232. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++) {
  233. if (pre->dout[idx].val != cur->dout[idx].val)
  234. GPIOVER("diff: dout[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->dout[idx].val, cur->dout[idx].val);
  235. }
  236. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++) {
  237. if (pre->mode[idx].val != cur->mode[idx].val)
  238. GPIOVER("diff: mode[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->mode[idx].val, cur->mode[idx].val);
  239. }
  240. for (idx = 0; idx < sizeof(*pre); idx++) {
  241. if (p[idx] != q[idx])
  242. GPIOVER("diff: raw[%2d]: 0x%02X <=> 0x%02X\n", idx, p[idx], q[idx]);
  243. }
  244. GPIOVER("memcmp(%p, %p, %d) = %d\n", p, q, sizeof(*pre), memcmp(p, q, sizeof(*pre)));
  245. GPIOVER("------ dumping difference end --------------------------------\n");
  246. #endif
  247. }
  248. /*----------------------------------------------------------------------------*/
  249. void mt_gpio_checkpoint_compare(void)
  250. {
  251. #if defined(GPIO_INIT_DEBUG)
  252. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  253. GPIO_REGS latest;
  254. GPIO_REGS *cur = &latest;
  255. int idx;
  256. memset(cur, 0x00, sizeof(*cur));
  257. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++)
  258. cur->dir[idx].val = GPIO_RD32(&pReg->dir[idx]);
  259. #if 0
  260. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++)
  261. cur->pullen[idx].val = GPIO_RD32(&pReg->pullen[idx]);
  262. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++)
  263. cur->pullsel[idx].val =GPIO_RD32(&pReg->pullsel[idx]);
  264. #endif
  265. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++)
  266. cur->dout[idx].val = GPIO_RD32(&pReg->dout[idx]);
  267. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++)
  268. cur->mode[idx].val = GPIO_RD32(&pReg->mode[idx]);
  269. //mt_gpio_dump_diff(&latest, &saved);
  270. //GPIODBG("memcmp(%p, %p, %d) = %d\n", &latest, &saved, sizeof(GPIO_REGS), memcmp(&latest, &saved, sizeof(GPIO_REGS)));
  271. if (memcmp(&latest, &saved, sizeof(GPIO_REGS))) {
  272. GPIODBG("checkpoint compare fail!!\n");
  273. GPIODBG("dump checkpoint....\n");
  274. //mt_gpio_dump(&saved);
  275. GPIODBG("\n\n");
  276. GPIODBG("dump current state\n");
  277. //mt_gpio_dump(&latest);
  278. GPIODBG("\n\n");
  279. mt_gpio_dump_diff(&saved, &latest);
  280. //WARN_ON(1);
  281. } else {
  282. GPIODBG("checkpoint compare success!!\n");
  283. }
  284. #endif
  285. }
  286. /*----------------------------------------------------------------------------*/
  287. EXPORT_SYMBOL(mt_gpio_checkpoint_compare);
  288. /*----------------------------------------------------------------------------*/
  289. #endif
  290. #endif