treewide: drop executable file attrib for non-executable files
[oweals/u-boot_mod.git] / u-boot / cpu / mips / ar7240 / hornet_serial.c
1 #include <asm/addrspace.h>
2 #include <asm/types.h>
3 #include <config.h>
4 #include <hornet_soc.h>
5
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)
8
9 static int AthrUartGet(char *__ch_data){
10         u32 rdata;
11
12         rdata = uart_reg_read(UARTDATA_ADDRESS);
13
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);
18                 return(1);
19         } else {
20                 return(0);
21         }
22 }
23
24 static void AthrUartPut(char __ch_data){
25         u32 rdata;
26
27         do {
28                 rdata = uart_reg_read(UARTDATA_ADDRESS);
29         } while(UARTDATA_UARTTXCSR_GET(rdata) == 0);
30
31         rdata = UARTDATA_UARTTXRXDATA_SET((u32)__ch_data);
32         rdata |= UARTDATA_UARTTXCSR_SET(1);
33
34         uart_reg_write(UARTDATA_ADDRESS, rdata);
35 }
36
37 /*
38  * Get CPU, RAM and AHB clocks
39  * Based on: Linux/arch/mips/ath79/clock.c
40  */
41 void ar7240_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq){
42         u32 ref_rate, clock_ctrl, cpu_config, pll, temp;
43
44         // determine reference clock (25 or 40 MHz)
45         temp = ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS);
46
47         if(temp & HORNET_BOOTSTRAP_SEL_25M_40M_MASK){
48                 ref_rate = 40000000;
49         } else {
50                 ref_rate = 25000000;
51         }
52
53         // read CPU CLock Control Register (CLOCK_CONTROL) value
54         clock_ctrl = ar7240_reg_rd(AR7240_CPU_CLOCK_CONTROL);
55
56         if(clock_ctrl & HORNET_CLOCK_CONTROL_BYPASS_MASK){
57                 // PLL is bypassed, so all clocks are == reference clock
58                 *cpu_freq = ref_rate;
59                 *ddr_freq = ref_rate;
60                 *ahb_freq = ref_rate;
61         } else {
62                 // read CPU PLL Configuration register (CPU_PLL_CONFIG) value
63                 cpu_config = ar7240_reg_rd(AR7240_CPU_PLL_CONFIG);
64
65                 // REFDIV
66                 temp = (cpu_config & HORNET_PLL_CONFIG_REFDIV_MASK) >> HORNET_PLL_CONFIG_REFDIV_SHIFT;
67                 pll = ref_rate / temp;
68
69                 // DIV_INT (multiplier)
70                 temp = (cpu_config & HORNET_PLL_CONFIG_NINT_MASK) >> HORNET_PLL_CONFIG_NINT_SHIFT;
71                 pll *= temp;
72
73                 // OUTDIV
74                 temp = (cpu_config & HORNET_PLL_CONFIG_OUTDIV_MASK) >> HORNET_PLL_CONFIG_OUTDIV_SHIFT;
75
76                 if(temp == 0){ // value 0 is not allowed
77                         temp = 1;
78                 }
79
80                 pll >>= temp;
81
82                 // CPU clock divider
83                 temp = ((clock_ctrl & HORNET_CLOCK_CONTROL_CPU_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_CPU_POST_DIV_SHIFT) + 1;
84                 *cpu_freq = pll / temp;
85
86                 // DDR clock divider
87                 temp = ((clock_ctrl & HORNET_CLOCK_CONTROL_DDR_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_DDR_POST_DIV_SFIFT) + 1;
88                 *ddr_freq = pll / temp;
89
90                 // AHB clock divider
91                 temp = ((clock_ctrl & HORNET_CLOCK_CONTROL_AHB_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_AHB_POST_DIV_SFIFT) + 1;
92                 *ahb_freq = pll / temp;
93         }
94 }
95
96 int serial_init(void){
97         u32 rdata;
98         u32 baudRateDivisor, clock_step;
99         u32 fcEnable = 0;
100
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);
106
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);
111
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;
115
116         if(rdata){
117                 baudRateDivisor = (40000000 / (16 * 115200)) - 1; // 40 MHz clock is taken as UART clock
118         } else {
119                 baudRateDivisor = (25000000 / (16 * 115200)) - 1; // 25 MHz clock is taken as UART clock
120         }
121
122         clock_step = 8192;
123
124         rdata = UARTCLOCK_UARTCLOCKSCALE_SET(baudRateDivisor) | UARTCLOCK_UARTCLOCKSTEP_SET(clock_step);
125         uart_reg_write(UARTCLOCK_ADDRESS, rdata);
126
127         /* Config Uart Controller */
128         /* No interrupt */
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);
130
131         /* is_dte == 1 */
132         rdata = rdata | UARTCS_UARTINTERFACEMODE_SET(2);
133
134         if (fcEnable) {
135                 rdata = rdata | UARTCS_UARTFLOWCONTROLMODE_SET(2);
136         }
137
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);
144
145         return 0;
146 }
147
148 int serial_tstc(void){
149         return(UARTDATA_UARTRXCSR_GET(uart_reg_read(UARTDATA_ADDRESS)));
150 }
151
152 u8 serial_getc(void){
153         char ch_data;
154
155         while(!AthrUartGet(&ch_data));
156
157         return((u8)ch_data);
158 }
159
160 void serial_putc(u8 byte){
161         if (byte == '\n'){
162                 AthrUartPut('\r');
163         }
164
165         AthrUartPut((char)byte);
166 }
167
168 void serial_puts(const char *s){
169         while(*s){
170                 serial_putc(*s++);
171         }
172 }