xref: /linux/arch/mips/pic32/pic32mzda/early_console.c (revision 6086f349a30232f3119ec647356cd191087b1333)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Joshua Henderson <joshua.henderson@microchip.com>
4  * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
5  */
6 #include <linux/io.h>
7 #include <linux/platform_data/pic32.h>
8 #include <asm/fw/fw.h>
9 #include <asm/setup.h>
10 
11 #include "pic32mzda.h"
12 #include "early_pin.h"
13 
14 /* Default early console parameters */
15 #define EARLY_CONSOLE_PORT	1
16 #define EARLY_CONSOLE_BAUDRATE	115200
17 
18 #define UART_ENABLE		BIT(15)
19 #define UART_ENABLE_RX		BIT(12)
20 #define UART_ENABLE_TX		BIT(10)
21 #define UART_TX_FULL		BIT(9)
22 
23 /* UART1(x == 0) - UART6(x == 5) */
24 #define UART_BASE(x)	((x) * 0x0200)
25 #define U_MODE(x)	UART_BASE(x)
26 #define U_STA(x)	(UART_BASE(x) + 0x10)
27 #define U_TXR(x)	(UART_BASE(x) + 0x20)
28 #define U_BRG(x)	(UART_BASE(x) + 0x40)
29 
30 static void __iomem *uart_base;
31 static int console_port = -1;
32 
configure_uart_pins(int port)33 static int __init configure_uart_pins(int port)
34 {
35 	switch (port) {
36 	case 1:
37 		pic32_pps_input(IN_FUNC_U2RX, IN_RPB0);
38 		pic32_pps_output(OUT_FUNC_U2TX, OUT_RPG9);
39 		break;
40 	case 5:
41 		pic32_pps_input(IN_FUNC_U6RX, IN_RPD0);
42 		pic32_pps_output(OUT_FUNC_U6TX, OUT_RPB8);
43 		break;
44 	default:
45 		return -1;
46 	}
47 
48 	return 0;
49 }
50 
configure_uart(int port,int baud)51 static void __init configure_uart(int port, int baud)
52 {
53 	u32 pbclk;
54 
55 	pbclk = pic32_get_pbclk(2);
56 
57 	__raw_writel(0, uart_base + U_MODE(port));
58 	__raw_writel(((pbclk / baud) / 16) - 1, uart_base + U_BRG(port));
59 	__raw_writel(UART_ENABLE, uart_base + U_MODE(port));
60 	__raw_writel(UART_ENABLE_TX | UART_ENABLE_RX,
61 		     uart_base + PIC32_SET(U_STA(port)));
62 }
63 
setup_early_console(int port,int baud)64 static void __init setup_early_console(int port, int baud)
65 {
66 	if (configure_uart_pins(port))
67 		return;
68 
69 	console_port = port;
70 	configure_uart(console_port, baud);
71 }
72 
pic32_getcmdline(void)73 static char * __init pic32_getcmdline(void)
74 {
75 	/*
76 	 * arch_mem_init() has not been called yet, so we don't have a real
77 	 * command line setup if using CONFIG_CMDLINE_BOOL.
78 	 */
79 #ifdef CONFIG_CMDLINE_OVERRIDE
80 	return CONFIG_CMDLINE;
81 #else
82 	return fw_getcmdline();
83 #endif
84 }
85 
get_port_from_cmdline(char * arch_cmdline)86 static int __init get_port_from_cmdline(char *arch_cmdline)
87 {
88 	char *s;
89 	int port = -1;
90 
91 	if (!arch_cmdline || *arch_cmdline == '\0')
92 		goto _out;
93 
94 	s = strstr(arch_cmdline, "earlyprintk=");
95 	if (s) {
96 		s = strstr(s, "ttyS");
97 		if (s)
98 			s += 4;
99 		else
100 			goto _out;
101 
102 		port = (*s) - '0';
103 	}
104 
105 _out:
106 	return port;
107 }
108 
get_baud_from_cmdline(char * arch_cmdline)109 static int __init get_baud_from_cmdline(char *arch_cmdline)
110 {
111 	char *s;
112 	int baud = -1;
113 
114 	if (!arch_cmdline || *arch_cmdline == '\0')
115 		goto _out;
116 
117 	s = strstr(arch_cmdline, "earlyprintk=");
118 	if (s) {
119 		s = strstr(s, "ttyS");
120 		if (s)
121 			s += 6;
122 		else
123 			goto _out;
124 
125 		baud = 0;
126 		while (*s >= '0' && *s <= '9')
127 			baud = baud * 10 + *s++ - '0';
128 	}
129 
130 _out:
131 	return baud;
132 }
133 
fw_init_early_console(void)134 void __init fw_init_early_console(void)
135 {
136 	char *arch_cmdline = pic32_getcmdline();
137 	int baud, port;
138 
139 	uart_base = ioremap(PIC32_BASE_UART, 0xc00);
140 
141 	baud = get_baud_from_cmdline(arch_cmdline);
142 	port = get_port_from_cmdline(arch_cmdline);
143 
144 	if (port == -1)
145 		port = EARLY_CONSOLE_PORT;
146 
147 	if (baud == -1)
148 		baud = EARLY_CONSOLE_BAUDRATE;
149 
150 	setup_early_console(port, baud);
151 }
152 
prom_putchar(char c)153 void prom_putchar(char c)
154 {
155 	if (console_port >= 0) {
156 		while (__raw_readl(
157 				uart_base + U_STA(console_port)) & UART_TX_FULL)
158 			;
159 
160 		__raw_writel(c, uart_base + U_TXR(console_port));
161 	}
162 }
163