dm: imx: serial: Support driver model in the MXC serial driver
Add driver model support with this driver. Boards which use this driver should define platform data in their board files. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
441d0cfff1
commit
a8ba569cba
@ -5,37 +5,15 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <serial_mxc.h>
|
||||
#include <watchdog.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <serial.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#define __REG(x) (*((volatile u32 *)(x)))
|
||||
|
||||
#ifndef CONFIG_MXC_UART_BASE
|
||||
#error "define CONFIG_MXC_UART_BASE to use the MXC UART driver"
|
||||
#endif
|
||||
|
||||
#define UART_PHYS CONFIG_MXC_UART_BASE
|
||||
|
||||
/* Register definitions */
|
||||
#define URXD 0x0 /* Receiver Register */
|
||||
#define UTXD 0x40 /* Transmitter Register */
|
||||
#define UCR1 0x80 /* Control Register 1 */
|
||||
#define UCR2 0x84 /* Control Register 2 */
|
||||
#define UCR3 0x88 /* Control Register 3 */
|
||||
#define UCR4 0x8c /* Control Register 4 */
|
||||
#define UFCR 0x90 /* FIFO Control Register */
|
||||
#define USR1 0x94 /* Status Register 1 */
|
||||
#define USR2 0x98 /* Status Register 2 */
|
||||
#define UESC 0x9c /* Escape Character Register */
|
||||
#define UTIM 0xa0 /* Escape Timer Register */
|
||||
#define UBIR 0xa4 /* BRM Incremental Register */
|
||||
#define UBMR 0xa8 /* BRM Modulator Register */
|
||||
#define UBRC 0xac /* Baud Rate Count Register */
|
||||
#define UTS 0xb4 /* UART Test Register (mx31) */
|
||||
|
||||
/* UART Control Register Bit Fields.*/
|
||||
#define URXD_CHARRDY (1<<15)
|
||||
#define URXD_ERR (1<<14)
|
||||
@ -128,6 +106,33 @@
|
||||
#define UTS_RXFULL (1<<3) /* RxFIFO full */
|
||||
#define UTS_SOFTRST (1<<0) /* Software reset */
|
||||
|
||||
#ifndef CONFIG_DM_SERIAL
|
||||
|
||||
#ifndef CONFIG_MXC_UART_BASE
|
||||
#error "define CONFIG_MXC_UART_BASE to use the MXC UART driver"
|
||||
#endif
|
||||
|
||||
#define UART_PHYS CONFIG_MXC_UART_BASE
|
||||
|
||||
#define __REG(x) (*((volatile u32 *)(x)))
|
||||
|
||||
/* Register definitions */
|
||||
#define URXD 0x0 /* Receiver Register */
|
||||
#define UTXD 0x40 /* Transmitter Register */
|
||||
#define UCR1 0x80 /* Control Register 1 */
|
||||
#define UCR2 0x84 /* Control Register 2 */
|
||||
#define UCR3 0x88 /* Control Register 3 */
|
||||
#define UCR4 0x8c /* Control Register 4 */
|
||||
#define UFCR 0x90 /* FIFO Control Register */
|
||||
#define USR1 0x94 /* Status Register 1 */
|
||||
#define USR2 0x98 /* Status Register 2 */
|
||||
#define UESC 0x9c /* Escape Character Register */
|
||||
#define UTIM 0xa0 /* Escape Timer Register */
|
||||
#define UBIR 0xa4 /* BRM Incremental Register */
|
||||
#define UBMR 0xa8 /* BRM Modulator Register */
|
||||
#define UBRC 0xac /* Baud Rate Count Register */
|
||||
#define UTS 0xb4 /* UART Test Register (mx31) */
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static void mxc_serial_setbrg(void)
|
||||
@ -222,3 +227,118 @@ __weak struct serial_device *default_serial_console(void)
|
||||
{
|
||||
return &mxc_serial_drv;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DM_SERIAL
|
||||
|
||||
struct mxc_uart {
|
||||
u32 rxd;
|
||||
u32 spare0[15];
|
||||
|
||||
u32 txd;
|
||||
u32 spare1[15];
|
||||
|
||||
u32 cr1;
|
||||
u32 cr2;
|
||||
u32 cr3;
|
||||
u32 cr4;
|
||||
|
||||
u32 fcr;
|
||||
u32 sr1;
|
||||
u32 sr2;
|
||||
u32 esc;
|
||||
|
||||
u32 tim;
|
||||
u32 bir;
|
||||
u32 bmr;
|
||||
u32 brc;
|
||||
|
||||
u32 onems;
|
||||
u32 ts;
|
||||
};
|
||||
|
||||
int mxc_serial_setbrg(struct udevice *dev, int baudrate)
|
||||
{
|
||||
struct mxc_serial_platdata *plat = dev->platdata;
|
||||
struct mxc_uart *const uart = plat->reg;
|
||||
u32 clk = imx_get_uartclk();
|
||||
|
||||
writel(4 << 7, &uart->fcr); /* divide input clock by 2 */
|
||||
writel(0xf, &uart->bir);
|
||||
writel(clk / (2 * baudrate), &uart->bmr);
|
||||
|
||||
writel(UCR2_WS | UCR2_IRTS | UCR2_RXEN | UCR2_TXEN | UCR2_SRST,
|
||||
&uart->cr2);
|
||||
writel(UCR1_UARTEN, &uart->cr1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxc_serial_probe(struct udevice *dev)
|
||||
{
|
||||
struct mxc_serial_platdata *plat = dev->platdata;
|
||||
struct mxc_uart *const uart = plat->reg;
|
||||
|
||||
writel(0, &uart->cr1);
|
||||
writel(0, &uart->cr2);
|
||||
while (!(readl(&uart->cr2) & UCR2_SRST));
|
||||
writel(0x704 | UCR3_ADNIMP, &uart->cr3);
|
||||
writel(0x8000, &uart->cr4);
|
||||
writel(0x2b, &uart->esc);
|
||||
writel(0, &uart->tim);
|
||||
writel(0, &uart->ts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxc_serial_getc(struct udevice *dev)
|
||||
{
|
||||
struct mxc_serial_platdata *plat = dev->platdata;
|
||||
struct mxc_uart *const uart = plat->reg;
|
||||
|
||||
if (readl(&uart->ts) & UTS_RXEMPTY)
|
||||
return -EAGAIN;
|
||||
|
||||
return readl(&uart->rxd) & URXD_RX_DATA;
|
||||
}
|
||||
|
||||
static int mxc_serial_putc(struct udevice *dev, const char ch)
|
||||
{
|
||||
struct mxc_serial_platdata *plat = dev->platdata;
|
||||
struct mxc_uart *const uart = plat->reg;
|
||||
|
||||
if (!(readl(&uart->ts) & UTS_TXEMPTY))
|
||||
return -EAGAIN;
|
||||
|
||||
writel(ch, &uart->txd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mxc_serial_pending(struct udevice *dev, bool input)
|
||||
{
|
||||
struct mxc_serial_platdata *plat = dev->platdata;
|
||||
struct mxc_uart *const uart = plat->reg;
|
||||
uint32_t sr2 = readl(&uart->sr2);
|
||||
|
||||
if (input)
|
||||
return sr2 & USR2_RDR ? 1 : 0;
|
||||
else
|
||||
return sr2 & USR2_TXDC ? 0 : 1;
|
||||
}
|
||||
|
||||
static const struct dm_serial_ops mxc_serial_ops = {
|
||||
.putc = mxc_serial_putc,
|
||||
.pending = mxc_serial_pending,
|
||||
.getc = mxc_serial_getc,
|
||||
.setbrg = mxc_serial_setbrg,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(serial_mxc) = {
|
||||
.name = "serial_mxc",
|
||||
.id = UCLASS_SERIAL,
|
||||
.probe = mxc_serial_probe,
|
||||
.ops = &mxc_serial_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
#endif
|
||||
|
14
include/serial_mxc.h
Normal file
14
include/serial_mxc.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __serial_mxc_h
|
||||
#define __serial_mxc_h
|
||||
|
||||
/* Information about a serial port */
|
||||
struct mxc_serial_platdata {
|
||||
struct mxc_uart *reg; /* address of registers in physical memory */
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user