void mtk_uart_init (U32 uartclk, U32 baudrate) { //#define AP_PERI_GLOBALCON_RST0 (PERI_CON_BASE+0x0) #define AP_PERI_GLOBALCON_PDN0 (0x10000084) /* uartclk != 0, means use custom bus clock; uartclk == 0, means use defaul bus clk */ if(0 == uartclk){ // default bus clk //uartclk = mtk_get_bus_freq()*1000/4; uartclk = UART_SRC_CLK; } mtk_serial_set_current_uart(CFG_UART_META); //PDN_Power_CONA_DOWN(PDN_PERI_UART1, 0); //UART_CLR_BITS(1 << 0, AP_PERI_GLOBALCON_RST0); /* Release UART1 reset signal */ //UART_SET_BITS(1 << 24, AP_PERI_GLOBALCON_PDN0); /* Power on UART1 */ //UART_CLR_BITS(1 << 10, AP_PERI_GLOBALCON_PDN0); /* Power on UART1 */ mtk_uart_power_on(CFG_UART_META); UART_SET_BITS(UART_FCR_FIFO_INIT, UART_FCR(g_uart)); /* clear fifo */ UART_WRITE16(UART_NONE_PARITY | UART_WLS_8 | UART_1_STOP, UART_LCR(g_uart)); serial_setbrg(uartclk, CFG_META_BAUDRATE); mtk_serial_set_current_uart(CFG_UART_LOG); //PDN_Power_CONA_DOWN(PDN_PERI_UART4, 0); //UART_SET_BITS(1 << 12, APMCU_CG_CLR0); //UART_CLR_BITS(1 << 3, AP_PERI_GLOBALCON_RST0); /* Release UART2 reset signal */ //UART_SET_BITS(1 << 27, AP_PERI_GLOBALCON_PDN0); /* Power on UART2 */ //UART_CLR_BITS(1 << 11, AP_PERI_GLOBALCON_PDN0); /* Power on UART2 */ mtk_uart_power_on(CFG_UART_LOG); UART_SET_BITS(UART_FCR_FIFO_INIT, UART_FCR(g_uart)); /* clear fifo */ UART_WRITE16(UART_NONE_PARITY | UART_WLS_8 | UART_1_STOP, UART_LCR(g_uart)); serial_setbrg(uartclk, baudrate); }
void serial_setbrg() { unsigned int byte,speed; unsigned int highspeed; unsigned int quot, divisor, remainder; //unsigned int ratefix; unsigned int uartclk; //unsigned int highclk = (UART_SRC_CLK/(speed*4)) > 10 ? (1) : 0; unsigned short data, high_speed_div, sample_count, sample_point; unsigned int tmp_div; speed = g_brg; //uartclk = UART_SRC_CLK; uartclk = (unsigned int)(mt6575_get_bus_freq()*1000/4); if (speed <= 115200 ) { highspeed = 0; quot = 16; } else { highspeed = 3; quot = 1; } if (highspeed < 3) { /*0~2*/ /* Set divisor DLL and DLH */ divisor = uartclk / (quot * speed); remainder = uartclk % (quot * speed); if (remainder >= (quot / 2) * speed) divisor += 1; UART_WRITE16(highspeed, UART_HIGHSPEED(g_uart)); byte = UART_READ32(UART_LCR(g_uart)); /* DLAB start */ UART_WRITE32((byte | UART_LCR_DLAB), UART_LCR(g_uart)); UART_WRITE32((divisor & 0x00ff), UART_DLL(g_uart)); UART_WRITE32(((divisor >> 8)&0x00ff), UART_DLH(g_uart)); UART_WRITE32(byte, UART_LCR(g_uart)); /* DLAB end */ } else {
void serial_setbrg (U32 uartclk, U32 baudrate) { #if (CFG_FPGA_PLATFORM) #define MAX_SAMPLE_COUNT 256 U16 tmp; U32 divisor; U32 sample_data; U32 sample_count; U32 sample_point; // Setup N81,(UART_WLS_8 | UART_NONE_PARITY | UART_1_STOP) = 0x03 UART_WRITE32(0x0003, UART_LCR(g_uart)); /* * NoteXXX: Below is the sample code to set UART baud rate. * I assume that when system is reset, the UART clock rate is 26MHz * and baud rate is 115200. * use UART1_HIGHSPEED = 0x3 can get more sample count to get better UART sample rate * based on baud_rate = uart clock frequency / (sampe_count * divisor) * divisor = (DLH+DLL) */ // In order to get better UART sample rate, set UART1_HIGHSPEED = 0x3. // And we can calculate sample count for reducing effect of UART sample rate variation UART_WRITE32(0x0003, UART_HIGHSPEED(g_uart)); // calculate sample_data = sample_count*divisor // round off the result for approximating to the real baudrate sample_data = (uartclk+(baudrate/2))/baudrate; // calculate divisor divisor = (sample_data+(MAX_SAMPLE_COUNT-1))/MAX_SAMPLE_COUNT; // calculate sample count sample_count = sample_data/divisor; // calculate sample point (count from 0) sample_point = (sample_count-1)/2; // set sample count (count from 0) UART_WRITE32((sample_count-1), UART_SAMPLE_COUNT(g_uart)); // set sample point UART_WRITE32(sample_point, UART_SAMPLE_POINT(g_uart)); tmp = UART_READ32(UART_LCR(g_uart)); /* DLAB start */ UART_WRITE32((tmp | UART_LCR_DLAB), UART_LCR(g_uart)); UART_WRITE32((divisor&0xFF), UART_DLL(g_uart)); UART_WRITE32(((divisor>>8)&0xFF), UART_DLH(g_uart)); UART_WRITE32(tmp, UART_LCR(g_uart)); #else unsigned int byte; unsigned int highspeed; unsigned int quot, divisor, remainder; unsigned int ratefix; if (baudrate <= 115200 ) { highspeed = 0; quot = 16; } else { highspeed = 2; quot = 4; } /* Set divisor DLL and DLH */ divisor = uartclk / (quot * baudrate); remainder = uartclk % (quot * baudrate); if (remainder >= (quot / 2) * baudrate) divisor += 1; UART_WRITE16(highspeed, UART_HIGHSPEED(g_uart)); byte = UART_READ32(UART_LCR(g_uart)); /* DLAB start */ UART_WRITE32((byte | UART_LCR_DLAB), UART_LCR(g_uart)); UART_WRITE32((divisor & 0x00ff), UART_DLL(g_uart)); UART_WRITE32(((divisor >> 8)&0x00ff), UART_DLH(g_uart)); //UART_WRITE32(byte, UART_LCR(g_uart)); /* DLAB end */ // Setup N81,(UART_WLS_8 | UART_NONE_PARITY | UART_1_STOP) = 0x03 UART_WRITE32(0x0003, UART_LCR(g_uart)); #endif }