Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp5591652pxb; Mon, 28 Mar 2022 14:40:19 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxODRXlPE+Ljr1vckGaqt641BJ+bzNFuOhmRoN86XS6uUP8NS3f8JaJjZbaxxxlHPH+7JjR X-Received: by 2002:a05:6870:42cc:b0:dd:a03f:195e with SMTP id z12-20020a05687042cc00b000dda03f195emr634414oah.234.1648503619630; Mon, 28 Mar 2022 14:40:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1648503619; cv=none; d=google.com; s=arc-20160816; b=j5y+YAKV8mR9yCOBUk6ivvO0TldHXKNJUyAMXWIpCevTcHyxSMggdNw8bovU9cg1RG aLgRuv3XKTJu6farxu85xhTGfdLnQiG3Rq2+PPQXqaFOyyAQtOdnOSftAa4xHHeT/jCJ uNdOU0dKnDwQGFfMTqJgalFhoWZO8WbYKAswD1L0Knd4R1F+0w6+Da9TI47mdF2S4K/z QL4WqgdP/lil1Pl3FfAmQSBAPp3uGFQ9milKRlGPykqewdAE+2T+SP1ccBoV/VnMGG9S CXLPrd1ZHk8uUGlkx3c77pkrNtk0CfzsxtAJDFqQBEX/hANHNqap10dIsWnFPeBTLmYB 4R/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-filter; bh=6Kd3qMHO00PfqoQRXxobfhr4JHDlRHPHTHTka6IvHzU=; b=vMqvHeo6LZTyxOlFRhMlzlW/hob+1XwYB1ZjdE8vpTBPcDetm/SX6DySvcm3xm8ywk bk4BVRz4TI+lB7xJDECRTKVZ7rh3xnqDJc1vkrB7B0xoA+KzuQStBb/n6HY9K3wdTzOR 2FKXeLKDXM/CLl6atiCOyanm28xWF6ESWYUdmbRMz4BfuRrTocksxQS6N7W6zgEhGRsG +bMDF0E/W+2BHpkw8kz4Vt9moZ61AKTQaaaxzr0t9T0vHQj8Ldw14wUVMrez6dSff5Wk 0ucvVGS/uCQw4XkUffc8IbE8WimGpEWhhL/Jy/LCgAYXBsKC+utIMYaBPu7eybNYVytT ksQg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@baikalelectronics.ru header.s=mail header.b=R4S7cLaf; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id z37-20020a056870462500b000da9200b88asi10874290oao.85.2022.03.28.14.40.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Mar 2022 14:40:19 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@baikalelectronics.ru header.s=mail header.b=R4S7cLaf; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id DDA19986D7; Mon, 28 Mar 2022 14:17:11 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240350AbiC1Ps5 (ORCPT + 99 others); Mon, 28 Mar 2022 11:48:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45928 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238796AbiC1PqD (ORCPT ); Mon, 28 Mar 2022 11:46:03 -0400 Received: from mail.baikalelectronics.ru (mail.baikalelectronics.com [87.245.175.226]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 1200E4A939; Mon, 28 Mar 2022 08:44:14 -0700 (PDT) Received: from mail.baikalelectronics.ru (unknown [192.168.51.25]) by mail.baikalelectronics.ru (Postfix) with ESMTP id 95F091E28E0; Thu, 24 Mar 2022 03:16:46 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.baikalelectronics.ru 95F091E28E0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baikalelectronics.ru; s=mail; t=1648081006; bh=6Kd3qMHO00PfqoQRXxobfhr4JHDlRHPHTHTka6IvHzU=; h=From:To:CC:Subject:Date:In-Reply-To:References:From; b=R4S7cLafeqzKFMHAT7tnNTxpGXj1ZXiAbnolqppgbqxwV7H24GU4nU5y5mtydGP3W 5RER6jTwF0ln2sWI+l1LinMGGnu5b+0hOVZ/Tcrx1VNGUJtJ33yooTv73s5yfyz9jF 0NDRyJZIxiFM2rEpftYbEiMCh4FJ9TvobkY/mwcQ= Received: from localhost (192.168.168.10) by mail (192.168.51.25) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Thu, 24 Mar 2022 03:16:46 +0300 From: Serge Semin To: Damien Le Moal , Hans de Goede , Jens Axboe , Serge Semin CC: Serge Semin , Alexey Malahov , Pavel Parkhomenko , Rob Herring , , , Subject: [PATCH 20/21] ata: ahci-dwc: Add Baikal-T1 AHCI SATA interface support Date: Thu, 24 Mar 2022 03:16:27 +0300 Message-ID: <20220324001628.13028-21-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20220324001628.13028-1-Sergey.Semin@baikalelectronics.ru> References: <20220324001628.13028-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org It's almost fully compatible DWC AHCI SATA IP-core derivative except the reference clocks source, which need to be very carefully selected. In particular the DWC AHCI SATA PHY can be clocked either from the pads ref_pad_clk_{m,p} or from the internal wires ref_alt_clk_{m,n}. In the later case the clock signal is generated from the Baikal-T1 CCU SATA PLL. The clocks source is selected by means of the ref_use_pad wire connected to the CCU SATA reference clock CSR. In normal situation it would be much more handy to use the internal reference clock source, but alas we haven't managed to make the AHCI controller working well with it so far. So it's preferable to have the controller clocked from the external clock generator and fallback to the internal clock source only as a last resort. Other than that the controller is full compatible with the DWC AHCI SATA IP-core. Signed-off-by: Serge Semin --- drivers/ata/Kconfig | 1 + drivers/ata/ahci_dwc.c | 86 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index ab11bcf8510c..003f000a69a7 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -178,6 +178,7 @@ config AHCI_DWC tristate "Synopsys DWC AHCI SATA support" select SATA_HOST default SATA_AHCI_PLATFORM + select MFD_SYSCON if (MIPS_BAIKAL_T1 || COMPILE_TEST) help This option enables support for the Synopsys DWC AHCI SATA controller implementation. diff --git a/drivers/ata/ahci_dwc.c b/drivers/ata/ahci_dwc.c index 9e294f994ed3..efcd5f74c2d4 100644 --- a/drivers/ata/ahci_dwc.c +++ b/drivers/ata/ahci_dwc.c @@ -13,10 +13,12 @@ #include #include #include +#include #include #include #include #include +#include #include "ahci.h" @@ -90,6 +92,26 @@ #define DWC_AHCI_PORT_PHYCR 0x74 #define DWC_AHCI_PORT_PHYSR 0x78 +/* Baikal-T1 AHCI SATA specific registers */ +#define BT1_AHCI_HOST_PHYCR DWC_AHCI_HOST_GPCR +#define BT1_AHCI_HOST_MPLM_MASK GENMASK(29, 23) +#define BT1_AHCI_HOST_LOSDT_MASK GENMASK(22, 20) +#define BT1_AHCI_HOST_CRR BIT(19) +#define BT1_AHCI_HOST_CRW BIT(18) +#define BT1_AHCI_HOST_CRCD BIT(17) +#define BT1_AHCI_HOST_CRCA BIT(16) +#define BT1_AHCI_HOST_CRDI_MASK GENMASK(15, 0) + +#define BT1_AHCI_HOST_PHYSR DWC_AHCI_HOST_GPSR +#define BT1_AHCI_HOST_CRA BIT(16) +#define BT1_AHCI_HOST_CRDO_MASK GENMASK(15, 0) + +/* Baikal-T1 CCU registers concerning the AHCI SATA module */ +#define BT1_CCU_SYS_SATA_REF 0x60 +#define BT1_CCU_SYS_SATA_REF_EXT BIT(28) +#define BT1_CCU_SYS_SATA_REF_INV BIT(29) +#define BT1_CCU_SYS_SATA_REF_BUF BIT(30) + struct dwc_ahci_plat_data { unsigned int pflags; unsigned int hflags; @@ -106,6 +128,64 @@ struct dwc_ahci_host_priv { u32 dmacr[AHCI_MAX_PORTS]; }; +static int bt1_ahci_init(struct ahci_host_priv *hpriv) +{ + struct dwc_ahci_host_priv *dpriv = hpriv->plat_data; + struct regmap *sys_regs; + u32 ref_ctl, mask; + + /* APB and application clocks are required */ + if (!ahci_platform_find_clk(hpriv, "pclk") || + !ahci_platform_find_clk(hpriv, "aclk")) { + dev_err(&dpriv->pdev->dev, "No system clocks specified\n"); + return -EINVAL; + } + + /* + * We need to select the PHY reference clock source. The signal + * can be delivered either from the chip pads or from the internal + * PLL. The source is selected by the PHY's ref_use_pad signal + * tied up into one of the CCU SATA ref-ctl register field. + */ + sys_regs = syscon_regmap_lookup_by_phandle(dpriv->pdev->dev.of_node, "syscon"); + if (IS_ERR(sys_regs)) { + dev_err(&dpriv->pdev->dev, "CCU syscon couldn't be found\n"); + return PTR_ERR(sys_regs); + } + + (void)regmap_read(sys_regs, BT1_CCU_SYS_SATA_REF, &ref_ctl); + + /* + * Prefer activating external reference clock if one is supplied. + * If there is no external ref clock, then we have no choice but + * to fall back to the internal signal coming from PLL. Alas + * we haven't managed to make the interface working well when it's + * used so far, but in no alternative let's at least try... + */ + if (ahci_platform_find_clk(hpriv, "ref_ext")) { + ref_ctl |= BT1_CCU_SYS_SATA_REF_EXT; + mask = BT1_CCU_SYS_SATA_REF_EXT; + } else if (ahci_platform_find_clk(hpriv, "ref_int")) { + ref_ctl &= ~BT1_CCU_SYS_SATA_REF_EXT; + ref_ctl |= BT1_CCU_SYS_SATA_REF_INV | BT1_CCU_SYS_SATA_REF_BUF; + mask = BT1_CCU_SYS_SATA_REF_EXT | + BT1_CCU_SYS_SATA_REF_INV | BT1_CCU_SYS_SATA_REF_BUF; + dev_warn(&dpriv->pdev->dev, "Fallback to PLL-based ref clock!\n"); + } else { + dev_err(&dpriv->pdev->dev, "No ref clock specified\n"); + return -EINVAL; + } + + regmap_update_bits(sys_regs, BT1_CCU_SYS_SATA_REF, mask, ref_ctl); + + /* + * Fully reset the SATA AXI and ref clocks domain so to ensure the + * state machine is working from scratch. + */ + ahci_platform_assert_rsts(hpriv); + return ahci_platform_deassert_rsts(hpriv); +} + static struct ahci_host_priv *dwc_ahci_get_resources(struct platform_device *pdev) { struct dwc_ahci_host_priv *dpriv; @@ -415,9 +495,15 @@ struct dwc_ahci_plat_data dwc_ahci_plat = { .pflags = AHCI_PLATFORM_GET_RESETS, }; +struct dwc_ahci_plat_data bt1_ahci_plat = { + .pflags = AHCI_PLATFORM_GET_RESETS | AHCI_PLATFORM_RST_TRIGGER, + .init = bt1_ahci_init, +}; + static const struct of_device_id dwc_ahci_of_match[] = { { .compatible = "snps,dwc-ahci", &dwc_ahci_plat }, { .compatible = "snps,spear-ahci", &dwc_ahci_plat }, + { .compatible = "baikal,bt1-ahci", &bt1_ahci_plat }, {}, }; MODULE_DEVICE_TABLE(of, dwc_ahci_of_match); -- 2.35.1