1aef60d8cSIan Lepore /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3718cf2ccSPedro F. Giffuni * 4aef60d8cSIan Lepore * Copyright (c) 2013 Ian Lepore 5aef60d8cSIan Lepore * All rights reserved. 6aef60d8cSIan Lepore * 7aef60d8cSIan Lepore * Redistribution and use in source and binary forms, with or without 8aef60d8cSIan Lepore * modification, are permitted provided that the following conditions 9aef60d8cSIan Lepore * are met: 10aef60d8cSIan Lepore * 11aef60d8cSIan Lepore * 1. Redistributions of source code must retain the above copyright 12aef60d8cSIan Lepore * notice, this list of conditions and the following disclaimer. 13aef60d8cSIan Lepore * 2. Redistributions in binary form must reproduce the above copyright 14aef60d8cSIan Lepore * notice, this list of conditions and the following disclaimer in the 15aef60d8cSIan Lepore * documentation and/or other materials provided with the distribution. 16aef60d8cSIan Lepore * 17aef60d8cSIan Lepore * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18aef60d8cSIan Lepore * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19aef60d8cSIan Lepore * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20aef60d8cSIan Lepore * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21aef60d8cSIan Lepore * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22aef60d8cSIan Lepore * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23aef60d8cSIan Lepore * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24aef60d8cSIan Lepore * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25aef60d8cSIan Lepore * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26aef60d8cSIan Lepore * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27aef60d8cSIan Lepore */ 28aef60d8cSIan Lepore 29aef60d8cSIan Lepore #include "opt_platform.h" 30aef60d8cSIan Lepore 31aef60d8cSIan Lepore #include <sys/cdefs.h> 32aef60d8cSIan Lepore __FBSDID("$FreeBSD$"); 33aef60d8cSIan Lepore 34aef60d8cSIan Lepore #include <sys/param.h> 35aef60d8cSIan Lepore #include <sys/systm.h> 36aef60d8cSIan Lepore #include <sys/bus.h> 37aef60d8cSIan Lepore #include <sys/conf.h> 38aef60d8cSIan Lepore #include <sys/kernel.h> 39aef60d8cSIan Lepore #include <sys/sysctl.h> 40aef60d8cSIan Lepore #include <machine/bus.h> 41aef60d8cSIan Lepore 42aef60d8cSIan Lepore #include <dev/fdt/fdt_common.h> 43aef60d8cSIan Lepore #include <dev/ofw/ofw_bus.h> 44aef60d8cSIan Lepore #include <dev/ofw/ofw_bus_subr.h> 45aef60d8cSIan Lepore 46aef60d8cSIan Lepore #include <dev/uart/uart.h> 47aef60d8cSIan Lepore #include <dev/uart/uart_cpu.h> 483bb693afSIan Lepore #include <dev/uart/uart_cpu_fdt.h> 49aef60d8cSIan Lepore #include <dev/uart/uart_bus.h> 50aef60d8cSIan Lepore #include <dev/uart/uart_dev_ns8250.h> 51aef60d8cSIan Lepore 520050ea24SMichal Meloun #include <arm/ti/ti_sysc.h> 530050ea24SMichal Meloun 54aef60d8cSIan Lepore #include "uart_if.h" 55aef60d8cSIan Lepore 56aef60d8cSIan Lepore /* 57aef60d8cSIan Lepore * High-level UART interface. 58aef60d8cSIan Lepore */ 59aef60d8cSIan Lepore struct ti8250_softc { 60aef60d8cSIan Lepore struct ns8250_softc ns8250_base; 61aef60d8cSIan Lepore /*uint32_t mystuff;*/ 62aef60d8cSIan Lepore }; 63aef60d8cSIan Lepore 64aef60d8cSIan Lepore #define MDR1_REG 8 65aef60d8cSIan Lepore #define MDR1_MODE_UART 0 66aef60d8cSIan Lepore #define MDR1_MODE_DISABLE 7 67aef60d8cSIan Lepore #define SYSCC_REG 15 68aef60d8cSIan Lepore #define SYSCC_SOFTRESET (1 << 1) 69aef60d8cSIan Lepore #define SYSS_REG 16 70aef60d8cSIan Lepore #define SYSS_STATUS_RESETDONE (1 << 0) 71aef60d8cSIan Lepore 72aef60d8cSIan Lepore static int 73aef60d8cSIan Lepore ti8250_bus_probe(struct uart_softc *sc) 74aef60d8cSIan Lepore { 75aef60d8cSIan Lepore int status; 76aef60d8cSIan Lepore 770050ea24SMichal Meloun if ((status = ti_sysc_clock_enable(device_get_parent(sc->sc_dev))) != 0) 78aef60d8cSIan Lepore return (status); 79aef60d8cSIan Lepore 80aef60d8cSIan Lepore /* 81aef60d8cSIan Lepore * Set the hardware to disabled mode, do a full device reset, then set 82aef60d8cSIan Lepore * it to uart mode. Most devices will be reset-and-disabled already, 83aef60d8cSIan Lepore * but you never know what a bootloader might have done. 84aef60d8cSIan Lepore */ 85aef60d8cSIan Lepore uart_setreg(&sc->sc_bas, MDR1_REG, MDR1_MODE_DISABLE); 86aef60d8cSIan Lepore uart_setreg(&sc->sc_bas, SYSCC_REG, SYSCC_SOFTRESET); 87aef60d8cSIan Lepore while (uart_getreg(&sc->sc_bas, SYSS_REG) & SYSS_STATUS_RESETDONE) 88aef60d8cSIan Lepore continue; 89aef60d8cSIan Lepore uart_setreg(&sc->sc_bas, MDR1_REG, MDR1_MODE_UART); 90aef60d8cSIan Lepore 91aef60d8cSIan Lepore status = ns8250_bus_probe(sc); 92aef60d8cSIan Lepore if (status == 0) 93aef60d8cSIan Lepore device_set_desc(sc->sc_dev, "TI UART (16550 compatible)"); 94aef60d8cSIan Lepore 95aef60d8cSIan Lepore return (status); 96aef60d8cSIan Lepore } 97aef60d8cSIan Lepore 98aef60d8cSIan Lepore static kobj_method_t ti8250_methods[] = { 99aef60d8cSIan Lepore KOBJMETHOD(uart_probe, ti8250_bus_probe), 100aef60d8cSIan Lepore 101aef60d8cSIan Lepore KOBJMETHOD(uart_attach, ns8250_bus_attach), 102aef60d8cSIan Lepore KOBJMETHOD(uart_detach, ns8250_bus_detach), 103aef60d8cSIan Lepore KOBJMETHOD(uart_flush, ns8250_bus_flush), 104aef60d8cSIan Lepore KOBJMETHOD(uart_getsig, ns8250_bus_getsig), 105aef60d8cSIan Lepore KOBJMETHOD(uart_ioctl, ns8250_bus_ioctl), 106aef60d8cSIan Lepore KOBJMETHOD(uart_ipend, ns8250_bus_ipend), 107aef60d8cSIan Lepore KOBJMETHOD(uart_param, ns8250_bus_param), 108aef60d8cSIan Lepore KOBJMETHOD(uart_receive, ns8250_bus_receive), 109aef60d8cSIan Lepore KOBJMETHOD(uart_setsig, ns8250_bus_setsig), 110aef60d8cSIan Lepore KOBJMETHOD(uart_transmit, ns8250_bus_transmit), 111aef60d8cSIan Lepore KOBJMETHOD_END 112aef60d8cSIan Lepore }; 113aef60d8cSIan Lepore 1143bb693afSIan Lepore static struct uart_class uart_ti8250_class = { 115aef60d8cSIan Lepore "ti8250", 116aef60d8cSIan Lepore ti8250_methods, 117aef60d8cSIan Lepore sizeof(struct ti8250_softc), 118aef60d8cSIan Lepore .uc_ops = &uart_ns8250_ops, 119aef60d8cSIan Lepore .uc_range = 0x88, 120405ada37SAndrew Turner .uc_rclk = 48000000, 1215b03aba6SOleksandr Tymoshenko .uc_rshift = 2 122aef60d8cSIan Lepore }; 1233bb693afSIan Lepore static struct ofw_compat_data compat_data[] = { 1243bb693afSIan Lepore {"ti,ns16550", (uintptr_t)&uart_ti8250_class}, 1255b03aba6SOleksandr Tymoshenko {"ti,omap3-uart", (uintptr_t)&uart_ti8250_class}, 1265b03aba6SOleksandr Tymoshenko {"ti,omap4-uart", (uintptr_t)&uart_ti8250_class}, 1273bb693afSIan Lepore {NULL, (uintptr_t)NULL}, 1283bb693afSIan Lepore }; 1293bb693afSIan Lepore UART_FDT_CLASS_AND_DEVICE(compat_data); 130