10812ab31SAndrew Turner /*- 20812ab31SAndrew Turner * Copyright (c) 2016 The FreeBSD Foundation 30812ab31SAndrew Turner * 40812ab31SAndrew Turner * This software was developed by Andrew Turner under sponsorship from 50812ab31SAndrew Turner * the FreeBSD Foundation. 60812ab31SAndrew Turner * 70812ab31SAndrew Turner * Redistribution and use in source and binary forms, with or without 80812ab31SAndrew Turner * modification, are permitted provided that the following conditions 90812ab31SAndrew Turner * are met: 100812ab31SAndrew Turner * 1. Redistributions of source code must retain the above copyright 110812ab31SAndrew Turner * notice, this list of conditions and the following disclaimer. 120812ab31SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright 130812ab31SAndrew Turner * notice, this list of conditions and the following disclaimer in the 140812ab31SAndrew Turner * documentation and/or other materials provided with the distribution. 150812ab31SAndrew Turner * 160812ab31SAndrew Turner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 170812ab31SAndrew Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 180812ab31SAndrew Turner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 190812ab31SAndrew Turner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 200812ab31SAndrew Turner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 210812ab31SAndrew Turner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 220812ab31SAndrew Turner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 230812ab31SAndrew Turner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 240812ab31SAndrew Turner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 250812ab31SAndrew Turner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 260812ab31SAndrew Turner * SUCH DAMAGE. 270812ab31SAndrew Turner */ 280812ab31SAndrew Turner 290812ab31SAndrew Turner #include "opt_acpi.h" 300812ab31SAndrew Turner #include "opt_platform.h" 310812ab31SAndrew Turner 320812ab31SAndrew Turner #include <sys/cdefs.h> 330812ab31SAndrew Turner __FBSDID("$FreeBSD$"); 340812ab31SAndrew Turner 350812ab31SAndrew Turner #include <sys/param.h> 360812ab31SAndrew Turner #include <sys/bus.h> 370812ab31SAndrew Turner #include <sys/kernel.h> 380812ab31SAndrew Turner #include <sys/module.h> 390812ab31SAndrew Turner #include <sys/systm.h> 400812ab31SAndrew Turner 410812ab31SAndrew Turner #include <vm/vm.h> 420812ab31SAndrew Turner #include <vm/pmap.h> 430812ab31SAndrew Turner 440812ab31SAndrew Turner #include <machine/bus.h> 450812ab31SAndrew Turner 460812ab31SAndrew Turner #include <dev/uart/uart.h> 470812ab31SAndrew Turner #include <dev/uart/uart_bus.h> 480812ab31SAndrew Turner #include <dev/uart/uart_cpu.h> 490812ab31SAndrew Turner 50eba1a249SAndrew Turner #ifdef DEV_ACPI 51eba1a249SAndrew Turner #include <contrib/dev/acpica/include/acpi.h> 52ef022bb1SAndrew Turner #include <contrib/dev/acpica/include/accommon.h> 53eba1a249SAndrew Turner #include <contrib/dev/acpica/include/actables.h> 54eba1a249SAndrew Turner #include <dev/uart/uart_cpu_acpi.h> 55eba1a249SAndrew Turner #endif 56eba1a249SAndrew Turner 570812ab31SAndrew Turner #ifdef FDT 580812ab31SAndrew Turner #include <dev/fdt/fdt_common.h> 590812ab31SAndrew Turner #include <dev/ofw/ofw_bus.h> 600812ab31SAndrew Turner #include <dev/ofw/ofw_bus_subr.h> 610812ab31SAndrew Turner #include <dev/uart/uart_cpu_fdt.h> 620812ab31SAndrew Turner #endif 630812ab31SAndrew Turner 640812ab31SAndrew Turner /* 650812ab31SAndrew Turner * UART console routines. 660812ab31SAndrew Turner */ 670624eddcSColin Percival extern struct bus_space memmap_bus; 680812ab31SAndrew Turner bus_space_tag_t uart_bus_space_io; 690624eddcSColin Percival bus_space_tag_t uart_bus_space_mem = &memmap_bus; 700812ab31SAndrew Turner 710812ab31SAndrew Turner int 720812ab31SAndrew Turner uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) 730812ab31SAndrew Turner { 740812ab31SAndrew Turner 750812ab31SAndrew Turner if (pmap_kextract(b1->bsh) == 0) 760812ab31SAndrew Turner return (0); 770812ab31SAndrew Turner if (pmap_kextract(b2->bsh) == 0) 780812ab31SAndrew Turner return (0); 790812ab31SAndrew Turner return ((pmap_kextract(b1->bsh) == pmap_kextract(b2->bsh)) ? 1 : 0); 800812ab31SAndrew Turner } 810812ab31SAndrew Turner 82*4a4ad02dSKyle Evans #ifdef FDT 83*4a4ad02dSKyle Evans static int 84*4a4ad02dSKyle Evans uart_cpu_fdt_setup(struct uart_class *class, int devtype, struct uart_devinfo *di) 850812ab31SAndrew Turner { 860812ab31SAndrew Turner bus_space_handle_t bsh; 870812ab31SAndrew Turner bus_space_tag_t bst; 88c214a270SRuslan Bukin u_int rclk, shift, iowidth; 890812ab31SAndrew Turner int br, err; 900812ab31SAndrew Turner 91eba1a249SAndrew Turner err = uart_cpu_fdt_probe(&class, &bst, &bsh, &br, &rclk, 921c5d066aSMitchell Horne &shift, &iowidth, devtype); 930812ab31SAndrew Turner if (err != 0) 940812ab31SAndrew Turner return (err); 950812ab31SAndrew Turner 960812ab31SAndrew Turner /* 970812ab31SAndrew Turner * Finalize configuration. 980812ab31SAndrew Turner */ 990812ab31SAndrew Turner di->bas.chan = 0; 1000812ab31SAndrew Turner di->bas.regshft = shift; 101c214a270SRuslan Bukin di->bas.regiowidth = iowidth; 1020812ab31SAndrew Turner di->baudrate = br; 1030812ab31SAndrew Turner di->bas.rclk = rclk; 1040812ab31SAndrew Turner di->ops = uart_getops(class); 1050812ab31SAndrew Turner di->databits = 8; 1060812ab31SAndrew Turner di->stopbits = 1; 1070812ab31SAndrew Turner di->parity = UART_PARITY_NONE; 1080812ab31SAndrew Turner di->bas.bst = bst; 1090812ab31SAndrew Turner di->bas.bsh = bsh; 1100812ab31SAndrew Turner uart_bus_space_mem = di->bas.bst; 1110812ab31SAndrew Turner uart_bus_space_io = NULL; 1120812ab31SAndrew Turner 1130812ab31SAndrew Turner return (0); 1140812ab31SAndrew Turner } 115*4a4ad02dSKyle Evans #endif 116*4a4ad02dSKyle Evans 117*4a4ad02dSKyle Evans int 118*4a4ad02dSKyle Evans uart_cpu_getdev(int devtype, struct uart_devinfo *di) 119*4a4ad02dSKyle Evans { 120*4a4ad02dSKyle Evans struct uart_class *class; 121*4a4ad02dSKyle Evans int err; 122*4a4ad02dSKyle Evans 123*4a4ad02dSKyle Evans /* Allow overriding ACPI/FDT using the environment. */ 124*4a4ad02dSKyle Evans class = &uart_ns8250_class; 125*4a4ad02dSKyle Evans err = uart_getenv(devtype, di, class); 126*4a4ad02dSKyle Evans if (err == 0) 127*4a4ad02dSKyle Evans return (0); 128*4a4ad02dSKyle Evans 129*4a4ad02dSKyle Evans #ifdef DEV_ACPI 130*4a4ad02dSKyle Evans /* Check if SPCR can tell us what console to use. */ 131*4a4ad02dSKyle Evans if (uart_cpu_acpi_spcr(devtype, di) == 0) 132*4a4ad02dSKyle Evans return (0); 133*4a4ad02dSKyle Evans #endif 134*4a4ad02dSKyle Evans #ifdef FDT 135*4a4ad02dSKyle Evans if (uart_cpu_fdt_setup(class, devtype, di) == 0) 136*4a4ad02dSKyle Evans return (0); 137*4a4ad02dSKyle Evans #endif 138*4a4ad02dSKyle Evans 139*4a4ad02dSKyle Evans return (ENXIO); 140*4a4ad02dSKyle Evans } 141