2 * Atheros AR7XXX/AR9XXX SoC early printk support
4 * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
5 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published
9 * by the Free Software Foundation.
13 #include <linux/errno.h>
14 #include <linux/serial_reg.h>
15 #include <asm/addrspace.h>
16 #include <asm/setup.h>
18 #include <asm/mach-ath79/ath79.h>
19 #include <asm/mach-ath79/ar71xx_regs.h>
20 #include <asm/mach-ath79/ar933x_uart.h>
22 static void (*_prom_putchar
)(char);
24 static inline void prom_putchar_wait(void __iomem
*reg
, u32 mask
, u32 val
)
30 if ((t
& mask
) == val
)
35 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
37 static void prom_putchar_ar71xx(char ch
)
39 void __iomem
*base
= (void __iomem
*)(KSEG1ADDR(AR71XX_UART_BASE
));
41 prom_putchar_wait(base
+ UART_LSR
* 4, BOTH_EMPTY
, BOTH_EMPTY
);
42 __raw_writel((unsigned char)ch
, base
+ UART_TX
* 4);
43 prom_putchar_wait(base
+ UART_LSR
* 4, BOTH_EMPTY
, BOTH_EMPTY
);
46 static void prom_putchar_ar933x(char ch
)
48 void __iomem
*base
= (void __iomem
*)(KSEG1ADDR(AR933X_UART_BASE
));
50 prom_putchar_wait(base
+ AR933X_UART_DATA_REG
, AR933X_UART_DATA_TX_CSR
,
51 AR933X_UART_DATA_TX_CSR
);
52 __raw_writel(AR933X_UART_DATA_TX_CSR
| (unsigned char)ch
,
53 base
+ AR933X_UART_DATA_REG
);
54 prom_putchar_wait(base
+ AR933X_UART_DATA_REG
, AR933X_UART_DATA_TX_CSR
,
55 AR933X_UART_DATA_TX_CSR
);
58 static void prom_putchar_dummy(char ch
)
63 static void prom_enable_uart(u32 id
)
65 void __iomem
*gpio_base
;
70 case REV_ID_MAJOR_AR71XX
:
71 uart_en
= AR71XX_GPIO_FUNC_UART_EN
;
74 case REV_ID_MAJOR_AR7240
:
75 case REV_ID_MAJOR_AR7241
:
76 case REV_ID_MAJOR_AR7242
:
77 uart_en
= AR724X_GPIO_FUNC_UART_EN
;
80 case REV_ID_MAJOR_AR913X
:
81 uart_en
= AR913X_GPIO_FUNC_UART_EN
;
84 case REV_ID_MAJOR_AR9330
:
85 case REV_ID_MAJOR_AR9331
:
86 uart_en
= AR933X_GPIO_FUNC_UART_EN
;
89 case REV_ID_MAJOR_AR9341
:
90 case REV_ID_MAJOR_AR9342
:
91 case REV_ID_MAJOR_AR9344
:
97 gpio_base
= (void __iomem
*)KSEG1ADDR(AR71XX_GPIO_BASE
);
98 t
= __raw_readl(gpio_base
+ AR71XX_GPIO_REG_FUNC
);
100 __raw_writel(t
, gpio_base
+ AR71XX_GPIO_REG_FUNC
);
103 static void prom_putchar_init(void)
108 base
= (void __iomem
*)(KSEG1ADDR(AR71XX_RESET_BASE
));
109 id
= __raw_readl(base
+ AR71XX_RESET_REG_REV_ID
);
110 id
&= REV_ID_MAJOR_MASK
;
113 case REV_ID_MAJOR_AR71XX
:
114 case REV_ID_MAJOR_AR7240
:
115 case REV_ID_MAJOR_AR7241
:
116 case REV_ID_MAJOR_AR7242
:
117 case REV_ID_MAJOR_AR913X
:
118 case REV_ID_MAJOR_AR9341
:
119 case REV_ID_MAJOR_AR9342
:
120 case REV_ID_MAJOR_AR9344
:
121 case REV_ID_MAJOR_QCA9533
:
122 case REV_ID_MAJOR_QCA9533_V2
:
123 case REV_ID_MAJOR_QCA9556
:
124 case REV_ID_MAJOR_QCA9558
:
125 case REV_ID_MAJOR_TP9343
:
126 case REV_ID_MAJOR_QCA956X
:
127 _prom_putchar
= prom_putchar_ar71xx
;
130 case REV_ID_MAJOR_AR9330
:
131 case REV_ID_MAJOR_AR9331
:
132 _prom_putchar
= prom_putchar_ar933x
;
136 _prom_putchar
= prom_putchar_dummy
;
140 prom_enable_uart(id
);
143 void prom_putchar(char ch
)