gpio_init.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  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_PROP_NAME "gpio_init_default"
  70. int mt_gpio_get_default_chip_from_dtb(void)
  71. {
  72. int off = fdt_path_offset(get_lk_overlayed_dtb(), GPIO_DT_NODE_NAME);
  73. unsigned int *data;
  74. int len = 0, pin, j;
  75. dprintf(INFO, "[GPIO] Found " GPIO_DT_NODE_NAME "at offset %d\n", off);
  76. if (off < 0) {
  77. dprintf(CRITICAL, "[GPIO] Failed to find " GPIO_DT_NODE_NAME " in dtb\n");
  78. return -1;
  79. } else {
  80. data = (unsigned int *)fdt_getprop(get_lk_overlayed_dtb(), off, GPIO_DT_NODE_PROP_NAME, &len);
  81. if (len <= 0 || !data) {
  82. dprintf(CRITICAL, "[GPIO] Fail to found property " GPIO_DT_NODE_PROP_NAME "\n");
  83. return -1;
  84. }
  85. dprintf(INFO, "[GPIO] Found perperty at 0x%08x, len %d\n", (unsigned int)data, len);
  86. }
  87. if ((len > 0) && ((len % ELEMENTS_PER_GPIO) == 0)) {
  88. len /= (ELEMENTS_PER_GPIO * 4); //Per element use 4 bytes */
  89. for (j = 0; j < len; j++) {
  90. pin = fdt32_to_cpu(*data);
  91. if (pin >= MT_GPIO_BASE_MAX) {
  92. data += 7;
  93. continue;
  94. }
  95. data++;
  96. gpio_array[pin].mode = (unsigned char) fdt32_to_cpu(*data);
  97. data++;
  98. gpio_array[pin].dir = (unsigned char) fdt32_to_cpu(*data);
  99. data++;
  100. gpio_array[pin].dataout = (unsigned char) fdt32_to_cpu(*data);
  101. data++;
  102. gpio_array[pin].pullen = (unsigned char) fdt32_to_cpu(*data);
  103. data++;
  104. gpio_array[pin].pull = (unsigned char) fdt32_to_cpu(*data);
  105. data++;
  106. gpio_array[pin].smt = (unsigned char) fdt32_to_cpu(*data);
  107. data++;
  108. #if 0
  109. dprintf(INFO, "GPIO: %d %d %d %d %d %d %d\n",
  110. pin,
  111. gpio_array[pin].mode,
  112. gpio_array[pin].dir,
  113. gpio_array[pin].dataout,
  114. gpio_array[pin].pullen,
  115. gpio_array[pin].pull,
  116. gpio_array[pin].smt
  117. );
  118. #endif
  119. }
  120. }
  121. return 0;
  122. }
  123. #endif
  124. void mt_gpio_set_default_chip(void)
  125. {
  126. unsigned pin = 0;
  127. #ifdef USE_DTB_NO_DWS
  128. if (mt_gpio_get_default_chip_from_dtb() < 0)
  129. return;
  130. #endif
  131. for (pin = 0; pin < MT_GPIO_BASE_MAX; pin++) {
  132. if (pin>=122 && pin<=133) continue;
  133. /* set GPIOx_MODE*/
  134. mt_set_gpio_mode(0x80000000 + pin , gpio_array[pin].mode);
  135. /* set GPIOx_DIR*/
  136. if (gpio_array[pin].dir != 0xFF)
  137. mt_set_gpio_dir(0x80000000 + pin, gpio_array[pin].dir);
  138. /* set GPIOx_PULL*/
  139. if (gpio_array[pin].pull != 0xFF)
  140. mt_set_gpio_pull_select(0x80000000 + pin, gpio_array[pin].pull);
  141. /* set GPIOx_PULLEN*/
  142. if (gpio_array[pin].pullen != 0xFF)
  143. mt_set_gpio_pull_enable(0x80000000 + pin , gpio_array[pin].pullen);
  144. /* set GPIOx_DATAOUT*/
  145. if (gpio_array[pin].dataout != 0xFF)
  146. mt_set_gpio_out(0x80000000 + pin, gpio_array[pin].dataout);
  147. /* set GPIO0_SMT */
  148. if (gpio_array[pin].smt != 0xFF)
  149. mt_set_gpio_smt(0x80000000 + pin, gpio_array[pin].smt);
  150. }
  151. }
  152. void mt_gpio_set_driving(void)
  153. {
  154. #if 0
  155. u32 val;
  156. u32 mask;
  157. /* [MT6571] for MD BSI request */
  158. mask = 0x3000;
  159. val = GPIO_RD32(IO_CFG_T_BASE+0xF0);
  160. val &= ~(mask);
  161. val |= (0x0000 & mask);
  162. GPIO_WR32(IO_CFG_T_BASE+0xF0, val);
  163. /* [MT6571] end */
  164. /* [MT6571] for desense request (AUD IO) */
  165. mask = 0x30;
  166. val = GPIO_RD32(IO_CFG_L_BASE+0xA0);
  167. val &= ~(mask);
  168. val |= (0x00 & mask);
  169. GPIO_WR32(IO_CFG_L_BASE+0xA0, val);
  170. /* [MT6571] end */
  171. #endif
  172. }
  173. void mt_gpio_set_power(u8 mc1_power,u8 mc2_power, u8 sim1_power, u8 sim2_power)
  174. {
  175. #if 0
  176. u32 reg=0;
  177. //sim1
  178. if (sim1_power == GPIO_VIO28) {
  179. reg = GPIO_RD32(IOCFG_0_BASE+0x050);
  180. //reg |= (0x6000);
  181. GPIO_WR32(IOCFG_0_BASE+0x0c28, reg);
  182. } else {
  183. reg = GPIO_RD32(IOCFG_0_BASE+0x050);
  184. reg &= ~(0x3f<<12);
  185. GPIO_WR32(IOCFG_0_BASE+0x050, reg);
  186. }
  187. //sim2
  188. if (sim2_power == GPIO_VIO28) {
  189. reg = GPIO_RD32(IOCFG_0_BASE+0x050);
  190. //reg |= 0x0c;
  191. GPIO_WR32(IOCFG_0_BASE+0x050, reg);
  192. } else {
  193. reg = GPIO_RD32(IOCFG_0_BASE+0x050);
  194. reg &= ~(0x3f<<6);
  195. GPIO_WR32(IOCFG_0_BASE+0x050, reg);
  196. }
  197. #endif
  198. }
  199. /*FIX ME: create a customized file for platform-specific operations */
  200. void mt_gpio_set_avoid_leakage(void)
  201. {
  202. #if 0
  203. #ifdef MTK_EMMC_SUPPORT
  204. GPIO_WR32(IO_CFG_B_BASE+0x58, 0x220000);
  205. #endif
  206. #endif
  207. }
  208. void mt_gpio_set_default(void)
  209. {
  210. //mt_gpio_set_avoid_leakage();
  211. mt_gpio_set_default_chip();
  212. //mt_gpio_set_driving();
  213. //mt_gpio_set_power();
  214. return;
  215. }
  216. /*----------------------------------------------------------------------------*/
  217. #if CHECK_POINT_TEST
  218. #if defined(GPIO_INIT_DEBUG)
  219. static GPIO_REGS saved;
  220. #endif
  221. void mt_gpio_checkpoint_save(void)
  222. {
  223. #if defined(GPIO_INIT_DEBUG)
  224. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  225. GPIO_REGS *cur = &saved;
  226. int idx;
  227. memset(cur, 0x00, sizeof(*cur));
  228. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++)
  229. cur->dir[idx].val = GPIO_RD32(&pReg->dir[idx]);
  230. #if 0
  231. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++)
  232. cur->pullen[idx].val = GPIO_RD32(&pReg->pullen[idx]);
  233. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++)
  234. cur->pullsel[idx].val =GPIO_RD32(&pReg->pullsel[idx]);
  235. #endif
  236. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++)
  237. cur->dout[idx].val = GPIO_RD32(&pReg->dout[idx]);
  238. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++)
  239. cur->mode[idx].val = GPIO_RD32(&pReg->mode[idx]);
  240. #endif
  241. }
  242. /*----------------------------------------------------------------------------*/
  243. EXPORT_SYMBOL(mt_gpio_checkpoint_save);
  244. /*----------------------------------------------------------------------------*/
  245. void mt_gpio_dump_diff(GPIO_REGS* pre, GPIO_REGS* cur)
  246. {
  247. #if defined(GPIO_INIT_DEBUG)
  248. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  249. int idx;
  250. unsigned char* p = (unsigned char*)pre;
  251. unsigned char* q = (unsigned char*)cur;
  252. GPIOVER("------ dumping difference between %p and %p ------\n", pre, cur);
  253. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++) {
  254. if (pre->dir[idx].val != cur->dir[idx].val)
  255. GPIOVER("diff: dir[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->dir[idx].val, cur->dir[idx].val);
  256. }
  257. #if 0
  258. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++) {
  259. if (pre->pullen[idx].val != cur->pullen[idx].val)
  260. GPIOVER("diff: pullen[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->pullen[idx].val, cur->pullen[idx].val);
  261. }
  262. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++) {
  263. if (pre->pullsel[idx].val != cur->pullsel[idx].val)
  264. GPIOVER("diff: pullsel[%2d]: 0x%08X <=> 0x%08X\n", idx, pre->pullsel[idx].val, cur->pullsel[idx].val);
  265. }
  266. #endif
  267. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++) {
  268. if (pre->dout[idx].val != cur->dout[idx].val)
  269. GPIOVER("diff: dout[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->dout[idx].val, cur->dout[idx].val);
  270. }
  271. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++) {
  272. if (pre->mode[idx].val != cur->mode[idx].val)
  273. GPIOVER("diff: mode[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->mode[idx].val, cur->mode[idx].val);
  274. }
  275. for (idx = 0; idx < sizeof(*pre); idx++) {
  276. if (p[idx] != q[idx])
  277. GPIOVER("diff: raw[%2d]: 0x%02X <=> 0x%02X\n", idx, p[idx], q[idx]);
  278. }
  279. GPIOVER("memcmp(%p, %p, %d) = %d\n", p, q, sizeof(*pre), memcmp(p, q, sizeof(*pre)));
  280. GPIOVER("------ dumping difference end --------------------------------\n");
  281. #endif
  282. }
  283. /*----------------------------------------------------------------------------*/
  284. void mt_gpio_checkpoint_compare(void)
  285. {
  286. #if defined(GPIO_INIT_DEBUG)
  287. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  288. GPIO_REGS latest;
  289. GPIO_REGS *cur = &latest;
  290. int idx;
  291. memset(cur, 0x00, sizeof(*cur));
  292. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++)
  293. cur->dir[idx].val = GPIO_RD32(&pReg->dir[idx]);
  294. #if 0
  295. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++)
  296. cur->pullen[idx].val = GPIO_RD32(&pReg->pullen[idx]);
  297. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++)
  298. cur->pullsel[idx].val =GPIO_RD32(&pReg->pullsel[idx]);
  299. #endif
  300. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++)
  301. cur->dout[idx].val = GPIO_RD32(&pReg->dout[idx]);
  302. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++)
  303. cur->mode[idx].val = GPIO_RD32(&pReg->mode[idx]);
  304. //mt_gpio_dump_diff(&latest, &saved);
  305. //GPIODBG("memcmp(%p, %p, %d) = %d\n", &latest, &saved, sizeof(GPIO_REGS), memcmp(&latest, &saved, sizeof(GPIO_REGS)));
  306. if (memcmp(&latest, &saved, sizeof(GPIO_REGS))) {
  307. GPIODBG("checkpoint compare fail!!\n");
  308. GPIODBG("dump checkpoint....\n");
  309. //mt_gpio_dump(&saved);
  310. GPIODBG("\n\n");
  311. GPIODBG("dump current state\n");
  312. //mt_gpio_dump(&latest);
  313. GPIODBG("\n\n");
  314. mt_gpio_dump_diff(&saved, &latest);
  315. //WARN_ON(1);
  316. } else {
  317. GPIODBG("checkpoint compare success!!\n");
  318. }
  319. #endif
  320. }
  321. /*----------------------------------------------------------------------------*/
  322. EXPORT_SYMBOL(mt_gpio_checkpoint_compare);
  323. /*----------------------------------------------------------------------------*/
  324. #endif
  325. #endif