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:
parent
128449c491
commit
4c5a9380ec
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user