From patchwork Thu May 3 20:14:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karthikeyan Ramasubramanian X-Patchwork-Id: 10379153 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 57C3560159 for ; Thu, 3 May 2018 20:15:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4635429271 for ; Thu, 3 May 2018 20:15:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3AA2929276; Thu, 3 May 2018 20:15:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 94E6629271 for ; Thu, 3 May 2018 20:15:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751132AbeECUPO (ORCPT ); Thu, 3 May 2018 16:15:14 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:60682 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751234AbeECUPK (ORCPT ); Thu, 3 May 2018 16:15:10 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id C711860AF9; Thu, 3 May 2018 20:15:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1525378509; bh=G0qQVWgsl4Kxo4PBISgQFSGnz0+gOCO4u/XqCCw5TaE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FJDT8FIN4J4DN3XLO+AKjaxfcgedWqfKRmdCDItH/70v7Vb3lVydvVkfW0vVLcjym pH986fjDE6ObDMTkCGBYeWc7yZnp1LazoitoEYyROdDzHI1izvQa8SWS2vkW/xDHvJ tKQKTUzwY4sWD8VY+5u3pMwDwKMsE1EcsRAdPXy8= Received: from codeaurora.org (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: kramasub@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 7709A601A0; Thu, 3 May 2018 20:15:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1525378509; bh=G0qQVWgsl4Kxo4PBISgQFSGnz0+gOCO4u/XqCCw5TaE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FJDT8FIN4J4DN3XLO+AKjaxfcgedWqfKRmdCDItH/70v7Vb3lVydvVkfW0vVLcjym pH986fjDE6ObDMTkCGBYeWc7yZnp1LazoitoEYyROdDzHI1izvQa8SWS2vkW/xDHvJ tKQKTUzwY4sWD8VY+5u3pMwDwKMsE1EcsRAdPXy8= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 7709A601A0 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=kramasub@codeaurora.org From: Karthikeyan Ramasubramanian To: gregkh@linuxfoundation.org, jslaby@suse.com Cc: Karthikeyan Ramasubramanian , linux-arm-msm@vger.kernel.org, linux-serial@vger.kernel.org, evgreen@chromium.org, acourbot@chromium.org, swboyd@chromium.org, dianders@chromium.org, mka@chromium.org, bjorn.andersson@linaro.org, Girish Mahadevan Subject: [PATCH v3 8/8] tty: serial: qcom_geni_serial: Add early console support Date: Thu, 3 May 2018 14:14:40 -0600 Message-Id: <1525378480-10296-9-git-send-email-kramasub@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1525378480-10296-1-git-send-email-kramasub@codeaurora.org> References: <1525378480-10296-1-git-send-email-kramasub@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add early console support in Qualcomm Technologies Inc., GENI based UART controller. Signed-off-by: Karthikeyan Ramasubramanian Signed-off-by: Girish Mahadevan Reviewed-by: Stephen Boyd --- Documentation/admin-guide/kernel-parameters.txt | 6 ++ drivers/tty/serial/qcom_geni_serial.c | 74 ++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 11fc28e..1dda0b6 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1025,6 +1025,12 @@ address. The serial port must already be setup and configured. Options are not yet supported. + qcom_geni, + Start an early, polled-mode console on a Qualcomm + Generic Interface (GENI) based serial port at the + specified address. The serial port must already be + setup and configured. Options are not yet supported. + earlyprintk= [X86,SH,ARM,M68k,S390] earlyprintk=vga earlyprintk=efi diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index c8fd7cd..9d773a9 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -196,8 +196,19 @@ static bool qcom_geni_serial_poll_bit(struct uart_port *uport, timeout_us = ((fifo_bits * USEC_PER_SEC) / baud) + 500; } - return !readl_poll_timeout_atomic(uport->membase + offset, reg, - (bool)(reg & field) == set, 10, timeout_us); + /* + * Use custom implementation instead of readl_poll_atomic since ktimer + * is not ready at the time of early console. + */ + timeout_us = DIV_ROUND_UP(timeout_us, 10) * 10; + while (timeout_us) { + reg = readl_relaxed(uport->membase + offset); + if ((bool)(reg & field) == set) + return true; + udelay(10); + timeout_us -= 10; + } + return false; } static void qcom_geni_serial_setup_tx(struct uart_port *uport, u32 xmit_size) @@ -943,6 +954,65 @@ static int __init qcom_geni_console_setup(struct console *co, char *options) return uart_set_options(uport, co, baud, parity, bits, flow); } +static void qcom_geni_serial_earlycon_write(struct console *con, + const char *s, unsigned int n) +{ + struct earlycon_device *dev = con->data; + + __qcom_geni_serial_console_write(&dev->port, s, n); +} + +static int __init qcom_geni_serial_earlycon_setup(struct earlycon_device *dev, + const char *opt) +{ + struct uart_port *uport = &dev->port; + u32 tx_trans_cfg; + u32 tx_parity_cfg = 0; /* Disable Tx Parity */ + u32 rx_trans_cfg = 0; + u32 rx_parity_cfg = 0; /* Disable Rx Parity */ + u32 stop_bit_len = 0; /* Default stop bit length - 1 bit */ + u32 bits_per_char; + struct geni_se se; + + if (!uport->membase) + return -EINVAL; + + memset(&se, 0, sizeof(se)); + se.base = uport->membase; + if (geni_se_read_proto(&se) != GENI_SE_UART) + return -ENXIO; + /* + * Ignore Flow control. + * n = 8. + */ + tx_trans_cfg = UART_CTS_MASK; + bits_per_char = BITS_PER_BYTE; + + /* + * Make an unconditional cancel on the main sequencer to reset + * it else we could end up in data loss scenarios. + */ + qcom_geni_serial_poll_tx_done(uport); + qcom_geni_serial_abort_rx(uport); + geni_se_config_packing(&se, BITS_PER_BYTE, 1, false, true, false); + geni_se_init(&se, DEF_FIFO_DEPTH_WORDS / 2, DEF_FIFO_DEPTH_WORDS - 2); + geni_se_select_mode(&se, GENI_SE_FIFO); + + writel_relaxed(tx_trans_cfg, uport->membase + SE_UART_TX_TRANS_CFG); + writel_relaxed(tx_parity_cfg, uport->membase + SE_UART_TX_PARITY_CFG); + writel_relaxed(rx_trans_cfg, uport->membase + SE_UART_RX_TRANS_CFG); + writel_relaxed(rx_parity_cfg, uport->membase + SE_UART_RX_PARITY_CFG); + writel_relaxed(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN); + writel_relaxed(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN); + writel_relaxed(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); + + dev->con->write = qcom_geni_serial_earlycon_write; + dev->con->setup = NULL; + return 0; +} +OF_EARLYCON_DECLARE(qcom_geni, "qcom,geni-debug-uart", + qcom_geni_serial_earlycon_setup); + static int __init console_register(struct uart_driver *drv) { return uart_register_driver(drv);