MT7621原廠openwrt SDK使能串列埠2和串列埠3
MT7621有三個串列埠,專案需要將三個串列埠都使能;
首先按照openwrt的方法修改DTS檔案來使能串列埠2和串列埠3是不行的,經試驗,還是要按照MTK傳統的方法,修改核心原始碼來解決;不同SDK版本可能不一定相同,因此僅供參考。
一)首先修改gpio mode使能串列埠2和串列埠3;
原廠SDK,預設串列埠3是不使能的;需要通過修改ralink_gpio.h和ralink_gpio.c來先將串列埠3使能;
linux-ramips_mt7621/linux-3.10.14-p112871/drivers/char/ralink_gpio.h
下面是#define RALINK_GPIOMODE_UART3 和 #define RALINK_GPIOMODE_UART2的預設定義
#elif defined (CONFIG_RALINK_MT7621)
#define RALINK_GPIOMODE_UART1 0x02
#define RALINK_GPIOMODE_I2C 0x04
#define RALINK_GPIOMODE_UART3 0x08
#define RALINK_GPIOMODE_UART2 0x20
#define RALINK_GPIOMODE_JTAG 0x80
#define RALINK_GPIOMODE_WDT 0x100
#define RALINK_GPIOMODE_PERST 0x400
#define RALINK_GPIOMODE_MDIO 0x1000
#define RALINK_GPIOMODE_GE1 0x4000
#define RALINK_GPIOMODE_GE2 0x8000
#define RALINK_GPIOMODE_SPI 0x10000
#define RALINK_GPIOMODE_SDXC 0x40000
#define RALINK_GPIOMODE_ESWINT 0x100000
#elif defined (CONFIG_RALINK_MT7628)
根據手冊中的說明,如果要使能串列埠2和串列埠3的話,修改如下
//#define RALINK_GPIOMODE_UART3 0x08
//#define RALINK_GPIOMODE_UART2 0x20
#define RALINK_GPIOMODE_UART3 0x00
#define RALINK_GPIOMODE_UART2 0x00
另外一個巨集是RALINK_GPIOMODE_DFT,定義了板子預設的GPIOMODE;可以根據自己的需求進行修改;
// if you would like to enable GPIO mode for other pins, please modify this value
// !! Warning: changing this value may make other features(MDIO, PCI, etc) lose efficacy
#if defined (CONFIG_RALINK_MT7621)
#define RALINK_GPIOMODE_DFT (RALINK_GPIOMODE_UART2 | RALINK_GPIOMODE_UART3 | RALINK_GPIOMODE_WDT)
#elif defined (CONFIG_RALINK_MT7620)
#define RALINK_GPIOMODE_DFT (RALINK_GPIOMODE_I2C)
#elif defined (CONFIG_RALINK_MT7628)
#define RALINK_GPIOMODE_DFT (RALINK_GPIOMODE_UART2 | RALINK_GPIOMODE_UART3) | (RALINK_GPIOMODE_SPI_CS1) | (RALINK_GPIOMODE_WDT)
#else
#define RALINK_GPIOMODE_DFT (RALINK_GPIOMODE_UARTF)
#endif
在ralink_gpio.c中它在如下地方使用到;
int __init ralink_gpio_init(void)
{
unsigned int i;
u32 gpiomode;
……
//config these pins to gpio mode
gpiomode = le32_to_cpu(*(volatile u32 *)(RALINK_REG_GPIOMODE));
#if !defined (CONFIG_RALINK_RT2880)
gpiomode &= ~0x1C; //clear bit[2:4]UARTF_SHARE_MODE
#endif
#if defined (CONFIG_RALINK_MT7620)
gpiomode &= ~0x2000; //clear bit[13] WLAN_LED
#endif
#if defined (CONFIG_RALINK_MT7621)
gpiomode &= ~0x3C; //clear bit[2:6]UART2_SHARE_MODE UART3_SHARE_MODE
#endif
gpiomode |= RALINK_GPIOMODE_DFT;
*(volatile u32 *)(RALINK_REG_GPIOMODE) = cpu_to_le32(gpiomode);
二)在init.c中建立對應的串列埠裝置
1)串列埠的中斷號在如下檔案中定義
surfboardint.h
#define SURFBOARDINT_UART_LITE1 26 /* UART Lite */
#define SURFBOARDINT_UART_LITE2 27 /* UART Lite */
#define SURFBOARDINT_UART_LITE3 28 /* UART Lite */
#define SURFBOARDINT_UART SURFBOARDINT_UART_LITE2 //ttyS0
#define SURFBOARDINT_UART1 SURFBOARDINT_UART_LITE1 //ttyS1
2)修改init.c
linux-ramips_mt7621/linux-3.10.14-p112871/arch/mips/relink/init.c中
static struct uart_port serial_req[3];
__init int prom_init_serial_port(void)
{
……
#if defined (CONFIG_RALINK_MT7621)
serial_req[2].type = PORT_16550A;
serial_req[2].line = 2;
serial_req[2].irq = SURFBOARDINT_UART_LITE3;
serial_req[2].flags = UPF_FIXED_TYPE;
serial_req[2].uartclk = 50000000;
serial_req[2].iotype = UPIO_MEM32;
serial_req[2].regshift = 2;
serial_req[2].mapbase = RALINK_UART_LITE3_BASE;
serial_req[2].membase = ioremap_nocache(RALINK_UART_LITE3_BASE, PAGE_SIZE);
early_serial_setup(&serial_req[2]);
#endif
以及修改prom_get_ttysnum和serial_setbrg這兩個函式,增加對串列埠3的描述;
三)修改CONFIG_SERIAL_8250_RUNTIME_UARTS
通過配置核心,以讓串列埠驅動支援串列埠3
drivers\tty\serial\8250\8250_core.c
static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
通過“make kernel_menuconfig”修改系統串列埠數量 CONFIG_SERIAL_8250_RUNTIME_UARTS
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_SERIAL_8250_PCI is not set
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
# CONFIG_SERIAL_8250_EXTENDED is not set
# CONFIG_SERIAL_8250_DW is not set
# CONFIG_SERIAL_8250_RT288X is not set
static void __init serial8250_isa_init_ports(void)
{
struct uart_8250_port *up;
static int first = 1;
int i, irqflag = 0;
if (!first)
return;
first = 0;
if (nr_uarts > UART_NR)
nr_uarts = UART_NR;
for (i = 0; i < nr_uarts; i++) {
struct uart_8250_port *up = &serial8250_ports[i];
struct uart_port *port = &up->port;