-/* $OpenBSD: cn30xxuart.c,v 1.9 2016/04/14 13:51:58 visa Exp $ */
+/* $OpenBSD: cn30xxuart.c,v 1.10 2017/07/03 08:17:20 visa Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
#include <sys/tty.h>
#include <sys/conf.h>
+#include <dev/ofw/fdt.h>
+#include <dev/ofw/openfirm.h>
+
+#include <machine/octeonreg.h>
#include <machine/octeonvar.h>
#include <machine/autoconf.h>
#include <machine/bus.h>
+#include <machine/fdt.h>
#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>
#include <dev/cons.h>
#include <octeon/dev/iobusvar.h>
-#include <octeon/dev/uartbusvar.h>
#include <octeon/dev/cn30xxuartreg.h>
#define OCTEON_UART_FIFO_SIZE 64
int cn30xxuart_delay(void);
void cn30xxuart_wait_txhr_empty(int);
+uint8_t uartbus_read_1(bus_space_tag_t, bus_space_handle_t, bus_size_t);
+void uartbus_write_1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
+ uint8_t);
+
+bus_space_t uartbus_tag = {
+ .bus_base = PHYS_TO_XKPHYS(0, CCA_NC),
+ .bus_private = NULL,
+ ._space_read_1 = uartbus_read_1,
+ ._space_write_1 = uartbus_write_1,
+ ._space_map = iobus_space_map,
+ ._space_unmap = iobus_space_unmap
+};
+
+void
+com_fdt_init_cons(void)
+{
+ comconsiot = &uartbus_tag;
+ comconsaddr = OCTEON_UART0_BASE;
+ comconsfreq = octeon_ioclock_speed();
+ comconsrate = B115200;
+ comconscflag = (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8;
+}
+
int
cn30xxuart_probe(struct device *parent, void *match, void *aux)
{
- struct cfdata *cf = match;
- struct uartbus_attach_args *uba = aux;
- bus_space_tag_t iot = uba->uba_memt;
- bus_space_handle_t ioh;
- int rv = 0, console;
-
- if (strcmp(uba->uba_name, com_cd.cd_name) != 0)
- return 0;
-
- console = 1;
-
- /* if it's in use as console, it's there. */
- if (!(console && !comconsattached)) {
- if (bus_space_map(iot, uba->uba_baseaddr, COM_NPORTS, 0, &ioh)) {
- printf(": can't map uart registers\n");
- return 1;
- }
- rv = comprobe1(iot, ioh);
- } else
- rv = 1;
-
- /* make a config stanza with exact locators match over a generic line */
- if (cf->cf_loc[0] != -1)
- rv += rv;
+ struct fdt_attach_args *faa = aux;
- return rv;
+ return OF_is_compatible(faa->fa_node, "cavium,octeon-3860-uart");
}
void
cn30xxuart_attach(struct device *parent, struct device *self, void *aux)
{
+ struct fdt_attach_args *faa = aux;
struct com_softc *sc = (void *)self;
- struct uartbus_attach_args *uba = aux;
- int console;
+ int console = 0;
+
+ if (faa->fa_nreg != 1)
+ return;
- console = 1;
+ if (comconsiot == &uartbus_tag && comconsaddr == faa->fa_reg[0].addr)
+ console = 1;
- sc->sc_iot = uba->uba_memt;
- sc->sc_iobase = uba->uba_baseaddr;
sc->sc_hwflags = 0;
sc->sc_swflags = 0;
sc->sc_frequency = octeon_ioclock_speed();
sc->sc_uarttype = COM_UART_16550A;
sc->sc_fifolen = OCTEON_UART_FIFO_SIZE;
- /* if it's in use as console, it's there. */
- if (bus_space_map(sc->sc_iot, sc->sc_iobase, COM_NPORTS, 0, &sc->sc_ioh)) {
- printf(": can't map uart registers\n");
- return;
- }
-
- if (console && !comconsattached) {
- /*
- * If we are the console, reuse the existing bus_space
- * information, so that comcnattach() invokes bus_space_map()
- * with correct parameters.
- */
-
- if (comcnattach(sc->sc_iot, sc->sc_iobase, 115200,
- sc->sc_frequency, (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8))
- panic("can't setup serial console");
+ if (!console || comconsattached) {
+ sc->sc_iot = &uartbus_tag;
+ sc->sc_iobase = faa->fa_reg[0].addr;
+ if (bus_space_map(sc->sc_iot, sc->sc_iobase, COM_NPORTS, 0,
+ &sc->sc_ioh)) {
+ printf(": could not map UART registers\n");
+ return;
+ }
+ } else {
+ /* Reuse the early console settings. */
+ sc->sc_iot = comconsiot;
+ sc->sc_iobase = comconsaddr;
+ if (comcnattach(sc->sc_iot, sc->sc_iobase, comconsrate,
+ sc->sc_frequency, comconscflag))
+ panic("could not set up serial console");
+ sc->sc_ioh = comconsioh;
}
com_attach_subr(sc);
- octeon_intr_establish(uba->uba_intr, IPL_TTY, cn30xxuart_intr,
- (void *)sc, sc->sc_dev.dv_xname);
+ octeon_intr_establish_fdt(faa->fa_node, IPL_TTY, cn30xxuart_intr, sc,
+ sc->sc_dev.dv_xname);
}
int
/*
* Early console routines.
*/
+
int
cn30xxuart_delay(void)
{
return (c);
}
+
+/*
+ * Bus access routines. These let com(4) work with the 64-bit registers.
+ */
+
+uint8_t
+uartbus_read_1(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t off)
+{
+ return *(volatile uint64_t *)(handle + (off << 3));
+}
+
+void
+uartbus_write_1(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t off,
+ uint8_t value)
+{
+ *(volatile uint64_t *)(handle + (off << 3)) = value;
+}
+++ /dev/null
-/* $OpenBSD: octeon_uartbus.c,v 1.7 2016/07/27 11:28:40 visa Exp $ */
-
-/*
- * Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- */
-
-/*
- * This is a uartbus, for OCTEON UART.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/conf.h>
-#include <sys/malloc.h>
-#include <sys/device.h>
-#include <sys/proc.h>
-#include <sys/atomic.h>
-
-#include <machine/autoconf.h>
-#include <machine/intr.h>
-#include <machine/octeonreg.h>
-
-#include <octeon/dev/uartbusvar.h>
-
-#include <dev/ic/comreg.h>
-#include <dev/ic/ns16550reg.h>
-
-int uartbusmatch(struct device *, void *, void *);
-void uartbusattach(struct device *, struct device *, void *);
-int uartbusprint(void *, const char *);
-int uartbussubmatch(struct device *, void *, void *);
-
-u_int8_t uartbus_read_1(bus_space_tag_t, bus_space_handle_t, bus_size_t);
-u_int16_t uartbus_read_2(bus_space_tag_t, bus_space_handle_t, bus_size_t);
-u_int32_t uartbus_read_4(bus_space_tag_t, bus_space_handle_t, bus_size_t);
-u_int64_t uartbus_read_8(bus_space_tag_t, bus_space_handle_t, bus_size_t);
-
-void uartbus_write_1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
- u_int8_t);
-void uartbus_write_2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
- u_int16_t);
-void uartbus_write_4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
- u_int32_t);
-void uartbus_write_8(bus_space_tag_t, bus_space_handle_t, bus_size_t,
- u_int64_t);
-
-void uartbus_read_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
- u_int8_t *, bus_size_t);
-void uartbus_write_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
- const u_int8_t *, bus_size_t);
-void uartbus_read_raw_4(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
- u_int8_t *, bus_size_t);
-void uartbus_write_raw_4(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
- const u_int8_t *, bus_size_t);
-void uartbus_read_raw_8(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
- u_int8_t *, bus_size_t);
-void uartbus_write_raw_8(bus_space_tag_t, bus_space_handle_t, bus_addr_t,
- const u_int8_t *, bus_size_t);
-
-int uartbus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
- bus_space_handle_t *);
-void uartbus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
-int uartbus_space_region(bus_space_tag_t, bus_space_handle_t, bus_size_t,
- bus_size_t, bus_space_handle_t *);
-
-void *uartbus_space_vaddr(bus_space_tag_t, bus_space_handle_t);
-
-bus_addr_t uartbus_pa_to_device(paddr_t);
-paddr_t uartbus_device_to_pa(bus_addr_t);
-
-struct cfattach uartbus_ca = {
- sizeof(struct device), uartbusmatch, uartbusattach
-};
-
-struct cfdriver uartbus_cd = {
- NULL, "uartbus", DV_DULL
-};
-
-bus_space_t uartbus_tag = {
- PHYS_TO_XKPHYS(0, CCA_NC),
- NULL,
- uartbus_read_1, uartbus_write_1,
- uartbus_read_2, uartbus_write_2,
- uartbus_read_4, uartbus_write_4,
- uartbus_read_8, uartbus_write_8,
- uartbus_read_raw_2, uartbus_write_raw_2,
- uartbus_read_raw_4, uartbus_write_raw_4,
- uartbus_read_raw_8, uartbus_write_raw_8,
- uartbus_space_map, uartbus_space_unmap, uartbus_space_region,
- uartbus_space_vaddr
-};
-
-/*
- * List of uartbus child devices.
- */
-
-#define UARTBUSDEV(name, addr, i) \
- { name, &uartbus_tag, addr, i }
-struct uartbus_attach_args uartbus_children[] = {
- UARTBUSDEV("com", OCTEON_UART0_BASE, CIU_INT_UART0),
- UARTBUSDEV("com", OCTEON_UART1_BASE, CIU_INT_UART1),
-};
-#undef UARTBUSDEV
-
-
-
-/*
- * Match bus only to targets which have this bus.
- */
-int
-uartbusmatch(struct device *parent, void *match, void *aux)
-{
- return (1);
-}
-
-int
-uartbusprint(void *aux, const char *uartbus)
-{
- struct uartbus_attach_args *uba = aux;
-
- if (uartbus != NULL)
- printf("%s at %s", uba->uba_name, uartbus);
-
- if (uba->uba_baseaddr != 0)
- printf(" base 0x%lx", uba->uba_baseaddr);
- if (uba->uba_intr >= 0)
- printf(" irq %d", uba->uba_intr);
-
- return (UNCONF);
-}
-
-int
-uartbussubmatch(struct device *parent, void *vcf, void *args)
-{
- struct cfdata *cf = vcf;
- struct uartbus_attach_args *uba = args;
-
- if (strcmp(cf->cf_driver->cd_name, uba->uba_name) != 0)
- return 0;
-
- if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != (int)uba->uba_baseaddr)
- return 0;
-
- return (*cf->cf_attach->ca_match)(parent, cf, uba);
-}
-
-void
-uartbusattach(struct device *parent, struct device *self, void *aux)
-{
- uint i;
-
- printf("\n");
-
- /*
- * Attach subdevices.
- */
- for (i = 0; i < nitems(uartbus_children); i++)
- config_found_sm(self, uartbus_children + i,
- uartbusprint, uartbussubmatch);
-}
-
-/*
- * Bus access primitives. These are really ugly...
- */
-
-u_int8_t
-uartbus_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
-{
- return *(volatile uint64_t *)(h + (o << 3));
-}
-
-u_int16_t
-uartbus_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
-{
- panic(__func__);
-}
-
-u_int32_t
-uartbus_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
-{
- panic(__func__);
-}
-
-u_int64_t
-uartbus_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
-{
- panic(__func__);
-}
-
-void
-uartbus_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t v)
-{
- *(volatile uint64_t *)(h + (o << 3)) = v;
-}
-
-void
-uartbus_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t v)
-{
- panic(__func__);
-}
-
-void
-uartbus_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t v)
-{
- panic(__func__);
-}
-
-void
-uartbus_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t v)
-{
- panic(__func__);
-}
-
-void
-uartbus_read_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
- u_int8_t *buf, bus_size_t len)
-{
- panic(__func__);
-}
-
-void
-uartbus_write_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
- const u_int8_t *buf, bus_size_t len)
-{
- panic(__func__);
-}
-
-void
-uartbus_read_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
- u_int8_t *buf, bus_size_t len)
-{
- panic(__func__);
-}
-
-void
-uartbus_write_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
- const u_int8_t *buf, bus_size_t len)
-{
- panic(__func__);
-}
-
-void
-uartbus_read_raw_8(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
- u_int8_t *buf, bus_size_t len)
-{
- panic(__func__);
-}
-
-void
-uartbus_write_raw_8(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
- const u_int8_t *buf, bus_size_t len)
-{
- panic(__func__);
-}
-
-int
-uartbus_space_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
- int flags, bus_space_handle_t *bshp)
-{
- *bshp = t->bus_base + offs;
-
- return 0;
-}
-
-void
-uartbus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
-{
-}
-
-int
-uartbus_space_region(bus_space_tag_t t, bus_space_handle_t bsh,
- bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
-{
- *nbshp = bsh + offset;
- return (0);
-}
-
-void *
-uartbus_space_vaddr(bus_space_tag_t t, bus_space_handle_t h)
-{
- return (void *)h;
-}
-
-/*
- * uartbus bus_dma helpers.
- */
-
-bus_addr_t
-uartbus_pa_to_device(paddr_t pa)
-{
- return (bus_addr_t)pa;
-}
-
-paddr_t
-uartbus_device_to_pa(bus_addr_t addr)
-{
- return (paddr_t)addr;
-}