ソースを参照

ar71xx: update early_printk code

SVN-Revision: 27165
Gabor Juhos 14 年 前
コミット
b58ede16a5

+ 54 - 44
target/linux/ar71xx/files/arch/mips/ar71xx/early_printk.c

@@ -15,72 +15,82 @@
 #include <asm/addrspace.h>
 
 #include <asm/mach-ar71xx/ar71xx.h>
+#include <asm/mach-ar71xx/ar933x_uart.h>
 
-static void __iomem *prom_uart_base;
-static void (*_putchar)(unsigned char);
+static void (*_prom_putchar) (unsigned char);
 
-#define UART_READ(r) \
-	__raw_readl(prom_uart_base + 4 * (r))
+static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val)
+{
+	u32 t;
 
-#define UART_WRITE(r, v) \
-	__raw_writel((v), prom_uart_base + 4 * (r))
+	do {
+		t = __raw_readl(reg);
+		if ((t & mask) == val)
+			break;
+	} while (1);
+}
 
 static void prom_putchar_ar71xx(unsigned char ch)
 {
-	while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0)
-		;
-	UART_WRITE(UART_TX, ch);
-	while (((UART_READ(UART_LSR)) & UART_LSR_THRE) == 0)
-		;
+	void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
+
+	prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
+	__raw_writel(ch, base + UART_TX * 4);
+	prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
 }
 
 static void prom_putchar_ar933x(unsigned char ch)
 {
-	while (((UART_READ(0)) & 0x200) == 0)
-		;
-	UART_WRITE(0, 0x200 | ch);
-	while (((UART_READ(0)) & 0x200) == 0)
-		;
+	void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE));
+
+	prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR,
+			  AR933X_UART_DATA_TX_CSR);
+	__raw_writel(AR933X_UART_DATA_TX_CSR | ch, base + AR933X_UART_DATA_REG);
+	prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR,
+			  AR933X_UART_DATA_TX_CSR);
 }
 
-static int prom_putchar_init(void)
+static void prom_putchar_dummy(unsigned char ch)
 {
-	if (_putchar)
-		return 0;
-
-	switch(ar71xx_soc) {
-	case AR71XX_SOC_AR7130:
-	case AR71XX_SOC_AR7141:
-	case AR71XX_SOC_AR7161:
-	case AR71XX_SOC_AR7240:
-	case AR71XX_SOC_AR7241:
-	case AR71XX_SOC_AR7242:
-	case AR71XX_SOC_AR9130:
-	case AR71XX_SOC_AR9132:
-	case AR71XX_SOC_AR9341:
-	case AR71XX_SOC_AR9342:
-	case AR71XX_SOC_AR9344:
-		prom_uart_base = (void __iomem *) KSEG1ADDR(AR71XX_UART_BASE);
-		_putchar = prom_putchar_ar71xx;
+	/* nothing to do */
+}
+
+static void prom_putchar_init(void)
+{
+	void __iomem *base;
+	u32 id;
+
+	base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE));
+	id = __raw_readl(base + AR71XX_RESET_REG_REV_ID);
+	id &= REV_ID_MAJOR_MASK;
+
+	switch (id) {
+	case REV_ID_MAJOR_AR71XX:
+	case REV_ID_MAJOR_AR7240:
+	case REV_ID_MAJOR_AR7241:
+	case REV_ID_MAJOR_AR7242:
+	case REV_ID_MAJOR_AR913X:
+	case REV_ID_MAJOR_AR9341:
+	case REV_ID_MAJOR_AR9342:
+	case REV_ID_MAJOR_AR9344:
+		_prom_putchar = prom_putchar_ar71xx;
 		break;
 
-	case AR71XX_SOC_AR9330:
-	case AR71XX_SOC_AR9331:
-		prom_uart_base = (void __iomem *) KSEG1ADDR(AR933X_UART_BASE);
-		_putchar = prom_putchar_ar933x;
+	case REV_ID_MAJOR_AR9330:
+	case REV_ID_MAJOR_AR9331:
+		_prom_putchar = prom_putchar_ar933x;
 		break;
 
 	default:
-		return -ENODEV;
+		_prom_putchar = prom_putchar_dummy;
+		break;
 	}
-
-	return 0;
 }
 
 void prom_putchar(unsigned char ch)
 {
-	if (prom_putchar_init())
-		return;
+	if (!_prom_putchar)
+		prom_putchar_init();
 
-	_putchar(ch);
+	_prom_putchar(ch);
 }

+ 58 - 0
target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/ar933x_uart.h

@@ -0,0 +1,58 @@
+/*
+ *  Atheros AR933X UART defines
+ *
+ *  Copyright (C) 2011 Gabor Juhos <[email protected]>
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ */
+
+#ifndef __AR933X_UART_H
+#define __AR933X_UART_H
+
+#define AR933X_UART_DATA_REG		0x00
+#define AR933X_UART_CS_REG		0x04
+#define AR933X_UART_CLOCK_REG		0x08
+#define AR933X_UART_INT_REG		0x0c
+#define AR933X_UART_INT_EN_REG		0x10
+
+#define AR933X_UART_DATA_TX_RX_MASK	0xff
+#define AR933X_UART_DATA_RX_CSR		BIT(8)
+#define AR933X_UART_DATA_TX_CSR		BIT(9)
+
+#define AR933X_UART_CS_PARITY_S		0
+#define AR933X_UART_CS_PARITY_M		0x3
+#define AR933X_UART_CS_PARITY_M		0x3
+#define AR933X_UART_CS_IF_MODE_S	2
+#define AR933X_UART_CS_IF_MODE_M	0x3
+#define AR933X_UART_CS_FLOW_CTRL_S	4
+#define AR933X_UART_CS_FLOW_CTRL_M	0x3
+#define AR933X_UART_CS_DMA_EN		BIT(6)
+#define AR933X_UART_CS_TX_READY_ORIDE	BIT(7)
+#define AR933X_UART_CS_RX_READY_ORIDE	BIT(8)
+#define AR933X_UART_CS_TX_READY		BIT(9)
+#define AR933X_UART_CS_RX_BREAK		BIT(10)
+#define AR933X_UART_CS_TX_BREAK		BIT(11)
+#define AR933X_UART_CS_HOST_INT		BIT(12)
+#define AR933X_UART_CS_HOST_INT_EN	BIT(13)
+#define AR933X_UART_CS_TX_BUSY		BIT(14)
+#define AR933X_UART_CS_RX_BUSY		BIT(15)
+
+#define AR933X_UART_CLOCK_STEP_M	0xffff
+#define AR933X_UART_CLOCK_SCALE_M	0xfff
+#define AR933X_UART_CLCOK_SCALE_S	16
+
+#define AR933X_UART_INT_RX_VALID	BIT(0)
+#define AR933X_UART_INT_TX_READY	BIT(1)
+#define AR933X_UART_INT_RX_FRAMING_ERR	BIT(2)
+#define AR933X_UART_INT_RX_OFLOW_ERR	BIT(3)
+#define AR933X_UART_INT_TX_OFLOW_ERR	BIT(4)
+#define AR933X_UART_INT_RX_PARITY_ERR	BIT(5)
+#define AR933X_UART_INT_RX_BREAK_ON	BIT(6)
+#define AR933X_UART_INT_RX_BREAK_OFF	BIT(7)
+#define AR933X_UART_INT_RX_FULL		BIT(8)
+#define AR933X_UART_INT_TX_EMPTY	BIT(9)
+#define AR933X_UART_INT_ALLINTS		0x3ff
+
+#endif /* __AR933X_UART_H */