diff options
author | Gabor Juhos <juhosg@openwrt.org> | 2011-06-20 15:26:03 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2011-12-07 17:02:45 -0500 |
commit | 0bd3acdf7d559c8289de73c4c711fd2381e6c7ad (patch) | |
tree | 7edee8764810ff405bf14083fd285da596d1a1e9 /arch/mips/ath79 | |
parent | 6d1c8fde2daa498fa6ddf8916bcfc5aee1bbe51b (diff) |
MIPS: ath79: Add early printk support for the AR933X SoCs
The AR933X SoCs are using a different UART, thus require
different code for early printk support.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Cc: linux-mips@linux-mips.org
Cc: Kathy Giori <kgiori@qca.qualcomm.com>
Cc: "Luis R. Rodriguez" <rodrigue@qca.qualcomm.com>
Patchwork: https://patchwork.linux-mips.org/patch/2521/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/ath79')
-rw-r--r-- | arch/mips/ath79/early_printk.c | 76 |
1 files changed, 67 insertions, 9 deletions
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c index 7499b0e9df26..6a51ced7a293 100644 --- a/arch/mips/ath79/early_printk.c +++ b/arch/mips/ath79/early_printk.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Atheros AR71XX/AR724X/AR913X SoC early printk support | 2 | * Atheros AR7XXX/AR9XXX SoC early printk support |
3 | * | 3 | * |
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | 4 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
@@ -10,27 +10,85 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
13 | #include <linux/errno.h> | ||
13 | #include <linux/serial_reg.h> | 14 | #include <linux/serial_reg.h> |
14 | #include <asm/addrspace.h> | 15 | #include <asm/addrspace.h> |
15 | 16 | ||
17 | #include <asm/mach-ath79/ath79.h> | ||
16 | #include <asm/mach-ath79/ar71xx_regs.h> | 18 | #include <asm/mach-ath79/ar71xx_regs.h> |
19 | #include <asm/mach-ath79/ar933x_uart.h> | ||
17 | 20 | ||
18 | static inline void prom_wait_thre(void __iomem *base) | 21 | static void (*_prom_putchar) (unsigned char); |
22 | |||
23 | static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val) | ||
19 | { | 24 | { |
20 | u32 lsr; | 25 | u32 t; |
21 | 26 | ||
22 | do { | 27 | do { |
23 | lsr = __raw_readl(base + UART_LSR * 4); | 28 | t = __raw_readl(reg); |
24 | if (lsr & UART_LSR_THRE) | 29 | if ((t & mask) == val) |
25 | break; | 30 | break; |
26 | } while (1); | 31 | } while (1); |
27 | } | 32 | } |
28 | 33 | ||
29 | void prom_putchar(unsigned char ch) | 34 | static void prom_putchar_ar71xx(unsigned char ch) |
30 | { | 35 | { |
31 | void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); | 36 | void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); |
32 | 37 | ||
33 | prom_wait_thre(base); | 38 | prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); |
34 | __raw_writel(ch, base + UART_TX * 4); | 39 | __raw_writel(ch, base + UART_TX * 4); |
35 | prom_wait_thre(base); | 40 | prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); |
41 | } | ||
42 | |||
43 | static void prom_putchar_ar933x(unsigned char ch) | ||
44 | { | ||
45 | void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE)); | ||
46 | |||
47 | prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, | ||
48 | AR933X_UART_DATA_TX_CSR); | ||
49 | __raw_writel(AR933X_UART_DATA_TX_CSR | ch, base + AR933X_UART_DATA_REG); | ||
50 | prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, | ||
51 | AR933X_UART_DATA_TX_CSR); | ||
52 | } | ||
53 | |||
54 | static void prom_putchar_dummy(unsigned char ch) | ||
55 | { | ||
56 | /* nothing to do */ | ||
57 | } | ||
58 | |||
59 | static void prom_putchar_init(void) | ||
60 | { | ||
61 | void __iomem *base; | ||
62 | u32 id; | ||
63 | |||
64 | base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE)); | ||
65 | id = __raw_readl(base + AR71XX_RESET_REG_REV_ID); | ||
66 | id &= REV_ID_MAJOR_MASK; | ||
67 | |||
68 | switch (id) { | ||
69 | case REV_ID_MAJOR_AR71XX: | ||
70 | case REV_ID_MAJOR_AR7240: | ||
71 | case REV_ID_MAJOR_AR7241: | ||
72 | case REV_ID_MAJOR_AR7242: | ||
73 | case REV_ID_MAJOR_AR913X: | ||
74 | _prom_putchar = prom_putchar_ar71xx; | ||
75 | break; | ||
76 | |||
77 | case REV_ID_MAJOR_AR9330: | ||
78 | case REV_ID_MAJOR_AR9331: | ||
79 | _prom_putchar = prom_putchar_ar933x; | ||
80 | break; | ||
81 | |||
82 | default: | ||
83 | _prom_putchar = prom_putchar_dummy; | ||
84 | break; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | void prom_putchar(unsigned char ch) | ||
89 | { | ||
90 | if (!_prom_putchar) | ||
91 | prom_putchar_init(); | ||
92 | |||
93 | _prom_putchar(ch); | ||
36 | } | 94 | } |