From patchwork Wed Sep 17 03:51:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 390276 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id D70AC140119 for ; Wed, 17 Sep 2014 13:53:51 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 80648A7482; Wed, 17 Sep 2014 05:53:30 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id sDiOoQ1JgZtI; Wed, 17 Sep 2014 05:53:30 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1DBE2A74D8; Wed, 17 Sep 2014 05:52:24 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A20C7A7450 for ; Wed, 17 Sep 2014 05:52:16 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gS3FHJzFUUQF for ; Wed, 17 Sep 2014 05:52:15 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pd0-f202.google.com (mail-pd0-f202.google.com [209.85.192.202]) by theia.denx.de (Postfix) with ESMTPS id 753DDA7470 for ; Wed, 17 Sep 2014 05:52:00 +0200 (CEST) Received: by mail-pd0-f202.google.com with SMTP id ft15so295285pdb.3 for ; Tue, 16 Sep 2014 20:51:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=r2c9ARRMI0keW+yX23dfvSyi7M7FmLmC/84V0YdmO1Y=; b=jbFYHA7bEmkM1qXsSoZVlWb4kXW97nBrxAqlAMOM5cX1sRdzkywmZ9MVBJIm2YASmo jCF2N0aHDIeEhySlLfdJl2VcTH5+vYQK0AqBFDGW870sTA3G4J9ewLjQUY0Jtq5XthBx sv0Z24z/3zzy2Bv0DaeFWIrQwZI5wWc+P2ZEzeaDL95g+zh6yP5gmwPP7heqbY73k27n wxLFlQ0zMU5YN6B6pcM9roMPEpIa02S1o+LFqVl6Q3YkzOV7rCQzT8yiB+c0lZ/9nq9M fhvrsYfAifw+tsa2SPvPvIStpgW7cqA6d4gIKq7MH4L6fcQgpg8uVqBqSy4WliugAQrw 551A== X-Gm-Message-State: ALoCoQm3amYLbhgUaOwNz7RWydVRYx0RWhL45o2JtUVYul3Pq1zsfaXtnwL4SQNBAtmtKBYaozA7 X-Received: by 10.68.219.226 with SMTP id pr2mr22602216pbc.4.1410925919093; Tue, 16 Sep 2014 20:51:59 -0700 (PDT) Received: from corpmail-nozzle1-1.hot.corp.google.com ([100.108.1.104]) by gmr-mx.google.com with ESMTPS id j25si795234yhb.0.2014.09.16.20.51.58 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 Sep 2014 20:51:59 -0700 (PDT) Received: from kaki.bld.corp.google.com ([172.29.216.32]) by corpmail-nozzle1-1.hot.corp.google.com with ESMTP id Va3pwbbX.1; Tue, 16 Sep 2014 20:51:58 -0700 Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 16551225470; Tue, 16 Sep 2014 21:51:57 -0600 (MDT) From: Simon Glass To: U-Boot Mailing List Date: Tue, 16 Sep 2014 21:51:23 -0600 Message-Id: <1410925884-8767-11-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 2.1.0.rc2.206.gedb03e5 In-Reply-To: <1410925884-8767-1-git-send-email-sjg@chromium.org> References: <1410925884-8767-1-git-send-email-sjg@chromium.org> Subject: [U-Boot] [PATCH v2 10/11] dm: imx: serial: Support driver model in the MXC serial driver X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de 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 --- Changes in v2: None drivers/serial/serial_mxc.c | 170 +++++++++++++++++++++++++++++++++++++------- include/serial_mxc.h | 14 ++++ 2 files changed, 159 insertions(+), 25 deletions(-) create mode 100644 include/serial_mxc.h diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c index 313d560..9ce24f9 100644 --- a/drivers/serial/serial_mxc.c +++ b/drivers/serial/serial_mxc.c @@ -5,37 +5,15 @@ */ #include +#include +#include +#include #include #include #include #include #include -#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 diff --git a/include/serial_mxc.h b/include/serial_mxc.h new file mode 100644 index 0000000..7d3ace2 --- /dev/null +++ b/include/serial_mxc.h @@ -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