1 #include <asm/addrspace.h>
4 #include <hornet_soc.h>
6 #define uart_reg_read(x) ar7240_reg_rd( (AR7240_UART_BASE+x) )
7 #define uart_reg_write(x, y) ar7240_reg_wr( (AR7240_UART_BASE+x), y)
9 static int AthrUartGet(char *__ch_data){
12 rdata = uart_reg_read(UARTDATA_ADDRESS);
14 if(UARTDATA_UARTRXCSR_GET(rdata)){
15 *__ch_data = (char)UARTDATA_UARTTXRXDATA_GET(rdata);
16 rdata = UARTDATA_UARTRXCSR_SET(1);
17 uart_reg_write(UARTDATA_ADDRESS, rdata);
24 static void AthrUartPut(char __ch_data){
28 rdata = uart_reg_read(UARTDATA_ADDRESS);
29 } while(UARTDATA_UARTTXCSR_GET(rdata) == 0);
31 rdata = UARTDATA_UARTTXRXDATA_SET((u32)__ch_data);
32 rdata |= UARTDATA_UARTTXCSR_SET(1);
34 uart_reg_write(UARTDATA_ADDRESS, rdata);
38 * Get CPU, RAM and AHB clocks
39 * Based on: Linux/arch/mips/ath79/clock.c
41 void ar7240_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq){
42 u32 ref_rate, clock_ctrl, cpu_config, pll, temp;
44 // determine reference clock (25 or 40 MHz)
45 temp = ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS);
47 if(temp & HORNET_BOOTSTRAP_SEL_25M_40M_MASK){
53 // read CPU CLock Control Register (CLOCK_CONTROL) value
54 clock_ctrl = ar7240_reg_rd(AR7240_CPU_CLOCK_CONTROL);
56 if(clock_ctrl & HORNET_CLOCK_CONTROL_BYPASS_MASK){
57 // PLL is bypassed, so all clocks are == reference clock
62 // read CPU PLL Configuration register (CPU_PLL_CONFIG) value
63 cpu_config = ar7240_reg_rd(AR7240_CPU_PLL_CONFIG);
66 temp = (cpu_config & HORNET_PLL_CONFIG_REFDIV_MASK) >> HORNET_PLL_CONFIG_REFDIV_SHIFT;
67 pll = ref_rate / temp;
69 // DIV_INT (multiplier)
70 temp = (cpu_config & HORNET_PLL_CONFIG_NINT_MASK) >> HORNET_PLL_CONFIG_NINT_SHIFT;
74 temp = (cpu_config & HORNET_PLL_CONFIG_OUTDIV_MASK) >> HORNET_PLL_CONFIG_OUTDIV_SHIFT;
76 if(temp == 0){ // value 0 is not allowed
83 temp = ((clock_ctrl & HORNET_CLOCK_CONTROL_CPU_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_CPU_POST_DIV_SHIFT) + 1;
84 *cpu_freq = pll / temp;
87 temp = ((clock_ctrl & HORNET_CLOCK_CONTROL_DDR_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_DDR_POST_DIV_SFIFT) + 1;
88 *ddr_freq = pll / temp;
91 temp = ((clock_ctrl & HORNET_CLOCK_CONTROL_AHB_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_AHB_POST_DIV_SFIFT) + 1;
92 *ahb_freq = pll / temp;
96 int serial_init(void){
98 u32 baudRateDivisor, clock_step;
101 /* GPIO Configuration */
102 ar7240_reg_wr(AR7240_GPIO_OE, 0xcff);
103 rdata = ar7240_reg_rd(AR7240_GPIO_OUT);
104 rdata |= 0x400; // GPIO 10 (UART_SOUT) must output 1
105 ar7240_reg_wr(AR7240_GPIO_OUT, rdata);
107 rdata = ar7240_reg_rd(AR7240_GPIO_FUNC);
108 /* GPIO_FUN, bit1/UART_EN, bit2/UART_RTS_CTS_EN, bit15(disable_s26_uart) */
109 rdata |= (0x3 << 1) | (0x1 << 15);
110 ar7240_reg_wr(AR7240_GPIO_FUNC, rdata);
112 /* Get reference clock rate, then set baud rate to 115200 */
113 rdata = ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS);
114 rdata &= HORNET_BOOTSTRAP_SEL_25M_40M_MASK;
117 baudRateDivisor = (40000000 / (16 * 115200)) - 1; // 40 MHz clock is taken as UART clock
119 baudRateDivisor = (25000000 / (16 * 115200)) - 1; // 25 MHz clock is taken as UART clock
124 rdata = UARTCLOCK_UARTCLOCKSCALE_SET(baudRateDivisor) | UARTCLOCK_UARTCLOCKSTEP_SET(clock_step);
125 uart_reg_write(UARTCLOCK_ADDRESS, rdata);
127 /* Config Uart Controller */
129 rdata = UARTCS_UARTDMAEN_SET(0) | UARTCS_UARTHOSTINTEN_SET(0) | UARTCS_UARTHOSTINT_SET(0) | UARTCS_UARTSERIATXREADY_SET(0) | UARTCS_UARTTXREADYORIDE_SET(~fcEnable) | UARTCS_UARTRXREADYORIDE_SET(~fcEnable) | UARTCS_UARTHOSTINTEN_SET(0);
132 rdata = rdata | UARTCS_UARTINTERFACEMODE_SET(2);
135 rdata = rdata | UARTCS_UARTFLOWCONTROLMODE_SET(2);
138 /* invert_fc ==0 (Inverted Flow Control) */
139 //rdata = rdata | UARTCS_UARTFLOWCONTROLMODE_SET(3);
140 /* parityEnable == 0 */
141 //rdata = rdata | UARTCS_UARTPARITYMODE_SET(2); -->Parity Odd
142 //rdata = rdata | UARTCS_UARTPARITYMODE_SET(3); -->Parity Even
143 uart_reg_write(UARTCS_ADDRESS, rdata);
148 int serial_tstc(void){
149 return(UARTDATA_UARTRXCSR_GET(uart_reg_read(UARTDATA_ADDRESS)));
152 u8 serial_getc(void){
155 while(!AthrUartGet(&ch_data));
160 void serial_putc(u8 byte){
165 AthrUartPut((char)byte);
168 void serial_puts(const char *s){