uart.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  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 "typedefs.h"
  38. #include "platform.h"
  39. #include "mt_uart.h"
  40. #include "meta.h"
  41. #include <gpio.h>
  42. #define Delay_Count 324675
  43. #define UART_BASE(uart) (uart)
  44. #define UART_RBR(uart) (UART_BASE(uart)+0x0) /* Read only */
  45. #define UART_THR(uart) (UART_BASE(uart)+0x0) /* Write only */
  46. #define UART_IER(uart) (UART_BASE(uart)+0x4)
  47. #define UART_IIR(uart) (UART_BASE(uart)+0x8) /* Read only */
  48. #define UART_FCR(uart) (UART_BASE(uart)+0x8) /* Write only */
  49. #define UART_LCR(uart) (UART_BASE(uart)+0xc)
  50. #define UART_MCR(uart) (UART_BASE(uart)+0x10)
  51. #define UART_LSR(uart) (UART_BASE(uart)+0x14)
  52. #define UART_MSR(uart) (UART_BASE(uart)+0x18)
  53. #define UART_SCR(uart) (UART_BASE(uart)+0x1c)
  54. #define UART_DLL(uart) (UART_BASE(uart)+0x0)
  55. #define UART_DLH(uart) (UART_BASE(uart)+0x4)
  56. #define UART_EFR(uart) (UART_BASE(uart)+0x8)
  57. #define UART_XON1(uart) (UART_BASE(uart)+0x10)
  58. #define UART_XON2(uart) (UART_BASE(uart)+0x14)
  59. #define UART_XOFF1(uart) (UART_BASE(uart)+0x18)
  60. #define UART_XOFF2(uart) (UART_BASE(uart)+0x1c)
  61. #define UART_AUTOBAUD_EN(uart) (UART_BASE(uart)+0x20)
  62. #define UART_HIGHSPEED(uart) (UART_BASE(uart)+0x24)
  63. #define UART_SAMPLE_COUNT(uart) (UART_BASE(uart)+0x28)
  64. #define UART_SAMPLE_POINT(uart) (UART_BASE(uart)+0x2c)
  65. #define UART_AUTOBAUD_REG(uart) (UART_BASE(uart)+0x30)
  66. #define UART_RATE_FIX_AD(uart) (UART_BASE(uart)+0x34)
  67. #define UART_AUTOBAUD_SAMPLE(uart) (UART_BASE(uart)+0x38)
  68. #define UART_GUARD(uart) (UART_BASE(uart)+0x3c)
  69. #define UART_ESCAPE_DAT(uart) (UART_BASE(uart)+0x40)
  70. #define UART_ESCAPE_EN(uart) (UART_BASE(uart)+0x44)
  71. #define UART_SLEEP_EN(uart) (UART_BASE(uart)+0x48)
  72. #define UART_VFIFO_EN(uart) (UART_BASE(uart)+0x4c)
  73. #define UART_RXTRI_AD(uart) (UART_BASE(uart)+0x50)
  74. #define UART_SET_BITS(BS,REG) ((*(volatile U32*)(REG)) |= (U32)(BS))
  75. #define UART_CLR_BITS(BS,REG) ((*(volatile U32*)(REG)) &= ~((U32)(BS)))
  76. #define UART_WRITE16(VAL, REG) DRV_WriteReg(REG,VAL)
  77. #define UART_READ32(REG) DRV_Reg32(REG)
  78. #define UART_WRITE32(VAL, REG) DRV_WriteReg32(REG,VAL)
  79. #if CFG_FPGA_PLATFORM
  80. volatile unsigned int g_uart = UART1;
  81. #define UART_SRC_CLK CFG_FPGA_UART_CLOCK
  82. #else
  83. volatile unsigned int g_uart = UART1;
  84. #define UART_SRC_CLK CFG_EVB_UART_CLOCK
  85. #endif
  86. void serial_setbrg (U32 uartclk, U32 baudrate)
  87. {
  88. #if (CFG_FPGA_PLATFORM)
  89. #define MAX_SAMPLE_COUNT 256
  90. U16 tmp;
  91. U32 divisor;
  92. U32 sample_data;
  93. U32 sample_count;
  94. U32 sample_point;
  95. // Setup N81,(UART_WLS_8 | UART_NONE_PARITY | UART_1_STOP) = 0x03
  96. UART_WRITE32(0x0003, UART_LCR(g_uart));
  97. /*
  98. * NoteXXX: Below is the sample code to set UART baud rate.
  99. * I assume that when system is reset, the UART clock rate is 26MHz
  100. * and baud rate is 115200.
  101. * use UART1_HIGHSPEED = 0x3 can get more sample count to get better UART sample rate
  102. * based on baud_rate = uart clock frequency / (sampe_count * divisor)
  103. * divisor = (DLH+DLL)
  104. */
  105. // In order to get better UART sample rate, set UART1_HIGHSPEED = 0x3.
  106. // And we can calculate sample count for reducing effect of UART sample rate variation
  107. UART_WRITE32(0x0003, UART_HIGHSPEED(g_uart));
  108. // calculate sample_data = sample_count*divisor
  109. // round off the result for approximating to the real baudrate
  110. sample_data = (uartclk+(baudrate/2))/baudrate;
  111. // calculate divisor
  112. divisor = (sample_data+(MAX_SAMPLE_COUNT-1))/MAX_SAMPLE_COUNT;
  113. // calculate sample count
  114. sample_count = sample_data/divisor;
  115. // calculate sample point (count from 0)
  116. sample_point = (sample_count-1)/2;
  117. // set sample count (count from 0)
  118. UART_WRITE32((sample_count-1), UART_SAMPLE_COUNT(g_uart));
  119. // set sample point
  120. UART_WRITE32(sample_point, UART_SAMPLE_POINT(g_uart));
  121. tmp = UART_READ32(UART_LCR(g_uart)); /* DLAB start */
  122. UART_WRITE32((tmp | UART_LCR_DLAB), UART_LCR(g_uart));
  123. UART_WRITE32((divisor&0xFF), UART_DLL(g_uart));
  124. UART_WRITE32(((divisor>>8)&0xFF), UART_DLH(g_uart));
  125. UART_WRITE32(tmp, UART_LCR(g_uart));
  126. #else
  127. unsigned int byte;
  128. unsigned int highspeed;
  129. unsigned int quot, divisor, remainder;
  130. unsigned int ratefix;
  131. if (baudrate <= 115200 ) {
  132. highspeed = 0;
  133. quot = 16;
  134. } else {
  135. highspeed = 2;
  136. quot = 4;
  137. }
  138. /* Set divisor DLL and DLH */
  139. divisor = uartclk / (quot * baudrate);
  140. remainder = uartclk % (quot * baudrate);
  141. if (remainder >= (quot / 2) * baudrate)
  142. divisor += 1;
  143. UART_WRITE16(highspeed, UART_HIGHSPEED(g_uart));
  144. byte = UART_READ32(UART_LCR(g_uart)); /* DLAB start */
  145. UART_WRITE32((byte | UART_LCR_DLAB), UART_LCR(g_uart));
  146. UART_WRITE32((divisor & 0x00ff), UART_DLL(g_uart));
  147. UART_WRITE32(((divisor >> 8)&0x00ff), UART_DLH(g_uart));
  148. //UART_WRITE32(byte, UART_LCR(g_uart)); /* DLAB end */
  149. // Setup N81,(UART_WLS_8 | UART_NONE_PARITY | UART_1_STOP) = 0x03
  150. UART_WRITE32(0x0003, UART_LCR(g_uart));
  151. #endif
  152. }
  153. int serial_nonblock_getc(void)
  154. {
  155. return (int)UART_READ32(UART_RBR(g_uart));
  156. }
  157. void mtk_serial_set_current_uart(MT65XX_UART uart_base)
  158. {
  159. g_uart = uart_base;
  160. }
  161. void mtk_uart_init (U32 uartclk, U32 baudrate)
  162. {
  163. #if !CFG_FPGA_PLATFORM
  164. #ifdef GPIO_UART_UTXD0_PIN
  165. #ifdef GPIO_UART_UTXD0_PIN_M_UTXD
  166. mt_set_gpio_mode(GPIO_UART_UTXD0_PIN, GPIO_UART_UTXD0_PIN_M_UTXD);
  167. #endif
  168. mt_set_gpio_dir(GPIO_UART_UTXD0_PIN, GPIO_DIR_OUT);
  169. #endif
  170. #ifdef GPIO_UART_URXD0_PIN
  171. #ifdef GPIO_UART_URXD0_PIN_M_URXD
  172. mt_set_gpio_mode(GPIO_UART_URXD0_PIN, GPIO_UART_URXD0_PIN_M_URXD);
  173. #endif
  174. mt_set_gpio_dir(GPIO_UART_URXD0_PIN, GPIO_DIR_IN);
  175. mt_set_gpio_pull_enable(GPIO_UART_URXD0_PIN, GPIO_PULL_ENABLE);
  176. mt_set_gpio_pull_select(GPIO_UART_URXD0_PIN, GPIO_PULL_UP);
  177. #endif
  178. #ifdef GPIO_UART_UTXD1_PIN
  179. #ifdef GPIO_UART_UTXD1_PIN_M_UTXD
  180. mt_set_gpio_mode(GPIO_UART_UTXD1_PIN, GPIO_UART_UTXD1_PIN_M_UTXD);
  181. #endif
  182. mt_set_gpio_dir(GPIO_UART_UTXD1_PIN, GPIO_DIR_OUT);
  183. #endif
  184. #ifdef GPIO_UART_URXD1_PIN
  185. #ifdef GPIO_UART_URXD1_PIN_M_URXD
  186. mt_set_gpio_mode(GPIO_UART_URXD1_PIN, GPIO_UART_URXD1_PIN_M_URXD);
  187. #endif
  188. mt_set_gpio_dir(GPIO_UART_URXD1_PIN, GPIO_DIR_IN);
  189. mt_set_gpio_pull_enable(GPIO_UART_URXD1_PIN, GPIO_PULL_ENABLE);
  190. mt_set_gpio_pull_select(GPIO_UART_URXD1_PIN, GPIO_PULL_UP);
  191. #endif
  192. #ifdef GPIO_UART_UTXD2_PIN
  193. mt_set_gpio_mode(GPIO_UART_UTXD2_PIN, GPIO_UART_UTXD2_PIN_M_UTXD);
  194. mt_set_gpio_dir(GPIO_UART_UTXD2_PIN, GPIO_DIR_OUT);
  195. #endif
  196. #ifdef GPIO_UART_URXD2_PIN
  197. mt_set_gpio_mode(GPIO_UART_URXD2_PIN, GPIO_UART_URXD2_PIN_M_URXD);
  198. mt_set_gpio_dir(GPIO_UART_URXD2_PIN, GPIO_DIR_IN);
  199. mt_set_gpio_pull_enable(GPIO_UART_URXD2_PIN, GPIO_PULL_ENABLE);
  200. mt_set_gpio_pull_select(GPIO_UART_URXD2_PIN, GPIO_PULL_UP);
  201. #endif
  202. #ifdef GPIO_UART_UTXD3_PIN
  203. mt_set_gpio_mode(GPIO_UART_UTXD3_PIN, GPIO_UART_UTXD3_PIN_M_UTXD);
  204. mt_set_gpio_dir(GPIO_UART_UTXD3_PIN, GPIO_DIR_OUT);
  205. #endif
  206. #ifdef GPIO_UART_URXD3_PIN
  207. mt_set_gpio_mode(GPIO_UART_URXD3_PIN, GPIO_UART_URXD3_PIN_M_URXD);
  208. mt_set_gpio_dir(GPIO_UART_URXD3_PIN, GPIO_DIR_IN);
  209. mt_set_gpio_pull_enable(GPIO_UART_URXD3_PIN, GPIO_PULL_ENABLE);
  210. mt_set_gpio_pull_select(GPIO_UART_URXD3_PIN, GPIO_PULL_UP);
  211. #endif
  212. #endif
  213. /* uartclk != 0, means use custom bus clock; uartclk == 0, means use defaul bus clk */
  214. if(0 == uartclk){ // default bus clk
  215. uartclk = UART_SRC_CLK;
  216. }
  217. #if (CFG_OUTPUT_PL_LOG_TO_UART1 && !(defined(HW_INIT_ONLY) || defined(SLT) || defined(DUMMY_AP) || defined(TINY)))
  218. mtk_serial_set_current_uart(UART2);
  219. UART_SET_BITS(UART_FCR_FIFO_INIT, UART_FCR(g_uart)); /* clear fifo */
  220. UART_WRITE16(UART_NONE_PARITY | UART_WLS_8 | UART_1_STOP, UART_LCR(g_uart));
  221. serial_setbrg(uartclk, CFG_LOG_BAUDRATE);
  222. /* set GPIO for UART1 */
  223. #ifdef GPIO_UART_UTXD1_PIN
  224. mt_set_gpio_mode(GPIO_UART_UTXD1_PIN, GPIO_UART_URXD1_PIN_M_URXD);
  225. mt_set_gpio_dir(GPIO_UART_UTXD1_PIN, GPIO_DIR_OUT);
  226. #endif
  227. #ifdef GPIO_UART_URXD1_PIN
  228. mt_set_gpio_mode(GPIO_UART_URXD1_PIN, GPIO_UART_URXD1_PIN_M_URXD);
  229. mt_set_gpio_dir(GPIO_UART_URXD1_PIN, GPIO_DIR_IN);
  230. mt_set_gpio_pull_enable(GPIO_UART_URXD1_PIN, GPIO_PULL_ENABLE);
  231. mt_set_gpio_pull_select(GPIO_UART_URXD1_PIN, GPIO_PULL_UP);
  232. #endif
  233. #endif /* #if CFG_OUTPUT_PL_LOG_TO_UART1 */
  234. // init UART2 for backup log port
  235. mtk_serial_set_current_uart(UART2);
  236. UART_SET_BITS(UART_FCR_FIFO_INIT, UART_FCR(g_uart)); /* clear fifo */
  237. UART_WRITE16(UART_NONE_PARITY | UART_WLS_8 | UART_1_STOP, UART_LCR(g_uart));
  238. serial_setbrg(uartclk, CFG_LOG_BAUDRATE);
  239. mtk_serial_set_current_uart(CFG_UART_META);
  240. UART_SET_BITS(UART_FCR_FIFO_INIT, UART_FCR(g_uart)); /* clear fifo */
  241. UART_WRITE16(UART_NONE_PARITY | UART_WLS_8 | UART_1_STOP, UART_LCR(g_uart));
  242. serial_setbrg(uartclk, CFG_META_BAUDRATE);
  243. mtk_serial_set_current_uart(CFG_UART_LOG);
  244. UART_SET_BITS(UART_FCR_FIFO_INIT, UART_FCR(g_uart)); /* clear fifo */
  245. UART_WRITE16(UART_NONE_PARITY | UART_WLS_8 | UART_1_STOP, UART_LCR(g_uart));
  246. serial_setbrg(uartclk, baudrate);
  247. }
  248. void PutUARTByte (const char c)
  249. {
  250. while (!(UART_READ32 (UART_LSR(g_uart)) & UART_LSR_THRE))
  251. {
  252. }
  253. if (c == '\n')
  254. UART_WRITE32 ((unsigned int) '\r', UART_THR(g_uart));
  255. UART_WRITE32 ((unsigned int) c, UART_THR(g_uart));
  256. }
  257. #if (CFG_OUTPUT_PL_LOG_TO_UART1 && !(defined(HW_INIT_ONLY) || defined(SLT) || defined(DUMMY_AP) || defined(TINY)))
  258. void PutUART1_Byte(const char c)
  259. {
  260. while(!(UART_READ32 (UART_LSR(UART2)) & UART_LSR_THRE))
  261. {
  262. }
  263. if (c == '\n')
  264. UART_WRITE32((unsigned int) '\r', UART_THR(UART2));
  265. UART_WRITE32((unsigned int) c, UART_THR(UART2));
  266. }
  267. #endif
  268. int GetUARTBytes(u8 *buf, u32 size, u32 tmo_ms)
  269. {
  270. u32 LSR;
  271. int tmo_en = (tmo_ms) ? 1 : 0;
  272. ulong start_time = get_timer(0);
  273. while (size) {
  274. if (tmo_en && (get_timer(start_time) > tmo_ms))
  275. break;
  276. /* kick watchdog to avoid cpu reset */
  277. if (!tmo_en)
  278. platform_wdt_kick();
  279. LSR = UART_READ32(UART_LSR(g_uart));
  280. if (LSR & UART_LSR_DR) {
  281. *buf++ = (u8)UART_READ32(UART_RBR(g_uart));
  282. size--;
  283. }
  284. }
  285. return (0 == size) ? 0 : -1;
  286. }