From patchwork Fri Jul 10 08:38:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sagar Shrikant Kadam X-Patchwork-Id: 1326553 X-Patchwork-Delegate: uboot@andestech.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=sifive.com header.i=@sifive.com header.a=rsa-sha256 header.s=selector1 header.b=GoYe+na9; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4B360q0WH4z9sRK for ; Fri, 10 Jul 2020 18:39:38 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 38E9E81F7C; Fri, 10 Jul 2020 10:39:19 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=sifive.com header.i=@sifive.com header.b="GoYe+na9"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 6AF0E81F3B; Fri, 10 Jul 2020 10:38:58 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FORGED_SPF_HELO,MSGID_FROM_MTA_HEADER, SPF_HELO_PASS,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from NAM02-BL2-obe.outbound.protection.outlook.com (mail-bl2nam02on0601.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe46::601]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id F10DC81F42 for ; Fri, 10 Jul 2020 10:38:53 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sagar.kadam@sifive.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=n4qOAT6WBU4rM0IP7xwcOSy0xPylwUHzZB7cXZB6KeGXTulAC8H3jqIpPEblyt8yCeuiG2ecKdRXYQyaNlY616x2BrSF6iwASgx/tCJej0FI/vHeCZXV7z6hjn5zUo4lqzRjccPo6phBDr+MbeQsP4D2m3KcahdAvrMMl3Qqxjk961N+hBQHVBE3R13TCcRmQLe9Jlh3SVqUJTdJ5meYWkDpDUj1CHKYuuCy0/oZUo25osarw3wVJdGgNnzh6M2GselNUBSmSJJ8rq8Wd3UUn+qLQLt4erOef+U5u7mjpfpuKYLwRcVR55wyuJOIcFuMcVx5swF1n1UkdkScvKOARw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=gFaLwyKjzjWR1a0K0lV164wgBI2JfR6GQlqJJL6K6EU=; b=Fnb5L0XcqPXG3Qo2A92Xs3NRXrVf1AkRu0FYvFdimPAsXRGdPpNBIsLIvu4UfBh53yayfyjpjVbYTUd37NXQMIrc4RG7Kic0GqADr2ZtmswS9owWn4g1vK6e6i/hN/FW/HUZirc/f1L3A1/zCCBjUupvxB1b72YEoH/iwNRSIIg8KUYo/4mEbrkc4JCQ0mUABenlf6/DPdvLY34KsbNttue4HobKeb35P4Lp5M3NCkdk5shW1MXfPS2Tfp88jfx+yuyU027kRPHDUNrooee20+c+kRAQAJtkPUqOOvfN6E3lrGwsOFuAKXt1D40PDySxmHdUfLCjc5EKMouSZaVo+A== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=sifive.com; dmarc=pass action=none header.from=sifive.com; dkim=pass header.d=sifive.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=gFaLwyKjzjWR1a0K0lV164wgBI2JfR6GQlqJJL6K6EU=; b=GoYe+na91BlsyNPx7n/4ZNnQm8RqTf4hJa1vYhFKHN+Csdy+So/9zXA3og5shvRfQRCDVlbRkdsoZh6nFvWi9+fhmlxRDdxn3Nt79assmkWQbaiLxCnM6ET5DtLjZWAwKrbKkUNAhq/fXTE0ZLO1hS+MyU4UGLka/ZMzsz6zD44= Authentication-Results: lists.denx.de; dkim=none (message not signed) header.d=none;lists.denx.de; dmarc=none action=none header.from=sifive.com; Received: from BN8PR13MB2611.namprd13.prod.outlook.com (2603:10b6:408:81::17) by BN6PR13MB3268.namprd13.prod.outlook.com (2603:10b6:405:83::39) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3195.11; Fri, 10 Jul 2020 08:38:52 +0000 Received: from BN8PR13MB2611.namprd13.prod.outlook.com ([fe80::c1d9:f4ee:80ab:de83]) by BN8PR13MB2611.namprd13.prod.outlook.com ([fe80::c1d9:f4ee:80ab:de83%6]) with mapi id 15.20.3174.023; Fri, 10 Jul 2020 08:38:52 +0000 From: Sagar Shrikant Kadam To: u-boot@lists.denx.de Cc: rick@andestech.com, paul.walmsley@sifive.com, palmer@dabbelt.com, anup.patel@wdc.com, atish.patra@wdc.com, lukma@denx.de, pragnesh.patel@sifive.com, bin.meng@windriver.com, jagan@amarulasolutions.com, sjg@chromium.org, twoerner@gmail.com, abrodkin@synopsys.com, Eugeniy.Paltsev@synopsys.com, patrick@blueri.se, weijie.gao@mediatek.com, festevam@gmail.com, Sagar Shrikant Kadam Subject: [PATCH v3 4/5] sifive: reset: add DM based reset driver for SiFive SoC's Date: Fri, 10 Jul 2020 01:38:27 -0700 Message-Id: <1594370308-30957-5-git-send-email-sagar.kadam@sifive.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1594370308-30957-1-git-send-email-sagar.kadam@sifive.com> References: <1594370308-30957-1-git-send-email-sagar.kadam@sifive.com> X-ClientProxiedBy: BYAPR04CA0011.namprd04.prod.outlook.com (2603:10b6:a03:40::24) To BN8PR13MB2611.namprd13.prod.outlook.com (2603:10b6:408:81::17) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from gamma07.internal.sifive.com (64.62.193.194) by BYAPR04CA0011.namprd04.prod.outlook.com (2603:10b6:a03:40::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.20.3174.20 via Frontend Transport; Fri, 10 Jul 2020 08:38:51 +0000 X-Mailer: git-send-email 2.7.4 X-Originating-IP: [64.62.193.194] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: e143dbdd-21b6-4468-9fa2-08d824acaca3 X-MS-TrafficTypeDiagnostic: BN6PR13MB3268: X-LD-Processed: 22f88e9d-ae0d-4ed9-b984-cdc9be1529f1,ExtAddr X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:345; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: S01bqIF4Qp7is9h4KRLBllEBotfB3+VwYdVURVrs2b5V3iUlA7IOqPGeBniqauV/BT5eHS3TxEta3Z5KbMsAT1zUFZHumhdQG1Ha4cRGrAn49FwMRE3taMIUt62O4mQCEaKQ1qhvAYCMPwudfQsCqnC2cAmo9A8BOmUqpgFwkmwMluUkyF17EzWdH2tp0I/RPaF3SJun3G/EWa1fRbWbwf9MHJO0AlzJe3nvEteQ2IcpcVY9iQeG15gH6DDMsBfQ7z8//KRb6U8FQiq9B/mYGr8Mh7Dtdbrt8esPrtxnjhEAHghN7ZpFUBaO3DpajR9w4qsb7lvNcC+BO6WX0AmUgg== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BN8PR13MB2611.namprd13.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(6029001)(376002)(39850400004)(136003)(396003)(366004)(346002)(478600001)(66946007)(2906002)(52116002)(7696005)(66476007)(66556008)(6486002)(4326008)(16526019)(186003)(2616005)(956004)(86362001)(5660300002)(316002)(107886003)(6666004)(26005)(7416002)(8936002)(8676002)(6916009)(36756003)(83380400001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: OBriyM6oFSaI6j9KmvB7FElpO3dM8A8FAochu4U//kHgdBHGdgJxJx15iiWsARjhfdpmYuDMWWJ8fpsfzeqTvRA8ONF7ndr5DSI3C1P3TvS/0s2/FHfgC1ruXQPWI0jrAkz0Kmo1F3S9b2GIcyHB4dVf1klBEYl984XKvAW8QxnbAhSZPUrtETHRNuue54OJkj2sKAviXYJ3yfV/etNp1mzE9nKDXCBZ3oYKmvx/EnQ3tVlBtdKvCc7cZnVD0ysVsWgVnjsbB9juXx+p1HnMhuGqf/oiD+kgOPPtVMdpwTgYbPtvezEcF1NF856GR0Nl7+SdKIoUtXVEC2agynXVeiIvNPsme+jmaRkijbIS+QrqFhzbi3ishtpcbFsCwl9SH9aydVVA7D4FHy27yqYcatRDFbU0pgLGhgknBcXtx8qB/0TGeMa3vTg6lQfmNMA0Apc06RjnCaQ9WNhbdryRr48dG8ih05rcmafDX70NGcc= X-OriginatorOrg: sifive.com X-MS-Exchange-CrossTenant-Network-Message-Id: e143dbdd-21b6-4468-9fa2-08d824acaca3 X-MS-Exchange-CrossTenant-AuthSource: BN8PR13MB2611.namprd13.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Jul 2020 08:38:52.4173 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 22f88e9d-ae0d-4ed9-b984-cdc9be1529f1 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: N2nRRYMaxRQGgxHde/hY8U1Te5NQtVKdZGJBHnh3hisqJRS25pMcgGPYhJmc0O77M1JZCd7fvyAJzRa7yK3DBg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR13MB3268 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean PRCI module within SiFive SoC's has register with which we can reset the sub-systems within the SoC. The resets to DDR and ethernet sub systems within FU540-C000 SoC are active low, and are hold low by default on power-up. Currently these are directly asserted within prci driver via register read/write. With the DM based reset driver support here, we bind the reset driver with clock (prci) driver and assert the reset signals of both sub-system's appropriately. Signed-off-by: Sagar Shrikant Kadam Reviewed-by: Pragnesh Patel Reviewed-by: Bin Meng Tested-by: Bin Meng --- arch/riscv/include/asm/arch-fu540/reset.h | 13 ++++ drivers/clk/sifive/fu540-prci.c | 73 ++++++++++++++---- drivers/reset/reset-sifive.c | 118 ++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 15 deletions(-) create mode 100644 arch/riscv/include/asm/arch-fu540/reset.h create mode 100644 drivers/reset/reset-sifive.c diff --git a/arch/riscv/include/asm/arch-fu540/reset.h b/arch/riscv/include/asm/arch-fu540/reset.h new file mode 100644 index 0000000..e42797a --- /dev/null +++ b/arch/riscv/include/asm/arch-fu540/reset.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2020 SiFive, Inc. + * + * Author: Sagar Kadam + */ + +#ifndef __RESET_SIFIVE_H +#define __RESET_SIFIVE_H + +int sifive_reset_bind(struct udevice *dev, ulong count); + +#endif diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c index 00c31fc..c5148e9 100644 --- a/drivers/clk/sifive/fu540-prci.c +++ b/drivers/clk/sifive/fu540-prci.c @@ -30,11 +30,15 @@ #include #include +#include #include #include #include #include #include +#include +#include +#include #include #include @@ -132,6 +136,7 @@ /* DEVICESRESETREG */ #define PRCI_DEVICESRESETREG_OFFSET 0x28 +#define PRCI_DEVICERESETCNT 5 #define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK \ (0x1 << PRCI_RST_DDR_CTRL_N) @@ -525,6 +530,41 @@ static const struct __prci_clock_ops sifive_fu540_prci_tlclksel_clk_ops = { .recalc_rate = sifive_fu540_prci_tlclksel_recalc_rate, }; +static int __prci_consumer_reset(const char *rst_name, bool trigger) +{ + struct udevice *dev; + struct reset_ctl rst_sig; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_RESET, + DM_GET_DRIVER(sifive_reset), + &dev); + if (ret) { + dev_err(dev, "Reset driver not found: %d\n", ret); + return ret; + } + + ret = reset_get_by_name(dev, rst_name, &rst_sig); + if (ret) { + dev_err(dev, "failed to get %s reset\n", rst_name); + return ret; + } + + if (reset_valid(&rst_sig)) { + if (trigger) + ret = reset_deassert(&rst_sig); + else + ret = reset_assert(&rst_sig); + if (ret) { + dev_err(dev, "failed to trigger reset id = %ld\n", + rst_sig.id); + return ret; + } + } + + return ret; +} + /** * __prci_ddr_release_reset() - Release DDR reset * @pd: struct __prci_data * for the PRCI containing the DDRCLK mux reg @@ -532,19 +572,20 @@ static const struct __prci_clock_ops sifive_fu540_prci_tlclksel_clk_ops = { */ static void __prci_ddr_release_reset(struct __prci_data *pd) { - u32 v; - - v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET); - v |= PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK; - __prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd); + /* Release DDR ctrl reset */ + __prci_consumer_reset("ddr_ctrl", true); /* HACK to get the '1 full controller clock cycle'. */ asm volatile ("fence"); - v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET); - v |= (PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK | - PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK | - PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK); - __prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd); + + /* Release DDR AXI reset */ + __prci_consumer_reset("ddr_axi", true); + + /* Release DDR AHB reset */ + __prci_consumer_reset("ddr_ahb", true); + + /* Release DDR PHY reset */ + __prci_consumer_reset("ddr_phy", true); /* HACK to get the '1 full controller clock cycle'. */ asm volatile ("fence"); @@ -564,12 +605,8 @@ static void __prci_ddr_release_reset(struct __prci_data *pd) */ static void __prci_ethernet_release_reset(struct __prci_data *pd) { - u32 v; - /* Release GEMGXL reset */ - v = __prci_readl(pd, PRCI_DEVICESRESETREG_OFFSET); - v |= PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK; - __prci_writel(v, PRCI_DEVICESRESETREG_OFFSET, pd); + __prci_consumer_reset("gemgxl_reset", true); /* Procmon => core clock */ __prci_writel(PRCI_PROCMONCFG_CORE_CLOCK_MASK, PRCI_PROCMONCFG_OFFSET, @@ -754,6 +791,11 @@ static struct clk_ops sifive_fu540_prci_ops = { .disable = sifive_fu540_prci_disable, }; +static int sifive_fu540_clk_bind(struct udevice *dev) +{ + return sifive_reset_bind(dev, PRCI_DEVICERESETCNT); +} + static const struct udevice_id sifive_fu540_prci_ids[] = { { .compatible = "sifive,fu540-c000-prci" }, { } @@ -766,4 +808,5 @@ U_BOOT_DRIVER(sifive_fu540_prci) = { .probe = sifive_fu540_prci_probe, .ops = &sifive_fu540_prci_ops, .priv_auto_alloc_size = sizeof(struct __prci_data), + .bind = sifive_fu540_clk_bind, }; diff --git a/drivers/reset/reset-sifive.c b/drivers/reset/reset-sifive.c new file mode 100644 index 0000000..527757f --- /dev/null +++ b/drivers/reset/reset-sifive.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Sifive, Inc. + * Author: Sagar Kadam + */ + +#include +#include +#include +#include +#include +#include +#include + +#define PRCI_RESETREG_OFFSET 0x28 + +struct sifive_reset_priv { + void *base; + /* number of reset signals */ + int nr_reset; +}; + +static int sifive_rst_trigger(struct reset_ctl *rst, bool level) +{ + struct sifive_reset_priv *priv = dev_get_priv(rst->dev); + int id = rst->id; + int regval = readl(priv->base + PRCI_RESETREG_OFFSET); + + /* Derive bitposition from rst id */ + if (level) + /* Reset deassert */ + regval |= BIT(id); + else + /* Reset assert */ + regval &= ~BIT(id); + + writel(regval, priv->base + PRCI_RESETREG_OFFSET); + + return 0; +} + +static int sifive_reset_assert(struct reset_ctl *rst) +{ + return sifive_rst_trigger(rst, false); +} + +static int sifive_reset_deassert(struct reset_ctl *rst) +{ + return sifive_rst_trigger(rst, true); +} + +static int sifive_reset_request(struct reset_ctl *rst) +{ + struct sifive_reset_priv *priv = dev_get_priv(rst->dev); + + debug("%s(rst=%p) (dev=%p, id=%lu) (nr_reset=%d)\n", __func__, + rst, rst->dev, rst->id, priv->nr_reset); + + if (rst->id > priv->nr_reset) + return -EINVAL; + + return 0; +} + +static int sifive_reset_free(struct reset_ctl *rst) +{ + struct sifive_reset_priv *priv = dev_get_priv(rst->dev); + + debug("%s(rst=%p) (dev=%p, id=%lu) (nr_reset=%d)\n", __func__, + rst, rst->dev, rst->id, priv->nr_reset); + + return 0; +} + +static int sifive_reset_probe(struct udevice *dev) +{ + struct sifive_reset_priv *priv = dev_get_priv(dev); + + priv->base = dev_remap_addr(dev); + if (!priv->base) + return -ENOMEM; + + return 0; +} + +int sifive_reset_bind(struct udevice *dev, ulong count) +{ + struct udevice *rst_dev; + struct sifive_reset_priv *priv; + int ret; + + ret = device_bind_driver_to_node(dev, "sifive-reset", "reset", + dev_ofnode(dev), &rst_dev); + if (ret) { + dev_err(dev, "failed to bind sifive_reset driver (ret=%d)\n", ret); + return ret; + } + priv = malloc(sizeof(struct sifive_reset_priv)); + priv->nr_reset = count; + rst_dev->priv = priv; + + return 0; +} + +const struct reset_ops sifive_reset_ops = { + .request = sifive_reset_request, + .rfree = sifive_reset_free, + .rst_assert = sifive_reset_assert, + .rst_deassert = sifive_reset_deassert, +}; + +U_BOOT_DRIVER(sifive_reset) = { + .name = "sifive-reset", + .id = UCLASS_RESET, + .ops = &sifive_reset_ops, + .probe = sifive_reset_probe, + .priv_auto_alloc_size = sizeof(struct sifive_reset_priv), +};