1248557Sray/*- 2250357Sray * Copyright (c) 2012, 2013 The FreeBSD Foundation 3248557Sray * All rights reserved. 4248557Sray * 5248557Sray * This software was developed by Oleksandr Rybalko under sponsorship 6248557Sray * from the FreeBSD Foundation. 7248557Sray * 8248557Sray * Redistribution and use in source and binary forms, with or without 9248557Sray * modification, are permitted provided that the following conditions 10248557Sray * are met: 11248557Sray * 1. Redistributions of source code must retain the above copyright 12248557Sray * notice, this list of conditions and the following disclaimer. 13248557Sray * 2. Redistributions in binary form must reproduce the above copyright 14248557Sray * notice, this list of conditions and the following disclaimer in the 15248557Sray * documentation and/or other materials provided with the distribution. 16248557Sray * 17248557Sray * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18248557Sray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19248557Sray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20248557Sray * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21248557Sray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22248557Sray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23248557Sray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24248557Sray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25248557Sray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26248557Sray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27248557Sray * SUCH DAMAGE. 28248557Sray */ 29248557Sray 30248557Sray/* Simple UART console driver for Freescale i.MX515 */ 31248557Sray 32248557Sray#include <sys/cdefs.h> 33248557Sray__FBSDID("$FreeBSD: releng/10.3/sys/arm/freescale/imx/console.c 253914 2013-08-03 13:31:10Z ian $"); 34248557Sray 35248557Sray#include <sys/types.h> 36248557Sray#include <sys/param.h> 37248557Sray#include <sys/systm.h> 38248557Sray#include <sys/cons.h> 39248557Sray#include <sys/consio.h> 40248557Sray#include <sys/kernel.h> 41248557Sray 42248557Sray/* Allow it to be predefined, to be able to use another UART for console */ 43248557Sray#ifndef IMX_UART_BASE 44253914Sian#define IMX_UART_BASE 0xe3fbc000 /* imx51 UART1 */ 45248557Sray#endif 46248557Sray 47253914Sian#define IMX_RXD 0x00 48253914Sian#define IMX_TXD 0x40 49248557Sray 50253914Sian#define IMX_UFCR 0x90 51253914Sian#define IMX_USR1 0x94 52248557Sray#define IMX_USR1_TRDY (1 << 13) 53248557Sray 54253914Sian#define IMX_USR2 0x98 55248557Sray#define IMX_USR2_RDR (1 << 0) 56248557Sray#define IMX_USR2_TXFE (1 << 14) 57248557Sray#define IMX_USR2_TXDC (1 << 3) 58248557Sray 59253914Sian#define IMX_UTS 0xb4 60248557Sray#define IMX_UTS_TXFULL (1 << 4) 61248557Sray 62248557Sray/* 63253914Sian * The base address of the uart registers. 64253914Sian * 65253914Sian * This is global so that it can be changed on the fly from the outside. For 66253914Sian * example, set imx_uart_base=physaddr and then call cninit() as the first two 67253914Sian * lines of initarm() and enjoy printf() availability through the tricky bits of 68253914Sian * startup. After initarm() switches from physical to virtual addressing, just 69253914Sian * set imx_uart_base=virtaddr and printf keeps working. 70253914Sian */ 71253914Sianuint32_t imx_uart_base = IMX_UART_BASE; 72253914Sian 73253914Sian/* 74248557Sray * uart related funcs 75248557Sray */ 76253914Sianstatic uint32_t 77253914Sianub_getreg(uint32_t off) 78248557Sray{ 79248557Sray 80253914Sian return *((volatile uint32_t *)(imx_uart_base + off)); 81248557Sray} 82248557Sray 83248557Sraystatic void 84253914Sianub_setreg(uint32_t off, uint32_t val) 85248557Sray{ 86248557Sray 87253914Sian *((volatile uint32_t *)(imx_uart_base + off)) = val; 88248557Sray} 89248557Sray 90248557Sraystatic int 91248557Srayub_tstc(void) 92248557Sray{ 93248557Sray 94253914Sian return ((ub_getreg(IMX_USR2) & IMX_USR2_RDR) ? 1 : 0); 95248557Sray} 96248557Sray 97248557Sraystatic int 98248557Srayub_getc(void) 99248557Sray{ 100248557Sray 101248557Sray while (!ub_tstc()); 102248557Sray __asm __volatile("nop"); 103248557Sray 104253914Sian return (ub_getreg(IMX_RXD) & 0xff); 105248557Sray} 106248557Sray 107248557Sraystatic void 108248557Srayub_putc(unsigned char c) 109248557Sray{ 110248557Sray 111248557Sray if (c == '\n') 112248557Sray ub_putc('\r'); 113248557Sray 114253914Sian while (ub_getreg(IMX_UTS) & IMX_UTS_TXFULL) 115248557Sray __asm __volatile("nop"); 116248557Sray 117253914Sian ub_setreg(IMX_TXD, c); 118248557Sray} 119248557Sray 120248557Sraystatic cn_probe_t uart_cnprobe; 121248557Sraystatic cn_init_t uart_cninit; 122248557Sraystatic cn_term_t uart_cnterm; 123248557Sraystatic cn_getc_t uart_cngetc; 124248557Sraystatic cn_putc_t uart_cnputc; 125248557Sraystatic cn_grab_t uart_cngrab; 126248557Sraystatic cn_ungrab_t uart_cnungrab; 127248557Sray 128248557Sraystatic void 129248557Srayuart_cngrab(struct consdev *cp) 130248557Sray{ 131248557Sray 132248557Sray} 133248557Sray 134248557Sraystatic void 135248557Srayuart_cnungrab(struct consdev *cp) 136248557Sray{ 137248557Sray 138248557Sray} 139248557Sray 140248557Sray 141248557Sraystatic void 142248557Srayuart_cnprobe(struct consdev *cp) 143248557Sray{ 144248557Sray 145248557Sray sprintf(cp->cn_name, "uart"); 146248557Sray cp->cn_pri = CN_NORMAL; 147248557Sray} 148248557Sray 149248557Sraystatic void 150248557Srayuart_cninit(struct consdev *cp) 151248557Sray{ 152253914Sian 153253914Sian /* Init fifo trigger levels to 32 bytes, refclock div to 2. */ 154253914Sian ub_setreg(IMX_UFCR, 0x00004210); 155248557Sray} 156248557Sray 157253914Sianstatic void 158248557Srayuart_cnputc(struct consdev *cp, int c) 159248557Sray{ 160248557Sray 161248557Sray ub_putc(c); 162248557Sray} 163248557Sray 164253914Sianstatic int 165248557Srayuart_cngetc(struct consdev * cp) 166248557Sray{ 167248557Sray 168248557Sray return ub_getc(); 169248557Sray} 170248557Sray 171248557Sraystatic void 172248557Srayuart_cnterm(struct consdev * cp) 173248557Sray{ 174248557Sray 175248557Sray} 176248557Sray 177248557SrayCONSOLE_DRIVER(uart); 178