From patchwork Mon Apr 9 19:38:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Karthikeyan Ramasubramanian X-Patchwork-Id: 10331951 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 1A5146022E for ; Mon, 9 Apr 2018 19:39:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 09E1628BF0 for ; Mon, 9 Apr 2018 19:39:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F2D7828BF4; Mon, 9 Apr 2018 19:39:08 +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 84BC128BF0 for ; Mon, 9 Apr 2018 19:39:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754230AbeDITjH (ORCPT ); Mon, 9 Apr 2018 15:39:07 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:42948 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754188AbeDITjG (ORCPT ); Mon, 9 Apr 2018 15:39:06 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 124846034E; Mon, 9 Apr 2018 19:39:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1523302746; bh=N8+pN63ID/3fmbdu1HIju0UW28HIyrfIeZDgwlI+sbU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jKXQ+hzKPCIL77agkPAulVt8+jhjlsZjKw+aIs6n6un22viUUH41kw0T946S+Cogk EXPncoGZGbuqo3OMb2hv2i6xR4a+KmEn48byQwtMvxLYjNNHXyRVNLGBZ++LLzRsl+ 2fvAw4YRLP1VA8WES5aanKjQUAG+GN4UoX/r8J8c= 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 653B460C66; Mon, 9 Apr 2018 19:38:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1523302740; bh=N8+pN63ID/3fmbdu1HIju0UW28HIyrfIeZDgwlI+sbU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G+LjbeAXwvUgfKatopFRcQwDgqvenGBhOKcjcPK9ntYapzs5nFka6foeZCDYeLR+T qmOYhFL31IPjLiCU1xXSE4OizfrdxCmkV1P6wcc/14JQiSYUHN01aA48ldlv+KZUry XVevVKbbSwCf+9fMr6w9zOYFEaXYhuYe9IoVQbLo= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 653B460C66 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, sdharia@codeaurora.org, girishm@codeaurora.org, festevam@gmail.com Subject: [PATCH v2 8/8] tty: serial: qcom_geni_serial: Add early console support Date: Mon, 9 Apr 2018 13:38:41 -0600 Message-Id: <1523302721-19439-9-git-send-email-kramasub@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1523302721-19439-1-git-send-email-kramasub@codeaurora.org> References: <1523302721-19439-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 --- drivers/tty/serial/qcom_geni_serial.c | 85 ++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index e40d4a4..2ce83a57 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -196,8 +196,18 @@ 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. + */ + 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) @@ -944,6 +954,77 @@ 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; + u32 ser_clk_cfg; + u32 baud = 115200; + unsigned int clk_div; + unsigned long clk_rate; + 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; + + clk_rate = get_clk_div_rate(baud, &clk_div); + if (!clk_rate) + return -EINVAL; + + ser_clk_cfg = SER_CLK_EN | (clk_div << CLK_DIV_SHFT); + /* + * 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); + writel_relaxed(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG); + writel_relaxed(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG); + + dev->con->write = qcom_geni_serial_earlycon_write; + dev->con->setup = NULL; + return 0; +} +OF_EARLYCON_DECLARE(qcom_serial, "qcom,geni-debug-uart", + qcom_geni_serial_earlycon_setup); + static int __init console_register(struct uart_driver *drv) { return uart_register_driver(drv);