msdc_irq.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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) 2018. 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. * The following software/firmware and/or related documentation ("MediaTek Software")
  32. * have been modified by MediaTek Inc. All revisions are subject to any receiver\'s
  33. * applicable license agreements with MediaTek Inc.
  34. */
  35. #include "msdc.h"
  36. #if defined(MMC_MSDC_DRV_LK)
  37. #include <kernel/event.h>
  38. #include <mt_gic.h>
  39. static event_t msdc_int_event;
  40. static u32 g_int_status = 0;
  41. void lk_msdc_irq_handler(unsigned int irq)
  42. {
  43. u32 intrs,sts;
  44. struct mmc_host *host = mmc_get_host(irq-MT_MSDC0_IRQ_ID);
  45. u32 base = host->base;
  46. mt_irq_ack(irq);
  47. intrs = MSDC_READ32(MSDC_INTEN);
  48. msdc_intr_mask(host,intrs);
  49. MSG(INT, "[lk_msdc_irq_handler]irq %x enable:%x %x\n",irq,intrs,MSDC_READ32(MSDC_INT));
  50. if ((sts = MSDC_READ32(MSDC_INT))& intrs) {
  51. g_int_status = sts;
  52. MSG(INT, "[lk_msdc_irq_handler]send event,%x\n",g_int_status);
  53. MSDC_WRITE32(MSDC_INT, sts);
  54. event_signal(&msdc_int_event,0);
  55. }
  56. return;
  57. }
  58. #endif
  59. #if defined(MSDC_USE_IRQ)
  60. #include "isrentry.h"
  61. //For CTP only
  62. typedef void (*irq_handler_t)(void);
  63. static const u32 msdc_irq_line[MSDC_MAX_NUM] = {MSDC0_IRQ_BIT_ID, MSDC1_IRQ_BIT__ID};
  64. static void *msdc_irq_data[MSDC_MAX_NUM];
  65. volatile u32 msdc_irq_sts[MSDC_MAX_NUM];
  66. static hw_irq_handler_t sdio_irq_handler[MSDC_MAX_NUM];
  67. #define DECLARE_MSDC_IRQ_HANDLER(x) \
  68. static void msdc_irq_handler_##x(void) \
  69. { \
  70. msdc_irq_handler(msdc_irq_data[(x)]); \
  71. }
  72. #define REGISTER_MSDC_IRQ_HANDLER(id, hndl, data) \
  73. do { \
  74. msdc_irq_data[(id)] = (void*)(data); \
  75. IRQSensitivity(msdc_irq_line[(id)], LEVEL_SENSITIVE); \
  76. IRQPolarity(msdc_irq_line[(id)], LOW_LEVEL_TRIGGER); \
  77. IRQ_Register_LISR(msdc_irq_line[(id)], hndl, NULL); \
  78. IRQUnmask(msdc_irq_line[(id)]); \
  79. } while(0)
  80. #define UNREGISTER_MSDC_IRQ_HANDLER(id) \
  81. do { \
  82. IRQMask(msdc_irq_line[(id)]); \
  83. msdc_irq_data[(id)] = NULL; \
  84. IRQ_Register_LISR(msdc_irq_line[(id)], IRQ_Default_LISR, NULL); \
  85. } while(0)
  86. #if defined(FEATURE_MMC_SDIO)
  87. static hw_irq_handler_t sdio_irq_handler[MSDC_MAX_NUM];
  88. void msdc_register_hwirq(struct mmc_host *host, hw_irq_handler_t handler)
  89. {
  90. sdio_irq_handler[host->id] = handler;
  91. }
  92. #endif
  93. #if defined(MMC_MSDC_DRV_CTP) && defined(FEATURE_MTH)
  94. extern void mth_get_gic_pending_reg(void);
  95. #endif
  96. int in_irq = 0;
  97. static void msdc_irq_handler(void *data)
  98. {
  99. struct mmc_host *host = (struct mmc_host*)data;
  100. u32 id = host->id;
  101. u32 base = host->base;
  102. u32 intsts;
  103. BUG_ON(base == 0);
  104. //IRQMask(msdc_irq_line[id]);
  105. DisableIRQ();
  106. #if defined(MMC_MSDC_DRV_CTP) && defined(FEATURE_MTH)
  107. mth_get_gic_pending_reg();
  108. #endif
  109. intsts = MSDC_READ32(MSDC_INT);
  110. msdc_irq_sts[id] |= intsts;
  111. if (intsts & MSDC_INT_CDSC) {
  112. /* card detection */
  113. in_irq++;
  114. MSG(INF, "in_irq(%d) intsts(0x%x)\n",in_irq, intsts);
  115. MSG(INF, "[SD%d] Card %s\n", id, msdc_card_avail(host) ? "Inserted" : "Removed");
  116. }
  117. if (intsts & MSDC_INT_SDIOIRQ) {
  118. /* sdio bus interrupt */
  119. MSG(INT, "[SD%d] SDIO interrupt <===\n", id);
  120. /* Note. msdc detects logical-low of dat1 to trigger sdio interrupt.
  121. * It will be triggered and should be _IGNORED_ since DAT1 of
  122. * SDIO/MMC/SD/SDXC card is pulled low when it's inserted into the slot.
  123. */
  124. #if defined(FEATURE_MMC_SDIO)
  125. if (sdio_irq_handler[id]) {
  126. sdio_irq_handler[id]();
  127. /* clear it since it's already handled */
  128. msdc_irq_sts[id] &= ~MSDC_INT_SDIOIRQ;
  129. }
  130. #endif
  131. }
  132. if (intsts & (MSDC_INT_CMDRDY|MSDC_INT_CMDTMO|MSDC_INT_RSPCRCERR)) {
  133. /* command done */
  134. }
  135. if (intsts & (MSDC_INT_ACMDRDY|MSDC_INT_ACMDTMO|MSDC_INT_ACMDCRCERR)) {
  136. /* auto command done */
  137. }
  138. if (intsts & MSDC_INT_ACMD19_DONE) {
  139. /* auto command 10 done */
  140. }
  141. if (intsts & MSDC_INT_XFER_COMPL) {
  142. /* data transfer done */
  143. }
  144. if (intsts & (MSDC_INT_DATCRCERR|MSDC_INT_DATTMO)) {
  145. /* data error */
  146. }
  147. if (intsts & MSDC_INT_DXFER_DONE) {
  148. /* dma transfer done */
  149. }
  150. if (intsts & MSDC_INT_DMAQ_EMPTY) {
  151. /* DMA queue empty */
  152. }
  153. if (intsts & MSDC_INT_CSTA) {
  154. /* CSTA available */
  155. }
  156. if (intsts & MSDC_INT_MMCIRQ) {
  157. /* MMCIRQ available */
  158. }
  159. MSDC_WRITE32(MSDC_INT, intsts); /* clear interrupts */
  160. //IRQUnmask(msdc_irq_line[id]);
  161. EnableIRQ();
  162. }
  163. DECLARE_MSDC_IRQ_HANDLER(0);
  164. DECLARE_MSDC_IRQ_HANDLER(1);
  165. DECLARE_MSDC_IRQ_HANDLER(2);
  166. DECLARE_MSDC_IRQ_HANDLER(3);
  167. static irq_handler_t isr[] = {
  168. msdc_irq_handler_0,
  169. msdc_irq_handler_1,
  170. msdc_irq_handler_2,
  171. msdc_irq_handler_3
  172. };
  173. #endif
  174. void msdc_irq_init(struct mmc_host *host)
  175. {
  176. #if defined(MMC_MSDC_DRV_LK)
  177. msdc_intr_mask(host,0xffffffff);
  178. mt_irq_set_sens(MT_MSDC0_IRQ_ID, MT65xx_LEVEL_SENSITIVE);
  179. mt_irq_set_polarity(MT_MSDC0_IRQ_ID, MT65xx_POLARITY_LOW);
  180. event_init(&msdc_int_event,false,EVENT_FLAG_AUTOUNSIGNAL);
  181. mt_irq_unmask(MT_MSDC0_IRQ_ID);
  182. #endif
  183. #if defined(MSDC_USE_IRQ)
  184. //For CTP only
  185. msdc_irq_sts[host->id] = 0;
  186. #if defined(FEATURE_MMC_SDIO)
  187. sdio_irq_handler[host->id] = NULL;
  188. #endif
  189. REGISTER_MSDC_IRQ_HANDLER(host->id, isr[host->id], host);
  190. #endif
  191. }
  192. void msdc_irq_deinit(struct mmc_host *host)
  193. {
  194. #if defined(MSDC_USE_IRQ)
  195. //UNREGISTER_MSDC_IRQ_HANDLER(host->id); //Light: Comment it out to solve build error in CTP
  196. #endif
  197. }
  198. extern u32 mth_get_gic_pending_reg(u32 user); //Light temp
  199. #if defined(MMC_MSDC_DRV_LK)
  200. u32 msdc_lk_intr_wait(struct mmc_host *host, u32 intrs)
  201. {
  202. u32 base = host->base;
  203. u32 sts;
  204. #if defined(FPGA_PLATFORM)
  205. u32 tmo = 0xFFFFFFFF;
  206. //SW timeout may occur on FPGA if request size is large, e.g., LK read kernel
  207. #else
  208. u32 tmo = 0xFFFF;
  209. #endif
  210. int ret = 0;
  211. MSG(INT, "[msdc_lk_intr_wait]\n");
  212. /* warning that interrupts are not enabled */
  213. WARN_ON((MSDC_READ32(MSDC_INTEN) & intrs) != intrs);
  214. ret = event_wait_timeout(&msdc_int_event, tmo);
  215. if (ret != 0) {
  216. msdc_pr_err("[%s]: failed to get event\n", __func__);
  217. } else {
  218. MSG(INT, "[%s]: get event\n", __func__);
  219. }
  220. sts = g_int_status;
  221. g_int_status = 0;
  222. MSG(INT, "[SD%d] INT(0x%x)\n", host->id, sts);
  223. if (~intrs & sts) {
  224. MSG(WRN, "[SD%d]<CHECKME> Unexpected INT(0x%x)\n",
  225. host->id, ~intrs & sts);
  226. }
  227. return sts;
  228. }
  229. #endif
  230. u32 msdc_intr_wait(struct mmc_host *host, u32 intrs)
  231. {
  232. u32 base = host->base;
  233. u32 sts;
  234. /* warning that interrupts are not enabled */
  235. WARN_ON((MSDC_READ32(MSDC_INTEN) & intrs) != intrs);
  236. #if defined(MSDC_USE_IRQ)
  237. //For CTP only
  238. while (1) {
  239. DisableIRQ();
  240. if (msdc_irq_sts[host->id] & intrs) {
  241. sts = msdc_irq_sts[host->id];
  242. msdc_irq_sts[host->id] &= ~intrs;
  243. EnableIRQ();
  244. break;
  245. }
  246. EnableIRQ();
  247. }
  248. #else
  249. {
  250. u32 tmo; //set tmo=0 to choose infinite wait
  251. if (host->cur_bus_clk > 1000000)
  252. tmo = 1000000;
  253. else
  254. tmo = 5000000;
  255. WAIT_COND( ((sts = MSDC_READ32(MSDC_INT)) & intrs), tmo, tmo);
  256. if (tmo == 0) {
  257. msdc_pr_err("[SD%d] Wait INT timeout\n", host->id);
  258. MSDC_RESET();
  259. }
  260. }
  261. MSDC_WRITE32(MSDC_INT, (sts & intrs));
  262. #endif
  263. MSG(INT, "[SD%d] INT(0x%x)\n", host->id, sts);
  264. if (~intrs & sts) {
  265. MSG(WRN, "[SD%d]<CHECKME> Unexpected INT(0x%x)\n",
  266. host->id, ~intrs & sts);
  267. }
  268. #if defined(FEATURE_MMC_SDIO)
  269. if (sts & MSDC_INT_SDIOIRQ) {
  270. #if (0 == MSDC_SLT_MASK_LOG)
  271. msdc_pr_info("(%s)INT status:0x%x\n", __func__, sts);
  272. #endif
  273. //if ( (host->id == 2) || (host->id == 3) ) {
  274. //mmc_sdio_proc_pending_irqs(host->card);
  275. //isPendingIRQ++;
  276. //}
  277. }
  278. #endif
  279. return sts;
  280. }