Add support for the PL011 to plcom. Pull across a bunch of fixes from

com(4) while I'm here and do some other tidyup.

Tested on a RaspberryPi.

PL010 not tested.
This commit is contained in:
skrll 2012-07-25 07:26:17 +00:00
parent 128449c491
commit 4c5a9380ec
6 changed files with 704 additions and 247 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: plcomreg.h,v 1.3 2012/05/14 19:40:06 skrll Exp $ */
/* $NetBSD: plcomreg.h,v 1.4 2012/07/25 07:26:17 skrll Exp $ */
/*-
* Copyright (c) 2001 ARM Ltd
@ -52,11 +52,12 @@
#define PL01X_CR_UARTEN 0x0001 /* Uart enable */
/* interrupt identification register */
#define PL010_IIR_IMASK 0x0f
#define PL010_IIR_RTIS 0x08
#define PL010_IIR_TIS 0x04
#define PL010_IIR_RIS 0x02
#define PL010_IIR_MIS 0x01
#define PL010_IIR_IMASK \
(PL010_IIR_RTIS | PL010_IIR_TIS | PL010_IIR_RIS | PL010_IIR_MIS)
/* line control register */
#define PL011_LCR_SPS 0x80 /* Stick parity select */
@ -77,16 +78,18 @@
/* modem control register */
#define PL01X_MCR_RTS 0x02 /* Request To Send */
#define PL01X_MCR_DTR 0x01 /* Data Terminal Ready */
#define PL011_MCR(mcr) ((mcr) << 10) /* MCR to CR bit values for PL011 */
/* receive status register */
#define PL01X_RSR_OE 0x08 /* Overrun Error */
#define PL01X_RSR_BE 0x04 /* Break */
#define PL01X_RSR_PE 0x02 /* Parity Error */
#define PL01X_RSR_FE 0x01 /* Framing Error */
#define PL01X_RSR_ERROR (PL01X_RSR_OE | PL01X_RSR_BE | PL01X_RSR_PE | PL01X_RSR_FE)
#define PL01X_RSR_ERROR \
(PL01X_RSR_OE | PL01X_RSR_BE | PL01X_RSR_PE | PL01X_RSR_FE)
/* flag register */
#define PL01X_FR_RI 0x100 /* Ring Indicator */
#define PL011_FR_RI 0x100 /* Ring Indicator */
#define PL01X_FR_TXFE 0x080 /* Transmit fifo empty */
#define PL01X_FR_RXFF 0x040 /* Recive fifo full */
#define PL01X_FR_TXFF 0x020 /* Transmit fifo full */
@ -101,6 +104,7 @@
#define PL01X_MSR_DCD PL01X_FR_DCD
#define PL01X_MSR_DSR PL01X_FR_DSR
#define PL01X_MSR_CTS PL01X_FR_CTS
#define PL011_MSR_RI PL011_FR_RI
/* All interrupt status/clear registers */
#define PL011_INT_OE 0x400
@ -114,6 +118,12 @@
#define PL011_INT_DCD 0x004
#define PL011_INT_CTS 0x002
#define PL011_INT_RIR 0x001
#define PL011_INT_MSMASK \
(PL011_INT_DSR | PL011_INT_DCD | PL011_INT_CTS | PL011_INT_RIR)
#define PL011_INT_ALLMASK \
(PL011_INT_RT | PL011_INT_TX | PL011_INT_RX | PL011_INT_MSMASK)
/* DMA control registers */
#define PL011_DMA_ONERR 0x4
@ -121,17 +131,27 @@
#define PL011_DMA_RXE 0x1
/* Register offsets */
#define plcom_dr 0x00
#define plcom_rsr 0x04
#define plcom_ecr 0x04
#define plcom_lcr 0x08
#define plcom_dlbh 0x0c
#define plcom_dlbl 0x10
#define plcom_cr 0x14
#define plcom_fr 0x18
#define plcom_iir 0x1c
#define plcom_icr 0x1c
#define plcom_ilpr 0x20
#define PL01XCOM_DR 0x00 /* Data Register */
#define PL01XCOM_RSR 0x04 /* Receive status register */
#define PL01XCOM_ECR 0x04 /* Error clear register - same as RSR */
#define PL010COM_LCR 0x08 /* Line Control Register */
#define PL010COM_DLBH 0x0c
#define PL010COM_DLBL 0x10
#define PL010COM_CR 0x14
#define PL01XCOM_FR 0x18 /* Flag Register */
#define PL010COM_IIR 0x1c
#define PL010COM_ICR 0x1c
#define PL01XCOM_ILPR 0x20 /* IrDA low-power control register */
#define PL011COM_IBRD 0x24 /* Integer baud rate divisor register */
#define PL011COM_FBRD 0x28 /* Fractional baud rate divisor register */
#define PL011COM_LCRH 0x2c /* Line control register */
#define PL011COM_CR 0x30 /* Control register */
#define PL011COM_IFLS 0x34 /* Interrupt FIFO level select register */
#define PL011COM_IMSC 0x38 /* Interrupt mask set/clear register */
#define PL011COM_RIS 0x3c /* Raw interrupt status register */
#define PL011COM_MIS 0x40 /* Masked interrupt status register */
#define PL011COM_ICR 0x44 /* Interrupt clear register register */
#define PL011COM_DMACR 0x48 /* DMA control register register */
/* IFPGA specific */
#define PLCOM_UART_SIZE 0x24
#define PL010COM_UART_SIZE 0x100
#define PL011COM_UART_SIZE 0x1000

View File

@ -1,4 +1,4 @@
/* $NetBSD: plcomvar.h,v 1.10 2012/05/20 10:28:44 skrll Exp $ */
/* $NetBSD: plcomvar.h,v 1.11 2012/07/25 07:26:18 skrll Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@ -44,14 +44,16 @@
#include <sys/timepps.h>
#include <sys/simplelock.h>
int plcomcnattach (bus_space_tag_t, bus_addr_t, int, int, tcflag_t, int);
struct plcom_instance;
int plcomcnattach (struct plcom_instance *, int, int, tcflag_t, int);
void plcomcndetach (void);
#ifdef KGDB
int plcom_kgdb_attach (bus_space_tag_t, bus_addr_t, int, int, tcflag_t);
int plcom_kgdb_attach (struct plcom_instance *, int, int, tcflag_t);
#endif
int plcom_is_console (bus_space_tag_t, int, bus_space_handle_t *);
int plcom_is_console (bus_space_tag_t, bus_addr_t, bus_space_handle_t *);
/* Hardware flag masks */
#define PLCOM_HW_NOIEN 0x01
@ -66,18 +68,43 @@ int plcom_is_console (bus_space_tag_t, int, bus_space_handle_t *);
/* Buffer size for character buffer */
#define PLCOM_RING_SIZE 2048
struct plcom_instance {
u_int pi_type;
#define PLCOM_TYPE_PL010 0
#define PLCOM_TYPE_PL011 1
uint32_t pi_flags; /* flags for this PLCOM */
#define PLC_FLAG_USE_DMA 0x0001
#define PLC_FLAG_32BIT_ACCESS 0x0002
void *pi_cookie;
bus_space_tag_t pi_iot;
bus_space_handle_t pi_ioh;
bus_addr_t pi_iobase;
bus_addr_t pi_size;
struct plcom_registers *pi_regs;
};
struct plcomcons_info {
int rate;
int frequency;
int type;
tcflag_t cflag;
};
struct plcom_softc {
device_t sc_dev;
void *sc_si;
struct tty *sc_tty;
void *sc_si;
struct callout sc_diag_callout;
bus_addr_t sc_iounit;
int sc_frequency;
int sc_frequency;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
struct plcom_instance sc_pi;
u_int sc_overflows,
sc_floods,
@ -112,12 +139,13 @@ struct plcom_softc {
sc_rx_ready;
volatile u_char sc_heldchange;
volatile u_char sc_msr, sc_msr_delta, sc_msr_mask, sc_mcr,
sc_mcr_active, sc_lcr, sc_cr, sc_dlbl, sc_dlbh;
volatile u_int sc_cr, sc_ratel, sc_rateh, sc_imsc;
volatile u_int sc_msr, sc_msr_delta, sc_msr_mask;
volatile u_char sc_mcr, sc_mcr_active, sc_lcr;
u_char sc_mcr_dtr, sc_mcr_rts, sc_msr_cts, sc_msr_dcd;
u_int sc_fifo;
/* Support routine to program mcr lines, if present. */
/* Support routine to program mcr lines for PL010, if present. */
void (*sc_set_mcr)(void *, int, u_int);
void *sc_set_mcr_arg;
@ -139,7 +167,9 @@ struct plcom_softc {
kmutex_t sc_lock;
};
#if 0
int plcomprobe1 (bus_space_tag_t, bus_space_handle_t);
#endif
int plcomintr (void *);
void plcom_attach_subr (struct plcom_softc *);
int plcom_detach (device_t, int);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ifpgareg.h,v 1.3 2005/12/11 12:17:09 christos Exp $ */
/* $NetBSD: ifpgareg.h,v 1.4 2012/07/25 07:26:18 skrll Exp $ */
/*
* Copyright (c) 2001 ARM Ltd
@ -32,6 +32,7 @@
/* System clock defaults. */
#define IFPGA_UART_CLK 14745600 /* Uart REFCLK freq */
#define IFPGA_UART_SIZE 0x24
/*
* IFPGA registers

View File

@ -1,4 +1,4 @@
/* $NetBSD: plcom_ifpga.c,v 1.13 2012/05/20 10:28:44 skrll Exp $ */
/* $NetBSD: plcom_ifpga.c,v 1.14 2012/07/25 07:26:18 skrll Exp $ */
/*
* Copyright (c) 2001 ARM Ltd
@ -32,7 +32,7 @@
/* Interface to plcom (PL010) serial driver. */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: plcom_ifpga.c,v 1.13 2012/05/20 10:28:44 skrll Exp $");
__KERNEL_RCSID(0, "$NetBSD: plcom_ifpga.c,v 1.14 2012/07/25 07:26:18 skrll Exp $");
#include <sys/types.h>
#include <sys/device.h>
@ -75,24 +75,27 @@ plcom_ifpga_attach(device_t parent, device_t self, void *aux)
isc->sc_iot = ifa->ifa_iot;
isc->sc_ioh = ifa->ifa_sc_ioh;
sc->sc_dev = self;
sc->sc_iounit = device_unit(sc->sc_dev);
sc->sc_pi.pi_type = PLCOM_TYPE_PL010;
sc->sc_pi.pi_iot = ifa->ifa_iot;
sc->sc_pi.pi_iobase = ifa->ifa_addr;
sc->sc_pi.pi_size = IFPGA_UART_SIZE;
sc->sc_frequency = IFPGA_UART_CLK;
sc->sc_iot = ifa->ifa_iot;
sc->sc_hwflags = 0;
sc->sc_swflags = 0;
sc->sc_set_mcr = plcom_ifpga_set_mcr;
sc->sc_set_mcr_arg = (void *)isc;
if (bus_space_map(ifa->ifa_iot, ifa->ifa_addr, PLCOM_UART_SIZE, 0,
&sc->sc_ioh)) {
if (bus_space_map(ifa->ifa_iot, ifa->ifa_addr, IFPGA_UART_SIZE, 0,
&sc->sc_pi.pi_ioh)) {
printf("%s: unable to map device\n", device_xname(sc->sc_dev));
return;
}
plcom_attach_subr(sc);
isc->sc_ih = ifpga_intr_establish(ifa->ifa_irq, IPL_SERIAL, plcomintr,
sc);
isc->sc_ih = ifpga_intr_establish(ifa->ifa_irq, IPL_SERIAL,
plcomintr, sc);
if (isc->sc_ih == NULL)
panic("%s: cannot install interrupt handler",
device_xname(sc->sc_dev));

View File

@ -1,4 +1,4 @@
/* $NetBSD: integrator_machdep.c,v 1.68 2011/07/01 20:39:34 dyoung Exp $ */
/* $NetBSD: integrator_machdep.c,v 1.69 2012/07/25 07:26:18 skrll Exp $ */
/*
* Copyright (c) 2001,2002 ARM Ltd
@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: integrator_machdep.c,v 1.68 2011/07/01 20:39:34 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: integrator_machdep.c,v 1.69 2012/07/25 07:26:18 skrll Exp $");
#include "opt_ddb.h"
#include "opt_pmap_debug.h"
@ -383,9 +383,6 @@ initarm(void *arg)
psize_t memsize;
vm_offset_t physical_freestart;
vm_offset_t physical_freeend;
#if NPLCOM > 0 && defined(PLCONSOLE)
static struct bus_space plcom_bus_space;
#endif
/*
* Heads up ... Setup the CPU / MMU / TLB functions
@ -402,13 +399,29 @@ initarm(void *arg)
*/
if (PLCOMCNUNIT == 0) {
static struct bus_space plcom_bus_space;
static struct plcom_instance ifpga_pi0 = {
.pi_type = PLCOM_TYPE_PL010,
.pi_iot = &plcom_bus_space,
.pi_size = IFPGA_UART_SIZE,
.pi_iobase = 0x0
};
ifpga_create_io_bs_tag(&plcom_bus_space, (void*)0xfd600000);
plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT);
plcomcnattach(&ifpga_pi0, plcomcnspeed, IFPGA_UART_CLK,
plcomcnmode, PLCOMCNUNIT);
} else if (PLCOMCNUNIT == 1) {
static struct bus_space plcom_bus_space;
static struct plcom_instance ifpga_pi1 = {
.pi_type = PLCOM_TYPE_PL010,
.pi_iot = &plcom_bus_space,
.pi_size = IFPGA_UART_SIZE,
.pi_iobase = 0x0
};
ifpga_create_io_bs_tag(&plcom_bus_space, (void*)0xfd700000);
plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT);
plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
plcomcnmode, PLCOMCNUNIT);
}
#endif
@ -788,9 +801,6 @@ void
consinit(void)
{
static int consinit_called = 0;
#if NPLCOM > 0 && defined(PLCONSOLE)
static struct bus_space plcom_bus_space;
#endif
#if 0
char *console = CONSDEVNAME;
#endif
@ -802,17 +812,35 @@ consinit(void)
#if NPLCOM > 0 && defined(PLCONSOLE)
if (PLCOMCNUNIT == 0) {
static struct bus_space plcom_bus_space;
static struct plcom_instance ifpga_pi1 = {
.pi_type = PLCOM_TYPE_PL010,
.pi_iot = &plcom_bus_space,
.pi_size = IFPGA_UART_SIZE,
.pi_iobase = 0x0
};
ifpga_create_io_bs_tag(&plcom_bus_space,
(void*)UART0_BOOT_BASE);
if (plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT))
if (plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
plcomcnmode, PLCOMCNUNIT))
panic("can't init serial console");
return;
} else if (PLCOMCNUNIT == 1) {
static struct bus_space plcom_bus_space;
static struct plcom_instance ifpga_pi1 = {
.pi_type = PLCOM_TYPE_PL010,
.pi_iot = &plcom_bus_space,
.pi_size = IFPGA_UART_SIZE,
.pi_iobase = 0x0
};
ifpga_create_io_bs_tag(&plcom_bus_space,
(void*)UART0_BOOT_BASE);
if (plcomcnattach(&plcom_bus_space, 0, plcomcnspeed,
IFPGA_UART_CLK, plcomcnmode, PLCOMCNUNIT))
if (plcomcnattach(&ifpga_pi1, plcomcnspeed, IFPGA_UART_CLK,
plcomcnmode, PLCOMCNUNIT))
panic("can't init serial console");
return;
}