1157317Smarcel/*- 2157317Smarcel * Copyright (c) 2006 Marcel Moolenaar 3157317Smarcel * All rights reserved. 4157317Smarcel * 5157317Smarcel * Redistribution and use in source and binary forms, with or without 6157317Smarcel * modification, are permitted provided that the following conditions 7157317Smarcel * are met: 8157317Smarcel * 9157317Smarcel * 1. Redistributions of source code must retain the above copyright 10157317Smarcel * notice, this list of conditions and the following disclaimer. 11157317Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12157317Smarcel * notice, this list of conditions and the following disclaimer in the 13157317Smarcel * documentation and/or other materials provided with the distribution. 14157317Smarcel * 15157317Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16157317Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17157317Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18157317Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19157317Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20157317Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21157317Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22157317Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23157317Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24157317Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25157317Smarcel */ 26157317Smarcel 27157317Smarcel#include <sys/cdefs.h> 28157317Smarcel__FBSDID("$FreeBSD$"); 29157317Smarcel 30157317Smarcel#include <sys/param.h> 31157317Smarcel#include <sys/systm.h> 32190681Snwhitehorn#include <vm/vm.h> 33190681Snwhitehorn#include <vm/pmap.h> 34157317Smarcel 35157317Smarcel#include <machine/bus.h> 36209908Sraj#include <machine/ofw_machdep.h> 37157317Smarcel 38160715Smarcel#include <dev/ofw/openfirm.h> 39157317Smarcel#include <dev/uart/uart.h> 40157317Smarcel#include <dev/uart/uart_cpu.h> 41157317Smarcel 42174782Smarcelbus_space_tag_t uart_bus_space_io = &bs_le_tag; 43174782Smarcelbus_space_tag_t uart_bus_space_mem = &bs_le_tag; 44157317Smarcel 45157317Smarcelint 46157317Smarceluart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) 47157317Smarcel{ 48209908Sraj 49190681Snwhitehorn return ((pmap_kextract(b1->bsh) == pmap_kextract(b2->bsh)) ? 1 : 0); 50157317Smarcel} 51157317Smarcel 52195831Snwhitehornstatic int 53195831Snwhitehornofw_get_uart_console(phandle_t opts, phandle_t *result, const char *inputdev, 54195831Snwhitehorn const char *outputdev) 55195831Snwhitehorn{ 56195831Snwhitehorn char buf[64]; 57195831Snwhitehorn phandle_t input; 58195831Snwhitehorn 59195831Snwhitehorn if (OF_getprop(opts, inputdev, buf, sizeof(buf)) == -1) 60195831Snwhitehorn return (ENXIO); 61195831Snwhitehorn input = OF_finddevice(buf); 62195831Snwhitehorn if (input == -1) 63195831Snwhitehorn return (ENXIO); 64195831Snwhitehorn if (OF_getprop(opts, outputdev, buf, sizeof(buf)) == -1) 65195831Snwhitehorn return (ENXIO); 66195831Snwhitehorn if (OF_finddevice(buf) != input) 67195831Snwhitehorn return (ENXIO); 68195831Snwhitehorn 69195831Snwhitehorn *result = input; 70195831Snwhitehorn return (0); 71195831Snwhitehorn} 72195831Snwhitehorn 73176771Srajint 74176771Srajuart_cpu_getdev(int devtype, struct uart_devinfo *di) 75176771Sraj{ 76160715Smarcel char buf[64]; 77168281Smarcel struct uart_class *class; 78160715Smarcel phandle_t input, opts; 79160715Smarcel int error; 80157317Smarcel 81168281Smarcel class = &uart_z8530_class; 82168281Smarcel if (class == NULL) 83168281Smarcel return (ENXIO); 84168281Smarcel 85160715Smarcel if ((opts = OF_finddevice("/options")) == -1) 86160715Smarcel return (ENXIO); 87160715Smarcel switch (devtype) { 88160715Smarcel case UART_DEV_CONSOLE: 89195831Snwhitehorn if (ofw_get_uart_console(opts, &input, "input-device", 90195831Snwhitehorn "output-device")) { 91195831Snwhitehorn /* 92195831Snwhitehorn * At least some G5 Xserves require that we 93195831Snwhitehorn * probe input-device-1 as well 94195831Snwhitehorn */ 95195831Snwhitehorn 96195831Snwhitehorn if (ofw_get_uart_console(opts, &input, "input-device-1", 97195831Snwhitehorn "output-device-1")) 98195831Snwhitehorn return (ENXIO); 99195831Snwhitehorn } 100160715Smarcel break; 101160715Smarcel case UART_DEV_DBGPORT: 102160715Smarcel if (!getenv_string("hw.uart.dbgport", buf, sizeof(buf))) 103160715Smarcel return (ENXIO); 104160715Smarcel input = OF_finddevice(buf); 105160715Smarcel if (input == -1) 106160715Smarcel return (ENXIO); 107160715Smarcel break; 108160715Smarcel default: 109160715Smarcel return (EINVAL); 110160715Smarcel } 111160715Smarcel 112160715Smarcel if (OF_getprop(input, "device_type", buf, sizeof(buf)) == -1) 113160715Smarcel return (ENXIO); 114160715Smarcel if (strcmp(buf, "serial") != 0) 115160715Smarcel return (ENXIO); 116160715Smarcel if (OF_getprop(input, "name", buf, sizeof(buf)) == -1) 117160715Smarcel return (ENXIO); 118190681Snwhitehorn 119190681Snwhitehorn if (strcmp(buf, "ch-a") == 0) { 120190681Snwhitehorn class = &uart_z8530_class; 121190681Snwhitehorn di->bas.regshft = 4; 122190681Snwhitehorn di->bas.chan = 1; 123190681Snwhitehorn } else if (strcmp(buf,"serial") == 0) { 124190681Snwhitehorn class = &uart_ns8250_class; 125190681Snwhitehorn di->bas.regshft = 0; 126190681Snwhitehorn di->bas.chan = 0; 127190681Snwhitehorn } else 128160715Smarcel return (ENXIO); 129160715Smarcel 130160715Smarcel error = OF_decode_addr(input, 0, &di->bas.bst, &di->bas.bsh); 131160715Smarcel if (error) 132160715Smarcel return (error); 133160715Smarcel 134168281Smarcel di->ops = uart_getops(class); 135160715Smarcel 136190681Snwhitehorn if (OF_getprop(input, "clock-frequency", &di->bas.rclk, 137190681Snwhitehorn sizeof(di->bas.rclk)) == -1) 138190681Snwhitehorn di->bas.rclk = 230400; 139190681Snwhitehorn if (OF_getprop(input, "current-speed", &di->baudrate, 140190681Snwhitehorn sizeof(di->baudrate)) == -1) 141190681Snwhitehorn di->baudrate = 0; 142160715Smarcel 143160715Smarcel di->databits = 8; 144160715Smarcel di->stopbits = 1; 145160715Smarcel di->parity = UART_PARITY_NONE; 146160715Smarcel return (0); 147157317Smarcel} 148