11.2Sjmcneill/* $Id: imx23_plcom.c,v 1.2 2018/10/23 09:15:35 jmcneill Exp $ */ 21.1Sjkunz 31.1Sjkunz/* 41.1Sjkunz * Copyright (c) 2012 The NetBSD Foundation, Inc. 51.1Sjkunz * All rights reserved. 61.1Sjkunz * 71.1Sjkunz * This code is derived from software contributed to The NetBSD Foundation 81.1Sjkunz * by Petri Laakso 91.1Sjkunz * 101.1Sjkunz * Redistribution and use in source and binary forms, with or without 111.1Sjkunz * modification, are permitted provided that the following conditions 121.1Sjkunz * are met: 131.1Sjkunz * 1. Redistributions of source code must retain the above copyright 141.1Sjkunz * notice, this list of conditions and the following disclaimer. 151.1Sjkunz * 2. Redistributions in binary form must reproduce the above copyright 161.1Sjkunz * notice, this list of conditions and the following disclaimer in the 171.1Sjkunz * documentation and/or other materials provided with the distribution. 181.1Sjkunz * 191.1Sjkunz * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 201.1Sjkunz * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 211.1Sjkunz * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 221.1Sjkunz * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 231.1Sjkunz * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 241.1Sjkunz * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 251.1Sjkunz * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 261.1Sjkunz * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 271.1Sjkunz * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 281.1Sjkunz * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 291.1Sjkunz * POSSIBILITY OF SUCH DAMAGE. 301.1Sjkunz */ 311.1Sjkunz 321.1Sjkunz/* Interface to plcom (PL011) serial driver. */ 331.1Sjkunz 341.1Sjkunz#include <sys/param.h> 351.1Sjkunz#include <sys/types.h> 361.1Sjkunz#include <sys/bus.h> 371.1Sjkunz#include <sys/device.h> 381.1Sjkunz#include <sys/systm.h> 391.1Sjkunz#include <sys/termios.h> 401.1Sjkunz 411.1Sjkunz#include <arm/pic/picvar.h> 421.1Sjkunz 431.1Sjkunz#include <arm/imx/imx23var.h> 441.1Sjkunz#include <arm/imx/imx23_uartdbgreg.h> 451.1Sjkunz 461.1Sjkunz#include <evbarm/dev/plcomreg.h> 471.1Sjkunz#include <evbarm/dev/plcomvar.h> 481.1Sjkunz 491.1Sjkunzstatic int imx23_plcom_match(device_t, cfdata_t, void *); 501.1Sjkunzstatic void imx23_plcom_attach(device_t, device_t, void *); 511.1Sjkunz 521.1SjkunzCFATTACH_DECL3_NEW(imx23plcom, 531.1Sjkunz sizeof(struct plcom_softc), 541.1Sjkunz imx23_plcom_match, 551.1Sjkunz imx23_plcom_attach, 561.1Sjkunz NULL, 571.1Sjkunz NULL, 581.1Sjkunz NULL, 591.1Sjkunz NULL, 601.1Sjkunz 0); 611.1Sjkunz 621.1Sjkunzstatic int 631.1Sjkunzimx23_plcom_match(device_t parent, cfdata_t cf, void *aux) 641.1Sjkunz{ 651.1Sjkunz struct apb_attach_args *aaa = aux; 661.1Sjkunz 671.1Sjkunz if (aaa->aa_addr == HW_UARTDBG_BASE && 681.1Sjkunz aaa->aa_size == PL011COM_UART_SIZE) { 691.1Sjkunz return 1; 701.1Sjkunz } 711.1Sjkunz 721.1Sjkunz return 0; 731.1Sjkunz} 741.1Sjkunz 751.1Sjkunzstatic void 761.1Sjkunzimx23_plcom_attach(device_t parent, device_t self, void *aux) 771.1Sjkunz{ 781.1Sjkunz static int plcom_attached = 0; 791.1Sjkunz struct plcom_softc *sc = device_private(self); 801.1Sjkunz struct apb_attach_args *aaa = aux; 811.1Sjkunz void *ih; 821.1Sjkunz 831.1Sjkunz if (plcom_attached) 841.1Sjkunz return; 851.1Sjkunz 861.2Sjmcneill aprint_naive("\n"); 871.2Sjmcneill aprint_normal("\n"); 881.2Sjmcneill 891.1Sjkunz sc->sc_dev = self; 901.1Sjkunz sc->sc_frequency = IMX23_UART_CLK; 911.1Sjkunz sc->sc_hwflags = PLCOM_HW_TXFIFO_DISABLE; 921.1Sjkunz sc->sc_swflags = 0; 931.1Sjkunz sc->sc_set_mcr = NULL; 941.1Sjkunz sc->sc_set_mcr_arg = NULL; 951.1Sjkunz 961.1Sjkunz sc->sc_pi.pi_type = PLCOM_TYPE_PL011; 971.1Sjkunz sc->sc_pi.pi_flags = PLC_FLAG_32BIT_ACCESS; 981.1Sjkunz sc->sc_pi.pi_iot = aaa->aa_iot; 991.1Sjkunz sc->sc_pi.pi_iobase = aaa->aa_addr; 1001.1Sjkunz 1011.1Sjkunz if (bus_space_map(aaa->aa_iot, aaa->aa_addr, PL011COM_UART_SIZE, 0, 1021.1Sjkunz &sc->sc_pi.pi_ioh)) { 1031.1Sjkunz aprint_error_dev(sc->sc_dev, "unable to map device\n"); 1041.1Sjkunz return; 1051.1Sjkunz } 1061.1Sjkunz 1071.1Sjkunz plcom_attach_subr(sc); 1081.1Sjkunz 1091.1Sjkunz ih = intr_establish(aaa->aa_irq, IPL_SERIAL, IST_LEVEL, 1101.1Sjkunz plcomintr, sc); 1111.1Sjkunz 1121.1Sjkunz if (ih == NULL) 1131.1Sjkunz panic("%s: cannot install interrupt handler", 1141.1Sjkunz device_xname(sc->sc_dev)); 1151.1Sjkunz 1161.1Sjkunz plcom_attached = 1; 1171.1Sjkunz 1181.1Sjkunz return; 1191.1Sjkunz} 120