From patchwork Mon Jan 24 04:48:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanley Chu X-Patchwork-Id: 1583269 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=G66yODH4; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4JhyDS6wGCz9sRR for ; Mon, 24 Jan 2022 15:48:38 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 21584810EC; Mon, 24 Jan 2022 05:48:31 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="G66yODH4"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D0863830B9; Mon, 24 Jan 2022 05:48:28 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id CE48F810EC for ; Mon, 24 Jan 2022 05:48:25 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=stanley.chuys@gmail.com Received: by mail-pg1-x535.google.com with SMTP id t32so14248945pgm.7 for ; Sun, 23 Jan 2022 20:48:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id; bh=fB/Z2fTiCCTjsWbLIxaD1rTUC+toipWN2Z3XHNf/TTs=; b=G66yODH4nQVDlIQ35MSgnzVOwdp49a0sFUfWP36GTLrOrmX5JiUaozqdsM8HGRDuzE zulScVXTBR/lAqzMJ/A+bP5QW+rUPHP25c8aGQ3gyX9vvStCdwpiT4r2Z3xZ5PktYiWg ThSCmk9rwX8IUFTaf9Cd9M4qo0T1NksC4Fvy78VvNahv6Zjf2rPWOtOtn67rxi7yfvZ6 Lm5PXNnhZpwEfW6cczZZRDDC3qvrq/rvWpiiYtPULqOCphdL3QV5liBtyGDnClY0S3ZS RV3DLveyEaT0kS1XRteO0FyCkL+fXEA6BJwjh1tt8bhUHdY4Y6lc+9K2oUEHtionLlF1 zZew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=fB/Z2fTiCCTjsWbLIxaD1rTUC+toipWN2Z3XHNf/TTs=; b=41U19YrKqG0A0wIlkstp4/uQnFuIE/MBPTTc20t3W0o+AMOSvM5+JciYBbGmq1B6m8 QDGcN671D1XWFS405mk6IjIONdWXB6dyq9T5AY7B34hx/g+mNvE05+DeEcF6TFkA4bQO bOBG+kwDylJ67yyAqYdQwPB1ZHwU0DcPtRp817R/kVfNbq9rFRQBs7DVB2MNTatsuKXd KKSsaLT8963MVW79jCW1rtsRLCvKPXUuEXFS4ZGuRIL8Ja7ZSAaR56cyR/L/36roeNS0 oGmUJICMn6Dt3au2dNdwMqIB073pCvHFIGXAPlXPQ+oQtVn7mbojynK8levliQ3n6E5s JqHw== X-Gm-Message-State: AOAM5312pZJHZYp+M5PBwtY7s5kl9OcNxcLM1W7lwpV8Hq8DiL1VZHSj 8NJIJgtG/X66pUOYV5irsDg= X-Google-Smtp-Source: ABdhPJzXu4OGBnlHQliMir44MLfEu8YX9J9wO2TdY7HQKRS+YcNkAiN1HzoQauVPwsEbUzzT9D4+Tw== X-Received: by 2002:a62:8fd0:0:b0:4c6:e1d9:7822 with SMTP id n199-20020a628fd0000000b004c6e1d97822mr12681636pfd.38.1642999703946; Sun, 23 Jan 2022 20:48:23 -0800 (PST) Received: from cs20-buildserver.lan ([116.89.135.206]) by smtp.gmail.com with ESMTPSA id l12sm17995498pjq.57.2022.01.23.20.48.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 23 Jan 2022 20:48:23 -0800 (PST) From: Stanley Chu X-Google-Original-From: Stanley Chu To: yschu@nuvoton.com, kwliu@nuvoton.com, ctcchien@nuvoton.com, avifishman70@gmail.com, tmaimon77@gmail.com, sr@denx.de, sjg@chromium.org Cc: u-boot@lists.denx.de Subject: [PATCH v2 1/1] serial: npcm: Add support for Nuvoton NPCM SoCs Date: Mon, 24 Jan 2022 12:48:14 +0800 Message-Id: <20220124044814.18993-1-yschu@nuvoton.com> X-Mailer: git-send-email 2.17.1 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Add Nuvoton BMC NPCM7xx/NPCM8xx uart driver Signed-off-by: Stanley Chu Reviewed-by: Simon Glass --- Changes in v2: Drop unnecessary outer brackets. Return -EAGAIN if not ready for tx/rx. Add comments. --- drivers/serial/Kconfig | 9 +++ drivers/serial/Makefile | 1 + drivers/serial/serial_npcm.c | 150 +++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 drivers/serial/serial_npcm.c diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 6c8fdda9a0..e67a76a424 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -920,6 +920,15 @@ config MPC8XX_CONS depends on MPC8xx default y +config NPCM_SERIAL + bool "UART driver for Nuvoton NPCM BMC" + depends on DM_SERIAL + help + Select this to enable UART support for Nuvoton BMCs + (NPCM7xx and NPCM8xx). + The driver enables the onboard serial port with 8-N-1 + configuration. + config XEN_SERIAL bool "XEN serial support" depends on XEN diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 8168af640f..866495e416 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -73,6 +73,7 @@ obj-$(CONFIG_OWL_SERIAL) += serial_owl.o obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o obj-$(CONFIG_MTK_SERIAL) += serial_mtk.o obj-$(CONFIG_MT7620_SERIAL) += serial_mt7620.o +obj-$(CONFIG_NPCM_SERIAL) += serial_npcm.o obj-$(CONFIG_SIFIVE_SERIAL) += serial_sifive.o obj-$(CONFIG_XEN_SERIAL) += serial_xen.o diff --git a/drivers/serial/serial_npcm.c b/drivers/serial/serial_npcm.c new file mode 100644 index 0000000000..0c6f0410cf --- /dev/null +++ b/drivers/serial/serial_npcm.c @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#include +#include +#include +#include + +struct npcm_uart { + union { + u32 rbr; /* Receive Buffer Register */ + u32 thr; /* Transmit Holding Register */ + u32 dll; /* Divisor Latch (Low Byte) Register */ + }; + union { + u32 ier; /* Interrupt Enable Register */ + u32 dlm; /* Divisor Latch (Low Byte) Register */ + }; + union { + u32 iir; /* Interrupt Identification Register */ + u32 fcr; /* FIFO Control Register */ + }; + u32 lcr; /* Line Control Register */ + u32 mcr; /* Modem Control Register */ + u32 lsr; /* Line Status Control Register */ + u32 msr; /* Modem Status Register */ + u32 tor; /* Timeout Register */ +}; + +#define LCR_WLS_8BITS 3 /* 8-bit word length select */ +#define FCR_TFR BIT(2) /* TxFIFO reset */ +#define FCR_RFR BIT(1) /* RxFIFO reset */ +#define FCR_FME BIT(0) /* FIFO mode enable */ +#define LSR_THRE BIT(5) /* Status of TxFIFO empty */ +#define LSR_RFDR BIT(0) /* Status of RxFIFO data ready */ +#define LCR_DLAB BIT(7) /* Divisor latch access bit */ + +struct npcm_serial_plat { + struct npcm_uart *reg; + u32 uart_clk; /* frequency of uart clock source */ +}; + +static int npcm_serial_pending(struct udevice *dev, bool input) +{ + struct npcm_serial_plat *plat = dev_get_plat(dev); + struct npcm_uart *uart = plat->reg; + + if (input) + return readb(&uart->lsr) & LSR_RFDR ? 1 : 0; + else + return readb(&uart->lsr) & LSR_THRE ? 0 : 1; +} + +static int npcm_serial_putc(struct udevice *dev, const char ch) +{ + struct npcm_serial_plat *plat = dev_get_plat(dev); + struct npcm_uart *uart = plat->reg; + + if (!(readb(&uart->lsr) & LSR_THRE)) + return -EAGAIN; + + writeb(ch, &uart->thr); + + return 0; +} + +static int npcm_serial_getc(struct udevice *dev) +{ + struct npcm_serial_plat *plat = dev_get_plat(dev); + struct npcm_uart *uart = plat->reg; + + if (!(readb(&uart->lsr) & LSR_RFDR)) + return -EAGAIN; + + return readb(&uart->rbr); +} + +static int npcm_serial_setbrg(struct udevice *dev, int baudrate) +{ + struct npcm_serial_plat *plat = dev_get_plat(dev); + struct npcm_uart *uart = plat->reg; + u16 divisor; + + /* BaudOut = UART Clock / (16 * [Divisor + 2]) */ + divisor = DIV_ROUND_CLOSEST(plat->uart_clk, 16 * baudrate + 2) - 2; + + setbits_8(&uart->lcr, LCR_DLAB); + writeb(divisor & 0xff, &uart->dll); + writeb(divisor >> 8, &uart->dlm); + clrbits_8(&uart->lcr, LCR_DLAB); + + return 0; +} + +static int npcm_serial_probe(struct udevice *dev) +{ + struct npcm_serial_plat *plat = dev_get_plat(dev); + struct npcm_uart *uart = plat->reg; + struct clk clk; + u32 freq; + int ret; + + plat->reg = dev_read_addr_ptr(dev); + freq = dev_read_u32_default(dev, "clock-frequency", 0); + + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) + return ret; + + ret = clk_set_rate(&clk, freq); + if (ret < 0) + return ret; + plat->uart_clk = ret; + + /* Disable all interrupt */ + writeb(0, &uart->ier); + + /* Set 8 bit, 1 stop, no parity */ + writeb(LCR_WLS_8BITS, &uart->lcr); + + /* Reset RX/TX FIFO */ + writeb(FCR_FME | FCR_RFR | FCR_TFR, &uart->fcr); + + return 0; +} + +static const struct dm_serial_ops npcm_serial_ops = { + .getc = npcm_serial_getc, + .setbrg = npcm_serial_setbrg, + .putc = npcm_serial_putc, + .pending = npcm_serial_pending, +}; + +static const struct udevice_id npcm_serial_ids[] = { + { .compatible = "nuvoton,npcm750-uart" }, + { .compatible = "nuvoton,npcm845-uart" }, + { } +}; + +U_BOOT_DRIVER(serial_npcm) = { + .name = "serial_npcm", + .id = UCLASS_SERIAL, + .of_match = npcm_serial_ids, + .plat_auto = sizeof(struct npcm_serial_plat), + .probe = npcm_serial_probe, + .ops = &npcm_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +};