Annotation of src/sys/arch/arm/sunxi/sunxi_com.c, Revision 1.2.6.2
1.2.6.2 ! skrll 1: /* $NetBSD: sunxi_com.c,v 1.2 2017/06/29 17:05:26 jmcneill Exp $ */
! 2:
! 3: /*-
! 4: * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
! 5: * All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: *
! 16: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
! 17: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 18: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 19: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 20: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 21: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 22: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 23: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 24: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 25: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 26: * POSSIBILITY OF SUCH DAMAGE.
! 27: */
! 28:
! 29: #include <sys/cdefs.h>
! 30:
! 31: __KERNEL_RCSID(1, "$NetBSD: sunxi_com.c,v 1.2 2017/06/29 17:05:26 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:
! 45: static int sunxi_com_match(device_t, cfdata_t, void *);
! 46: static void sunxi_com_attach(device_t, device_t, void *);
! 47:
! 48: static const char * const compatible[] = {
! 49: "snps,dw-apb-uart",
! 50: NULL
! 51: };
! 52:
! 53: struct sunxi_com_softc {
! 54: struct com_softc ssc_sc;
! 55: void *ssc_ih;
! 56:
! 57: struct clk *ssc_clk;
! 58: struct fdtbus_reset *ssc_rst;
! 59: };
! 60:
! 61: CFATTACH_DECL_NEW(sunxi_com, sizeof(struct sunxi_com_softc),
! 62: sunxi_com_match, sunxi_com_attach, NULL, NULL);
! 63:
! 64: static int
! 65: sunxi_com_match(device_t parent, cfdata_t cf, void *aux)
! 66: {
! 67: struct fdt_attach_args * const faa = aux;
! 68:
! 69: return of_match_compatible(faa->faa_phandle, compatible);
! 70: }
! 71:
! 72: static void
! 73: sunxi_com_attach(device_t parent, device_t self, void *aux)
! 74: {
! 75: struct sunxi_com_softc * const ssc = device_private(self);
! 76: struct com_softc * const sc = &ssc->ssc_sc;
! 77: struct fdt_attach_args * const faa = aux;
! 78: bus_space_handle_t bsh;
! 79: bus_space_tag_t bst;
! 80: char intrstr[128];
! 81: bus_addr_t addr;
! 82: bus_size_t size;
! 83: u_int reg_shift;
! 84: int error;
! 85:
! 86: if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
! 87: aprint_error(": couldn't get registers\n");
! 88: return;
! 89: }
! 90:
! 91: if (of_getprop_uint32(faa->faa_phandle, "reg-shift", ®_shift)) {
! 92: /* missing or bad reg-shift property, assume 2 */
! 93: bst = faa->faa_a4x_bst;
! 94: } else {
! 95: if (reg_shift == 2) {
! 96: bst = faa->faa_a4x_bst;
! 97: } else if (reg_shift == 0) {
! 98: bst = faa->faa_bst;
! 99: } else {
! 100: aprint_error(": unsupported reg-shift value %d\n",
! 101: reg_shift);
! 102: return;
! 103: }
! 104: }
! 105:
! 106: sc->sc_dev = self;
! 107:
! 108: ssc->ssc_clk = fdtbus_clock_get_index(faa->faa_phandle, 0);
! 109: ssc->ssc_rst = fdtbus_reset_get_index(faa->faa_phandle, 0);
! 110:
! 111: if (ssc->ssc_clk == NULL) {
! 112: aprint_error(": couldn't get frequency\n");
! 113: return;
! 114: }
! 115:
! 116: sc->sc_frequency = clk_get_rate(ssc->ssc_clk);
! 117: sc->sc_type = COM_TYPE_NORMAL;
! 118:
! 119: error = bus_space_map(bst, addr, size, 0, &bsh);
! 120: if (error) {
! 121: aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
! 122: return;
! 123: }
! 124:
! 125: COM_INIT_REGS(sc->sc_regs, bst, bsh, addr);
! 126:
! 127: com_attach_subr(sc);
! 128: aprint_naive("\n");
! 129:
! 130: if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
! 131: aprint_error_dev(self, "failed to decode interrupt\n");
! 132: return;
! 133: }
! 134:
! 135: ssc->ssc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_SERIAL,
! 136: FDT_INTR_MPSAFE, comintr, sc);
! 137: if (ssc->ssc_ih == NULL) {
! 138: aprint_error_dev(self, "failed to establish interrupt on %s\n",
! 139: intrstr);
! 140: }
! 141: aprint_normal_dev(self, "interrupting on %s\n", intrstr);
! 142: }
! 143:
! 144: /*
! 145: * Console support
! 146: */
! 147:
! 148: static int
! 149: sunxi_com_console_match(int phandle)
! 150: {
! 151: return of_match_compatible(phandle, compatible);
! 152: }
! 153:
! 154: static void
! 155: sunxi_com_console_consinit(struct fdt_attach_args *faa, u_int uart_freq)
! 156: {
! 157: const int phandle = faa->faa_phandle;
! 158: bus_space_tag_t bst = faa->faa_a4x_bst;
! 159: bus_addr_t addr;
! 160: tcflag_t flags;
! 161: int speed;
! 162:
! 163: fdtbus_get_reg(phandle, 0, &addr, NULL);
! 164: speed = fdtbus_get_stdout_speed();
! 165: if (speed < 0)
! 166: speed = 115200; /* default */
! 167: flags = fdtbus_get_stdout_flags();
! 168:
! 169: if (comcnattach(bst, addr, speed, uart_freq, COM_TYPE_NORMAL, flags))
! 170: panic("Cannot initialize sunxi com console");
! 171: }
! 172:
! 173: static const struct fdt_console sunxi_com_console = {
! 174: .match = sunxi_com_console_match,
! 175: .consinit = sunxi_com_console_consinit,
! 176: };
! 177:
! 178: FDT_CONSOLE(sunxi_com, &sunxi_com_console);
CVSweb <webmaster@jp.NetBSD.org>