root/arch/mips/ath79/early_printk.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. prom_putchar_wait
  2. prom_putchar_ar71xx
  3. prom_putchar_ar933x
  4. prom_putchar_dummy
  5. prom_enable_uart
  6. prom_putchar_init
  7. prom_putchar

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  Atheros AR7XXX/AR9XXX SoC early printk support
   4  *
   5  *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
   6  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
   7  */
   8 
   9 #include <linux/io.h>
  10 #include <linux/errno.h>
  11 #include <linux/serial_reg.h>
  12 #include <asm/addrspace.h>
  13 #include <asm/setup.h>
  14 
  15 #include <asm/mach-ath79/ath79.h>
  16 #include <asm/mach-ath79/ar71xx_regs.h>
  17 #include <asm/mach-ath79/ar933x_uart.h>
  18 
  19 static void (*_prom_putchar)(char);
  20 
  21 static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val)
  22 {
  23         u32 t;
  24 
  25         do {
  26                 t = __raw_readl(reg);
  27                 if ((t & mask) == val)
  28                         break;
  29         } while (1);
  30 }
  31 
  32 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
  33 
  34 static void prom_putchar_ar71xx(char ch)
  35 {
  36         void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
  37 
  38         prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
  39         __raw_writel((unsigned char)ch, base + UART_TX * 4);
  40         prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
  41 }
  42 
  43 static void prom_putchar_ar933x(char ch)
  44 {
  45         void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE));
  46 
  47         prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR,
  48                           AR933X_UART_DATA_TX_CSR);
  49         __raw_writel(AR933X_UART_DATA_TX_CSR | (unsigned char)ch,
  50                      base + AR933X_UART_DATA_REG);
  51         prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR,
  52                           AR933X_UART_DATA_TX_CSR);
  53 }
  54 
  55 static void prom_putchar_dummy(char ch)
  56 {
  57         /* nothing to do */
  58 }
  59 
  60 static void prom_enable_uart(u32 id)
  61 {
  62         void __iomem *gpio_base;
  63         u32 uart_en;
  64         u32 t;
  65 
  66         switch (id) {
  67         case REV_ID_MAJOR_AR71XX:
  68                 uart_en = AR71XX_GPIO_FUNC_UART_EN;
  69                 break;
  70 
  71         case REV_ID_MAJOR_AR7240:
  72         case REV_ID_MAJOR_AR7241:
  73         case REV_ID_MAJOR_AR7242:
  74                 uart_en = AR724X_GPIO_FUNC_UART_EN;
  75                 break;
  76 
  77         case REV_ID_MAJOR_AR913X:
  78                 uart_en = AR913X_GPIO_FUNC_UART_EN;
  79                 break;
  80 
  81         case REV_ID_MAJOR_AR9330:
  82         case REV_ID_MAJOR_AR9331:
  83                 uart_en = AR933X_GPIO_FUNC_UART_EN;
  84                 break;
  85 
  86         case REV_ID_MAJOR_AR9341:
  87         case REV_ID_MAJOR_AR9342:
  88         case REV_ID_MAJOR_AR9344:
  89                 /* TODO */
  90         default:
  91                 return;
  92         }
  93 
  94         gpio_base = (void __iomem *)KSEG1ADDR(AR71XX_GPIO_BASE);
  95         t = __raw_readl(gpio_base + AR71XX_GPIO_REG_FUNC);
  96         t |= uart_en;
  97         __raw_writel(t, gpio_base + AR71XX_GPIO_REG_FUNC);
  98 }
  99 
 100 static void prom_putchar_init(void)
 101 {
 102         void __iomem *base;
 103         u32 id;
 104 
 105         base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE));
 106         id = __raw_readl(base + AR71XX_RESET_REG_REV_ID);
 107         id &= REV_ID_MAJOR_MASK;
 108 
 109         switch (id) {
 110         case REV_ID_MAJOR_AR71XX:
 111         case REV_ID_MAJOR_AR7240:
 112         case REV_ID_MAJOR_AR7241:
 113         case REV_ID_MAJOR_AR7242:
 114         case REV_ID_MAJOR_AR913X:
 115         case REV_ID_MAJOR_AR9341:
 116         case REV_ID_MAJOR_AR9342:
 117         case REV_ID_MAJOR_AR9344:
 118         case REV_ID_MAJOR_QCA9533:
 119         case REV_ID_MAJOR_QCA9533_V2:
 120         case REV_ID_MAJOR_QCA9556:
 121         case REV_ID_MAJOR_QCA9558:
 122         case REV_ID_MAJOR_TP9343:
 123         case REV_ID_MAJOR_QCA956X:
 124                 _prom_putchar = prom_putchar_ar71xx;
 125                 break;
 126 
 127         case REV_ID_MAJOR_AR9330:
 128         case REV_ID_MAJOR_AR9331:
 129                 _prom_putchar = prom_putchar_ar933x;
 130                 break;
 131 
 132         default:
 133                 _prom_putchar = prom_putchar_dummy;
 134                 return;
 135         }
 136 
 137         prom_enable_uart(id);
 138 }
 139 
 140 void prom_putchar(char ch)
 141 {
 142         if (!_prom_putchar)
 143                 prom_putchar_init();
 144 
 145         _prom_putchar(ch);
 146 }

/* [<][>][^][v][top][bottom][index][help] */