From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 96F45C433F5 for ; Wed, 6 Apr 2022 07:59:09 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1096283DAE; Wed, 6 Apr 2022 09:58:47 +0200 (CEST) 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="MkCP7grK"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 8DEA083D4D; Wed, 6 Apr 2022 09:58:38 +0200 (CEST) Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) (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 C6DB683D95 for ; Wed, 6 Apr 2022 09:58:28 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=jim.t90615@gmail.com Received: by mail-pj1-x1033.google.com with SMTP id a16-20020a17090a6d9000b001c7d6c1bb13so1924228pjk.4 for ; Wed, 06 Apr 2022 00:58:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xWUnggi2jKh+1m+boXVtErmZHBoSiynr6KjgDbgx+Ug=; b=MkCP7grK5Ug8ar4hg94+9VdtOqvihWlHr8Ya9r2YFH42qttL8IgTtZKpRDqPp/S0TS fH6TUAXVJUwSmo36GsDw8V9n5I0Kk4TcfHM4IxTR0Su1KR7zttngHMIt8llrQ0nXSP5D yhC/TGl/+ubicOaBR3qKPhLuIrgQ/LXbY9ObxzJsYF/tno9nuvKbh/ZyO1xezapfy1V3 D60NnLwpKzfRLN3V7ts/pPgs9AXI9NDfNBJlBWlLBDcvzUN6GnslmlW3ISKkFz+dY/v/ SwnA2EHP8N1x9f5l7E5rVgA4v31AJXcg1yAyUO665SmKUlTm7qnF6zep1NR9m5X9mKt+ kqPQ== 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:in-reply-to :references; bh=xWUnggi2jKh+1m+boXVtErmZHBoSiynr6KjgDbgx+Ug=; b=mY7yz8+sKyyabmpvEu6QyuEE1bXtQav2hd1YO/P2u6SHQioTJpmSlH+Pbl0HZ5iShU /OzXdFSBrpVxnJupxPVRDIkOrFt7Otqu1osJsGuooPtVYPLrxwf3FOQzdPwcJoMLHxcN Um6b4l8wa0O2hsSezGhfRmjAMVET3Jp1iAde3cfPLfdCCifvym/4/zUaz/nbj0z+MU6K OT3dmCPfFsSX+HzpcbEekcLerD0+ddULsdV8rlB8zE6QV/tGTbptB3dFF/oGgh5O0Rhg EzdeDXgRdzhqkL9+eYN+aZkE+E74cVHroq9bdE4aVNihLFOJjvox4LwoBYdx9Lqfi5m/ ZfHA== X-Gm-Message-State: AOAM5311RxhR3pBIrqjy9LWHr8cBHEvF3zs3HWV6LsdS9I/iDo330JnK +9XU4Ka+Cd9bjrA1Dtk7DDE= X-Google-Smtp-Source: ABdhPJx4zWzYUbroMtVd10dehOW8bIp55AOryzt+q5jnfxgtOZ2cd4ekdCP/fyAVREBwztS0KAPSAg== X-Received: by 2002:a17:903:1210:b0:151:fa59:95ef with SMTP id l16-20020a170903121000b00151fa5995efmr7639498plh.57.1649231907150; Wed, 06 Apr 2022 00:58:27 -0700 (PDT) Received: from localhost.localdomain ([112.78.82.106]) by smtp.gmail.com with ESMTPSA id p3-20020a056a000b4300b004faee36ea56sm18457765pfo.155.2022.04.06.00.58.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Apr 2022 00:58:26 -0700 (PDT) From: Jim Liu X-Google-Original-From: Jim Liu To: JJLIU0@nuvoton.com, YSCHU@nuvoton.com, KWLIU@nuvoton.com, lukma@denx.de, seanga2@gmail.com, sjg@chromium.org, sr@denx.de, trini@konsulko.com Cc: u-boot@lists.denx.de, Stanley Chu Subject: [PATCH v1 4/6] serial: npcm: Add support for Nuvoton NPCM SoCs Date: Wed, 6 Apr 2022 15:57:35 +0800 Message-Id: <20220406075737.27938-5-JJLIU0@nuvoton.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220406075737.27938-1-JJLIU0@nuvoton.com> References: <20220406075737.27938-1-JJLIU0@nuvoton.com> 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: Jim Liu Signed-off-by: Stanley Chu Reviewed-by: Simon Glass --- drivers/serial/Kconfig | 7 ++ drivers/serial/Makefile | 1 + drivers/serial/serial_npcm.c | 150 +++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 drivers/serial/serial_npcm.c diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 345d1881f5..77458084d4 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -928,6 +928,13 @@ config MPC8XX_CONS depends on MPC8xx default y +config NPCM_SERIAL + bool "Nuvoton NPCM UART driver" + depends on DM_SERIAL + help + Select this to enable UART support for Nuvoton BMCs + (NPCM7xx and NPCM8xx) + config XEN_SERIAL bool "XEN serial support" depends on XEN diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 52e70aa191..8f12af4779 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_MSM_GENI_SERIAL) += serial_msm_geni.o obj-$(CONFIG_MVEBU_A3700_UART) += serial_mvebu_a3700.o obj-$(CONFIG_MPC8XX_CONS) += serial_mpc8xx.o obj-$(CONFIG_NULLDEV_SERIAL) += serial_nulldev.o +obj-$(CONFIG_NPCM_SERIAL) += serial_npcm.o obj-$(CONFIG_OCTEON_SERIAL_BOOTCMD) += serial_octeon_bootcmd.o obj-$(CONFIG_OCTEON_SERIAL_PCIE_CONSOLE) += serial_octeon_pcie_console.o obj-$(CONFIG_OWL_SERIAL) += serial_owl.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, +}; -- 2.17.1