mt_gpio_init.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <platform/mt_gpio.h>
  32. #if !defined(FPGA_PLATFORM) && !defined(USE_DTB_NO_DWS)
  33. #include <cust_power.h>
  34. #include <cust_gpio_boot.h>
  35. #endif
  36. #include <platform/mt_reg_base.h>
  37. #include <debug.h>
  38. #define GPIO_INIT_DEBUG
  39. /*----------------------------------------------------------------------------*/
  40. #define GPIOTAG "[GPIO] "
  41. #define GPIODBG(fmt, arg...) dprintf(INFO, GPIOTAG "%s: " fmt, __FUNCTION__ ,##arg)
  42. #define GPIOERR(fmt, arg...) dprintf(INFO, GPIOTAG "%s: " fmt, __FUNCTION__ ,##arg)
  43. #define GPIOVER(fmt, arg...) dprintf(INFO, GPIOTAG "%s: " fmt, __FUNCTION__ ,##arg)
  44. #define GPIO_WR32(addr, data) DRV_WriteReg32(addr,data)
  45. #define GPIO_RD32(addr) DRV_Reg32(addr)
  46. #define ADDR_BIT 0
  47. #define VAL_BIT 1
  48. #define MASK_BIT 2
  49. /*----------------------------------------------------------------------------*/
  50. #ifdef FPGA_PLATFORM
  51. void mt_gpio_set_default(void)
  52. {
  53. return;
  54. }
  55. #else
  56. #include <platform/gpio_init.h>
  57. #if defined(GPIO_INIT_DEBUG)
  58. static GPIO_REGS saved;
  59. #endif
  60. #ifdef USE_DTB_NO_DWS
  61. #include <libfdt.h>
  62. #include <lk_builtin_dtb.h>
  63. extern void msdc_gpio_and_pad_init_by_id(int id);
  64. #define ELEMENTS_PER_GPIO 7
  65. #define GPIO_DT_NODE_NAME "/gpio@10005000"
  66. #define GPIO_DT_NODE_PROP_NAME "gpio_init_default"
  67. int mt_gpio_get_default_chip_from_dtb(void)
  68. {
  69. void *lk_drv_fdt = get_lk_overlayed_dtb();
  70. if (lk_drv_fdt == NULL)
  71. panic("lk driver fdt is NULL!\n");
  72. int off = fdt_path_offset(lk_drv_fdt, 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(lk_drv_fdt, 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 %p, len %d\n", 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. mt_set_gpio_dir(0x80000000 + pin, gpio_array[pin].dir);
  137. //GPIOVER("fwq2..........\n");
  138. /* set GPIOx_PULLEN*/
  139. mt_set_gpio_pull_enable(0x80000000 + pin , gpio_array[pin].pullen);
  140. //GPIOVER("fwq3..........\n");
  141. /* set GPIOx_PULL*/
  142. mt_set_gpio_pull_select(0x80000000 + pin, gpio_array[pin].pull);
  143. /* set GPIOx_DATAOUT*/
  144. mt_set_gpio_out(0x80000000 + pin, gpio_array[pin].dataout);
  145. //GPIOVER("fwq5..........\n");
  146. /* set GPIO0_SMT */
  147. mt_set_gpio_smt(0x80000000 + pin, gpio_array[pin].smt);
  148. //GPIOVER("smt1-init %d\n",pin);
  149. }
  150. #ifdef USE_DTB_NO_DWS
  151. msdc_gpio_and_pad_init_by_id(0);
  152. #endif
  153. }
  154. void mt_gpio_set_driving(void)
  155. {
  156. #if 0
  157. u32 val;
  158. u32 mask;
  159. /* [MT6571] for MD BSI request */
  160. mask = 0x3000;
  161. val = GPIO_RD32(IO_CFG_T_BASE+0xF0);
  162. val &= ~(mask);
  163. val |= (0x0000 & mask);
  164. GPIO_WR32(IO_CFG_T_BASE+0xF0, val);
  165. /* [MT6571] end */
  166. /* [MT6571] for desense request (AUD IO) */
  167. mask = 0x30;
  168. val = GPIO_RD32(IO_CFG_L_BASE+0xA0);
  169. val &= ~(mask);
  170. val |= (0x00 & mask);
  171. GPIO_WR32(IO_CFG_L_BASE+0xA0, val);
  172. /* [MT6571] end */
  173. #endif
  174. }
  175. void mt_gpio_set_power(u8 mc1_power,u8 mc2_power, u8 sim1_power, u8 sim2_power)
  176. {
  177. #if 0
  178. u32 reg=0;
  179. //sim1
  180. if (sim1_power == GPIO_VIO28) {
  181. reg = GPIO_RD32(IOCFG_0_BASE+0x050);
  182. //reg |= (0x6000);
  183. GPIO_WR32(IOCFG_0_BASE+0x0c28, reg);
  184. } else {
  185. reg = GPIO_RD32(IOCFG_0_BASE+0x050);
  186. reg &= ~(0x3f<<12);
  187. GPIO_WR32(IOCFG_0_BASE+0x050, reg);
  188. }
  189. //sim2
  190. if (sim2_power == GPIO_VIO28) {
  191. reg = GPIO_RD32(IOCFG_0_BASE+0x050);
  192. //reg |= 0x0c;
  193. GPIO_WR32(IOCFG_0_BASE+0x050, reg);
  194. } else {
  195. reg = GPIO_RD32(IOCFG_0_BASE+0x050);
  196. reg &= ~(0x3f<<6);
  197. GPIO_WR32(IOCFG_0_BASE+0x050, reg);
  198. }
  199. #endif
  200. }
  201. /*FIX ME: create a customized file for platform-specific operations */
  202. void mt_gpio_set_avoid_leakage(void)
  203. {
  204. #if 0
  205. #ifdef MTK_EMMC_SUPPORT
  206. GPIO_WR32(IO_CFG_B_BASE+0x58, 0x220000);
  207. #endif
  208. #endif
  209. }
  210. void mt_gpio_set_default(void)
  211. {
  212. //mt_gpio_set_avoid_leakage();
  213. mt_gpio_set_default_chip();
  214. //mt_gpio_set_driving();
  215. //mt_gpio_set_power();
  216. return;
  217. }
  218. /*----------------------------------------------------------------------------*/
  219. #if CHECK_POINT_TEST
  220. void mt_gpio_checkpoint_save(void)
  221. {
  222. #if defined(GPIO_INIT_DEBUG)
  223. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  224. GPIO_REGS *cur = &saved;
  225. int idx;
  226. memset(cur, 0x00, sizeof(*cur));
  227. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++)
  228. cur->dir[idx].val = GPIO_RD32(&pReg->dir[idx]);
  229. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++)
  230. cur->pullen[idx].val = GPIO_RD32(&pReg->pullen[idx]);
  231. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++)
  232. cur->pullsel[idx].val =GPIO_RD32(&pReg->pullsel[idx]);
  233. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++)
  234. cur->dout[idx].val = GPIO_RD32(&pReg->dout[idx]);
  235. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++)
  236. cur->mode[idx].val = GPIO_RD32(&pReg->mode[idx]);
  237. #endif
  238. }
  239. /*----------------------------------------------------------------------------*/
  240. EXPORT_SYMBOL(mt_gpio_checkpoint_save);
  241. /*----------------------------------------------------------------------------*/
  242. void mt_gpio_dump_diff(GPIO_REGS* pre, GPIO_REGS* cur)
  243. {
  244. #if defined(GPIO_INIT_DEBUG)
  245. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  246. int idx;
  247. unsigned char* p = (unsigned char*)pre;
  248. unsigned char* q = (unsigned char*)cur;
  249. GPIOVER("------ dumping difference between %p and %p ------\n", pre, cur);
  250. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++) {
  251. if (pre->dir[idx].val != cur->dir[idx].val)
  252. GPIOVER("diff: dir[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->dir[idx].val, cur->dir[idx].val);
  253. }
  254. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++) {
  255. if (pre->pullen[idx].val != cur->pullen[idx].val)
  256. GPIOVER("diff: pullen[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->pullen[idx].val, cur->pullen[idx].val);
  257. }
  258. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++) {
  259. if (pre->pullsel[idx].val != cur->pullsel[idx].val)
  260. GPIOVER("diff: pullsel[%2d]: 0x%08X <=> 0x%08X\n", idx, pre->pullsel[idx].val, cur->pullsel[idx].val);
  261. }
  262. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++) {
  263. if (pre->dout[idx].val != cur->dout[idx].val)
  264. GPIOVER("diff: dout[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->dout[idx].val, cur->dout[idx].val);
  265. }
  266. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++) {
  267. if (pre->mode[idx].val != cur->mode[idx].val)
  268. GPIOVER("diff: mode[%2d] : 0x%08X <=> 0x%08X\n", idx, pre->mode[idx].val, cur->mode[idx].val);
  269. }
  270. for (idx = 0; idx < sizeof(*pre); idx++) {
  271. if (p[idx] != q[idx])
  272. GPIOVER("diff: raw[%2d]: 0x%02X <=> 0x%02X\n", idx, p[idx], q[idx]);
  273. }
  274. GPIOVER("memcmp(%p, %p, %d) = %d\n", p, q, sizeof(*pre), memcmp(p, q, sizeof(*pre)));
  275. GPIOVER("------ dumping difference end --------------------------------\n");
  276. #endif
  277. }
  278. /*----------------------------------------------------------------------------*/
  279. void mt_gpio_checkpoint_compare(void)
  280. {
  281. #if defined(GPIO_INIT_DEBUG)
  282. GPIO_REGS *pReg = (GPIO_REGS*)(GPIO_BASE);
  283. GPIO_REGS latest;
  284. GPIO_REGS *cur = &latest;
  285. int idx;
  286. memset(cur, 0x00, sizeof(*cur));
  287. for (idx = 0; idx < sizeof(pReg->dir)/sizeof(pReg->dir[0]); idx++)
  288. cur->dir[idx].val = GPIO_RD32(&pReg->dir[idx]);
  289. for (idx = 0; idx < sizeof(pReg->pullen)/sizeof(pReg->pullen[0]); idx++)
  290. cur->pullen[idx].val = GPIO_RD32(&pReg->pullen[idx]);
  291. for (idx = 0; idx < sizeof(pReg->pullsel)/sizeof(pReg->pullsel[0]); idx++)
  292. cur->pullsel[idx].val =GPIO_RD32(&pReg->pullsel[idx]);
  293. for (idx = 0; idx < sizeof(pReg->dout)/sizeof(pReg->dout[0]); idx++)
  294. cur->dout[idx].val = GPIO_RD32(&pReg->dout[idx]);
  295. for (idx = 0; idx < sizeof(pReg->mode)/sizeof(pReg->mode[0]); idx++)
  296. cur->mode[idx].val = GPIO_RD32(&pReg->mode[idx]);
  297. //mt_gpio_dump_diff(&latest, &saved);
  298. //GPIODBG("memcmp(%p, %p, %d) = %d\n", &latest, &saved, sizeof(GPIO_REGS), memcmp(&latest, &saved, sizeof(GPIO_REGS)));
  299. if (memcmp(&latest, &saved, sizeof(GPIO_REGS))) {
  300. GPIODBG("checkpoint compare fail!!\n");
  301. GPIODBG("dump checkpoint....\n");
  302. //mt_gpio_dump(&saved);
  303. GPIODBG("\n\n");
  304. GPIODBG("dump current state\n");
  305. //mt_gpio_dump(&latest);
  306. GPIODBG("\n\n");
  307. mt_gpio_dump_diff(&saved, &latest);
  308. //WARN_ON(1);
  309. } else {
  310. GPIODBG("checkpoint compare success!!\n");
  311. }
  312. #endif
  313. }
  314. /*----------------------------------------------------------------------------*/
  315. EXPORT_SYMBOL(mt_gpio_checkpoint_compare);
  316. /*----------------------------------------------------------------------------*/
  317. #endif
  318. #endif