linux/arch/mips/pic32/pic32mzda/early_console.c
<<
>>
Prefs
   1/*
   2 * Joshua Henderson <joshua.henderson@microchip.com>
   3 * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
   4 *
   5 *  This program is free software; you can distribute it and/or modify it
   6 *  under the terms of the GNU General Public License (Version 2) as
   7 *  published by the Free Software Foundation.
   8 *
   9 *  This program is distributed in the hope it will be useful, but WITHOUT
  10 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 *  for more details.
  13 */
  14#include <asm/mach-pic32/pic32.h>
  15#include <asm/fw/fw.h>
  16
  17#include "pic32mzda.h"
  18#include "early_pin.h"
  19
  20/* Default early console parameters */
  21#define EARLY_CONSOLE_PORT      1
  22#define EARLY_CONSOLE_BAUDRATE  115200
  23
  24#define UART_ENABLE             BIT(15)
  25#define UART_ENABLE_RX          BIT(12)
  26#define UART_ENABLE_TX          BIT(10)
  27#define UART_TX_FULL            BIT(9)
  28
  29/* UART1(x == 0) - UART6(x == 5) */
  30#define UART_BASE(x)    ((x) * 0x0200)
  31#define U_MODE(x)       UART_BASE(x)
  32#define U_STA(x)        (UART_BASE(x) + 0x10)
  33#define U_TXR(x)        (UART_BASE(x) + 0x20)
  34#define U_BRG(x)        (UART_BASE(x) + 0x40)
  35
  36static void __iomem *uart_base;
  37static char console_port = -1;
  38
  39static int __init configure_uart_pins(int port)
  40{
  41        switch (port) {
  42        case 1:
  43                pic32_pps_input(IN_FUNC_U2RX, IN_RPB0);
  44                pic32_pps_output(OUT_FUNC_U2TX, OUT_RPG9);
  45                break;
  46        case 5:
  47                pic32_pps_input(IN_FUNC_U6RX, IN_RPD0);
  48                pic32_pps_output(OUT_FUNC_U6TX, OUT_RPB8);
  49                break;
  50        default:
  51                return -1;
  52        }
  53
  54        return 0;
  55}
  56
  57static void __init configure_uart(char port, int baud)
  58{
  59        u32 pbclk;
  60
  61        pbclk = pic32_get_pbclk(2);
  62
  63        __raw_writel(0, uart_base + U_MODE(port));
  64        __raw_writel(((pbclk / baud) / 16) - 1, uart_base + U_BRG(port));
  65        __raw_writel(UART_ENABLE, uart_base + U_MODE(port));
  66        __raw_writel(UART_ENABLE_TX | UART_ENABLE_RX,
  67                     uart_base + PIC32_SET(U_STA(port)));
  68}
  69
  70static void __init setup_early_console(char port, int baud)
  71{
  72        if (configure_uart_pins(port))
  73                return;
  74
  75        console_port = port;
  76        configure_uart(console_port, baud);
  77}
  78
  79static char * __init pic32_getcmdline(void)
  80{
  81        /*
  82         * arch_mem_init() has not been called yet, so we don't have a real
  83         * command line setup if using CONFIG_CMDLINE_BOOL.
  84         */
  85#ifdef CONFIG_CMDLINE_OVERRIDE
  86        return CONFIG_CMDLINE;
  87#else
  88        return fw_getcmdline();
  89#endif
  90}
  91
  92static int __init get_port_from_cmdline(char *arch_cmdline)
  93{
  94        char *s;
  95        int port = -1;
  96
  97        if (!arch_cmdline || *arch_cmdline == '\0')
  98                goto _out;
  99
 100        s = strstr(arch_cmdline, "earlyprintk=");
 101        if (s) {
 102                s = strstr(s, "ttyS");
 103                if (s)
 104                        s += 4;
 105                else
 106                        goto _out;
 107
 108                port = (*s) - '0';
 109        }
 110
 111_out:
 112        return port;
 113}
 114
 115static int __init get_baud_from_cmdline(char *arch_cmdline)
 116{
 117        char *s;
 118        int baud = -1;
 119
 120        if (!arch_cmdline || *arch_cmdline == '\0')
 121                goto _out;
 122
 123        s = strstr(arch_cmdline, "earlyprintk=");
 124        if (s) {
 125                s = strstr(s, "ttyS");
 126                if (s)
 127                        s += 6;
 128                else
 129                        goto _out;
 130
 131                baud = 0;
 132                while (*s >= '0' && *s <= '9')
 133                        baud = baud * 10 + *s++ - '0';
 134        }
 135
 136_out:
 137        return baud;
 138}
 139
 140void __init fw_init_early_console(char port)
 141{
 142        char *arch_cmdline = pic32_getcmdline();
 143        int baud = -1;
 144
 145        uart_base = ioremap_nocache(PIC32_BASE_UART, 0xc00);
 146
 147        baud = get_baud_from_cmdline(arch_cmdline);
 148        if (port == -1)
 149                port = get_port_from_cmdline(arch_cmdline);
 150
 151        if (port == -1)
 152                port = EARLY_CONSOLE_PORT;
 153
 154        if (baud == -1)
 155                baud = EARLY_CONSOLE_BAUDRATE;
 156
 157        setup_early_console(port, baud);
 158}
 159
 160int prom_putchar(char c)
 161{
 162        if (console_port >= 0) {
 163                while (__raw_readl(
 164                                uart_base + U_STA(console_port)) & UART_TX_FULL)
 165                        ;
 166
 167                __raw_writel(c, uart_base + U_TXR(console_port));
 168        }
 169
 170        return 1;
 171}
 172