[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/driver/devdrv/uart/src/uart.c b/mcu/driver/devdrv/uart/src/uart.c
new file mode 100644
index 0000000..a04bbf0
--- /dev/null
+++ b/mcu/driver/devdrv/uart/src/uart.c
@@ -0,0 +1,4149 @@
+/*****************************************************************************
+* Copyright Statement:
+* --------------------
+* This software is protected by Copyright and the information contained
+* herein is confidential. The software may not be copied and the information
+* contained herein may not be used or disclosed except with the written
+* permission of MediaTek Inc. (C) 2012
+*
+* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+*
+* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*******************************************************************************
+ * Filename:
+ * ---------
+ * uart.c
+ *
+ * Project:
+ * --------
+ * TATAKA
+ *
+ * Description:
+ * ------------
+ * This Module defines the uart1 driver and the adaption layer
+ * between driver and TATAKA protocol.
+ * Author:
+ * -------
+ * -------
+ * -------
+ * -------
+ *
+ * ==========================================================================
+ * $Log$
+ *
+ * 07 02 2019 yao.xue
+ * [MOLY00418070] ISR Centralization : remove UART & WDT & Logseq IRQSensitivity/IRQ_Register_LISR
+ * ISR Centralization : remove UART & WDT & Logseq IRQSensitivity/IRQ_Register_LISR
+ *
+ * 04 11 2019 yao.xue
+ * [MOLY00397471] [VMOLY]Use API ust_us_duration take place ust_get_duration
+ * modify API ust_us_duration takeplace ust_get_duration in uart/slt code
+ *
+ * 02 15 2019 panu.peisa
+ * [MOLY00384803] [Gen97][SystemService][Change Request] KAL Refactoring Phase-in
+ *
+ * Added changes to swrd part.
+ *
+ * 10 29 2018 yao.xue
+ * [MOLY00360949] [SWRD] DRVTEST maintain
+ * Fix DRVTEST build pass in SWRD
+ *
+ * 03 13 2018 shenghui.shi
+ * [MOLY00309657] UMOLYE driver warning fix
+ * update UART driver
+ *
+ * 11 21 2017 shenghui.shi
+ * [MOLY00290848] [UMOLYA] Usage of INT_SW_SecVersion
+ * removed no used API INT_SW_SecVersion
+ *
+ * 11 21 2017 shenghui.shi
+ * [MOLY00290848] [UMOLYA] Usage of INT_SW_SecVersion
+ * remove INT_SW_SecVersion API from UART driver. This API is not used in 93/95
+ *
+ *
+ * 11 07 2017 shenghui.shi
+ * [MOLY00288093] update UART driver to remove no needed project option
+ * .
+ *
+ * 11 07 2017 shenghui.shi
+ * [MOLY00288093] update UART driver to remove no needed project option
+ * update uart driver to remove no needed files
+ *
+ * 11 03 2017 shenghui.shi
+ * [MOLY00287577] UMOLYA HISR coding change for UART part
+ * .
+ *
+ * 10 24 2017 yao.xue
+ * [MOLY00284920] [Cervino] UART driver porting for Cervino.
+ *
+ * 09 15 2017 da.li
+ * [MOLY00270315] [System Service][KIR] make ex robust before ex steplog work
+ * Replace INT_QueryExceptionStatus with #include <ex_public.h>.
+ *
+ * 09 08 2017 da.li
+ * [MOLY00274163] [Sylvia] Driver porting
+ * Build warning(error) fix.
+ *
+ * 09 07 2017 da.li
+ * [MOLY00274163] [Sylvia] Driver porting
+ * UART driver porting for Sylvia.
+ *
+ * 07 13 2017 shenghui.shi
+ * [MOLY00263518] Update UART driver test code
+ * fix build error
+ *
+ * 07 13 2017 shenghui.shi
+ * [MOLY00263518] Update UART driver test code
+ * update UART driver
+ *
+ * 06 12 2017 flamingo.wang
+ * [MOLY00244966] [ZION][IDC] add chip define of MT6739 in idc driver
+ * Add MT6739 define
+ *
+ * 06 12 2017 flamingo.wang
+ * [MOLY00254599] Normal mode UARTDriver���ܳ�Log
+ * norm uart mode print log fix
+ *
+ * 04 24 2017 shenghui.shi
+ * [MOLY00243727] update UART PDN feature
+ * update UART pdn feature,to void system could not entry DCM issue.
+ *
+ * 03 07 2017 shenghui.shi
+ * [MOLY00233604] UART print driver update for baudrate
+ * update UART driver for uart include.
+ *
+ * 02 07 2017 shenghui.shi
+ * [MOLY00228102] [Bianco Bring-up]UMOLYA uart driver update
+ * update UART dbgprint driver
+ *
+ * 09 22 2016 yuke.ren
+ * [MOLY00204183] Fix UART HDMA usage
+ * set RX SEL for RX channel
+ *
+ *
+ * 09 20 2016 yuke.ren
+ * [MOLY00204183] Fix UART HDMA usage
+ * .
+ *
+ * 07 15 2016 shenghui.shi
+ * [MOLY00171995] update uart driver for 93
+ * update UART cloclk to 26MHz (after GEN93 Bitfile 2016071380)
+ *
+ * 05 19 2016 shenghui.shi
+ * [MOLY00175766] NVRAM update for UMOLYA
+ * modify UART 26MHz macro to 20.8MHz to match real clock freq.
+ *
+ * 03 30 2016 shenghui.shi
+ * [MOLY00171995] update uart driver for 93
+ * update uart driver for 93.
+ *
+ * 01 27 2016 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * use sst_get_exception_count() to replace INT_Exception_Enter.
+ *
+ * 01 22 2016 shenghui.shi
+ * [MOLY00162415] [Coverity inspect] driver coding issue fix
+ * [coverity inspect]driver coding issue fix
+ *
+ * 01 15 2016 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * Merging
+ *
+ * update UART debug driver to use HMDA mode.
+ *
+ * 10 13 2015 shenghui.shi
+ * [MOLY00145129] fixed EWS build error which caused by UART IRQ naming exchange on ELBRUS
+ * .
+ *
+ * 10 13 2015 shenghui.shi
+ * [MOLY00145129] fixed EWS build error which caused by UART IRQ naming exchange on ELBRUS
+ * .
+ *
+ * 08 17 2015 shenghui.shi
+ * [MOLY00137551] [MOLY_LINUX_DOWNLOADBIN notify] ELBRUS_FPGA(BASIC) build error
+ * <saved by Perforce>
+ *
+ * 06 18 2015 da.li
+ * [MOLY00121478] [UMOLY][JADE]UART driver compile error fix
+ * Compile error fix on JADE(MT6755).
+ *
+ * 06 15 2015 da.li
+ * [MOLY00121478] [UMOLY][JADE]UART driver compile error fix
+ * UART driver compile error fix on MT6755(JADE).
+ *
+ * 05 11 2015 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * pdn clear UART/GDMA clock before use UART driver
+ *
+ * 04 02 2015 tero.jarkko
+ * [MOLY00094214] [System Service][MOLY Kernel Internal Request]Modify driver HISR to individual HISR
+ *
+ * 03 25 2015 shenghui.shi
+ * [MOLY00104131] [UMOLY][Klocwork] Fix potential code defect in uart driver
+ * .
+ *
+ * 02 11 2015 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * fix ews build error
+ *
+ * 02 11 2015 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * 1. add sw escape feature to UMOLY
+ * 2. phase out VFIFO hw code in devdrv_common.c
+ *
+ * 12 18 2014 shenghui.shi
+ * [MOLY00081492] [UART] update uart driver
+ * .
+ *
+ * 11 17 2014 shenghui.shi
+ * [MOLY00084720] update UMOLY HDMA HISR
+ * move GDMA2 to DEVDRV share HISR
+ *
+ * 11 17 2014 shenghui.shi
+ * [MOLY00084720] update UMOLY HDMA HISR
+ * .
+ *
+ * 05 13 2014 shenghui.shi
+ * [MOLY00062001] TK6291 UART Fix EWS error
+ * .
+ *
+ * 05 13 2014 shenghui.shi
+ * [MOLY00065467] [TK6291] update UART driver for TK6291
+ * update UART clock to 26MHZ for TK6291
+ *
+ * 04 08 2014 shenghui.shi
+ * [MOLY00062001] TK6291 UART Fix EWS error
+ * .
+ *
+ * 04 08 2014 shenghui.shi
+ * [MOLY00062003] [MakeFile] [Modify Common Makefile] Disable __CUST_NEW__
+ * update a patch for no __FPGA__ macro
+ *
+ * 04 08 2014 shenghui.shi
+ * [MOLY00062001] TK6291 UART Fix EWS error
+ * update uart driver to fix ews error
+ *
+ * 01 10 2014 shenghui.shi
+ * [MOLY00043671] [klocwork_95][LTE] in uart.c, line 428
+ * .
+ *
+ * 01 10 2014 shenghui.shi
+ * [MOLY00043674] [klocwork_95][LTE] in uart.c, line 2247
+ * update uart driver to fix uninitial risk.
+ *
+ * 01 09 2014 shenghui.shi
+ * [MOLY00052974] MT6595 UART driver merge to Trunk
+ * MT6595 uart driver merge to MOLY TRUNK
+ *
+ * 12 10 2013 shenghui.shi
+ * [MOLY00049628] MT6595 UART merge to Trunk
+ * .
+ *
+ * 10 29 2013 shenghui.shi
+ * [MOLY00044172] uart all memory dump
+ * .
+ *
+ * 10 02 2013 vend_brandon-hy.lin
+ * [MOLY00040071] [MT6290] SRCLKEN cannot be toggled when LTE sleep feature is enable
+ * Fix SRCLEN_OUT0 cannot be toggle when LTE sleep feature is enable.
+ * Solution: enlarge transmission time of dummy fdma patch.
+ *
+ * 09 13 2013 shenghui.shi
+ * [MOLY00035078] [MT6290][PDN] Enable GDMA & HDMA related module PDN support
+ * move uart pdn_clr from dcl_tty.c to uart.c
+ *
+ * 09 03 2013 shenghui.shi
+ * [MOLY00036272] open UART SlEEP_EN feature
+ * open uart SLEEP_EN feature when MTK_SLEEP_EN enable.
+ *
+ * 08 29 2013 shenghui.shi
+ * [MOLY00035659] [MOLY] [MT6290][SLT] SLT Tool Communication API for driver test
+ * .
+ *
+ * 08 29 2013 shenghui.shi
+ * [MOLY00035768] fix uart build warnning
+ * .
+ *
+ * 08 26 2013 shenghui.shi
+ * [MOLY00035078] [MT6290][PDN] Enable GDMA & HDMA related module PDN support
+ * add uart PDN feature
+ *
+ * 08 14 2013 shenghui.shi
+ * [MOLY00033671] update exception uart driver for void use qbm_dest_q
+ * .
+ *
+ * 08 12 2013 shenghui.shi
+ * [MOLY00033396] update dummy_fdma() patch
+ * .
+ *
+ * 08 02 2013 shenghui.shi
+ * [MOLY00032203] update dummy_fdma for GDMA sleep ack issue
+ * update dummy_fdma() for GDMA sleep ack issue
+ * 08/02/2013 shenghui.shi
+ * [MOLY00032203]update dummy_fdma() for GDMA sleep ack issue
+ *
+ * 07 29 2013 shenghui.shi
+ * [MOLY00030921] [MT6290]Low Power Feature patch back from CBr
+ * merge UART dummy_fdma() patch from Branch to Trunk.
+ *
+ * 04 24 2013 shenghui.shi
+ * [MOLY00020330] MT6290 UART driver update
+ * uart driver update: modify the uart_hdma_isr().
+ *
+ * 04 03 2013 shenghui.shi
+ * [MOLY00012769] IOMUX driver
+ * update UART driver: add ASIC version for UART_CLOCK
+ *
+ * 02 04 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * rename: 7208 -> 6290
+ *
+ * 01 29 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Integration change.
+ *
+ * 01 22 2013 ansel.liao
+ * [MOLY00006575] USIM driver modification
+ * *: remove an en-Q situation which won't occur
+ *
+ * 01 15 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * *: recover U_GetUARTByte function, WCP3/SE7/SD9 Chuanbo need this function to verify MSDC driver (port from MT6280)
+ *
+ * 01 14 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Integration change.
+ *
+ * 01 04 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * *: clear rx data timeout counter periodly to prevent XON/XOFF of sw flow control to destroy rx data timeout mechanism
+ *
+ * 01 02 2013 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * *: does not destroy rx queue when head of queue is null
+ *
+ * 12 26 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Integration change.
+ *
+ * 12 25 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * *: free all TGPD/RGPD when TTY_CMD_EXCEPTION_CLEAR_CHANNEL is get
+ *
+ * 12 19 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Integration change.
+ *
+ * 12 06 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Integration change.
+ *
+ * 11 30 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * add dbg_flush and corresponding drvtest
+ *
+ * 11 27 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * update stress test
+ *
+ * 11 25 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * update UART stress test
+ *
+ * 11 23 2012 ansel.liao
+ * [MOLY00006575] Add UART/HDMA Driver
+ * Add UART/HDMA driver
+ ****************************************************************************/
+#include "drv_features.h"
+#include "kal_general_types.h"
+#include "kal_public_api.h"
+#ifdef KTEST_UART_TRACES
+#include "kal_hrt_api.h"
+#endif
+#include "kal_public_defs.h"
+#include "hisr_config.h"
+#include "stack_msgs.h"
+#include "stack_ltlcom.h" /* Task message communiction */
+#include "drv_comm.h"
+#include "reg_base.h"
+#include "uart_hw.h"
+#include "bmd.h"
+#include "intrCtrl.h"
+#include "drvpdn.h"
+#include "stack_config.h" /*MOD_UART1_HISR,MOD_UART2_HISR*/
+#include "uart_sw.h"
+#include "uart_internal.h"
+#include "dcl.h"
+#include "uart_gpd.h"
+#include "drv_msgid.h"
+#include "devdrv_ls.h"
+#include "pll.h"
+#include "drv_gdma.h"
+// for HDMA
+#include "qmu_bm.h"
+#include "qmu_bm_size.h"
+#include "qmu_bm_util.h"
+#include "init.h"
+#include "cpu.h"
+#include "cache_sw.h"
+#include <ex_item.h>
+#include <ex_public.h>
+#if defined(__HMU_ENABLE__)
+#include "hmu.h"
+#include "hmu_conf_data.h"
+#endif
+#include "us_timer.h"
+
+#if !defined(DRV_UART_OFF)
+
+#define UART_CLOCK (26*1000000)
+
+#ifndef MD_IRQID_MDGDMA2
+#define MD_IRQID_MDGDMA2 PS_IRQID_MDGDMA2
+#endif
+
+// To enable or disable META Mode SW Escaping, defined this macro to enable it
+#define META_MODE_SW_ESCAPING
+#define UART_ESCAPE_CHAR 0x77
+#define UART_ECPT_MAX_TIMEOUT 5000 //5s
+
+kal_uint8 UART_handle;
+
+tty_excp_hif_state uart_ecpt_tx_state[MAX_UART_PORT_NUM] =
+{
+ HIF_STATE_NORMAL,
+ HIF_STATE_NORMAL,
+};
+UART_ecpt_timer_t uart_ecpt_timer[MAX_UART_PORT_NUM];
+UARTStruct UARTPort[MAX_UART_PORT_NUM];
+
+#ifdef DRV_DEBUG
+kal_uint8 uart_initialize[MAX_UART_PORT_NUM];
+#endif /*DRV_DEBUG*/
+
+#define DEBUG_PORT uart_port1 // Use UART1 as debug port
+#define DEBUG_BAUDRATE 115200
+kal_int32 init_log_fail_count = 0;
+kal_bool mutex_status = KAL_FALSE;
+kal_mutexid mutexid = 0;
+
+#if __LTE_ONLY__
+#define MCU_BOOT_SPEED 40040000
+#else
+//MCU booting speed 26M/baudrate(bits/second) = 260M/baudrate(bytes/second) = MCU tick/bytes
+#define MCU_BOOT_SPEED 260000000 //Currently all chips use 26M, 260M because of count [MCU ticks/byte]
+#endif
+
+kal_bool send_Txilm[MAX_UART_PORT_NUM] = {// change from kal_uint8 to kal_bool, avoid Warning 641: Converting enum 'kal_bool' to int"
+ KAL_FALSE,
+ KAL_FALSE,
+};
+
+kal_bool send_Rxilm[MAX_UART_PORT_NUM] = {// change from kal_uint8 to kal_bool, avoid Warning 641: Converting enum 'kal_bool' to int"
+ KAL_TRUE,
+ KAL_TRUE,
+};
+
+const VOID_FUNC UART_HISR[MAX_UART_PORT_NUM] =
+{
+ UART1_HISR,
+ UART2_HISR,
+};
+
+const kal_uint32 UART_BaseAddr[MAX_UART_PORT_NUM] =
+{
+ UART1_base,
+ UART2_base,
+};
+#ifdef __DMA_UART_VIRTUAL_FIFO__
+kal_bool UART_VFIFO_support[MAX_UART_PORT_NUM] =
+{
+ KAL_TRUE,
+ KAL_TRUE,
+};
+
+#else
+kal_bool UART_VFIFO_support[MAX_UART_PORT_NUM] =
+{
+ KAL_FALSE,
+ KAL_FALSE,
+};
+#endif/*__DMA_UART_VIRTUAL_FIFO__*/
+
+//Add for new internal func
+void UART2_TrxHandler(void);
+kal_uint8 UART_GetIRQCode(UART_PORT port);
+void uart_qbm_virt_to_phy(void** pp_gpd_head, void** pp_gpd_tail);
+void uart_qbm_phy_to_virt(void**pp_gpd_head, void**pp_gpd_tail);
+void UART_META_PutBytes(UART_PORT port, void * gpd_head, void * gpd_tail);
+kal_uint16 U_ExBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid);
+void UART_META_ExBytes(UART_PORT port, void * gpd_head, void * gpd_tail);
+
+
+
+kal_uint8 uart_escape_state=0;
+
+extern UartDriver_strcut* pUart_CMD_FUNC[];
+#if defined(DRV_DEBUG_BUFFER_DMA_MODE) && !defined(KTEST_UART_TRACES)
+kal_spinlockid print_buf_lock = 0;
+#endif
+//void dummy_fdma(kal_uint32 gdma_start);
+
+
+void UART_Calback(void *parameter);
+void U_ConfigEscape (UART_PORT port, kal_uint8 EscChar, kal_uint16 ESCGuardtime, module_type ownerid);
+void UART_TrxHandler(void *parameter);
+void UART_TxDMAHandler(void *parameter, kal_uint8 chk_done);
+/*UART Customization */
+extern const UART_customize_function_struct *UART_GetFunc(void);
+const UART_customize_function_struct *UartCustomFunc;
+const UART_rings_struct *UART_rings;
+kal_bool WaitForUARTTx[MAX_UART_PORT_NUM] = {KAL_FALSE};
+
+#define ASSERT_WAIT_LOOP 0xffffffff
+#define VFIFO_SWITCH_WAIT_LOOP 100000
+kal_uint16 DELAY_FOR_PUTBYTE = 300;
+
+// for HDMA
+void *uart_tgpd_head[3];
+void *uart_rgpd_head[3];
+void *uart_tgpd_tail[3];
+void *uart_rgpd_tail[3];
+
+void *uart_wait_tgpd_head[3];
+void *uart_wait_tgpd_tail[3];
+
+
+// for UART Exception mode
+kal_uint8 uart_ecpt_bps_buf[UART_ECPT_QBM_BPS_BUF_SZ];
+kal_bool uart_ecpt_init = KAL_FALSE;
+uart_bps_gpd_t uart_bps_gpd;
+
+
+#if defined(DRV_UART_MEMORY_TRACE)
+UART_DRV_DBG_STRUCT UART_DRV_DBG_INFO_DATA;
+/*uart_drv_dbg_trace(NAND_READ_START,drv_get_current_time(),0,0);*/
+void uart_drv_dbg_trace(kal_uint16 index, kal_uint32 time, kal_uint32 data1, kal_uint32 data2)
+{
+ kal_uint32 savedMask;
+ savedMask = SaveAndSetIRQMask();
+ {
+ UART_DRV_DBG_INFO_DATA.dbg_data[UART_DRV_DBG_INFO_DATA.dbg_data_idx&(MAX_UART_DRV_DBG_INFO_SIZE-1)].tag = index;
+ UART_DRV_DBG_INFO_DATA.dbg_data[UART_DRV_DBG_INFO_DATA.dbg_data_idx&(MAX_UART_DRV_DBG_INFO_SIZE-1)].time = time;
+ UART_DRV_DBG_INFO_DATA.dbg_data[UART_DRV_DBG_INFO_DATA.dbg_data_idx&(MAX_UART_DRV_DBG_INFO_SIZE-1)].data1 = data1;
+ UART_DRV_DBG_INFO_DATA.dbg_data[UART_DRV_DBG_INFO_DATA.dbg_data_idx&(MAX_UART_DRV_DBG_INFO_SIZE-1)].data2 = data2;
+ UART_DRV_DBG_INFO_DATA.dbg_data_idx++;
+ }
+ RestoreIRQMask(savedMask);
+}
+#endif //#if defined(DRV_UART_MEMORY_TRACE)
+
+
+
+void uart_customize_init(void)
+{
+ /* retreive the function table */
+ UartCustomFunc=UART_GetFunc();
+ /* use the entry in function table to retreive desired information */
+ UART_rings = UartCustomFunc->UART_Get_Data();
+
+}
+
+kal_bool UART_IsVfifoSetting(UART_PORT port, UART_TxRx_VFIFO_support vs)
+{
+#ifdef __DMA_UART_VIRTUAL_FIFO__
+ if(port >= MAX_UART_PORT_NUM)
+ return KAL_FALSE;
+ if(vs != NONE_VFIFO)
+ return UART_VFIFO_support[port];
+ else //NONE_VFIFO
+ return (kal_bool)!UART_VFIFO_support[port];
+#else
+ if(vs == NONE_VFIFO)
+ return KAL_TRUE;
+ else //NONE_VFIFO
+ return KAL_FALSE;
+#endif
+}
+
+/*check if chip can support auto escape*/
+kal_bool uart_support_autoescape(void)
+{
+ return KAL_TRUE;
+}
+
+void UART_sendilm(UART_PORT port, msg_type msgid) {}
+
+//Add for U_ClrRxBuffer and U_ClrTxBuffer, reduce code size
+void UART_Set_NormalFlowControl(UART_PORT port)
+{
+ if (UARTPort[port].DCB.flowControl == fc_none)
+ DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_HW_NORMALINTS);
+ else if (UARTPort[port].DCB.flowControl == fc_hw)
+ DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_HW_NORMALINTS);
+ else if (UARTPort[port].DCB.flowControl == fc_sw)
+ DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_SW_NORMALINTS);
+}
+
+void U_ClrRxBuffer(UART_PORT port, module_type ownerid) /*clear sw buffer*/
+{
+ kal_uint32 savedMask;
+
+ savedMask = SaveAndSetIRQMask();
+ BWrite_addr(UARTPort[port].Rx_Buffer) = 0;
+ BRead_addr(UARTPort[port].Rx_Buffer) = 0;
+
+// UART_Set_NormalFlowControl(port);
+
+ send_Rxilm[port] = KAL_TRUE;
+ RestoreIRQMask(savedMask);
+
+// HDMA procedure
+ uart_en_q_de_q_with_mutex(port, UART_RX, UART_DE_Q_ALL, NULL, NULL);
+// end of HDMA procedure
+
+}
+
+void U_ClrTxBuffer(UART_PORT port, module_type ownerid) /*clear sw buffer*/
+{
+
+ kal_uint32 savedMask;
+
+ savedMask = SaveAndSetIRQMask();
+
+ BWrite_addr(UARTPort[port].Tx_Buffer) = 0;
+ BRead_addr(UARTPort[port].Tx_Buffer) = 0;
+
+// UART_Set_NormalFlowControl(port);
+
+ send_Txilm[port] = KAL_TRUE;
+
+ RestoreIRQMask(savedMask);
+
+
+// HDMA procedure
+ uart_en_q_de_q_with_mutex(port, UART_TX, UART_DE_Q_ALL, NULL, NULL);
+// end of HDMA procedure
+}
+void UART_EnableTX(UART_PORT port, kal_bool enable)
+{
+ if (port < MAX_UART_PORT_NUM)
+ {
+ UARTPort[port].EnableTX= enable;
+ if(enable == KAL_TRUE){
+ EnableTxIntr(UART_BaseAddr[port]);
+ }else{
+ DisableTxIntr(UART_BaseAddr[port]);
+ }
+ }else{
+ ASSERT(0);
+ }
+}
+
+void UART_SleepOnTx_Enable(UART_PORT port, UART_SLEEP_ON_TX enable_flag) {}
+
+kal_uint16 U_GetBytesAvail(UART_PORT port)
+{
+ kal_uint16 real_count;
+
+ Buf_GetBytesAvail(&(UARTPort[port].Rx_Buffer),real_count);
+
+ return real_count;
+}
+
+kal_uint16 U_GetTxRoomLeft(UART_PORT port)
+{
+ kal_uint16 real_count;
+
+ Buf_GetRoomLeft(&(UARTPort[port].Tx_Buffer),real_count);
+ return real_count;
+}
+
+#ifndef __ROMSA_SUPPORT__ /* Note: for ROM code */
+
+#if defined(__MTK_INTERNAL__) && defined(__MTK_TARGET__)
+kal_uint16 DEVDRV_LS_INTERNCODE
+#else
+kal_uint16
+#endif
+U_GetTxISRRoomLeft(UART_PORT port)
+{
+ return 0;
+}
+
+#endif /* Note: for ROM code */
+
+
+/*
+* FUNCTION
+* GetUARTByte
+*
+* DESCRIPTION
+* This function is to read data from UART
+*
+* CALLS
+* This function is to receive data through UART
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* the data from UART
+*
+* GLOBALS AFFECTED
+* external_global
+*/
+kal_uint8 U_GetUARTByte(UART_PORT port)
+{
+ kal_uint8 data;
+ kal_uint8 U_GetUARTByteWithTimeOut(UART_PORT port, kal_uint8* ch, kal_uint32 timeout_value);//liming add statement
+ while(!U_GetUARTByteWithTimeOut(port, &data, 0xffffffff)); // for descrease code size (U_GetUARTByte &U_GetUARTByteTimeout)
+ return data;
+}
+
+
+/*
+* FUNCTION
+* GetUARTByte
+*
+* DESCRIPTION
+* This function is to read data from UART
+*
+* CALLS
+* This function is to receive data through UART
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* the data from UART
+*
+* GLOBALS AFFECTED
+* external_global
+*/
+kal_uint8 U_GetUARTByteWithTimeOut(UART_PORT port, kal_uint8* ch, kal_uint32 timeout_value)
+{
+ kal_uint8 res_byte = 0;
+ kal_uint8 data;
+
+ while(timeout_value != 0)
+ {
+ kal_uint16 LSR;
+ LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));
+ if (LSR & UART_LSR_DR)
+ {
+ data = (kal_uint8)DRV_UART_Reg(UART_RBR(UART_BaseAddr[port]));
+ res_byte = 1;
+ //only META port use old flow control escape character,
+ if( (kal_query_boot_mode()== FACTORY_BOOT && UARTPort[port].DCB.flowControl==fc_sw && UARTPort[port].ownerid==MOD_DHL_READER)||
+ (uart_support_autoescape()==KAL_FALSE&&UARTPort[port].DCB.flowControl==fc_sw))
+ {
+ if(uart_escape_state==0)
+ {
+ if(data==0x77)
+ uart_escape_state=0x77;
+ else
+ {
+ *ch = data;
+ break;
+ }
+ }
+ else if (uart_escape_state==0x77)
+ {
+ uart_escape_state=0x0;
+
+ if (data == 0x01)
+ {
+ *ch = UARTPort[port].DCB.xonChar;
+ break;
+ }
+ else if (data == 0x02)
+ {
+ *ch = UARTPort[port].DCB.xoffChar;
+ break;
+ }
+ else if (data == 0x03)
+ {
+ *ch = 0x77;
+ break;
+ }
+ }
+ }
+ else
+ {
+ *ch = data;
+ break;
+ }
+ }
+
+ --timeout_value;
+ }
+
+ return res_byte;
+}
+
+/*
+* FUNCTION
+* PutUARTByte
+*
+* DESCRIPTION
+* This function is to write data to UART
+*
+* CALLS
+* This function is to transmit data through UART
+*
+* PARAMETERS
+* None
+*
+* RETURNS
+* the data from UART
+*
+* GLOBALS AFFECTED
+* external_global
+*/
+void PutUARTRingBufferData(UART_PORT port) {}
+
+void UART_PutUARTByte_limited(UART_PORT port, kal_uint8 data)
+{
+ volatile kal_uint16 LSR;
+ kal_uint32 count = 0;
+
+ if(init_log_fail_count > 3)
+ {
+ DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data);
+ return;
+ }
+
+ while(1)
+ {
+ LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));
+ count++;
+ if ( LSR & UART_LSR_THRE )
+ {
+ DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data);
+ break;
+ }
+ else if(count > (MCU_BOOT_SPEED/DEBUG_BAUDRATE) )
+ {
+ DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data); //don't care the pending
+ init_log_fail_count++;
+ break;
+ }
+}
+}
+
+void U_PutUARTByte(UART_PORT port, kal_uint8 data) {
+ kal_uint16 LSR;
+
+ while(1)
+ {
+ LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));
+ if ( LSR & UART_LSR_THRE )
+ {
+ DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data);
+ break;
+ }
+ }
+}
+void PutUARTData(UART_PORT port, kal_uint8 escape_char, kal_uint8 data)
+{
+ if(port >= MAX_UART_PORT_NUM)
+ return;
+
+ //only META port use old flow control escape character,
+if((kal_query_boot_mode() == FACTORY_BOOT && UARTPort[port].DCB.flowControl == fc_sw && UARTPort[port].ownerid == MOD_DHL_READER)
+ || (uart_support_autoescape() == KAL_FALSE && UARTPort[port].DCB.flowControl == fc_sw))
+ {
+ if (data == UARTPort[port].DCB.xonChar)
+ {
+ pUart_CMD_FUNC[port]->PutUARTByte(port, escape_char);
+ pUart_CMD_FUNC[port]->PutUARTByte(port, 0x01);
+ }
+ else if (data == UARTPort[port].DCB.xoffChar)
+ {
+ pUart_CMD_FUNC[port]->PutUARTByte(port, escape_char);
+ pUart_CMD_FUNC[port]->PutUARTByte(port, 0x02);
+ }
+ else if (data == escape_char)
+ {
+ pUart_CMD_FUNC[port]->PutUARTByte(port, escape_char);
+ pUart_CMD_FUNC[port]->PutUARTByte(port, 0x03);
+ }
+ else
+ {
+ pUart_CMD_FUNC[port]->PutUARTByte(port, data);
+ }
+ }
+ else
+ {
+ pUart_CMD_FUNC[port]->PutUARTByte(port, data);
+ }
+}
+
+void PutUARTByteDelay(UART_PORT port, kal_uint8 data)
+{
+ kal_uint16 LSR;
+ kal_uint16 i;
+ if(port >= MAX_UART_PORT_NUM)
+ return;
+
+ while(1)
+ {
+ LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));
+
+ if( LSR & UART_LSR_THRE )
+ {
+ for(i = 0; i < DELAY_FOR_PUTBYTE; i++); //add delay...
+ DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]),(kal_uint16)data);
+ break;
+ }
+ }
+}
+
+void PutUARTDataDelay(UART_PORT port, kal_uint8 escape_char, kal_uint8 data)
+{
+ if(port >= MAX_UART_PORT_NUM)
+ return;
+
+ if( (kal_query_boot_mode()== FACTORY_BOOT && UARTPort[port].DCB.flowControl==fc_sw && UARTPort[port].ownerid==MOD_DHL_READER)||
+ (uart_support_autoescape()==KAL_FALSE))
+ {
+ if (data == UARTPort[port].DCB.xonChar)
+ {
+ PutUARTByteDelay(port, escape_char);
+ PutUARTByteDelay(port, 0x01);
+ }
+ else if (data == UARTPort[port].DCB.xoffChar)
+ {
+ PutUARTByteDelay(port, escape_char);
+ PutUARTByteDelay(port, 0x02);
+ }
+ else if (data == escape_char)
+ {
+ PutUARTByteDelay(port, escape_char);
+ PutUARTByteDelay(port, 0x03);
+ }
+ else
+ {
+ PutUARTByteDelay(port, data);
+ }
+ }
+ else
+ {
+ PutUARTByteDelay(port, data);
+ }
+}
+
+
+kal_uint16 U_ExBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid)
+{
+ kal_uint16 real_count= Length, index;
+ kal_uint16 data_count = 0;
+
+ if((kal_query_boot_mode() == FACTORY_BOOT && UARTPort[port].DCB.flowControl == fc_sw && UARTPort[port].ownerid == MOD_DHL_READER)
+ || (uart_support_autoescape() == KAL_FALSE && UARTPort[port].DCB.flowControl == fc_sw))
+ //if(0)
+ {
+ for(index = 0; (index < real_count) && (data_count < Length); index++)
+ {
+ // The following are for software flow control
+ if(uart_escape_state==0)
+ {
+ if(*(Buffaddr + index) == 0x77)
+ {
+ uart_escape_state=0x77;
+ } else
+ {
+ *(Buffaddr + data_count) = *(Buffaddr + index);
+ data_count++;
+ }
+
+ } else if(uart_escape_state == 0x77)
+ {
+ switch(*(Buffaddr + index))
+ {
+ case 0x01:
+ *(Buffaddr+data_count) = 0x11;//UARTPort[port].DCB.xonChar;
+ data_count++;
+ break;
+ case 0x02:
+ *(Buffaddr+data_count)= 0x13; //UARTPort[port].DCB.xoffChar;
+ data_count++;
+ break;
+ case 0x03:
+ *(Buffaddr + data_count) = 0x77;
+ data_count++;
+ break;
+ default:
+ break;
+
+ }
+ uart_escape_state=0x0;
+ }
+
+
+ }
+ }else{
+ for(index = 0; (index < real_count) && (data_count < Length); index++){
+ *(Buffaddr + data_count) = *(Buffaddr + index);
+ data_count++;
+ }
+
+ }
+
+ return data_count;
+}
+
+void UART_META_ExBytes(UART_PORT port, void * gpd_head, void * gpd_tail){
+ hdma_tbd_t *bd_ptr = NULL, *p_bd_cur =NULL;
+ hdma_tgpd_t *gpd_ptr = NULL;
+ kal_uint32 gpd_data_len=0, gpd_data_real_len = 0, bd_data_len=0, bd_data_real_len = 0;
+ kal_uint8 *gpd_data_ptr=NULL, *bd_data_ptr=NULL;
+
+
+ gpd_ptr = (hdma_tgpd_t*)gpd_head;
+ while(1){
+ if (QBM_DES_GET_BDP(gpd_ptr)) {
+ bd_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+ p_bd_cur = bd_ptr;
+ while (1) {
+ bd_data_len = QBM_DES_GET_DATALEN(p_bd_cur);
+ if(bd_data_len>0){
+ bd_data_ptr = QBM_DES_GET_DATAPTR(p_bd_cur);
+ QBM_CACHE_INVALID(bd_data_ptr, bd_data_len);
+ bd_data_real_len = U_ExBytes(port,bd_data_ptr ,bd_data_len, NULL, UARTPort[port].ownerid);
+ if (bd_data_len != bd_data_real_len) {
+ QBM_CACHE_FLUSH(bd_data_ptr, bd_data_real_len);
+ QBM_DES_SET_DATALEN(p_bd_cur, bd_data_real_len);
+ QBM_CACHE_FLUSH(p_bd_cur, QBM_SIZE_TGPD);
+ }
+ }
+ if (QBM_DES_GET_EOL(p_bd_cur)) {
+ break;
+ }
+ p_bd_cur =(void *) QBM_DES_GET_NEXT(p_bd_cur);
+
+ }
+ } else{
+ gpd_data_len = QBM_DES_GET_DATALEN(gpd_ptr);
+ if(gpd_data_len>0){
+ gpd_data_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+ QBM_CACHE_INVALID(gpd_data_ptr, gpd_data_len);
+ gpd_data_real_len = U_ExBytes(port,gpd_data_ptr ,gpd_data_len, NULL, UARTPort[port].ownerid);
+ if (gpd_data_len != gpd_data_real_len) {
+ QBM_CACHE_FLUSH(gpd_data_ptr, gpd_data_real_len);
+ QBM_DES_SET_DATALEN(gpd_ptr,gpd_data_real_len);
+ QBM_CACHE_FLUSH(gpd_ptr, QBM_SIZE_TGPD);
+ }
+ }
+ }
+ if(gpd_ptr == gpd_tail)
+ {
+ break;
+ } else
+ {
+ gpd_ptr = (void *) QBM_DES_GET_NEXT(gpd_ptr);
+ }
+ }
+}
+void UART_Boot_PutUARTBytes(UART_PORT port, kal_uint8 *data,kal_uint16 len)
+{
+ volatile kal_uint16 LSR;
+ kal_uint16 index;
+ static kal_uint32 UART_Boot_Send_Count = 0;
+
+ UART_Boot_Send_Count+=len;
+
+ for(index=0;index<len;index++)
+ UART_PutUARTByte_limited(port,*(data+index));
+
+ index = 0;
+ while(1) //make sure tx already send out all data.
+ {
+ LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));
+ if( LSR & UART_LSR_THRE )
+ {
+ break;
+ }else if( (MCU_BOOT_SPEED/DEBUG_BAUDRATE) < index++)
+ {
+ init_log_fail_count++;
+ break;
+ }
+ }
+}
+
+void U_PutUARTBytes(UART_PORT port, kal_uint8 *data,kal_uint16 len) {
+ kal_uint16 index;
+
+ for(index=0;index<len;index++)
+ pUart_CMD_FUNC[port]->PutUARTByte(port,*(data+index));
+
+}
+void PutUARTDatas(UART_PORT port, kal_uint8 escape_char, kal_uint8 *data,kal_uint16 len)
+{
+ kal_uint16 index;
+ if(port >= MAX_UART_PORT_NUM)
+ return;
+
+ if( (sst_get_exception_count() > 0) && (0 == UARTPort[port].Tx_DMA_Ch) && (1500000 == UARTPort[port].DCB.baud))
+ for(index=0;index<len;index++)
+ PutUARTDataDelay(port,escape_char,*(data+index));
+ else
+ for(index=0;index<len;index++)
+ PutUARTData(port,escape_char,*(data+index));
+}
+
+void U_SetBaudRate(UART_PORT port, UART_baudrate baudrate, module_type ownerid)
+{
+ kal_uint16 byte = 0;
+ kal_uint32 freq_div = 1;
+ kal_uint32 sample_count = 0;
+ kal_uint32 UART_BASE;
+
+ UART_BASE = UART_BaseAddr[port];
+ UARTPort[port].DCB.baud = baudrate;
+
+ if(baudrate)
+ {
+ do {
+ sample_count = (UART_CLOCK + (freq_div * baudrate / 2)) / (freq_div * baudrate);
+ if(sample_count > 0xff) freq_div++;
+ } while(sample_count > 0xff);
+ }
+
+ // configure register
+ DRV_UART_WriteReg(UART_RATE_STEP(UART_BASE), 0x3);
+
+ byte = DRV_Reg32(UART_LCR(UART_BASE)); // DLAB start
+ DRV_WriteReg32(UART_LCR(UART_BASE), byte | UART_LCR_DLAB);
+
+ DRV_WriteReg32(UART_DLL(UART_BASE), freq_div & 0xFF);
+ DRV_WriteReg32(UART_DLH(UART_BASE), (freq_div >> 8) & 0xFF);
+
+ DRV_UART_WriteReg(UART_STEP_COUNT(UART_BASE), sample_count - 1);
+ DRV_UART_WriteReg(UART_SAMPLE_COUNT(UART_BASE), sample_count >> 1);
+ DRV_UART_WriteReg(UART_LCR(UART_BASE), byte); // DLAB end
+}
+
+
+void UART_Bootup_Init()
+{
+ UARTPort[DEBUG_PORT].ownerid = (module_type)( (kal_uint16)MOD_UART1_HISR + (kal_uint8) DEBUG_PORT);
+
+ //Set SW flow control as equal to catcher default flow control
+ DRV_UART_WriteReg(UART_LCR(UART1_base),0xbf); /* Enchance setting */
+ DRV_UART_WriteReg(UART_EFR(UART1_base),UART_EFR_SWFlowCtrlX1);
+
+ //always open as new SW flow control, DHL under META will reset to disable
+ {
+ DRV_UART_WriteReg(UART_ESCAPE_DAT(UART1_base),0x77);
+ DRV_UART_WriteReg(UART_ESCAPE_EN(UART1_base),0x1);
+ }
+ DRV_UART_WriteReg(UART_XON1(UART1_base),0x11);
+ DRV_UART_WriteReg(UART_XOFF1(UART1_base),0x13);
+ DRV_UART_WriteReg(UART_XON2(UART1_base),0x11);
+ DRV_UART_WriteReg(UART_XOFF2(UART1_base),0x13);
+ DRV_UART_WriteReg(UART_LCR(UART1_base),0x3);
+
+
+ U_SetBaudRate(DEBUG_PORT, DEBUG_BAUDRATE, (module_type)( (kal_uint16)MOD_UART1_HISR + (kal_uint8) DEBUG_PORT));
+}
+
+/*This function is to cover 6218B/6219 hw bug.
+UART should not send receiving data to its FIFO when doing auto baud*/
+void U_SetAutoBaud_Div(UART_PORT port, module_type ownerid) {}
+
+void U_SetDCBConfig(UART_PORT port, UARTDCBStruct *UART_Config, module_type ownerid)
+{
+ kal_uint16 byte;
+ kal_uint16 IER;
+ kal_uint32 savedMask;
+ kal_uint32 UART_BASE;
+
+ UART_BASE = UART_BaseAddr[port];
+ savedMask = SaveAndSetIRQMask();
+ IER = DRV_UART_Reg(UART_IER(UART_BASE));
+ DRV_UART_WriteReg(UART_IER(UART_BASE),UART_IER_ALLOFF);
+ RestoreIRQMask(savedMask);
+
+ U_SetBaudRate(port, UART_Config->baud, ownerid);
+
+ /* Setup N81 */
+ byte = DRV_UART_Reg(UART_LCR(UART_BASE)); /* DLAB start */
+ byte &= ~UART_DATA_MASK;
+ switch(UART_Config->dataBits)
+ {
+ case len_5:
+ byte |= UART_WLS_5;
+ break;
+
+ case len_6:
+ byte |= UART_WLS_6;
+ break;
+
+ case len_7:
+ byte |= UART_WLS_7;
+ break;
+
+ case len_8:
+ byte |= UART_WLS_8;
+ break;
+
+ default:
+ break;
+ }
+ byte &= ~UART_STOP_MASK;
+ switch(UART_Config->stopBits)
+ {
+ case sb_1:
+ byte |= UART_1_STOP;
+ break;
+
+ case sb_2:
+ byte |= UART_2_STOP;
+ break;
+
+ case sb_1_5:
+ byte |= UART_1_5_STOP;
+ break;
+
+ default:
+ break;
+ }
+
+ byte &= ~UART_PARITY_MASK;
+ switch(UART_Config->parity)
+ {
+ case pa_none:
+ byte |= UART_NONE_PARITY;
+ break;
+
+ case pa_odd:
+ byte |= UART_ODD_PARITY;
+ break;
+
+ case pa_even:
+ byte |= UART_EVEN_PARITY;
+ break;
+
+ case pa_space:
+ byte |= UART_SPACE_PARITY;
+ break;
+
+ default:
+ break;
+ }
+ DRV_UART_WriteReg(UART_LCR(UART_BASE),byte); /* DLAB End */
+ /* flowControl */
+ byte = DRV_UART_Reg(UART_LCR(UART_BASE));
+
+ DRV_UART_WriteReg(UART_LCR(UART_BASE),0xbf); /* Enchance setting */
+ switch(UART_Config->flowControl)
+ {
+ case fc_none:
+ DRV_UART_WriteReg(UART_EFR(UART_BASE),UART_EFR_ALLOFF);
+
+ // Disable AutoEscape, we expect to use this functionality for S/W flow control
+ /*For AutoEscape*/
+ DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x0);
+
+ break;
+
+ case fc_hw:
+ DRV_UART_WriteReg(UART_EFR(UART_BASE),UART_EFR_AutoRTSCTS);
+
+ // Disable AutoEscape, we expect to use this functionality for S/W flow control
+ /*For AutoEscape*/
+ DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x0);
+ break;
+
+ case fc_sw:
+
+ DRV_UART_WriteReg(UART_EFR(UART_BASE), UART_EFR_SWFlowCtrlX1 |UART_EFR_Enchance);
+ //reset first
+ DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x0);
+ if(uart_support_autoescape()==KAL_TRUE)
+ {
+ /*For META, Dont use auto escape*/
+#if defined(META_MODE_SW_ESCAPING)
+ if(kal_query_boot_mode() != FACTORY_BOOT || UARTPort[port].ownerid != MOD_DHL_READER)
+#endif
+ {
+ /*For AutoEscape*/
+ DRV_UART_WriteReg(UART_ESCAPE_DAT(UART_BaseAddr[port]),0x77);
+ DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x1);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ /* XON and XOFF characters */
+ DRV_UART_WriteReg(UART_XON1(UART_BASE),UART_Config->xonChar);
+ DRV_UART_WriteReg(UART_XOFF1(UART_BASE),UART_Config->xoffChar);
+ DRV_UART_WriteReg(UART_XON2(UART_BASE),UART_Config->xonChar);
+ DRV_UART_WriteReg(UART_XOFF2(UART_BASE),UART_Config->xoffChar);
+ DRV_UART_WriteReg(UART_LCR(UART_BASE),byte); /* DLAB End */
+
+ kal_mem_cpy( &UARTPort[port].DCB, UART_Config, sizeof(UARTDCBStruct) );
+
+ savedMask = SaveAndSetIRQMask();
+ DRV_UART_WriteReg(UART_IER(UART_BASE),IER);
+ RestoreIRQMask(savedMask);
+}
+
+void U_ReadDCBConfig (UART_PORT port, UARTDCBStruct *DCB)
+{
+ kal_mem_cpy( DCB, &UARTPort[port].DCB, sizeof(UARTDCBStruct) );
+}
+
+void UART_loopback(UART_PORT port)
+{
+ kal_uint16 tmp;
+ kal_uint32 UART_BASE;
+ /* Enable Loop Back test!! */
+ if(port >= MAX_UART_PORT_NUM)
+ return;
+ UART_BASE = UART_BaseAddr[port];
+ tmp = DRV_UART_Reg(UART_MCR(UART_BASE));
+ tmp |= UART_MCR_LOOPB;
+ DRV_UART_WriteReg(UART_MCR(UART_BASE), tmp);
+}
+
+void UART_PDN_Disable(UART_PORT port)
+{
+ switch(port)
+ {
+ case uart_port1:
+ PDN_CLR(PDN_UART0);
+ #if defined(__HIF_UART_SUPPORT__) ||(defined(DRV_DEBUG)&&(defined(DRV_DEBUG_DMA_MODE) || defined(DRV_DEBUG_BUFFER_DMA_MODE)))
+ HDMA_PDN_CLR(port+2);
+ HDMA_PDN_CLR(port+3);
+ #endif
+ break;
+ case uart_port2:
+ PDN_CLR(PDN_UART1);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+}
+
+void UART_PDN_Enable(UART_PORT port)
+{
+ switch(port)
+ {
+ case uart_port1:
+ PDN_SET(PDN_UART0);
+ HDMA_PDN_SET(port+2);
+ HDMA_PDN_SET(port+3);
+ break;
+ case uart_port2:
+ PDN_SET(PDN_UART1);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+}
+
+void UART_HWInit(UART_PORT port)
+{
+ UARTDCBStruct *DCBdefault;
+ UARTDCBStruct UART_DefaultConfig =
+ {
+ UART_BAUD_1500000, // baud
+ len_8, // dataBits
+ sb_1, // stopBits
+ pa_none, // parity
+ fc_none, // no flow control
+ 0x11, // xonChar
+ 0x13, // xoffChar
+ KAL_FALSE
+ };
+ kal_uint32 UART_BASE;
+
+ if(port >= MAX_UART_PORT_NUM)
+ return;
+ UART_BASE = UART_BaseAddr[port];
+
+ UART_PDN_Disable(port);
+
+ /* Setup N81,(UART_WLS_8 | UART_NONE_PARITY | UART_1_STOP) = 0x03 */
+ /* BaudRate and autoflowcontrol */
+ DCBdefault = (UARTDCBStruct *)&UART_DefaultConfig;
+ U_SetDCBConfig(port, DCBdefault, UARTPort[port].ownerid);
+
+ DRV_UART_Reg(UART_LSR(UART_BASE));
+ DRV_UART_Reg(UART_MSR(UART_BASE));
+
+ /* DTR , RTS is on, data will be coming,Output2 is high */
+ DRV_UART_SetBits(UART_MCR(UART_BASE), UART_MCR_Normal);
+
+ DRV_UART_WriteReg(UART_IER(UART_BASE), UART_IER_ALLOFF);
+
+ // Set handle value to 0xFF to indicate this handle is invalid
+ UARTPort[port].handle = 0xFF;
+
+ UARTPort[port].Rec_state = UART_RecNormal;
+ UARTPort[port].port_no = port;
+
+ UARTPort[port].sleep_on_tx = uart_sleep_on_tx_allow;
+ UARTPort[port].EnableTX= KAL_TRUE;
+ UARTPort[port].power_on= KAL_TRUE;
+
+ // HDMA related HW init
+ // init FIFO Control Regitser: UART_FCR_RFTL_12 | UART_FCR_TFTL_0 | UART_FCR_CLRT | UART_FCR_CLRR | UART_FCR_FIFOE
+ DRV_UART_WriteReg(UART_FCR(UART_BaseAddr[port]), 0x87);
+#if defined(MTK_SLEEP_ENABLE)
+ DRV_UART_WriteReg(UART_SLEEP_EN(UART_BASE),KAL_TRUE);
+#endif
+ switch(port)
+ {
+ case uart_port1:
+ // init TX HDMA
+ HDMA_MODE_CONFIG(UART1_HDMA_TX_CHANNEL, HDMA_CKSUM_EN_DEFAULT, HDMA_LIST_MODE, HDMA_CKSUM_12B);
+ HDMA_CONFIG(UART1_HDMA_TX_CHANNEL, HDMA_BURST_SIZE_DEFAULT, HDMA_DEV_BUS_WIDTH_DEFAULT, HDMA_MEM_BUS_WIDTH_DEFAULT);
+ HDMA_BUF0_XFER_SIZE_CONFIG(UART1_HDMA_TX_CHANNEL, 0);
+
+ // init RX HDMA
+ HDMA_CONFIG_RX_SEL(UART1_HDMA_RX_CHANNEL, 0x3);
+ HDMA_MODE_CONFIG(UART1_HDMA_RX_CHANNEL, HDMA_CKSUM_EN_DEFAULT, HDMA_LIST_MODE, HDMA_CKSUM_12B);
+ HDMA_CONFIG(UART1_HDMA_RX_CHANNEL, HDMA_BURST_SIZE_DEFAULT, HDMA_DEV_BUS_WIDTH_DEFAULT, HDMA_MEM_BUS_WIDTH_DEFAULT);
+ HDMA_BUF0_XFER_SIZE_CONFIG(UART1_HDMA_RX_CHANNEL, 0);
+#ifdef DRV_DEBUG
+ DRV_WriteReg32(UART_DMA_EN(UART_BaseAddr[port]), 0x0);
+#else
+ DRV_WriteReg32(UART_DMA_EN(UART_BaseAddr[port]), UART_TXRXDMA_ON|UART_TO_CNT_AUTORST);
+ DRV_WriteReg32(UART_DMA_ACK(UART_BaseAddr[port]),UART_DMA_ACK_DIS);
+#endif
+ break;
+
+ case uart_port2:
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ // If needTxDoneCb is 1, the driver must call DclSerialPort_DrvTxDone(handle, source_id, tx_ior) after tx_ior data is sent.
+ // initial value is 0
+ UARTPort[port].need_tx_done_cb = KAL_FALSE;
+}
+
+kal_bool U_Open(UART_PORT port, module_type ownerid)
+{
+ kal_uint32 UART_BASE;
+ kal_uint16 MSR;
+ kal_uint8 byte;
+ kal_uint8 irq_code = 0;
+
+ UART_BASE = UART_BaseAddr[port];
+ if(port == uart_port_null)
+ return KAL_FALSE;
+
+ UARTPort[port].initialized = KAL_TRUE;
+ UARTPort[port].ownerid = ownerid;
+
+ UARTPort[port].RingBuffers.rx_buffer = UART_rings->ring[port].rx_adrs;
+ UARTPort[port].RingBuffers.tx_buffer = UART_rings->ring[port].tx_adrs;
+ Buf_init(&(UARTPort[port].Rx_Buffer),(kal_uint8 *)(UARTPort[port].RingBuffers.rx_buffer),(kal_uint16)UART_rings->ring[port].rx_len);
+ Buf_init(&(UARTPort[port].Tx_Buffer),(kal_uint8 *)(UARTPort[port].RingBuffers.tx_buffer),(kal_uint16)UART_rings->ring[port].tx_len);
+ if( UART_IsVfifoSetting(port, TX_VFIFO) == KAL_FALSE )
+ {
+ UARTPort[port].RingBuffers.txISR_buffer = UART_rings->ring[port].txisr_adrs;
+ Buf_init(&(UARTPort[port].Tx_Buffer_ISR),(kal_uint8 *)(UARTPort[port].RingBuffers.txISR_buffer),(kal_uint16)UART_rings->ring[port].txisr_len);
+ }
+
+ MSR = DRV_UART_Reg(UART_MSR(UART_BASE));
+
+ if (MSR & UART_MSR_DSR)
+ UARTPort[port].DSR = io_high;
+ else
+ UARTPort[port].DSR = io_low;
+
+ /* Rx FIFO trigger = 62, Tx FIFO trigger is 16, and FIFO enable. */
+ DRV_UART_WriteReg(UART_FCR(UART_BASE),UART_FCR_Normal);
+
+ if( UART_IsVfifoSetting(port, TXRX_VFIFO))
+ {
+ ASSERT(0);/*wrong configuration*/
+ }
+ else
+ {
+ if (UARTPort[port].DCB.flowControl == fc_none)
+ {
+ DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_HW_NORMALINTS);
+ }
+ else if (UARTPort[port].DCB.flowControl == fc_hw)
+ {
+// DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_HW_NORMALINTS);
+ DRV_UART_WriteReg32(UART_MCR(UART_BASE), (DRV_UART_Reg32(UART_MCR(UART_BASE)) | 0x02));
+ byte = DRV_UART_Reg(UART_LCR(UART_BASE));
+ DRV_UART_WriteReg(UART_LCR(UART_BASE), 0xbf);
+ DRV_UART_WriteReg(UART_EFR(UART_BASE), DRV_UART_Reg(UART_EFR(UART_BASE)) | UART_EFR_AutoRTSCTS);
+ DRV_UART_WriteReg(UART_LCR(UART_BASE), byte);
+ }
+ else if (UARTPort[port].DCB.flowControl == fc_sw)
+ {
+ // need to set EFR enhance before IRE
+ byte = DRV_UART_Reg(UART_LCR(UART_BASE));
+ DRV_UART_WriteReg(UART_LCR(UART_BASE),0xbf);
+ DRV_UART_WriteReg(UART_EFR(UART_BASE), DRV_UART_Reg(UART_EFR(UART_BASE)) | UART_EFR_Enchance);
+ DRV_UART_WriteReg(UART_LCR(UART_BASE),byte);
+
+ DRV_UART_WriteReg(UART_IER(UART_BaseAddr[port]),IER_SW_NORMALINTS);
+ DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x0); //reset to disable first
+ if(uart_support_autoescape()==KAL_TRUE)
+ {
+ /*For META, Dont use auto escape*/
+#if defined(META_MODE_SW_ESCAPING)
+ if(kal_query_boot_mode() != FACTORY_BOOT || UARTPort[port].ownerid != MOD_DHL_READER)
+#endif
+ {
+ /*For AutoEscape*/
+ byte = DRV_UART_Reg(UART_LCR(UART_BASE));
+ // DLAB start */
+ DRV_UART_WriteReg(UART_LCR(UART_BASE),0xbf); /* Enchance setting */
+ DRV_UART_WriteReg(UART_XON1(UART_BaseAddr[port]),0x11);
+ DRV_UART_WriteReg(UART_XON2(UART_BaseAddr[port]),0x11);
+ DRV_UART_WriteReg(UART_XOFF1(UART_BaseAddr[port]),0x13);
+ DRV_UART_WriteReg(UART_XOFF2(UART_BaseAddr[port]),0x13);
+ //autoescape
+ DRV_UART_WriteReg(UART_ESCAPE_DAT(UART_BaseAddr[port]),0x77);
+ DRV_UART_WriteReg(UART_ESCAPE_EN(UART_BaseAddr[port]),0x1);
+ DRV_UART_WriteReg(UART_LCR(UART_BASE),byte); /* Enchance setting */
+ }
+ }
+ }
+ }
+
+ /*For excetpion, we dont need to do the following */
+#ifdef __MTK_TARGET__
+ if(INT_QueryExceptionStatus())
+ return KAL_TRUE;
+#endif
+ switch(port)
+ {
+ case uart_port1:
+ irq_code = UART_GetIRQCode(uart_port1);
+ IRQMask(irq_code);
+ //IRQ_Register_LISR(irq_code, UART1_LISR, "UART1");
+ //IRQSensitivity(irq_code, LEVEL_SENSITIVE);
+ IRQClearInt(irq_code);
+ DRV_WriteReg32(UART_IER(UART_BASE), 0x4);
+ IRQUnmask(irq_code);
+ break;
+
+ case uart_port2:
+ irq_code = UART_GetIRQCode(uart_port2);
+ IRQMask(irq_code);
+ //IRQ_Register_LISR(irq_code, UART2_LISR, "UART2");
+ //IRQSensitivity(irq_code, LEVEL_SENSITIVE);
+ IRQClearInt(irq_code);
+ DRV_WriteReg32(UART_IER(UART_BASE), 0x4);
+ IRQUnmask(irq_code);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ IRQMask(UART_HDMA_INTR_ID);
+ //IRQ_Register_LISR(UART_HDMA_INTR_ID, uart_hdma_lisr, "UART_HDMA");
+ //IRQSensitivity(UART_HDMA_INTR_ID, LEVEL_SENSITIVE);
+
+ HDMA_LENERR_INTR_UNMASK(2);
+ HDMA_BD_CSERR_INTR_UNMASK(2);
+ HDMA_GPD_CSERR_INTR_UNMASK(2);
+ HDMA_LENERR_INTR_UNMASK(3);
+ HDMA_BD_CSERR_INTR_UNMASK(3);
+ HDMA_GPD_CSERR_INTR_UNMASK(3);
+ HDMA_QE_INTR_UNMASK(3); // RX done
+ HDMA_INT_CLEAR_ALL();
+ IRQUnmask(UART_HDMA_INTR_ID);
+
+ return KAL_TRUE;
+}
+
+void U_Purge(UART_PORT port, UART_buffer dir, module_type ownerid)
+{
+ kal_uint32 UART_BASE = UART_BaseAddr[port];
+
+ /* Rx FIFO trigger = 62, Tx FIFO trigger is 16, and FIFO enable. */
+ // for MT6290, Rx FIFO trigger = 12. Tx FIFO trigger is 0
+ if (dir == RX_BUF)
+ DRV_UART_WriteReg(UART_FCR(UART_BASE),(UART_FCR_Normal & ~UART_FCR_CLRT));
+ else
+ DRV_UART_WriteReg(UART_FCR(UART_BASE),(UART_FCR_Normal & ~UART_FCR_CLRR));
+}
+
+void U_Close(UART_PORT port, module_type ownerid)
+{
+ kal_uint32 UART_BASE = UART_BaseAddr[port];
+ kal_uint8 irq_code;
+
+ UARTPort[port].initialized = KAL_FALSE;
+ UARTPort[port].ownerid = (module_type) ((kal_uint16) MOD_UART1_HISR + (kal_uint8) port);
+
+ switch(port)
+ {
+ case uart_port1:
+ irq_code = UART_GetIRQCode(uart_port1);
+ IRQMask(irq_code);
+ break;
+ case uart_port2:
+ irq_code = UART_GetIRQCode(uart_port2);
+ IRQMask(irq_code);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ DRV_UART_WriteReg(UART_IER(UART_BASE), UART_IER_ALLOFF);
+
+ U_ConfigEscape(port, 0xff, 0, UARTPort[port].ownerid);
+
+ U_ClrRxBuffer(port, UARTPort[port].ownerid); // clear sw RX buffer
+ U_ClrTxBuffer(port, UARTPort[port].ownerid); // clear sw TX buffer
+ U_Purge(port, RX_BUF, UARTPort[port].ownerid); // clear hw RX FIFO
+ U_Purge(port, TX_BUF, UARTPort[port].ownerid); // clear hw TX FIFO
+
+ DRV_UART_WriteReg(UART_IER(UART_BASE),UART_IER_ALLOFF);
+
+ UART_PDN_Enable(port);
+
+
+ if(UARTPort[port].handle != 0xFF)
+ {
+ UARTPort[port].handle = 0xFF;
+ }
+}
+
+void U_SetOwner (UART_PORT port, module_type ownerid)
+{
+ U_ClrTxBuffer(port, UARTPort[port].ownerid); // clear sw TX buffer
+ U_ClrRxBuffer(port, UARTPort[port].ownerid); // clear sw RX buffer
+
+ UARTPort[port].ownerid = ownerid;
+ UARTPort[port].need_tx_done_cb = KAL_FALSE;
+}
+
+module_type U_GetOwnerID(UART_PORT port)
+{
+ return UARTPort[port].ownerid;
+}
+
+void U_ConfigEscape (UART_PORT port, kal_uint8 EscChar, kal_uint16 ESCGuardtime, module_type ownerid)
+{
+
+ UARTPort[port].ESCDet.EscChar = EscChar;
+ UARTPort[port].ESCDet.GuardTime = ESCGuardtime;
+ // Escape character register is WO
+ DRV_UART_WriteReg(UART_ESCAPE_DAT(UART_BaseAddr[port]), EscChar); // added by ansel
+ DRV_UART_WriteReg(UART_GUARD(UART_BaseAddr[port]), ESCGuardtime); // added by ansel
+ if (UARTPort[port].ESCDet.GuardTime)
+ {
+ UARTPort[port].Rec_state = UART_RecNormal;
+ }
+}
+
+void U_SetFlowCtrl(UART_PORT port, kal_bool XON, module_type ownerid) {} /*NULL for all*/
+
+kal_uint32 U_GetFlowCtrl(UART_PORT port, module_type ownerid)
+{
+ kal_uint16 IER, LCR;
+ kal_uint32 savedMask;
+ kal_uint32 UART_BASE;
+ kal_uint32 EFR;
+
+ UART_BASE = UART_BaseAddr[port];
+
+ savedMask = SaveAndSetIRQMask();
+ IER = DRV_UART_Reg(UART_IER(UART_BASE));
+ DRV_UART_WriteReg(UART_IER(UART_BASE), UART_IER_ALLOFF);
+ RestoreIRQMask(savedMask);
+
+ LCR = DRV_UART_Reg(UART_LCR(UART_BASE));
+ DRV_UART_WriteReg(UART_LCR(UART_BASE), 0xBF);
+ EFR = DRV_UART_Reg(UART_EFR(UART_BASE));
+ DRV_UART_WriteReg(UART_LCR(UART_BASE), LCR);
+
+ savedMask = SaveAndSetIRQMask();
+ DRV_UART_WriteReg(UART_IER(UART_BASE), IER);
+ RestoreIRQMask(savedMask);
+
+ return EFR;
+}
+
+void U_CtrlDCD(UART_PORT port, IO_level SDCD, module_type ownerid) {} /*NULL for DCE*/
+void U_CtrlRI (UART_PORT port, IO_level SRI, module_type ownerid) {} /*NULL for DCE*/
+void U_CtrlDTR (UART_PORT port, IO_level SDTR, module_type ownerid) {}
+void U_ReadHWStatus(UART_PORT port, IO_level *SDSR, IO_level *SCTS)
+{
+ kal_uint16 MSR;
+ kal_uint32 UART_BASE;
+
+ UART_BASE = UART_BaseAddr[port];
+ MSR = DRV_UART_Reg(UART_MSR(UART_BASE));
+ *SDSR = (IO_level)(( MSR & UART_MSR_DSR) >> 5);
+ *SCTS = (IO_level)(( MSR & UART_MSR_CTS) >> 4);
+}
+
+void U_CtrlBreak(UART_PORT port, IO_level SBREAK, module_type ownerid)
+{
+ kal_uint32 UART_BASE = UART_BaseAddr[port];
+ if(SBREAK == io_high)
+ {
+ if(HDMA_BUF0_IS_ACTIVE((port + 2)))
+ HDMA_BUF0_STOP((port + 2));
+ DRV_UART_SetBits(UART_LCR(UART_BASE), UART_LCR_BREAK);
+ } else
+ {
+ DRV_UART_ClearBits(UART_LCR(UART_BASE), UART_LCR_BREAK);
+ if(uart_wait_tgpd_head[port] != NULL || uart_tgpd_head[port] != NULL)
+ HDMA_BUF0_RESUME((port + 2));
+ }
+}
+
+kal_uint16 U_GetBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid)
+{
+ kal_uint16 real_count, index;
+ kal_uint16 data_count = 0;
+
+ if(status != NULL)
+ *status = 0;
+
+ DisableRxIntr(UART_BaseAddr[port]);
+ if (status != NULL)
+ {
+ if (UARTPort[port].EscFound)
+ {
+ *status |= UART_STAT_EscDet;
+ UARTPort[port].EscFound = KAL_FALSE;
+ }
+ if(UARTPort[port].breakDet)
+ {
+ *status |= UART_STAT_Break;
+ UARTPort[port].breakDet = KAL_FALSE;
+ }
+ }
+
+ EnableRxIntr(UART_BaseAddr[port]);
+
+ do {
+ Buf_GetBytesAvail(&(UARTPort[port].Rx_Buffer),real_count);
+
+ if((kal_query_boot_mode() == FACTORY_BOOT && UARTPort[port].DCB.flowControl == fc_sw && UARTPort[port].ownerid == MOD_DHL_READER)
+ || (uart_support_autoescape() == KAL_FALSE && UARTPort[port].DCB.flowControl == fc_sw))
+ {
+
+ for(index = 0; (index < real_count) && (data_count < Length); index++)
+ {
+ Buf_Pop(&(UARTPort[port].Rx_Buffer), *(Buffaddr + data_count));
+
+ // The following are for software flow control
+ if(uart_escape_state==0)
+ {
+ if(*(Buffaddr + data_count) == 0x77)
+ {
+ uart_escape_state=0x77;
+ } else
+ {
+ data_count++;
+ }
+
+ } else if(uart_escape_state == 0x77)
+ {
+ switch(*(Buffaddr + data_count))
+ {
+ case 0x01:
+ *(Buffaddr+data_count) = UARTPort[port].DCB.xonChar;
+ data_count++;
+ break;
+ case 0x02:
+ *(Buffaddr+data_count)=UARTPort[port].DCB.xoffChar;
+ data_count++;
+ break;
+ case 0x03:
+ *(Buffaddr + data_count) = 0x77;
+ data_count++;
+ break;
+ default:
+ break;
+
+ }
+ uart_escape_state=0x0;
+
+ }
+ }
+
+ } else // HW flow control
+ {
+ for(index = 0; (index < real_count) && (data_count < Length); index++)
+ {
+ Buf_Pop(&(UARTPort[port].Rx_Buffer),*(Buffaddr + data_count));
+ data_count++;
+ }
+ }
+
+ // satisfy uart owner request, so break
+ if (data_count == Length) break;
+
+ // disable interrupt
+ DisableRxIntr(UART_BaseAddr[port]);
+
+ Buf_GetBytesAvail(&(UARTPort[port].Rx_Buffer),real_count);
+ // there is no data in ringbuffer, so break
+ if(real_count == 0)
+ {
+ send_Rxilm[port] = KAL_TRUE;
+ // enable interrupt
+ EnableRxIntr(UART_BaseAddr[port]);
+ break;
+ }
+
+ /* enable interrupt*/
+ EnableRxIntr(UART_BaseAddr[port]);
+ } while(KAL_TRUE);
+
+ return data_count;
+}
+
+#ifdef DRV_DEBUG
+
+void UART_DMA_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length)
+{
+ if(port>=uart_port3){
+ return;
+ }
+ clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)Buffaddr), CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)Buffaddr, (kal_uint32)Length));
+
+ HDMA_BUF0_PROG_ADDR_CONFIG(port+2, (kal_uint32)Buffaddr);
+ HDMA_BUF0_XFER_SIZE_CONFIG(port+2, (kal_uint32)Length);
+
+ Data_Sync_Barrier();
+
+ HDMA_BUF0_START(port+2);
+}
+
+kal_uint16 BMT_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length)
+{
+ kal_uint16 real_count, index;
+ #if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+ kal_uint16 is_empty;
+ #endif
+ if(port >= MAX_UART_PORT_NUM)
+ return 0;
+
+ Buf_GetRoomLeft(&(UARTPort[port].Tx_Buffer), real_count);
+ if(real_count > Length)
+ {
+ real_count = Length;
+ }
+
+ /*
+ * The spin lock is used for the con-currency case of HDMA HISR
+ * and dbg_print. The write/read pointer of buffer is the basis
+ * whether to start the next DMA or NOT, so use the spin lock
+ * to protect the pointer updatding actions
+ */
+ #if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+ #ifndef KTEST_UART_TRACES
+ kal_take_spinlock(print_buf_lock, KAL_INFINITE_WAIT);
+ #else
+ kal_hrt_take_itc_lock(KAL_ITC_PRINT, KAL_INFINITE_WAIT);
+ #endif
+
+ /* To check if DMA should be start in this API */
+ Buf_IsEmpty(&(UARTPort[port].Tx_Buffer), is_empty);
+ #endif
+
+ for(index = 0; index < real_count; index++)
+ {
+ Buf_Push(&(UARTPort[port].Tx_Buffer), *(Buffaddr + index));
+ }
+
+ #if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+ #ifndef KTEST_UART_TRACES
+ kal_give_spinlock(print_buf_lock);
+ #else
+ kal_hrt_give_itc_lock(KAL_ITC_PRINT);
+ #endif
+ #endif
+
+ switch(port)
+ {
+ case uart_port1:
+ #if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+ if (is_empty == Buff_isEmpty)
+ UART_TxDMAHandler(&UARTPort[uart_port1], 0);
+ #else
+ EnableTxIntr(UART_BaseAddr[port]);
+ #endif
+ break;
+ case uart_port2:
+ EnableTxIntr(UART_BaseAddr[port]);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+
+ return real_count;
+}
+#endif /*DRV_DEBUG*/
+
+/*************************************************************************
+ * FUNCTION
+ * UART_GetTxWorkingMode
+ *
+ * DESCRIPTION
+ *
+ * This function is to get the uart TX working mode.
+ *
+ * PARAMETERS
+ * port - the uart port
+ *
+ * RETURNS
+ * UART_ON_VFIFO: the uart port Tx working on VFIFO mode
+ * UART_ON_DMA: the uart port Tx working on normal DMA mode
+ * UART_ON_MCU: the uart port Tx working on sw mode
+ *
+ * Global AFFECTED
+ *
+ *************************************************************************/
+UART_WORKING_MODE UART_GetTxWorkingMode(UART_PORT port)
+{
+ if(UART_IsVfifoSetting(port, TX_VFIFO))
+ return UART_ON_VFIFO;
+
+ return UART_ON_MCU;
+}
+
+kal_uint16 U_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid )
+{
+ kal_uint16 real_count, index;
+ if(port >= MAX_UART_PORT_NUM)
+ return 0;
+
+ Buf_GetRoomLeft(&(UARTPort[port].Tx_Buffer), real_count);
+ if(real_count > Length)
+ {
+ real_count = Length;
+ }
+
+ for(index = 0; index < real_count; index++)
+ {
+ Buf_Push(&(UARTPort[port].Tx_Buffer), *(Buffaddr + index));
+ }
+
+ switch(port)
+ {
+ case uart_port1:
+ EnableTxIntr(UART_BaseAddr[port]);
+ break;
+ case uart_port2:
+ EnableTxIntr(UART_BaseAddr[port]);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ return real_count;
+}
+
+#ifndef __ROMSA_SUPPORT__ /* Note: for ROM code */
+
+#if defined(__MTK_INTERNAL__) && defined(__MTK_TARGET__)
+kal_uint16 DEVDRV_LS_INTERNCODE
+#else
+kal_uint16
+#endif
+U_PutISRBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid)
+{
+ return 0;
+}
+#endif /* Note: for ROM code */
+
+#if defined(__MTK_INTERNAL__) && defined(__MTK_TARGET__)
+kal_uint16 DEVDRV_LS_INTERNCODE
+#else
+kal_uint16
+#endif
+U_SendISRData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode, kal_uint8 escape_char, module_type ownerid)
+{
+ return 0;
+}
+
+kal_uint16 U_SendData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode,kal_uint8 escape_char, module_type ownerid)
+{
+ return 0;
+}
+
+//============================== ISR level ====================
+/*============================ UART1 ========================*/
+void UART_RLSHandler(void *parameter)
+{
+ kal_uint16 LSR;
+ UARTStruct *UARTData = (UARTStruct *) parameter;
+ kal_uint32 UART_BASE;
+
+ if(UARTData->port_no >= MAX_UART_PORT_NUM)
+ return;
+
+ UART_BASE = UART_BaseAddr[UARTData->port_no];
+ LSR = DRV_UART_Reg(UART_LSR(UART_BASE));
+/*
+ if(LSR & UART_LSR_OE) dbg_print("Overrun Error\n\r");
+ if(LSR & UART_LSR_PE) dbg_print("Parity Error\n\r");
+ if(LSR & UART_LSR_FE) dbg_print("Framing Error\n\r");
+*/
+ if(LSR & UART_LSR_BI)
+ {
+ UARTData->breakDet = KAL_TRUE;
+ U_Purge(UARTData->port_no, RX_BUF, UARTPort[UARTData->port_no].ownerid);
+ }
+
+ if((LSR & UART_LSR_OE) || (LSR & UART_LSR_FIFOERR))
+ {
+ //for check BT overwrite UART FIFO, because BT do not use flow control, lost data will cause BT fail
+// if((UARTPort[UARTData->port_no].ownerid == MOD_BT))
+// {
+// UART_DBG(__LINE__, UART_GetTimeStamp(), ust_get_current_time(), LSR);
+// ASSERT(!(LSR & UART_LSR_OE)); // BT send too fast, VFIFO can not get bus, overwrite UART FIFO
+// }
+ DisableRLSIntr(UART_BASE);
+ }
+}
+
+void UART_Calback(void *parameter) {}
+
+void UART_SetRateFix(UART_PORT port) {}
+
+int uart_pio_get_data_like_dma(UART_PORT port, kal_uint8 *ptr_dat, kal_uint32 allow_len)
+{
+ int real_len = 0;
+ kal_uint32 base = UART_BaseAddr[port];
+ if ((DRV_Reg8(UART_LSR(base))&UART_LSR_DR) == 0) {
+ /* RX no data */
+ return 0;
+ }
+ for(;;) {
+ while ((real_len < allow_len) && (DRV_Reg8(UART_LSR(base))&UART_LSR_DR)) {
+ *ptr_dat++ = DRV_Reg8(UART_RBR(base));
+ real_len ++;
+ }
+
+ if (real_len == allow_len) {
+ /* Got Enough data */
+ break;
+ }
+
+ /* 32k timer, 30us */
+ kal_uint32 delayTime1;
+ delayTime1 = drv_get_current_time()+3; /* delay 60~90us*/
+ while(delayTime1 != drv_get_current_time()) {
+ if ((DRV_Reg8(UART_LSR(base))&UART_LSR_DR))
+ break;
+
+ }
+
+ if ((DRV_Reg8(UART_LSR(base))&UART_LSR_DR) == 0) {
+ /* RX Timeout */
+ break;
+ }
+ }
+
+ return real_len;
+}
+void UART_RecHandler(void *parameter) {
+ UARTStruct *UARTData=(UARTStruct *)parameter;
+ kal_uint32 UART_BASE;
+ kal_uint16 RoomLeft;
+ kal_uint16 LSR;
+ kal_uint8 cRXChar;
+ if(UARTData->port_no >= MAX_UART_PORT_NUM)
+ return;
+
+ UART_BASE = UART_BaseAddr[UARTData->port_no];
+ Buf_GetRoomLeft(&(UARTData->Rx_Buffer),RoomLeft);
+
+ while (RoomLeft)
+ {
+ LSR = DRV_UART_Reg(UART_LSR(UART_BASE));
+ if (LSR & UART_LSR_BI)
+ {
+ UARTData->breakDet = KAL_TRUE;
+ U_Purge(UARTData->port_no,RX_BUF,UARTPort[UARTData->port_no].ownerid);
+ LSR = DRV_UART_Reg(UART_LSR(UART_BASE));
+ }
+
+ if (LSR & UART_LSR_DR)
+ {
+
+ cRXChar = (kal_uint8)DRV_UART_Reg(UART_RBR(UART_BASE));
+
+ Buf_Push(&(UARTData->Rx_Buffer),cRXChar);
+ RoomLeft--;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if (!RoomLeft) /*buffer is full*/
+ DisableRxIntr(UART_BASE);
+
+
+}
+
+#if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+/* This function might be called by HISR and dbg_print */
+void UART_TxDMAHandler(void *parameter, kal_uint8 chk_done)
+{
+ UARTStruct *UARTData = (UARTStruct *) parameter;
+ kal_uint16 real_count_TASK, done_count;
+ BUFFER_INFO *TxBuf = (BUFFER_INFO *)(&(UARTData->Tx_Buffer));
+
+ if(UARTData->port_no >= MAX_UART_PORT_NUM)
+ return;
+
+ /*
+ * The spin lock is used for the con-currency case of HDMA HISR
+ * and dbg_print. The write/read pointer of buffer is the basis
+ * whether to start the next DMA or NOT, so use the spin lock
+ * to protect the pointer updatding actions
+ */
+ #ifndef KTEST_UART_TRACES
+ kal_take_spinlock(print_buf_lock, KAL_INFINITE_WAIT);
+ #else
+ kal_hrt_take_itc_lock(KAL_ITC_PRINT, KAL_INFINITE_WAIT);
+ #endif
+
+ if (chk_done) {
+ done_count = DRV_Reg32(GDMA_HCCR(UARTData->port_no+2)) & 0xFFFF;
+
+ if (done_count) {
+ BRead(TxBuf) += done_count;
+ if (BRead(TxBuf) >= BLength(TxBuf))
+ BRead(TxBuf) -= BLength(TxBuf);
+ }
+ }
+
+ Buf_GetBytesAvail_DMA(&(UARTData->Tx_Buffer), real_count_TASK);
+
+ #ifndef KTEST_UART_TRACES
+ kal_give_spinlock(print_buf_lock);
+ #else
+ kal_hrt_give_itc_lock(KAL_ITC_PRINT);
+ #endif
+
+ if (real_count_TASK) {
+ clean_and_invalidate_dcache(CPU_CACHE_LINE_ALIGN_ADDR((kal_uint32)BuffRead(TxBuf)),
+ CPU_CACHE_LINE_ALIGN_LEN((kal_uint32)BuffRead(TxBuf), (kal_uint32)real_count_TASK));
+
+ HDMA_BUF0_PROG_ADDR_CONFIG(UARTData->port_no+2, (kal_uint32)BuffRead(TxBuf));
+ HDMA_BUF0_XFER_SIZE_CONFIG(UARTData->port_no+2, (kal_uint32)real_count_TASK);
+ HDMA_BUF0_START(UARTData->port_no+2);
+
+ return;
+ }
+}
+#endif
+
+void UART_TrxHandler(void *parameter)
+{
+ UARTStruct *UARTData = (UARTStruct *) parameter;
+ kal_uint32 UART_BASE;
+ kal_uint16 byteCount, index;
+ kal_uint16 real_count_TASK, real_count = 0;
+ kal_uint16 offset;
+ kal_uint8 TX_DATA;
+
+ if(UARTData->port_no >= MAX_UART_PORT_NUM)
+ return;
+
+ UART_BASE = UART_BaseAddr[UARTData->port_no];
+
+ byteCount = UART1_TxFIFO_DEPTH;
+
+ if(real_count != byteCount)
+ {
+ Buf_GetBytesAvail(&(UARTData->Tx_Buffer), real_count_TASK);
+ offset = byteCount - real_count;
+ real_count = real_count_TASK;
+ if(real_count_TASK > offset)
+ {
+ real_count = offset;
+ }
+
+ for(index = 0; index < real_count; index++)
+ {
+ Buf_Pop(&(UARTData->Tx_Buffer),TX_DATA);
+ DRV_UART_WriteReg(UART_THR(UART_BASE), (kal_uint16) TX_DATA);
+ }
+ }
+
+ Buf_GetBytesAvail(&(UARTData->Tx_Buffer), real_count_TASK);
+ if(real_count_TASK == 0)
+ DisableTxIntr(UART_BASE);
+}
+
+void UART_MsHandler(void *parameter) {}
+
+//Bei add for get irq code
+kal_uint8 UART_GetIRQCode(UART_PORT port)
+{
+ kal_uint8 IRQ_code = 0;
+ switch(port)
+ {
+ case uart_port1:
+ IRQ_code = IRQ_UART_MD0_CODE;
+ break;
+ case uart_port2:
+ IRQ_code = IRQ_UART_MD1_CODE;
+ break;
+ default:
+ break;
+ }
+ return IRQ_code;
+}
+
+void UART1_LISR(kal_uint32 vector)
+{
+ IRQMask(IRQ_UART_MD0_CODE);
+ kal_activate_hisr_index(UART_1_HISR);
+}
+
+void UART1_HISR(void)
+{
+ kal_uint16 IIR;
+
+ IIR = DRV_UART_Reg(UART_IIR(UART_BaseAddr[uart_port1]));
+ if (IIR & UART_IIR_INT_INVALID)
+ {
+ IRQClearInt(IRQ_UART_MD0_CODE);
+ IRQUnmask(IRQ_UART_MD0_CODE);
+
+ return;
+ }
+
+ switch(IIR & UART_IIR_INT_MASK)
+ {
+
+ case UART_IIR_RLS:
+ UART_RLSHandler(&UARTPort[uart_port1]);
+ break;
+ case UART_IIR_CTI:
+ case UART_IIR_RDA:
+#ifdef __SLT_TOOL_SUPPORT__
+ UART_RecHandler(&UARTPort[uart_port1]) ;
+#endif
+ break;
+ case UART_IIR_THRE:
+ UART_TrxHandler(&UARTPort[uart_port1]);
+ break;
+ case UART_IIR_MS :
+ case UART_IIR_SWFlowCtrl:
+ case UART_IIR_HWFlowCtrl:
+ default:
+ break;
+ }
+ IRQClearInt(IRQ_UART_MD0_CODE);
+ IRQUnmask(IRQ_UART_MD0_CODE);
+}
+
+/*============================ UART2 ========================*/
+void UART2_LISR(kal_uint32 vector)
+{
+ IRQMask(IRQ_UART_MD1_CODE);
+ kal_activate_hisr_index(UART_2_HISR);
+}
+
+void UART2_HISR(void)
+{
+ kal_uint16 IIR;
+
+ IIR = DRV_UART_Reg(UART_IIR(UART_BaseAddr[uart_port2]));
+ if (IIR & UART_IIR_INT_INVALID)
+ {
+ IRQClearInt(IRQ_UART_MD1_CODE);
+ IRQUnmask(IRQ_UART_MD1_CODE);
+
+ return;
+ }
+
+ switch(IIR & UART_IIR_INT_MASK)
+ {
+
+ case UART_IIR_RLS:
+ UART_RLSHandler(&UARTPort[uart_port2]);
+ break;
+ case UART_IIR_CTI:
+ case UART_IIR_RDA:
+ break;
+ case UART_IIR_THRE:
+ UART_TrxHandler(&UARTPort[uart_port2]);
+ break;
+ case UART_IIR_MS :
+ case UART_IIR_SWFlowCtrl:
+ case UART_IIR_HWFlowCtrl:
+ default:
+ break;
+ }
+ IRQClearInt(IRQ_UART_MD1_CODE);
+ IRQUnmask(IRQ_UART_MD1_CODE);
+}
+
+
+typedef struct _ut_hdma_intr_s{
+ kal_uint32 hdma_done_int;
+ kal_uint32 hdma_qe_int;
+ kal_uint32 hdma_len_err_int;
+ kal_uint32 hdma_bd_cserr_int;
+ kal_uint32 hdma_gpd_cserr_int;
+}ut_hdma_intr_t;
+
+volatile static ut_hdma_intr_t ut_hdma_intr_record[2];
+
+
+void uart_hdma_lisr(kal_uint32 vector)
+{
+ IRQMask(UART_HDMA_INTR_ID);
+ kal_activate_hisr_index(GDMA2_HISR);
+}
+
+void uart_hdma_hisr(void)
+{
+ //kal_uint32 mask;
+ kal_uint32 val, chl;
+ kal_uint32 i;
+
+ //mask = SaveAndSetIRQMask();
+
+ val = DRV_Reg32(GDMA_GISAR_UART);
+
+ //Set the interrupt record table
+ for(i = 0; i < sizeof(ut_hdma_intr_record) / sizeof(ut_hdma_intr_t); i++ ){
+ chl = i + 2;
+
+ if(IS_HDMA_DONE_INTR(val, chl)){
+ ut_hdma_intr_record[i].hdma_done_int++;
+
+ #if defined(DRV_DEBUG_BUFFER_DMA_MODE)
+ if (chl == UART1_HDMA_TX_CHANNEL) {
+ UART_TxDMAHandler(&UARTPort[uart_port1], 1);
+ }
+ #endif
+ }
+
+ if(IS_HDMA_QE_INTR(val, chl)){
+ ut_hdma_intr_record[i].hdma_qe_int++;
+
+ #if defined(__HMU_ENABLE__)
+ if (chl == UART1_HDMA_RX_CHANNEL) {
+ // trigger UARTCORE task to polling RX
+ hmu_hifeg_set(HIF_DRV_EG_HIF_TICK_EVENT_UART);
+ }
+ #endif
+ }
+
+ if(IS_HDMA_GPD_CSERR_INTR(val, chl)){
+ ut_hdma_intr_record[i].hdma_gpd_cserr_int++;
+ ASSERT(0);
+ }
+
+ if(IS_HDMA_BD_CSERR_INTR(val, chl)){
+ ut_hdma_intr_record[i].hdma_bd_cserr_int++;
+ ASSERT(0);
+ }
+
+ if(IS_HDMA_LENERR_INTR(val, chl)){
+ ut_hdma_intr_record[i].hdma_len_err_int++;
+ ASSERT(0);
+ }
+ }
+
+ //Clear the interrupt status
+ HDMA_INT_CLEAR_ALL();
+
+ //RestoreIRQMask(mask);
+ IRQUnmask(UART_HDMA_INTR_ID);
+}
+
+#ifdef __USB_COM_PORT_ENABLE__
+extern UARTStruct USB2UARTPort[MAX_USB_PORT_NUM];
+#endif /*__USB_COM_PORT_ENABLE__*/
+
+void UART_SetSleepEnable(UART_PORT port, kal_bool enable)
+{
+ DRV_UART_WriteReg(UART_SLEEP_EN(UART_BaseAddr[port]), enable);
+}
+
+//This API only for test purpose, can only be called by MEUT DVT test.
+//*********** do not call this API directly ************
+//*********** do not call this API directly ************
+//*********** do not call this API directly ************
+void UART_set_FIFO_trigger(UART_PORT port, kal_uint16 tx_level, kal_uint16 rx_level)
+{
+ if(port >= MAX_UART_PORT_NUM)
+ return;
+ DRV_UART_WriteReg(UART_FCR(UART_BaseAddr[port]), ((tx_level<<4) | (rx_level<<6) | 0x7));
+}
+
+void U_Register_TX_cb(UART_PORT port, module_type ownerid, UART_TX_FUNC func) {}
+void U_Register_RX_cb(UART_PORT port, module_type ownerid, UART_RX_FUNC func) {}
+void UART_TurnOnPower(UART_PORT port, kal_bool enable) {}
+
+/* This is to check that all the data in UART TX ring buffer is empty. */
+kal_bool UART_CheckTxBufferEmpty(UART_PORT port)
+{
+ kal_uint8 result;
+ void *p_cur_gpd;
+ if(port >= MAX_UART_PORT_NUM)
+ return KAL_FALSE;
+
+// HDMA
+ if(uart_wait_tgpd_head[port] != NULL || uart_wait_tgpd_tail[port] != NULL) return KAL_FALSE;
+ p_cur_gpd = uart_tgpd_head[port];
+ while(1)
+ {
+ if(p_cur_gpd == NULL) break;
+ if(p_cur_gpd == uart_tgpd_tail[port]) break;
+ if(QBM_DES_GET_HWO(p_cur_gpd + 0x40000000)) return KAL_FALSE;
+ p_cur_gpd = QBM_DES_GET_NEXT(p_cur_gpd);
+ }
+
+ Buf_IsEmpty(&(UARTPort[port].Tx_Buffer), result);
+ return ((Buff_isEmpty == result) ? KAL_TRUE : KAL_FALSE);
+}
+
+/* This is to check that all TX data have been sent out
+including UART TX ring buffer and UART FIFO. */
+kal_bool UART_CheckTxAllSentOut(UART_PORT port)
+{
+ if(port >= MAX_UART_PORT_NUM)
+ return KAL_FALSE;
+
+ if (UART_CheckTxBufferEmpty(port) == KAL_FALSE)
+ return KAL_FALSE;
+ if (UART_LSR_TEMT & DRV_UART_Reg(UART_LSR(UART_BaseAddr[port])))
+ return KAL_TRUE;
+ else
+ return KAL_FALSE;
+}
+
+
+// this function has a problem
+void UART_GetTxBufferSize(UART_PORT port, kal_uint32 *total_size, kal_uint32 *rest_size)
+{
+ if(port >= MAX_UART_PORT_NUM)
+ return;
+ *total_size = UARTPort[port].Tx_Buffer.Length;
+ if(uart_tgpd_head[port] != NULL || uart_wait_tgpd_head[port] != NULL)
+ {
+ *rest_size = uart_cal_tgpd_buf_length((void *) GDMA_HDCPRN((port + 2)), (void *) uart_tgpd_tail[port]);
+ *rest_size += uart_cal_tgpd_buf_length((void *) uart_wait_tgpd_head[port], (void *) uart_wait_tgpd_tail[port]);
+
+ } else
+ Buf_GetBytesAvail(&(UARTPort[port].Tx_Buffer), *rest_size);
+}
+
+
+/*
+* FUNCTION
+* UART_VFIFO_TX_DMA_Enable
+*
+* DESCRIPTION
+* for
+*
+* CALLS
+* This function is called to enable or disable VFIFO DMA TX
+* it is for logacc only , logacc will take UART TX , it might cause UART & VFIFO DMA sync problem
+* so we must disable VFIFO DMA when logacc on
+* enable and reset VFIFO DMA when logacc off
+*
+* PARAMETERS
+* port: uart port
+* enable: disable or enable VFIFO DMA TX
+* RETURNS
+* None
+*
+* GLOBALS AFFECTED
+* external_global
+*/
+void UART_VFIFO_TX_DMA_Enable(UART_PORT port,kal_bool enable) {}
+
+
+
+
+// Used under ASSERT condition
+// This has effect only when the port does NOT support VFIFO and used as Catcher port
+// After ASSERT, DHL will wait UART to send out all the data before ASSERT.
+// But now, all the interrupts are disabled, DHL may wait forever when the UART port is configured with DMA
+// To solve this problem, we provide this function for DHL to call
+// in order to send out all the data in ring buffer before ASSERT
+// DHL will open UART port again after previous data is sent out
+void UART_AssertWaitPrevDataSentOut(UART_PORT port){
+ kal_uint16 LSR;
+ kal_uint16 TX_DATA;
+
+ if(port >= MAX_UART_PORT_NUM)
+ return;
+
+ // Manually send out data by MCU polling
+ while(!UART_CheckTxBufferEmpty(port))
+ {
+ LSR = DRV_UART_Reg(UART_LSR(UART_BaseAddr[port]));
+ if(LSR & UART_LSR_THRE)
+ {
+ Buf_Pop(&(UARTPort[port].Tx_Buffer), TX_DATA);
+ DRV_UART_WriteReg(UART_THR(UART_BaseAddr[port]), (kal_uint16) TX_DATA);
+ }
+ }
+
+ // Wait UART controller to sent out the data in FIFO
+ while(!UART_CheckTxAllSentOut(port));
+}
+
+kal_uint32 UART_Get_Maxbaudrate(UART_PORT port)
+{
+ return 6000000;
+}
+
+kal_uint32 UART_PutBytesIor(UART_PORT port, void *putIor)
+{
+ void *p_ior;
+ if(port >= MAX_UART_PORT_NUM)
+ return 0;
+
+ p_ior = putIor;
+ while(1)
+ {
+ // if there is no tgpd, atach a bypass tgpd
+ uart_en_q_de_q_with_mutex(port, UART_TX, UART_EN_Q, ((tty_io_request_t *) putIor)->first_gpd, ((tty_io_request_t *) putIor)->last_gpd);
+ if(((tty_io_request_t *) p_ior)->next_request == NULL)
+ {
+ break;
+ } else
+ {
+ p_ior = ((tty_io_request_t *) p_ior)->next_request;
+ }
+ }
+
+ return 0;
+}
+
+kal_uint32 UART_PutBytesIor_LIGHT(UART_PORT port, void *putIor)
+{
+ void *p_ior;
+ if(port >= MAX_UART_PORT_NUM)
+ return 0;
+
+ p_ior = putIor;
+ while(1)
+ {
+ // if there is no tgpd, atach a bypass tgpd
+ uart_en_q_de_q_with_mutex(port, UART_TX, UART_EN_Q_LIGHT, ((tty_io_request_t *) putIor)->first_gpd, ((tty_io_request_t *) putIor)->last_gpd);
+ if(((tty_io_request_t *) p_ior)->next_request == NULL)
+ {
+ break;
+ } else
+ {
+ p_ior = ((tty_io_request_t *) p_ior)->next_request;
+ }
+ }
+
+ return 0;
+}
+
+kal_uint32 UART_GetBytesIor(UART_PORT port, void *ior)
+{
+ void *p_ior;
+
+ if(port >= MAX_UART_PORT_NUM)
+ return 0;
+
+ p_ior = ior;
+ while(1)
+ {
+ uart_en_q_de_q_with_mutex(port, UART_RX, UART_EN_Q, ((tty_io_request_t *) p_ior)->first_gpd, ((tty_io_request_t *) p_ior)->last_gpd);
+ if(((tty_io_request_t *) p_ior)->next_request == NULL)
+ {
+ break;
+ } else
+ {
+ p_ior = ((tty_io_request_t *) p_ior)->next_request;
+ }
+ }
+
+ return 0;
+}
+
+
+void UART_DriverInit(UART_PORT port)
+{
+ module_type ownerid;
+ static kal_bool b_uart_custom_init = KAL_FALSE;
+ kal_bool Is_OpenUart = KAL_TRUE;
+
+ ownerid = (MOD_UART1_HISR + port);
+
+ // Customization
+ if(b_uart_custom_init == KAL_FALSE)
+ {
+ uart_customize_init();
+ b_uart_custom_init = KAL_TRUE;
+ }
+
+ if(Is_OpenUart == KAL_TRUE)
+ {
+ UART_HWInit(port);
+
+ pUart_CMD_FUNC[port]= &UartDriver;
+
+ U_Open(port, ownerid);
+ }
+
+ // create mutex
+ if(mutex_status == KAL_FALSE && !INT_QueryExceptionStatus())
+ {
+ mutexid = kal_create_mutex("DRV_UART");
+ mutex_status = KAL_TRUE;
+ }
+}
+
+void UART_SetNeedTxDoneCb(UART_PORT port, kal_bool needTxDoneCb, module_type ownerid)
+{
+ UARTPort[port].need_tx_done_cb = needTxDoneCb;
+}
+
+kal_uint32 uart_cal_tgpd_buf_length(void *head, void *tail)
+{
+ void *gpd_cur, *bd_cur;
+ kal_uint32 sum = 0;
+
+ if(head == NULL || tail == NULL)
+ return 0;
+
+ gpd_cur = head;
+ while(1)
+ {
+ if(QBM_DES_GET_BPS(gpd_cur) == 0)
+ {
+ if(QBM_DES_GET_BDP(gpd_cur))
+ {
+ bd_cur = QBM_DES_GET_DATAPTR(gpd_cur);
+ while(1)
+ {
+ sum += QBM_DES_GET_DATALEN(bd_cur);
+
+ if(QBM_DES_GET_EOL(bd_cur)) {break;}
+ else {bd_cur = QBM_DES_GET_NEXT(bd_cur);}
+ }
+ } else
+ {
+ sum += QBM_DES_GET_DATALEN(gpd_cur);
+ }
+ }
+
+ if(gpd_cur == tail) {return sum;}
+ else {gpd_cur = QBM_DES_GET_NEXT(gpd_cur);}
+ }
+}
+
+void uart_en_q_de_q_with_mutex(UART_PORT port, kal_bool tx_or_rx, kal_uint8 en_q_or_de_q, void *p_ior_head, void *p_ior_tail)
+{
+ void *p_gpd_head = NULL;
+ void *p_gpd_tail = NULL;
+ void *p_gpd_cur = NULL;
+ kal_uint32 queue_len = 0;
+ tty_io_request_t *ior = NULL;
+if(!kal_if_hisr()){
+ // lock mutex
+ kal_take_mutex(mutexid);
+}
+ DCL_HANDLE handle = DclSerialPort_Open(port, 0);
+
+ if(tx_or_rx == (kal_bool) UART_TX)
+ {
+ if(en_q_or_de_q == UART_EN_Q)
+ {
+
+ uart_cal_chksum_and_flush_gpd_list(p_ior_head, p_ior_tail);
+
+ if(uart_wait_tgpd_head[port] == NULL && uart_wait_tgpd_tail[port] == NULL)
+ {
+ uart_wait_tgpd_head[port] = p_ior_head;
+ uart_wait_tgpd_tail[port] = p_ior_tail;
+ } else
+ {
+ qbmt_common_en_q_rx(p_ior_head, p_ior_tail, (void **) &uart_wait_tgpd_head[port], (void **) &uart_wait_tgpd_tail[port]);
+ }
+ } else if(en_q_or_de_q == UART_EN_Q_LIGHT)
+ {
+ if(uart_wait_tgpd_head[port] == NULL && uart_wait_tgpd_tail[port] == NULL)
+ {
+ uart_wait_tgpd_head[port] = p_ior_head;
+ uart_wait_tgpd_tail[port] = p_ior_tail;
+ } else
+ {
+ qbmt_common_en_q_rx(p_ior_head, p_ior_tail, (void **) &uart_wait_tgpd_head[port], (void **) &uart_wait_tgpd_tail[port]);
+ }
+ } else
+ {
+ if(uart_tgpd_head[port] != NULL)
+ {
+ if(en_q_or_de_q == UART_DE_Q)
+ {
+ queue_len = qbmt_de_q((void **) &uart_tgpd_head[port], (void **) &uart_tgpd_tail[port], (void **) &p_gpd_head, (void **) &p_gpd_tail);
+ } else if(en_q_or_de_q == UART_DE_Q_ALL)
+ {
+#if defined(META_MODE_SW_ESCAPING)
+ if(kal_query_boot_mode() != FACTORY_BOOT)
+#endif
+ {
+ HDMA_BUF0_STOP((2 + port));
+ }
+ uart_clear_hwo_of_gpd_list(uart_tgpd_head[port], uart_tgpd_tail[port]);
+ queue_len = qbmt_de_q((void **) &uart_tgpd_head[port], (void **) &uart_tgpd_tail[port], (void **) &p_gpd_head, (void **) &p_gpd_tail);
+ QBM_FREE_ONE(uart_tgpd_head[port]);
+
+ if(uart_wait_tgpd_head[port] != NULL)
+ {
+ if(queue_len > 0)
+ {
+ qbmt_common_en_q_rx(uart_wait_tgpd_head[port], uart_wait_tgpd_tail[port], (void **) &p_gpd_head, (void **) &p_gpd_tail);
+ } else
+ {
+ p_gpd_head = uart_wait_tgpd_head[port];
+ p_gpd_tail = uart_wait_tgpd_tail[port];
+ queue_len = 1;
+ }
+ uart_clear_hwo_of_gpd_list(p_gpd_head, p_gpd_tail);
+ }
+
+ uart_tgpd_head[port] = NULL;
+ uart_tgpd_tail[port] = NULL;
+ uart_wait_tgpd_head[port] = NULL;
+ uart_wait_tgpd_tail[port] = NULL;
+ } else ASSERT(0);
+
+ if(queue_len > 0)
+ {
+ if(UARTPort[port].need_tx_done_cb)
+ {
+ ior = (tty_io_request_t *) QBM_DES_GET_SW_CTRL_FIELD(p_gpd_head);
+ ior->first_gpd = p_gpd_head;
+ ior->last_gpd = p_gpd_tail;
+ ior->next_request = NULL;
+ DclSerialPort_DrvTxDone(handle, kal_get_active_module_id(), ior);
+ } else
+ {
+ qbmt_dest_q((void *) p_gpd_head, (void *) p_gpd_tail);
+ }
+ }
+ }
+ }
+ } else
+ {
+ if(en_q_or_de_q == (kal_bool) UART_EN_Q)
+ {
+ if(uart_rgpd_head[port] == NULL && uart_rgpd_tail[port] == NULL)
+ {
+ uart_cal_chksum_and_flush_gpd_list(p_ior_head, p_ior_tail);
+
+ QBM_DES_CLR_HWO(p_ior_tail);
+ QBM_CACHE_FLUSH((void *) p_ior_tail, QBM_SIZE_GPD_BD_TST);
+ HDMA_BUF0_PROG_ADDR_CONFIG((3 + port), p_ior_head);
+ uart_rgpd_head[port] = p_ior_head;
+ uart_rgpd_tail[port] = p_ior_tail;
+ HDMA_BUF0_START((3 + port));
+ }else{
+ qbmt_common_en_q_rx(p_ior_head, p_ior_tail, (void **) &uart_rgpd_head[port], (void **) &uart_rgpd_tail[port]);
+ uart_cal_chksum_and_flush_gpd_list(uart_rgpd_head[port], uart_rgpd_tail[port]);
+ QBM_DES_CLR_HWO(uart_rgpd_tail[port]);
+ QBM_CACHE_FLUSH((void *) uart_rgpd_tail[port], QBM_SIZE_GPD_BD_TST);
+
+ HDMA_BUF0_RESUME((3 + port));
+ }
+ } else
+ {
+ if(uart_rgpd_head[port] == NULL)
+ {
+ if(!kal_if_hisr()){
+ kal_give_mutex(mutexid);
+ }
+ return;
+ } else
+ {
+ if(en_q_or_de_q == UART_DE_Q)
+ {
+ queue_len = qbmt_de_q((void **) &uart_rgpd_head[port], (void **) &uart_rgpd_tail[port], (void **) &p_gpd_head, (void **) &p_gpd_tail);
+ } else if(en_q_or_de_q == UART_DE_Q_ALL)
+ {
+ // stop q
+ HDMA_BUF0_STOP((port + 3));
+ // de-Q all GPDs
+ p_gpd_head = uart_rgpd_head[port];
+ p_gpd_tail = uart_rgpd_tail[port];
+ uart_rgpd_head[port] = NULL;
+ uart_rgpd_tail[port] = NULL;
+ queue_len = 1; // not real queue length
+ }
+
+ if(p_gpd_head != NULL && p_gpd_tail != NULL && queue_len > 0)
+ {
+#if defined(META_MODE_SW_ESCAPING) && !defined(UART_SIM_QMU)
+ if(kal_query_boot_mode() == FACTORY_BOOT){
+ UART_META_ExBytes(port, p_gpd_head, p_gpd_tail);
+ }
+#endif
+ ior = (tty_io_request_t *) QBM_DES_GET_SW_CTRL_FIELD(p_gpd_head);
+ ior->first_gpd = p_gpd_head;
+ ior->last_gpd = p_gpd_tail;
+ ior->next_request = NULL;
+ DclSerialPort_DrvRx(handle, kal_get_active_module_id(), ior); // need to modify
+ }
+ }
+ }
+ }
+
+ if(uart_wait_tgpd_head[port] != NULL && uart_wait_tgpd_tail[port] != NULL && !(DRV_Reg32(UART_LCR(UART_BaseAddr[port])) & UART_LCR_BREAK))
+ {
+ if(uart_tgpd_head[port] == NULL && uart_tgpd_tail[port] == NULL)
+ {
+ uart_tgpd_head[port] = uart_wait_tgpd_head[port];
+ uart_tgpd_tail[port] = uart_wait_tgpd_tail[port];
+
+ // connect a BPS GPD to the tail
+ qbmt_alloc_q(QBM_TYPE_TGPD_BPS, 1, (void **) &p_gpd_cur, (void **) &p_gpd_cur);
+ ASSERT(p_gpd_cur!= NULL);
+
+ qbmt_common_en_q_rx(p_gpd_cur, p_gpd_cur, (void **) &uart_tgpd_head[port], (void **) &uart_tgpd_tail[port]);
+#if defined(META_MODE_SW_ESCAPING)
+ if(kal_query_boot_mode() == FACTORY_BOOT){
+ UART_META_PutBytes(port,uart_tgpd_head[port], uart_tgpd_tail[port]);
+ }else
+#endif
+ {
+ HDMA_BUF0_PROG_ADDR_CONFIG((2 + port), uart_tgpd_head[port]);
+ HDMA_BUF0_START((2 + port));
+ }
+ uart_wait_tgpd_head[port] = NULL;
+ uart_wait_tgpd_tail[port] = NULL;
+ } else if(QBM_DES_GET_BPS(uart_tgpd_head[port]) && QBM_DES_GET_BPS(uart_tgpd_tail[port]))
+ {
+ QBM_FREE_ONE(uart_tgpd_head[port]);
+
+ uart_tgpd_head[port] = uart_wait_tgpd_head[port];
+ uart_tgpd_tail[port] = uart_wait_tgpd_tail[port];
+
+ // connect a BPS GPD to the tail
+ qbmt_alloc_q(QBM_TYPE_TGPD_BPS, 1, (void **) &p_gpd_cur, (void **) &p_gpd_cur);
+ ASSERT(p_gpd_cur!= NULL);
+ qbmt_common_en_q_rx(p_gpd_cur, p_gpd_cur, (void **) &uart_tgpd_head[port], (void **) &uart_tgpd_tail[port]);
+#if defined(META_MODE_SW_ESCAPING)
+ if(kal_query_boot_mode() == FACTORY_BOOT){
+ UART_META_PutBytes(port,uart_wait_tgpd_head[port], uart_wait_tgpd_tail[port]);
+ }else
+#endif
+ {
+ HDMA_BUF0_PROG_ADDR_CONFIG((2 + port), uart_wait_tgpd_head[port]);
+ HDMA_BUF0_START((2 + port));
+ }
+ uart_wait_tgpd_head[port] = NULL;
+ uart_wait_tgpd_tail[port] = NULL;
+ }
+ }
+ if(!kal_if_hisr()){
+ // unlock mutex
+ kal_give_mutex(mutexid);
+ }
+ return;
+}
+
+
+void uart_qbm_virt_to_phy(void** pp_gpd_head, void** pp_gpd_tail)
+{
+ void *gpd_ptr = NULL, *gpd_ptr_tmp = NULL;
+ void *bd_ptr = NULL, *bd_ptr_tmp = NULL;;
+ void *pgd_data_ptr = NULL, *bd_data_ptr = NULL;
+
+ *pp_gpd_head = (void*)virt_to_phys(*pp_gpd_head);
+ gpd_ptr = *pp_gpd_head;
+ while(1)
+ {
+ if(QBM_DES_GET_BDP(gpd_ptr))
+ {
+ bd_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+ bd_ptr = (void*)virt_to_phys(bd_ptr);
+ QBM_DES_SET_DATAPTR(gpd_ptr,bd_ptr);
+ qbm_cal_set_checksum_by_len((const kal_uint8 *)gpd_ptr, 12);
+ while(1)
+ {
+ bd_data_ptr = QBM_DES_GET_DATAPTR(bd_ptr);
+ bd_data_ptr = (void*)virt_to_phys(bd_data_ptr);
+ QBM_DES_SET_DATAPTR(bd_ptr,bd_data_ptr);
+ if(QBM_DES_GET_EOL(bd_ptr))
+ {
+ break;
+ } else
+ {
+ bd_ptr_tmp = (void*)QBM_DES_GET_NEXT(bd_ptr);
+ bd_ptr_tmp = (void*)virt_to_phys(bd_ptr_tmp);
+ QBM_DES_SET_NEXT(bd_ptr,bd_ptr_tmp);
+ qbm_cal_set_checksum_by_len((const kal_uint8 *)bd_ptr, 12);
+ bd_ptr = QBM_DES_GET_NEXT(bd_ptr);
+ }
+ }
+ } else
+ {
+ pgd_data_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+ pgd_data_ptr = (void*)virt_to_phys(pgd_data_ptr);
+ QBM_DES_SET_DATAPTR(gpd_ptr,pgd_data_ptr);
+ }
+
+ if(gpd_ptr == *pp_gpd_tail)
+ {
+ break;
+ } else
+ {
+ gpd_ptr_tmp = (void*)QBM_DES_GET_NEXT(gpd_ptr);
+ gpd_ptr_tmp = (void*)virt_to_phys(gpd_ptr_tmp);
+ QBM_DES_SET_NEXT(gpd_ptr,gpd_ptr_tmp);
+ qbm_cal_set_checksum_by_len((const kal_uint8 *) gpd_ptr, 12);
+ gpd_ptr = QBM_DES_GET_NEXT(gpd_ptr);
+ }
+
+ }
+
+}
+
+void uart_qbm_phy_to_virt(void**pp_gpd_head, void**pp_gpd_tail)
+{
+ void *gpd_ptr = NULL, *gpd_ptr_tmp = NULL;
+ void *bd_ptr = NULL, *bd_ptr_tmp = NULL;;
+ void *pgd_data_ptr = NULL, *bd_data_ptr = NULL;
+
+
+ *pp_gpd_head = (void*)phys_to_virt(*pp_gpd_head);
+ QBM_CACHE_INVALID(*pp_gpd_head, QBM_SIZE_TGPD);
+ gpd_ptr = *pp_gpd_head;
+ *pp_gpd_tail = (void*)phys_to_virt(*pp_gpd_tail);
+ QBM_CACHE_INVALID(*pp_gpd_tail, QBM_SIZE_TGPD);
+ while(1)
+ {
+ if(QBM_DES_GET_BDP(gpd_ptr))
+ {
+ bd_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+ bd_ptr = (void*)phys_to_virt(bd_ptr);
+ QBM_CACHE_INVALID(bd_ptr, QBM_SIZE_TBD);
+ QBM_DES_SET_DATAPTR(gpd_ptr,bd_ptr);
+
+ while(1)
+ {
+ bd_data_ptr = QBM_DES_GET_DATAPTR(bd_ptr);
+ bd_data_ptr = (void*)phys_to_virt(bd_data_ptr);
+ QBM_CACHE_INVALID(bd_data_ptr, QBM_SIZE_CACHE_ALIGN(QBM_DES_GET_DATALEN(bd_data_ptr)));
+ QBM_DES_SET_DATAPTR(bd_ptr,bd_data_ptr);
+
+ if(QBM_DES_GET_EOL(bd_ptr))
+ {
+ break;
+ } else
+ {
+ bd_ptr_tmp = (void*)QBM_DES_GET_NEXT(bd_ptr);
+ bd_ptr_tmp = (void*)phys_to_virt(bd_ptr_tmp);
+ QBM_CACHE_INVALID(bd_ptr_tmp, QBM_SIZE_TBD);
+ QBM_DES_SET_NEXT(bd_ptr,bd_ptr_tmp);
+ bd_ptr = QBM_DES_GET_NEXT(bd_ptr);
+ }
+ }
+ } else
+ {
+ pgd_data_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+ pgd_data_ptr = (void*)phys_to_virt(pgd_data_ptr);
+ QBM_CACHE_INVALID(pgd_data_ptr, QBM_SIZE_CACHE_ALIGN(QBM_DES_GET_DATALEN(pgd_data_ptr)));
+ QBM_DES_SET_DATAPTR(gpd_ptr,pgd_data_ptr);
+ }
+
+ if(gpd_ptr == *pp_gpd_tail)
+ {
+ break;
+ } else
+ {
+ gpd_ptr_tmp = (void*)QBM_DES_GET_NEXT(gpd_ptr);
+ gpd_ptr_tmp = (void*)phys_to_virt(gpd_ptr_tmp);
+ QBM_CACHE_INVALID(gpd_ptr_tmp, QBM_SIZE_TGPD);
+ QBM_DES_SET_NEXT(gpd_ptr,gpd_ptr_tmp);
+ gpd_ptr = QBM_DES_GET_NEXT(gpd_ptr);
+ }
+
+ }
+
+}
+
+void UART_META_PutBytes(UART_PORT port, void * gpd_head, void * gpd_tail){
+ hdma_tbd_t *bd_ptr = NULL, *p_bd_cur =NULL;
+ hdma_tgpd_t *gpd_ptr = NULL;
+ kal_uint8 gpd_ext_len=0, bd_ext_len=0;
+ kal_uint32 gpd_data_len=0, bd_data_len=0;
+ kal_uint8 *gpd_ext_ptr=NULL, *gpd_data_ptr=NULL, *bd_ext_ptr=NULL, *bd_data_ptr=NULL;
+
+ gpd_ptr = (hdma_tgpd_t*)gpd_head;
+ while(1){
+ if(QBM_DES_GET_HWO(gpd_ptr)==0){
+ break;
+ }
+ if(QBM_DES_GET_BPS(gpd_ptr)){
+ QBM_DES_CLR_HWO(gpd_ptr);
+ QBM_CACHE_FLUSH(gpd_ptr, QBM_SIZE_TGPD);
+ goto next;
+ }
+ if (QBM_DES_GET_EXTLEN(gpd_ptr)) {
+ gpd_ext_len = QBM_DES_GET_EXTLEN(gpd_ptr);
+ gpd_ext_ptr = QBM_DES_GET_EXT(gpd_ptr);
+ PutUARTDatas(port, UART_ESCAPE_CHAR, gpd_ext_ptr,gpd_ext_len);
+ //U_SendData(port, gpd_ext_ptr, gpd_ext_len, FACTORY_BOOT, UART_ESCAPE_CHAR, UARTPort[port].ownerid);
+ }
+ if (QBM_DES_GET_BDP(gpd_ptr)) {
+ bd_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+ p_bd_cur = bd_ptr;
+ while (1) {
+ if (QBM_DES_GET_EXTLEN(p_bd_cur)) {
+ bd_ext_len = QBM_DES_GET_EXTLEN(p_bd_cur);
+ bd_ext_ptr = QBM_DES_GET_EXT(p_bd_cur);
+ PutUARTDatas(port, UART_ESCAPE_CHAR, bd_ext_ptr,bd_ext_len);
+ //U_SendData(port, bd_ext_ptr, bd_ext_len, FACTORY_BOOT, UART_ESCAPE_CHAR, UARTPort[port].ownerid);
+
+ }
+ if (QBM_DES_GET_DATALEN(p_bd_cur)) {
+ bd_data_len = QBM_DES_GET_DATALEN(p_bd_cur);
+ bd_data_ptr = QBM_DES_GET_DATAPTR(p_bd_cur);
+ PutUARTDatas(port, UART_ESCAPE_CHAR, bd_data_ptr,bd_data_len);
+ //U_SendData(port, bd_data_ptr, bd_data_len, FACTORY_BOOT, UART_ESCAPE_CHAR, UARTPort[port].ownerid);
+ }
+ if (QBM_DES_GET_EOL(p_bd_cur)) {
+ break;
+ }
+ p_bd_cur = (void *)QBM_DES_GET_NEXT(p_bd_cur);
+ }
+ } else{
+
+ gpd_data_len = QBM_DES_GET_DATALEN(gpd_ptr);
+ gpd_data_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+ PutUARTDatas(port, UART_ESCAPE_CHAR, gpd_data_ptr,gpd_data_len);
+ //U_SendData(port, gpd_data_ptr, gpd_data_len, FACTORY_BOOT, UART_ESCAPE_CHAR, UARTPort[port].ownerid);
+ }
+
+ QBM_DES_CLR_HWO(gpd_ptr);
+ QBM_CACHE_FLUSH(gpd_ptr, QBM_SIZE_TGPD);
+ if(gpd_ptr == gpd_tail)
+ {
+ break;
+ } else
+ {
+next:
+ gpd_ptr = (void *) QBM_DES_GET_NEXT(gpd_ptr);
+ }
+ }
+
+ /* Cooperate with Non-Blocking CACHE API */
+ MM_Sync();
+}
+
+
+void uart_cal_chksum_and_flush_gpd_list(void * gpd_head, void * gpd_tail)
+{
+ hdma_tbd_t *gpd_ptr = NULL, *bd_ptr = NULL;
+ void *pgd_data_ptr = NULL, *bd_data_ptr = NULL;
+
+ gpd_ptr = (hdma_tbd_t*)gpd_head;
+ while(1)
+ {
+ QBM_DES_SET_HWO(gpd_ptr);
+#if !defined(__DRVTEST_SW_DOMAIN__)
+ qbm_cal_set_checksum_by_len((const kal_uint8 *) gpd_ptr, 12);
+#endif
+ QBM_CACHE_FLUSH((void *) gpd_ptr, QBM_SIZE_TGPD);
+
+ if(QBM_DES_GET_BDP(gpd_ptr))
+ {
+ bd_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+ while(1)
+ {
+#if !defined(__DRVTEST_SW_DOMAIN__)
+ qbm_cal_set_checksum_by_len((const kal_uint8 *) bd_ptr, 12);
+#endif
+ QBM_CACHE_FLUSH((void *) bd_ptr, QBM_SIZE_TBD);
+ bd_data_ptr = QBM_DES_GET_DATAPTR(bd_ptr);
+ QBM_CACHE_FLUSH((void *) bd_data_ptr, QBM_DES_GET_DATALEN(bd_ptr));
+
+ if(QBM_DES_GET_EOL(bd_ptr))
+ {
+ break;
+ } else
+ {
+ bd_ptr = (void *) QBM_DES_GET_NEXT(bd_ptr);
+ }
+ }
+ } else
+ {
+ pgd_data_ptr = QBM_DES_GET_DATAPTR(gpd_ptr);
+ QBM_CACHE_FLUSH((void *) pgd_data_ptr, QBM_DES_GET_DATALEN(gpd_ptr));
+ }
+
+ if(gpd_ptr == gpd_tail)
+ {
+ break;
+ } else
+ {
+ gpd_ptr = (void *) QBM_DES_GET_NEXT(gpd_ptr);
+ }
+
+ }
+
+ /* Cooperate with Non-Blocking CACHE API */
+ MM_Sync();
+}
+
+void uart_clear_hwo_of_gpd_list(void *gpd_head, void *gpd_tail)
+{
+ hdma_tbd_t *gpd_ptr = NULL;//, *bd_ptr = NULL;
+
+ gpd_ptr = gpd_head;
+ while(1)
+ {
+ QBM_DES_CLR_HWO(gpd_ptr);
+ QBM_CACHE_FLUSH(gpd_ptr, QBM_SIZE_GPD_BD_TST);
+
+ if(gpd_ptr == gpd_tail)
+ {
+ break;
+ } else
+ {
+ gpd_ptr = (void *) QBM_DES_GET_NEXT(gpd_ptr);
+ }
+ }
+
+ /* Cooperate with Non-Blocking CACHE API */
+ MM_Sync();
+}
+
+typedef struct _uart_bps_gpd_pool {
+ void *gpd_head;
+ void *gpd_tail;
+ kal_uint32 free_num;
+ kal_uint32 alloc_ok_cnt;
+ kal_uint32 alloc_fail_cnt;
+ kal_uint32 free_ok_cnt;
+ void *buffer_start;
+ void *buffer_end;
+ kal_uint32 total_num;
+} uart_bps_gpd_pool;
+
+static void *uart_discard_tgpd_head = NULL;
+static void *uart_discard_tgpd_tail = NULL;
+static void *uart_discard_rgpd_head = NULL;
+static void *uart_discard_rgpd_tail = NULL;
+static kal_uint32 uart_excpt_tx_bytes[MAX_UART_PORT_NUM];
+static kal_uint32 uart_excpt_rx_bytes[MAX_UART_PORT_NUM];
+static uart_bps_gpd_pool uart_bps_gpd_pool_info;
+
+extern void uart_cal_chksum_and_flush_gpd_list(void *gpd_head, void *gpd_tail);
+
+
+kal_bool uart_except_init_qbm()
+{
+ uart_bps_gpd_pool *gpd_pool = &uart_bps_gpd_pool_info;
+ bm_queue_config conf;
+ kal_uint32 ret;
+
+ qbm_init_q_config(&conf);
+
+ conf.buff_num = UART_ECPT_QBM_BPS_NUM;
+ conf.p_mem_pool_str = uart_ecpt_bps_buf;
+ conf.p_mem_pool_end = conf.p_mem_pool_str + UART_ECPT_QBM_BPS_BUF_SZ;
+ ret = qbm_init_queue_non_free(QBM_TYPE_TGPD_BPS, &conf,
+ &gpd_pool->gpd_head,
+ &gpd_pool->gpd_tail);
+ if(QBM_ERROR_OK != ret)
+ return KAL_FALSE;
+
+ gpd_pool->buffer_start = conf.p_mem_pool_str;
+ gpd_pool->buffer_end = conf.p_mem_pool_end;
+ gpd_pool->total_num = conf.buff_num;
+ gpd_pool->free_num = conf.buff_num;
+
+ return KAL_TRUE;
+}
+
+kal_bool uart_except_check_bps_gpd(void *p_gpd)
+{
+ kal_uint8* uart_bps_buf;
+
+ uart_bps_buf = uart_ecpt_bps_buf;
+
+ if (((kal_uint8 *)p_gpd >= uart_bps_buf) && ((kal_uint8 *)p_gpd < uart_bps_buf + UART_ECPT_QBM_BPS_BUF_SZ)){
+ return KAL_TRUE;
+ }
+ return KAL_FALSE;
+}
+
+void uart_except_free_bps_gpd(void *p_gpd)
+{
+ uart_bps_gpd_pool *gpd_pool = &uart_bps_gpd_pool_info;
+
+ ASSERT(uart_except_check_bps_gpd(p_gpd));
+
+ if (gpd_pool->gpd_head == NULL) {
+ gpd_pool->gpd_head = gpd_pool->gpd_tail = p_gpd;
+ } else {
+ QBM_DES_SET_NEXT(gpd_pool->gpd_tail, p_gpd);
+ gpd_pool->gpd_tail = p_gpd;
+ }
+
+ gpd_pool->free_num ++;
+ gpd_pool->free_ok_cnt ++;
+}
+
+void *uart_except_alloc_bps_gpd(kal_bool tx_or_rx)
+{
+ void *p_ret_gpd;
+ uart_bps_gpd_pool *gpd_pool = &uart_bps_gpd_pool_info;
+
+ if (gpd_pool->gpd_head == NULL) {
+ gpd_pool->alloc_fail_cnt ++;
+ return NULL;
+ }
+
+ p_ret_gpd = gpd_pool->gpd_head;
+ if (gpd_pool->gpd_head == gpd_pool->gpd_tail) {
+ gpd_pool->gpd_head = gpd_pool->gpd_tail = NULL;
+ } else {
+ gpd_pool->gpd_head = QBM_DES_GET_NEXT(gpd_pool->gpd_head);
+ }
+
+ gpd_pool->free_num --;
+ gpd_pool->alloc_ok_cnt ++;
+
+ QBM_DES_SET_NEXT(p_ret_gpd, NULL);
+
+ //QBM_DES_SET_BPS(p_ret_gpd);
+
+ return p_ret_gpd;
+}
+
+kal_uint32 uart_except_free_bps_gpd_in_list(void **pp_head, void **pp_tail)
+{
+ void *p_gpd_cur, *p_gpd_pre, *p_gpd_nex;
+ int free_num = 0;
+
+ p_gpd_cur = *pp_head;
+ p_gpd_pre = NULL;
+
+ if (*pp_head == NULL || *pp_tail == NULL)
+ return 0;
+
+ while (1) {
+ p_gpd_nex = QBM_DES_GET_NEXT(p_gpd_cur);
+ if (uart_except_check_bps_gpd(p_gpd_cur)) {
+ /* free this gpd from list */
+ if (p_gpd_pre == NULL)
+ *pp_head = p_gpd_nex;
+ else
+ QBM_DES_SET_NEXT(p_gpd_pre, p_gpd_nex);
+
+ uart_except_free_bps_gpd(p_gpd_cur);
+ free_num ++;
+ } else {
+ p_gpd_pre = p_gpd_cur;
+ }
+
+ if(p_gpd_cur == *pp_tail)
+ break;
+
+ p_gpd_cur = p_gpd_nex;
+ }
+
+ return free_num;
+}
+
+void uart_except_en_q_rx(
+ void *p_new_head,
+ void *p_new_tail,
+ void **pp_orig_head,
+ void **pp_orig_tail
+ )
+{
+ void *p_orig_tail = NULL;
+
+ ASSERT(pp_orig_head!=NULL);
+ ASSERT(pp_orig_tail!=NULL);
+ if (*pp_orig_head != NULL) {
+ p_orig_tail = *pp_orig_tail;
+
+ /* set new tail's HWO=0 */
+ QBM_DES_CLR_HWO(p_new_tail);
+ QBM_CACHE_FLUSH(p_new_tail, QBM_SIZE_TGPD);
+
+ /* link new list to tail of orig list */
+ QBM_DES_SET_NEXT(p_orig_tail, p_new_head);
+
+ /* re-calc the orig tail's checksum */
+#if !defined(__DRVTEST_SW_DOMAIN__)
+ qbm_cal_set_checksum_wth_hwo(p_orig_tail);
+#endif
+
+ /* set the orig tail's HWO=1 */
+ QBM_DES_SET_HWO(p_orig_tail);
+ QBM_CACHE_FLUSH(p_orig_tail, QBM_SIZE_TGPD);
+
+ /* update the orig tail */
+ *pp_orig_tail = p_new_tail;
+ } else {
+ *pp_orig_head = p_new_head;
+ *pp_orig_tail = p_new_tail;
+ }
+}
+/* the last gpd will not be de-queued */
+kal_uint32 uart_except_de_q(
+ void **pp_src_head,
+ void **pp_src_tail,
+ void **pp_new_head,
+ void **pp_new_tail
+ )
+{
+ kal_uint32 deqno = 0;
+ void *p_this_gpd = NULL;
+ *pp_new_head = NULL;
+ *pp_new_tail = NULL;
+
+ if (pp_src_head != NULL && *pp_src_head != NULL && *pp_src_head != *pp_src_tail) {
+ p_this_gpd = *pp_src_head;
+ QBM_CACHE_INVALID(p_this_gpd, QBM_SIZE_TGPD);
+ if (!QBM_DES_GET_HWO(p_this_gpd)){
+ *pp_new_head = p_this_gpd;
+
+ while(!QBM_DES_GET_HWO(p_this_gpd) && p_this_gpd != *pp_src_tail) {
+ *pp_new_tail = p_this_gpd;
+ deqno ++;
+
+ p_this_gpd = QBM_DES_GET_NEXT(p_this_gpd);
+ QBM_CACHE_INVALID(p_this_gpd, QBM_SIZE_TGPD);
+ }
+
+ *pp_src_head = p_this_gpd;
+ }
+ }
+
+ return deqno;
+}
+
+kal_uint32 uart_except_de_q_with_timeout(
+ UART_PORT port,
+ void **pp_src_head,
+ void **pp_src_tail,
+ void **pp_new_head,
+ void **pp_new_tail
+ )
+{
+ kal_uint32 deqno = 0;
+ void *p_this_gpd = NULL;
+ *pp_new_head = NULL;
+ *pp_new_tail = NULL;
+
+ if (pp_src_head != NULL && *pp_src_head != NULL && *pp_src_head != *pp_src_tail) {
+ p_this_gpd = *pp_src_head;
+ QBM_CACHE_INVALID(p_this_gpd, QBM_SIZE_TGPD);
+ if (!QBM_DES_GET_HWO(p_this_gpd)){
+ *pp_new_head = p_this_gpd;
+
+ while(!QBM_DES_GET_HWO(p_this_gpd) && p_this_gpd != *pp_src_tail) {
+ *pp_new_tail = p_this_gpd;
+ deqno ++;
+
+ p_this_gpd = QBM_DES_GET_NEXT(p_this_gpd);
+ QBM_CACHE_INVALID(p_this_gpd, QBM_SIZE_TGPD);
+ }
+
+ *pp_src_head = p_this_gpd;
+ uart_ecpt_timer_reset(port);
+ }else{
+ uart_ecpt_timer_start(port);
+ }
+ }
+
+ return deqno;
+}
+
+DCL_STATUS uart_except_check_dma_status(kal_uint32 hdma_channel)
+{
+ kal_uint32 int_sts;
+ DCL_STATUS ret_sts = STATUS_OK;
+
+ int_sts = DRV_Reg32(GDMA_GISAR_UART);
+
+ if(IS_HDMA_LENERR_INTR(int_sts, hdma_channel)) {
+ DRV_WriteReg32(GDMA_GISAR_UART, (HDMA_INTR_CHL_MASK(hdma_channel) << 16));
+ ret_sts = STATUS_FAIL;
+ }
+
+ if(IS_HDMA_BD_CSERR_INTR(int_sts, hdma_channel)) {
+ DRV_WriteReg32(GDMA_GISAR_UART, (HDMA_INTR_CHL_MASK(hdma_channel) << 24));
+ ret_sts = STATUS_ERROR_CRCERROR;
+ }
+
+ if(IS_HDMA_GPD_CSERR_INTR(int_sts, hdma_channel)) {
+ DRV_WriteReg32(GDMA_GISAR_UART, (HDMA_INTR_CHL_MASK(hdma_channel) << 28));
+ ret_sts = STATUS_ERROR_CRCERROR;
+ }
+
+ return ret_sts;
+}
+
+DCL_STATUS
+uart_en_q_de_q_for_ecpt(
+ UART_PORT port,
+ kal_bool tx_or_rx,
+ kal_uint8 en_q_or_de_q,
+ void **pp_gpd_head,
+ void **pp_gpd_tail,
+ kal_uint32 *p_num
+)
+{
+ void *p_gpd_head, *p_gpd_tail; /* work queue */
+ void *p_bps_gpd;
+ kal_uint32 deq_num;
+ DCL_STATUS ret = STATUS_OK;
+ kal_uint32 hdma_ch;
+ kal_uint32 xfer_bytes;
+
+ ASSERT(pp_gpd_head != NULL);
+ ASSERT(pp_gpd_tail != NULL);
+
+ /* get global variable to local variable */
+ if (tx_or_rx == (kal_bool)UART_TX) {
+ p_gpd_head = uart_tgpd_head[port];
+ p_gpd_tail = uart_tgpd_tail[port];
+ } else {
+ p_gpd_head = uart_rgpd_head[port];
+ p_gpd_tail = uart_rgpd_tail[port];
+ }
+
+ hdma_ch = (tx_or_rx == (kal_bool)UART_TX)?port+2:port+3;
+
+ if (en_q_or_de_q == UART_EN_Q) {
+ if (*pp_gpd_head == NULL || *pp_gpd_tail == NULL) {
+ goto end;
+ }
+
+ /* alloc a bypass gpd */
+ if (tx_or_rx == (kal_bool)UART_TX) {
+ p_bps_gpd = uart_except_alloc_bps_gpd(tx_or_rx);
+ if (p_bps_gpd == NULL) {
+ ret = STATUS_FAIL;
+ goto end;
+ }
+
+ /* append the bypass gpd to the gpd list */
+ QBM_DES_SET_NEXT(*pp_gpd_tail, p_bps_gpd);
+ *pp_gpd_tail = p_bps_gpd;
+ } else {
+ QBM_DES_CLR_HWO(*pp_gpd_tail);
+ }
+
+ /* re-calc checksum and flush cache */
+ uart_cal_chksum_and_flush_gpd_list(*pp_gpd_head, *pp_gpd_tail);
+
+ /* now, start en-q operation */
+ if (p_gpd_head == NULL) {
+ /* clear tail's HWO bit manually */
+ QBM_DES_CLR_HWO(*pp_gpd_tail);
+ QBM_CACHE_FLUSH(*pp_gpd_tail, QBM_SIZE_TGPD_BPS);
+
+ p_gpd_head = *pp_gpd_head;
+ p_gpd_tail = *pp_gpd_tail;
+#if defined(META_MODE_SW_ESCAPING)
+ if((kal_query_boot_mode() == FACTORY_BOOT) && (tx_or_rx ==(kal_bool)UART_TX)){
+ UART_META_PutBytes(port, p_gpd_head, p_gpd_tail);
+ }else
+#endif
+ {
+ /* newly configure and start DMA */
+ HDMA_BUF0_PROG_ADDR_CONFIG(hdma_ch, p_gpd_head);
+ HDMA_BUF0_START(hdma_ch);
+ }
+ } else {
+ /* Because META mode Tx should be done before new en_q, p_gpd_head must be NULL. so Tx would not be affected by new Start putbytes.
+ The following step just for backup, but should not be running. If it run, will may send more data or lose data*/
+#if defined(META_MODE_SW_ESCAPING)
+ if((kal_query_boot_mode() == FACTORY_BOOT) && (tx_or_rx ==(kal_bool)UART_TX)){
+ UART_META_PutBytes(port, p_gpd_head, p_gpd_tail);
+ }else
+#endif
+ {
+ /* tail's HWO bit will be cleared automatically */
+ /* en-q and resume DMA */
+ uart_except_en_q_rx(*pp_gpd_head, *pp_gpd_tail, (void **)&p_gpd_head, (void **)&p_gpd_tail);
+ HDMA_BUF0_RESUME(hdma_ch);
+ }
+ }
+ } else if (en_q_or_de_q == UART_DE_Q) {
+ if (p_gpd_head == NULL) {
+ *pp_gpd_head = NULL;
+ *pp_gpd_tail = NULL;
+ if (NULL != p_num)
+ *p_num = 0;
+ goto end;
+ }
+
+ if(tx_or_rx == (kal_bool)UART_TX){
+ deq_num = uart_except_de_q_with_timeout(port,(void **)&p_gpd_head, (void **) &p_gpd_tail, (void **)pp_gpd_head, (void **)pp_gpd_tail);
+ }else{
+ deq_num = uart_except_de_q((void **)&p_gpd_head, (void **) &p_gpd_tail, (void **)pp_gpd_head, (void **)pp_gpd_tail);
+ }
+
+ if (deq_num == 0) {
+ *pp_gpd_head = NULL;
+ *pp_gpd_tail = NULL;
+ if (NULL != p_num)
+ *p_num = deq_num;
+ goto end;
+ }
+
+ /* check if all is done */
+ if (p_gpd_head == p_gpd_tail && QBM_DES_GET_HWO(p_gpd_head)==0) {
+ if (uart_except_check_bps_gpd(p_gpd_head)) {
+ uart_except_free_bps_gpd(p_gpd_head);
+ QBM_DES_SET_NEXT(*pp_gpd_tail, NULL);
+ } else {
+ QBM_DES_SET_NEXT(*pp_gpd_tail, p_gpd_head);
+ *pp_gpd_tail = p_gpd_head;
+ }
+
+ p_gpd_head = p_gpd_tail = NULL;
+ }
+
+ /* check and free bypass GPD allocated by us in list */
+ deq_num -= uart_except_free_bps_gpd_in_list(pp_gpd_head, pp_gpd_tail);
+
+ if (NULL != p_num && deq_num > 0) {
+ *p_num = deq_num;
+#if defined(META_MODE_SW_ESCAPING)
+ if(kal_query_boot_mode() == FACTORY_BOOT && tx_or_rx == (kal_bool)UART_RX){
+ UART_META_ExBytes(port, *pp_gpd_head, *pp_gpd_tail);
+ }
+#endif
+ xfer_bytes = uart_cal_tgpd_buf_length(*pp_gpd_head, *pp_gpd_tail);
+ if (tx_or_rx == (kal_bool)UART_TX)
+ uart_excpt_tx_bytes[port] += xfer_bytes;
+ else
+ uart_excpt_rx_bytes[port] += xfer_bytes;
+ }
+
+ } else {
+ ASSERT(en_q_or_de_q != UART_EN_Q && en_q_or_de_q != UART_DE_Q);
+ }
+
+ /* updated global variable from local variable */
+ if (tx_or_rx == (kal_bool)UART_TX) {
+ uart_tgpd_head[port] = p_gpd_head;
+ uart_tgpd_tail[port] = p_gpd_tail;
+ } else {
+ uart_rgpd_head[port] = p_gpd_head;
+ uart_rgpd_tail[port] = p_gpd_tail;
+ }
+
+end:
+ return ret;
+}
+
+DCL_STATUS uart_ecpt_tx_gpd(UART_PORT port, void *p_first_gpd, void *p_last_gpd)
+{
+ ASSERT(port < MAX_UART_PORT_NUM);
+
+ return uart_en_q_de_q_for_ecpt(port, UART_TX, UART_EN_Q, &p_first_gpd, &p_last_gpd, NULL);
+}
+
+DCL_STATUS uart_ecpt_tx_done_info(UART_PORT port, void **pp_first_gpd, void **pp_last_gpd, kal_uint32 *gpd_num)
+{
+ ASSERT(port < MAX_UART_PORT_NUM);
+
+ return uart_en_q_de_q_for_ecpt(port, UART_TX, UART_DE_Q, pp_first_gpd, pp_last_gpd, gpd_num);
+}
+
+DCL_STATUS uart_ecpt_assign_rx_gpd(UART_PORT port, void *p_first_gpd, void *p_last_gpd)
+{
+ ASSERT(port < MAX_UART_PORT_NUM);
+
+ return uart_en_q_de_q_for_ecpt(port, UART_RX, UART_EN_Q, &p_first_gpd, &p_last_gpd, NULL);
+}
+
+DCL_STATUS uart_ecpt_get_rx_gpd(UART_PORT port, void **pp_first_gpd, void **pp_last_gpd, kal_uint32 *gpd_num)
+{
+ ASSERT(port < MAX_UART_PORT_NUM);
+
+ return uart_en_q_de_q_for_ecpt(port, UART_RX, UART_DE_Q, pp_first_gpd, pp_last_gpd, gpd_num);
+}
+
+void uart_ecpt_clear_sw_queue(UART_PORT port)
+{
+ static kal_bool first_time_clear = KAL_TRUE;
+
+ if (first_time_clear) {
+ first_time_clear = KAL_FALSE;
+
+ if (uart_wait_tgpd_head[port] != NULL) {
+ if (uart_discard_tgpd_head != NULL) {
+ QBM_DES_SET_NEXT(uart_discard_tgpd_tail, uart_wait_tgpd_head[port]);
+ uart_discard_tgpd_tail = uart_wait_tgpd_tail[port];
+ } else {
+ uart_discard_tgpd_head = uart_wait_tgpd_head[port];
+ uart_discard_tgpd_tail = uart_wait_tgpd_tail[port];
+ }
+ }
+
+ if (uart_tgpd_head[port] != NULL) {
+ if (uart_discard_tgpd_head != NULL) {
+ QBM_DES_SET_NEXT(uart_discard_tgpd_tail, uart_tgpd_head[port]);
+ uart_discard_tgpd_tail = uart_tgpd_tail[port];
+ } else {
+ uart_discard_tgpd_head = uart_tgpd_head[port];
+ uart_discard_tgpd_tail = uart_tgpd_tail[port];
+ }
+ }
+
+ if (uart_rgpd_head[port] != NULL) {
+ if (uart_discard_rgpd_head != NULL) {
+ QBM_DES_SET_NEXT(uart_discard_rgpd_tail, uart_rgpd_head[port]);
+ uart_discard_rgpd_tail = uart_rgpd_tail[port];
+ } else {
+ uart_discard_rgpd_head = uart_rgpd_head[port];
+ uart_discard_rgpd_tail = uart_rgpd_tail[port];
+ }
+ }
+
+ } else {
+ ;
+ }
+
+ uart_wait_tgpd_head[port] = NULL;
+ uart_wait_tgpd_tail[port] = NULL;
+
+ uart_tgpd_head[port] = NULL;
+ uart_tgpd_tail[port] = NULL;
+
+ uart_rgpd_head[port] = NULL;
+ uart_rgpd_tail[port] = NULL;
+}
+
+DCL_STATUS uart_ecpt_clear_ch(UART_PORT port)
+{
+ kal_uint32 val = 0;
+
+ ASSERT(port < MAX_UART_PORT_NUM);
+
+#if defined(META_MODE_SW_ESCAPING)
+ if(kal_query_boot_mode() != FACTORY_BOOT)
+#endif
+ {
+ /* Wait Tx HDMA Channel to be inactive */
+ while(HDMA_BUF0_IS_ACTIVE((port + 2)))
+ {
+ val = DRV_Reg32(GDMA_GISAR_UART);
+ if(IS_HDMA_LENERR_INTR(val, (2 + port))) break;
+ if(IS_HDMA_GPD_CSERR_INTR(val, (2 + port))) break;
+ if(IS_HDMA_BD_CSERR_INTR(val, (2 + port))) break;
+ }
+
+ /* Stop Tx HDMA Channel */
+ HDMA_BUF0_STOP((2 + port));
+ while (HDMA_BUF0_IS_ACTIVE((port + 2)));
+}
+ /* Stop Rx HDMA Channel */
+ HDMA_BUF0_STOP((3 + port));
+ while (HDMA_BUF0_IS_ACTIVE((port + 3)));
+
+ /* Clear SW Queue */
+ uart_ecpt_clear_sw_queue(port);
+
+ return STATUS_OK;
+}
+
+void uart_ecpt_timer_reset(UART_PORT port){
+ ASSERT(port < MAX_UART_PORT_NUM);
+ uart_ecpt_timer[port].timer_during = 0;
+ uart_ecpt_timer[port].timer_old = 0;
+ uart_ecpt_timer[port].timer_now = 0;
+ uart_ecpt_timer[port].timer_start = 0;
+}
+
+void uart_ecpt_timer_start(UART_PORT port)
+{
+ ASSERT(port < MAX_UART_PORT_NUM);
+ if(uart_ecpt_timer[port].timer_start == 0){
+ uart_ecpt_timer[port].timer_now = ust_get_current_time();
+ uart_ecpt_timer[port].timer_old = uart_ecpt_timer[port].timer_now;
+ uart_ecpt_timer[port].timer_during = 0;
+ uart_ecpt_timer[port].timer_start = 1;
+ }else{
+ uart_ecpt_timer[port].timer_now = ust_get_current_time();
+ }
+}
+
+kal_uint32 uart_ecpt_get_timer_during(UART_PORT port)
+{
+ ASSERT(port < MAX_UART_PORT_NUM);
+ uart_ecpt_timer[port].timer_during =ust_us_duration(uart_ecpt_timer[port].timer_old,uart_ecpt_timer[port].timer_now)/1000 ;
+ return uart_ecpt_timer[port].timer_during;
+}
+
+DCL_STATUS uart_ecpt_init_hif(UART_PORT port)
+{
+ ASSERT(port < MAX_UART_PORT_NUM);
+
+ /* need re-init hardware ??? */
+
+ /* initial exception mode qbm */
+ if (uart_except_init_qbm() != KAL_TRUE) {
+ return STATUS_FAIL;
+ }
+ return STATUS_OK;
+}
+
+DCL_STATUS uart_except_reset(UART_PORT port)
+{
+ ASSERT(port < MAX_UART_PORT_NUM);
+ uart_ecpt_tx_state[port] = HIF_STATE_NORMAL;
+ uart_ecpt_timer_reset(port);
+
+ return STATUS_OK;
+}
+kal_uint32 uart_ecpt_get_tx_state(UART_PORT port){
+ ASSERT(port < MAX_UART_PORT_NUM);
+ kal_uint32 timer_dur = 0;
+ timer_dur = uart_ecpt_get_timer_during(port);
+ if(timer_dur>=UART_ECPT_MAX_TIMEOUT){
+ uart_ecpt_tx_state[port] = HIF_STATE_TXERROR;
+ uart_ecpt_timer_reset( port);
+ }else{
+ uart_ecpt_tx_state[port] = HIF_STATE_NORMAL;
+ }
+
+ return uart_ecpt_tx_state[port];
+}
+
+
+#else //#if !defined(DRV_UART_OFF)
+
+UARTStruct UARTPort[MAX_UART_PORT_NUM];
+
+kal_bool UART_VFIFO_support[MAX_UART_PORT_NUM] =
+{
+ KAL_FALSE,
+ KAL_FALSE,
+};
+
+void UART_Boot_PutUARTBytes(UART_PORT port, kal_uint8 *data,kal_uint16 len){}
+void U_Register(UART_PORT port, UartType_enum type, UartDriver_strcut* drv){}
+kal_bool U_Open(UART_PORT port, module_type ownerid){}
+void U_Close(UART_PORT port, module_type ownerid){}
+kal_uint16 U_GetBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid){}
+kal_uint16 U_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid){}
+kal_uint16 U_GetBytesAvail(UART_PORT port){}
+kal_uint16 U_GetTxRoomLeft(UART_PORT port){}
+kal_uint16 U_PutISRBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid){}
+kal_uint16 U_GetTxISRRoomLeft(UART_PORT port){}
+kal_uint16 U_SendISRData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode, kal_uint8 escape_char, module_type ownerid){}
+kal_uint16 U_SendData(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length,kal_uint8 mode,kal_uint8 escape_char, module_type ownerid ){}
+void U_Purge(UART_PORT port, UART_buffer dir, module_type ownerid){}
+void U_SetOwner (UART_PORT port, module_type ownerid){}
+void U_SetFlowCtrl(UART_PORT port, kal_bool XON, module_type ownerid){}
+void U_ConfigEscape (UART_PORT port, kal_uint8 EscChar, kal_uint16 ESCGuardtime, module_type ownerid){}
+void U_SetDCBConfig(UART_PORT port, UARTDCBStruct *UART_Config, module_type ownerid){}
+void U_CtrlDCD(UART_PORT port, IO_level SDCD, module_type ownerid){}
+void U_CtrlBreak(UART_PORT port, IO_level SBREAK, module_type ownerid){}
+void U_ClrRxBuffer(UART_PORT port, module_type ownerid){}
+void U_ClrTxBuffer(UART_PORT port, module_type ownerid){}
+void U_SetBaudRate(UART_PORT port, UART_baudrate baudrate, module_type ownerid){}
+module_type U_GetOwnerID(UART_PORT port){}
+void U_SetAutoBaud_Div(UART_PORT port, module_type ownerid){}
+void U_Register_TX_cb(UART_PORT port, module_type ownerid, UART_TX_FUNC func){}
+void U_Register_RX_cb(UART_PORT port, module_type ownerid, UART_RX_FUNC func){}
+kal_uint8 U_GetUARTByte(UART_PORT port){}
+kal_uint8 U_GetUARTByteWithTimeOut(UART_PORT port, kal_uint8* ch, kal_uint32 timeout_value){return 0;}
+void U_PutUARTByte(UART_PORT port, kal_uint8 data){}
+void U_PutUARTBytes(UART_PORT port, kal_uint8 *data, kal_uint16 len){}
+void U_ReadDCBConfig(UART_PORT port, UARTDCBStruct *DCB){}
+void U_CtrlRI (UART_PORT port, IO_level SRI, module_type ownerid){}
+void U_CtrlDTR (UART_PORT port, IO_level SDTR, module_type ownerid){}
+void U_ReadHWStatus(UART_PORT port, IO_level *SDSR, IO_level *SCTS){}
+void UART_AssertWaitPrevDataSentOut(UART_PORT port){}
+void UART_Calback(void *parameter){}
+void UART_CheckAT_Callback(void *parameter){}
+kal_bool UART_CheckTxAllSentOut(UART_PORT port){}
+kal_bool UART_CheckTxBufferEmpty(UART_PORT port){}
+void UART_CompensateAT(UART_PORT port){}
+void uart_customize_init(void){}
+void UART_dafault_rx_cb(UART_PORT port){}
+void UART_dafault_tx_cb(UART_PORT port){}
+void UART_DriverInit(UART_PORT port){}
+void UART_EnableTX(UART_PORT port, kal_bool enable){}
+void UART_GetTxBufferSize(UART_PORT port, kal_uint32 *total_size, kal_uint32 *rest_size){}
+void UART_HWInit(UART_PORT port){}
+kal_bool UART_IsVfifoSetting(UART_PORT port, UART_TxRx_VFIFO_support vs){}
+void UART_RecHandler(void *parameter){}
+void UART_MsHandler(void *parameter){}
+void UART_RLSHandler(void *parameter){}
+void UART_sendilm(UART_PORT port, msg_type msgid){}
+void UART_set_FIFO_trigger(UART_PORT port, kal_uint16 tx_level, kal_uint16 rx_level){}
+void UART_SetRateFix(UART_PORT port){}
+void UART_SetSleepEnable(UART_PORT port, kal_bool enable){}
+void UART_SleepOnTx_Enable(UART_PORT port, UART_SLEEP_ON_TX enable_flag){}
+kal_bool uart_support_autoescape(void){}
+void UART_SwitchPort(UART_PORT *APP_port, UART_PORT new_uart_port){}
+void UART_TrxHandler(void *parameter){}
+void UART_TxDMAHandler(void *parameter, kal_uint8 chk_done){}
+void UART_TurnOnPower(UART_PORT port, kal_bool enable){}
+void UART1_HISR(void){}
+void UART2_HISR(void){}
+void PutUARTDatas(UART_PORT port, kal_uint8 escape_char, kal_uint8 *data,kal_uint16 len){}
+kal_uint16 BMT_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length){}
+void PutUARTRingBufferData(UART_PORT port){}
+void UART_loopback(UART_PORT port){}
+void UART_dsp_dafault_tx_cb(UART_PORT port){}
+void UART_dsp_dafault_rx_cb(UART_PORT port){}
+#endif //if !defined(DRV_UART_OFF)
+
+
+// uart dispatch funtion table
+UartDriver_strcut UartDriver=
+{
+ U_Open,
+ U_Close,
+ U_GetBytes, // SIO_CMD_GET_BYTES is not supported
+ U_PutBytes, // SIO_CMD_PUT_BYTES is not supported
+ U_GetBytesAvail, // SIO_CMD_GET_RX_AVAIL is not supported
+ U_GetTxRoomLeft, // SIO_CMD_GET_TX_AVAIL is not supported
+ U_PutISRBytes, // SIO_CMD_PUT_ISR_BYTES is not supported
+ U_GetTxISRRoomLeft, // SIO_CMD_GET_ISR_TX_AVAIL is not supported
+ U_Purge,
+ U_SetOwner,
+ U_SetFlowCtrl,
+ U_ConfigEscape,
+ U_SetDCBConfig,
+ U_CtrlDCD, // SIO_CMD_CTRL_DCD is not supported
+ U_CtrlBreak,
+ U_ClrRxBuffer,
+ U_ClrTxBuffer,
+ U_SetBaudRate,
+ U_SendISRData, // SIO_CMD_SEND_ISR_DATA is not supported
+ U_SendData, // SIO_CMD_SEND_DATA is not supported
+ U_GetOwnerID,
+ U_SetAutoBaud_Div, // SIO_CMD_SET_AUTOBAUD_DIV is not supported
+ /*TY adds these to expand flexibility 2004/10/15*/
+ U_Register_TX_cb, // SIO_CMD_REG_TX_CB is not supported
+ U_Register_RX_cb, // SIO_CMD_REG_RX_CB is not supported
+ /*TY adds these to let virtual COM port can retrive exception log 2005/3/8*/
+ U_GetUARTByte, // SIO_CMD_GET_UART_BYTE is not supported
+ U_PutUARTByte, // SIO_CMD_PUT_UART_BYTE is not supported
+ U_PutUARTBytes, // SIO_CMD_PUT_UART_BYTES is not supported
+ /*for virtual com port to return DCB configuration*/
+ U_ReadDCBConfig,
+ U_CtrlRI, // SIO_CMD_CTRL_RI is not supported
+ U_CtrlDTR, // SIO_CMD_CTRL_DTR is not supported
+ U_ReadHWStatus,
+ U_GetUARTByteWithTimeOut
+};
+
+
+typedef struct hdma_tgpd_ss {
+ kal_uint8 hwo:1;
+ kal_uint8 bdp:1;
+ kal_uint8 bps:1;
+ kal_uint8 resv1:4;
+ kal_uint8 ioc:1;
+ kal_uint8 cksum;
+ kal_uint16 resv2;
+ kal_uint32 nextPtr;
+ kal_uint32 bufPtr;
+ kal_uint8 resv3;
+} hdma_tgpd_tt;
+
+typedef struct hdma_rgpd_ss {
+ kal_uint8 hwo:1;
+ kal_uint8 bdp:1;
+ kal_uint8 bps:1;
+ kal_uint8 resv1:4;
+ kal_uint8 ioc:1;
+ kal_uint8 cksum;
+ kal_uint16 allowBufLen;
+ kal_uint32 nextPtr;
+ kal_uint32 bufPtr;
+ kal_uint16 bufLen;
+ kal_uint16 resv2;
+} hdma_rgpd_tt;
+
+
+// dummy_fdma() just for mt6595 workaround patch. removed on LR12.
+/*
+void dummy_fdma(kal_uint32 gdma_start)
+{
+
+ FDMA_PDN_CLR(3);
+ if(gdma_start == 0){
+ DRV_WriteReg32(0xff2c0080, 0x4); // stop (GDMA_FDCR0)
+ FDMA_PDN_SET(3);
+ }
+ else{
+ DRV_WriteReg32(0xff2c0080, 0x4); // stop (GDMA_FDCR0)
+ while(DRV_Reg32(0xff2c0014) & (1<<16)); // check done state (GDMA_FDCSR0)
+
+ DRV_WriteReg32(0xff2c0014, 0x02000000); // GDMA_FDCSR
+ DRV_WriteReg32(0xff2c0084, 0xbf830C20); // GDMA_FDSAR3
+ DRV_WriteReg32(0xff2c0088, 0xbf830C24); // GDMA_FDDAR3
+ DRV_WriteReg32(0xff2c0080, 0xffff43a1); // start (GDMA_FDCR3)
+ }
+ return;
+}
+
+}
+*/
+
+extern UARTStruct UARTPort[];
+extern Seriport_HANDLER_T Uart_Drv_Handler;
+
+enum {
+ INIT_NOTINIT,
+ INIT_REG_CB,
+ INIT_DRV_ATTACH,
+ INIT_DRV_INIT,
+ INIT_UPMOD_INIT,
+ INIT_SET_BAUDRATE,
+ INIT_DONE,
+} uart_excpt_drv_init_stage = INIT_NOTINIT;
+kal_bool uart_excpt_drv_init_done_g = KAL_FALSE;
+kal_bool uart_st_in_except_mode_g = KAL_FALSE;
+
+#if defined __UART_UT__
+kal_int32 uart_hmu_pre_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ return 0;
+}
+
+kal_int32 uart_hmu_post_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_pre_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_post_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_except_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ return KAL_TRUE;
+}
+
+#else
+
+kal_int32 uart_hmu_pre_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+
+ return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_post_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_pre_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+
+ return KAL_TRUE;
+}
+
+kal_int32 uart_hmu_post_deinit(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ return KAL_TRUE;
+}
+
+UARTStruct* uart_core_get_instance(kal_uint32 uart_port)
+{
+ return &UARTPort[uart_port];
+}
+
+DCL_STATUS uart_ttyhdr_reg_ttycore(UARTStruct*p_dev_inst, kal_uint32 port)
+{
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+
+ handle = DclSerialPort_Open(port, 0);
+
+ uart_excpt_drv_init_stage = INIT_REG_CB;
+ status = DclSerialPort_DrvRegisterCb(handle, &Uart_Drv_Handler);
+
+ if (KAL_TRUE == uart_st_in_except_mode_g && STATUS_ALREADY_OPENED == status) {
+ return STATUS_OK;
+ }
+ return status;
+}
+
+DCL_STATUS uart_ttyhdr_cmd_init(UART_PORT port)
+{
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ DCL_CTRL_DATA_T data;
+
+ handle = DclSerialPort_Open(port, 0);
+
+ uart_excpt_drv_init_stage = INIT_DRV_ATTACH;
+ status = DclSerialPort_DrvAttach(handle);
+ if(status != STATUS_OK)
+ {
+ return STATUS_FAIL;
+ }
+
+ uart_excpt_drv_init_stage = INIT_DRV_INIT;
+ status = DclSerialPort_Control(handle, SIO_CMD_INIT, &data);
+
+ return status;
+
+}
+
+DCL_STATUS uart_ttyhdr_upmodule_init(UART_PORT port)
+{
+ DCL_STATUS status;
+ DCL_HANDLE handle;
+ UART_CTRL_DCB_T data;
+
+ handle = DclSerialPort_Open(port, 0);
+
+ uart_excpt_drv_init_stage = INIT_UPMOD_INIT;
+ status = DclSerialPort_UpModuleInit(handle, MOD_DRV_DBG, TTY_FLAG_NEW_TX | TTY_FLAG_NEW_RX);
+ if (status != STATUS_OK && status != STATUS_ALREADY_OPENED) {
+ return status;
+ }
+
+ //DclSerialPort_UpModuleRegisterCb(handle, dbg_print_tty_rx_cb, NULL, dbg_print_tty_state_cb);
+
+ data.u4OwenrId = MOD_DRV_DBG;
+ data.rUARTConfig.u4Baud = UART_BAUD_1500000;
+ data.rUARTConfig.u1DataBits = len_8;
+ data.rUARTConfig.u1StopBits = sb_1;
+ data.rUARTConfig.u1Parity = pa_none;
+ data.rUARTConfig.u1FlowControl = fc_sw;
+ data.rUARTConfig.ucXonChar = 0x11;
+ data.rUARTConfig.ucXoffChar = 0x13;
+ data.rUARTConfig.fgDSRCheck = KAL_FALSE;
+
+ // Set baudrate
+ uart_excpt_drv_init_stage = INIT_SET_BAUDRATE;
+ status = DclSerialPort_Control(handle, SIO_CMD_SET_DCB_CONFIG, (DCL_CTRL_DATA_T*)&data);
+
+ return status;
+}
+
+kal_int32 uart_hmu_except_init(kal_uint32 dev_mapping, kal_uint32 ext_devinfo_len, kal_char *ext_devinfo)
+{
+ DCL_STATUS ret;
+ UARTStruct* p_dev_inst;
+ kal_uint32 uart_port;
+ kal_uint32 init_ports[] = {uart_port1, uart_port2};
+ kal_uint32 ret_val = 0;
+ int i;
+
+ uart_st_in_except_mode_g = KAL_TRUE;
+ if (uart_excpt_drv_init_done_g == KAL_TRUE) {
+ return 0;
+ }
+
+ for (i = 0; i < sizeof(init_ports)/sizeof(init_ports[0]); i++) {
+ uart_port = init_ports[i];
+
+ p_dev_inst = uart_core_get_instance(uart_port);
+
+ if(p_dev_inst->initialized == KAL_TRUE){
+ continue;
+ }
+
+ ret = uart_ttyhdr_reg_ttycore(p_dev_inst, uart_port);
+ if (STATUS_OK != ret) {
+ ret_val = -1;
+ continue;
+ }
+
+ ret = uart_ttyhdr_cmd_init(uart_port);
+ if (STATUS_OK != ret) {
+ ret_val = -1;
+ continue;
+ }
+ }
+
+ uart_excpt_drv_init_stage = INIT_DONE;
+ uart_excpt_drv_init_done_g = KAL_TRUE;
+
+ return ret_val;
+}
+
+#endif
+
+