Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/ath79/early_printk.c
26439 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Atheros AR7XXX/AR9XXX SoC early printk support
4
*
5
* Copyright (C) 2008-2011 Gabor Juhos <[email protected]>
6
* Copyright (C) 2008 Imre Kaloz <[email protected]>
7
*/
8
9
#include <linux/io.h>
10
#include <linux/errno.h>
11
#include <linux/serial.h>
12
#include <linux/serial_reg.h>
13
#include <asm/addrspace.h>
14
#include <asm/setup.h>
15
16
#include <asm/mach-ath79/ath79.h>
17
#include <asm/mach-ath79/ar71xx_regs.h>
18
#include <asm/mach-ath79/ar933x_uart.h>
19
20
static void (*_prom_putchar)(char);
21
22
static inline void prom_putchar_wait(void __iomem *reg, u32 val)
23
{
24
u32 t;
25
26
do {
27
t = __raw_readl(reg);
28
if ((t & val) == val)
29
break;
30
} while (1);
31
}
32
33
static void prom_putchar_ar71xx(char ch)
34
{
35
void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
36
37
prom_putchar_wait(base + UART_LSR * 4, UART_LSR_BOTH_EMPTY);
38
__raw_writel((unsigned char)ch, base + UART_TX * 4);
39
prom_putchar_wait(base + UART_LSR * 4, UART_LSR_BOTH_EMPTY);
40
}
41
42
static void prom_putchar_ar933x(char ch)
43
{
44
void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE));
45
46
prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR);
47
__raw_writel(AR933X_UART_DATA_TX_CSR | (unsigned char)ch,
48
base + AR933X_UART_DATA_REG);
49
prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR);
50
}
51
52
static void prom_putchar_dummy(char ch)
53
{
54
/* nothing to do */
55
}
56
57
static void prom_enable_uart(u32 id)
58
{
59
void __iomem *gpio_base;
60
u32 uart_en;
61
u32 t;
62
63
switch (id) {
64
case REV_ID_MAJOR_AR71XX:
65
uart_en = AR71XX_GPIO_FUNC_UART_EN;
66
break;
67
68
case REV_ID_MAJOR_AR7240:
69
case REV_ID_MAJOR_AR7241:
70
case REV_ID_MAJOR_AR7242:
71
uart_en = AR724X_GPIO_FUNC_UART_EN;
72
break;
73
74
case REV_ID_MAJOR_AR913X:
75
uart_en = AR913X_GPIO_FUNC_UART_EN;
76
break;
77
78
case REV_ID_MAJOR_AR9330:
79
case REV_ID_MAJOR_AR9331:
80
uart_en = AR933X_GPIO_FUNC_UART_EN;
81
break;
82
83
case REV_ID_MAJOR_AR9341:
84
case REV_ID_MAJOR_AR9342:
85
case REV_ID_MAJOR_AR9344:
86
/* TODO */
87
default:
88
return;
89
}
90
91
gpio_base = (void __iomem *)KSEG1ADDR(AR71XX_GPIO_BASE);
92
t = __raw_readl(gpio_base + AR71XX_GPIO_REG_FUNC);
93
t |= uart_en;
94
__raw_writel(t, gpio_base + AR71XX_GPIO_REG_FUNC);
95
}
96
97
static void prom_putchar_init(void)
98
{
99
void __iomem *base;
100
u32 id;
101
102
base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE));
103
id = __raw_readl(base + AR71XX_RESET_REG_REV_ID);
104
id &= REV_ID_MAJOR_MASK;
105
106
switch (id) {
107
case REV_ID_MAJOR_AR71XX:
108
case REV_ID_MAJOR_AR7240:
109
case REV_ID_MAJOR_AR7241:
110
case REV_ID_MAJOR_AR7242:
111
case REV_ID_MAJOR_AR913X:
112
case REV_ID_MAJOR_AR9341:
113
case REV_ID_MAJOR_AR9342:
114
case REV_ID_MAJOR_AR9344:
115
case REV_ID_MAJOR_QCA9533:
116
case REV_ID_MAJOR_QCA9533_V2:
117
case REV_ID_MAJOR_QCA9556:
118
case REV_ID_MAJOR_QCA9558:
119
case REV_ID_MAJOR_TP9343:
120
case REV_ID_MAJOR_QCA956X:
121
case REV_ID_MAJOR_QCN550X:
122
_prom_putchar = prom_putchar_ar71xx;
123
break;
124
125
case REV_ID_MAJOR_AR9330:
126
case REV_ID_MAJOR_AR9331:
127
_prom_putchar = prom_putchar_ar933x;
128
break;
129
130
default:
131
_prom_putchar = prom_putchar_dummy;
132
return;
133
}
134
135
prom_enable_uart(id);
136
}
137
138
void prom_putchar(char ch)
139
{
140
if (!_prom_putchar)
141
prom_putchar_init();
142
143
_prom_putchar(ch);
144
}
145
146