ti_com.c revision 1.2
134198Sjdp/* $NetBSD: ti_com.c,v 1.2 2017/10/26 10:56:57 jmcneill Exp $ */
238928Sjdp
334198Sjdp/*-
434198Sjdp * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
534198Sjdp * All rights reserved.
634198Sjdp *
738928Sjdp * Redistribution and use in source and binary forms, with or without
834198Sjdp * modification, are permitted provided that the following conditions
934198Sjdp * are met:
1034198Sjdp * 1. Redistributions of source code must retain the above copyright
1134198Sjdp *    notice, this list of conditions and the following disclaimer.
1234198Sjdp * 2. Redistributions in binary form must reproduce the above copyright
1334198Sjdp *    notice, this list of conditions and the following disclaimer in the
1434198Sjdp *    documentation and/or other materials provided with the distribution.
1534198Sjdp *
1634198Sjdp * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1734198Sjdp * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1834198Sjdp * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1938928Sjdp * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2038928Sjdp * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2138928Sjdp * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2234198Sjdp * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2334198Sjdp * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2434198Sjdp * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2534198Sjdp * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2634198Sjdp * POSSIBILITY OF SUCH DAMAGE.
2734198Sjdp */
2834198Sjdp
29#include <sys/cdefs.h>
30
31__KERNEL_RCSID(1, "$NetBSD: ti_com.c,v 1.2 2017/10/26 10:56:57 jmcneill Exp $");
32
33#include <sys/param.h>
34#include <sys/bus.h>
35#include <sys/device.h>
36#include <sys/intr.h>
37#include <sys/systm.h>
38#include <sys/time.h>
39#include <sys/termios.h>
40
41#include <dev/ic/comvar.h>
42
43#include <dev/fdt/fdtvar.h>
44
45static int ti_com_match(device_t, cfdata_t, void *);
46static void ti_com_attach(device_t, device_t, void *);
47
48static const char * const compatible[] = {
49	"ti,am3352-uart",
50	"ti,omap3-uart",
51	NULL
52};
53
54struct ti_com_softc {
55	struct com_softc ssc_sc;
56	void *ssc_ih;
57};
58
59CFATTACH_DECL_NEW(ti_com, sizeof(struct ti_com_softc),
60	ti_com_match, ti_com_attach, NULL, NULL);
61
62static int
63ti_com_match(device_t parent, cfdata_t cf, void *aux)
64{
65	struct fdt_attach_args * const faa = aux;
66
67	return of_match_compatible(faa->faa_phandle, compatible);
68}
69
70static void
71ti_com_attach(device_t parent, device_t self, void *aux)
72{
73	struct ti_com_softc * const ssc = device_private(self);
74	struct com_softc * const sc = &ssc->ssc_sc;
75	struct fdt_attach_args * const faa = aux;
76	const int phandle = faa->faa_phandle;
77	bus_space_handle_t bsh;
78	bus_space_tag_t bst;
79	char intrstr[128];
80	bus_addr_t addr;
81	bus_size_t size;
82	int error;
83
84	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
85		aprint_error(": couldn't get registers\n");
86		return;
87	}
88
89	bst = faa->faa_a4x_bst;
90
91	sc->sc_dev = self;
92
93	if (of_getprop_uint32(phandle, "clock-frequency", &sc->sc_frequency) != 0) {
94		aprint_error(": missing 'clock-frequency' property\n");
95		return;
96	}
97
98	sc->sc_type = COM_TYPE_NORMAL;
99
100	error = bus_space_map(bst, addr, size, 0, &bsh);
101	if (error) {
102		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
103		return;
104	}
105
106	COM_INIT_REGS(sc->sc_regs, bst, bsh, addr);
107
108	com_attach_subr(sc);
109	aprint_naive("\n");
110
111	if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
112		aprint_error_dev(self, "failed to decode interrupt\n");
113		return;
114	}
115
116	ssc->ssc_ih = fdtbus_intr_establish(phandle, 0, IPL_SERIAL,
117	    FDT_INTR_MPSAFE, comintr, sc);
118	if (ssc->ssc_ih == NULL) {
119		aprint_error_dev(self, "failed to establish interrupt on %s\n",
120		    intrstr);
121	}
122	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
123}
124
125/*
126 * Console support
127 */
128
129static int
130ti_com_console_match(int phandle)
131{
132	return of_match_compatible(phandle, compatible);
133}
134
135static void
136ti_com_console_consinit(struct fdt_attach_args *faa, u_int uart_freq)
137{
138	const int phandle = faa->faa_phandle;
139	bus_space_tag_t bst = faa->faa_a4x_bst;
140	bus_addr_t addr;
141	tcflag_t flags;
142	int speed;
143
144	fdtbus_get_reg(phandle, 0, &addr, NULL);
145	speed = fdtbus_get_stdout_speed();
146	if (speed < 0)
147		speed = 115200;	/* default */
148	flags = fdtbus_get_stdout_flags();
149
150	if (comcnattach(bst, addr, speed, uart_freq, COM_TYPE_NORMAL, flags))
151		panic("Cannot initialize ti com console");
152}
153
154static const struct fdt_console ti_com_console = {
155	.match = ti_com_console_match,
156	.consinit = ti_com_console_consinit,
157};
158
159FDT_CONSOLE(ti_com, &ti_com_console);
160