gpio_init.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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. /*----------------------------------------------------------------------------*/
  56. #ifdef FPGA_PLATFORM
  57. void mt_gpio_set_default(void)
  58. {
  59. return;
  60. }
  61. #else
  62. #include <platform/gpio_init.h>
  63. #ifdef USE_DTB_NO_DWS
  64. #include <libfdt.h>
  65. #include <lk_builtin_dtb.h>
  66. extern void msdc_gpio_and_pad_init_by_id(int id);
  67. #define ELEMENTS_PER_GPIO 7
  68. #define GPIO_DT_NODE_NAME "/gpio@10005000"
  69. #define GPIO_DT_NODE_NAME_SOC "/soc/gpio@10005000"
  70. #define GPIO_DT_NODE_PROP_NAME "gpio_init_default"
  71. int mt_gpio_get_default_chip_from_dtb(void)
  72. {
  73. int off;
  74. unsigned int *data;
  75. int len = 0, pin, j;
  76. void *lk_drv_fdt = get_lk_overlayed_dtb();
  77. if (lk_drv_fdt == NULL)
  78. panic("lk driver fdt is NULL!\n");
  79. off = fdt_path_offset(lk_drv_fdt, GPIO_DT_NODE_NAME);
  80. dprintf(INFO, "[GPIO] Found " GPIO_DT_NODE_NAME "at offset %d\n", off);
  81. /* if default name is not found, retry for common kernel */
  82. if (off < 0) {
  83. off = fdt_path_offset(lk_drv_fdt, GPIO_DT_NODE_NAME_SOC);
  84. dprintf(INFO, "[GPIO] Found " GPIO_DT_NODE_NAME_SOC "at offset %d\n", off);
  85. /* fatal return if fail again */
  86. if (off < 0) {
  87. dprintf(CRITICAL, "[GPIO] Failed to find " GPIO_DT_NODE_NAME_SOC " in dtb\n");
  88. return -1;
  89. }
  90. }
  91. data = (unsigned int *)fdt_getprop(lk_drv_fdt, off, GPIO_DT_NODE_PROP_NAME, &len);
  92. if (len <= 0 || !data) {
  93. dprintf(CRITICAL, "[GPIO] Fail to found property " GPIO_DT_NODE_PROP_NAME "\n");
  94. return -1;
  95. }
  96. dprintf(INFO, "[GPIO] Found property at %p, len %d\n", data, len);
  97. if ((len > 0) && ((len % ELEMENTS_PER_GPIO) == 0)) {
  98. len /= (ELEMENTS_PER_GPIO * 4); //Per element use 4 bytes */
  99. for (j = 0; j < len; j++) {
  100. pin = fdt32_to_cpu(*data);
  101. if (pin < 0 || pin >= MT_GPIO_BASE_MAX) {
  102. data += 7;
  103. continue;
  104. }
  105. data++;
  106. gpio_array[pin].mode = (unsigned char) fdt32_to_cpu(*data);
  107. data++;
  108. gpio_array[pin].dir = (unsigned char) fdt32_to_cpu(*data);
  109. data++;
  110. gpio_array[pin].dataout = (unsigned char) fdt32_to_cpu(*data);
  111. data++;
  112. gpio_array[pin].pullen = (unsigned char) fdt32_to_cpu(*data);
  113. data++;
  114. gpio_array[pin].pull = (unsigned char) fdt32_to_cpu(*data);
  115. data++;
  116. gpio_array[pin].smt = (unsigned char) fdt32_to_cpu(*data);
  117. data++;
  118. #if 0
  119. dprintf(INFO, "GPIO: %d %d %d %d %d %d %d\n",
  120. pin,
  121. gpio_array[pin].mode,
  122. gpio_array[pin].dir,
  123. gpio_array[pin].dataout,
  124. gpio_array[pin].pullen,
  125. gpio_array[pin].pull,
  126. gpio_array[pin].smt
  127. );
  128. #endif
  129. }
  130. }
  131. return 0;
  132. }
  133. #endif
  134. void mt_gpio_set_default_chip(void)
  135. {
  136. unsigned pin = 0;
  137. #ifdef USE_DTB_NO_DWS
  138. /*
  139. * Pins set as GPIO_INIT_NO_COVER,
  140. * mode setting will not override in
  141. * mt_gpio_get_default_chip_from_dtb()
  142. */
  143. /* Init pin mode as 0xFF */
  144. for (pin = 0; pin < MT_GPIO_BASE_MAX; pin++)
  145. gpio_array[pin].mode = 0xFF;
  146. if (mt_gpio_get_default_chip_from_dtb() < 0)
  147. return;
  148. #endif
  149. for (pin = 0; pin < MT_GPIO_BASE_MAX; pin++) {
  150. /* Skip pins which is set as GPIO_INIT_NO_COVER */
  151. if (gpio_array[pin].mode == 0xFF)
  152. continue;
  153. /* set GPIOx_MODE*/
  154. mt_set_gpio_mode(0x80000000 + pin , gpio_array[pin].mode);
  155. /* set GPIOx_DIR*/
  156. if (gpio_array[pin].dir != 0xFF)
  157. mt_set_gpio_dir(0x80000000 + pin, gpio_array[pin].dir);
  158. /* set GPIOx_PULL*/
  159. if (gpio_array[pin].pull != 0xFF)
  160. mt_set_gpio_pull_select(0x80000000 + pin, gpio_array[pin].pull);
  161. /* set GPIOx_PULLEN*/
  162. if (gpio_array[pin].pullen != 0xFF)
  163. mt_set_gpio_pull_enable(0x80000000 + pin , gpio_array[pin].pullen);
  164. /* set GPIOx_DATAOUT*/
  165. if (gpio_array[pin].dataout != 0xFF)
  166. mt_set_gpio_out(0x80000000 + pin, gpio_array[pin].dataout);
  167. /* set GPIO0_SMT */
  168. if (gpio_array[pin].smt != 0xFF)
  169. mt_set_gpio_smt(0x80000000 + pin, gpio_array[pin].smt);
  170. }
  171. }
  172. void mt_gpio_set_default(void)
  173. {
  174. mt_gpio_set_default_chip();
  175. return;
  176. }
  177. /*----------------------------------------------------------------------------*/
  178. #if CHECK_POINT_TEST
  179. #if defined(GPIO_INIT_DEBUG)
  180. static GPIO_REGS saved;
  181. #endif
  182. void mt_gpio_checkpoint_save(void)
  183. {
  184. #if defined(GPIO_INIT_DEBUG)
  185. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  186. GPIO_REGS *cur = &saved;
  187. int idx;
  188. memset(cur, 0x00, sizeof(*cur));
  189. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++)
  190. cur->dir[idx].val = GPIO_RD32(&pReg->dir[idx]);
  191. #if 0
  192. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++)
  193. cur->pullen[idx].val = GPIO_RD32(&pReg->pullen[idx]);
  194. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++)
  195. cur->pullsel[idx].val =GPIO_RD32(&pReg->pullsel[idx]);
  196. #endif
  197. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++)
  198. cur->dout[idx].val = GPIO_RD32(&pReg->dout[idx]);
  199. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++)
  200. cur->mode[idx].val = GPIO_RD32(&pReg->mode[idx]);
  201. #endif
  202. }
  203. /*----------------------------------------------------------------------------*/
  204. EXPORT_SYMBOL(mt_gpio_checkpoint_save);
  205. /*----------------------------------------------------------------------------*/
  206. void mt_gpio_dump_diff(GPIO_REGS* pre, GPIO_REGS* cur)
  207. {
  208. #if defined(GPIO_INIT_DEBUG)
  209. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  210. int idx;
  211. unsigned char* p = (unsigned char*)pre;
  212. unsigned char* q = (unsigned char*)cur;
  213. GPIOVER("------ dumping difference between %p and %p ------\n", pre, cur);
  214. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++) {
  215. if (pre->dir[idx].val != cur->dir[idx].val)
  216. GPIOVER("diff: dir[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->dir[idx].val, cur->dir[idx].val);
  217. }
  218. #if 0
  219. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++) {
  220. if (pre->pullen[idx].val != cur->pullen[idx].val)
  221. GPIOVER("diff: pullen[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->pullen[idx].val, cur->pullen[idx].val);
  222. }
  223. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++) {
  224. if (pre->pullsel[idx].val != cur->pullsel[idx].val)
  225. GPIOVER("diff: pullsel[%2d]: 0x%08X <=> 0x%08X\n", idx, pre->pullsel[idx].val, cur->pullsel[idx].val);
  226. }
  227. #endif
  228. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++) {
  229. if (pre->dout[idx].val != cur->dout[idx].val)
  230. GPIOVER("diff: dout[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->dout[idx].val, cur->dout[idx].val);
  231. }
  232. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++) {
  233. if (pre->mode[idx].val != cur->mode[idx].val)
  234. GPIOVER("diff: mode[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->mode[idx].val, cur->mode[idx].val);
  235. }
  236. for (idx = 0; idx < sizeof(*pre); idx++) {
  237. if (p[idx] != q[idx])
  238. GPIOVER("diff: raw[%2d]: 0x%02X <=> 0x%02X\n", idx, p[idx], q[idx]);
  239. }
  240. GPIOVER("memcmp(%p, %p, %d) = %d\n", p, q, sizeof(*pre), memcmp(p, q, sizeof(*pre)));
  241. GPIOVER("------ dumping difference end --------------------------------\n");
  242. #endif
  243. }
  244. /*----------------------------------------------------------------------------*/
  245. void mt_gpio_checkpoint_compare(void)
  246. {
  247. #if defined(GPIO_INIT_DEBUG)
  248. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  249. GPIO_REGS latest;
  250. GPIO_REGS *cur = &latest;
  251. int idx;
  252. memset(cur, 0x00, sizeof(*cur));
  253. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++)
  254. cur->dir[idx].val = GPIO_RD32(&pReg->dir[idx]);
  255. #if 0
  256. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++)
  257. cur->pullen[idx].val = GPIO_RD32(&pReg->pullen[idx]);
  258. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++)
  259. cur->pullsel[idx].val =GPIO_RD32(&pReg->pullsel[idx]);
  260. #endif
  261. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++)
  262. cur->dout[idx].val = GPIO_RD32(&pReg->dout[idx]);
  263. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++)
  264. cur->mode[idx].val = GPIO_RD32(&pReg->mode[idx]);
  265. //mt_gpio_dump_diff(&latest, &saved);
  266. //GPIODBG("memcmp(%p, %p, %d) = %d\n", &latest, &saved, sizeof(GPIO_REGS), memcmp(&latest, &saved, sizeof(GPIO_REGS)));
  267. if (memcmp(&latest, &saved, sizeof(GPIO_REGS))) {
  268. GPIODBG("checkpoint compare fail!!\n");
  269. GPIODBG("dump checkpoint....\n");
  270. //mt_gpio_dump(&saved);
  271. GPIODBG("\n\n");
  272. GPIODBG("dump current state\n");
  273. //mt_gpio_dump(&latest);
  274. GPIODBG("\n\n");
  275. mt_gpio_dump_diff(&saved, &latest);
  276. //WARN_ON(1);
  277. } else {
  278. GPIODBG("checkpoint compare success!!\n");
  279. }
  280. #endif
  281. }
  282. /*----------------------------------------------------------------------------*/
  283. EXPORT_SYMBOL(mt_gpio_checkpoint_compare);
  284. /*----------------------------------------------------------------------------*/
  285. #endif
  286. #endif