From: Du Huanpeng <[email protected]> set pin to uart alternate function and enable uart for lowlevel debug, also future pinctrl driver can base on this code.
Signed-off-by: Du Huanpeng <[email protected]> --- arch/mips/mach-loongson/include/mach/serial.h | 16 +++ arch/mips/mach-loongson/ls1c300/gpio.c | 66 +++++++++++ arch/mips/mach-loongson/ls1c300/serial.c | 104 ++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 arch/mips/mach-loongson/include/mach/serial.h create mode 100644 arch/mips/mach-loongson/ls1c300/gpio.c create mode 100644 arch/mips/mach-loongson/ls1c300/serial.c diff --git a/arch/mips/mach-loongson/include/mach/serial.h b/arch/mips/mach-loongson/include/mach/serial.h new file mode 100644 index 00000000000..7afe5788cb7 --- /dev/null +++ b/arch/mips/mach-loongson/include/mach/serial.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020 MediaTek Inc. + * + * Author: Gao Weijie <[email protected]> + * + * Copyright (C) 2022 Du Huanpeng <[email protected]> + */ + +#ifndef __LSMIPS_SERIAL_H_ +#define __LSMIPS_SERIAL_H_ + +void loongson_spl_serial_init(void); +int gpio_set_alternate(int gpio, int func); + +#endif /* __LSMIPS_SERIAL_H_ */ diff --git a/arch/mips/mach-loongson/ls1c300/gpio.c b/arch/mips/mach-loongson/ls1c300/gpio.c new file mode 100644 index 00000000000..7f160408382 --- /dev/null +++ b/arch/mips/mach-loongson/ls1c300/gpio.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Du Huanpeng <[email protected]> + */ + +#include <linux/errno.h> +#include <asm/bitops.h> + +#define CBUS_FIRST0 0xbfd011c0 +#define CBUS_SECOND0 0xbfd011d0 +#define CBUS_THIRD0 0xbfd011e0 +#define CBUS_FOURTHT0 0xbfd011f0 +#define CBUS_FIFTHT0 0xbfd01200 + +#define CBUS_FIRST1 0xbfd011c4 +#define CBUS_SECOND1 0xbfd011d4 +#define CBUS_THIRD1 0xbfd011e4 +#define CBUS_FOURTHT1 0xbfd011f4 +#define CBUS_FIFTHT1 0xbfd01204 + +#define CBUS_FIRST2 0xbfd011c8 +#define CBUS_SECOND2 0xbfd011d8 +#define CBUS_THIRD2 0xbfd011e8 +#define CBUS_FOURTHT2 0xbfd011f8 +#define CBUS_FIFTHT2 0xbfd01208 + +#define CBUS_FIRST3 0xbfd011cc +#define CBUS_SECOND3 0xbfd011dc +#define CBUS_THIRD3 0xbfd011ec +#define CBUS_FOURTHT3 0xbfd011fc +#define CBUS_FIFTHT3 0xbfd0120c + +/* + * pinmux for debug uart and spl only, for others, please + * use a pinctrl driver and device-tree for pin muxing. + * + * @gpio: gpio number + * @func: alternate function 1 to 5, 0 for GPIO. + */ + +int gpio_set_alternate(int gpio, int func) +{ + volatile void __iomem *addr; + int i; + + if (gpio < 0 || gpio > 104) + return -ENODEV; + if (func < 0 || func > 5) + return -EINVAL; + + if (func) { + i = func - 1; + addr = (void *)CBUS_FIRST0 + i * 16; + set_bit(gpio, addr); + } else { + /* GPIO, clear CBUS 1 ~ 5 */ + i = 5; + } + + while (i--) { + addr = (void *)CBUS_FIRST0 + 16 * i; + clear_bit(gpio, addr); + } + + return 0; +} diff --git a/arch/mips/mach-loongson/ls1c300/serial.c b/arch/mips/mach-loongson/ls1c300/serial.c new file mode 100644 index 00000000000..a7697574dad --- /dev/null +++ b/arch/mips/mach-loongson/ls1c300/serial.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020-2026 Du Huanpeng <[email protected]> + */ + +#include <mach/serial.h> +#include <linux/kernel.h> + +struct uart_pin_config { + char port; + char afunc; + char rx; + char tx; +}; + +struct uart_pin_config con[] = { +#if CONFIG_CONS_INDEX == 0 + { 0, 2, 74, 75 }, + { 0, 3, 23, 24 }, + { 0, 3, 99, 100 }, + +#elif CONFIG_CONS_INDEX == 1 + { 1, 1, 17, 18 }, + { 1, 1, 101, 102 }, + { 1, 2, 40, 41 }, + { 1, 4, 2, 3 }, + +#elif CONFIG_CONS_INDEX == 2 + { 2, 2, 36, 37 }, + { 2, 2, 42, 43 }, + { 2, 3, 27, 28 }, + { 2, 3, 103, 104 }, + { 2, 4, 4, 5 }, + +#elif CONFIG_CONS_INDEX == 3 + { 3, 2, 17, 18 }, + { 3, 2, 33, 34 }, + { 3, 2, 44, 45 }, + { 3, 4, 0, 1 }, + +#elif CONFIG_CONS_INDEX == 4 + { 4, 5, 23, 24 }, + { 4, 5, 58, 59 }, + { 4, 5, 80, 79 }, + +#elif CONFIG_CONS_INDEX == 5 + { 5, 5, 25, 26 }, + { 5, 5, 60, 61 }, + { 5, 5, 81, 78 }, + +#elif CONFIG_CONS_INDEX == 6 + { 6, 5, 27, 46 }, + { 6, 5, 62, 63 }, + +#elif CONFIG_CONS_INDEX == 7 + { 7, 5, 57, 56 }, + { 7, 5, 64, 65 }, + { 7, 5, 87, 88 }, + +#elif CONFIG_CONS_INDEX == 8 + { 8, 5, 55, 54 }, + { 8, 5, 66, 67 }, + { 8, 5, 89, 90 }, + +#elif CONFIG_CONS_INDEX == 9 + { 9, 5, 53, 52 }, + { 9, 5, 68, 69 }, + { 9, 5, 85, 86 }, + +#elif CONFIG_CONS_INDEX == 10 + { 10, 5, 51, 50 }, + { 10, 5, 70, 71 }, + { 10, 5, 84, 82 }, + +#elif CONFIG_CONS_INDEX == 11 + { 11, 5, 49, 48 }, + { 11, 5, 72, 73 }, +#endif /* CONFIG_CONS_INDEX */ +}; + +#define UART2_RX 36 +#define UART2_TX 37 +#define AFUNC 2 + +void loongson_spl_serial_init(void) +{ +#if defined(CONFIG_SPL_SERIAL) + int pin_rx, pin_tx; + int afunc; + + if (CONFIG_CONS_PIN < ARRAY_SIZE(con)) { + pin_rx = con[CONFIG_CONS_PIN].rx; + pin_tx = con[CONFIG_CONS_PIN].tx; + afunc = con[CONFIG_CONS_PIN].afunc; + } else { + pin_rx = UART2_RX; + pin_tx = UART2_TX; + afunc = AFUNC; + } + + gpio_set_alternate(pin_rx, afunc); + gpio_set_alternate(pin_tx, afunc); +#endif /* CONFIG_SPL_SERIAL */ +} -- 2.43.0

