From patchwork Sun Mar 27 20:22:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Beniamino Galvani X-Patchwork-Id: 602383 X-Patchwork-Delegate: trini@ti.com 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 3qY7lg3xGGz9s5M for ; Mon, 28 Mar 2016 07:23:27 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=Q4sYDRad; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 8A07CA75F2; Sun, 27 Mar 2016 22:23:16 +0200 (CEST) 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 npJpV56RsR-r; Sun, 27 Mar 2016 22:23:16 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 35E55A74F1; Sun, 27 Mar 2016 22:23:03 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id DC4ADA748A for ; Sun, 27 Mar 2016 22:22:58 +0200 (CEST) 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 dJ2m-BxwtXUV for ; Sun, 27 Mar 2016 22:22:58 +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-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by theia.denx.de (Postfix) with ESMTPS id 31871A74E9 for ; Sun, 27 Mar 2016 22:22:52 +0200 (CEST) Received: by mail-wm0-f68.google.com with SMTP id l68so16613005wml.3 for ; Sun, 27 Mar 2016 13:22:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=n05L5eYMp2wnn//WWd0gpPNSp66Vvksio0mbrGnyaMk=; b=Q4sYDRadJupodObDyozxNLSLRU4T910ridVwd6NJu2R/0odp2xci3ch9lc0NpWe2Dp 30uYG2NDVgs2Xxf/tGdI+gDh5Og7VudfbW3Dxy6582vF9G/q7R81KdaAzsoK1ln3rBs8 fmPfa4d7Rh8pJ91Hep6rf8qEp4zXftyUrzyxMnMXERe85iOBu2REhfGjZwoDx3VUgkr2 keiD52kBlTac/QW2ScAgVOmBlFG8VN2c/U2dUGPkk2GBzdgos7l7qADNAJT8SwjH7g8q jbvQJPa9QvvOz3GB28tp+ce10IakV80nvNLboFnZgHVWFpBKO8QdbI19qwGlZBRqKuR0 8AMA== 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=n05L5eYMp2wnn//WWd0gpPNSp66Vvksio0mbrGnyaMk=; b=mBzrsII2v0252YvVhEmMlvMVjPcBCTsWOpqfKfhpe8QxVXb9NBtGbaQo0cRhMZXqe9 R6MuU84RuYxKvI/fuARLUL2EwzR6S1I44QDA9rzm3qCqfrt48VWxFqUSCiWYZhEp0klU FffF+tcLHhHdxOnE5tSdCsxx5EKab3dzhALxuw1iHgQ5ABZZLoe4eZk1eMgyVFzNzXYJ UuHXaPi24WbgHYv3B2kgcBzw6Wb2j9KCubFy50crJdlQZZZB1E6n7jSPsTdPaIvtJpsT /6+QUX58cIKPv0xM3GqY5zBULOMndEmAWl6w/82tr04hAhPBFMWc7k9QBQJGwdh0MIk3 tO7Q== X-Gm-Message-State: AD7BkJK5DJgAHsz+PQ67I2Me98DSFxDtNbbvx4R2oBuXF6c/yrCrCNr18YJcX26DAjgdeQ== X-Received: by 10.194.116.9 with SMTP id js9mr29184584wjb.112.1459110172386; Sun, 27 Mar 2016 13:22:52 -0700 (PDT) Received: from shire.fritz.box ([95.236.43.82]) by smtp.gmail.com with ESMTPSA id jo6sm21667503wjb.48.2016.03.27.13.22.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 27 Mar 2016 13:22:51 -0700 (PDT) From: Beniamino Galvani To: u-boot@lists.denx.de Date: Sun, 27 Mar 2016 22:22:13 +0200 Message-Id: <1459110135-10837-4-git-send-email-b.galvani@gmail.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1459110135-10837-1-git-send-email-b.galvani@gmail.com> References: <1459110135-10837-1-git-send-email-b.galvani@gmail.com> Cc: =?UTF-8?q?Andreas=20F=C3=A4rber?= , Carlo Caione Subject: [U-Boot] [PATCH 3/5] serial: add support for Amlogic Meson UART X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Implement a driver for the UART adapter available in Meson SoCs. Signed-off-by: Beniamino Galvani --- drivers/serial/Kconfig | 14 ++++ drivers/serial/Makefile | 1 + drivers/serial/serial_meson.c | 162 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 drivers/serial/serial_meson.c diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 2a770a1..47e26ab 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -112,6 +112,14 @@ config DEBUG_UART_S5P will need to provide parameters to make this work. The driver will be available until the real driver-model serial is running. +config DEBUG_UART_MESON + bool "Amlogic Meson" + depends on MESON_SERIAL + help + Select this to enable a debug UART using the serial_meson driver. You + will need to provide parameters to make this work. The driver will + be available until the real driver-model serial is running. + config DEBUG_UART_UARTLITE bool "Xilinx Uartlite" help @@ -320,4 +328,10 @@ config XILINX_UARTLITE If you have a Xilinx based board and want to use the uartlite serial ports, say Y to this option. If unsure, say N. +config MESON_SERIAL + bool "Support for Amlogic Meson UART" + depends on DM_SERIAL && ARCH_MESON + help + If you have an Amlogic Meson based board and want to use the on-chip + serial ports, say Y to this option. If unsure, say N. endmenu diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 05bdf56..8eb0ca2 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_SYS_NS16550) += ns16550.o obj-$(CONFIG_S5P) += serial_s5p.o obj-$(CONFIG_MXC_UART) += serial_mxc.o obj-$(CONFIG_PXA_SERIAL) += serial_pxa.o +obj-$(CONFIG_MESON_SERIAL) += serial_meson.o obj-$(CONFIG_S3C24X0_SERIAL) += serial_s3c24x0.o obj-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o obj-$(CONFIG_SANDBOX_SERIAL) += sandbox.o diff --git a/drivers/serial/serial_meson.c b/drivers/serial/serial_meson.c new file mode 100644 index 0000000..550b8a5 --- /dev/null +++ b/drivers/serial/serial_meson.c @@ -0,0 +1,162 @@ +/* + * (C) Copyright 2016 Beniamino Galvani + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct meson_uart { + uint32_t wfifo; + uint32_t rfifo; + uint32_t control; + uint32_t status; + uint32_t misc; +}; + +struct meson_serial_platdata { + struct meson_uart *reg; +}; + +/* AML_UART_STATUS bits */ +#define AML_UART_PARITY_ERR BIT(16) +#define AML_UART_FRAME_ERR BIT(17) +#define AML_UART_TX_FIFO_WERR BIT(18) +#define AML_UART_RX_EMPTY BIT(20) +#define AML_UART_TX_FULL BIT(21) +#define AML_UART_TX_EMPTY BIT(22) +#define AML_UART_XMIT_BUSY BIT(25) +#define AML_UART_ERR (AML_UART_PARITY_ERR | \ + AML_UART_FRAME_ERR | \ + AML_UART_TX_FIFO_WERR) + +/* AML_UART_CONTROL bits */ +#define AML_UART_TX_EN BIT(12) +#define AML_UART_RX_EN BIT(13) +#define AML_UART_TX_RST BIT(22) +#define AML_UART_RX_RST BIT(23) +#define AML_UART_CLR_ERR BIT(24) + +static void __maybe_unused meson_serial_init(struct meson_uart *uart) +{ + u32 val; + + val = readl(&uart->control); + val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR); + writel(val, &uart->control); + val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLR_ERR); + writel(val, &uart->control); + val |= (AML_UART_RX_EN | AML_UART_TX_EN); + writel(val, &uart->control); +} + +static int meson_serial_probe(struct udevice *dev) +{ + struct meson_serial_platdata *plat = dev->platdata; + struct meson_uart *const uart = plat->reg; + + meson_serial_init(uart); + + return 0; +} + +static int meson_serial_getc(struct udevice *dev) +{ + struct meson_serial_platdata *plat = dev->platdata; + struct meson_uart *const uart = plat->reg; + + if (readl(&uart->status) & AML_UART_RX_EMPTY) + return -EAGAIN; + + return readl(&uart->rfifo) & 0xff; +} + +static int meson_serial_putc(struct udevice *dev, const char ch) +{ + struct meson_serial_platdata *plat = dev->platdata; + struct meson_uart *const uart = plat->reg; + + if (readl(&uart->status) & AML_UART_TX_FULL) + return -EAGAIN; + + writel(ch, &uart->wfifo); + + return 0; +} + +static int meson_serial_pending(struct udevice *dev, bool input) +{ + struct meson_serial_platdata *plat = dev->platdata; + struct meson_uart *const uart = plat->reg; + uint32_t status = readl(&uart->status); + + if (input) + return !(status & AML_UART_RX_EMPTY); + else + return !(status & AML_UART_TX_FULL); +} + +static int meson_serial_ofdata_to_platdata(struct udevice *dev) +{ + struct meson_serial_platdata *plat = dev->platdata; + fdt_addr_t addr; + + addr = dev_get_addr(dev); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + plat->reg = (struct meson_uart *)addr; + + return 0; +} + +static const struct dm_serial_ops meson_serial_ops = { + .putc = meson_serial_putc, + .pending = meson_serial_pending, + .getc = meson_serial_getc, +}; + +static const struct udevice_id meson_serial_ids[] = { + { .compatible = "amlogic,meson-uart" }, + { } +}; + +U_BOOT_DRIVER(serial_meson) = { + .name = "serial_meson", + .id = UCLASS_SERIAL, + .of_match = meson_serial_ids, + .ofdata_to_platdata = meson_serial_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct meson_serial_platdata), + .probe = meson_serial_probe, + .ops = &meson_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +#ifdef CONFIG_DEBUG_UART_MESON + +#include + +static inline void _debug_uart_init(void) +{ +} + +static inline void _debug_uart_putc(int ch) +{ + struct meson_uart *regs = (struct meson_uart *)CONFIG_DEBUG_UART_BASE; + + while (readl(®s->status) & AML_UART_TX_FULL) + ; + + writel(ch, ®s->wfifo); +} + +DEBUG_UART_FUNCS + +#endif