| 1 | From 84ead7964e423c37a73da30a1a2c4c486f74242d Mon Sep 17 00:00:00 2001 |
| 2 | From: Gabor Juhos <juhosg@openwrt.org> |
| 3 | Date: Mon, 20 Jun 2011 21:26:03 +0200 |
| 4 | Subject: [PATCH 06/27] MIPS: ath79: Add early printk support for the AR933X SoCs |
| 5 | |
| 6 | The AR933X SoCs are using a different UART, thus require |
| 7 | different code for early printk support. |
| 8 | |
| 9 | Signed-off-by: Gabor Juhos <juhosg@openwrt.org> |
| 10 | Cc: linux-mips@linux-mips.org |
| 11 | Cc: Kathy Giori <kgiori@qca.qualcomm.com> |
| 12 | Cc: "Luis R. Rodriguez" <rodrigue@qca.qualcomm.com> |
| 13 | Patchwork: https://patchwork.linux-mips.org/patch/2521/ |
| 14 | Signed-off-by: Ralf Baechle <ralf@linux-mips.org> |
| 15 | --- |
| 16 | arch/mips/ath79/early_printk.c | 76 +++++++++++++++++++++--- |
| 17 | arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 3 + |
| 18 | arch/mips/include/asm/mach-ath79/ar933x_uart.h | 67 +++++++++++++++++++++ |
| 19 | 3 files changed, 137 insertions(+), 9 deletions(-) |
| 20 | create mode 100644 arch/mips/include/asm/mach-ath79/ar933x_uart.h |
| 21 | |
| 22 | --- a/arch/mips/ath79/early_printk.c |
| 23 | +++ b/arch/mips/ath79/early_printk.c |
| 24 | @@ -1,7 +1,7 @@ |
| 25 | /* |
| 26 | - * Atheros AR71XX/AR724X/AR913X SoC early printk support |
| 27 | + * Atheros AR7XXX/AR9XXX SoC early printk support |
| 28 | * |
| 29 | - * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> |
| 30 | + * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
| 31 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
| 32 | * |
| 33 | * This program is free software; you can redistribute it and/or modify it |
| 34 | @@ -10,27 +10,85 @@ |
| 35 | */ |
| 36 | |
| 37 | #include <linux/io.h> |
| 38 | +#include <linux/errno.h> |
| 39 | #include <linux/serial_reg.h> |
| 40 | #include <asm/addrspace.h> |
| 41 | |
| 42 | +#include <asm/mach-ath79/ath79.h> |
| 43 | #include <asm/mach-ath79/ar71xx_regs.h> |
| 44 | +#include <asm/mach-ath79/ar933x_uart.h> |
| 45 | |
| 46 | -static inline void prom_wait_thre(void __iomem *base) |
| 47 | +static void (*_prom_putchar) (unsigned char); |
| 48 | + |
| 49 | +static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val) |
| 50 | { |
| 51 | - u32 lsr; |
| 52 | + u32 t; |
| 53 | |
| 54 | do { |
| 55 | - lsr = __raw_readl(base + UART_LSR * 4); |
| 56 | - if (lsr & UART_LSR_THRE) |
| 57 | + t = __raw_readl(reg); |
| 58 | + if ((t & mask) == val) |
| 59 | break; |
| 60 | } while (1); |
| 61 | } |
| 62 | |
| 63 | -void prom_putchar(unsigned char ch) |
| 64 | +static void prom_putchar_ar71xx(unsigned char ch) |
| 65 | { |
| 66 | void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); |
| 67 | |
| 68 | - prom_wait_thre(base); |
| 69 | + prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); |
| 70 | __raw_writel(ch, base + UART_TX * 4); |
| 71 | - prom_wait_thre(base); |
| 72 | + prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); |
| 73 | +} |
| 74 | + |
| 75 | +static void prom_putchar_ar933x(unsigned char ch) |
| 76 | +{ |
| 77 | + void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE)); |
| 78 | + |
| 79 | + prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, |
| 80 | + AR933X_UART_DATA_TX_CSR); |
| 81 | + __raw_writel(AR933X_UART_DATA_TX_CSR | ch, base + AR933X_UART_DATA_REG); |
| 82 | + prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, |
| 83 | + AR933X_UART_DATA_TX_CSR); |
| 84 | +} |
| 85 | + |
| 86 | +static void prom_putchar_dummy(unsigned char ch) |
| 87 | +{ |
| 88 | + /* nothing to do */ |
| 89 | +} |
| 90 | + |
| 91 | +static void prom_putchar_init(void) |
| 92 | +{ |
| 93 | + void __iomem *base; |
| 94 | + u32 id; |
| 95 | + |
| 96 | + base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE)); |
| 97 | + id = __raw_readl(base + AR71XX_RESET_REG_REV_ID); |
| 98 | + id &= REV_ID_MAJOR_MASK; |
| 99 | + |
| 100 | + switch (id) { |
| 101 | + case REV_ID_MAJOR_AR71XX: |
| 102 | + case REV_ID_MAJOR_AR7240: |
| 103 | + case REV_ID_MAJOR_AR7241: |
| 104 | + case REV_ID_MAJOR_AR7242: |
| 105 | + case REV_ID_MAJOR_AR913X: |
| 106 | + _prom_putchar = prom_putchar_ar71xx; |
| 107 | + break; |
| 108 | + |
| 109 | + case REV_ID_MAJOR_AR9330: |
| 110 | + case REV_ID_MAJOR_AR9331: |
| 111 | + _prom_putchar = prom_putchar_ar933x; |
| 112 | + break; |
| 113 | + |
| 114 | + default: |
| 115 | + _prom_putchar = prom_putchar_dummy; |
| 116 | + break; |
| 117 | + } |
| 118 | +} |
| 119 | + |
| 120 | +void prom_putchar(unsigned char ch) |
| 121 | +{ |
| 122 | + if (!_prom_putchar) |
| 123 | + prom_putchar_init(); |
| 124 | + |
| 125 | + _prom_putchar(ch); |
| 126 | } |
| 127 | --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h |
| 128 | +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h |
| 129 | @@ -53,6 +53,9 @@ |
| 130 | #define AR913X_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000) |
| 131 | #define AR913X_WMAC_SIZE 0x30000 |
| 132 | |
| 133 | +#define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000) |
| 134 | +#define AR933X_UART_SIZE 0x14 |
| 135 | + |
| 136 | /* |
| 137 | * DDR_CTRL block |
| 138 | */ |
| 139 | --- /dev/null |
| 140 | +++ b/arch/mips/include/asm/mach-ath79/ar933x_uart.h |
| 141 | @@ -0,0 +1,67 @@ |
| 142 | +/* |
| 143 | + * Atheros AR933X UART defines |
| 144 | + * |
| 145 | + * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> |
| 146 | + * |
| 147 | + * This program is free software; you can redistribute it and/or modify it |
| 148 | + * under the terms of the GNU General Public License version 2 as published |
| 149 | + * by the Free Software Foundation. |
| 150 | + */ |
| 151 | + |
| 152 | +#ifndef __AR933X_UART_H |
| 153 | +#define __AR933X_UART_H |
| 154 | + |
| 155 | +#define AR933X_UART_REGS_SIZE 20 |
| 156 | +#define AR933X_UART_FIFO_SIZE 16 |
| 157 | + |
| 158 | +#define AR933X_UART_DATA_REG 0x00 |
| 159 | +#define AR933X_UART_CS_REG 0x04 |
| 160 | +#define AR933X_UART_CLOCK_REG 0x08 |
| 161 | +#define AR933X_UART_INT_REG 0x0c |
| 162 | +#define AR933X_UART_INT_EN_REG 0x10 |
| 163 | + |
| 164 | +#define AR933X_UART_DATA_TX_RX_MASK 0xff |
| 165 | +#define AR933X_UART_DATA_RX_CSR BIT(8) |
| 166 | +#define AR933X_UART_DATA_TX_CSR BIT(9) |
| 167 | + |
| 168 | +#define AR933X_UART_CS_PARITY_S 0 |
| 169 | +#define AR933X_UART_CS_PARITY_M 0x3 |
| 170 | +#define AR933X_UART_CS_PARITY_NONE 0 |
| 171 | +#define AR933X_UART_CS_PARITY_ODD 1 |
| 172 | +#define AR933X_UART_CS_PARITY_EVEN 2 |
| 173 | +#define AR933X_UART_CS_IF_MODE_S 2 |
| 174 | +#define AR933X_UART_CS_IF_MODE_M 0x3 |
| 175 | +#define AR933X_UART_CS_IF_MODE_NONE 0 |
| 176 | +#define AR933X_UART_CS_IF_MODE_DTE 1 |
| 177 | +#define AR933X_UART_CS_IF_MODE_DCE 2 |
| 178 | +#define AR933X_UART_CS_FLOW_CTRL_S 4 |
| 179 | +#define AR933X_UART_CS_FLOW_CTRL_M 0x3 |
| 180 | +#define AR933X_UART_CS_DMA_EN BIT(6) |
| 181 | +#define AR933X_UART_CS_TX_READY_ORIDE BIT(7) |
| 182 | +#define AR933X_UART_CS_RX_READY_ORIDE BIT(8) |
| 183 | +#define AR933X_UART_CS_TX_READY BIT(9) |
| 184 | +#define AR933X_UART_CS_RX_BREAK BIT(10) |
| 185 | +#define AR933X_UART_CS_TX_BREAK BIT(11) |
| 186 | +#define AR933X_UART_CS_HOST_INT BIT(12) |
| 187 | +#define AR933X_UART_CS_HOST_INT_EN BIT(13) |
| 188 | +#define AR933X_UART_CS_TX_BUSY BIT(14) |
| 189 | +#define AR933X_UART_CS_RX_BUSY BIT(15) |
| 190 | + |
| 191 | +#define AR933X_UART_CLOCK_STEP_M 0xffff |
| 192 | +#define AR933X_UART_CLOCK_SCALE_M 0xfff |
| 193 | +#define AR933X_UART_CLOCK_SCALE_S 16 |
| 194 | +#define AR933X_UART_CLOCK_STEP_M 0xffff |
| 195 | + |
| 196 | +#define AR933X_UART_INT_RX_VALID BIT(0) |
| 197 | +#define AR933X_UART_INT_TX_READY BIT(1) |
| 198 | +#define AR933X_UART_INT_RX_FRAMING_ERR BIT(2) |
| 199 | +#define AR933X_UART_INT_RX_OFLOW_ERR BIT(3) |
| 200 | +#define AR933X_UART_INT_TX_OFLOW_ERR BIT(4) |
| 201 | +#define AR933X_UART_INT_RX_PARITY_ERR BIT(5) |
| 202 | +#define AR933X_UART_INT_RX_BREAK_ON BIT(6) |
| 203 | +#define AR933X_UART_INT_RX_BREAK_OFF BIT(7) |
| 204 | +#define AR933X_UART_INT_RX_FULL BIT(8) |
| 205 | +#define AR933X_UART_INT_TX_EMPTY BIT(9) |
| 206 | +#define AR933X_UART_INT_ALLINTS 0x3ff |
| 207 | + |
| 208 | +#endif /* __AR933X_UART_H */ |
| 209 | |