hifiveu: add FU740 support via backporting kernel patches from SDK
authorZoltan HERPAI <[email protected]>
Mon, 1 Nov 2021 23:51:05 +0000 (00:51 +0100)
committerZoltan HERPAI <[email protected]>
Mon, 1 Nov 2021 23:58:03 +0000 (00:58 +0100)
Signed-off-by: Zoltan HERPAI <[email protected]>
25 files changed:
target/linux/hifiveu/patches-5.10/0001-clk_sifive_add_driver_for_Sifive_FU740.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0002-improve-kernel-section-protections.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0004-riscv-dts-add-initial-support-for-the-SiFive-FU740-C.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0006-riscv-dts-add-initial-board-data-for-the-SiFive-HiFi.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0008-RISC-V-sifive_l2_cache-Update-L2-cache-driver-to-sup.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0009-riscv-dts-fu740-fix-cache-controller-interrupts.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0010-riscv-sifive-fu740-cpu-1-2-3-4-set-compatible-to-sif.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0011-riscv-sifive-unmatched-update-for-16GB-rev3.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0012-riscv-Add-3-SBI-wrapper-functions-to-get-cpu-manufac.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0013-riscv-Introduce-alternative-mechanism-to-apply-errat.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0014-riscv-sifive-Add-SiFive-alternative-ports.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0015-riscv-sifive-Apply-errata-cip-453-patch.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0016-riscv-sifive-Apply-errata-cip-1200-patch.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0017-clk-sifive-Add-pcie_aux-clock-in-prci-driver-for-PCI.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0018-clk-sifive-Use-reset-simple-in-prci-driver-for-PCIe-.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0021-PCI-fu740-Add-SiFive-FU740-PCIe-host-controller-driv.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0022-riscv-dts-Add-PCIe-support-for-the-SiFive-FU740-C000.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0023-riscv-sifive-unmatched-add-D12-PWM-LED.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0024-riscv-sifive-unmatched-add-gpio-poweroff-node.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0025-riscv-sifive-unmatched-add-D2-RGB-LED.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0026-riscv-sifive-unmatched-remove-A00-from-model.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0027-riscv-sifive-unmatched-define-LEDs-color.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0028-riscv-enable-generic-PCI-resource-mapping.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0104-SiFive-Unleashed-CPUFreq.patch [new file with mode: 0644]
target/linux/hifiveu/patches-5.10/0107-Add-PWM-LEDs-D1-D2-D3-D4.patch [new file with mode: 0644]

diff --git a/target/linux/hifiveu/patches-5.10/0001-clk_sifive_add_driver_for_Sifive_FU740.patch b/target/linux/hifiveu/patches-5.10/0001-clk_sifive_add_driver_for_Sifive_FU740.patch
new file mode 100644 (file)
index 0000000..206e50f
--- /dev/null
@@ -0,0 +1,2556 @@
+From patchwork Wed Nov 11 10:06:05 2020
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Zong Li <[email protected]>
+X-Patchwork-Id: 11898191
+Return-Path: 
+ <SRS0=XU8h=ER=lists.infradead.org=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@kernel.org>
+Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
+ [172.30.200.123])
+       by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 65B0A1391
+       for <[email protected]>;
+ Wed, 11 Nov 2020 16:47:21 +0000 (UTC)
+Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])
+       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+       (No client certificate requested)
+       by mail.kernel.org (Postfix) with ESMTPS id D7F48206FB
+       for <[email protected]>;
+ Wed, 11 Nov 2020 16:47:20 +0000 (UTC)
+Authentication-Results: mail.kernel.org;
+       dkim=pass (2048-bit key) header.d=lists.infradead.org
[email protected] header.b="Y/a4oqWE";
+       dkim=fail reason="signature verification failed" (2048-bit key)
+ header.d=sifive.com [email protected] header.b="AFj9tIwI"
+DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D7F48206FB
+Authentication-Results: mail.kernel.org;
+ dmarc=none (p=none dis=none) header.from=sifive.com
+Authentication-Results: mail.kernel.org;
+ spf=none
+ smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+       d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding:
+       Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
+       List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:
+       Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:
+       Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner;
+        bh=mXnSFZXMGisE2lDMkTUOOvUC/Kyr45NVjphI8tYXLzM=; b=Y/a4oqWEq/yUVKeLqi8reTYUM
+       EAsnXe1PUAgkUYK5Q0sp5Cc/cOtbLCZn0W6+B4kmJdYiIejGvc9Iz+1prVXtBw9AQYtamNp+Gtwjn
+       rnDLa1TL9UxJr8Tc2kACZNvkN7OLbuMTucdaKmudxS9LPgBDHZpUR58P2ptp83fr48x/FQbn1XoOz
+       xdFGekeIxgN7crqG2MkDZz5TqJWLNqY2za551mzNTN4rc9wMFWg4SEMx4CqPmLmwWsxwTWWb9BLhi
+       W6p6id/YvHglypggoP8zRIBWKPUly1eJVTFL67ODGaTtcFlrUSSpw8yHacwPpzU8nsAw7U/uh6xym
+       gTi/XcNmA==;
+Received: from localhost ([::1] helo=merlin.infradead.org)
+       by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
+       id 1kctGq-0000D2-PT; Wed, 11 Nov 2020 16:46:56 +0000
+Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542])
+ by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
+ id 1kcn18-0001JE-Vr
+ for [email protected]; Wed, 11 Nov 2020 10:06:22 +0000
+Received: by mail-pg1-x542.google.com with SMTP id f18so1134899pgi.8
+ for <[email protected]>; Wed, 11 Nov 2020 02:06:18 -0800 (PST)
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google;
+ h=from:to:cc:subject:date:message-id:in-reply-to:references
+ :mime-version:content-transfer-encoding;
+ bh=jL0tNU5hYFb7CUkP07ONQLx8L/T/xIAB3EAjS9DXImE=;
+ b=AFj9tIwIOmVUroqhyJd02VjhXIiSoSRxNL4OpbvnCjJRF/0vbs5I0JSaeJ7WvkBzZR
+ 3G0jDsBWbRX0zskB8JJEpepnElnvxLhfE+pPLf1pM/kucT9jYG6DyDZV/NtLl6ByppdO
+ NATEr+3GJISSuZ9myc7i3mpPkaIXOilTRYG46fcp17hbEbVyto+AD0WlByCSxxKbrr7Q
+ 4Yd2Ot3N7zyUVG+CaiTRFEgbgo8jMOyWS+mCGSgxtEsvyukg4v32KryY0kAaR9q/qBFw
+ He9p9S43OPStloEwi6JoxNu3o/5K1zw6c8mdTkD+17fTTABpUhm+MI94D0C/cVyHBQNa
+ V+Tw==
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+ d=1e100.net; s=20161025;
+ h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
+ :references:mime-version:content-transfer-encoding;
+ bh=jL0tNU5hYFb7CUkP07ONQLx8L/T/xIAB3EAjS9DXImE=;
+ b=IyojVq+ov6yc6UGaulkTn2AtRqjerTeTbLN3m/6yzbf1SbhNaFU5VMCgxxGhspnpoy
+ OUM84DRBMPX16h7/y1E1c3gylb7UNx7qdzG5AA/GzFghmsikTJKqTNifC+gvvfnkJJFO
+ LIx5nc+fQSXV6wQ2ppy8mfjZS2p/4vc2gGsebpj/8QKz6jkw8Dhd1QxNPGhu+W23kFla
+ /bYoBC6B/fIcetWBt7Bhwe5FQ/erh7ULiSQlObnkWKiZbR2HFKUJ7VQQckBBcLGrUjDg
+ aa3bDJnCR9DHvQwYs0I0KmPJG67TG9YvOgWyTkEGi0A+aa/wPSg4lF388+CpnYNK6azG
+ TdkQ==
+X-Gm-Message-State: AOAM530Uxpk8eMOmjXxbBdooCEyI6LvqPd7SKQ0MNdvLz+ubFKdGuSGA
+ x3rqGyCiTIqVI7qErEKZpQhV71fxtBcaYQ==
+X-Google-Smtp-Source: 
+ ABdhPJzR6NhJ3vRp8GB36lz7N/OocbSO0kByZ0JnlUQayrXj7eA5KOHRgUv//OPPs35/ef72XIjb0A==
+X-Received: by 2002:a63:e612:: with SMTP id
+ g18mr20277608pgh.388.1605089176158;
+ Wed, 11 Nov 2020 02:06:16 -0800 (PST)
+Received: from hsinchu02.internal.sifive.com
+ (114-34-229-221.HINET-IP.hinet.net. [114.34.229.221])
+ by smtp.gmail.com with ESMTPSA id u22sm1872801pgf.24.2020.11.11.02.06.13
+ (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
+ Wed, 11 Nov 2020 02:06:15 -0800 (PST)
+From: Zong Li <[email protected]>
+Subject: [PATCH v4 1/4] clk: sifive: Extract prci core to common base
+Date: Wed, 11 Nov 2020 18:06:05 +0800
+Message-Id: <[email protected]>
+X-Mailer: git-send-email 2.29.2
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+MIME-Version: 1.0
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
+X-CRM114-CacheID: sfid-20201111_050619_330980_6A671390 
+X-CRM114-Status: GOOD (  27.34  )
+X-Spam-Score: -0.2 (/)
+X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary:
+ Content analysis details:   (-0.2 points)
+ pts rule name              description
+ ---- ----------------------
+ --------------------------------------------------
+ -0.0 RCVD_IN_DNSWL_NONE     RBL: Sender listed at https://www.dnswl.org/,
+ no trust [2607:f8b0:4864:20:0:0:0:542 listed in]
+ [list.dnswl.org]
+ -0.0 SPF_PASS               SPF: sender matches SPF record
+ 0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record
+ 0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
+ not necessarily
+ valid
+ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
+ -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from
+ author's domain
+ -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from
+ envelope-from domain
+X-Mailman-Approved-At: Wed, 11 Nov 2020 11:46:52 -0500
+X-BeenThere: [email protected]
+X-Mailman-Version: 2.1.29
+Precedence: list
+List-Id: <linux-riscv.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-riscv>,
+ <mailto:[email protected]?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-riscv/>
+List-Post: <mailto:[email protected]>
+List-Help: <mailto:[email protected]?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-riscv>,
+ <mailto:[email protected]?subject=subscribe>
+Cc: Pragnesh Patel <[email protected]>, Zong Li <[email protected]>
+Sender: "linux-riscv" <[email protected]>
+Errors-To: 
+ linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+
+Extract common core of prci driver to an independent file, it could
+allow other chips to reuse it. Separate SoCs-dependent code 'fu540'
+from prci core, then we can easily add 'fu740' later.
+
+Almost these changes are code movement. The different is adding the
+private data for each SoC use, so it needs to get match data in probe
+callback function, then use the data for initialization.
+
+Signed-off-by: Zong Li <[email protected]>
+Reviewed-by: Pragnesh Patel <[email protected]>
+Acked-by: Palmer Dabbelt <[email protected]>
+---
+ drivers/clk/sifive/Makefile                   |   2 +
+ drivers/clk/sifive/fu540-prci.c               | 586 +-----------------
+ drivers/clk/sifive/fu540-prci.h               |  21 +
+ .../sifive/{fu540-prci.c => sifive-prci.c}    | 381 +++---------
+ drivers/clk/sifive/sifive-prci.h              | 201 ++++++
+ 5 files changed, 323 insertions(+), 868 deletions(-)
+ create mode 100644 drivers/clk/sifive/fu540-prci.h
+ copy drivers/clk/sifive/{fu540-prci.c => sifive-prci.c} (45%)
+ create mode 100644 drivers/clk/sifive/sifive-prci.h
+
+diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
+index 0797f14fef6b..627effe2ece1 100644
+--- a/drivers/clk/sifive/Makefile
++++ b/drivers/clk/sifive/Makefile
+@@ -1,2 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0-only
++obj-y += sifive-prci.o
++
+ obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI)   += fu540-prci.o
+diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
+index a8901f90a61a..840b97bfff85 100644
+--- a/drivers/clk/sifive/fu540-prci.c
++++ b/drivers/clk/sifive/fu540-prci.c
+@@ -3,6 +3,7 @@
+  * Copyright (C) 2018-2019 SiFive, Inc.
+  * Wesley Terpstra
+  * Paul Walmsley
++ * Zong Li
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+@@ -13,475 +14,48 @@
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+- * The FU540 PRCI implements clock and reset control for the SiFive
+- * FU540-C000 chip.  This driver assumes that it has sole control
+- * over all PRCI resources.
+- *
+- * This driver is based on the PRCI driver written by Wesley Terpstra:
+- * https://github.com/riscv/riscv-linux/commit/999529edf517ed75b56659d456d221b2ee56bb60
+- *
+  * References:
+  * - SiFive FU540-C000 manual v1p0, Chapter 7 "Clocking and Reset"
+  */
+ #include <dt-bindings/clock/sifive-fu540-prci.h>
+-#include <linux/clkdev.h>
+-#include <linux/clk-provider.h>
+-#include <linux/clk/analogbits-wrpll-cln28hpc.h>
+-#include <linux/delay.h>
+-#include <linux/err.h>
+-#include <linux/io.h>
+ #include <linux/module.h>
+-#include <linux/of.h>
+-#include <linux/of_clk.h>
+-#include <linux/platform_device.h>
+-#include <linux/slab.h>
+-
+-/*
+- * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
+- *     hfclk and rtcclk
+- */
+-#define EXPECTED_CLK_PARENT_COUNT             2
+-
+-/*
+- * Register offsets and bitmasks
+- */
+-
+-/* COREPLLCFG0 */
+-#define PRCI_COREPLLCFG0_OFFSET                       0x4
+-# define PRCI_COREPLLCFG0_DIVR_SHIFT          0
+-# define PRCI_COREPLLCFG0_DIVR_MASK           (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT)
+-# define PRCI_COREPLLCFG0_DIVF_SHIFT          6
+-# define PRCI_COREPLLCFG0_DIVF_MASK           (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT)
+-# define PRCI_COREPLLCFG0_DIVQ_SHIFT          15
+-# define PRCI_COREPLLCFG0_DIVQ_MASK           (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT)
+-# define PRCI_COREPLLCFG0_RANGE_SHIFT         18
+-# define PRCI_COREPLLCFG0_RANGE_MASK          (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT)
+-# define PRCI_COREPLLCFG0_BYPASS_SHIFT                24
+-# define PRCI_COREPLLCFG0_BYPASS_MASK         (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT)
+-# define PRCI_COREPLLCFG0_FSE_SHIFT           25
+-# define PRCI_COREPLLCFG0_FSE_MASK            (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT)
+-# define PRCI_COREPLLCFG0_LOCK_SHIFT          31
+-# define PRCI_COREPLLCFG0_LOCK_MASK           (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
+-
+-/* DDRPLLCFG0 */
+-#define PRCI_DDRPLLCFG0_OFFSET                        0xc
+-# define PRCI_DDRPLLCFG0_DIVR_SHIFT           0
+-# define PRCI_DDRPLLCFG0_DIVR_MASK            (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT)
+-# define PRCI_DDRPLLCFG0_DIVF_SHIFT           6
+-# define PRCI_DDRPLLCFG0_DIVF_MASK            (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT)
+-# define PRCI_DDRPLLCFG0_DIVQ_SHIFT           15
+-# define PRCI_DDRPLLCFG0_DIVQ_MASK            (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT)
+-# define PRCI_DDRPLLCFG0_RANGE_SHIFT          18
+-# define PRCI_DDRPLLCFG0_RANGE_MASK           (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT)
+-# define PRCI_DDRPLLCFG0_BYPASS_SHIFT         24
+-# define PRCI_DDRPLLCFG0_BYPASS_MASK          (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT)
+-# define PRCI_DDRPLLCFG0_FSE_SHIFT            25
+-# define PRCI_DDRPLLCFG0_FSE_MASK             (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT)
+-# define PRCI_DDRPLLCFG0_LOCK_SHIFT           31
+-# define PRCI_DDRPLLCFG0_LOCK_MASK            (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT)
++#include "sifive-prci.h"
+-/* DDRPLLCFG1 */
+-#define PRCI_DDRPLLCFG1_OFFSET                        0x10
+-# define PRCI_DDRPLLCFG1_CKE_SHIFT            24
+-# define PRCI_DDRPLLCFG1_CKE_MASK             (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
++/* PRCI integration data for each WRPLL instance */
+-/* GEMGXLPLLCFG0 */
+-#define PRCI_GEMGXLPLLCFG0_OFFSET             0x1c
+-# define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT                0
+-# define PRCI_GEMGXLPLLCFG0_DIVR_MASK         (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT                6
+-# define PRCI_GEMGXLPLLCFG0_DIVF_MASK         (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT                15
+-# define PRCI_GEMGXLPLLCFG0_DIVQ_MASK         (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT               18
+-# define PRCI_GEMGXLPLLCFG0_RANGE_MASK                (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT      24
+-# define PRCI_GEMGXLPLLCFG0_BYPASS_MASK               (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_FSE_SHIFT         25
+-# define PRCI_GEMGXLPLLCFG0_FSE_MASK          (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT                31
+-# define PRCI_GEMGXLPLLCFG0_LOCK_MASK         (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT)
+-
+-/* GEMGXLPLLCFG1 */
+-#define PRCI_GEMGXLPLLCFG1_OFFSET             0x20
+-# define PRCI_GEMGXLPLLCFG1_CKE_SHIFT         24
+-# define PRCI_GEMGXLPLLCFG1_CKE_MASK          (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
+-
+-/* CORECLKSEL */
+-#define PRCI_CORECLKSEL_OFFSET                        0x24
+-# define PRCI_CORECLKSEL_CORECLKSEL_SHIFT     0
+-# define PRCI_CORECLKSEL_CORECLKSEL_MASK      (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT)
+-
+-/* DEVICESRESETREG */
+-#define PRCI_DEVICESRESETREG_OFFSET                   0x28
+-# define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT    0
+-# define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK     (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT)
+-# define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT     1
+-# define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK      (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT)
+-# define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT     2
+-# define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK      (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT)
+-# define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT     3
+-# define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK      (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT)
+-# define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT      5
+-# define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK               (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
+-
+-/* CLKMUXSTATUSREG */
+-#define PRCI_CLKMUXSTATUSREG_OFFSET                   0x2c
+-# define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT   1
+-# define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK    (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
+-
+-/*
+- * Private structures
+- */
+-
+-/**
+- * struct __prci_data - per-device-instance data
+- * @va: base virtual address of the PRCI IP block
+- * @hw_clks: encapsulates struct clk_hw records
+- *
+- * PRCI per-device instance data
+- */
+-struct __prci_data {
+-      void __iomem *va;
+-      struct clk_hw_onecell_data hw_clks;
++static struct __prci_wrpll_data __prci_corepll_data = {
++      .cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
++      .enable_bypass = sifive_prci_coreclksel_use_hfclk,
++      .disable_bypass = sifive_prci_coreclksel_use_corepll,
+ };
+-/**
+- * struct __prci_wrpll_data - WRPLL configuration and integration data
+- * @c: WRPLL current configuration record
+- * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
+- * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
+- * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
+- *
+- * @enable_bypass and @disable_bypass are used for WRPLL instances
+- * that contain a separate external glitchless clock mux downstream
+- * from the PLL.  The WRPLL internal bypass mux is not glitchless.
+- */
+-struct __prci_wrpll_data {
+-      struct wrpll_cfg c;
+-      void (*enable_bypass)(struct __prci_data *pd);
+-      void (*disable_bypass)(struct __prci_data *pd);
+-      u8 cfg0_offs;
++static struct __prci_wrpll_data __prci_ddrpll_data = {
++      .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
+ };
+-/**
+- * struct __prci_clock - describes a clock device managed by PRCI
+- * @name: user-readable clock name string - should match the manual
+- * @parent_name: parent name for this clock
+- * @ops: struct clk_ops for the Linux clock framework to use for control
+- * @hw: Linux-private clock data
+- * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
+- * @pd: PRCI-specific data associated with this clock (if not NULL)
+- *
+- * PRCI clock data.  Used by the PRCI driver to register PRCI-provided
+- * clocks to the Linux clock infrastructure.
+- */
+-struct __prci_clock {
+-      const char *name;
+-      const char *parent_name;
+-      const struct clk_ops *ops;
+-      struct clk_hw hw;
+-      struct __prci_wrpll_data *pwd;
+-      struct __prci_data *pd;
++static struct __prci_wrpll_data __prci_gemgxlpll_data = {
++      .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+ };
+-#define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw)
+-
+-/*
+- * Private functions
+- */
+-
+-/**
+- * __prci_readl() - read from a PRCI register
+- * @pd: PRCI context
+- * @offs: register offset to read from (in bytes, from PRCI base address)
+- *
+- * Read the register located at offset @offs from the base virtual
+- * address of the PRCI register target described by @pd, and return
+- * the value to the caller.
+- *
+- * Context: Any context.
+- *
+- * Return: the contents of the register described by @pd and @offs.
+- */
+-static u32 __prci_readl(struct __prci_data *pd, u32 offs)
+-{
+-      return readl_relaxed(pd->va + offs);
+-}
+-
+-static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd)
+-{
+-      writel_relaxed(v, pd->va + offs);
+-}
+-
+-/* WRPLL-related private functions */
+-
+-/**
+- * __prci_wrpll_unpack() - unpack WRPLL configuration registers into parameters
+- * @c: ptr to a struct wrpll_cfg record to write config into
+- * @r: value read from the PRCI PLL configuration register
+- *
+- * Given a value @r read from an FU540 PRCI PLL configuration register,
+- * split it into fields and populate it into the WRPLL configuration record
+- * pointed to by @c.
+- *
+- * The COREPLLCFG0 macros are used below, but the other *PLLCFG0 macros
+- * have the same register layout.
+- *
+- * Context: Any context.
+- */
+-static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r)
+-{
+-      u32 v;
+-
+-      v = r & PRCI_COREPLLCFG0_DIVR_MASK;
+-      v >>= PRCI_COREPLLCFG0_DIVR_SHIFT;
+-      c->divr = v;
+-
+-      v = r & PRCI_COREPLLCFG0_DIVF_MASK;
+-      v >>= PRCI_COREPLLCFG0_DIVF_SHIFT;
+-      c->divf = v;
+-
+-      v = r & PRCI_COREPLLCFG0_DIVQ_MASK;
+-      v >>= PRCI_COREPLLCFG0_DIVQ_SHIFT;
+-      c->divq = v;
+-
+-      v = r & PRCI_COREPLLCFG0_RANGE_MASK;
+-      v >>= PRCI_COREPLLCFG0_RANGE_SHIFT;
+-      c->range = v;
+-
+-      c->flags &= (WRPLL_FLAGS_INT_FEEDBACK_MASK |
+-                   WRPLL_FLAGS_EXT_FEEDBACK_MASK);
+-
+-      /* external feedback mode not supported */
+-      c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK;
+-}
+-
+-/**
+- * __prci_wrpll_pack() - pack PLL configuration parameters into a register value
+- * @c: pointer to a struct wrpll_cfg record containing the PLL's cfg
+- *
+- * Using a set of WRPLL configuration values pointed to by @c,
+- * assemble a PRCI PLL configuration register value, and return it to
+- * the caller.
+- *
+- * Context: Any context.  Caller must ensure that the contents of the
+- *          record pointed to by @c do not change during the execution
+- *          of this function.
+- *
+- * Returns: a value suitable for writing into a PRCI PLL configuration
+- *          register
+- */
+-static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
+-{
+-      u32 r = 0;
+-
+-      r |= c->divr << PRCI_COREPLLCFG0_DIVR_SHIFT;
+-      r |= c->divf << PRCI_COREPLLCFG0_DIVF_SHIFT;
+-      r |= c->divq << PRCI_COREPLLCFG0_DIVQ_SHIFT;
+-      r |= c->range << PRCI_COREPLLCFG0_RANGE_SHIFT;
+-
+-      /* external feedback mode not supported */
+-      r |= PRCI_COREPLLCFG0_FSE_MASK;
+-
+-      return r;
+-}
+-
+-/**
+- * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI
+- * @pd: PRCI context
+- * @pwd: PRCI WRPLL metadata
+- *
+- * Read the current configuration of the PLL identified by @pwd from
+- * the PRCI identified by @pd, and store it into the local configuration
+- * cache in @pwd.
+- *
+- * Context: Any context.  Caller must prevent the records pointed to by
+- *          @pd and @pwd from changing during execution.
+- */
+-static void __prci_wrpll_read_cfg(struct __prci_data *pd,
+-                                struct __prci_wrpll_data *pwd)
+-{
+-      __prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs));
+-}
+-
+-/**
+- * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI
+- * @pd: PRCI context
+- * @pwd: PRCI WRPLL metadata
+- * @c: WRPLL configuration record to write
+- *
+- * Write the WRPLL configuration described by @c into the WRPLL
+- * configuration register identified by @pwd in the PRCI instance
+- * described by @c.  Make a cached copy of the WRPLL's current
+- * configuration so it can be used by other code.
+- *
+- * Context: Any context.  Caller must prevent the records pointed to by
+- *          @pd and @pwd from changing during execution.
+- */
+-static void __prci_wrpll_write_cfg(struct __prci_data *pd,
+-                                 struct __prci_wrpll_data *pwd,
+-                                 struct wrpll_cfg *c)
+-{
+-      __prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd);
+-
+-      memcpy(&pwd->c, c, sizeof(*c));
+-}
+-
+-/* Core clock mux control */
+-
+-/**
+- * __prci_coreclksel_use_hfclk() - switch the CORECLK mux to output HFCLK
+- * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
+- *
+- * Switch the CORECLK mux to the HFCLK input source; return once complete.
+- *
+- * Context: Any context.  Caller must prevent concurrent changes to the
+- *          PRCI_CORECLKSEL_OFFSET register.
+- */
+-static void __prci_coreclksel_use_hfclk(struct __prci_data *pd)
+-{
+-      u32 r;
+-
+-      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
+-      r |= PRCI_CORECLKSEL_CORECLKSEL_MASK;
+-      __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
+-
+-      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
+-}
+-
+-/**
+- * __prci_coreclksel_use_corepll() - switch the CORECLK mux to output COREPLL
+- * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
+- *
+- * Switch the CORECLK mux to the PLL output clock; return once complete.
+- *
+- * Context: Any context.  Caller must prevent concurrent changes to the
+- *          PRCI_CORECLKSEL_OFFSET register.
+- */
+-static void __prci_coreclksel_use_corepll(struct __prci_data *pd)
+-{
+-      u32 r;
+-
+-      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
+-      r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK;
+-      __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
+-
+-      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
+-}
+-
+-/*
+- * Linux clock framework integration
+- *
+- * See the Linux clock framework documentation for more information on
+- * these functions.
+- */
+-
+-static unsigned long sifive_fu540_prci_wrpll_recalc_rate(struct clk_hw *hw,
+-                                                       unsigned long parent_rate)
+-{
+-      struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+-      struct __prci_wrpll_data *pwd = pc->pwd;
+-
+-      return wrpll_calc_output_rate(&pwd->c, parent_rate);
+-}
+-
+-static long sifive_fu540_prci_wrpll_round_rate(struct clk_hw *hw,
+-                                             unsigned long rate,
+-                                             unsigned long *parent_rate)
+-{
+-      struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+-      struct __prci_wrpll_data *pwd = pc->pwd;
+-      struct wrpll_cfg c;
+-
+-      memcpy(&c, &pwd->c, sizeof(c));
+-
+-      wrpll_configure_for_rate(&c, rate, *parent_rate);
+-
+-      return wrpll_calc_output_rate(&c, *parent_rate);
+-}
+-
+-static int sifive_fu540_prci_wrpll_set_rate(struct clk_hw *hw,
+-                                          unsigned long rate,
+-                                          unsigned long parent_rate)
+-{
+-      struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+-      struct __prci_wrpll_data *pwd = pc->pwd;
+-      struct __prci_data *pd = pc->pd;
+-      int r;
+-
+-      r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate);
+-      if (r)
+-              return r;
+-
+-      if (pwd->enable_bypass)
+-              pwd->enable_bypass(pd);
+-
+-      __prci_wrpll_write_cfg(pd, pwd, &pwd->c);
+-
+-      udelay(wrpll_calc_max_lock_us(&pwd->c));
+-
+-      if (pwd->disable_bypass)
+-              pwd->disable_bypass(pd);
+-
+-      return 0;
+-}
++/* Linux clock framework integration */
+ static const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = {
+-      .set_rate = sifive_fu540_prci_wrpll_set_rate,
+-      .round_rate = sifive_fu540_prci_wrpll_round_rate,
+-      .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate,
++      .set_rate = sifive_prci_wrpll_set_rate,
++      .round_rate = sifive_prci_wrpll_round_rate,
++      .recalc_rate = sifive_prci_wrpll_recalc_rate,
+ };
+ static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = {
+-      .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate,
++      .recalc_rate = sifive_prci_wrpll_recalc_rate,
+ };
+-/* TLCLKSEL clock integration */
+-
+-static unsigned long sifive_fu540_prci_tlclksel_recalc_rate(struct clk_hw *hw,
+-                                                          unsigned long parent_rate)
+-{
+-      struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+-      struct __prci_data *pd = pc->pd;
+-      u32 v;
+-      u8 div;
+-
+-      v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET);
+-      v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK;
+-      div = v ? 1 : 2;
+-
+-      return div_u64(parent_rate, div);
+-}
+-
+ static const struct clk_ops sifive_fu540_prci_tlclksel_clk_ops = {
+-      .recalc_rate = sifive_fu540_prci_tlclksel_recalc_rate,
+-};
+-
+-/*
+- * PRCI integration data for each WRPLL instance
+- */
+-
+-static struct __prci_wrpll_data __prci_corepll_data = {
+-      .cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
+-      .enable_bypass = __prci_coreclksel_use_hfclk,
+-      .disable_bypass = __prci_coreclksel_use_corepll,
+-};
+-
+-static struct __prci_wrpll_data __prci_ddrpll_data = {
+-      .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
++      .recalc_rate = sifive_prci_tlclksel_recalc_rate,
+ };
+-static struct __prci_wrpll_data __prci_gemgxlpll_data = {
+-      .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+-};
+-
+-/*
+- * List of clock controls provided by the PRCI
+- */
+-
+-static struct __prci_clock __prci_init_clocks[] = {
++/* List of clock controls provided by the PRCI */
++struct __prci_clock __prci_init_clocks_fu540[] = {
+       [PRCI_CLK_COREPLL] = {
+               .name = "corepll",
+               .parent_name = "hfclk",
+@@ -506,125 +80,3 @@ static struct __prci_clock __prci_init_clocks[] = {
+               .ops = &sifive_fu540_prci_tlclksel_clk_ops,
+       },
+ };
+-
+-/**
+- * __prci_register_clocks() - register clock controls in the PRCI with Linux
+- * @dev: Linux struct device *
+- *
+- * Register the list of clock controls described in __prci_init_plls[] with
+- * the Linux clock framework.
+- *
+- * Return: 0 upon success or a negative error code upon failure.
+- */
+-static int __prci_register_clocks(struct device *dev, struct __prci_data *pd)
+-{
+-      struct clk_init_data init = { };
+-      struct __prci_clock *pic;
+-      int parent_count, i, r;
+-
+-      parent_count = of_clk_get_parent_count(dev->of_node);
+-      if (parent_count != EXPECTED_CLK_PARENT_COUNT) {
+-              dev_err(dev, "expected only two parent clocks, found %d\n",
+-                      parent_count);
+-              return -EINVAL;
+-      }
+-
+-      /* Register PLLs */
+-      for (i = 0; i < ARRAY_SIZE(__prci_init_clocks); ++i) {
+-              pic = &__prci_init_clocks[i];
+-
+-              init.name = pic->name;
+-              init.parent_names = &pic->parent_name;
+-              init.num_parents = 1;
+-              init.ops = pic->ops;
+-              pic->hw.init = &init;
+-
+-              pic->pd = pd;
+-
+-              if (pic->pwd)
+-                      __prci_wrpll_read_cfg(pd, pic->pwd);
+-
+-              r = devm_clk_hw_register(dev, &pic->hw);
+-              if (r) {
+-                      dev_warn(dev, "Failed to register clock %s: %d\n",
+-                               init.name, r);
+-                      return r;
+-              }
+-
+-              r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev));
+-              if (r) {
+-                      dev_warn(dev, "Failed to register clkdev for %s: %d\n",
+-                               init.name, r);
+-                      return r;
+-              }
+-
+-              pd->hw_clks.hws[i] = &pic->hw;
+-      }
+-
+-      pd->hw_clks.num = i;
+-
+-      r = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+-                                      &pd->hw_clks);
+-      if (r) {
+-              dev_err(dev, "could not add hw_provider: %d\n", r);
+-              return r;
+-      }
+-
+-      return 0;
+-}
+-
+-/*
+- * Linux device model integration
+- *
+- * See the Linux device model documentation for more information about
+- * these functions.
+- */
+-static int sifive_fu540_prci_probe(struct platform_device *pdev)
+-{
+-      struct device *dev = &pdev->dev;
+-      struct resource *res;
+-      struct __prci_data *pd;
+-      int r;
+-
+-      pd = devm_kzalloc(dev,
+-                        struct_size(pd, hw_clks.hws,
+-                                    ARRAY_SIZE(__prci_init_clocks)),
+-                        GFP_KERNEL);
+-      if (!pd)
+-              return -ENOMEM;
+-
+-      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      pd->va = devm_ioremap_resource(dev, res);
+-      if (IS_ERR(pd->va))
+-              return PTR_ERR(pd->va);
+-
+-      r = __prci_register_clocks(dev, pd);
+-      if (r) {
+-              dev_err(dev, "could not register clocks: %d\n", r);
+-              return r;
+-      }
+-
+-      dev_dbg(dev, "SiFive FU540 PRCI probed\n");
+-
+-      return 0;
+-}
+-
+-static const struct of_device_id sifive_fu540_prci_of_match[] = {
+-      { .compatible = "sifive,fu540-c000-prci", },
+-      {}
+-};
+-MODULE_DEVICE_TABLE(of, sifive_fu540_prci_of_match);
+-
+-static struct platform_driver sifive_fu540_prci_driver = {
+-      .driver = {
+-              .name = "sifive-fu540-prci",
+-              .of_match_table = sifive_fu540_prci_of_match,
+-      },
+-      .probe = sifive_fu540_prci_probe,
+-};
+-
+-static int __init sifive_fu540_prci_init(void)
+-{
+-      return platform_driver_register(&sifive_fu540_prci_driver);
+-}
+-core_initcall(sifive_fu540_prci_init);
+diff --git a/drivers/clk/sifive/fu540-prci.h b/drivers/clk/sifive/fu540-prci.h
+new file mode 100644
+index 000000000000..c8271efa7bdc
+--- /dev/null
++++ b/drivers/clk/sifive/fu540-prci.h
+@@ -0,0 +1,21 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2020 SiFive, Inc.
++ * Zong Li
++ */
++
++#ifndef __SIFIVE_CLK_FU540_PRCI_H
++#define __SIFIVE_CLK_FU540_PRCI_H
++
++#include "sifive-prci.h"
++
++#define NUM_CLOCK_FU540       4
++
++extern struct __prci_clock __prci_init_clocks_fu540[NUM_CLOCK_FU540];
++
++static const struct prci_clk_desc prci_clk_fu540 = {
++      .clks = __prci_init_clocks_fu540,
++      .num_clks = ARRAY_SIZE(__prci_init_clocks_fu540),
++};
++
++#endif /* __SIFIVE_CLK_FU540_PRCI_H */
+diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/sifive-prci.c
+similarity index 45%
+copy from drivers/clk/sifive/fu540-prci.c
+copy to drivers/clk/sifive/sifive-prci.c
+index a8901f90a61a..0ac729eeb71b 100644
+--- a/drivers/clk/sifive/fu540-prci.c
++++ b/drivers/clk/sifive/sifive-prci.c
+@@ -3,6 +3,7 @@
+  * Copyright (C) 2018-2019 SiFive, Inc.
+  * Wesley Terpstra
+  * Paul Walmsley
++ * Zong Li
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+@@ -13,180 +14,19 @@
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+- * The FU540 PRCI implements clock and reset control for the SiFive
+- * FU540-C000 chip.  This driver assumes that it has sole control
+- * over all PRCI resources.
++ * The PRCI implements clock and reset control for the SiFive chip.
++ * This driver assumes that it has sole control over all PRCI resources.
+  *
+  * This driver is based on the PRCI driver written by Wesley Terpstra:
+  * https://github.com/riscv/riscv-linux/commit/999529edf517ed75b56659d456d221b2ee56bb60
+- *
+- * References:
+- * - SiFive FU540-C000 manual v1p0, Chapter 7 "Clocking and Reset"
+  */
+-#include <dt-bindings/clock/sifive-fu540-prci.h>
+ #include <linux/clkdev.h>
+-#include <linux/clk-provider.h>
+-#include <linux/clk/analogbits-wrpll-cln28hpc.h>
+ #include <linux/delay.h>
+-#include <linux/err.h>
+ #include <linux/io.h>
+-#include <linux/module.h>
+-#include <linux/of.h>
+-#include <linux/of_clk.h>
+-#include <linux/platform_device.h>
+-#include <linux/slab.h>
+-
+-/*
+- * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
+- *     hfclk and rtcclk
+- */
+-#define EXPECTED_CLK_PARENT_COUNT             2
+-
+-/*
+- * Register offsets and bitmasks
+- */
+-
+-/* COREPLLCFG0 */
+-#define PRCI_COREPLLCFG0_OFFSET                       0x4
+-# define PRCI_COREPLLCFG0_DIVR_SHIFT          0
+-# define PRCI_COREPLLCFG0_DIVR_MASK           (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT)
+-# define PRCI_COREPLLCFG0_DIVF_SHIFT          6
+-# define PRCI_COREPLLCFG0_DIVF_MASK           (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT)
+-# define PRCI_COREPLLCFG0_DIVQ_SHIFT          15
+-# define PRCI_COREPLLCFG0_DIVQ_MASK           (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT)
+-# define PRCI_COREPLLCFG0_RANGE_SHIFT         18
+-# define PRCI_COREPLLCFG0_RANGE_MASK          (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT)
+-# define PRCI_COREPLLCFG0_BYPASS_SHIFT                24
+-# define PRCI_COREPLLCFG0_BYPASS_MASK         (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT)
+-# define PRCI_COREPLLCFG0_FSE_SHIFT           25
+-# define PRCI_COREPLLCFG0_FSE_MASK            (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT)
+-# define PRCI_COREPLLCFG0_LOCK_SHIFT          31
+-# define PRCI_COREPLLCFG0_LOCK_MASK           (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
+-
+-/* DDRPLLCFG0 */
+-#define PRCI_DDRPLLCFG0_OFFSET                        0xc
+-# define PRCI_DDRPLLCFG0_DIVR_SHIFT           0
+-# define PRCI_DDRPLLCFG0_DIVR_MASK            (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT)
+-# define PRCI_DDRPLLCFG0_DIVF_SHIFT           6
+-# define PRCI_DDRPLLCFG0_DIVF_MASK            (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT)
+-# define PRCI_DDRPLLCFG0_DIVQ_SHIFT           15
+-# define PRCI_DDRPLLCFG0_DIVQ_MASK            (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT)
+-# define PRCI_DDRPLLCFG0_RANGE_SHIFT          18
+-# define PRCI_DDRPLLCFG0_RANGE_MASK           (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT)
+-# define PRCI_DDRPLLCFG0_BYPASS_SHIFT         24
+-# define PRCI_DDRPLLCFG0_BYPASS_MASK          (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT)
+-# define PRCI_DDRPLLCFG0_FSE_SHIFT            25
+-# define PRCI_DDRPLLCFG0_FSE_MASK             (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT)
+-# define PRCI_DDRPLLCFG0_LOCK_SHIFT           31
+-# define PRCI_DDRPLLCFG0_LOCK_MASK            (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT)
+-
+-/* DDRPLLCFG1 */
+-#define PRCI_DDRPLLCFG1_OFFSET                        0x10
+-# define PRCI_DDRPLLCFG1_CKE_SHIFT            24
+-# define PRCI_DDRPLLCFG1_CKE_MASK             (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
+-
+-/* GEMGXLPLLCFG0 */
+-#define PRCI_GEMGXLPLLCFG0_OFFSET             0x1c
+-# define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT                0
+-# define PRCI_GEMGXLPLLCFG0_DIVR_MASK         (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT                6
+-# define PRCI_GEMGXLPLLCFG0_DIVF_MASK         (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT                15
+-# define PRCI_GEMGXLPLLCFG0_DIVQ_MASK         (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT               18
+-# define PRCI_GEMGXLPLLCFG0_RANGE_MASK                (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT      24
+-# define PRCI_GEMGXLPLLCFG0_BYPASS_MASK               (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_FSE_SHIFT         25
+-# define PRCI_GEMGXLPLLCFG0_FSE_MASK          (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT)
+-# define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT                31
+-# define PRCI_GEMGXLPLLCFG0_LOCK_MASK         (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT)
+-
+-/* GEMGXLPLLCFG1 */
+-#define PRCI_GEMGXLPLLCFG1_OFFSET             0x20
+-# define PRCI_GEMGXLPLLCFG1_CKE_SHIFT         24
+-# define PRCI_GEMGXLPLLCFG1_CKE_MASK          (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
+-
+-/* CORECLKSEL */
+-#define PRCI_CORECLKSEL_OFFSET                        0x24
+-# define PRCI_CORECLKSEL_CORECLKSEL_SHIFT     0
+-# define PRCI_CORECLKSEL_CORECLKSEL_MASK      (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT)
+-
+-/* DEVICESRESETREG */
+-#define PRCI_DEVICESRESETREG_OFFSET                   0x28
+-# define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT    0
+-# define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK     (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT)
+-# define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT     1
+-# define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK      (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT)
+-# define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT     2
+-# define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK      (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT)
+-# define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT     3
+-# define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK      (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT)
+-# define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT      5
+-# define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK               (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
+-
+-/* CLKMUXSTATUSREG */
+-#define PRCI_CLKMUXSTATUSREG_OFFSET                   0x2c
+-# define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT   1
+-# define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK    (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
+-
+-/*
+- * Private structures
+- */
+-
+-/**
+- * struct __prci_data - per-device-instance data
+- * @va: base virtual address of the PRCI IP block
+- * @hw_clks: encapsulates struct clk_hw records
+- *
+- * PRCI per-device instance data
+- */
+-struct __prci_data {
+-      void __iomem *va;
+-      struct clk_hw_onecell_data hw_clks;
+-};
+-
+-/**
+- * struct __prci_wrpll_data - WRPLL configuration and integration data
+- * @c: WRPLL current configuration record
+- * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
+- * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
+- * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
+- *
+- * @enable_bypass and @disable_bypass are used for WRPLL instances
+- * that contain a separate external glitchless clock mux downstream
+- * from the PLL.  The WRPLL internal bypass mux is not glitchless.
+- */
+-struct __prci_wrpll_data {
+-      struct wrpll_cfg c;
+-      void (*enable_bypass)(struct __prci_data *pd);
+-      void (*disable_bypass)(struct __prci_data *pd);
+-      u8 cfg0_offs;
+-};
+-
+-/**
+- * struct __prci_clock - describes a clock device managed by PRCI
+- * @name: user-readable clock name string - should match the manual
+- * @parent_name: parent name for this clock
+- * @ops: struct clk_ops for the Linux clock framework to use for control
+- * @hw: Linux-private clock data
+- * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
+- * @pd: PRCI-specific data associated with this clock (if not NULL)
+- *
+- * PRCI clock data.  Used by the PRCI driver to register PRCI-provided
+- * clocks to the Linux clock infrastructure.
+- */
+-struct __prci_clock {
+-      const char *name;
+-      const char *parent_name;
+-      const struct clk_ops *ops;
+-      struct clk_hw hw;
+-      struct __prci_wrpll_data *pwd;
+-      struct __prci_data *pd;
+-};
+-
+-#define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw)
++#include <linux/of_device.h>
++#include "sifive-prci.h"
++#include "fu540-prci.h"
+ /*
+  * Private functions
+@@ -222,7 +62,7 @@ static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd)
+  * @c: ptr to a struct wrpll_cfg record to write config into
+  * @r: value read from the PRCI PLL configuration register
+  *
+- * Given a value @r read from an FU540 PRCI PLL configuration register,
++ * Given a value @r read from an FU740 PRCI PLL configuration register,
+  * split it into fields and populate it into the WRPLL configuration record
+  * pointed to by @c.
+  *
+@@ -251,8 +91,8 @@ static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r)
+       v >>= PRCI_COREPLLCFG0_RANGE_SHIFT;
+       c->range = v;
+-      c->flags &= (WRPLL_FLAGS_INT_FEEDBACK_MASK |
+-                   WRPLL_FLAGS_EXT_FEEDBACK_MASK);
++      c->flags &=
++          (WRPLL_FLAGS_INT_FEEDBACK_MASK | WRPLL_FLAGS_EXT_FEEDBACK_MASK);
+       /* external feedback mode not supported */
+       c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK;
+@@ -329,48 +169,6 @@ static void __prci_wrpll_write_cfg(struct __prci_data *pd,
+       memcpy(&pwd->c, c, sizeof(*c));
+ }
+-/* Core clock mux control */
+-
+-/**
+- * __prci_coreclksel_use_hfclk() - switch the CORECLK mux to output HFCLK
+- * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
+- *
+- * Switch the CORECLK mux to the HFCLK input source; return once complete.
+- *
+- * Context: Any context.  Caller must prevent concurrent changes to the
+- *          PRCI_CORECLKSEL_OFFSET register.
+- */
+-static void __prci_coreclksel_use_hfclk(struct __prci_data *pd)
+-{
+-      u32 r;
+-
+-      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
+-      r |= PRCI_CORECLKSEL_CORECLKSEL_MASK;
+-      __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
+-
+-      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
+-}
+-
+-/**
+- * __prci_coreclksel_use_corepll() - switch the CORECLK mux to output COREPLL
+- * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
+- *
+- * Switch the CORECLK mux to the PLL output clock; return once complete.
+- *
+- * Context: Any context.  Caller must prevent concurrent changes to the
+- *          PRCI_CORECLKSEL_OFFSET register.
+- */
+-static void __prci_coreclksel_use_corepll(struct __prci_data *pd)
+-{
+-      u32 r;
+-
+-      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
+-      r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK;
+-      __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
+-
+-      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */
+-}
+-
+ /*
+  * Linux clock framework integration
+  *
+@@ -378,8 +176,8 @@ static void __prci_coreclksel_use_corepll(struct __prci_data *pd)
+  * these functions.
+  */
+-static unsigned long sifive_fu540_prci_wrpll_recalc_rate(struct clk_hw *hw,
+-                                                       unsigned long parent_rate)
++unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
++                                          unsigned long parent_rate)
+ {
+       struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+       struct __prci_wrpll_data *pwd = pc->pwd;
+@@ -387,9 +185,9 @@ static unsigned long sifive_fu540_prci_wrpll_recalc_rate(struct clk_hw *hw,
+       return wrpll_calc_output_rate(&pwd->c, parent_rate);
+ }
+-static long sifive_fu540_prci_wrpll_round_rate(struct clk_hw *hw,
+-                                             unsigned long rate,
+-                                             unsigned long *parent_rate)
++long sifive_prci_wrpll_round_rate(struct clk_hw *hw,
++                                unsigned long rate,
++                                unsigned long *parent_rate)
+ {
+       struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+       struct __prci_wrpll_data *pwd = pc->pwd;
+@@ -402,9 +200,8 @@ static long sifive_fu540_prci_wrpll_round_rate(struct clk_hw *hw,
+       return wrpll_calc_output_rate(&c, *parent_rate);
+ }
+-static int sifive_fu540_prci_wrpll_set_rate(struct clk_hw *hw,
+-                                          unsigned long rate,
+-                                          unsigned long parent_rate)
++int sifive_prci_wrpll_set_rate(struct clk_hw *hw,
++                             unsigned long rate, unsigned long parent_rate)
+ {
+       struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+       struct __prci_wrpll_data *pwd = pc->pwd;
+@@ -428,20 +225,10 @@ static int sifive_fu540_prci_wrpll_set_rate(struct clk_hw *hw,
+       return 0;
+ }
+-static const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = {
+-      .set_rate = sifive_fu540_prci_wrpll_set_rate,
+-      .round_rate = sifive_fu540_prci_wrpll_round_rate,
+-      .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate,
+-};
+-
+-static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = {
+-      .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate,
+-};
+-
+ /* TLCLKSEL clock integration */
+-static unsigned long sifive_fu540_prci_tlclksel_recalc_rate(struct clk_hw *hw,
+-                                                          unsigned long parent_rate)
++unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
++                                             unsigned long parent_rate)
+ {
+       struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+       struct __prci_data *pd = pc->pd;
+@@ -455,68 +242,62 @@ static unsigned long sifive_fu540_prci_tlclksel_recalc_rate(struct clk_hw *hw,
+       return div_u64(parent_rate, div);
+ }
+-static const struct clk_ops sifive_fu540_prci_tlclksel_clk_ops = {
+-      .recalc_rate = sifive_fu540_prci_tlclksel_recalc_rate,
+-};
+-
+ /*
+- * PRCI integration data for each WRPLL instance
++ * Core clock mux control
+  */
+-static struct __prci_wrpll_data __prci_corepll_data = {
+-      .cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
+-      .enable_bypass = __prci_coreclksel_use_hfclk,
+-      .disable_bypass = __prci_coreclksel_use_corepll,
+-};
++/**
++ * sifive_prci_coreclksel_use_hfclk() - switch the CORECLK mux to output HFCLK
++ * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
++ *
++ * Switch the CORECLK mux to the HFCLK input source; return once complete.
++ *
++ * Context: Any context.  Caller must prevent concurrent changes to the
++ *          PRCI_CORECLKSEL_OFFSET register.
++ */
++void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd)
++{
++      u32 r;
+-static struct __prci_wrpll_data __prci_ddrpll_data = {
+-      .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
+-};
++      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
++      r |= PRCI_CORECLKSEL_CORECLKSEL_MASK;
++      __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
+-static struct __prci_wrpll_data __prci_gemgxlpll_data = {
+-      .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+-};
++      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);   /* barrier */
++}
+-/*
+- * List of clock controls provided by the PRCI
++/**
++ * sifive_prci_coreclksel_use_corepll() - switch the CORECLK mux to output
++ * COREPLL
++ * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
++ *
++ * Switch the CORECLK mux to the COREPLL output clock; return once complete.
++ *
++ * Context: Any context.  Caller must prevent concurrent changes to the
++ *          PRCI_CORECLKSEL_OFFSET register.
+  */
++void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd)
++{
++      u32 r;
+-static struct __prci_clock __prci_init_clocks[] = {
+-      [PRCI_CLK_COREPLL] = {
+-              .name = "corepll",
+-              .parent_name = "hfclk",
+-              .ops = &sifive_fu540_prci_wrpll_clk_ops,
+-              .pwd = &__prci_corepll_data,
+-      },
+-      [PRCI_CLK_DDRPLL] = {
+-              .name = "ddrpll",
+-              .parent_name = "hfclk",
+-              .ops = &sifive_fu540_prci_wrpll_ro_clk_ops,
+-              .pwd = &__prci_ddrpll_data,
+-      },
+-      [PRCI_CLK_GEMGXLPLL] = {
+-              .name = "gemgxlpll",
+-              .parent_name = "hfclk",
+-              .ops = &sifive_fu540_prci_wrpll_clk_ops,
+-              .pwd = &__prci_gemgxlpll_data,
+-      },
+-      [PRCI_CLK_TLCLK] = {
+-              .name = "tlclk",
+-              .parent_name = "corepll",
+-              .ops = &sifive_fu540_prci_tlclksel_clk_ops,
+-      },
+-};
++      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
++      r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK;
++      __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
++
++      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);   /* barrier */
++}
+ /**
+- * __prci_register_clocks() - register clock controls in the PRCI with Linux
++ * __prci_register_clocks() - register clock controls in the PRCI
+  * @dev: Linux struct device *
+  *
+- * Register the list of clock controls described in __prci_init_plls[] with
++ * Register the list of clock controls described in __prci_init_clocks[] with
+  * the Linux clock framework.
+  *
+  * Return: 0 upon success or a negative error code upon failure.
+  */
+-static int __prci_register_clocks(struct device *dev, struct __prci_data *pd)
++static int __prci_register_clocks(struct device *dev, struct __prci_data *pd,
++                                const struct prci_clk_desc *desc)
+ {
+       struct clk_init_data init = { };
+       struct __prci_clock *pic;
+@@ -530,8 +311,8 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd)
+       }
+       /* Register PLLs */
+-      for (i = 0; i < ARRAY_SIZE(__prci_init_clocks); ++i) {
+-              pic = &__prci_init_clocks[i];
++      for (i = 0; i < desc->num_clks; ++i) {
++              pic = &(desc->clks[i]);
+               init.name = pic->name;
+               init.parent_names = &pic->parent_name;
+@@ -573,23 +354,22 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd)
+       return 0;
+ }
+-/*
+- * Linux device model integration
++/**
++ * sifive_prci_init() - initialize prci data and check parent count
+  *
+- * See the Linux device model documentation for more information about
+- * these functions.
++ * Return: 0 upon success or a negative error code upon failure.
+  */
+-static int sifive_fu540_prci_probe(struct platform_device *pdev)
++static int sifive_prci_probe(struct platform_device *pdev)
+ {
+       struct device *dev = &pdev->dev;
+       struct resource *res;
+       struct __prci_data *pd;
++      const struct prci_clk_desc *desc;
+       int r;
+-      pd = devm_kzalloc(dev,
+-                        struct_size(pd, hw_clks.hws,
+-                                    ARRAY_SIZE(__prci_init_clocks)),
+-                        GFP_KERNEL);
++      desc = of_device_get_match_data(&pdev->dev);
++
++      pd = devm_kzalloc(dev, struct_size(pd, hw_clks.hws, desc->num_clks), GFP_KERNEL);
+       if (!pd)
+               return -ENOMEM;
+@@ -598,33 +378,32 @@ static int sifive_fu540_prci_probe(struct platform_device *pdev)
+       if (IS_ERR(pd->va))
+               return PTR_ERR(pd->va);
+-      r = __prci_register_clocks(dev, pd);
++      r = __prci_register_clocks(dev, pd, desc);
+       if (r) {
+               dev_err(dev, "could not register clocks: %d\n", r);
+               return r;
+       }
+-      dev_dbg(dev, "SiFive FU540 PRCI probed\n");
++      dev_dbg(dev, "SiFive PRCI probed\n");
+       return 0;
+ }
+-static const struct of_device_id sifive_fu540_prci_of_match[] = {
+-      { .compatible = "sifive,fu540-c000-prci", },
++static const struct of_device_id sifive_prci_of_match[] = {
++      {.compatible = "sifive,fu540-c000-prci", .data = &prci_clk_fu540},
+       {}
+ };
+-MODULE_DEVICE_TABLE(of, sifive_fu540_prci_of_match);
+-static struct platform_driver sifive_fu540_prci_driver = {
+-      .driver = {
+-              .name = "sifive-fu540-prci",
+-              .of_match_table = sifive_fu540_prci_of_match,
++static struct platform_driver sifive_prci_driver = {
++      .driver = {
++              .name = "sifive-clk-prci",
++              .of_match_table = sifive_prci_of_match,
+       },
+-      .probe = sifive_fu540_prci_probe,
++      .probe = sifive_prci_probe,
+ };
+-static int __init sifive_fu540_prci_init(void)
++static int __init sifive_prci_init(void)
+ {
+-      return platform_driver_register(&sifive_fu540_prci_driver);
++      return platform_driver_register(&sifive_prci_driver);
+ }
+-core_initcall(sifive_fu540_prci_init);
++core_initcall(sifive_prci_init);
+diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
+new file mode 100644
+index 000000000000..025f717bc053
+--- /dev/null
++++ b/drivers/clk/sifive/sifive-prci.h
+@@ -0,0 +1,201 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2018-2019 SiFive, Inc.
++ * Wesley Terpstra
++ * Paul Walmsley
++ * Zong Li
++ */
++
++#ifndef __SIFIVE_CLK_SIFIVE_PRCI_H
++#define __SIFIVE_CLK_SIFIVE_PRCI_H
++
++#include <linux/clk/analogbits-wrpll-cln28hpc.h>
++#include <linux/clk-provider.h>
++#include <linux/platform_device.h>
++
++/*
++ * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects:
++ *     hfclk and rtcclk
++ */
++#define EXPECTED_CLK_PARENT_COUNT 2
++
++/*
++ * Register offsets and bitmasks
++ */
++
++/* COREPLLCFG0 */
++#define PRCI_COREPLLCFG0_OFFSET               0x4
++#define PRCI_COREPLLCFG0_DIVR_SHIFT   0
++#define PRCI_COREPLLCFG0_DIVR_MASK    (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT)
++#define PRCI_COREPLLCFG0_DIVF_SHIFT   6
++#define PRCI_COREPLLCFG0_DIVF_MASK    (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT)
++#define PRCI_COREPLLCFG0_DIVQ_SHIFT   15
++#define PRCI_COREPLLCFG0_DIVQ_MASK    (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT)
++#define PRCI_COREPLLCFG0_RANGE_SHIFT  18
++#define PRCI_COREPLLCFG0_RANGE_MASK   (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT)
++#define PRCI_COREPLLCFG0_BYPASS_SHIFT 24
++#define PRCI_COREPLLCFG0_BYPASS_MASK  (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT)
++#define PRCI_COREPLLCFG0_FSE_SHIFT    25
++#define PRCI_COREPLLCFG0_FSE_MASK     (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT)
++#define PRCI_COREPLLCFG0_LOCK_SHIFT   31
++#define PRCI_COREPLLCFG0_LOCK_MASK    (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT)
++
++/* DDRPLLCFG0 */
++#define PRCI_DDRPLLCFG0_OFFSET                0xc
++#define PRCI_DDRPLLCFG0_DIVR_SHIFT    0
++#define PRCI_DDRPLLCFG0_DIVR_MASK     (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT)
++#define PRCI_DDRPLLCFG0_DIVF_SHIFT    6
++#define PRCI_DDRPLLCFG0_DIVF_MASK     (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT)
++#define PRCI_DDRPLLCFG0_DIVQ_SHIFT    15
++#define PRCI_DDRPLLCFG0_DIVQ_MASK     (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT)
++#define PRCI_DDRPLLCFG0_RANGE_SHIFT   18
++#define PRCI_DDRPLLCFG0_RANGE_MASK    (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT)
++#define PRCI_DDRPLLCFG0_BYPASS_SHIFT  24
++#define PRCI_DDRPLLCFG0_BYPASS_MASK   (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT)
++#define PRCI_DDRPLLCFG0_FSE_SHIFT     25
++#define PRCI_DDRPLLCFG0_FSE_MASK      (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT)
++#define PRCI_DDRPLLCFG0_LOCK_SHIFT    31
++#define PRCI_DDRPLLCFG0_LOCK_MASK     (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT)
++
++/* DDRPLLCFG1 */
++#define PRCI_DDRPLLCFG1_OFFSET                0x10
++#define PRCI_DDRPLLCFG1_CKE_SHIFT     24
++#define PRCI_DDRPLLCFG1_CKE_MASK      (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
++
++/* GEMGXLPLLCFG0 */
++#define PRCI_GEMGXLPLLCFG0_OFFSET     0x1c
++#define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0
++#define PRCI_GEMGXLPLLCFG0_DIVR_MASK  (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT)
++#define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT 6
++#define PRCI_GEMGXLPLLCFG0_DIVF_MASK  (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT)
++#define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT 15
++#define PRCI_GEMGXLPLLCFG0_DIVQ_MASK  (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT)
++#define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT        18
++#define PRCI_GEMGXLPLLCFG0_RANGE_MASK (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT)
++#define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT       24
++#define PRCI_GEMGXLPLLCFG0_BYPASS_MASK        (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT)
++#define PRCI_GEMGXLPLLCFG0_FSE_SHIFT  25
++#define PRCI_GEMGXLPLLCFG0_FSE_MASK   (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT)
++#define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT 31
++#define PRCI_GEMGXLPLLCFG0_LOCK_MASK  (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT)
++
++/* GEMGXLPLLCFG1 */
++#define PRCI_GEMGXLPLLCFG1_OFFSET     0x20
++#define RCI_GEMGXLPLLCFG1_CKE_SHIFT   24
++#define PRCI_GEMGXLPLLCFG1_CKE_MASK   (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
++
++/* CORECLKSEL */
++#define PRCI_CORECLKSEL_OFFSET                        0x24
++#define PRCI_CORECLKSEL_CORECLKSEL_SHIFT      0
++#define PRCI_CORECLKSEL_CORECLKSEL_MASK                                       \
++              (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT)
++
++/* DEVICESRESETREG */
++#define PRCI_DEVICESRESETREG_OFFSET                           0x28
++#define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT             0
++#define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK                      \
++              (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT)
++#define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT              1
++#define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK                               \
++              (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT)
++#define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT              2
++#define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK                               \
++              (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT)
++#define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT              3
++#define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK                               \
++              (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT)
++#define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT                       5
++#define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK                                \
++              (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT)
++#define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT             6
++#define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK                      \
++              (0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
++
++/* CLKMUXSTATUSREG */
++#define PRCI_CLKMUXSTATUSREG_OFFSET                           0x2c
++#define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT            1
++#define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK                     \
++              (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
++
++/*
++ * Private structures
++ */
++
++/**
++ * struct __prci_data - per-device-instance data
++ * @va: base virtual address of the PRCI IP block
++ * @hw_clks: encapsulates struct clk_hw records
++ *
++ * PRCI per-device instance data
++ */
++struct __prci_data {
++      void __iomem *va;
++      struct clk_hw_onecell_data hw_clks;
++};
++
++/**
++ * struct __prci_wrpll_data - WRPLL configuration and integration data
++ * @c: WRPLL current configuration record
++ * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL)
++ * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL)
++ * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address
++ *
++ * @enable_bypass and @disable_bypass are used for WRPLL instances
++ * that contain a separate external glitchless clock mux downstream
++ * from the PLL.  The WRPLL internal bypass mux is not glitchless.
++ */
++struct __prci_wrpll_data {
++      struct wrpll_cfg c;
++      void (*enable_bypass)(struct __prci_data *pd);
++      void (*disable_bypass)(struct __prci_data *pd);
++      u8 cfg0_offs;
++};
++
++/**
++ * struct __prci_clock - describes a clock device managed by PRCI
++ * @name: user-readable clock name string - should match the manual
++ * @parent_name: parent name for this clock
++ * @ops: struct clk_ops for the Linux clock framework to use for control
++ * @hw: Linux-private clock data
++ * @pwd: WRPLL-specific data, associated with this clock (if not NULL)
++ * @pd: PRCI-specific data associated with this clock (if not NULL)
++ *
++ * PRCI clock data.  Used by the PRCI driver to register PRCI-provided
++ * clocks to the Linux clock infrastructure.
++ */
++struct __prci_clock {
++      const char *name;
++      const char *parent_name;
++      const struct clk_ops *ops;
++      struct clk_hw hw;
++      struct __prci_wrpll_data *pwd;
++      struct __prci_data *pd;
++};
++
++#define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw)
++
++/*
++ * struct prci_clk_desc - describes the information of clocks of each SoCs
++ * @clks: point to a array of __prci_clock
++ * @num_clks: the number of element of clks
++ */
++struct prci_clk_desc {
++      struct __prci_clock *clks;
++      size_t num_clks;
++};
++
++/* Core clock mux control */
++void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd);
++void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd);
++
++/* Linux clock framework integration */
++long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
++                                unsigned long *parent_rate);
++int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate,
++                             unsigned long parent_rate);
++unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
++                                          unsigned long parent_rate);
++unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
++                                             unsigned long parent_rate);
++
++#endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
+
+From patchwork Wed Nov 11 10:06:06 2020
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Zong Li <[email protected]>
+X-Patchwork-Id: 11897343
+Return-Path: 
+ <SRS0=XU8h=ER=lists.infradead.org=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@kernel.org>
+Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
+ [172.30.200.123])
+       by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A1FFB139F
+       for <[email protected]>;
+ Wed, 11 Nov 2020 10:06:41 +0000 (UTC)
+Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])
+       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+       (No client certificate requested)
+       by mail.kernel.org (Postfix) with ESMTPS id 4C7A420674
+       for <[email protected]>;
+ Wed, 11 Nov 2020 10:06:41 +0000 (UTC)
+Authentication-Results: mail.kernel.org;
+       dkim=pass (2048-bit key) header.d=lists.infradead.org
[email protected] header.b="qBw7oS3m";
+       dkim=fail reason="signature verification failed" (2048-bit key)
+ header.d=sifive.com [email protected] header.b="GC+wCOZX"
+DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4C7A420674
+Authentication-Results: mail.kernel.org;
+ dmarc=none (p=none dis=none) header.from=sifive.com
+Authentication-Results: mail.kernel.org;
+ spf=none
+ smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+       d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding:
+       Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
+       List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:
+       Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:
+       Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner;
+        bh=8M31xTWIfUttsrqEIOFkLkkyiFCsznYAXX4jpceXv4A=; b=qBw7oS3mwfu033UCPMmqQoIpb
+       2vAv10HZmtsPiax38/U81wtjBg4Prf+wINDCyMfFA14jB9t6/x4k9OcO0u88m3qtvCxA2vv0j/u7d
+       pyBT39UMr2TpTP0YPjAfe5Myl6ocXBR7SS2fxa2rwa6KzdGSMPOnjjPUtgiU2ymt5rDFCPT0SaS2T
+       FoLBk0SJQFfGu50k7NlCZkQhNsmWdgkM54WUn+ZnjTlHxEXPuMNN88H30OHs3AHVulXszS5bG3SSF
+       xKe8wds85aA3Q0xFFNL12ydnrEQVCoFcq4MONORy7b+XXqCl2a++jSSU31FSMA/XhxJhR8qObW7T2
+       syj36oKsQ==;
+Received: from localhost ([::1] helo=merlin.infradead.org)
+       by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
+       id 1kcn1F-0001Lp-3C; Wed, 11 Nov 2020 10:06:25 +0000
+Received: from mail-pg1-x543.google.com ([2607:f8b0:4864:20::543])
+ by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
+ id 1kcn1B-0001Ju-Md
+ for [email protected]; Wed, 11 Nov 2020 10:06:22 +0000
+Received: by mail-pg1-x543.google.com with SMTP id h6so1153275pgk.4
+ for <[email protected]>; Wed, 11 Nov 2020 02:06:21 -0800 (PST)
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google;
+ h=from:to:cc:subject:date:message-id:in-reply-to:references
+ :mime-version:content-transfer-encoding;
+ bh=jUzLpOLCCQxDI0oXwDQj4vn2ea5xlcrxx/Uo+2NUKPY=;
+ b=GC+wCOZXigNUTzVyZoZ5sQt0B+qGYQ1rxmobkqe9PjmIvCc/rsn/BC8H3SYZc1hh7I
+ ccETM+g3YzkfkhlvzwnMVXtFwOcS9ucDcp9DLB0k6R0WOAdnNzMABEvcf5WqS0Im3vSN
+ Q8DKnOqwENJeRcYAZBFf2Cm/JpxjIZlkTedy2/RlgQ0hj60kJk9yTI6lvt4enmm9Rhhq
+ 00HHbUlbR28KDigrln9y4ub2QAB8IT1RoQdrVL8NlXWcUK/g1VPzGDK9B1xJ0dx8NrNO
+ 0WrqDqiHfe0ve9o60xGs5YrUO4zAbx/BYypBao5sHykIa0P47nR/r9/I5PDEpjN94jxC
+ sPuw==
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+ d=1e100.net; s=20161025;
+ h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
+ :references:mime-version:content-transfer-encoding;
+ bh=jUzLpOLCCQxDI0oXwDQj4vn2ea5xlcrxx/Uo+2NUKPY=;
+ b=qpt+M+z3gzNH3+8gmx03oWa43xIXEC5PTMslEd6R5Sl7l1rVS7HOPJt/XzUyfQXh/k
+ MQJPZxGh8zyZFR6V9zMFXbL04yHowZaDdn8SJZ9A7QPc/Z2MM3XxzIHXWtgBwDXPqICD
+ 0ku+Z8LEQDuATbKcNJUlF8dhXub/sK4MNMPTNJYh86UXqymHHUNaXgWSG8nHpvUyaKWA
+ q11d27V29oreOq7kK+1VDMIbMRPBXdS1Ra4rJuviWOb02GLLSqVgLWVuYcoocJbRsEqE
+ fk/jhVIOy7AKX26bE34/lEWTmXaHwzz3zLIgdgT8nUKq0WzlPHiqgGY4GD1k8DZmbp4D
+ A3YQ==
+X-Gm-Message-State: AOAM530gEeGE8OMORL33Vr/vtRwFsN1QjnQM5BPR+3Rn9/uySLb3uYjl
+ 54lBbM0xgBN1yrC6kUnjgcpNLA==
+X-Google-Smtp-Source: 
+ ABdhPJzaTSpLq60xMn+cJpFbOkkYXEhNYIOqlqrtQTK0CvD4ZUtz6woJa+U319CNjyJImvVsb89P1A==
+X-Received: by 2002:a63:e650:: with SMTP id
+ p16mr20477838pgj.295.1605089179165;
+ Wed, 11 Nov 2020 02:06:19 -0800 (PST)
+Received: from hsinchu02.internal.sifive.com
+ (114-34-229-221.HINET-IP.hinet.net. [114.34.229.221])
+ by smtp.gmail.com with ESMTPSA id u22sm1872801pgf.24.2020.11.11.02.06.16
+ (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
+ Wed, 11 Nov 2020 02:06:18 -0800 (PST)
+From: Zong Li <[email protected]>
+Subject: [PATCH v4 2/4] clk: sifive: Use common name for prci configuration
+Date: Wed, 11 Nov 2020 18:06:06 +0800
+Message-Id: <[email protected]>
+X-Mailer: git-send-email 2.29.2
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+MIME-Version: 1.0
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
+X-CRM114-CacheID: sfid-20201111_050621_742564_129A155B 
+X-CRM114-Status: GOOD (  11.99  )
+X-Spam-Score: -0.2 (/)
+X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary:
+ Content analysis details:   (-0.2 points)
+ pts rule name              description
+ ---- ----------------------
+ --------------------------------------------------
+ -0.0 RCVD_IN_DNSWL_NONE     RBL: Sender listed at https://www.dnswl.org/,
+ no trust [2607:f8b0:4864:20:0:0:0:543 listed in]
+ [list.dnswl.org]
+ -0.0 SPF_PASS               SPF: sender matches SPF record
+ 0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record
+ 0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
+ not necessarily
+ valid
+ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
+ -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from
+ author's domain
+ -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from
+ envelope-from domain
+X-BeenThere: [email protected]
+X-Mailman-Version: 2.1.29
+Precedence: list
+List-Id: <linux-riscv.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-riscv>,
+ <mailto:[email protected]?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-riscv/>
+List-Post: <mailto:[email protected]>
+List-Help: <mailto:[email protected]?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-riscv>,
+ <mailto:[email protected]?subject=subscribe>
+Cc: Palmer Dabbelt <[email protected]>,
+ Pragnesh Patel <[email protected]>, Zong Li <[email protected]>
+Sender: "linux-riscv" <[email protected]>
+Errors-To: 
+ linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+
+Use generic name CLK_SIFIVE_PRCI instead of CLK_SIFIVE_FU540_PRCI. This
+patch is prepared for fu740 support.
+
+Signed-off-by: Zong Li <[email protected]>
+Reviewed-by: Palmer Dabbelt <[email protected]>
+Acked-by: Palmer Dabbelt <[email protected]>
+Reviewed-by: Pragnesh Patel <[email protected]>
+---
+ arch/riscv/Kconfig.socs     | 2 +-
+ drivers/clk/sifive/Kconfig  | 6 +++---
+ drivers/clk/sifive/Makefile | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
+index 8a55f6156661..3284d5c291be 100644
+--- a/arch/riscv/Kconfig.socs
++++ b/arch/riscv/Kconfig.socs
+@@ -5,7 +5,7 @@ config SOC_SIFIVE
+       select SERIAL_SIFIVE if TTY
+       select SERIAL_SIFIVE_CONSOLE if TTY
+       select CLK_SIFIVE
+-      select CLK_SIFIVE_FU540_PRCI
++      select CLK_SIFIVE_PRCI
+       select SIFIVE_PLIC
+       help
+         This enables support for SiFive SoC platform hardware.
+diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
+index f3b4eb9cb0f5..ab48cf7e0105 100644
+--- a/drivers/clk/sifive/Kconfig
++++ b/drivers/clk/sifive/Kconfig
+@@ -8,12 +8,12 @@ menuconfig CLK_SIFIVE
+ if CLK_SIFIVE
+-config CLK_SIFIVE_FU540_PRCI
+-      bool "PRCI driver for SiFive FU540 SoCs"
++config CLK_SIFIVE_PRCI
++      bool "PRCI driver for SiFive SoCs"
+       select CLK_ANALOGBITS_WRPLL_CLN28HPC
+       help
+         Supports the Power Reset Clock interface (PRCI) IP block found in
+-        FU540 SoCs.  If this kernel is meant to run on a SiFive FU540 SoC,
++        FU540 SoCs. If this kernel is meant to run on a SiFive FU540 SoC,
+         enable this driver.
+ endif
+diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
+index 627effe2ece1..fe3e2cb4c4d8 100644
+--- a/drivers/clk/sifive/Makefile
++++ b/drivers/clk/sifive/Makefile
+@@ -1,4 +1,4 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ obj-y += sifive-prci.o
+-obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI)   += fu540-prci.o
++obj-$(CONFIG_CLK_SIFIVE_PRCI) += fu540-prci.o
+
+From patchwork Wed Nov 11 10:06:07 2020
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Zong Li <[email protected]>
+X-Patchwork-Id: 11897347
+Return-Path: 
+ <SRS0=XU8h=ER=lists.infradead.org=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@kernel.org>
+Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
+ [172.30.200.123])
+       by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CB2CB16C1
+       for <[email protected]>;
+ Wed, 11 Nov 2020 10:06:45 +0000 (UTC)
+Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])
+       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+       (No client certificate requested)
+       by mail.kernel.org (Postfix) with ESMTPS id 5EA7020756
+       for <[email protected]>;
+ Wed, 11 Nov 2020 10:06:45 +0000 (UTC)
+Authentication-Results: mail.kernel.org;
+       dkim=pass (2048-bit key) header.d=lists.infradead.org
[email protected] header.b="t946ymQk";
+       dkim=fail reason="signature verification failed" (2048-bit key)
+ header.d=sifive.com [email protected] header.b="RiuGW/pZ"
+DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5EA7020756
+Authentication-Results: mail.kernel.org;
+ dmarc=none (p=none dis=none) header.from=sifive.com
+Authentication-Results: mail.kernel.org;
+ spf=none
+ smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+       d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding:
+       Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
+       List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:
+       Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:
+       Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner;
+        bh=lVhQgWcRK8t+icobc320Mvw2SK2pa6BityQVJ8tOZ44=; b=t946ymQkXiy0CVBWstEyQ1Iv4
+       CMq9F3UMDuPInkASSB1F/j+7tdXjKJ03wTyuqnLGkIUt11JFYR6nvZFGbaAWvHbRmjqFKOzTH+4eh
+       aCzv/PLkRmr+nlttEybZ7IwalGjbt9iC3udKjjZ8acr8AdVXg/VrEcJFht4ZPZHmQa0mw7oaCGzPi
+       otXN80S8tunksRvUbRAmvN8THK563yWX65Siucg/BSGOQRAa8HLKlcJDRho28eLaeEHXIjiFD0Qt8
+       y09HUFPwyCLutKEvb0hSKVClHmCzQJ05EXHioc8rXxtX4dUJ/8XMkLCWyN/PX4GU9md7jHFQ3mN0y
+       1qBlXZesA==;
+Received: from localhost ([::1] helo=merlin.infradead.org)
+       by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
+       id 1kcn1I-0001Nc-Ui; Wed, 11 Nov 2020 10:06:28 +0000
+Received: from mail-pl1-x641.google.com ([2607:f8b0:4864:20::641])
+ by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
+ id 1kcn1E-0001Kp-IL
+ for [email protected]; Wed, 11 Nov 2020 10:06:26 +0000
+Received: by mail-pl1-x641.google.com with SMTP id b3so710408pls.11
+ for <[email protected]>; Wed, 11 Nov 2020 02:06:24 -0800 (PST)
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google;
+ h=from:to:cc:subject:date:message-id:in-reply-to:references
+ :mime-version:content-transfer-encoding;
+ bh=A3BlQc2MRybB5FiAx2c+SYK+EYdvwk/XU5ETgPyL/wo=;
+ b=RiuGW/pZdiApo0EHoEoRg45i8IdvCrf5jJh5UtuNQHC0Q5czsccHssCZnZPedAp82F
+ zXlCG5FYVq0tw7zRvDrjWwQ+3d3JhVL21KLXFkhIL0D0qFc6FXQY8eKkjmUFtBtzarIo
+ A7BzBRkRctw7K2nCGMLrO7doquccZ+RpIKOjzzxWZcPoD9G7U8oBpJ/tC1ItLnBj/kmp
+ VEz76o8vXe5xe1+BY9bm+SGRoYx4z5s++qXYOmZv9lWlOw/Cvo+9m9LGpZLk4R67Tvux
+ /SZYwcHJo0Ljp8pSo47HtdApGwrw8NjhefAmMRIvUg/gMVnu5kc3ZZWrl8dwVut5q+Hg
+ Y/fw==
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+ d=1e100.net; s=20161025;
+ h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
+ :references:mime-version:content-transfer-encoding;
+ bh=A3BlQc2MRybB5FiAx2c+SYK+EYdvwk/XU5ETgPyL/wo=;
+ b=HacOL1rHKTeNifDz8nzY5Zax4zXuoS62ZJSP8cdEWe5jwlUncU5Mz2/Ji+T46T87LN
+ ug2pPq8YkQvo5mAawUFmAWTMnfiaY2woj1JmM/KVnQS/Yy4+q3kY3vbBJaKHoADoRIN+
+ bHirNo0vW5Z3wQfc6dwkZXZ60k4BgdPlbc9Dnquw0SUJGsX62SBzX2pJANKs+9+puGHj
+ ZKKl4N4X23ueD6sbslC2R3WDzu/xF5BuVvWmg+l8g0Q8g2PVbY1FuUEnIQTtXAQaQ9EY
+ JkmwA+x/hEv+f+poqj60vzpmcxKv0mqmXEc4q2TT9B5K7FFOvGJ9nhuQs0PAlJPwJYx/
+ TS2g==
+X-Gm-Message-State: AOAM5309joyTx8wVWXyuyzu51vBS6RfWmH2pgM6NkUtihJVV/BuT3lXy
+ tqSd2TfNKGEYrA3s9XKAwTZDsw==
+X-Google-Smtp-Source: 
+ ABdhPJwxRk/wVkQDxS/Mw8BxslnAIh64ghgND8BjM79JF2E4Tx+1u+PP6NaDddejbfJt4j1Vvz5cZQ==
+X-Received: by 2002:a17:902:d386:b029:d7:c6c4:b128 with SMTP id
+ e6-20020a170902d386b02900d7c6c4b128mr19757740pld.70.1605089182337;
+ Wed, 11 Nov 2020 02:06:22 -0800 (PST)
+Received: from hsinchu02.internal.sifive.com
+ (114-34-229-221.HINET-IP.hinet.net. [114.34.229.221])
+ by smtp.gmail.com with ESMTPSA id u22sm1872801pgf.24.2020.11.11.02.06.19
+ (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
+ Wed, 11 Nov 2020 02:06:21 -0800 (PST)
+From: Zong Li <[email protected]>
+Subject: [PATCH v4 3/4] clk: sifive: Add a driver for the SiFive FU740 PRCI IP
+ block
+Date: Wed, 11 Nov 2020 18:06:07 +0800
+Message-Id: <[email protected]>
+X-Mailer: git-send-email 2.29.2
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+MIME-Version: 1.0
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
+X-CRM114-CacheID: sfid-20201111_050624_696105_7EAC376D 
+X-CRM114-Status: GOOD (  27.29  )
+X-Spam-Score: -0.2 (/)
+X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary:
+ Content analysis details:   (-0.2 points)
+ pts rule name              description
+ ---- ----------------------
+ --------------------------------------------------
+ -0.0 RCVD_IN_DNSWL_NONE     RBL: Sender listed at https://www.dnswl.org/,
+ no trust [2607:f8b0:4864:20:0:0:0:641 listed in]
+ [list.dnswl.org]
+ -0.0 SPF_PASS               SPF: sender matches SPF record
+ 0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record
+ 0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
+ not necessarily
+ valid
+ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
+ -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from
+ author's domain
+ -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from
+ envelope-from domain
+X-BeenThere: [email protected]
+X-Mailman-Version: 2.1.29
+Precedence: list
+List-Id: <linux-riscv.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-riscv>,
+ <mailto:[email protected]?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-riscv/>
+List-Post: <mailto:[email protected]>
+List-Help: <mailto:[email protected]?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-riscv>,
+ <mailto:[email protected]?subject=subscribe>
+Cc: Erik Danie <[email protected]>, Henry Styles <[email protected]>,
+ Pragnesh Patel <[email protected]>, Zong Li <[email protected]>
+Sender: "linux-riscv" <[email protected]>
+Errors-To: 
+ linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+
+Add driver code for the SiFive FU740 PRCI IP block. This IP block
+handles reset and clock control for the SiFive FU740 device and
+implements SoC-level clock tree controls and dividers.
+
+This driver contains bug fixes and contributions from
+Henry Styles <[email protected]>
+Erik Danie <[email protected]>
+Pragnesh Patel <[email protected]>
+
+Signed-off-by: Zong Li <[email protected]>
+Reviewed-by: Pragnesh Patel <[email protected]>
+Cc: Henry Styles <[email protected]>
+Cc: Erik Danie <[email protected]>
+Cc: Pragnesh Patel <[email protected]>
+Acked-by: Palmer Dabbelt <[email protected]>
+---
+ drivers/clk/sifive/Kconfig                    |   4 +-
+ drivers/clk/sifive/Makefile                   |   1 +
+ drivers/clk/sifive/fu740-prci.c               | 122 ++++++++++++++++++
+ drivers/clk/sifive/fu740-prci.h               |  21 +++
+ drivers/clk/sifive/sifive-prci.c              | 120 +++++++++++++++++
+ drivers/clk/sifive/sifive-prci.h              |  88 +++++++++++++
+ include/dt-bindings/clock/sifive-fu740-prci.h |  23 ++++
+ 7 files changed, 377 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/clk/sifive/fu740-prci.c
+ create mode 100644 drivers/clk/sifive/fu740-prci.h
+ create mode 100644 include/dt-bindings/clock/sifive-fu740-prci.h
+
+diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
+index ab48cf7e0105..1c14eb20c066 100644
+--- a/drivers/clk/sifive/Kconfig
++++ b/drivers/clk/sifive/Kconfig
+@@ -13,7 +13,7 @@ config CLK_SIFIVE_PRCI
+       select CLK_ANALOGBITS_WRPLL_CLN28HPC
+       help
+         Supports the Power Reset Clock interface (PRCI) IP block found in
+-        FU540 SoCs. If this kernel is meant to run on a SiFive FU540 SoC,
+-        enable this driver.
++        FU540/FU740 SoCs. If this kernel is meant to run on a SiFive FU540/
++        FU740 SoCs, enable this driver.
+ endif
+diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
+index fe3e2cb4c4d8..2c05798e4ba4 100644
+--- a/drivers/clk/sifive/Makefile
++++ b/drivers/clk/sifive/Makefile
+@@ -2,3 +2,4 @@
+ obj-y += sifive-prci.o
+ obj-$(CONFIG_CLK_SIFIVE_PRCI) += fu540-prci.o
++obj-$(CONFIG_CLK_SIFIVE_PRCI) += fu740-prci.o
+diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
+new file mode 100644
+index 000000000000..3b87e273c3eb
+--- /dev/null
++++ b/drivers/clk/sifive/fu740-prci.c
+@@ -0,0 +1,122 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (C) 2018-2019 SiFive, Inc.
++ * Wesley Terpstra
++ * Paul Walmsley
++ * Zong Li
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ */
++
++#include <dt-bindings/clock/sifive-fu740-prci.h>
++#include <linux/module.h>
++#include "sifive-prci.h"
++
++/* PRCI integration data for each WRPLL instance */
++
++static struct __prci_wrpll_data __prci_corepll_data = {
++      .cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
++      .enable_bypass = sifive_prci_coreclksel_use_hfclk,
++      .disable_bypass = sifive_prci_coreclksel_use_final_corepll,
++};
++
++static struct __prci_wrpll_data __prci_ddrpll_data = {
++      .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
++};
++
++static struct __prci_wrpll_data __prci_gemgxlpll_data = {
++      .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
++};
++
++static struct __prci_wrpll_data __prci_dvfscorepll_data = {
++      .cfg0_offs = PRCI_DVFSCOREPLLCFG0_OFFSET,
++      .enable_bypass = sifive_prci_corepllsel_use_corepll,
++      .disable_bypass = sifive_prci_corepllsel_use_dvfscorepll,
++};
++
++static struct __prci_wrpll_data __prci_hfpclkpll_data = {
++      .cfg0_offs = PRCI_HFPCLKPLLCFG0_OFFSET,
++      .enable_bypass = sifive_prci_hfpclkpllsel_use_hfclk,
++      .disable_bypass = sifive_prci_hfpclkpllsel_use_hfpclkpll,
++};
++
++static struct __prci_wrpll_data __prci_cltxpll_data = {
++      .cfg0_offs = PRCI_CLTXPLLCFG0_OFFSET,
++};
++
++/* Linux clock framework integration */
++
++static const struct clk_ops sifive_fu740_prci_wrpll_clk_ops = {
++      .set_rate = sifive_prci_wrpll_set_rate,
++      .round_rate = sifive_prci_wrpll_round_rate,
++      .recalc_rate = sifive_prci_wrpll_recalc_rate,
++};
++
++static const struct clk_ops sifive_fu740_prci_wrpll_ro_clk_ops = {
++      .recalc_rate = sifive_prci_wrpll_recalc_rate,
++};
++
++static const struct clk_ops sifive_fu740_prci_tlclksel_clk_ops = {
++      .recalc_rate = sifive_prci_tlclksel_recalc_rate,
++};
++
++static const struct clk_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = {
++      .recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
++};
++
++/* List of clock controls provided by the PRCI */
++struct __prci_clock __prci_init_clocks_fu740[] = {
++      [PRCI_CLK_COREPLL] = {
++              .name = "corepll",
++              .parent_name = "hfclk",
++              .ops = &sifive_fu740_prci_wrpll_clk_ops,
++              .pwd = &__prci_corepll_data,
++      },
++      [PRCI_CLK_DDRPLL] = {
++              .name = "ddrpll",
++              .parent_name = "hfclk",
++              .ops = &sifive_fu740_prci_wrpll_ro_clk_ops,
++              .pwd = &__prci_ddrpll_data,
++      },
++      [PRCI_CLK_GEMGXLPLL] = {
++              .name = "gemgxlpll",
++              .parent_name = "hfclk",
++              .ops = &sifive_fu740_prci_wrpll_clk_ops,
++              .pwd = &__prci_gemgxlpll_data,
++      },
++      [PRCI_CLK_DVFSCOREPLL] = {
++              .name = "dvfscorepll",
++              .parent_name = "hfclk",
++              .ops = &sifive_fu740_prci_wrpll_clk_ops,
++              .pwd = &__prci_dvfscorepll_data,
++      },
++      [PRCI_CLK_HFPCLKPLL] = {
++              .name = "hfpclkpll",
++              .parent_name = "hfclk",
++              .ops = &sifive_fu740_prci_wrpll_clk_ops,
++              .pwd = &__prci_hfpclkpll_data,
++      },
++      [PRCI_CLK_CLTXPLL] = {
++              .name = "cltxpll",
++              .parent_name = "hfclk",
++              .ops = &sifive_fu740_prci_wrpll_clk_ops,
++              .pwd = &__prci_cltxpll_data,
++      },
++      [PRCI_CLK_TLCLK] = {
++              .name = "tlclk",
++              .parent_name = "corepll",
++              .ops = &sifive_fu740_prci_tlclksel_clk_ops,
++      },
++      [PRCI_CLK_PCLK] = {
++              .name = "pclk",
++              .parent_name = "hfpclkpll",
++              .ops = &sifive_fu740_prci_hfpclkplldiv_clk_ops,
++      },
++};
+diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h
+new file mode 100644
+index 000000000000..13ef971f7764
+--- /dev/null
++++ b/drivers/clk/sifive/fu740-prci.h
+@@ -0,0 +1,21 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Copyright (C) 2020 SiFive, Inc.
++ * Zong Li
++ */
++
++#ifndef __SIFIVE_CLK_FU740_PRCI_H
++#define __SIFIVE_CLK_FU740_PRCI_H
++
++#include "sifive-prci.h"
++
++#define NUM_CLOCK_FU740       8
++
++extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740];
++
++static const struct prci_clk_desc prci_clk_fu740 = {
++      .clks = __prci_init_clocks_fu740,
++      .num_clks = ARRAY_SIZE(__prci_init_clocks_fu740),
++};
++
++#endif /* __SIFIVE_CLK_FU740_PRCI_H */
+diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
+index 0ac729eeb71b..4098dbc5881a 100644
+--- a/drivers/clk/sifive/sifive-prci.c
++++ b/drivers/clk/sifive/sifive-prci.c
+@@ -27,6 +27,7 @@
+ #include <linux/of_device.h>
+ #include "sifive-prci.h"
+ #include "fu540-prci.h"
++#include "fu740-prci.h"
+ /*
+  * Private functions
+@@ -242,6 +243,18 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
+       return div_u64(parent_rate, div);
+ }
++/* HFPCLK clock integration */
++
++unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
++                                                 unsigned long parent_rate)
++{
++      struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
++      struct __prci_data *pd = pc->pd;
++      u32 div = __prci_readl(pd, PRCI_HFPCLKPLLDIV_OFFSET);
++
++      return div_u64(parent_rate, div + 2);
++}
++
+ /*
+  * Core clock mux control
+  */
+@@ -287,6 +300,112 @@ void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd)
+       r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);   /* barrier */
+ }
++/**
++ * sifive_prci_coreclksel_use_final_corepll() - switch the CORECLK mux to output
++ * FINAL_COREPLL
++ * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg
++ *
++ * Switch the CORECLK mux to the final COREPLL output clock; return once
++ * complete.
++ *
++ * Context: Any context.  Caller must prevent concurrent changes to the
++ *          PRCI_CORECLKSEL_OFFSET register.
++ */
++void sifive_prci_coreclksel_use_final_corepll(struct __prci_data *pd)
++{
++      u32 r;
++
++      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);
++      r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK;
++      __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd);
++
++      r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET);   /* barrier */
++}
++
++/**
++ * sifive_prci_corepllsel_use_dvfscorepll() - switch the COREPLL mux to
++ * output DVFS_COREPLL
++ * @pd: struct __prci_data * for the PRCI containing the COREPLL mux reg
++ *
++ * Switch the COREPLL mux to the DVFSCOREPLL output clock; return once complete.
++ *
++ * Context: Any context.  Caller must prevent concurrent changes to the
++ *          PRCI_COREPLLSEL_OFFSET register.
++ */
++void sifive_prci_corepllsel_use_dvfscorepll(struct __prci_data *pd)
++{
++      u32 r;
++
++      r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET);
++      r |= PRCI_COREPLLSEL_COREPLLSEL_MASK;
++      __prci_writel(r, PRCI_COREPLLSEL_OFFSET, pd);
++
++      r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET);   /* barrier */
++}
++
++/**
++ * sifive_prci_corepllsel_use_corepll() - switch the COREPLL mux to
++ * output COREPLL
++ * @pd: struct __prci_data * for the PRCI containing the COREPLL mux reg
++ *
++ * Switch the COREPLL mux to the COREPLL output clock; return once complete.
++ *
++ * Context: Any context.  Caller must prevent concurrent changes to the
++ *          PRCI_COREPLLSEL_OFFSET register.
++ */
++void sifive_prci_corepllsel_use_corepll(struct __prci_data *pd)
++{
++      u32 r;
++
++      r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET);
++      r &= ~PRCI_COREPLLSEL_COREPLLSEL_MASK;
++      __prci_writel(r, PRCI_COREPLLSEL_OFFSET, pd);
++
++      r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET);   /* barrier */
++}
++
++/**
++ * sifive_prci_hfpclkpllsel_use_hfclk() - switch the HFPCLKPLL mux to
++ * output HFCLK
++ * @pd: struct __prci_data * for the PRCI containing the HFPCLKPLL mux reg
++ *
++ * Switch the HFPCLKPLL mux to the HFCLK input source; return once complete.
++ *
++ * Context: Any context.  Caller must prevent concurrent changes to the
++ *          PRCI_HFPCLKPLLSEL_OFFSET register.
++ */
++void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd)
++{
++      u32 r;
++
++      r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET);
++      r |= PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK;
++      __prci_writel(r, PRCI_HFPCLKPLLSEL_OFFSET, pd);
++
++      r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
++}
++
++/**
++ * sifive_prci_hfpclkpllsel_use_hfpclkpll() - switch the HFPCLKPLL mux to
++ * output HFPCLKPLL
++ * @pd: struct __prci_data * for the PRCI containing the HFPCLKPLL mux reg
++ *
++ * Switch the HFPCLKPLL mux to the HFPCLKPLL output clock; return once complete.
++ *
++ * Context: Any context.  Caller must prevent concurrent changes to the
++ *          PRCI_HFPCLKPLLSEL_OFFSET register.
++ */
++void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd)
++{
++      u32 r;
++
++      r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET);
++      r &= ~PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK;
++      __prci_writel(r, PRCI_HFPCLKPLLSEL_OFFSET, pd);
++
++      r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
++}
++
+ /**
+  * __prci_register_clocks() - register clock controls in the PRCI
+  * @dev: Linux struct device *
+@@ -391,6 +510,7 @@ static int sifive_prci_probe(struct platform_device *pdev)
+ static const struct of_device_id sifive_prci_of_match[] = {
+       {.compatible = "sifive,fu540-c000-prci", .data = &prci_clk_fu540},
++      {.compatible = "sifive,fu740-c000-prci", .data = &prci_clk_fu740},
+       {}
+ };
+diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
+index 025f717bc053..802fc8fb9c09 100644
+--- a/drivers/clk/sifive/sifive-prci.h
++++ b/drivers/clk/sifive/sifive-prci.h
+@@ -117,6 +117,87 @@
+ #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK                     \
+               (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT)
++/* CLTXPLLCFG0 */
++#define PRCI_CLTXPLLCFG0_OFFSET               0x30
++#define PRCI_CLTXPLLCFG0_DIVR_SHIFT   0
++#define PRCI_CLTXPLLCFG0_DIVR_MASK    (0x3f << PRCI_CLTXPLLCFG0_DIVR_SHIFT)
++#define PRCI_CLTXPLLCFG0_DIVF_SHIFT   6
++#define PRCI_CLTXPLLCFG0_DIVF_MASK    (0x1ff << PRCI_CLTXPLLCFG0_DIVF_SHIFT)
++#define PRCI_CLTXPLLCFG0_DIVQ_SHIFT   15
++#define PRCI_CLTXPLLCFG0_DIVQ_MASK    (0x7 << PRCI_CLTXPLLCFG0_DIVQ_SHIFT)
++#define PRCI_CLTXPLLCFG0_RANGE_SHIFT  18
++#define PRCI_CLTXPLLCFG0_RANGE_MASK   (0x7 << PRCI_CLTXPLLCFG0_RANGE_SHIFT)
++#define PRCI_CLTXPLLCFG0_BYPASS_SHIFT 24
++#define PRCI_CLTXPLLCFG0_BYPASS_MASK  (0x1 << PRCI_CLTXPLLCFG0_BYPASS_SHIFT)
++#define PRCI_CLTXPLLCFG0_FSE_SHIFT    25
++#define PRCI_CLTXPLLCFG0_FSE_MASK     (0x1 << PRCI_CLTXPLLCFG0_FSE_SHIFT)
++#define PRCI_CLTXPLLCFG0_LOCK_SHIFT   31
++#define PRCI_CLTXPLLCFG0_LOCK_MASK    (0x1 << PRCI_CLTXPLLCFG0_LOCK_SHIFT)
++
++/* CLTXPLLCFG1 */
++#define PRCI_CLTXPLLCFG1_OFFSET               0x34
++#define PRCI_CLTXPLLCFG1_CKE_SHIFT    31
++#define PRCI_CLTXPLLCFG1_CKE_MASK     (0x1 << PRCI_CLTXPLLCFG1_CKE_SHIFT)
++
++/* DVFSCOREPLLCFG0 */
++#define PRCI_DVFSCOREPLLCFG0_OFFSET   0x38
++
++/* DVFSCOREPLLCFG1 */
++#define PRCI_DVFSCOREPLLCFG1_OFFSET   0x3c
++#define PRCI_DVFSCOREPLLCFG1_CKE_SHIFT        31
++#define PRCI_DVFSCOREPLLCFG1_CKE_MASK (0x1 << PRCI_DVFSCOREPLLCFG1_CKE_SHIFT)
++
++/* COREPLLSEL */
++#define PRCI_COREPLLSEL_OFFSET                        0x40
++#define PRCI_COREPLLSEL_COREPLLSEL_SHIFT      0
++#define PRCI_COREPLLSEL_COREPLLSEL_MASK                                       \
++              (0x1 << PRCI_COREPLLSEL_COREPLLSEL_SHIFT)
++
++/* HFPCLKPLLCFG0 */
++#define PRCI_HFPCLKPLLCFG0_OFFSET             0x50
++#define PRCI_HFPCLKPLL_CFG0_DIVR_SHIFT                0
++#define PRCI_HFPCLKPLL_CFG0_DIVR_MASK                                 \
++              (0x3f << PRCI_HFPCLKPLLCFG0_DIVR_SHIFT)
++#define PRCI_HFPCLKPLL_CFG0_DIVF_SHIFT                6
++#define PRCI_HFPCLKPLL_CFG0_DIVF_MASK                                 \
++              (0x1ff << PRCI_HFPCLKPLLCFG0_DIVF_SHIFT)
++#define PRCI_HFPCLKPLL_CFG0_DIVQ_SHIFT                15
++#define PRCI_HFPCLKPLL_CFG0_DIVQ_MASK                                 \
++              (0x7 << PRCI_HFPCLKPLLCFG0_DIVQ_SHIFT)
++#define PRCI_HFPCLKPLL_CFG0_RANGE_SHIFT               18
++#define PRCI_HFPCLKPLL_CFG0_RANGE_MASK                                        \
++              (0x7 << PRCI_HFPCLKPLLCFG0_RANGE_SHIFT)
++#define PRCI_HFPCLKPLL_CFG0_BYPASS_SHIFT      24
++#define PRCI_HFPCLKPLL_CFG0_BYPASS_MASK                                       \
++              (0x1 << PRCI_HFPCLKPLLCFG0_BYPASS_SHIFT)
++#define PRCI_HFPCLKPLL_CFG0_FSE_SHIFT         25
++#define PRCI_HFPCLKPLL_CFG0_FSE_MASK                                  \
++              (0x1 << PRCI_HFPCLKPLLCFG0_FSE_SHIFT)
++#define PRCI_HFPCLKPLL_CFG0_LOCK_SHIFT                31
++#define PRCI_HFPCLKPLL_CFG0_LOCK_MASK                                 \
++              (0x1 << PRCI_HFPCLKPLLCFG0_LOCK_SHIFT)
++
++/* HFPCLKPLLCFG1 */
++#define PRCI_HFPCLKPLLCFG1_OFFSET             0x54
++#define PRCI_HFPCLKPLLCFG1_CKE_SHIFT          31
++#define PRCI_HFPCLKPLLCFG1_CKE_MASK                                   \
++              (0x1 << PRCI_HFPCLKPLLCFG1_CKE_SHIFT)
++
++/* HFPCLKPLLSEL */
++#define PRCI_HFPCLKPLLSEL_OFFSET              0x58
++#define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT  0
++#define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK                           \
++              (0x1 << PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT)
++
++/* HFPCLKPLLDIV */
++#define PRCI_HFPCLKPLLDIV_OFFSET              0x5c
++
++/* PRCIPLL */
++#define PRCI_PRCIPLL_OFFSET                   0xe0
++
++/* PROCMONCFG */
++#define PRCI_PROCMONCFG_OFFSET                        0xf0
++
+ /*
+  * Private structures
+  */
+@@ -187,6 +268,11 @@ struct prci_clk_desc {
+ /* Core clock mux control */
+ void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd);
+ void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd);
++void sifive_prci_coreclksel_use_final_corepll(struct __prci_data *pd);
++void sifive_prci_corepllsel_use_dvfscorepll(struct __prci_data *pd);
++void sifive_prci_corepllsel_use_corepll(struct __prci_data *pd);
++void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd);
++void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd);
+ /* Linux clock framework integration */
+ long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate,
+@@ -197,5 +283,7 @@ unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw,
+                                           unsigned long parent_rate);
+ unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
+                                              unsigned long parent_rate);
++unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
++                                                 unsigned long parent_rate);
+ #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
+diff --git a/include/dt-bindings/clock/sifive-fu740-prci.h b/include/dt-bindings/clock/sifive-fu740-prci.h
+new file mode 100644
+index 000000000000..cd7706ea5677
+--- /dev/null
++++ b/include/dt-bindings/clock/sifive-fu740-prci.h
+@@ -0,0 +1,23 @@
++/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
++/*
++ * Copyright (C) 2019 SiFive, Inc.
++ * Wesley Terpstra
++ * Paul Walmsley
++ * Zong Li
++ */
++
++#ifndef __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H
++#define __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H
++
++/* Clock indexes for use by Device Tree data and the PRCI driver */
++
++#define PRCI_CLK_COREPLL             0
++#define PRCI_CLK_DDRPLL                      1
++#define PRCI_CLK_GEMGXLPLL           2
++#define PRCI_CLK_DVFSCOREPLL         3
++#define PRCI_CLK_HFPCLKPLL           4
++#define PRCI_CLK_CLTXPLL             5
++#define PRCI_CLK_TLCLK                       6
++#define PRCI_CLK_PCLK                7
++
++#endif        /* __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H */
+
+From patchwork Wed Nov 11 10:06:08 2020
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Zong Li <[email protected]>
+X-Patchwork-Id: 11897345
+Return-Path: 
+ <SRS0=XU8h=ER=lists.infradead.org=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@kernel.org>
+Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
+ [172.30.200.123])
+       by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C81D7921
+       for <[email protected]>;
+ Wed, 11 Nov 2020 10:06:45 +0000 (UTC)
+Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])
+       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+       (No client certificate requested)
+       by mail.kernel.org (Postfix) with ESMTPS id 5D73E20674
+       for <[email protected]>;
+ Wed, 11 Nov 2020 10:06:45 +0000 (UTC)
+Authentication-Results: mail.kernel.org;
+       dkim=pass (2048-bit key) header.d=lists.infradead.org
[email protected] header.b="n3HMvSwO";
+       dkim=fail reason="signature verification failed" (2048-bit key)
+ header.d=sifive.com [email protected] header.b="PeekuDgz"
+DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5D73E20674
+Authentication-Results: mail.kernel.org;
+ dmarc=none (p=none dis=none) header.from=sifive.com
+Authentication-Results: mail.kernel.org;
+ spf=none
+ smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+       d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding:
+       Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
+       List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:
+       Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:
+       Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner;
+        bh=Iews4m/vXSIqqkrhG9iaPa7cWeSAQe21FZQymVbjsek=; b=n3HMvSwOSedTdvwm4hsUJQn4J
+       LMx/juTx/k+vS98k9FAGRpif02amIkwVzJqzx0DwyzZyrIOWtAElnhs//2qkI6cypy145twFMcNJ1
+       VwSP2z+13zR6wJoaxL6GoyE7oKCDc5nuVJYgtF5p7Xnt7CfSm3mTufIrP22q6o1tvcL4rVICrXfcs
+       4c5qmrRP0dJhLna/LyehaPS2NilAd3iHikmA4WEP3/4mXYrPqcy2LMIsfKCyIFIONgautnQBaCqiP
+       qE3M+PtaL5B+IkXATvHgq2ElUBGlrs+ApmEQg3HFJxBQ+BK7sLGRyKb1mbAjMSCcg4tfigDBJsqCj
+       Stj5xG5ZQ==;
+Received: from localhost ([::1] helo=merlin.infradead.org)
+       by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
+       id 1kcn1J-0001O2-Vw; Wed, 11 Nov 2020 10:06:30 +0000
+Received: from mail-pl1-x641.google.com ([2607:f8b0:4864:20::641])
+ by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
+ id 1kcn1G-0001M8-M3
+ for [email protected]; Wed, 11 Nov 2020 10:06:27 +0000
+Received: by mail-pl1-x641.google.com with SMTP id t18so741935plo.0
+ for <[email protected]>; Wed, 11 Nov 2020 02:06:26 -0800 (PST)
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google;
+ h=from:to:cc:subject:date:message-id:in-reply-to:references
+ :mime-version:content-transfer-encoding;
+ bh=ZNKLbQTe0EJyIiECa6jG2QS24SEV6zzCe3D1RGbycgk=;
+ b=PeekuDgz0P2oQrbgHf0FCJsHiFPz2BZ5Cv0EpubvZV33MfWN9TBmNIoMvevKzpAKwl
+ 7LJeN/GGuGZ1R8SpAyvdx9PV6YbcoggRDY0x4w9xPXzQGeKz4WnDAw06gmxneyOgmKhA
+ /lAFxcltub4Uf/tXXaz4ZpsXGpLrCoyGmwQFdiISsmB4SgURGnWWwnYgNloUH1NuXD4I
+ fVbamNCDjQnkK9gW1s3b1+yDDha0yEI92ND4/KzlrlG4VVgfF5U6OOfUgRj2uq9OGYl7
+ 8ZzoZiJQdd8CKeidNnJUbHDKXKybBKhey4LHDnjRvLwKZchOpPaIBJl5Llx+6ySZtwDi
+ Ww/g==
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+ d=1e100.net; s=20161025;
+ h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
+ :references:mime-version:content-transfer-encoding;
+ bh=ZNKLbQTe0EJyIiECa6jG2QS24SEV6zzCe3D1RGbycgk=;
+ b=SWpgmTh3mw2jAC1m2kFTI+MTPWGdATCrm7BeHr8h1itmKaar496vqFFosmLa8W2Zu2
+ 3bmEUpTRpqbU4csrwJ08+o6g6iRy05FrUbCY5OC8mbGdKFImjlzq2l5DHewQtc1u+dAk
+ g29Rbuq3HsOXZCahBqdf6RGGr5aG9Abqb7HPiLUKt3eObcwpyfFcQvuC2IuG058oFlS/
+ HiOUBFTlM+LpAXVTzSft+WUtuve9Ygg2eFcEM+KW76DIU0YPap437NMquK5i5Z3/+e91
+ NbDca+1mYv10N1y1lZkWfCQV684IsbDonNEbVWeaqua6Cz2NgJV91CSqh4lTrW/1I/fB
+ 4NHA==
+X-Gm-Message-State: AOAM531SY0ngV//lj1q8qfNb19tAN6GloaUG8Oe2G9K2D7ZgjhIgLIzj
+ CfyzHRvEm76GevoBY2v6m0YSRA==
+X-Google-Smtp-Source: 
+ ABdhPJyXKkTB6t7sDQgeqfdIEFT0KtFRUawfjJ4kwO8HBmsgEDtvRVY0BcyIF6ftITFc/IHnSOKd3Q==
+X-Received: by 2002:a17:902:d3d4:b029:d7:e936:7651 with SMTP id
+ w20-20020a170902d3d4b02900d7e9367651mr10846937plb.57.1605089185026;
+ Wed, 11 Nov 2020 02:06:25 -0800 (PST)
+Received: from hsinchu02.internal.sifive.com
+ (114-34-229-221.HINET-IP.hinet.net. [114.34.229.221])
+ by smtp.gmail.com with ESMTPSA id u22sm1872801pgf.24.2020.11.11.02.06.22
+ (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
+ Wed, 11 Nov 2020 02:06:24 -0800 (PST)
+From: Zong Li <[email protected]>
+Subject: [PATCH v4 4/4] clk: sifive: Fix the wrong bit field shift
+Date: Wed, 11 Nov 2020 18:06:08 +0800
+Message-Id: <[email protected]>
+X-Mailer: git-send-email 2.29.2
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+MIME-Version: 1.0
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
+X-CRM114-CacheID: sfid-20201111_050626_820934_FD67C5E9 
+X-CRM114-Status: GOOD (  10.51  )
+X-Spam-Score: -0.2 (/)
+X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary:
+ Content analysis details:   (-0.2 points)
+ pts rule name              description
+ ---- ----------------------
+ --------------------------------------------------
+ -0.0 RCVD_IN_DNSWL_NONE     RBL: Sender listed at https://www.dnswl.org/,
+ no trust [2607:f8b0:4864:20:0:0:0:641 listed in]
+ [list.dnswl.org]
+ -0.0 SPF_PASS               SPF: sender matches SPF record
+ 0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record
+ 0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
+ not necessarily
+ valid
+ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
+ -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from
+ author's domain
+ -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from
+ envelope-from domain
+X-BeenThere: [email protected]
+X-Mailman-Version: 2.1.29
+Precedence: list
+List-Id: <linux-riscv.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-riscv>,
+ <mailto:[email protected]?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-riscv/>
+List-Post: <mailto:[email protected]>
+List-Help: <mailto:[email protected]?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-riscv>,
+ <mailto:[email protected]?subject=subscribe>
+Cc: Pragnesh Patel <[email protected]>, Zong Li <[email protected]>
+Sender: "linux-riscv" <[email protected]>
+Errors-To: 
+ linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+
+The clk enable bit should be 31 instead of 24.
+
+Signed-off-by: Zong Li <[email protected]>
+Reported-by: Pragnesh Patel <[email protected]>
+---
+ drivers/clk/sifive/sifive-prci.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
+index 802fc8fb9c09..da7be9103d4d 100644
+--- a/drivers/clk/sifive/sifive-prci.h
++++ b/drivers/clk/sifive/sifive-prci.h
+@@ -59,7 +59,7 @@
+ /* DDRPLLCFG1 */
+ #define PRCI_DDRPLLCFG1_OFFSET                0x10
+-#define PRCI_DDRPLLCFG1_CKE_SHIFT     24
++#define PRCI_DDRPLLCFG1_CKE_SHIFT     31
+ #define PRCI_DDRPLLCFG1_CKE_MASK      (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
+ /* GEMGXLPLLCFG0 */
+@@ -81,7 +81,7 @@
+ /* GEMGXLPLLCFG1 */
+ #define PRCI_GEMGXLPLLCFG1_OFFSET     0x20
+-#define RCI_GEMGXLPLLCFG1_CKE_SHIFT   24
++#define RCI_GEMGXLPLLCFG1_CKE_SHIFT   31
+ #define PRCI_GEMGXLPLLCFG1_CKE_MASK   (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
+ /* CORECLKSEL */
diff --git a/target/linux/hifiveu/patches-5.10/0002-improve-kernel-section-protections.patch b/target/linux/hifiveu/patches-5.10/0002-improve-kernel-section-protections.patch
new file mode 100644 (file)
index 0000000..72fbc31
--- /dev/null
@@ -0,0 +1,1268 @@
+From patchwork Mon Oct 26 23:02:49 2020
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Atish Patra <[email protected]>
+X-Patchwork-Id: 11858967
+Return-Path: 
+ <SRS0=2xBv=EB=lists.infradead.org=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@kernel.org>
+Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
+ [172.30.200.123])
+       by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4BD05697
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:54 +0000 (UTC)
+Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])
+       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+       (No client certificate requested)
+       by mail.kernel.org (Postfix) with ESMTPS id 1C98220708
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:54 +0000 (UTC)
+Authentication-Results: mail.kernel.org;
+       dkim=pass (2048-bit key) header.d=lists.infradead.org
[email protected] header.b="td8C3JZ+";
+       dkim=fail reason="signature verification failed" (2048-bit key)
+ header.d=wdc.com [email protected] header.b="nGr05oxD"
+DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1C98220708
+Authentication-Results: mail.kernel.org;
+ dmarc=fail (p=none dis=none) header.from=wdc.com
+Authentication-Results: mail.kernel.org;
+ spf=none
+ smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+       d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding:
+       Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
+       List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:
+       Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:
+       Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner;
+        bh=wX4g/n6Z4vxFkVtoaai8oo26/fP6F8kk0A+XsmapyyU=; b=td8C3JZ+t42jYE9JYqpuhrzG4
+       mf/Cyo+A34YAryyjJ0WDmJm+tlQtkguSCgdrAi0i9m5xvsxFET+HAp02yWKh4dNV1x1FSRYvzS4/h
+       eLBjlmfQ3qmmCW7AOqwHU0JtVkosQDjljJPFBvpo9PPSGHRXUAwC8L1Jdk9jTxselPR8xSnRWZiJz
+       PM2YlEJvLc7D1eMDhuD3w16L86NeGguAdgOVRf9zRyy1pdWtr6zLzXIcpObNv1LnfQ557Idrq83EV
+       dRnIUFsIvavBFOWvmCvPeoscvnVkj1crBbLS7OrJUVO3/OU0WFY9zDvp3RcFq+dTxdqVptvB17q95
+       LjIWwpkyA==;
+Received: from localhost ([::1] helo=merlin.infradead.org)
+       by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
+       id 1kXBWV-0004Hv-KO; Mon, 26 Oct 2020 23:03:31 +0000
+Received: from esa6.hgst.iphmx.com ([216.71.154.45])
+ by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
+ id 1kXBWS-0004FU-Ay
+ for [email protected]; Mon, 26 Oct 2020 23:03:29 +0000
+DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;
+ d=wdc.com; [email protected]; q=dns/txt; s=dkim.wdc.com;
+ t=1603753408; x=1635289408;
+ h=from:to:cc:subject:date:message-id:in-reply-to:
+ references:mime-version:content-transfer-encoding;
+ bh=Qmlk0Pnoc73PLeMzxCGZ41KUAZ0XJ8ZZaWUmbVJfPT0=;
+ b=nGr05oxDAK6SRe7L7o1giKU1GJuN/1wDt6UpyPcYMwzGiDbNCVn3Jas8
+ C7rWDC0lAKjCVjADONzoQTYpDq5AUGTNYO+dhqbDNJBsApSIv8jvsg1ZL
+ RU3/nobD5FMZ2k3NJwx1BEde/T9oy5Gfq5OThiRZwe6cSGSoKCH+WXQda
+ 2kPPEDzScTwjpc2hMdq7+reRiFHvtVgaBg7FM4IXejGhxVN0SwEsVG6z2
+ o3SSsreUZvNH8XtK83CNdDidTNESY/VNJHnP7lt23/8LIe6fgXwhVjC+g
+ A6+Cml40M8I34uazxz9OngDliKt61AZr1YuXRQsOAfQ+GpvwabO8ZjIWp A==;
+IronPort-SDR: 
+ JybhKPbwUi/q9fGONsYOeF/38aYwXWBa5uJtb/Y1EvUxqi+u/0Y2wm/lhLJgB4UR2aiwBOv4vW
+ l3ApnDplRsZZx+azT1MoIzF+XCBslSC+ay04xht2qVX7bx3MSjjOIEnmE86rzQFSgx+GoEkQRs
+ RttASlhJq4ZZ8RsyaRJRI0uxRXOmxkoajSiY5dMfebzmp7PTLBY84j8c1WzH28wekiXAwbmUB1
+ H6hF2AahkCfeVbWPNAIjPwy/qWb3Fe52LbS3baXCDuiY0fjR3gAtZFfc4CTknO2ITlDcxRbIbq
+ QtI=
+X-IronPort-AV: E=Sophos;i="5.77,421,1596470400"; d="scan'208";a="152152906"
+Received: from h199-255-45-15.hgst.com (HELO uls-op-cesaep02.wdc.com)
+ ([199.255.45.15])
+ by ob1.hgst.iphmx.com with ESMTP; 27 Oct 2020 07:03:23 +0800
+IronPort-SDR: 
+ Tpcus0rX16e4qgtbXcdZdBeFOG1T6Zg8N83jXFLUk3LPYmFifOthq2plK4SHViNbDmZQ6i1Lh8
+ LUQCBq6AtyWkG4vl1cO1s/n8422erEiTSRrgtK60jzcY35aOrbaNASElmyzB+XB0rYFn7/C45Z
+ qyoJhhP2uu+D+bCiyp8yea7M+ZZg15R1jhtXx0s7WGu26muiQfQAHWRe29m/cxwIsTbloNQkx9
+ 5jgejPdPMcAg6jW+VZNpy83oy9KALuxI6bnHbH+1nTUXijsxw1AyV1pZGy1wh23Gg+xqL7/VuT
+ ZZ9sOmrtOa+0MTbHhXA4fcfz
+Received: from uls-op-cesaip02.wdc.com ([10.248.3.37])
+ by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
+ 26 Oct 2020 15:48:34 -0700
+IronPort-SDR: 
+ w0qKrqk4Ps76VXo2fhQqnJ3FzMjkvDA5n76UhstySma3ZkkQkkND11NhJZJe1RlXHu/OQkarV/
+ 5eJJS29Zjj//2bfffUYVZXW2/yuSD0isOWFHbB8RAWw1+v7/ODIlLVksfre4BHHKG/C4su00sv
+ EAC/XmNixR8peOtynxZ0tW4ZofnRxUZ5ok6zjykyuVEQPSkyAFY4IZSWqNz+XVT+JZAK6I8bpi
+ YWP1fNPizwdXJD1KYcY1PiwAqN04YYwkFs6RUTz+WYH+vwTMz3OLF7cwaI9wldwepnoJKem0cx
+ 6Ho=
+WDCIronportException: Internal
+Received: from 8223p12.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.110])
+ by uls-op-cesaip02.wdc.com with ESMTP; 26 Oct 2020 16:03:24 -0700
+From: Atish Patra <[email protected]>
+Subject: [PATCH v2 1/6] RISC-V: Move __start_kernel to .head.text
+Date: Mon, 26 Oct 2020 16:02:49 -0700
+Message-Id: <[email protected]>
+X-Mailer: git-send-email 2.25.1
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+MIME-Version: 1.0
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
+X-CRM114-CacheID: sfid-20201026_190328_503890_B35AEB06 
+X-CRM114-Status: GOOD (  13.15  )
+X-Spam-Score: -2.5 (--)
+X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary:
+ Content analysis details:   (-2.5 points)
+ pts rule name              description
+ ---- ----------------------
+ --------------------------------------------------
+ -2.3 RCVD_IN_DNSWL_MED      RBL: Sender listed at https://www.dnswl.org/,
+ medium trust [216.71.154.45 listed in list.dnswl.org]
+ -0.0 SPF_PASS               SPF: sender matches SPF record
+ -0.0 SPF_HELO_PASS          SPF: HELO matches SPF record
+ -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from
+ envelope-from domain
+ 0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
+ not necessarily
+ valid
+ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
+ -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from
+ author's domain
+X-BeenThere: [email protected]
+X-Mailman-Version: 2.1.29
+Precedence: list
+List-Id: <linux-riscv.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-riscv>,
+ <mailto:[email protected]?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-riscv/>
+List-Post: <mailto:[email protected]>
+List-Help: <mailto:[email protected]?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-riscv>,
+ <mailto:[email protected]?subject=subscribe>
+Cc: Albert Ou <[email protected]>, Kees Cook <[email protected]>,
+ Atish Patra <[email protected]>, Palmer Dabbelt <[email protected]>,
+ Zong Li <[email protected]>, Paul Walmsley <[email protected]>,
+ Greentime Hu <[email protected]>,
+ Andrew Morton <[email protected]>, Borislav Petkov <[email protected]>,
+ Michel Lespinasse <[email protected]>, Ard Biesheuvel <[email protected]>,
+ Mike Rapoport <[email protected]>
+Sender: "linux-riscv" <[email protected]>
+Errors-To: 
+ linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+
+Currently, __start_kernel is kept in _init while _start is in head section.
+This may result in "relocation truncated to fit error" if _init section is
+moved far from head. It also makes sense to keep entire head.S in one
+section.
+
+Keep __start_kernel in head section rather than _init.
+
+Signed-off-by: Atish Patra <[email protected]>
+---
+ arch/riscv/kernel/head.S | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
+index 11e2a4fe66e0..45dbdae930bf 100644
+--- a/arch/riscv/kernel/head.S
++++ b/arch/riscv/kernel/head.S
+@@ -177,7 +177,6 @@ setup_trap_vector:
+ END(_start)
+-      __INIT
+ ENTRY(_start_kernel)
+       /* Mask all interrupts */
+       csrw CSR_IE, zero
+
+From patchwork Mon Oct 26 23:02:50 2020
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Atish Patra <[email protected]>
+X-Patchwork-Id: 11858963
+Return-Path: 
+ <SRS0=2xBv=EB=lists.infradead.org=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@kernel.org>
+Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
+ [172.30.200.123])
+       by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4E41514C0
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:51 +0000 (UTC)
+Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])
+       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+       (No client certificate requested)
+       by mail.kernel.org (Postfix) with ESMTPS id 12B3620780
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:50 +0000 (UTC)
+Authentication-Results: mail.kernel.org;
+       dkim=pass (2048-bit key) header.d=lists.infradead.org
[email protected] header.b="R2N4oQv0";
+       dkim=fail reason="signature verification failed" (2048-bit key)
+ header.d=wdc.com [email protected] header.b="JXSoMBF4"
+DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 12B3620780
+Authentication-Results: mail.kernel.org;
+ dmarc=fail (p=none dis=none) header.from=wdc.com
+Authentication-Results: mail.kernel.org;
+ spf=none
+ smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+       d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding:
+       Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
+       List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:
+       Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:
+       Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner;
+        bh=jItsVKgw3M8EfidQQEWfLINsB65ulKh31mJBLTzxhDI=; b=R2N4oQv042pLH7TrdlwNl7i50
+       JjJy5OvLFC7t//03XjlRdVlWhM7FNziOhNkUx4TR4LRsdhYbQzg1uMxn7yAmZXSXldhIR6W2JsZTO
+       jEOLLZl8TALQpLU/nc9Hx27O2pnp9vVLtXNjp0bi1hXSf09zSdDG99wlmmlgTwsxi58Z8opCAtLlc
+       b5eYKGc/KQEhrPrF8/K3XPpKjb/ubPyDnL4Pe2wxp1arN3ruor691TL7rSFM9u9RbJUiSaE0C4H52
+       +5ywoRk22VlNHevpvSo7+Ciak7INBHIQGNvR6n69NNMsPvEHvhzlw/63bQ/dm8p6jMNjN6vCogORd
+       SDruDBTMw==;
+Received: from localhost ([::1] helo=merlin.infradead.org)
+       by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
+       id 1kXBWX-0004Ij-0J; Mon, 26 Oct 2020 23:03:33 +0000
+Received: from esa6.hgst.iphmx.com ([216.71.154.45])
+ by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
+ id 1kXBWS-0004G3-NQ
+ for [email protected]; Mon, 26 Oct 2020 23:03:29 +0000
+DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;
+ d=wdc.com; [email protected]; q=dns/txt; s=dkim.wdc.com;
+ t=1603753408; x=1635289408;
+ h=from:to:cc:subject:date:message-id:in-reply-to:
+ references:mime-version:content-transfer-encoding;
+ bh=AVRSSDssQdWbrcRKwBjC+hUtmkwJEL8J+eqHnYnc5QE=;
+ b=JXSoMBF4ncwPVXLxewMSTeYsKp0BzDGS31RbupMBJvpJXzJAd/M1iJmL
+ TBSJVfuyzHcCdd1Il/SovevTs8tWGJHiD5H6/jgM9WngeEiBJfRRrAJEi
+ zz2z/CTcvEF8uUNS/NeXxi9zHprzolNuwagt8HIJQ4im6++Z+V4MYBBFa
+ rIwOLsRyNRuPQd+uavq+ecYDaII6BW0AQgMPlbBFs20+h4l9ug/5r8lvq
+ vkaGEWWmHJy+Y7uFf/H59nyE+YyVgl5VWIXxeq+lTsBLThebrhcfNR5rF
+ mX+GKYLwKesukjd5kivkf/O4bChtj+Zk5mjygV0JXnu8/qKTgdKGgFb2c g==;
+IronPort-SDR: 
+ 4YNJctnRQh5CAun/n5enQjM7oquvPrOE3nkGFW+C5QqyuTdTfMuPC9ObswJdNtZwfXOZSP5M47
+ iBPtDJ5kPm5b5SYNOuUKAQ4oE8q8nZ2FxIJT8P6gv9OeHvvG5/KH6gbbwAscyn4o7xOmg7CKr0
+ jtoKxdwABk51IwBt/KNR8GAxr+yFheq2GxCKokyowKQ7NR10DGS87oI72liz3W2KnjsAvP2g2P
+ zQWDZ1IVj6vcGosiDETTFL931i534FP9dlQ6Qj75JQ8WbRCsmrMJkEqLHGdpQpPCOjvKI/c+F5
+ vTk=
+X-IronPort-AV: E=Sophos;i="5.77,421,1596470400"; d="scan'208";a="152152907"
+Received: from h199-255-45-15.hgst.com (HELO uls-op-cesaep02.wdc.com)
+ ([199.255.45.15])
+ by ob1.hgst.iphmx.com with ESMTP; 27 Oct 2020 07:03:24 +0800
+IronPort-SDR: 
+ rJJ/C8JZke0ThawF2PuVIjlUTsSDKbnB73s5tnzsxw/p0QX5zEUP6q14uvBl6dU4RoaituDCkX
+ n8z2GJl3XoFXVFB9aMQAACJSppt4l3VQkYp+g4VAc9icZSGARojUqMHmfIZ2GUtB9AoDv5tyj0
+ q2xQFgoW//H8fhLERqeSoNYn04PByFAqa6rpWjZc2LLmNIyjNFqnHY5Pt/73yZyqdvLYuwrNUC
+ olBFQjlaaXPsankbmZBSYN4NJX37cZjcNTKQ2CpkOEMM+CinKrHXsShQEx6J5FIysSY33/fvhQ
+ ypYbSqAvYJ5rr0SpmaSNGvdH
+Received: from uls-op-cesaip02.wdc.com ([10.248.3.37])
+ by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
+ 26 Oct 2020 15:48:35 -0700
+IronPort-SDR: 
+ 3Ij9aVJeppLgiNBWU3i6/X2lSE43Hhk1vz4ATQcxpjVCxcKhKrhmo10TYjsLHqnNpODk0WtNen
+ Jk3krrwCqPcL89Wud7ibOl0NwE8tiPXGwsV+VOBu7+XKdtCGk/wxHi26nHu4oq3DgH1BoSgD/M
+ yerK255lPug90GLaMc/tBilGkgTn2lyb38VH4Cd9zyBbfIniEjmkrpqFWHyXEDr+ZTPAFpzKMm
+ x+t6xCJh33r7HlknIojBzHJXHJZ+dw0Lj9+d9N04W6lg2IfrWFFKMUVNhjjU6p4QVZ/yqZzPjo
+ I/U=
+WDCIronportException: Internal
+Received: from 8223p12.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.110])
+ by uls-op-cesaip02.wdc.com with ESMTP; 26 Oct 2020 16:03:24 -0700
+From: Atish Patra <[email protected]>
+Subject: [PATCH v2 2/6] RISC-V: Initialize SBI early
+Date: Mon, 26 Oct 2020 16:02:50 -0700
+Message-Id: <[email protected]>
+X-Mailer: git-send-email 2.25.1
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+MIME-Version: 1.0
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
+X-CRM114-CacheID: sfid-20201026_190328_882682_FE50A426 
+X-CRM114-Status: GOOD (  12.31  )
+X-Spam-Score: -2.5 (--)
+X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary:
+ Content analysis details:   (-2.5 points)
+ pts rule name              description
+ ---- ----------------------
+ --------------------------------------------------
+ -2.3 RCVD_IN_DNSWL_MED      RBL: Sender listed at https://www.dnswl.org/,
+ medium trust [216.71.154.45 listed in list.dnswl.org]
+ -0.0 SPF_PASS               SPF: sender matches SPF record
+ -0.0 SPF_HELO_PASS          SPF: HELO matches SPF record
+ -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from
+ envelope-from domain
+ 0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
+ not necessarily
+ valid
+ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
+ -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from
+ author's domain
+X-BeenThere: [email protected]
+X-Mailman-Version: 2.1.29
+Precedence: list
+List-Id: <linux-riscv.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-riscv>,
+ <mailto:[email protected]?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-riscv/>
+List-Post: <mailto:[email protected]>
+List-Help: <mailto:[email protected]?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-riscv>,
+ <mailto:[email protected]?subject=subscribe>
+Cc: Albert Ou <[email protected]>, Kees Cook <[email protected]>,
+ Atish Patra <[email protected]>, Palmer Dabbelt <[email protected]>,
+ Zong Li <[email protected]>, Paul Walmsley <[email protected]>,
+ Greentime Hu <[email protected]>,
+ Andrew Morton <[email protected]>, Borislav Petkov <[email protected]>,
+ Michel Lespinasse <[email protected]>, Ard Biesheuvel <[email protected]>,
+ Mike Rapoport <[email protected]>
+Sender: "linux-riscv" <[email protected]>
+Errors-To: 
+ linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+
+Currently, SBI is initialized towards the end of arch setup. This prevents
+the set memory operations to be invoked earlier as it requires a full tlb
+flush.
+
+Initialize SBI as early as possible.
+
+Signed-off-by: Atish Patra <[email protected]>
+---
+ arch/riscv/kernel/setup.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index c424cc6dd833..7d6a04ae3929 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -89,6 +89,9 @@ void __init setup_arch(char **cmdline_p)
+               pr_err("No DTB found in kernel mappings\n");
+ #endif
++#if IS_ENABLED(CONFIG_RISCV_SBI)
++      sbi_init();
++#endif
+ #ifdef CONFIG_SWIOTLB
+       swiotlb_init(1);
+ #endif
+@@ -97,10 +100,6 @@ void __init setup_arch(char **cmdline_p)
+       kasan_init();
+ #endif
+-#if IS_ENABLED(CONFIG_RISCV_SBI)
+-      sbi_init();
+-#endif
+-
+ #ifdef CONFIG_SMP
+       setup_smp();
+ #endif
+
+From patchwork Mon Oct 26 23:02:51 2020
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Atish Patra <[email protected]>
+X-Patchwork-Id: 11858961
+Return-Path: 
+ <SRS0=2xBv=EB=lists.infradead.org=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@kernel.org>
+Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
+ [172.30.200.123])
+       by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E03AC697
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:50 +0000 (UTC)
+Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])
+       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+       (No client certificate requested)
+       by mail.kernel.org (Postfix) with ESMTPS id 9E26520780
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:50 +0000 (UTC)
+Authentication-Results: mail.kernel.org;
+       dkim=pass (2048-bit key) header.d=lists.infradead.org
[email protected] header.b="xYC8Kiam";
+       dkim=fail reason="signature verification failed" (2048-bit key)
+ header.d=wdc.com [email protected] header.b="IGlvH/He"
+DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9E26520780
+Authentication-Results: mail.kernel.org;
+ dmarc=fail (p=none dis=none) header.from=wdc.com
+Authentication-Results: mail.kernel.org;
+ spf=none
+ smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+       d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding:
+       Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
+       List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:
+       Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:
+       Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner;
+        bh=LLvjP6UUF+mN2NFHQ/w8mCLk894u/K6BT448BmhIzQ4=; b=xYC8KiamK0TAM3BY6T9hRqDcY
+       wB95sKdyXf2pP404bJ28keqaeUu59O9F12gNLiMlaDSXue16RKAyMMcv91I0NOptDVGZZsOEC5q5e
+       zF2nqG23tJt41TlS7tm/muslXV3klrPXdtdWyMWbNMn5yzKEUozzBfqDJ8/l4J5RI09A3eI3N2iHd
+       rKoweCxhcX3fgQwwHpcmS+lWa+zvBMr4TDQJpKG3IbWMJiMuc1HwIBfoIVJNE/S0CaH4aFslFFYWV
+       dNwCUzN/Y2iQdsb0gxaLHWXD8duKjsagaZj0Pubwqjvz8RjdfdzyRVOA9z7oOSvRWik1T2Q/doFJo
+       SsgbTSlNg==;
+Received: from localhost ([::1] helo=merlin.infradead.org)
+       by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
+       id 1kXBWY-0004J6-7l; Mon, 26 Oct 2020 23:03:34 +0000
+Received: from esa6.hgst.iphmx.com ([216.71.154.45])
+ by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
+ id 1kXBWT-0004FU-At
+ for [email protected]; Mon, 26 Oct 2020 23:03:30 +0000
+DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;
+ d=wdc.com; [email protected]; q=dns/txt; s=dkim.wdc.com;
+ t=1603753409; x=1635289409;
+ h=from:to:cc:subject:date:message-id:in-reply-to:
+ references:mime-version:content-transfer-encoding;
+ bh=rpPh1ri27/mV4Lq6GihXSvX59Cmyy4U53NNqLUWVVFg=;
+ b=IGlvH/HeG+LtRaV9YRN/VJ92x3cba2Xbt5IlgvhW6e+2kqLjoheazKa4
+ sW1k4tE7X3IClbO8GZrCFtEWXWaw9Z10Up+X6W49lJYIho/4KKBhLxPr2
+ +SCivaneKgpreYsC5Y8azdPya3U/n+E6tRaDB0Ng+h9KlEA4yLVQqFKuW
+ 5EV34s13VQxzRapuie7tGx1zyifO+6Q5LDaThml/ORK27gZ6YyBj0KtL6
+ GHRilGu/kY2wjPWoyrDcf4iHq4r9f1cDqC8idZ7XZfadax/iMkDzWSvxc
+ h3S4iEtcZS0Q5No2RWoGmOeTp52XEQEbzIpu4vPsmBPYFAqNY7Yvtel/0 w==;
+IronPort-SDR: 
+ upmBvvWfa2b8MmYHtzqu/BqkOl1YAZk4qwb3OWmRVkBz8Q8KNLXxZyJtY64PG/zF08rvh/1ZYP
+ eovKyM4rqIXsWEQeZSixcDrHE288ygjSxu/f+cXPkVfHxCPMN9tpkTqQgBIfsHe8Y0BHaCOc8/
+ H1knVJMdHIOeCfezAL5il2HBu/Vym8HSP4WMEa6m622CDWZS5oefiHvEmWwI65GZcaPoKObN4B
+ GJY7amcMkWsk0AGmo7dnQY0jxcqcEaGcsiKs8/iV8DsGM6MhpQ3Cgu/fZbCNR/A83dQTFTtHi9
+ w90=
+X-IronPort-AV: E=Sophos;i="5.77,421,1596470400"; d="scan'208";a="152152909"
+Received: from h199-255-45-15.hgst.com (HELO uls-op-cesaep02.wdc.com)
+ ([199.255.45.15])
+ by ob1.hgst.iphmx.com with ESMTP; 27 Oct 2020 07:03:24 +0800
+IronPort-SDR: 
+ LUcWKsGyxMhMy14zInqMDnSWvfLodcW3JZm43fD96zVbcHRGq/jkMyPQqmKawb3/LQH2EKNkH6
+ 68itcHUR8Xwwv5Vo/ao/+1tgsmQFo+r8v44sW7uMNA0ifzfNDS5w5hhrR4yQGlaxdrzwim8RBe
+ bIu9SGubi5/WfG5pmuBdctXpWGyr3ahj7O4Z/z3AzIvgp9VndisL9xZGGOrv1Pc82IALWjlrDX
+ wSvQpsoUO/jqBe5rRTNxSiGlVEu2VVYYkXXfaRrnHfol12PqMWCBve/MdFLrLdrbM2gHsPxczG
+ cRcC19KGip4DdpqeSITONqGB
+Received: from uls-op-cesaip02.wdc.com ([10.248.3.37])
+ by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
+ 26 Oct 2020 15:48:35 -0700
+IronPort-SDR: 
+ rriut/QXTurmMnXEV+/wkdh18jeVeIaUuF5OpX2DpiAjha4uQ2m8xvQ2+CYVPztIlri/dGG9Fx
+ sn4DjUGAMl9xld4i92d4WY0ChJTrDHbpMX+/nWTBiwVYjSvhmt8dWvvRfITcAe8aHbsJflfw31
+ X7bMdmMoJiKhs3WflXZAL19ePomMnN9ectpJbqja3ffpDKFD6UTBM+ZaybUNAdN7ZoQ4QlFV6l
+ 1tP01QkDPJPYD5O1x+9fKaT5edDaRfBK6oaYcjCM8Jv0VUQ424prp5C290AGcHQRTt2fhXTuUe
+ LPU=
+WDCIronportException: Internal
+Received: from 8223p12.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.110])
+ by uls-op-cesaip02.wdc.com with ESMTP; 26 Oct 2020 16:03:25 -0700
+From: Atish Patra <[email protected]>
+Subject: [PATCH v2 3/6] RISC-V: Enforce protections for kernel sections early
+Date: Mon, 26 Oct 2020 16:02:51 -0700
+Message-Id: <[email protected]>
+X-Mailer: git-send-email 2.25.1
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+MIME-Version: 1.0
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
+X-CRM114-CacheID: sfid-20201026_190329_555710_AE8BAB41 
+X-CRM114-Status: GOOD (  16.68  )
+X-Spam-Score: -2.5 (--)
+X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary:
+ Content analysis details:   (-2.5 points)
+ pts rule name              description
+ ---- ----------------------
+ --------------------------------------------------
+ -2.3 RCVD_IN_DNSWL_MED      RBL: Sender listed at https://www.dnswl.org/,
+ medium trust [216.71.154.45 listed in list.dnswl.org]
+ -0.0 SPF_PASS               SPF: sender matches SPF record
+ -0.0 SPF_HELO_PASS          SPF: HELO matches SPF record
+ -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from
+ envelope-from domain
+ 0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
+ not necessarily
+ valid
+ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
+ -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from
+ author's domain
+X-BeenThere: [email protected]
+X-Mailman-Version: 2.1.29
+Precedence: list
+List-Id: <linux-riscv.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-riscv>,
+ <mailto:[email protected]?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-riscv/>
+List-Post: <mailto:[email protected]>
+List-Help: <mailto:[email protected]?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-riscv>,
+ <mailto:[email protected]?subject=subscribe>
+Cc: Albert Ou <[email protected]>, Kees Cook <[email protected]>,
+ Atish Patra <[email protected]>, Palmer Dabbelt <[email protected]>,
+ Zong Li <[email protected]>, Paul Walmsley <[email protected]>,
+ Greentime Hu <[email protected]>,
+ Andrew Morton <[email protected]>, Borislav Petkov <[email protected]>,
+ Michel Lespinasse <[email protected]>, Ard Biesheuvel <[email protected]>,
+ Mike Rapoport <[email protected]>
+Sender: "linux-riscv" <[email protected]>
+Errors-To: 
+ linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+
+Currently, all memblocks are mapped with PAGE_KERNEL_EXEC and the strict
+permissions are only enforced after /init starts. This leaves the kernel
+vulnerable from possible buggy built-in modules.
+
+Apply permissions to individual sections as early as possible.
+
+Signed-off-by: Atish Patra <[email protected]>
+---
+ arch/riscv/include/asm/set_memory.h |  2 ++
+ arch/riscv/kernel/setup.c           |  2 ++
+ arch/riscv/mm/init.c                | 11 +++++++++--
+ 3 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
+index 4c5bae7ca01c..4cc3a4e2afd3 100644
+--- a/arch/riscv/include/asm/set_memory.h
++++ b/arch/riscv/include/asm/set_memory.h
+@@ -15,11 +15,13 @@ int set_memory_ro(unsigned long addr, int numpages);
+ int set_memory_rw(unsigned long addr, int numpages);
+ int set_memory_x(unsigned long addr, int numpages);
+ int set_memory_nx(unsigned long addr, int numpages);
++void protect_kernel_text_data(void);
+ #else
+ static inline int set_memory_ro(unsigned long addr, int numpages) { return 0; }
+ static inline int set_memory_rw(unsigned long addr, int numpages) { return 0; }
+ static inline int set_memory_x(unsigned long addr, int numpages) { return 0; }
+ static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
++static inline void protect_kernel_text_data(void) {};
+ #endif
+ int set_direct_map_invalid_noflush(struct page *page);
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index 7d6a04ae3929..b722c5bf892c 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -22,6 +22,7 @@
+ #include <asm/cpu_ops.h>
+ #include <asm/early_ioremap.h>
+ #include <asm/setup.h>
++#include <asm/set_memory.h>
+ #include <asm/sections.h>
+ #include <asm/sbi.h>
+ #include <asm/tlbflush.h>
+@@ -92,6 +93,7 @@ void __init setup_arch(char **cmdline_p)
+ #if IS_ENABLED(CONFIG_RISCV_SBI)
+       sbi_init();
+ #endif
++      protect_kernel_text_data();
+ #ifdef CONFIG_SWIOTLB
+       swiotlb_init(1);
+ #endif
+diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
+index ea933b789a88..5f196f8158d4 100644
+--- a/arch/riscv/mm/init.c
++++ b/arch/riscv/mm/init.c
+@@ -608,7 +608,7 @@ static inline void setup_vm_final(void)
+ #endif /* CONFIG_MMU */
+ #ifdef CONFIG_STRICT_KERNEL_RWX
+-void mark_rodata_ro(void)
++void protect_kernel_text_data(void)
+ {
+       unsigned long text_start = (unsigned long)_text;
+       unsigned long text_end = (unsigned long)_etext;
+@@ -617,9 +617,16 @@ void mark_rodata_ro(void)
+       unsigned long max_low = (unsigned long)(__va(PFN_PHYS(max_low_pfn)));
+       set_memory_ro(text_start, (text_end - text_start) >> PAGE_SHIFT);
+-      set_memory_ro(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT);
+       set_memory_nx(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT);
+       set_memory_nx(data_start, (max_low - data_start) >> PAGE_SHIFT);
++}
++
++void mark_rodata_ro(void)
++{
++      unsigned long rodata_start = (unsigned long)__start_rodata;
++      unsigned long data_start = (unsigned long)_data;
++
++      set_memory_ro(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT);
+       debug_checkwx();
+ }
+
+From patchwork Mon Oct 26 23:02:52 2020
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Atish Patra <[email protected]>
+X-Patchwork-Id: 11858957
+Return-Path: 
+ <SRS0=2xBv=EB=lists.infradead.org=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@kernel.org>
+Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
+ [172.30.200.123])
+       by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 02FB2697
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:38 +0000 (UTC)
+Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])
+       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+       (No client certificate requested)
+       by mail.kernel.org (Postfix) with ESMTPS id A5CAE20708
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:37 +0000 (UTC)
+Authentication-Results: mail.kernel.org;
+       dkim=pass (2048-bit key) header.d=lists.infradead.org
[email protected] header.b="X0mvMGeV";
+       dkim=fail reason="signature verification failed" (2048-bit key)
+ header.d=wdc.com [email protected] header.b="URJjjHRL"
+DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A5CAE20708
+Authentication-Results: mail.kernel.org;
+ dmarc=fail (p=none dis=none) header.from=wdc.com
+Authentication-Results: mail.kernel.org;
+ spf=none
+ smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+       d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding:
+       Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
+       List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:
+       Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:
+       Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner;
+        bh=K4aClDeRkTGSHM6Q3W9Eo4LL84FjDanPKTlxKTMYT2Y=; b=X0mvMGeVLhaZowgqwRF0Oy00W
+       Ro3DTyI28iAxiYsgQk7tOKFm6yRviAAo61fD4CxEw0kAPfJGvb2M95clzrlSGqoJejHLAMO33adTG
+       WzEJi2IwBvyKp0jyWLDkXQVeXiXA3fXO2Fdf40zfHtdT7iaNSu7soNx9r0g9RwD0XtCEe0iWXYDCy
+       VYekhBN4Fw2wC4eplt45X+fkkuE3+0tF41fE6RupWyY7GQUxknVYOAdyLwNWiBCZAHnTUQfmeiFwO
+       uJGDjjkmP20pBxhl9RJJaYWtr+NA0KJF8Lz94t4taxRSf6lJ+VMb32ZlXsCufd4x+h9vJjOLs35ef
+       rTVgylhTg==;
+Received: from localhost ([::1] helo=merlin.infradead.org)
+       by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
+       id 1kXBWZ-0004Jf-BW; Mon, 26 Oct 2020 23:03:35 +0000
+Received: from esa6.hgst.iphmx.com ([216.71.154.45])
+ by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
+ id 1kXBWT-0004G3-Pa
+ for [email protected]; Mon, 26 Oct 2020 23:03:30 +0000
+DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;
+ d=wdc.com; [email protected]; q=dns/txt; s=dkim.wdc.com;
+ t=1603753409; x=1635289409;
+ h=from:to:cc:subject:date:message-id:in-reply-to:
+ references:mime-version:content-transfer-encoding;
+ bh=BXRrXHASEZw+q5AEH6JXn4IG5K15cGG21TkLjxF25TY=;
+ b=URJjjHRLy8KmQfGlwj/WBLzTx4gHsfdUY8YsCSHPkMnU6I/nuYRNK6Ga
+ bFb3AWymzww5MFphpcpliqhWOgO7o5ggmA/PU54Lw0bMOPZCA+rynjwXo
+ 3S+KsjpSiGmSEq4q8fjZfKa2ErdI+J5zImh2i5Z1BSB+TnBH9I45lN6AP
+ EaBFxk2EkIUlP/6LoKRzLmneYZf5HJVBOKW7pRcr48ZJbX1nj95w972SA
+ FMJjzWioIkGlR3K+L4I9r0w+HJgzqTJHIS+DZnLF3LQWEoRJaPGrzgi1+
+ 80pshfjh4GMd0a9tcSQj/wSS17P3kJQ49XhDYEw61qpuk61DCWKl4XwXz A==;
+IronPort-SDR: 
+ QJtG6KvnHciweTON41ovUFASCfAMlNSE35baDpF5gZo80LXmQZYFWDxGQuqCn75wzVDRu9qTha
+ OVLwC/ghV4iZnQszcl4+JLFqr+xcefARIea4vQbe+lD+SBXej8h1etv6Sn/BGlDI4z218G7Ies
+ gd0hxcq0cfi9vgrb1zOrwHQ3BNrmw1FOuOApx6fEUAqtSs9ucezKvJJyeyy4ZszU3ckY0J9G4I
+ rZTBTHkd6wGgYuvcq+3IiRVQtXPfxkXXzpIkQfnrpQpkW9rJ6S8VzSZ3Su4XpXi4pT/fHmnS9y
+ bsg=
+X-IronPort-AV: E=Sophos;i="5.77,421,1596470400"; d="scan'208";a="152152912"
+Received: from h199-255-45-15.hgst.com (HELO uls-op-cesaep02.wdc.com)
+ ([199.255.45.15])
+ by ob1.hgst.iphmx.com with ESMTP; 27 Oct 2020 07:03:25 +0800
+IronPort-SDR: 
+ oz9iIUPO41YXmSe5lIg1FWt9CkcMbjZjMOQWhQN3Eu+YCvga4haAmUvFUzr/dCRkEcGOibXBfo
+ eM/I7m5DAnRSaeBbbs1FXY8Pmgw/I4NoLQ7/N5vBqPpbV6i20QzmfCUhUoleEfOnhjpM7M5NKq
+ GcrT+a43FwhHMDO3722Gh76G8hGmXJ/TQpNUrJLD6d6F2rao3fIRtOs4X6DwAsP3T4TKHwjDaT
+ 8s8oMKCFFJGKKBsgvzcRbxR8SYhbYY+IoKN5H3LmowqOqe/EqvmOOs8j862dIJx/SQsGrd5KNW
+ OJ+6YOzCjCoSwS47k5WebISH
+Received: from uls-op-cesaip02.wdc.com ([10.248.3.37])
+ by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
+ 26 Oct 2020 15:48:36 -0700
+IronPort-SDR: 
+ nc5o0tmxjzldhTvYndCLRMxDkR7DVB0Qk9xsu3nOE77OHiF++vF7uzB8dkN6FOL63EaQPgW6vg
+ 32Ps9rMRe6NjHIcHRp5jbx3Fek2i+PHg9bgM/sHhvhKm4Md89MmIf3oyZeyDszhniw1Vs1X25M
+ OlI0GIJkCqeeclxiq3vzCN9bZC15BwvNL5vcbuD1e7UMTO2rDsIYlNsUJfTOQ3loffL7C1jBXK
+ u9QjFn66K/qD/FBZsbsXUkxk7teb0SZUKmIJ96W9LgSUVq77xPrfBzq/ABINxmwTYilVzPaYOF
+ RYQ=
+WDCIronportException: Internal
+Received: from 8223p12.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.110])
+ by uls-op-cesaip02.wdc.com with ESMTP; 26 Oct 2020 16:03:25 -0700
+From: Atish Patra <[email protected]>
+Subject: [PATCH v2 4/6] RISC-V: Align the .init.text section
+Date: Mon, 26 Oct 2020 16:02:52 -0700
+Message-Id: <[email protected]>
+X-Mailer: git-send-email 2.25.1
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+MIME-Version: 1.0
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
+X-CRM114-CacheID: sfid-20201026_190330_004554_38C54A71 
+X-CRM114-Status: GOOD (  14.66  )
+X-Spam-Score: -2.5 (--)
+X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary:
+ Content analysis details:   (-2.5 points)
+ pts rule name              description
+ ---- ----------------------
+ --------------------------------------------------
+ -2.3 RCVD_IN_DNSWL_MED      RBL: Sender listed at https://www.dnswl.org/,
+ medium trust [216.71.154.45 listed in list.dnswl.org]
+ -0.0 SPF_PASS               SPF: sender matches SPF record
+ -0.0 SPF_HELO_PASS          SPF: HELO matches SPF record
+ -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from
+ envelope-from domain
+ 0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
+ not necessarily
+ valid
+ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
+ -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from
+ author's domain
+X-BeenThere: [email protected]
+X-Mailman-Version: 2.1.29
+Precedence: list
+List-Id: <linux-riscv.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-riscv>,
+ <mailto:[email protected]?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-riscv/>
+List-Post: <mailto:[email protected]>
+List-Help: <mailto:[email protected]?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-riscv>,
+ <mailto:[email protected]?subject=subscribe>
+Cc: Albert Ou <[email protected]>, Kees Cook <[email protected]>,
+ Atish Patra <[email protected]>, Palmer Dabbelt <[email protected]>,
+ Zong Li <[email protected]>, Paul Walmsley <[email protected]>,
+ Greentime Hu <[email protected]>,
+ Andrew Morton <[email protected]>, Borislav Petkov <[email protected]>,
+ Michel Lespinasse <[email protected]>, Ard Biesheuvel <[email protected]>,
+ Mike Rapoport <[email protected]>, Jim Wilson <[email protected]>
+Sender: "linux-riscv" <[email protected]>
+Errors-To: 
+ linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+
+In order to improve kernel text protection, we need separate .init.text/
+.init.data/.text in separate sections. However, RISC-V linker relaxation
+code is not aware of any alignment between sections. As a result, it may
+relax any RISCV_CALL relocations between sections to JAL without realizing
+that an inter section alignment may move the address farther. That may
+lead to a relocation truncated fit error. However, linker relaxation code
+is aware of the individual section alignments.
+
+The detailed discussion on this issue can be found here.
+https://github.com/riscv/riscv-gnu-toolchain/issues/738
+
+Keep the .init.text section aligned so that linker relaxation will take
+that as a hint while relaxing inter section calls.
+Here are the code size changes for each section because of this change.
+
+section         change in size (in bytes)
+  .head.text      +4
+  .text           +40
+  .init.text      +6530
+  .exit.text      +84
+
+The only significant increase in size happened for .init.text because
+all intra relocations also use 2MB alignment.
+
+Suggested-by: Jim Wilson <[email protected]>
+Signed-off-by: Atish Patra <[email protected]>
+---
+ arch/riscv/kernel/vmlinux.lds.S | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
+index 3ffbd6cbdb86..cacd7898ba7f 100644
+--- a/arch/riscv/kernel/vmlinux.lds.S
++++ b/arch/riscv/kernel/vmlinux.lds.S
+@@ -30,7 +30,13 @@ SECTIONS
+       . = ALIGN(PAGE_SIZE);
+       __init_begin = .;
+-      INIT_TEXT_SECTION(PAGE_SIZE)
++      __init_text_begin = .;
++      .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) ALIGN(SECTION_ALIGN) { \
++              _sinittext = .;                                         \
++              INIT_TEXT                                               \
++              _einittext = .;                                         \
++      }
++
+       . = ALIGN(8);
+       __soc_early_init_table : {
+               __soc_early_init_table_start = .;
+
+From patchwork Mon Oct 26 23:02:53 2020
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Atish Patra <[email protected]>
+X-Patchwork-Id: 11858965
+Return-Path: 
+ <SRS0=2xBv=EB=lists.infradead.org=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@kernel.org>
+Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
+ [172.30.200.123])
+       by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CEAA592C
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:51 +0000 (UTC)
+Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])
+       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+       (No client certificate requested)
+       by mail.kernel.org (Postfix) with ESMTPS id 984E420708
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:51 +0000 (UTC)
+Authentication-Results: mail.kernel.org;
+       dkim=pass (2048-bit key) header.d=lists.infradead.org
[email protected] header.b="tormdiD4";
+       dkim=fail reason="signature verification failed" (2048-bit key)
+ header.d=wdc.com [email protected] header.b="TINKrKy1"
+DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 984E420708
+Authentication-Results: mail.kernel.org;
+ dmarc=fail (p=none dis=none) header.from=wdc.com
+Authentication-Results: mail.kernel.org;
+ spf=none
+ smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+       d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding:
+       Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
+       List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:
+       Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:
+       Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner;
+        bh=oywE//1iXDBCyZMx/g2q51Gaz+jyhPQi+ZXU++cKzDw=; b=tormdiD4MrtCitBw7gI19k1yX
+       QoRXXSgmXFbYBSCnc/8iMMZfO9Pqq19sern8kdCtQfMSKoBHmyHpdRBDtf5HX8gbZAlyfrHivX0wm
+       zkpY7xzgZ0OHlaoFladcnJPJSojoMl+0gUeqV0bIlmBRFngaGP3j0Owje1pHFagZTsqi7g5+r3gd7
+       ISEhANtyxlX301o1K28/yYIdBq652NzL0QSBGqhs1vNVJ0OrPhxuBQNRXLbh/l6q144HKBmBLfklM
+       LOHVxqzca6fYMg7AA4XMaO8Pr3ov3xDYHtqmtjCKxEsovZf2SC8BX2f1MoGNWIVVI8nitiQVuE4Vv
+       pVqjtr42Q==;
+Received: from localhost ([::1] helo=merlin.infradead.org)
+       by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
+       id 1kXBWa-0004KB-4Y; Mon, 26 Oct 2020 23:03:36 +0000
+Received: from esa6.hgst.iphmx.com ([216.71.154.45])
+ by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
+ id 1kXBWU-0004H6-Er
+ for [email protected]; Mon, 26 Oct 2020 23:03:32 +0000
+DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;
+ d=wdc.com; [email protected]; q=dns/txt; s=dkim.wdc.com;
+ t=1603753410; x=1635289410;
+ h=from:to:cc:subject:date:message-id:in-reply-to:
+ references:mime-version:content-transfer-encoding;
+ bh=iPUv/PUCUw9poafNmoCWlV7tTLouxKtDuq6y3HZQDjc=;
+ b=TINKrKy1j7UvdoiLMTeHUQ/tMBzQuLtdTEH/fWFrgO6GS+tfZcEZ8JHu
+ Cl2FOprdMaFJ02crvI0iY3uM/H++1sZNJlYKC81UfIWEROxDKgp0pdDI4
+ I6QBWtOpDcvdfYolhms30rt3tqELl2JP1csmhLb78lJbIgcwbZkAu0D0M
+ 0hblQSEchmVhvcSFc3cket/LBv6gEqdvViw+5WKkCsT5sKuBEmjZ5N8Mo
+ 6BaHAosKbWj4CtithfGsVHfyhVkX0czQFMHbgAWBkfUNdLyj+svAGcBaF
+ /L1NRhojdJC+/A7+0TRv7wF65E3xRBRVb1jPZdwTp024gNcjRa6N//K/Z Q==;
+IronPort-SDR: 
+ CsILWxdqzjyqU2FwYLjPK+jZdSUoiFWfCLCK+zomYaBEEBdHYGDeaNr7VvK9zze/GpA6btdait
+ F1JdnNzUJfawMwtwWVtbM80tYohxjLjTkce7af85Ed+TPHgSzENYmGcC6ODWnQ8/RUXMWmX19Z
+ sHcoBfNu6L8r42mWepVbU0Iwl9uNPRG3jHzlJ8w8gSj+DWbjwfR8WWgSnONL6BjmJA88gqBS1q
+ M/Bwcdr2OMD5ks7Gp2TfMj/7ykp/9agc8yDoViH+z7+v/8XjJohC59tKu6NIkStZgO3jdA79cN
+ fMM=
+X-IronPort-AV: E=Sophos;i="5.77,421,1596470400"; d="scan'208";a="152152914"
+Received: from h199-255-45-15.hgst.com (HELO uls-op-cesaep02.wdc.com)
+ ([199.255.45.15])
+ by ob1.hgst.iphmx.com with ESMTP; 27 Oct 2020 07:03:25 +0800
+IronPort-SDR: 
+ 3u2+d01NfPNLyJepvSU9gqztIqwBrsJhqYka2NFJ9fpUx5JTnhNRJABKy6ymocr+VACsvFbW0b
+ 6IrLWS8PlkhTEoMNENQpQZY/Dg3kkiMoplXxpCudshL4S7UCtXcY4cloLua+RDS0oHtpSFbVzU
+ Y+X7uqSvXZrCUQOkIV5UCjT224FgPTw2OAhCeEAyTTPpgudiMZjzE9YrQNgG4A+BLF2tUVsuBR
+ BImVlogyHkN9O4t2kyVGoYGTNHNi5bqZhvUwAY1RNzRvcA+vQD0w7T2SoaguxxMPOwTACcF/d3
+ Z+sMS87NekBWHXBRqTecgl0W
+Received: from uls-op-cesaip02.wdc.com ([10.248.3.37])
+ by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
+ 26 Oct 2020 15:48:36 -0700
+IronPort-SDR: 
+ ey/+IpD7q+PZFkntsCEL5kRkGMghTUQ92D4aSwCY0hicm+MUionuNfl6dBlx3Gh91OzXB6oKuq
+ FIrt8TuWoscWKGL5FZGzu4oj0jqXFxfqAjrHGnQLM0h4LD3Er1WjUcaV2wAoJI00VcLs3/mXyS
+ /Prep/fH4qGRAmABa+qjbQbvBrGkfszca5mZUfa2SOTn3Nb0sYaGlEKe6wEY2Vo3ZSHVRn7fll
+ 21NHZZZaa3XJN3YV/d0MMiVrPYSdIbcOhg7XGcbFSgMmsM0NEy7Y5E1i8priVbwPj6Z7qmOgj+
+ tBg=
+WDCIronportException: Internal
+Received: from 8223p12.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.110])
+ by uls-op-cesaip02.wdc.com with ESMTP; 26 Oct 2020 16:03:26 -0700
+From: Atish Patra <[email protected]>
+Subject: [PATCH v2 5/6] RISC-V: Protect .init.text & .init.data
+Date: Mon, 26 Oct 2020 16:02:53 -0700
+Message-Id: <[email protected]>
+X-Mailer: git-send-email 2.25.1
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+MIME-Version: 1.0
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
+X-CRM114-CacheID: sfid-20201026_190330_837440_84C45BC2 
+X-CRM114-Status: GOOD (  19.16  )
+X-Spam-Score: -2.5 (--)
+X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary:
+ Content analysis details:   (-2.5 points)
+ pts rule name              description
+ ---- ----------------------
+ --------------------------------------------------
+ -2.3 RCVD_IN_DNSWL_MED      RBL: Sender listed at https://www.dnswl.org/,
+ medium trust [216.71.154.45 listed in list.dnswl.org]
+ -0.0 SPF_PASS               SPF: sender matches SPF record
+ -0.0 SPF_HELO_PASS          SPF: HELO matches SPF record
+ -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from
+ envelope-from domain
+ 0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
+ not necessarily
+ valid
+ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
+ -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from
+ author's domain
+X-BeenThere: [email protected]
+X-Mailman-Version: 2.1.29
+Precedence: list
+List-Id: <linux-riscv.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-riscv>,
+ <mailto:[email protected]?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-riscv/>
+List-Post: <mailto:[email protected]>
+List-Help: <mailto:[email protected]?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-riscv>,
+ <mailto:[email protected]?subject=subscribe>
+Cc: Albert Ou <[email protected]>, Kees Cook <[email protected]>,
+ Atish Patra <[email protected]>, Palmer Dabbelt <[email protected]>,
+ Zong Li <[email protected]>, Paul Walmsley <[email protected]>,
+ Greentime Hu <[email protected]>,
+ Andrew Morton <[email protected]>, Borislav Petkov <[email protected]>,
+ Michel Lespinasse <[email protected]>, Ard Biesheuvel <[email protected]>,
+ Mike Rapoport <[email protected]>
+Sender: "linux-riscv" <[email protected]>
+Errors-To: 
+ linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+
+Currently, .init.text & .init.data are intermixed which makes it impossible
+apply different permissions to them. .init.data shouldn't need exec
+permissions while .init.text shouldn't have write permission.
+
+Keep them in separate sections so that different permissions are applied to
+each section. This improves the kernel protection under
+CONFIG_STRICT_KERNEL_RWX. We also need to restore the permissions for the
+entire _init section after it is freed so that those pages can be used for
+other purpose.
+
+Signed-off-by: Atish Patra <[email protected]>
+---
+ arch/riscv/include/asm/sections.h   |  2 ++
+ arch/riscv/include/asm/set_memory.h |  2 ++
+ arch/riscv/kernel/setup.c           |  9 +++++
+ arch/riscv/kernel/vmlinux.lds.S     | 51 ++++++++++++++++-------------
+ arch/riscv/mm/init.c                |  8 ++++-
+ arch/riscv/mm/pageattr.c            |  6 ++++
+ 6 files changed, 54 insertions(+), 24 deletions(-)
+
+diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h
+index 3a9971b1210f..1595c5b60cfd 100644
+--- a/arch/riscv/include/asm/sections.h
++++ b/arch/riscv/include/asm/sections.h
+@@ -9,5 +9,7 @@
+ extern char _start[];
+ extern char _start_kernel[];
++extern char __init_data_begin[], __init_data_end[];
++extern char __init_text_begin[], __init_text_end[];
+ #endif /* __ASM_SECTIONS_H */
+diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
+index 4cc3a4e2afd3..913429c9c1ae 100644
+--- a/arch/riscv/include/asm/set_memory.h
++++ b/arch/riscv/include/asm/set_memory.h
+@@ -15,6 +15,7 @@ int set_memory_ro(unsigned long addr, int numpages);
+ int set_memory_rw(unsigned long addr, int numpages);
+ int set_memory_x(unsigned long addr, int numpages);
+ int set_memory_nx(unsigned long addr, int numpages);
++int set_memory_default(unsigned long addr, int numpages);
+ void protect_kernel_text_data(void);
+ #else
+ static inline int set_memory_ro(unsigned long addr, int numpages) { return 0; }
+@@ -22,6 +23,7 @@ static inline int set_memory_rw(unsigned long addr, int numpages) { return 0; }
+ static inline int set_memory_x(unsigned long addr, int numpages) { return 0; }
+ static inline int set_memory_nx(unsigned long addr, int numpages) { return 0; }
+ static inline void protect_kernel_text_data(void) {};
++static inline int set_memory_default(unsigned long addr, int numpages) { return 0; }
+ #endif
+ int set_direct_map_invalid_noflush(struct page *page);
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
+index b722c5bf892c..abfbdc8cfef3 100644
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -123,3 +123,12 @@ static int __init topology_init(void)
+       return 0;
+ }
+ subsys_initcall(topology_init);
++
++void free_initmem(void)
++{
++      unsigned long init_begin = (unsigned long)__init_begin;
++      unsigned long init_end = (unsigned long)__init_end;
++
++      set_memory_default(init_begin, (init_end - init_begin) >> PAGE_SHIFT);
++      free_initmem_default(POISON_FREE_INITMEM);
++}
+diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
+index cacd7898ba7f..0a1874e48e8a 100644
+--- a/arch/riscv/kernel/vmlinux.lds.S
++++ b/arch/riscv/kernel/vmlinux.lds.S
+@@ -29,6 +29,26 @@ SECTIONS
+       HEAD_TEXT_SECTION
+       . = ALIGN(PAGE_SIZE);
++      .text : {
++              _text = .;
++              _stext = .;
++              TEXT_TEXT
++              SCHED_TEXT
++              CPUIDLE_TEXT
++              LOCK_TEXT
++              KPROBES_TEXT
++              ENTRY_TEXT
++              IRQENTRY_TEXT
++              SOFTIRQENTRY_TEXT
++              *(.fixup)
++              _etext = .;
++      }
++
++#ifdef CONFIG_EFI
++      . = ALIGN(PECOFF_SECTION_ALIGNMENT);
++      __pecoff_text_end = .;
++#endif
++      . = ALIGN(SECTION_ALIGN);
+       __init_begin = .;
+       __init_text_begin = .;
+       .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) ALIGN(SECTION_ALIGN) { \
+@@ -53,35 +73,20 @@ SECTIONS
+       {
+               EXIT_TEXT
+       }
++
++      __init_text_end = .;
++      . = ALIGN(SECTION_ALIGN);
++      /* Start of init data section */
++      __init_data_begin = .;
++      INIT_DATA_SECTION(16)
+       .exit.data :
+       {
+               EXIT_DATA
+       }
+       PERCPU_SECTION(L1_CACHE_BYTES)
+-      __init_end = .;
+-      . = ALIGN(SECTION_ALIGN);
+-      .text : {
+-              _text = .;
+-              _stext = .;
+-              TEXT_TEXT
+-              SCHED_TEXT
+-              CPUIDLE_TEXT
+-              LOCK_TEXT
+-              KPROBES_TEXT
+-              ENTRY_TEXT
+-              IRQENTRY_TEXT
+-              SOFTIRQENTRY_TEXT
+-              *(.fixup)
+-              _etext = .;
+-      }
+-
+-#ifdef CONFIG_EFI
+-      . = ALIGN(PECOFF_SECTION_ALIGNMENT);
+-      __pecoff_text_end = .;
+-#endif
+-
+-      INIT_DATA_SECTION(16)
++      __init_data_end = .;
++      __init_end = .;
+       /* Start of data section */
+       _sdata = .;
+diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
+index 5f196f8158d4..1bb3821d81d5 100644
+--- a/arch/riscv/mm/init.c
++++ b/arch/riscv/mm/init.c
+@@ -610,13 +610,19 @@ static inline void setup_vm_final(void)
+ #ifdef CONFIG_STRICT_KERNEL_RWX
+ void protect_kernel_text_data(void)
+ {
+-      unsigned long text_start = (unsigned long)_text;
++      unsigned long text_start = (unsigned long)_start;
+       unsigned long text_end = (unsigned long)_etext;
++      unsigned long init_text_start = (unsigned long)__init_text_begin;
++      unsigned long init_text_end = (unsigned long)__init_text_end;
++      unsigned long init_data_start = (unsigned long)__init_data_begin;
++      unsigned long init_data_end = (unsigned long)__init_data_end;
+       unsigned long rodata_start = (unsigned long)__start_rodata;
+       unsigned long data_start = (unsigned long)_data;
+       unsigned long max_low = (unsigned long)(__va(PFN_PHYS(max_low_pfn)));
++      set_memory_ro(init_text_start, (init_text_end - init_text_start) >> PAGE_SHIFT);
+       set_memory_ro(text_start, (text_end - text_start) >> PAGE_SHIFT);
++      set_memory_nx(init_data_start, (init_data_end - init_data_start) >> PAGE_SHIFT);
+       set_memory_nx(rodata_start, (data_start - rodata_start) >> PAGE_SHIFT);
+       set_memory_nx(data_start, (max_low - data_start) >> PAGE_SHIFT);
+ }
+diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
+index 19fecb362d81..04f3fc16aa9c 100644
+--- a/arch/riscv/mm/pageattr.c
++++ b/arch/riscv/mm/pageattr.c
+@@ -128,6 +128,12 @@ static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask,
+       return ret;
+ }
++int set_memory_default(unsigned long addr, int numpages)
++{
++      return __set_memory(addr, numpages, __pgprot(_PAGE_KERNEL),
++                          __pgprot(_PAGE_EXEC));
++}
++
+ int set_memory_ro(unsigned long addr, int numpages)
+ {
+       return __set_memory(addr, numpages, __pgprot(_PAGE_READ),
+
+From patchwork Mon Oct 26 23:02:54 2020
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Atish Patra <[email protected]>
+X-Patchwork-Id: 11858959
+Return-Path: 
+ <SRS0=2xBv=EB=lists.infradead.org=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@kernel.org>
+Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
+ [172.30.200.123])
+       by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CA26E697
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:38 +0000 (UTC)
+Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])
+       (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
+       (No client certificate requested)
+       by mail.kernel.org (Postfix) with ESMTPS id 738AA20708
+       for <[email protected]>;
+ Mon, 26 Oct 2020 23:03:38 +0000 (UTC)
+Authentication-Results: mail.kernel.org;
+       dkim=pass (2048-bit key) header.d=lists.infradead.org
[email protected] header.b="0aEtXH3V";
+       dkim=fail reason="signature verification failed" (2048-bit key)
+ header.d=wdc.com [email protected] header.b="P7imCxg+"
+DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 738AA20708
+Authentication-Results: mail.kernel.org;
+ dmarc=fail (p=none dis=none) header.from=wdc.com
+Authentication-Results: mail.kernel.org;
+ spf=none
+ smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
+       d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding:
+       Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
+       List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date:
+       Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:
+       Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner;
+        bh=fXVyYS2t9va4G58pC03VA4d9ZBiDIWidqr+XRUr8uOM=; b=0aEtXH3VAgmEBQKzqXhgabfRE
+       V2/Yqid/iy8LtCw6WoK+IVDI0gOLkgqLP2ChmPXt/RfAxTA+A3xxvMKazG/ygUYBu1vPG3HUQz/de
+       bcSLaUFmCBulOt7OZR90WhPVW0D8wAdA/xmh6FX8AwRnN6My2vAB54m9VcZ00hokRdPWtSF8kzQNY
+       2H/DkxGNMtg8XXR/w/9+i13bwLOrTP3sj5oJxGkMjrzESGKfJU65gkd8/EuLSbTq+If+fmG5nBq52
+       BXgpz9qxiE1Fju1w5btn8AE1Y97YALESFOPRdOm7uZIEmXlm/OayEkYwZMCQZMW6MyUxcagLM+Sib
+       /7oyW5gOg==;
+Received: from localhost ([::1] helo=merlin.infradead.org)
+       by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
+       id 1kXBWa-0004Ka-Lz; Mon, 26 Oct 2020 23:03:36 +0000
+Received: from esa6.hgst.iphmx.com ([216.71.154.45])
+ by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
+ id 1kXBWV-0004FU-0j
+ for [email protected]; Mon, 26 Oct 2020 23:03:33 +0000
+DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;
+ d=wdc.com; [email protected]; q=dns/txt; s=dkim.wdc.com;
+ t=1603753411; x=1635289411;
+ h=from:to:cc:subject:date:message-id:in-reply-to:
+ references:mime-version:content-transfer-encoding;
+ bh=ySjO0ROtxsgulKuASejfUOnFI2wPdTDF4D2jhNgjeiY=;
+ b=P7imCxg+9oBiw8aBtRk+L6Zz8THT17cCHNj7XjaKdrZmC2+KBGDAvFWO
+ 5V/fRypY/s9wxrudt5RjyPOp87Ob7g+gSuRQ9v2Ickh6Dl0cg/bmflozp
+ nlSCPgJUH0uCTqgckGDx9Kg+EdFOUmnUNTFlItmvIOJIYmaDjqe58y+HC
+ ej8tpDrRJdN3oAN6uc5hYyO5kMWuiFVJibm/bKr+5oJgimJ9DsG2bA4f+
+ jKvLQRQCI5MidMbWd1/oj0QSwCNghHSUahIwFeQjZjwy0Do2Wn7AyjwHz
+ Pimf0/AVzQYqo8BacBX5cUK7OXAkBRsTu6BUIu/h6VPuvV/t7ZwQp9z8R Q==;
+IronPort-SDR: 
+ PT0RiwbgnnB9A6wwG+sCRTPlsjfPISJwc8M+pA4S6cjb6g/gX+CxZDF5bjLlqnkTWQiYX2pzM7
+ oy40QCbgnrOmeGDuoRhTSdYyZ4yxn/8MGgWB7Mo7ASVn/rRoeSGkcUjDsDZ1i3vGEcW3It9BJJ
+ xoamU0sMqFCB/KXU9pOVY7ZWo9e/fTAAl59xrdy9nnLDHTSmOxqnxIugOPx36qVNglEGPVoRp3
+ PcLgXDjtPzOvLJp0XI9G/dGNZ0zs2mZyt2jKX6+XcufPL6perAaPdrPzUAa5YOsoImLBpZsT5d
+ ogU=
+X-IronPort-AV: E=Sophos;i="5.77,421,1596470400"; d="scan'208";a="152152918"
+Received: from h199-255-45-15.hgst.com (HELO uls-op-cesaep02.wdc.com)
+ ([199.255.45.15])
+ by ob1.hgst.iphmx.com with ESMTP; 27 Oct 2020 07:03:26 +0800
+IronPort-SDR: 
+ ZbbpiJxajYyqZgq/FisScuJrRZsjrqlKTSHhQnmaz5I2bxr8Q/Q13rQQ+52de0CtGTdgnVXive
+ f7e/l3eRWTzARcycqNkGjCUHbg25Lr5CkXXYOeafY1cnnz3cLPy1D53MkmPQ9RDajUYFYvhxJq
+ /LDSLVmZiWjquoJBfjk4NUyfaczNQ7Ttnee0ZhyENiPr0n9B2fhJa07FPYS9R1t7ReBR/TZydI
+ UKxgygabdrP3YNvguDZCWoy6tI9mvzSWi0cMxM5SA6Uv9Qq3W1TqnD7rxSnMUDViRrpoS/F7gU
+ WcKtaoA+nEMc+wxCU8YiHZdf
+Received: from uls-op-cesaip02.wdc.com ([10.248.3.37])
+ by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;
+ 26 Oct 2020 15:48:37 -0700
+IronPort-SDR: 
+ ZIK6pBlHow57hiV8D7ho7M4zJo6JZXmXc68rJru36zg2zepGnFLYfk0rMM063VRf2xcII5Vlm6
+ k22KEvndaC4UkvZdmPy7PsVD3hmZnU/emkdOcOh9ZfogHtkgStZuny0fTzU6a6UKM//grYrAnu
+ g2DxU2TKr9SHf2reP/hg81Iij6L7dTzG1xKtuyPaToFyfsS8Ud3UlSpzrBY8RZEc9935R2b6nJ
+ OLPJbTTgczk/7d57STXaSaoAVH2omOc9iwiC6afLAGgmwM3l5XwA5ZkyLRltkHkbZ7/aPO0BEN
+ FHg=
+WDCIronportException: Internal
+Received: from 8223p12.ad.shared (HELO jedi-01.hgst.com) ([10.86.60.110])
+ by uls-op-cesaip02.wdc.com with ESMTP; 26 Oct 2020 16:03:26 -0700
+From: Atish Patra <[email protected]>
+Subject: [PATCH v2 6/6] RISC-V: Move dynamic relocation section under __init
+Date: Mon, 26 Oct 2020 16:02:54 -0700
+Message-Id: <[email protected]>
+X-Mailer: git-send-email 2.25.1
+In-Reply-To: <[email protected]>
+References: <[email protected]>
+MIME-Version: 1.0
+X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 
+X-CRM114-CacheID: sfid-20201026_190331_505428_453BB9CC 
+X-CRM114-Status: GOOD (  12.45  )
+X-Spam-Score: -2.5 (--)
+X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary:
+ Content analysis details:   (-2.5 points)
+ pts rule name              description
+ ---- ----------------------
+ --------------------------------------------------
+ -2.3 RCVD_IN_DNSWL_MED      RBL: Sender listed at https://www.dnswl.org/,
+ medium trust [216.71.154.45 listed in list.dnswl.org]
+ -0.0 SPF_PASS               SPF: sender matches SPF record
+ -0.0 SPF_HELO_PASS          SPF: HELO matches SPF record
+ -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from
+ envelope-from domain
+ 0.1 DKIM_SIGNED            Message has a DKIM or DK signature,
+ not necessarily
+ valid
+ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
+ -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from
+ author's domain
+X-BeenThere: [email protected]
+X-Mailman-Version: 2.1.29
+Precedence: list
+List-Id: <linux-riscv.lists.infradead.org>
+List-Unsubscribe: <http://lists.infradead.org/mailman/options/linux-riscv>,
+ <mailto:[email protected]?subject=unsubscribe>
+List-Archive: <http://lists.infradead.org/pipermail/linux-riscv/>
+List-Post: <mailto:[email protected]>
+List-Help: <mailto:[email protected]?subject=help>
+List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-riscv>,
+ <mailto:[email protected]?subject=subscribe>
+Cc: Albert Ou <[email protected]>, Kees Cook <[email protected]>,
+ Atish Patra <[email protected]>, Palmer Dabbelt <[email protected]>,
+ Zong Li <[email protected]>, Paul Walmsley <[email protected]>,
+ Greentime Hu <[email protected]>,
+ Andrew Morton <[email protected]>, Borislav Petkov <[email protected]>,
+ Michel Lespinasse <[email protected]>, Ard Biesheuvel <[email protected]>,
+ Mike Rapoport <[email protected]>
+Sender: "linux-riscv" <[email protected]>
+Errors-To: 
+ linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org
+
+Dynamic relocation section are only required during boot. Those sections
+can be freed after init. Thus, it can be moved to __init section.
+
+Signed-off-by: Atish Patra <[email protected]>
+---
+ arch/riscv/kernel/vmlinux.lds.S | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
+index 0a1874e48e8a..64c5e74008b7 100644
+--- a/arch/riscv/kernel/vmlinux.lds.S
++++ b/arch/riscv/kernel/vmlinux.lds.S
+@@ -85,6 +85,10 @@ SECTIONS
+       }
+       PERCPU_SECTION(L1_CACHE_BYTES)
++      .rel.dyn : {
++              *(.rel.dyn*)
++      }
++
+       __init_data_end = .;
+       __init_end = .;
+@@ -116,10 +120,6 @@ SECTIONS
+       BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0)
+-      .rel.dyn : {
+-              *(.rel.dyn*)
+-      }
+-
+ #ifdef CONFIG_EFI
+       . = ALIGN(PECOFF_SECTION_ALIGNMENT);
+       __pecoff_data_virt_size = ABSOLUTE(. - __pecoff_text_end);
diff --git a/target/linux/hifiveu/patches-5.10/0004-riscv-dts-add-initial-support-for-the-SiFive-FU740-C.patch b/target/linux/hifiveu/patches-5.10/0004-riscv-dts-add-initial-support-for-the-SiFive-FU740-C.patch
new file mode 100644 (file)
index 0000000..b73e41a
--- /dev/null
@@ -0,0 +1,320 @@
+From 621dd9aa125dbd597ac51a0b2a466ef49562d561 Mon Sep 17 00:00:00 2001
+From: Yash Shah <[email protected]>
+Date: Tue, 8 Dec 2020 10:25:39 +0530
+Subject: [PATCH 04/28] riscv: dts: add initial support for the SiFive
+ FU740-C000 SoC
+
+Add initial support for the SiFive FU540-C000 SoC. FU740-C000 is built
+around the SiFIve U7 Core Complex and a TileLink interconnect.
+
+This file is expected to grow as more device drivers are added to the
+kernel.
+
+Signed-off-by: Yash Shah <[email protected]>
+---
+ arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 293 +++++++++++++++++++++++++++++
+ 1 file changed, 293 insertions(+)
+ create mode 100644 arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+
+diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+new file mode 100644
+index 00000000..eeb4f8c3
+--- /dev/null
++++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+@@ -0,0 +1,293 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/* Copyright (c) 2020 SiFive, Inc */
++
++/dts-v1/;
++
++#include <dt-bindings/clock/sifive-fu740-prci.h>
++
++/ {
++      #address-cells = <2>;
++      #size-cells = <2>;
++      compatible = "sifive,fu740-c000", "sifive,fu740";
++
++      aliases {
++              serial0 = &uart0;
++              serial1 = &uart1;
++              ethernet0 = &eth0;
++      };
++
++      chosen {
++      };
++
++      cpus {
++              #address-cells = <1>;
++              #size-cells = <0>;
++              cpu0: cpu@0 {
++                      compatible = "sifive,bullet0", "riscv";
++                      device_type = "cpu";
++                      i-cache-block-size = <64>;
++                      i-cache-sets = <128>;
++                      i-cache-size = <16384>;
++                      next-level-cache = <&ccache>;
++                      reg = <0x0>;
++                      riscv,isa = "rv64imac";
++                      status = "disabled";
++                      cpu0_intc: interrupt-controller {
++                              #interrupt-cells = <1>;
++                              compatible = "riscv,cpu-intc";
++                              interrupt-controller;
++                      };
++              };
++              cpu1: cpu@1 {
++                      compatible = "sifive,bullet0", "riscv";
++                      d-cache-block-size = <64>;
++                      d-cache-sets = <64>;
++                      d-cache-size = <32768>;
++                      d-tlb-sets = <1>;
++                      d-tlb-size = <40>;
++                      device_type = "cpu";
++                      i-cache-block-size = <64>;
++                      i-cache-sets = <128>;
++                      i-cache-size = <32768>;
++                      i-tlb-sets = <1>;
++                      i-tlb-size = <40>;
++                      mmu-type = "riscv,sv39";
++                      next-level-cache = <&ccache>;
++                      reg = <0x1>;
++                      riscv,isa = "rv64imafdc";
++                      tlb-split;
++                      cpu1_intc: interrupt-controller {
++                              #interrupt-cells = <1>;
++                              compatible = "riscv,cpu-intc";
++                              interrupt-controller;
++                      };
++              };
++              cpu2: cpu@2 {
++                      compatible = "sifive,bullet0", "riscv";
++                      d-cache-block-size = <64>;
++                      d-cache-sets = <64>;
++                      d-cache-size = <32768>;
++                      d-tlb-sets = <1>;
++                      d-tlb-size = <40>;
++                      device_type = "cpu";
++                      i-cache-block-size = <64>;
++                      i-cache-sets = <128>;
++                      i-cache-size = <32768>;
++                      i-tlb-sets = <1>;
++                      i-tlb-size = <40>;
++                      mmu-type = "riscv,sv39";
++                      next-level-cache = <&ccache>;
++                      reg = <0x2>;
++                      riscv,isa = "rv64imafdc";
++                      tlb-split;
++                      cpu2_intc: interrupt-controller {
++                              #interrupt-cells = <1>;
++                              compatible = "riscv,cpu-intc";
++                              interrupt-controller;
++                      };
++              };
++              cpu3: cpu@3 {
++                      compatible = "sifive,bullet0", "riscv";
++                      d-cache-block-size = <64>;
++                      d-cache-sets = <64>;
++                      d-cache-size = <32768>;
++                      d-tlb-sets = <1>;
++                      d-tlb-size = <40>;
++                      device_type = "cpu";
++                      i-cache-block-size = <64>;
++                      i-cache-sets = <128>;
++                      i-cache-size = <32768>;
++                      i-tlb-sets = <1>;
++                      i-tlb-size = <40>;
++                      mmu-type = "riscv,sv39";
++                      next-level-cache = <&ccache>;
++                      reg = <0x3>;
++                      riscv,isa = "rv64imafdc";
++                      tlb-split;
++                      cpu3_intc: interrupt-controller {
++                              #interrupt-cells = <1>;
++                              compatible = "riscv,cpu-intc";
++                              interrupt-controller;
++                      };
++              };
++              cpu4: cpu@4 {
++                      compatible = "sifive,bullet0", "riscv";
++                      d-cache-block-size = <64>;
++                      d-cache-sets = <64>;
++                      d-cache-size = <32768>;
++                      d-tlb-sets = <1>;
++                      d-tlb-size = <40>;
++                      device_type = "cpu";
++                      i-cache-block-size = <64>;
++                      i-cache-sets = <128>;
++                      i-cache-size = <32768>;
++                      i-tlb-sets = <1>;
++                      i-tlb-size = <40>;
++                      mmu-type = "riscv,sv39";
++                      next-level-cache = <&ccache>;
++                      reg = <0x4>;
++                      riscv,isa = "rv64imafdc";
++                      tlb-split;
++                      cpu4_intc: interrupt-controller {
++                              #interrupt-cells = <1>;
++                              compatible = "riscv,cpu-intc";
++                              interrupt-controller;
++                      };
++              };
++      };
++      soc {
++              #address-cells = <2>;
++              #size-cells = <2>;
++              compatible = "simple-bus";
++              ranges;
++              plic0: interrupt-controller@c000000 {
++                      #interrupt-cells = <1>;
++                      #address-cells = <0>;
++                      compatible = "sifive,fu540-c000-plic", "sifive,plic-1.0.0";
++                      reg = <0x0 0xc000000 0x0 0x4000000>;
++                      riscv,ndev = <69>;
++                      interrupt-controller;
++                      interrupts-extended = <
++                              &cpu0_intc 0xffffffff
++                              &cpu1_intc 0xffffffff &cpu1_intc 9
++                              &cpu2_intc 0xffffffff &cpu2_intc 9
++                              &cpu3_intc 0xffffffff &cpu3_intc 9
++                              &cpu4_intc 0xffffffff &cpu4_intc 9>;
++              };
++              prci: clock-controller@10000000 {
++                      compatible = "sifive,fu740-c000-prci";
++                      reg = <0x0 0x10000000 0x0 0x1000>;
++                      clocks = <&hfclk>, <&rtcclk>;
++                      #clock-cells = <1>;
++              };
++              uart0: serial@10010000 {
++                      compatible = "sifive,fu740-c000-uart", "sifive,uart0";
++                      reg = <0x0 0x10010000 0x0 0x1000>;
++                      interrupt-parent = <&plic0>;
++                      interrupts = <39>;
++                      clocks = <&prci PRCI_CLK_PCLK>;
++                      status = "disabled";
++              };
++              uart1: serial@10011000 {
++                      compatible = "sifive,fu740-c000-uart", "sifive,uart0";
++                      reg = <0x0 0x10011000 0x0 0x1000>;
++                      interrupt-parent = <&plic0>;
++                      interrupts = <40>;
++                      clocks = <&prci PRCI_CLK_PCLK>;
++                      status = "disabled";
++              };
++              i2c0: i2c@10030000 {
++                      compatible = "sifive,fu740-c000-i2c", "sifive,i2c0";
++                      reg = <0x0 0x10030000 0x0 0x1000>;
++                      interrupt-parent = <&plic0>;
++                      interrupts = <52>;
++                      clocks = <&prci PRCI_CLK_PCLK>;
++                      reg-shift = <2>;
++                      reg-io-width = <1>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++              i2c1: i2c@10031000 {
++                      compatible = "sifive,fu740-c000-i2c", "sifive,i2c0";
++                      reg = <0x0 0x10031000 0x0 0x1000>;
++                      interrupt-parent = <&plic0>;
++                      interrupts = <53>;
++                      clocks = <&prci PRCI_CLK_PCLK>;
++                      reg-shift = <2>;
++                      reg-io-width = <1>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++              qspi0: spi@10040000 {
++                      compatible = "sifive,fu740-c000-spi", "sifive,spi0";
++                      reg = <0x0 0x10040000 0x0 0x1000>,
++                            <0x0 0x20000000 0x0 0x10000000>;
++                      interrupt-parent = <&plic0>;
++                      interrupts = <41>;
++                      clocks = <&prci PRCI_CLK_PCLK>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++              qspi1: spi@10041000 {
++                      compatible = "sifive,fu740-c000-spi", "sifive,spi0";
++                      reg = <0x0 0x10041000 0x0 0x1000>,
++                            <0x0 0x30000000 0x0 0x10000000>;
++                      interrupt-parent = <&plic0>;
++                      interrupts = <42>;
++                      clocks = <&prci PRCI_CLK_PCLK>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++              spi0: spi@10050000 {
++                      compatible = "sifive,fu740-c000-spi", "sifive,spi0";
++                      reg = <0x0 0x10050000 0x0 0x1000>;
++                      interrupt-parent = <&plic0>;
++                      interrupts = <43>;
++                      clocks = <&prci PRCI_CLK_PCLK>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++              eth0: ethernet@10090000 {
++                      compatible = "sifive,fu540-c000-gem";
++                      interrupt-parent = <&plic0>;
++                      interrupts = <55>;
++                      reg = <0x0 0x10090000 0x0 0x2000>,
++                            <0x0 0x100a0000 0x0 0x1000>;
++                      local-mac-address = [00 00 00 00 00 00];
++                      clock-names = "pclk", "hclk";
++                      clocks = <&prci PRCI_CLK_GEMGXLPLL>,
++                               <&prci PRCI_CLK_GEMGXLPLL>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++              pwm0: pwm@10020000 {
++                      compatible = "sifive,fu740-c000-pwm", "sifive,pwm0";
++                      reg = <0x0 0x10020000 0x0 0x1000>;
++                      interrupt-parent = <&plic0>;
++                      interrupts = <44>, <45>, <46>, <47>;
++                      clocks = <&prci PRCI_CLK_PCLK>;
++                      #pwm-cells = <3>;
++                      status = "disabled";
++              };
++              pwm1: pwm@10021000 {
++                      compatible = "sifive,fu740-c000-pwm", "sifive,pwm0";
++                      reg = <0x0 0x10021000 0x0 0x1000>;
++                      interrupt-parent = <&plic0>;
++                      interrupts = <48>, <49>, <50>, <51>;
++                      clocks = <&prci PRCI_CLK_PCLK>;
++                      #pwm-cells = <3>;
++                      status = "disabled";
++              };
++              ccache: cache-controller@2010000 {
++                      compatible = "sifive,fu740-c000-ccache", "cache";
++                      cache-block-size = <64>;
++                      cache-level = <2>;
++                      cache-sets = <2048>;
++                      cache-size = <2097152>;
++                      cache-unified;
++                      interrupt-parent = <&plic0>;
++                      interrupts = <19 20 21 22>;
++                      reg = <0x0 0x2010000 0x0 0x1000>;
++              };
++              gpio: gpio@10060000 {
++                      compatible = "sifive,fu740-c000-gpio", "sifive,gpio0";
++                      interrupt-parent = <&plic0>;
++                      interrupts = <23>, <24>, <25>, <26>, <27>, <28>, <29>,
++                                   <30>, <31>, <32>, <33>, <34>, <35>, <36>,
++                                   <37>, <38>;
++                      reg = <0x0 0x10060000 0x0 0x1000>;
++                      gpio-controller;
++                      #gpio-cells = <2>;
++                      interrupt-controller;
++                      #interrupt-cells = <2>;
++                      clocks = <&prci PRCI_CLK_PCLK>;
++                      status = "disabled";
++              };
++      };
++};
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0006-riscv-dts-add-initial-board-data-for-the-SiFive-HiFi.patch b/target/linux/hifiveu/patches-5.10/0006-riscv-dts-add-initial-board-data-for-the-SiFive-HiFi.patch
new file mode 100644 (file)
index 0000000..a177ba1
--- /dev/null
@@ -0,0 +1,290 @@
+From 4c3ea0f7a7ff303c83273c66b10fe62eed86a7c8 Mon Sep 17 00:00:00 2001
+From: Yash Shah <[email protected]>
+Date: Tue, 8 Dec 2020 10:25:41 +0530
+Subject: [PATCH 06/28] riscv: dts: add initial board data for the SiFive
+ HiFive Unmatched
+
+Add initial board data for the SiFive HiFive Unmatched A00.
+This patch is dependent on Zong's Patchset[0].
+
+[0]: https://lore.kernel.org/linux-riscv/[email protected]/T/#u
+
+Signed-off-by: Yash Shah <[email protected]>
+Reviewed-by: Bin Meng <[email protected]>
+---
+ arch/riscv/boot/dts/sifive/Makefile                |   3 +-
+ .../riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 253 +++++++++++++++++++++
+ 2 files changed, 255 insertions(+), 1 deletion(-)
+ create mode 100644 arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+
+diff --git a/arch/riscv/boot/dts/sifive/Makefile b/arch/riscv/boot/dts/sifive/Makefile
+index 6d6189e..74c47fe 100644
+--- a/arch/riscv/boot/dts/sifive/Makefile
++++ b/arch/riscv/boot/dts/sifive/Makefile
+@@ -1,2 +1,3 @@
+ # SPDX-License-Identifier: GPL-2.0
+-dtb-$(CONFIG_SOC_SIFIVE) += hifive-unleashed-a00.dtb
++dtb-$(CONFIG_SOC_SIFIVE) += hifive-unleashed-a00.dtb \
++                          hifive-unmatched-a00.dtb
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+new file mode 100644
+index 00000000..b1c3c59
+--- /dev/null
++++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+@@ -0,0 +1,253 @@
++// SPDX-License-Identifier: (GPL-2.0 OR MIT)
++/* Copyright (c) 2020 SiFive, Inc */
++
++#include "fu740-c000.dtsi"
++#include <dt-bindings/interrupt-controller/irq.h>
++
++/* Clock frequency (in Hz) of the PCB crystal for rtcclk */
++#define RTCCLK_FREQ           1000000
++
++/ {
++      #address-cells = <2>;
++      #size-cells = <2>;
++      model = "SiFive HiFive Unmatched A00";
++      compatible = "sifive,hifive-unmatched-a00", "sifive,fu740-c000",
++                   "sifive,fu740";
++
++      chosen {
++              stdout-path = "serial0";
++      };
++
++      cpus {
++              timebase-frequency = <RTCCLK_FREQ>;
++      };
++
++      memory@80000000 {
++              device_type = "memory";
++              reg = <0x0 0x80000000 0x2 0x00000000>;
++      };
++
++      soc {
++      };
++
++      hfclk: hfclk {
++              #clock-cells = <0>;
++              compatible = "fixed-clock";
++              clock-frequency = <26000000>;
++              clock-output-names = "hfclk";
++      };
++
++      rtcclk: rtcclk {
++              #clock-cells = <0>;
++              compatible = "fixed-clock";
++              clock-frequency = <RTCCLK_FREQ>;
++              clock-output-names = "rtcclk";
++      };
++};
++
++&uart0 {
++      status = "okay";
++};
++
++&uart1 {
++      status = "okay";
++};
++
++&i2c0 {
++      status = "okay";
++
++      temperature-sensor@4c {
++              compatible = "ti,tmp451";
++              reg = <0x4c>;
++              interrupt-parent = <&gpio>;
++              interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
++      };
++
++      pmic@58 {
++              compatible = "dlg,da9063";
++              reg = <0x58>;
++              interrupt-parent = <&gpio>;
++              interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
++              interrupt-controller;
++
++              regulators {
++                      vdd_bcore1: bcore1 {
++                              regulator-min-microvolt = <900000>;
++                              regulator-max-microvolt = <900000>;
++                              regulator-min-microamp = <5000000>;
++                              regulator-max-microamp = <5000000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_bcore2: bcore2 {
++                              regulator-min-microvolt = <900000>;
++                              regulator-max-microvolt = <900000>;
++                              regulator-min-microamp = <5000000>;
++                              regulator-max-microamp = <5000000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_bpro: bpro {
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microamp = <2500000>;
++                              regulator-max-microamp = <2500000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_bperi: bperi {
++                              regulator-min-microvolt = <1050000>;
++                              regulator-max-microvolt = <1050000>;
++                              regulator-min-microamp = <1500000>;
++                              regulator-max-microamp = <1500000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_bmem: bmem {
++                              regulator-min-microvolt = <1200000>;
++                              regulator-max-microvolt = <1200000>;
++                              regulator-min-microamp = <3000000>;
++                              regulator-max-microamp = <3000000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_bio: bio {
++                              regulator-min-microvolt = <1200000>;
++                              regulator-max-microvolt = <1200000>;
++                              regulator-min-microamp = <3000000>;
++                              regulator-max-microamp = <3000000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_ldo1: ldo1 {
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microamp = <100000>;
++                              regulator-max-microamp = <100000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_ldo2: ldo2 {
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microamp = <200000>;
++                              regulator-max-microamp = <200000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_ldo3: ldo3 {
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microamp = <200000>;
++                              regulator-max-microamp = <200000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_ldo4: ldo4 {
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microamp = <200000>;
++                              regulator-max-microamp = <200000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_ldo5: ldo5 {
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microamp = <100000>;
++                              regulator-max-microamp = <100000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_ldo6: ldo6 {
++                              regulator-min-microvolt = <3300000>;
++                              regulator-max-microvolt = <3300000>;
++                              regulator-min-microamp = <200000>;
++                              regulator-max-microamp = <200000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_ldo7: ldo7 {
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microamp = <200000>;
++                              regulator-max-microamp = <200000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_ldo8: ldo8 {
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microamp = <200000>;
++                              regulator-max-microamp = <200000>;
++                              regulator-always-on;
++                      };
++
++                      vdd_ld09: ldo9 {
++                              regulator-min-microvolt = <1050000>;
++                              regulator-max-microvolt = <1050000>;
++                              regulator-min-microamp = <200000>;
++                              regulator-max-microamp = <200000>;
++                      };
++
++                      vdd_ldo10: ldo10 {
++                              regulator-min-microvolt = <1000000>;
++                              regulator-max-microvolt = <1000000>;
++                              regulator-min-microamp = <300000>;
++                              regulator-max-microamp = <300000>;
++                      };
++
++                      vdd_ldo11: ldo11 {
++                              regulator-min-microvolt = <2500000>;
++                              regulator-max-microvolt = <2500000>;
++                              regulator-min-microamp = <300000>;
++                              regulator-max-microamp = <300000>;
++                              regulator-always-on;
++                      };
++              };
++      };
++};
++
++&qspi0 {
++      status = "okay";
++      flash@0 {
++              compatible = "issi,is25wp256", "jedec,spi-nor";
++              reg = <0>;
++              spi-max-frequency = <50000000>;
++              m25p,fast-read;
++              spi-tx-bus-width = <4>;
++              spi-rx-bus-width = <4>;
++      };
++};
++
++&spi0 {
++      status = "okay";
++      mmc@0 {
++              compatible = "mmc-spi-slot";
++              reg = <0>;
++              spi-max-frequency = <20000000>;
++              voltage-ranges = <3300 3300>;
++              disable-wp;
++      };
++};
++
++&eth0 {
++      status = "okay";
++      phy-mode = "gmii";
++      phy-handle = <&phy0>;
++      phy0: ethernet-phy@0 {
++              reg = <0>;
++      };
++};
++
++&pwm0 {
++      status = "okay";
++};
++
++&pwm1 {
++      status = "okay";
++};
++
++&gpio {
++      status = "okay";
++};
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0008-RISC-V-sifive_l2_cache-Update-L2-cache-driver-to-sup.patch b/target/linux/hifiveu/patches-5.10/0008-RISC-V-sifive_l2_cache-Update-L2-cache-driver-to-sup.patch
new file mode 100644 (file)
index 0000000..2cb58f6
--- /dev/null
@@ -0,0 +1,98 @@
+From c6ed58c46436731279045a01c3611251a8ebd76b Mon Sep 17 00:00:00 2001
+From: Yash Shah <[email protected]>
+Date: Thu, 10 Dec 2020 15:58:03 +0530
+Subject: [PATCH 08/28] RISC-V: sifive_l2_cache: Update L2 cache driver to
+ support SiFive FU740
+
+SiFive FU740 has 4 ECC interrupt sources as compared to 3 in FU540.
+Update the L2 cache controller driver to support this additional
+interrupt in case of FU740-C000 chip.
+
+Signed-off-by: Yash Shah <[email protected]>
+---
+ drivers/soc/sifive/sifive_l2_cache.c | 27 ++++++++++++++++++++++++---
+ 1 file changed, 24 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/soc/sifive/sifive_l2_cache.c b/drivers/soc/sifive/sifive_l2_cache.c
+index 44d7e1951..59640a1 100644
+--- a/drivers/soc/sifive/sifive_l2_cache.c
++++ b/drivers/soc/sifive/sifive_l2_cache.c
+@@ -17,6 +17,10 @@
+ #define SIFIVE_L2_DIRECCFIX_HIGH 0x104
+ #define SIFIVE_L2_DIRECCFIX_COUNT 0x108
++#define SIFIVE_L2_DIRECCFAIL_LOW 0x120
++#define SIFIVE_L2_DIRECCFAIL_HIGH 0x124
++#define SIFIVE_L2_DIRECCFAIL_COUNT 0x128
++
+ #define SIFIVE_L2_DATECCFIX_LOW 0x140
+ #define SIFIVE_L2_DATECCFIX_HIGH 0x144
+ #define SIFIVE_L2_DATECCFIX_COUNT 0x148
+@@ -29,7 +33,7 @@
+ #define SIFIVE_L2_WAYENABLE 0x08
+ #define SIFIVE_L2_ECCINJECTERR 0x40
+-#define SIFIVE_L2_MAX_ECCINTR 3
++#define SIFIVE_L2_MAX_ECCINTR 4
+ static void __iomem *l2_base;
+ static int g_irq[SIFIVE_L2_MAX_ECCINTR];
+@@ -39,6 +43,7 @@ enum {
+       DIR_CORR = 0,
+       DATA_CORR,
+       DATA_UNCORR,
++      DIR_UNCORR,
+ };
+ #ifdef CONFIG_DEBUG_FS
+@@ -93,6 +98,7 @@ static void l2_config_read(void)
+ static const struct of_device_id sifive_l2_ids[] = {
+       { .compatible = "sifive,fu540-c000-ccache" },
++      { .compatible = "sifive,fu740-c000-ccache" },
+       { /* end of table */ },
+ };
+@@ -155,6 +161,15 @@ static irqreturn_t l2_int_handler(int irq, void *device)
+               atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_CE,
+                                          "DirECCFix");
+       }
++      if (irq == g_irq[DIR_UNCORR]) {
++              add_h = readl(l2_base + SIFIVE_L2_DIRECCFAIL_HIGH);
++              add_l = readl(l2_base + SIFIVE_L2_DIRECCFAIL_LOW);
++              /* Reading this register clears the DirFail interrupt sig */
++              readl(l2_base + SIFIVE_L2_DIRECCFAIL_COUNT);
++              atomic_notifier_call_chain(&l2_err_chain, SIFIVE_L2_ERR_TYPE_UE,
++                                         "DirECCFail");
++              panic("L2CACHE: DirFail @ 0x%08X.%08X\n", add_h, add_l);
++      }
+       if (irq == g_irq[DATA_CORR]) {
+               add_h = readl(l2_base + SIFIVE_L2_DATECCFIX_HIGH);
+               add_l = readl(l2_base + SIFIVE_L2_DATECCFIX_LOW);
+@@ -181,7 +196,7 @@ static int __init sifive_l2_init(void)
+ {
+       struct device_node *np;
+       struct resource res;
+-      int i, rc;
++      int i, rc, intr_num;
+       np = of_find_matching_node(NULL, sifive_l2_ids);
+       if (!np)
+@@ -194,7 +209,13 @@ static int __init sifive_l2_init(void)
+       if (!l2_base)
+               return -ENOMEM;
+-      for (i = 0; i < SIFIVE_L2_MAX_ECCINTR; i++) {
++      intr_num = of_property_count_u32_elems(np, "interrupts");
++      if (!intr_num) {
++              pr_err("L2CACHE: no interrupts property\n");
++              return -ENODEV;
++      }
++
++      for (i = 0; i < intr_num; i++) {
+               g_irq[i] = irq_of_parse_and_map(np, i);
+               rc = request_irq(g_irq[i], l2_int_handler, 0, "l2_ecc", NULL);
+               if (rc) {
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0009-riscv-dts-fu740-fix-cache-controller-interrupts.patch b/target/linux/hifiveu/patches-5.10/0009-riscv-dts-fu740-fix-cache-controller-interrupts.patch
new file mode 100644 (file)
index 0000000..f3cf7b3
--- /dev/null
@@ -0,0 +1,36 @@
+From bc7576ad8540ac5fd49c38eae072f561ee6ed8fa Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <[email protected]>
+Date: Wed, 3 Feb 2021 07:00:15 -0800
+Subject: [PATCH 09/28] riscv: dts: fu740: fix cache-controller interrupts
+
+The order of interrupt numbers is incorrect.
+
+The order for FU740 is: DirError, DataError, DataFail, DirFail
+
+From SiFive FU740-C000 Manual:
+19 - L2 Cache DirError
+20 - L2 Cache DirFail
+21 - L2 Cache DataError
+22 - L2 Cache DataFail
+
+Signed-off-by: David Abdurachmanov <[email protected]>
+---
+ arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+index eeb4f8c3..d0d206c 100644
+--- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
++++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+@@ -272,7 +272,7 @@
+                       cache-size = <2097152>;
+                       cache-unified;
+                       interrupt-parent = <&plic0>;
+-                      interrupts = <19 20 21 22>;
++                      interrupts = <19 21 22 20>;
+                       reg = <0x0 0x2010000 0x0 0x1000>;
+               };
+               gpio: gpio@10060000 {
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0010-riscv-sifive-fu740-cpu-1-2-3-4-set-compatible-to-sif.patch b/target/linux/hifiveu/patches-5.10/0010-riscv-sifive-fu740-cpu-1-2-3-4-set-compatible-to-sif.patch
new file mode 100644 (file)
index 0000000..9705659
--- /dev/null
@@ -0,0 +1,54 @@
+From aae0bd387f1c3a81bfa1108dfa3fcd7a631ef482 Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <[email protected]>
+Date: Wed, 17 Feb 2021 06:06:14 -0800
+Subject: [PATCH 10/28] riscv: sifive: fu740: cpu{1,2,3,4} set compatible to
+ sifive,u74-mc
+
+Signed-off-by: David Abdurachmanov <[email protected]>
+---
+ arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+index d0d206c..cd9cc02 100644
+--- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
++++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+@@ -39,7 +39,7 @@
+                       };
+               };
+               cpu1: cpu@1 {
+-                      compatible = "sifive,bullet0", "riscv";
++                      compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
+                       d-cache-block-size = <64>;
+                       d-cache-sets = <64>;
+                       d-cache-size = <32768>;
+@@ -63,7 +63,7 @@
+                       };
+               };
+               cpu2: cpu@2 {
+-                      compatible = "sifive,bullet0", "riscv";
++                      compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
+                       d-cache-block-size = <64>;
+                       d-cache-sets = <64>;
+                       d-cache-size = <32768>;
+@@ -87,7 +87,7 @@
+                       };
+               };
+               cpu3: cpu@3 {
+-                      compatible = "sifive,bullet0", "riscv";
++                      compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
+                       d-cache-block-size = <64>;
+                       d-cache-sets = <64>;
+                       d-cache-size = <32768>;
+@@ -111,7 +111,7 @@
+                       };
+               };
+               cpu4: cpu@4 {
+-                      compatible = "sifive,bullet0", "riscv";
++                      compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
+                       d-cache-block-size = <64>;
+                       d-cache-sets = <64>;
+                       d-cache-size = <32768>;
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0011-riscv-sifive-unmatched-update-for-16GB-rev3.patch b/target/linux/hifiveu/patches-5.10/0011-riscv-sifive-unmatched-update-for-16GB-rev3.patch
new file mode 100644 (file)
index 0000000..613a4ab
--- /dev/null
@@ -0,0 +1,108 @@
+From e0fc0af6df9f5a1c9835d73e649b88c8a533db0c Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <[email protected]>
+Date: Mon, 22 Feb 2021 01:33:52 -0800
+Subject: [PATCH 11/28] riscv: sifive: unmatched: update for 16GB rev3
+
+Signed-off-by: David Abdurachmanov <[email protected]>
+---
+ .../riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 34 +++++++++++-----------
+ 1 file changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+index b1c3c59..e026f60 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+@@ -24,7 +24,7 @@
+       memory@80000000 {
+               device_type = "memory";
+-              reg = <0x0 0x80000000 0x2 0x00000000>;
++              reg = <0x0 0x80000000 0x4 0x00000000>;
+       };
+       soc {
+@@ -72,16 +72,16 @@
+               regulators {
+                       vdd_bcore1: bcore1 {
+-                              regulator-min-microvolt = <900000>;
+-                              regulator-max-microvolt = <900000>;
++                              regulator-min-microvolt = <1050000>;
++                              regulator-max-microvolt = <1050000>;
+                               regulator-min-microamp = <5000000>;
+                               regulator-max-microamp = <5000000>;
+                               regulator-always-on;
+                       };
+                       vdd_bcore2: bcore2 {
+-                              regulator-min-microvolt = <900000>;
+-                              regulator-max-microvolt = <900000>;
++                              regulator-min-microvolt = <1050000>;
++                              regulator-max-microvolt = <1050000>;
+                               regulator-min-microamp = <5000000>;
+                               regulator-max-microamp = <5000000>;
+                               regulator-always-on;
+@@ -136,48 +136,48 @@
+                       };
+                       vdd_ldo3: ldo3 {
+-                              regulator-min-microvolt = <1800000>;
+-                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microvolt = <3300000>;
++                              regulator-max-microvolt = <3300000>;
+                               regulator-min-microamp = <200000>;
+                               regulator-max-microamp = <200000>;
+                               regulator-always-on;
+                       };
+                       vdd_ldo4: ldo4 {
+-                              regulator-min-microvolt = <1800000>;
+-                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microvolt = <2500000>;
++                              regulator-max-microvolt = <2500000>;
+                               regulator-min-microamp = <200000>;
+                               regulator-max-microamp = <200000>;
+                               regulator-always-on;
+                       };
+                       vdd_ldo5: ldo5 {
+-                              regulator-min-microvolt = <1800000>;
+-                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microvolt = <3300000>;
++                              regulator-max-microvolt = <3300000>;
+                               regulator-min-microamp = <100000>;
+                               regulator-max-microamp = <100000>;
+                               regulator-always-on;
+                       };
+                       vdd_ldo6: ldo6 {
+-                              regulator-min-microvolt = <3300000>;
+-                              regulator-max-microvolt = <3300000>;
++                              regulator-min-microvolt = <1800000>;
++                              regulator-max-microvolt = <1800000>;
+                               regulator-min-microamp = <200000>;
+                               regulator-max-microamp = <200000>;
+                               regulator-always-on;
+                       };
+                       vdd_ldo7: ldo7 {
+-                              regulator-min-microvolt = <1800000>;
+-                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microvolt = <3300000>;
++                              regulator-max-microvolt = <3300000>;
+                               regulator-min-microamp = <200000>;
+                               regulator-max-microamp = <200000>;
+                               regulator-always-on;
+                       };
+                       vdd_ldo8: ldo8 {
+-                              regulator-min-microvolt = <1800000>;
+-                              regulator-max-microvolt = <1800000>;
++                              regulator-min-microvolt = <3300000>;
++                              regulator-max-microvolt = <3300000>;
+                               regulator-min-microamp = <200000>;
+                               regulator-max-microamp = <200000>;
+                               regulator-always-on;
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0012-riscv-Add-3-SBI-wrapper-functions-to-get-cpu-manufac.patch b/target/linux/hifiveu/patches-5.10/0012-riscv-Add-3-SBI-wrapper-functions-to-get-cpu-manufac.patch
new file mode 100644 (file)
index 0000000..dc3e3b7
--- /dev/null
@@ -0,0 +1,59 @@
+From 1707c6daff527d1661de60a9279b72d22265fd4b Mon Sep 17 00:00:00 2001
+From: Vincent Chen <[email protected]>
+Date: Mon, 22 Mar 2021 22:26:02 +0800
+Subject: [PATCH 12/28] riscv: Add 3 SBI wrapper functions to get cpu
+ manufacturer information
+
+Add 3 wrapper functions to get vendor id, architecture id and implement id
+from M-mode
+
+Signed-off-by: Vincent Chen <[email protected]>
+Reviewed-by: Anup Patel <[email protected]>
+---
+ arch/riscv/include/asm/sbi.h |  3 +++
+ arch/riscv/kernel/sbi.c      | 15 +++++++++++++++
+ 2 files changed, 18 insertions(+)
+
+diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
+index c0fdb05..072c91f 100644
+--- a/arch/riscv/include/asm/sbi.h
++++ b/arch/riscv/include/asm/sbi.h
+@@ -97,6 +97,9 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
+ void sbi_console_putchar(int ch);
+ int sbi_console_getchar(void);
++long sbi_get_mvendorid(void);
++long sbi_get_marchid(void);
++long sbi_get_mimpid(void);
+ void sbi_set_timer(uint64_t stime_value);
+ void sbi_shutdown(void);
+ void sbi_clear_ipi(void);
+diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
+index 226ccce..51a4e5f 100644
+--- a/arch/riscv/kernel/sbi.c
++++ b/arch/riscv/kernel/sbi.c
+@@ -547,6 +547,21 @@ static inline long sbi_get_firmware_version(void)
+       return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION);
+ }
++long sbi_get_mvendorid(void)
++{
++      return __sbi_base_ecall(SBI_EXT_BASE_GET_MVENDORID);
++}
++
++long sbi_get_marchid(void)
++{
++      return __sbi_base_ecall(SBI_EXT_BASE_GET_MARCHID);
++}
++
++long sbi_get_mimpid(void)
++{
++      return __sbi_base_ecall(SBI_EXT_BASE_GET_MIMPID);
++}
++
+ static void sbi_send_cpumask_ipi(const struct cpumask *target)
+ {
+       struct cpumask hartid_mask;
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0013-riscv-Introduce-alternative-mechanism-to-apply-errat.patch b/target/linux/hifiveu/patches-5.10/0013-riscv-Introduce-alternative-mechanism-to-apply-errat.patch
new file mode 100644 (file)
index 0000000..712fd8c
--- /dev/null
@@ -0,0 +1,481 @@
+From 5c0093a1e2b8ef676d413576b2f74f4b6b7c1c51 Mon Sep 17 00:00:00 2001
+From: Vincent Chen <[email protected]>
+Date: Mon, 22 Mar 2021 22:26:03 +0800
+Subject: [PATCH 13/28] riscv: Introduce alternative mechanism to apply errata
+ solution
+
+Introduce the "alternative" mechanism from ARM64 and x86 to apply the CPU
+vendors' errata solution at runtime. The main purpose of this patch is
+to provide a framework. Therefore, the implementation is quite basic for
+now so that some scenarios could not use this schemei, such as patching
+code to a module, relocating the patching code and heterogeneous CPU
+topology.
+
+Users could use the macro ALTERNATIVE to apply an errata to the existing
+code flow. In the macro ALTERNATIVE, users need to specify the manufacturer
+information(vendorid, archid, and impid) for this errata. Therefore, kernel
+will know this errata is suitable for which CPU core. During the booting
+procedure, kernel will select the errata required by the CPU core and then
+patch it. It means that the kernel only applies the errata to the specified
+CPU core. In this case, the vendor's errata does not affect each other at
+runtime. The above patching procedure only occurs during the booting phase,
+so we only take the overhead of the "alternative" mechanism once.
+
+This "alternative" mechanism is enabled by default to ensure that all
+required errata will be applied. However, users can disable this feature by
+the Kconfig "CONFIG_RISCV_ERRATA_ALTERNATIVE".
+
+Signed-off-by: Vincent Chen <[email protected]>
+Reviewed-by: Anup Patel <[email protected]>
+---
+ arch/riscv/Kconfig                          |   1 +
+ arch/riscv/Kconfig.erratas                  |  12 +++
+ arch/riscv/Makefile                         |   1 +
+ arch/riscv/errata/Makefile                  |   1 +
+ arch/riscv/errata/alternative.c             |  69 ++++++++++++++
+ arch/riscv/include/asm/alternative-macros.h | 142 ++++++++++++++++++++++++++++
+ arch/riscv/include/asm/alternative.h        |  36 +++++++
+ arch/riscv/include/asm/asm.h                |   1 +
+ arch/riscv/include/asm/csr.h                |   3 +
+ arch/riscv/include/asm/errata_list.h        |  12 +++
+ arch/riscv/include/asm/sections.h           |   1 +
+ arch/riscv/include/asm/vendorid_list.h      |  10 ++
+ arch/riscv/kernel/smpboot.c                 |   4 +
+ arch/riscv/kernel/vmlinux.lds.S             |   7 ++
+ 14 files changed, 300 insertions(+)
+ create mode 100644 arch/riscv/Kconfig.erratas
+ create mode 100644 arch/riscv/errata/Makefile
+ create mode 100644 arch/riscv/errata/alternative.c
+ create mode 100644 arch/riscv/include/asm/alternative-macros.h
+ create mode 100644 arch/riscv/include/asm/alternative.h
+ create mode 100644 arch/riscv/include/asm/errata_list.h
+ create mode 100644 arch/riscv/include/asm/vendorid_list.h
+
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index e6d569a..3c66957 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -195,6 +195,7 @@ config LOCKDEP_SUPPORT
+       def_bool y
+ source "arch/riscv/Kconfig.socs"
++source "arch/riscv/Kconfig.erratas"
+ menu "Platform type"
+diff --git a/arch/riscv/Kconfig.erratas b/arch/riscv/Kconfig.erratas
+new file mode 100644
+index 00000000..4d0bafc
+--- /dev/null
++++ b/arch/riscv/Kconfig.erratas
+@@ -0,0 +1,12 @@
++menu "CPU errata selection"
++
++config RISCV_ERRATA_ALTERNATIVE
++      bool "RISC-V alternative scheme"
++      default y
++      help
++        This Kconfig allows the kernel to automatically patch the
++        errata required by the execution platform at run time. The
++        code patching is performed once in the boot stages. It means
++        that the overhead from this mechanism is just taken once.
++
++endmenu
+diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
+index 8c29e55..2bff64c 100644
+--- a/arch/riscv/Makefile
++++ b/arch/riscv/Makefile
+@@ -75,6 +75,7 @@ KBUILD_IMAGE := $(boot)/Image.gz
+ head-y := arch/riscv/kernel/head.o
+ core-y += arch/riscv/
++core-$(CONFIG_RISCV_ERRATA_ALTERNATIVE) += arch/riscv/errata/
+ libs-y += arch/riscv/lib/
+ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
+diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
+new file mode 100644
+index 00000000..43e6d54
+--- /dev/null
++++ b/arch/riscv/errata/Makefile
+@@ -0,0 +1 @@
++obj-y += alternative.o
+diff --git a/arch/riscv/errata/alternative.c b/arch/riscv/errata/alternative.c
+new file mode 100644
+index 00000000..8efa60a
+--- /dev/null
++++ b/arch/riscv/errata/alternative.c
+@@ -0,0 +1,69 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * alternative runtime patching
++ * inspired by the ARM64 and x86 version
++ *
++ * Copyright (C) 2021 Sifive.
++ */
++
++#include <linux/init.h>
++#include <linux/cpu.h>
++#include <linux/uaccess.h>
++#include <asm/alternative.h>
++#include <asm/sections.h>
++#include <asm/vendorid_list.h>
++#include <asm/sbi.h>
++#include <asm/csr.h>
++
++static struct cpu_manufacturer_info_t {
++      unsigned long vendor_id;
++      unsigned long arch_id;
++      unsigned long imp_id;
++} cpu_mfr_info;
++
++static void (*vendor_patch_func)(struct alt_entry *begin, struct alt_entry *end,
++                               unsigned long archid, unsigned long impid);
++
++static inline void __init riscv_fill_cpu_mfr_info(void)
++{
++#ifdef CONFIG_RISCV_M_MODE
++      cpu_mfr_info.vendor_id = csr_read(CSR_MVENDORID);
++      cpu_mfr_info.arch_id = csr_read(CSR_MARCHID);
++      cpu_mfr_info.imp_id = csr_read(CSR_MIMPID);
++#else
++      cpu_mfr_info.vendor_id = sbi_get_mvendorid();
++      cpu_mfr_info.arch_id = sbi_get_marchid();
++      cpu_mfr_info.imp_id = sbi_get_mimpid();
++#endif
++}
++
++static void __init init_alternative(void)
++{
++      riscv_fill_cpu_mfr_info();
++
++      switch (cpu_mfr_info.vendor_id) {
++      default:
++              vendor_patch_func = NULL;
++      }
++}
++
++/*
++ * This is called very early in the boot process (directly after we run
++ * a feature detect on the boot CPU). No need to worry about other CPUs
++ * here.
++ */
++void __init apply_boot_alternatives(void)
++{
++      /* If called on non-boot cpu things could go wrong */
++      WARN_ON(smp_processor_id() != 0);
++
++      init_alternative();
++
++      if (!vendor_patch_func)
++              return;
++
++      vendor_patch_func((struct alt_entry *)__alt_start,
++                        (struct alt_entry *)__alt_end,
++                        cpu_mfr_info.arch_id, cpu_mfr_info.imp_id);
++}
++
+diff --git a/arch/riscv/include/asm/alternative-macros.h b/arch/riscv/include/asm/alternative-macros.h
+new file mode 100644
+index 00000000..88c0870
+--- /dev/null
++++ b/arch/riscv/include/asm/alternative-macros.h
+@@ -0,0 +1,142 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++#ifndef __ASM_ALTERNATIVE_MACROS_H
++#define __ASM_ALTERNATIVE_MACROS_H
++
++#ifdef CONFIG_RISCV_ERRATA_ALTERNATIVE
++
++#ifdef __ASSEMBLY__
++
++.macro ALT_ENTRY oldptr newptr vendor_id errata_id new_len
++      RISCV_PTR \oldptr
++      RISCV_PTR \newptr
++      REG_ASM \vendor_id
++      REG_ASM \new_len
++      .word   \errata_id
++.endm
++
++.macro ALT_NEW_CONTENT vendor_id, errata_id, enable = 1, new_c : vararg
++      .if \enable
++      .pushsection .alternative, "a"
++      ALT_ENTRY 886b, 888f, \vendor_id, \errata_id, 889f - 888f
++      .popsection
++      .subsection 1
++888 :
++      \new_c
++889 :
++      .previous
++      .org    . - (889b - 888b) + (887b - 886b)
++      .org    . - (887b - 886b) + (889b - 888b)
++      .endif
++.endm
++
++.macro __ALTERNATIVE_CFG old_c, new_c, vendor_id, errata_id, enable
++886 :
++      \old_c
++887 :
++      ALT_NEW_CONTENT \vendor_id, \errata_id, \enable, \new_c
++.endm
++
++#define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \
++      __ALTERNATIVE_CFG old_c, new_c, vendor_id, errata_id, IS_ENABLED(CONFIG_k)
++
++#else /* !__ASSEMBLY__ */
++
++#include <asm/asm.h>
++#include <linux/stringify.h>
++
++#define ALT_ENTRY(oldptr, newptr, vendor_id, errata_id, newlen) \
++      RISCV_PTR " " oldptr "\n" \
++      RISCV_PTR " " newptr "\n" \
++      REG_ASM " " vendor_id "\n" \
++      REG_ASM " " newlen "\n" \
++      ".word " errata_id "\n"
++
++#define ALT_NEW_CONSTENT(vendor_id, errata_id, enable, new_c) \
++      ".if " __stringify(enable) " == 1\n"                            \
++      ".pushsection .alternative, \"a\"\n"                            \
++      ALT_ENTRY("886b", "888f", __stringify(vendor_id), __stringify(errata_id), "889f - 888f") \
++      ".popsection\n"                                                 \
++      ".subsection 1\n"                                               \
++      "888 :\n"                                                       \
++      new_c "\n"                                                      \
++      "889 :\n"                                                       \
++      ".previous\n"                                                   \
++      ".org   . - (887b - 886b) + (889b - 888b)\n"                    \
++      ".org   . - (889b - 888b) + (887b - 886b)\n"                    \
++      ".endif\n"
++
++#define __ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, enable) \
++      "886 :\n"       \
++      old_c "\n"      \
++      "887 :\n"       \
++      ALT_NEW_CONSTENT(vendor_id, errata_id, enable, new_c)
++
++#define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k)        \
++      __ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, IS_ENABLED(CONFIG_k))
++
++#endif /* __ASSEMBLY__ */
++
++#else /* !CONFIG_RISCV_ERRATA_ALTERNATIVE*/
++#ifdef __ASSEMBLY__
++
++.macro __ALTERNATIVE_CFG old_c
++      \old_c
++.endm
++
++#define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \
++      __ALTERNATIVE_CFG old_c
++
++#else /* !__ASSEMBLY__ */
++
++#define __ALTERNATIVE_CFG(old_c)  \
++      old_c "\n"
++
++#define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, errata_id, CONFIG_k) \
++      __ALTERNATIVE_CFG(old_c)
++
++#endif /* __ASSEMBLY__ */
++#endif /* CONFIG_RISCV_ERRATA_ALTERNATIVE */
++/*
++ * Usage:
++ *   ALTERNATIVE(old_content, new_content, vendor_id, errata_id, CONFIG_k)
++ * in the assembly code. Otherwise,
++ *   asm(ALTERNATIVE(old_content, new_content, vendor_id, errata_id, CONFIG_k));
++ *
++ * old_content: The old content which is probably replaced with new content.
++ * new_content: The new content.
++ * vendor_id: The CPU vendor ID.
++ * errata_id: The errata ID.
++ * CONFIG_k: The Kconfig of this errata. When Kconfig is disabled, the old
++ *         content will alwyas be executed.
++ */
++#define ALTERNATIVE(old_content, new_content, vendor_id, errata_id, CONFIG_k) \
++      _ALTERNATIVE_CFG(old_content, new_content, vendor_id, errata_id, CONFIG_k)
++
++/*
++ * A vendor wants to replace an old_content, but another vendor has used
++ * ALTERNATIVE() to patch its customized content at the same location. In
++ * this case, this vendor can create a new macro ALTERNATIVE_2() based
++ * on the following sample code and then replace ALTERNATIVE() with
++ * ALTERNATIVE_2() to append its customized content.
++ *
++ * .macro __ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, errata_id_1, enable_1, \
++ *                                   new_c_2, vendor_id_2, errata_id_2, enable_2
++ * 886 :
++ *      \old_c
++ * 887 :
++ *      ALT_NEW_CONTENT \vendor_id_1, \errata_id_1, \enable_1, \new_c_1
++ *      ALT_NEW_CONTENT \vendor_id_2, \errata_id_2, \enable_2, \new_c_2
++ * .endm
++ *
++ * #define _ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, CONFIG_k_1, \
++ *                                   new_c_2, vendor_id_2, errata_id_2, CONFIG_k_2) \
++ *        __ALTERNATIVE_CFG_2 old_c, new_c_1, vendor_id_1, errata_id_1, IS_ENABLED(CONFIG_k_1), \
++ *                                   new_c_2, vendor_id_2, errata_id_2, IS_ENABLED(CONFIG_k_2) \
++ *
++ * #define ALTERNATIVE_2(old_content, new_content_1, vendor_id_1, errata_id_1, CONFIG_k_1, \
++ *                                    new_content_2, vendor_id_2, errata_id_2, CONFIG_k_2) \
++ *         _ALTERNATIVE_CFG_2(old_content, new_content_1, vendor_id_1, errata_id_1, CONFIG_k_1, \
++ *                                         new_content_2, vendor_id_2, errata_id_2, CONFIG_k_2)
++ *
++ */
++#endif
+diff --git a/arch/riscv/include/asm/alternative.h b/arch/riscv/include/asm/alternative.h
+new file mode 100644
+index 00000000..430bc4f
+--- /dev/null
++++ b/arch/riscv/include/asm/alternative.h
+@@ -0,0 +1,36 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2021 Sifive.
++ */
++
++#ifndef __ASM_ALTERNATIVE_H
++#define __ASM_ALTERNATIVE_H
++
++#define ERRATA_STRING_LENGTH_MAX 32
++
++#include <asm/alternative-macros.h>
++
++#ifndef __ASSEMBLY__
++
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/stddef.h>
++#include <asm/hwcap.h>
++
++void __init apply_boot_alternatives(void);
++
++struct alt_entry {
++      void *old_ptr;           /* address of original instruciton or data  */
++      void *alt_ptr;           /* address of replacement instruction or data */
++      unsigned long vendor_id; /* cpu vendor id */
++      unsigned long alt_len;   /* The replacement size */
++      unsigned int errata_id;  /* The errata id */
++} __packed;
++
++struct errata_checkfunc_id {
++      unsigned long vendor_id;
++      bool (*func)(struct alt_entry *alt);
++};
++
++#endif
++#endif
+diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
+index 9c992a8..618d7c5 100644
+--- a/arch/riscv/include/asm/asm.h
++++ b/arch/riscv/include/asm/asm.h
+@@ -23,6 +23,7 @@
+ #define REG_L         __REG_SEL(ld, lw)
+ #define REG_S         __REG_SEL(sd, sw)
+ #define REG_SC                __REG_SEL(sc.d, sc.w)
++#define REG_ASM               __REG_SEL(.dword, .word)
+ #define SZREG         __REG_SEL(8, 4)
+ #define LGREG         __REG_SEL(3, 2)
+diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
+index cec462e..076beb9 100644
+--- a/arch/riscv/include/asm/csr.h
++++ b/arch/riscv/include/asm/csr.h
+@@ -109,6 +109,9 @@
+ #define CSR_MIP                       0x344
+ #define CSR_PMPCFG0           0x3a0
+ #define CSR_PMPADDR0          0x3b0
++#define CSR_MVENDORID         0xf11
++#define CSR_MARCHID           0xf12
++#define CSR_MIMPID            0xf13
+ #define CSR_MHARTID           0xf14
+ #ifdef CONFIG_RISCV_M_MODE
+diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
+new file mode 100644
+index 00000000..1b56131
+--- /dev/null
++++ b/arch/riscv/include/asm/errata_list.h
+@@ -0,0 +1,12 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2021 Sifive.
++ */
++#ifndef ASM_ERRATA_LIST_H
++#define ASM_ERRATA_LIST_H
++
++#ifdef CONFIG_ERRATA_SIFIVE
++#define       ERRATA_SIFIVE_NUMBER 0
++#endif
++
++#endif
+diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h
+index 1595c5b..8a303fb 100644
+--- a/arch/riscv/include/asm/sections.h
++++ b/arch/riscv/include/asm/sections.h
+@@ -11,5 +11,6 @@ extern char _start[];
+ extern char _start_kernel[];
+ extern char __init_data_begin[], __init_data_end[];
+ extern char __init_text_begin[], __init_text_end[];
++extern char __alt_start[], __alt_end[];
+ #endif /* __ASM_SECTIONS_H */
+diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h
+new file mode 100644
+index 00000000..9d93421
+--- /dev/null
++++ b/arch/riscv/include/asm/vendorid_list.h
+@@ -0,0 +1,10 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2021 SiFive
++ */
++#ifndef ASM_VENDOR_LIST_H
++#define ASM_VENDOR_LIST_H
++
++#define SIFIVE_VENDOR_ID      0x489
++
++#endif
+diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
+index 96167d5..79788d2 100644
+--- a/arch/riscv/kernel/smpboot.c
++++ b/arch/riscv/kernel/smpboot.c
+@@ -31,6 +31,7 @@
+ #include <asm/sections.h>
+ #include <asm/sbi.h>
+ #include <asm/smp.h>
++#include <asm/alternative.h>
+ #include "head.h"
+@@ -39,6 +40,9 @@ static DECLARE_COMPLETION(cpu_running);
+ void __init smp_prepare_boot_cpu(void)
+ {
+       init_cpu_topology();
++#ifdef CONFIG_RISCV_ERRATA_ALTERNATIVE
++      apply_boot_alternatives();
++#endif
+ }
+ void __init smp_prepare_cpus(unsigned int max_cpus)
+diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
+index de03cb2..7e61bc1 100644
+--- a/arch/riscv/kernel/vmlinux.lds.S
++++ b/arch/riscv/kernel/vmlinux.lds.S
+@@ -90,6 +90,13 @@ SECTIONS
+       }
+       __init_data_end = .;
++
++      . = ALIGN(8);
++      .alternative : {
++              __alt_start = .;
++              *(.alternative)
++              __alt_end = .;
++      }
+       __init_end = .;
+       /* Start of data section */
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0014-riscv-sifive-Add-SiFive-alternative-ports.patch b/target/linux/hifiveu/patches-5.10/0014-riscv-sifive-Add-SiFive-alternative-ports.patch
new file mode 100644 (file)
index 0000000..f995726
--- /dev/null
@@ -0,0 +1,172 @@
+From a56d45ca5b618c553be90591d883747e4cee30e3 Mon Sep 17 00:00:00 2001
+From: Vincent Chen <[email protected]>
+Date: Mon, 22 Mar 2021 22:26:04 +0800
+Subject: [PATCH 14/28] riscv: sifive: Add SiFive alternative ports
+
+Add required ports of the Alternative scheme for SiFive.
+
+Signed-off-by: Vincent Chen <[email protected]>
+Reviewed-by: Anup Patel <[email protected]>
+---
+ arch/riscv/Kconfig.erratas           | 10 ++++++
+ arch/riscv/Kconfig.socs              |  1 +
+ arch/riscv/errata/Makefile           |  1 +
+ arch/riscv/errata/alternative.c      |  5 +++
+ arch/riscv/errata/sifive/Makefile    |  1 +
+ arch/riscv/errata/sifive/errata.c    | 68 ++++++++++++++++++++++++++++++++++++
+ arch/riscv/include/asm/alternative.h |  3 ++
+ 7 files changed, 89 insertions(+)
+ create mode 100644 arch/riscv/errata/sifive/Makefile
+ create mode 100644 arch/riscv/errata/sifive/errata.c
+
+diff --git a/arch/riscv/Kconfig.erratas b/arch/riscv/Kconfig.erratas
+index 4d0bafc..302e746 100644
+--- a/arch/riscv/Kconfig.erratas
++++ b/arch/riscv/Kconfig.erratas
+@@ -9,4 +9,14 @@ config RISCV_ERRATA_ALTERNATIVE
+         code patching is performed once in the boot stages. It means
+         that the overhead from this mechanism is just taken once.
++config ERRATA_SIFIVE
++      bool "SiFive errata"
++      depends on RISCV_ERRATA_ALTERNATIVE
++      help
++        All SiFive errata Kconfig depend on this Kconfig. Disabling
++        this Kconfig will disable all SiFive errata. Please say "Y"
++        here if your platform uses SiFive CPU cores.
++
++        Otherwise, please say "N" here to avoid unnecessary overhead.
++
+ endmenu
+diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
+index 3284d5c..77d18f2 100644
+--- a/arch/riscv/Kconfig.socs
++++ b/arch/riscv/Kconfig.socs
+@@ -7,6 +7,7 @@ config SOC_SIFIVE
+       select CLK_SIFIVE
+       select CLK_SIFIVE_PRCI
+       select SIFIVE_PLIC
++      select ERRATA_SIFIVE
+       help
+         This enables support for SiFive SoC platform hardware.
+diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
+index 43e6d54..b8f8740 100644
+--- a/arch/riscv/errata/Makefile
++++ b/arch/riscv/errata/Makefile
+@@ -1 +1,2 @@
+ obj-y += alternative.o
++obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
+diff --git a/arch/riscv/errata/alternative.c b/arch/riscv/errata/alternative.c
+index 8efa60a..3b15885d 100644
+--- a/arch/riscv/errata/alternative.c
++++ b/arch/riscv/errata/alternative.c
+@@ -42,6 +42,11 @@ static void __init init_alternative(void)
+       riscv_fill_cpu_mfr_info();
+       switch (cpu_mfr_info.vendor_id) {
++#ifdef CONFIG_ERRATA_SIFIVE
++      case SIFIVE_VENDOR_ID:
++              vendor_patch_func = sifive_errata_patch_func;
++              break;
++#endif
+       default:
+               vendor_patch_func = NULL;
+       }
+diff --git a/arch/riscv/errata/sifive/Makefile b/arch/riscv/errata/sifive/Makefile
+new file mode 100644
+index 00000000..2d644e1
+--- /dev/null
++++ b/arch/riscv/errata/sifive/Makefile
+@@ -0,0 +1 @@
++obj-y += errata.o
+diff --git a/arch/riscv/errata/sifive/errata.c b/arch/riscv/errata/sifive/errata.c
+new file mode 100644
+index 00000000..826cd39
+--- /dev/null
++++ b/arch/riscv/errata/sifive/errata.c
+@@ -0,0 +1,68 @@
++// SPDX-License-Identifier: GPL-2.0-only
++/*
++ * Copyright (C) 2021 Sifive.
++ */
++
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/bug.h>
++#include <asm/patch.h>
++#include <asm/alternative.h>
++#include <asm/vendorid_list.h>
++#include <asm/errata_list.h>
++
++struct errata_info_t {
++      char name[ERRATA_STRING_LENGTH_MAX];
++      bool (*check_func)(unsigned long  arch_id, unsigned long impid);
++};
++
++static u32 __init sifive_errata_probe(unsigned long archid, unsigned long impid)
++{
++      int idx;
++      u32 cpu_req_errata = 0;
++
++      for (idx = 0; idx < ERRATA_SIFIVE_NUMBER; idx++)
++              if (errata_list[idx].check_func(archid, impid))
++                      cpu_req_errata |= (1U << idx);
++
++      return cpu_req_errata;
++}
++
++static void __init warn_miss_errata(u32 miss_errata)
++{
++      int i;
++
++      pr_warn("----------------------------------------------------------------\n");
++      pr_warn("WARNING: Missing the following errata may cause potential issues\n");
++      for (i = 0; i < ERRATA_SIFIVE_NUMBER; i++)
++              if (miss_errata & 0x1 << i)
++                      pr_warn("\tSiFive Errata[%d]:%s\n", i, errata_list[i].name);
++      pr_warn("Please enable the corresponding Kconfig to apply them\n");
++      pr_warn("----------------------------------------------------------------\n");
++}
++
++void __init sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
++                                   unsigned long archid, unsigned long impid)
++{
++      struct alt_entry *alt;
++      u32 cpu_req_errata = sifive_errata_probe(archid, impid);
++      u32 cpu_apply_errata = 0;
++      u32 tmp;
++
++      for (alt = begin; alt < end; alt++) {
++              if (alt->vendor_id != SIFIVE_VENDOR_ID)
++                      continue;
++              if (alt->errata_id >= ERRATA_SIFIVE_NUMBER) {
++                      WARN(1, "This errata id:%d is not in kernel errata list", alt->errata_id);
++                      continue;
++              }
++
++              tmp = (1U << alt->errata_id);
++              if (cpu_req_errata & tmp) {
++                      patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
++                      cpu_apply_errata |= tmp;
++              }
++      }
++      if (cpu_apply_errata != cpu_req_errata)
++              warn_miss_errata(cpu_req_errata - cpu_apply_errata);
++}
+diff --git a/arch/riscv/include/asm/alternative.h b/arch/riscv/include/asm/alternative.h
+index 430bc4f..e625d3ca 100644
+--- a/arch/riscv/include/asm/alternative.h
++++ b/arch/riscv/include/asm/alternative.h
+@@ -32,5 +32,8 @@ struct errata_checkfunc_id {
+       bool (*func)(struct alt_entry *alt);
+ };
++void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
++                            unsigned long archid, unsigned long impid);
++
+ #endif
+ #endif
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0015-riscv-sifive-Apply-errata-cip-453-patch.patch b/target/linux/hifiveu/patches-5.10/0015-riscv-sifive-Apply-errata-cip-453-patch.patch
new file mode 100644 (file)
index 0000000..0427f0c
--- /dev/null
@@ -0,0 +1,196 @@
+From ef3d7fb53eff4d043a011bf10e07a77e8ed92736 Mon Sep 17 00:00:00 2001
+From: Vincent Chen <[email protected]>
+Date: Mon, 22 Mar 2021 22:26:05 +0800
+Subject: [PATCH 15/28] riscv: sifive: Apply errata "cip-453" patch
+
+Add sign extension to the $badaddr before addressing the instruction page
+fault and instruction access fault to workaround the issue "cip-453".
+
+To avoid affecting the existing code sequence, this patch will creates two
+trampolines to add sign extension to the $badaddr. By the "alternative"
+mechanism, these two trampolines will replace the original exception
+handler of instruction page fault and instruction access fault in the
+excp_vect_table. In this case, only the specific SiFive CPU core jumps to
+the do_page_fault and do_trap_insn_fault through these two trampolines.
+Other CPUs are not affected.
+
+Signed-off-by: Vincent Chen <[email protected]>
+---
+ arch/riscv/Kconfig.erratas                | 11 +++++++++
+ arch/riscv/errata/sifive/Makefile         |  1 +
+ arch/riscv/errata/sifive/errata.c         | 20 ++++++++++++++++
+ arch/riscv/errata/sifive/errata_cip_453.S | 38 +++++++++++++++++++++++++++++++
+ arch/riscv/include/asm/errata_list.h      | 21 ++++++++++++++++-
+ arch/riscv/kernel/entry.S                 |  6 +++--
+ 6 files changed, 94 insertions(+), 3 deletions(-)
+ create mode 100644 arch/riscv/errata/sifive/errata_cip_453.S
+
+diff --git a/arch/riscv/Kconfig.erratas b/arch/riscv/Kconfig.erratas
+index 302e746..b4146dc 100644
+--- a/arch/riscv/Kconfig.erratas
++++ b/arch/riscv/Kconfig.erratas
+@@ -19,4 +19,15 @@ config ERRATA_SIFIVE
+         Otherwise, please say "N" here to avoid unnecessary overhead.
++config ERRATA_SIFIVE_CIP_453
++      bool "Apply SiFive errata CIP-453"
++      depends on ERRATA_SIFIVE
++      default y
++      help
++        This will apply the SiFive CIP-453 errata to add sign extension
++        to the $badaddr when exception type is instruction page fault
++        and instruction access fault.
++
++        If you don't know what to do here, say "Y".
++
+ endmenu
+diff --git a/arch/riscv/errata/sifive/Makefile b/arch/riscv/errata/sifive/Makefile
+index 2d644e1..bdd5fc8 100644
+--- a/arch/riscv/errata/sifive/Makefile
++++ b/arch/riscv/errata/sifive/Makefile
+@@ -1 +1,2 @@
++obj-y += errata_cip_453.o
+ obj-y += errata.o
+diff --git a/arch/riscv/errata/sifive/errata.c b/arch/riscv/errata/sifive/errata.c
+index 826cd39..e273918 100644
+--- a/arch/riscv/errata/sifive/errata.c
++++ b/arch/riscv/errata/sifive/errata.c
+@@ -16,6 +16,26 @@ struct errata_info_t {
+       bool (*check_func)(unsigned long  arch_id, unsigned long impid);
+ };
++static bool errata_cip_453_check_func(unsigned long  arch_id, unsigned long impid)
++{
++      /*
++       * Affected cores:
++       * Architecture ID: 0x8000000000000007
++       * Implement ID: 0x20181004 <= impid <= 0x20191105
++       */
++      if (arch_id != 0x8000000000000007 ||
++          (impid < 0x20181004 || impid > 0x20191105))
++              return false;
++      return true;
++}
++
++static struct errata_info_t errata_list[ERRATA_SIFIVE_NUMBER] = {
++      {
++              .name = "cip-453",
++              .check_func = errata_cip_453_check_func
++      },
++};
++
+ static u32 __init sifive_errata_probe(unsigned long archid, unsigned long impid)
+ {
+       int idx;
+diff --git a/arch/riscv/errata/sifive/errata_cip_453.S b/arch/riscv/errata/sifive/errata_cip_453.S
+new file mode 100644
+index 00000000..f1b9623
+--- /dev/null
++++ b/arch/riscv/errata/sifive/errata_cip_453.S
+@@ -0,0 +1,38 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2021 SiFive
++ */
++
++#include <linux/linkage.h>
++#include <asm/asm.h>
++#include <asm/asm-offsets.h>
++#include <asm/alternative.h>
++
++.macro ADD_SIGN_EXT pt_reg badaddr tmp_reg
++      REG_L \badaddr, PT_BADADDR(\pt_reg)
++      li \tmp_reg,1
++      slli \tmp_reg,\tmp_reg,0x26
++      and \tmp_reg,\tmp_reg,\badaddr
++      beqz \tmp_reg, 1f
++      li \tmp_reg,-1
++      slli \tmp_reg,\tmp_reg,0x27
++      or \badaddr,\tmp_reg,\badaddr
++      REG_S \badaddr, PT_BADADDR(\pt_reg)
++1:
++.endm
++
++ENTRY(sifive_cip_453_page_fault_trp)
++      ADD_SIGN_EXT a0, t0, t1
++#ifdef CONFIG_MMU
++      la t0, do_page_fault
++#else
++      la t0, do_trap_unknown
++#endif
++      jr t0
++END(sifive_cip_453_page_fault_trp)
++
++ENTRY(sifive_cip_453_insn_fault_trp)
++      ADD_SIGN_EXT a0, t0, t1
++      la t0, do_trap_insn_fault
++      jr t0
++END(sifive_cip_453_insn_fault_trp)
+diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
+index 1b56131..6148d34 100644
+--- a/arch/riscv/include/asm/errata_list.h
++++ b/arch/riscv/include/asm/errata_list.h
+@@ -5,8 +5,27 @@
+ #ifndef ASM_ERRATA_LIST_H
+ #define ASM_ERRATA_LIST_H
++#include <asm/alternative.h>
++#include <asm/vendorid_list.h>
++
+ #ifdef CONFIG_ERRATA_SIFIVE
+-#define       ERRATA_SIFIVE_NUMBER 0
++#define       ERRATA_SIFIVE_CIP_453 0
++#define       ERRATA_SIFIVE_NUMBER 1
+ #endif
++#ifdef __ASSEMBLY__
++
++#define ALT_INSN_FAULT(x)                                             \
++ALTERNATIVE(__stringify(RISCV_PTR do_trap_insn_fault),                        \
++          __stringify(RISCV_PTR sifive_cip_453_insn_fault_trp),       \
++          SIFIVE_VENDOR_ID, ERRATA_SIFIVE_CIP_453,                    \
++          CONFIG_ERRATA_SIFIVE_CIP_453)
++
++#define ALT_PAGE_FAULT(x)                                             \
++ALTERNATIVE(__stringify(RISCV_PTR do_page_fault),                     \
++          __stringify(RISCV_PTR sifive_cip_453_page_fault_trp),       \
++          SIFIVE_VENDOR_ID, ERRATA_SIFIVE_CIP_453,                    \
++          CONFIG_ERRATA_SIFIVE_CIP_453)
++#endif /* __ASSEMBLY__ */
++
+ #endif
+diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
+index 744f320..60d0a2f 100644
+--- a/arch/riscv/kernel/entry.S
++++ b/arch/riscv/kernel/entry.S
+@@ -12,6 +12,7 @@
+ #include <asm/unistd.h>
+ #include <asm/thread_info.h>
+ #include <asm/asm-offsets.h>
++#include <asm/errata_list.h>
+ #if !IS_ENABLED(CONFIG_PREEMPTION)
+ .set resume_kernel, restore_all
+@@ -450,7 +451,7 @@ ENDPROC(__switch_to)
+       /* Exception vector table */
+ ENTRY(excp_vect_table)
+       RISCV_PTR do_trap_insn_misaligned
+-      RISCV_PTR do_trap_insn_fault
++      ALT_INSN_FAULT(RISCV_PTR do_trap_insn_fault)
+       RISCV_PTR do_trap_insn_illegal
+       RISCV_PTR do_trap_break
+       RISCV_PTR do_trap_load_misaligned
+@@ -461,7 +462,8 @@ ENTRY(excp_vect_table)
+       RISCV_PTR do_trap_ecall_s
+       RISCV_PTR do_trap_unknown
+       RISCV_PTR do_trap_ecall_m
+-      RISCV_PTR do_page_fault   /* instruction page fault */
++      /* instruciton page fault */
++      ALT_PAGE_FAULT(RISCV_PTR do_page_fault)
+       RISCV_PTR do_page_fault   /* load page fault */
+       RISCV_PTR do_trap_unknown
+       RISCV_PTR do_page_fault   /* store page fault */
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0016-riscv-sifive-Apply-errata-cip-1200-patch.patch b/target/linux/hifiveu/patches-5.10/0016-riscv-sifive-Apply-errata-cip-1200-patch.patch
new file mode 100644 (file)
index 0000000..2a86293
--- /dev/null
@@ -0,0 +1,125 @@
+From 00238b2b634a61b51f7aa1433786d1f8473fa94e Mon Sep 17 00:00:00 2001
+From: Vincent Chen <[email protected]>
+Date: Mon, 22 Mar 2021 22:26:06 +0800
+Subject: [PATCH 16/28] riscv: sifive: Apply errata "cip-1200" patch
+
+For certain SiFive CPUs, "sfence.vma addr" cannot exactly flush addr
+from TLB in the particular cases. The details could be found here:
+https://sifive.cdn.prismic.io/sifive/167a1a56-03f4-4615-a79e-b2a86153148f_FU740_errata_20210205.pdf
+In order to ensure the functionality, this patch uses the Alternative
+scheme to replace all "sfence.vma addr" with "sfence.vma" at runtime.
+
+Signed-off-by: Vincent Chen <[email protected]>
+---
+ arch/riscv/Kconfig.erratas           | 11 +++++++++++
+ arch/riscv/errata/sifive/errata.c    | 18 ++++++++++++++++++
+ arch/riscv/include/asm/errata_list.h | 10 +++++++++-
+ arch/riscv/include/asm/tlbflush.h    |  3 ++-
+ 4 files changed, 40 insertions(+), 2 deletions(-)
+
+diff --git a/arch/riscv/Kconfig.erratas b/arch/riscv/Kconfig.erratas
+index b4146dc..d5d03ae 100644
+--- a/arch/riscv/Kconfig.erratas
++++ b/arch/riscv/Kconfig.erratas
+@@ -30,4 +30,15 @@ config ERRATA_SIFIVE_CIP_453
+         If you don't know what to do here, say "Y".
++config ERRATA_SIFIVE_CIP_1200
++      bool "Apply SiFive errata CIP-1200"
++      depends on ERRATA_SIFIVE
++      default y
++      help
++        This will apply the SiFive CIP-1200 errata to repalce all
++        "sfence.vma addr" with "sfence.vma" to ensure that the addr
++        has been flushed from TLB.
++
++        If you don't know what to do here, say "Y".
++
+ endmenu
+diff --git a/arch/riscv/errata/sifive/errata.c b/arch/riscv/errata/sifive/errata.c
+index e273918..f5e5ae7 100644
+--- a/arch/riscv/errata/sifive/errata.c
++++ b/arch/riscv/errata/sifive/errata.c
+@@ -29,11 +29,29 @@ static bool errata_cip_453_check_func(unsigned long  arch_id, unsigned long impi
+       return true;
+ }
++static bool errata_cip_1200_check_func(unsigned long  arch_id, unsigned long impid)
++{
++      /*
++       * Affected cores:
++       * Architecture ID: 0x8000000000000007 or 0x1
++       * Implement ID: mimpid[23:0] <= 0x200630 and mimpid != 0x01200626
++       */
++      if (arch_id != 0x8000000000000007 && arch_id != 0x1)
++              return false;
++      if ((impid & 0xffffff) > 0x200630 || impid == 0x1200626)
++              return false;
++      return true;
++}
++
+ static struct errata_info_t errata_list[ERRATA_SIFIVE_NUMBER] = {
+       {
+               .name = "cip-453",
+               .check_func = errata_cip_453_check_func
+       },
++      {
++              .name = "cip-1200",
++              .check_func = errata_cip_1200_check_func
++      },
+ };
+ static u32 __init sifive_errata_probe(unsigned long archid, unsigned long impid)
+diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
+index 6148d34..5f1046e 100644
+--- a/arch/riscv/include/asm/errata_list.h
++++ b/arch/riscv/include/asm/errata_list.h
+@@ -10,7 +10,8 @@
+ #ifdef CONFIG_ERRATA_SIFIVE
+ #define       ERRATA_SIFIVE_CIP_453 0
+-#define       ERRATA_SIFIVE_NUMBER 1
++#define       ERRATA_SIFIVE_CIP_1200 1
++#define       ERRATA_SIFIVE_NUMBER 2
+ #endif
+ #ifdef __ASSEMBLY__
+@@ -26,6 +27,13 @@ ALTERNATIVE(__stringify(RISCV_PTR do_page_fault),                   \
+           __stringify(RISCV_PTR sifive_cip_453_page_fault_trp),       \
+           SIFIVE_VENDOR_ID, ERRATA_SIFIVE_CIP_453,                    \
+           CONFIG_ERRATA_SIFIVE_CIP_453)
++#else /* !__ASSEMBLY__ */
++
++#define ALT_FLUSH_TLB_PAGE(x)                                         \
++asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID,      \
++              ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200)  \
++              : : "r" (addr) : "memory")
++
+ #endif /* __ASSEMBLY__ */
+ #endif
+diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
+index 394cfbc..c84218a 100644
+--- a/arch/riscv/include/asm/tlbflush.h
++++ b/arch/riscv/include/asm/tlbflush.h
+@@ -9,6 +9,7 @@
+ #include <linux/mm_types.h>
+ #include <asm/smp.h>
++#include <asm/errata_list.h>
+ #ifdef CONFIG_MMU
+ static inline void local_flush_tlb_all(void)
+@@ -19,7 +20,7 @@ static inline void local_flush_tlb_all(void)
+ /* Flush one page from local TLB */
+ static inline void local_flush_tlb_page(unsigned long addr)
+ {
+-      __asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory");
++      ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory"));
+ }
+ #else /* CONFIG_MMU */
+ #define local_flush_tlb_all()                 do { } while (0)
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0017-clk-sifive-Add-pcie_aux-clock-in-prci-driver-for-PCI.patch b/target/linux/hifiveu/patches-5.10/0017-clk-sifive-Add-pcie_aux-clock-in-prci-driver-for-PCI.patch
new file mode 100644 (file)
index 0000000..00b7ba9
--- /dev/null
@@ -0,0 +1,151 @@
+From 1b27caf83ab572e422069caa8217391f7fbcb7e3 Mon Sep 17 00:00:00 2001
+From: Greentime Hu <[email protected]>
+Date: Tue, 6 Apr 2021 17:26:29 +0800
+Subject: [PATCH 17/28] clk: sifive: Add pcie_aux clock in prci driver for PCIe
+ driver
+
+We add pcie_aux clock in this patch so that pcie driver can use
+clk_prepare_enable() and clk_disable_unprepare() to enable and disable
+pcie_aux clock.
+
+Signed-off-by: Greentime Hu <[email protected]>
+Acked-by: Stephen Boyd <[email protected]>
+---
+ drivers/clk/sifive/fu740-prci.c               | 11 +++++++
+ drivers/clk/sifive/fu740-prci.h               |  2 +-
+ drivers/clk/sifive/sifive-prci.c              | 41 +++++++++++++++++++++++++++
+ drivers/clk/sifive/sifive-prci.h              |  9 ++++++
+ include/dt-bindings/clock/sifive-fu740-prci.h |  1 +
+ 5 files changed, 63 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
+index 764d109..53f6e00 100644
+--- a/drivers/clk/sifive/fu740-prci.c
++++ b/drivers/clk/sifive/fu740-prci.c
+@@ -72,6 +72,12 @@ static const struct clk_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = {
+       .recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
+ };
++static const struct clk_ops sifive_fu740_prci_pcie_aux_clk_ops = {
++      .enable = sifive_prci_pcie_aux_clock_enable,
++      .disable = sifive_prci_pcie_aux_clock_disable,
++      .is_enabled = sifive_prci_pcie_aux_clock_is_enabled,
++};
++
+ /* List of clock controls provided by the PRCI */
+ struct __prci_clock __prci_init_clocks_fu740[] = {
+       [PRCI_CLK_COREPLL] = {
+@@ -120,4 +126,9 @@ struct __prci_clock __prci_init_clocks_fu740[] = {
+               .parent_name = "hfpclkpll",
+               .ops = &sifive_fu740_prci_hfpclkplldiv_clk_ops,
+       },
++      [PRCI_CLK_PCIE_AUX] = {
++              .name = "pcie_aux",
++              .parent_name = "hfclk",
++              .ops = &sifive_fu740_prci_pcie_aux_clk_ops,
++      },
+ };
+diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h
+index 13ef971f7..511a0bf 100644
+--- a/drivers/clk/sifive/fu740-prci.h
++++ b/drivers/clk/sifive/fu740-prci.h
+@@ -9,7 +9,7 @@
+ #include "sifive-prci.h"
+-#define NUM_CLOCK_FU740       8
++#define NUM_CLOCK_FU740       9
+ extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740];
+diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
+index c78b042..8fdba5d 100644
+--- a/drivers/clk/sifive/sifive-prci.c
++++ b/drivers/clk/sifive/sifive-prci.c
+@@ -448,6 +448,47 @@ void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd)
+       r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
+ }
++/* PCIE AUX clock APIs for enable, disable. */
++int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw)
++{
++      struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
++      struct __prci_data *pd = pc->pd;
++      u32 r;
++
++      r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET);
++
++      if (r & PRCI_PCIE_AUX_EN_MASK)
++              return 1;
++      else
++              return 0;
++}
++
++int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw)
++{
++      struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
++      struct __prci_data *pd = pc->pd;
++      u32 r __maybe_unused;
++
++      if (sifive_prci_pcie_aux_clock_is_enabled(hw))
++              return 0;
++
++      __prci_writel(1, PRCI_PCIE_AUX_OFFSET, pd);
++      r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET);     /* barrier */
++
++      return 0;
++}
++
++void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw)
++{
++      struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
++      struct __prci_data *pd = pc->pd;
++      u32 r __maybe_unused;
++
++      __prci_writel(0, PRCI_PCIE_AUX_OFFSET, pd);
++      r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET);     /* barrier */
++
++}
++
+ /**
+  * __prci_register_clocks() - register clock controls in the PRCI
+  * @dev: Linux struct device
+diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
+index dbdbd17..022c67c 100644
+--- a/drivers/clk/sifive/sifive-prci.h
++++ b/drivers/clk/sifive/sifive-prci.h
+@@ -67,6 +67,11 @@
+ #define PRCI_DDRPLLCFG1_CKE_SHIFT     31
+ #define PRCI_DDRPLLCFG1_CKE_MASK      (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
++/* PCIEAUX */
++#define PRCI_PCIE_AUX_OFFSET          0x14
++#define PRCI_PCIE_AUX_EN_SHIFT                0
++#define PRCI_PCIE_AUX_EN_MASK         (0x1 << PRCI_PCIE_AUX_EN_SHIFT)
++
+ /* GEMGXLPLLCFG0 */
+ #define PRCI_GEMGXLPLLCFG0_OFFSET     0x1c
+ #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0
+@@ -296,4 +301,8 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw,
+ unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
+                                                  unsigned long parent_rate);
++int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
++int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
++void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
++
+ #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
+diff --git a/include/dt-bindings/clock/sifive-fu740-prci.h b/include/dt-bindings/clock/sifive-fu740-prci.h
+index cd7706e..7899b7f 100644
+--- a/include/dt-bindings/clock/sifive-fu740-prci.h
++++ b/include/dt-bindings/clock/sifive-fu740-prci.h
+@@ -19,5 +19,6 @@
+ #define PRCI_CLK_CLTXPLL             5
+ #define PRCI_CLK_TLCLK                       6
+ #define PRCI_CLK_PCLK                7
++#define PRCI_CLK_PCIE_AUX            8
+ #endif        /* __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H */
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0018-clk-sifive-Use-reset-simple-in-prci-driver-for-PCIe-.patch b/target/linux/hifiveu/patches-5.10/0018-clk-sifive-Use-reset-simple-in-prci-driver-for-PCIe-.patch
new file mode 100644 (file)
index 0000000..d213194
--- /dev/null
@@ -0,0 +1,101 @@
+From e52c5adad77711186c6d8a0e972ec3302bb69d63 Mon Sep 17 00:00:00 2001
+From: Greentime Hu <[email protected]>
+Date: Tue, 6 Apr 2021 17:26:30 +0800
+Subject: [PATCH 18/28] clk: sifive: Use reset-simple in prci driver for PCIe
+ driver
+
+We use reset-simple in this patch so that pcie driver can use
+devm_reset_control_get() to get this reset data structure and use
+reset_control_deassert() to deassert pcie_power_up_rst_n.
+
+Signed-off-by: Greentime Hu <[email protected]>
+Reviewed-by: Philipp Zabel <[email protected]>
+Acked-by: Stephen Boyd <[email protected]>
+---
+ drivers/clk/sifive/Kconfig       |  2 ++
+ drivers/clk/sifive/sifive-prci.c | 13 +++++++++++++
+ drivers/clk/sifive/sifive-prci.h |  4 ++++
+ drivers/reset/Kconfig            |  1 +
+ 4 files changed, 20 insertions(+)
+
+diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
+index 1c14eb2..9132c3c 100644
+--- a/drivers/clk/sifive/Kconfig
++++ b/drivers/clk/sifive/Kconfig
+@@ -10,6 +10,8 @@ if CLK_SIFIVE
+ config CLK_SIFIVE_PRCI
+       bool "PRCI driver for SiFive SoCs"
++      select RESET_CONTROLLER
++      select RESET_SIMPLE
+       select CLK_ANALOGBITS_WRPLL_CLN28HPC
+       help
+         Supports the Power Reset Clock interface (PRCI) IP block found in
+diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
+index 8fdba5d..0704fdd 100644
+--- a/drivers/clk/sifive/sifive-prci.c
++++ b/drivers/clk/sifive/sifive-prci.c
+@@ -583,6 +583,19 @@ static int sifive_prci_probe(struct platform_device *pdev)
+       if (IS_ERR(pd->va))
+               return PTR_ERR(pd->va);
++      pd->reset.rcdev.owner = THIS_MODULE;
++      pd->reset.rcdev.nr_resets = PRCI_RST_NR;
++      pd->reset.rcdev.ops = &reset_simple_ops;
++      pd->reset.rcdev.of_node = pdev->dev.of_node;
++      pd->reset.active_low = true;
++      pd->reset.membase = pd->va + PRCI_DEVICESRESETREG_OFFSET;
++      spin_lock_init(&pd->reset.lock);
++
++      r = devm_reset_controller_register(&pdev->dev, &pd->reset.rcdev);
++      if (r) {
++              dev_err(dev, "could not register reset controller: %d\n", r);
++              return r;
++      }
+       r = __prci_register_clocks(dev, pd, desc);
+       if (r) {
+               dev_err(dev, "could not register clocks: %d\n", r);
+diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
+index 022c67c..91658a8 100644
+--- a/drivers/clk/sifive/sifive-prci.h
++++ b/drivers/clk/sifive/sifive-prci.h
+@@ -11,6 +11,7 @@
+ #include <linux/clk/analogbits-wrpll-cln28hpc.h>
+ #include <linux/clk-provider.h>
++#include <linux/reset/reset-simple.h>
+ #include <linux/platform_device.h>
+ /*
+@@ -121,6 +122,8 @@
+ #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK                      \
+               (0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
++#define PRCI_RST_NR                                           7
++
+ /* CLKMUXSTATUSREG */
+ #define PRCI_CLKMUXSTATUSREG_OFFSET                           0x2c
+ #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT            1
+@@ -221,6 +224,7 @@
+  */
+ struct __prci_data {
+       void __iomem *va;
++      struct reset_simple_data reset;
+       struct clk_hw_onecell_data hw_clks;
+ };
+diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
+index 71ab75a..d0f5d0a 100644
+--- a/drivers/reset/Kconfig
++++ b/drivers/reset/Kconfig
+@@ -187,6 +187,7 @@ config RESET_SIMPLE
+          - RCC reset controller in STM32 MCUs
+          - Allwinner SoCs
+          - ZTE's zx2967 family
++         - SiFive FU740 SoCs
+ config RESET_STM32MP157
+       bool "STM32MP157 Reset Driver" if COMPILE_TEST
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0021-PCI-fu740-Add-SiFive-FU740-PCIe-host-controller-driv.patch b/target/linux/hifiveu/patches-5.10/0021-PCI-fu740-Add-SiFive-FU740-PCIe-host-controller-driv.patch
new file mode 100644 (file)
index 0000000..2a2645f
--- /dev/null
@@ -0,0 +1,371 @@
+From e59df5889b82f239eb324e81599108ae75584438 Mon Sep 17 00:00:00 2001
+From: Paul Walmsley <[email protected]>
+Date: Tue, 6 Apr 2021 17:26:33 +0800
+Subject: [PATCH 21/28] PCI: fu740: Add SiFive FU740 PCIe host controller
+ driver
+
+Add driver for the SiFive FU740 PCIe host controller.
+This controller is based on the DesignWare PCIe core.
+
+Signed-off-by: Paul Walmsley <[email protected]>
+Co-developed-by: Henry Styles <[email protected]>
+Signed-off-by: Henry Styles <[email protected]>
+Co-developed-by: Erik Danie <[email protected]>
+Signed-off-by: Erik Danie <[email protected]>
+Co-developed-by: Greentime Hu <[email protected]>
+Signed-off-by: Greentime Hu <[email protected]>
+Reviewed-by: Rob Herring <[email protected]>
+---
+ drivers/pci/controller/dwc/Kconfig      |   9 +
+ drivers/pci/controller/dwc/Makefile     |   1 +
+ drivers/pci/controller/dwc/pcie-fu740.c | 308 ++++++++++++++++++++++++++++++++
+ 3 files changed, 318 insertions(+)
+ create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c
+
+diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
+index 22c5529..0a37d21 100644
+--- a/drivers/pci/controller/dwc/Kconfig
++++ b/drivers/pci/controller/dwc/Kconfig
+@@ -318,4 +318,13 @@ config PCIE_AL
+         required only for DT-based platforms. ACPI platforms with the
+         Annapurna Labs PCIe controller don't need to enable this.
++config PCIE_FU740
++      bool "SiFive FU740 PCIe host controller"
++      depends on PCI_MSI_IRQ_DOMAIN
++      depends on SOC_SIFIVE || COMPILE_TEST
++      select PCIE_DW_HOST
++      help
++        Say Y here if you want PCIe controller support for the SiFive
++        FU740.
++
+ endmenu
+diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
+index a751553..625f6aa 100644
+--- a/drivers/pci/controller/dwc/Makefile
++++ b/drivers/pci/controller/dwc/Makefile
+@@ -5,6 +5,7 @@ obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
+ obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
+ obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
+ obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
++obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
+ obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
+ obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
+diff --git a/drivers/pci/controller/dwc/pcie-fu740.c b/drivers/pci/controller/dwc/pcie-fu740.c
+new file mode 100644
+index 00000000..f8abb08
+--- /dev/null
++++ b/drivers/pci/controller/dwc/pcie-fu740.c
+@@ -0,0 +1,308 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * FU740 DesignWare PCIe Controller integration
++ * Copyright (C) 2019-2021 SiFive, Inc.
++ * Paul Walmsley
++ * Greentime Hu
++ *
++ * Based in part on the i.MX6 PCIe host controller shim which is:
++ *
++ * Copyright (C) 2013 Kosagi
++ *            https://www.kosagi.com
++ */
++
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/gpio.h>
++#include <linux/kernel.h>
++#include <linux/mfd/syscon.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/platform_device.h>
++#include <linux/regulator/consumer.h>
++#include <linux/resource.h>
++#include <linux/types.h>
++#include <linux/interrupt.h>
++#include <linux/iopoll.h>
++#include <linux/reset.h>
++
++#include "pcie-designware.h"
++
++#define to_fu740_pcie(x)      dev_get_drvdata((x)->dev)
++
++struct fu740_pcie {
++      struct dw_pcie pci;
++      void __iomem *mgmt_base;
++      struct gpio_desc *reset;
++      struct gpio_desc *pwren;
++      struct clk *pcie_aux;
++      struct reset_control *rst;
++};
++
++#define SIFIVE_DEVICESRESETREG                0x28
++
++#define PCIEX8MGMT_PERST_N            0x0
++#define PCIEX8MGMT_APP_LTSSM_ENABLE   0x10
++#define PCIEX8MGMT_APP_HOLD_PHY_RST   0x18
++#define PCIEX8MGMT_DEVICE_TYPE                0x708
++#define PCIEX8MGMT_PHY0_CR_PARA_ADDR  0x860
++#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN 0x870
++#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA       0x878
++#define PCIEX8MGMT_PHY0_CR_PARA_SEL   0x880
++#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA       0x888
++#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN 0x890
++#define PCIEX8MGMT_PHY0_CR_PARA_ACK   0x898
++#define PCIEX8MGMT_PHY1_CR_PARA_ADDR  0x8a0
++#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN 0x8b0
++#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA       0x8b8
++#define PCIEX8MGMT_PHY1_CR_PARA_SEL   0x8c0
++#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA       0x8c8
++#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN 0x8d0
++#define PCIEX8MGMT_PHY1_CR_PARA_ACK   0x8d8
++
++#define PCIEX8MGMT_PHY_CDR_TRACK_EN   BIT(0)
++#define PCIEX8MGMT_PHY_LOS_THRSHLD    BIT(5)
++#define PCIEX8MGMT_PHY_TERM_EN                BIT(9)
++#define PCIEX8MGMT_PHY_TERM_ACDC      BIT(10)
++#define PCIEX8MGMT_PHY_EN             BIT(11)
++#define PCIEX8MGMT_PHY_INIT_VAL               (PCIEX8MGMT_PHY_CDR_TRACK_EN|\
++                                       PCIEX8MGMT_PHY_LOS_THRSHLD|\
++                                       PCIEX8MGMT_PHY_TERM_EN|\
++                                       PCIEX8MGMT_PHY_TERM_ACDC|\
++                                       PCIEX8MGMT_PHY_EN)
++
++#define PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3    0x1008
++#define PCIEX8MGMT_PHY_LANE_OFF               0x100
++#define PCIEX8MGMT_PHY_LANE0_BASE     (PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 0)
++#define PCIEX8MGMT_PHY_LANE1_BASE     (PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 1)
++#define PCIEX8MGMT_PHY_LANE2_BASE     (PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 2)
++#define PCIEX8MGMT_PHY_LANE3_BASE     (PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 3)
++
++static void fu740_pcie_assert_reset(struct fu740_pcie *afp)
++{
++      /* Assert PERST_N GPIO */
++      gpiod_set_value_cansleep(afp->reset, 0);
++      /* Assert controller PERST_N */
++      writel_relaxed(0x0, afp->mgmt_base + PCIEX8MGMT_PERST_N);
++}
++
++static void fu740_pcie_deassert_reset(struct fu740_pcie *afp)
++{
++      /* Deassert controller PERST_N */
++      writel_relaxed(0x1, afp->mgmt_base + PCIEX8MGMT_PERST_N);
++      /* Deassert PERST_N GPIO */
++      gpiod_set_value_cansleep(afp->reset, 1);
++}
++
++static void fu740_pcie_power_on(struct fu740_pcie *afp)
++{
++      gpiod_set_value_cansleep(afp->pwren, 1);
++      /*
++       * Ensure that PERST has been asserted for at least 100 ms.
++       * Section 2.2 of PCI Express Card Electromechanical Specification
++       * Revision 3.0
++       */
++      msleep(100);
++}
++
++static void fu740_pcie_drive_reset(struct fu740_pcie *afp)
++{
++      fu740_pcie_assert_reset(afp);
++      fu740_pcie_power_on(afp);
++      fu740_pcie_deassert_reset(afp);
++}
++
++static void fu740_phyregwrite(const uint8_t phy, const uint16_t addr,
++                            const uint16_t wrdata, struct fu740_pcie *afp)
++{
++      struct device *dev = afp->pci.dev;
++      void __iomem *phy_cr_para_addr;
++      void __iomem *phy_cr_para_wr_data;
++      void __iomem *phy_cr_para_wr_en;
++      void __iomem *phy_cr_para_ack;
++      int ret, val;
++
++      /* Setup */
++      if (phy) {
++              phy_cr_para_addr = afp->mgmt_base + PCIEX8MGMT_PHY1_CR_PARA_ADDR;
++              phy_cr_para_wr_data = afp->mgmt_base + PCIEX8MGMT_PHY1_CR_PARA_WR_DATA;
++              phy_cr_para_wr_en = afp->mgmt_base + PCIEX8MGMT_PHY1_CR_PARA_WR_EN;
++              phy_cr_para_ack = afp->mgmt_base + PCIEX8MGMT_PHY1_CR_PARA_ACK;
++      } else {
++              phy_cr_para_addr = afp->mgmt_base + PCIEX8MGMT_PHY0_CR_PARA_ADDR;
++              phy_cr_para_wr_data = afp->mgmt_base + PCIEX8MGMT_PHY0_CR_PARA_WR_DATA;
++              phy_cr_para_wr_en = afp->mgmt_base + PCIEX8MGMT_PHY0_CR_PARA_WR_EN;
++              phy_cr_para_ack = afp->mgmt_base + PCIEX8MGMT_PHY0_CR_PARA_ACK;
++      }
++
++      writel_relaxed(addr, phy_cr_para_addr);
++      writel_relaxed(wrdata, phy_cr_para_wr_data);
++      writel_relaxed(1, phy_cr_para_wr_en);
++
++      /* Wait for wait_idle */
++      ret = readl_poll_timeout(phy_cr_para_ack, val, val, 10, 5000);
++      if (ret)
++              dev_warn(dev, "Wait for wait_idle state failed!\n");
++
++      /* Clear */
++      writel_relaxed(0, phy_cr_para_wr_en);
++
++      /* Wait for ~wait_idle */
++      ret = readl_poll_timeout(phy_cr_para_ack, val, !val, 10, 5000);
++      if (ret)
++              dev_warn(dev, "Wait for !wait_idle state failed!\n");
++}
++
++static void fu740_pcie_init_phy(struct fu740_pcie *afp)
++{
++      /* Enable phy cr_para_sel interfaces */
++      writel_relaxed(0x1, afp->mgmt_base + PCIEX8MGMT_PHY0_CR_PARA_SEL);
++      writel_relaxed(0x1, afp->mgmt_base + PCIEX8MGMT_PHY1_CR_PARA_SEL);
++
++      /*
++       * Wait 10 cr_para cycles to guarantee that the registers are ready
++       * to be edited.
++       */
++      ndelay(10);
++
++      /* Set PHY AC termination mode */
++      fu740_phyregwrite(0, PCIEX8MGMT_PHY_LANE0_BASE, PCIEX8MGMT_PHY_INIT_VAL, afp);
++      fu740_phyregwrite(0, PCIEX8MGMT_PHY_LANE1_BASE, PCIEX8MGMT_PHY_INIT_VAL, afp);
++      fu740_phyregwrite(0, PCIEX8MGMT_PHY_LANE2_BASE, PCIEX8MGMT_PHY_INIT_VAL, afp);
++      fu740_phyregwrite(0, PCIEX8MGMT_PHY_LANE3_BASE, PCIEX8MGMT_PHY_INIT_VAL, afp);
++      fu740_phyregwrite(1, PCIEX8MGMT_PHY_LANE0_BASE, PCIEX8MGMT_PHY_INIT_VAL, afp);
++      fu740_phyregwrite(1, PCIEX8MGMT_PHY_LANE1_BASE, PCIEX8MGMT_PHY_INIT_VAL, afp);
++      fu740_phyregwrite(1, PCIEX8MGMT_PHY_LANE2_BASE, PCIEX8MGMT_PHY_INIT_VAL, afp);
++      fu740_phyregwrite(1, PCIEX8MGMT_PHY_LANE3_BASE, PCIEX8MGMT_PHY_INIT_VAL, afp);
++}
++
++static int fu740_pcie_start_link(struct dw_pcie *pci)
++{
++      struct device *dev = pci->dev;
++      struct fu740_pcie *afp = dev_get_drvdata(dev);
++
++      /* Enable LTSSM */
++      writel_relaxed(0x1, afp->mgmt_base + PCIEX8MGMT_APP_LTSSM_ENABLE);
++      return 0;
++}
++
++static int fu740_pcie_host_init(struct pcie_port *pp)
++{
++      struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
++      struct fu740_pcie *afp = to_fu740_pcie(pci);
++      struct device *dev = pci->dev;
++      int ret;
++
++      /* Power on reset */
++      fu740_pcie_drive_reset(afp);
++
++      /* Enable pcieauxclk */
++      ret = clk_prepare_enable(afp->pcie_aux);
++      if (ret) {
++              dev_err(dev, "unable to enable pcie_aux clock\n");
++              return ret;
++      }
++
++      /*
++       * Assert hold_phy_rst (hold the controller LTSSM in reset after
++       * power_up_rst_n for register programming with cr_para)
++       */
++      writel_relaxed(0x1, afp->mgmt_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
++
++      /* Deassert power_up_rst_n */
++      ret = reset_control_deassert(afp->rst);
++      if (ret) {
++              dev_err(dev, "unable to deassert pcie_power_up_rst_n\n");
++              return ret;
++      }
++
++      fu740_pcie_init_phy(afp);
++
++      /* Disable pcieauxclk */
++      clk_disable_unprepare(afp->pcie_aux);
++      /* Clear hold_phy_rst */
++      writel_relaxed(0x0, afp->mgmt_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
++      /* Enable pcieauxclk */
++      ret = clk_prepare_enable(afp->pcie_aux);
++      /* Set RC mode */
++      writel_relaxed(0x4, afp->mgmt_base + PCIEX8MGMT_DEVICE_TYPE);
++
++      return 0;
++}
++
++static const struct dw_pcie_host_ops fu740_pcie_host_ops = {
++      .host_init = fu740_pcie_host_init,
++};
++
++static const struct dw_pcie_ops dw_pcie_ops = {
++      .start_link = fu740_pcie_start_link,
++};
++
++static int fu740_pcie_probe(struct platform_device *pdev)
++{
++      struct device *dev = &pdev->dev;
++      struct dw_pcie *pci;
++      struct fu740_pcie *afp;
++
++      afp = devm_kzalloc(dev, sizeof(*afp), GFP_KERNEL);
++      if (!afp)
++              return -ENOMEM;
++      pci = &afp->pci;
++      pci->dev = dev;
++      pci->ops = &dw_pcie_ops;
++      pci->pp.ops = &fu740_pcie_host_ops;
++
++      /* SiFive specific region: mgmt */
++      afp->mgmt_base = devm_platform_ioremap_resource_byname(pdev, "mgmt");
++      if (IS_ERR(afp->mgmt_base))
++              return PTR_ERR(afp->mgmt_base);
++
++      /* Fetch GPIOs */
++      afp->reset = devm_gpiod_get_optional(dev, "reset-gpios", GPIOD_OUT_LOW);
++      if (IS_ERR(afp->reset))
++              return dev_err_probe(dev, PTR_ERR(afp->reset), "unable to get reset-gpios\n");
++
++      afp->pwren = devm_gpiod_get_optional(dev, "pwren-gpios", GPIOD_OUT_LOW);
++      if (IS_ERR(afp->pwren))
++              return dev_err_probe(dev, PTR_ERR(afp->pwren), "unable to get pwren-gpios\n");
++
++      /* Fetch clocks */
++      afp->pcie_aux = devm_clk_get(dev, "pcie_aux");
++      if (IS_ERR(afp->pcie_aux))
++              return dev_err_probe(dev, PTR_ERR(afp->pcie_aux),
++                                           "pcie_aux clock source missing or invalid\n");
++
++      /* Fetch reset */
++      afp->rst = devm_reset_control_get_exclusive(dev, NULL);
++      if (IS_ERR(afp->rst))
++              return dev_err_probe(dev, PTR_ERR(afp->rst), "unable to get reset\n");
++
++      platform_set_drvdata(pdev, afp);
++
++      return dw_pcie_host_init(&pci->pp);
++}
++
++static void fu740_pcie_shutdown(struct platform_device *pdev)
++{
++      struct fu740_pcie *afp = platform_get_drvdata(pdev);
++
++      /* Bring down link, so bootloader gets clean state in case of reboot */
++      fu740_pcie_assert_reset(afp);
++}
++
++static const struct of_device_id fu740_pcie_of_match[] = {
++      { .compatible = "sifive,fu740-pcie", },
++      {},
++};
++
++static struct platform_driver fu740_pcie_driver = {
++      .driver = {
++                 .name = "fu740-pcie",
++                 .of_match_table = fu740_pcie_of_match,
++                 .suppress_bind_attrs = true,
++      },
++      .probe = fu740_pcie_probe,
++      .shutdown = fu740_pcie_shutdown,
++};
++
++builtin_platform_driver(fu740_pcie_driver);
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0022-riscv-dts-Add-PCIe-support-for-the-SiFive-FU740-C000.patch b/target/linux/hifiveu/patches-5.10/0022-riscv-dts-Add-PCIe-support-for-the-SiFive-FU740-C000.patch
new file mode 100644 (file)
index 0000000..1275ad9
--- /dev/null
@@ -0,0 +1,65 @@
+From 54c43398c4bc7cdedbabe3d40105c2e6e9d09c98 Mon Sep 17 00:00:00 2001
+From: Greentime Hu <[email protected]>
+Date: Tue, 6 Apr 2021 17:26:34 +0800
+Subject: [PATCH 22/28] riscv: dts: Add PCIe support for the SiFive FU740-C000
+ SoC
+
+Signed-off-by: Greentime Hu <[email protected]>
+Acked-by: Palmer Dabbelt <[email protected]>
+---
+ arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 33 ++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+index cd9cc02..3095d82 100644
+--- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
++++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+@@ -159,6 +159,7 @@
+                       reg = <0x0 0x10000000 0x0 0x1000>;
+                       clocks = <&hfclk>, <&rtcclk>;
+                       #clock-cells = <1>;
++                      #reset-cells = <1>;
+               };
+               uart0: serial@10010000 {
+                       compatible = "sifive,fu740-c000-uart", "sifive,uart0";
+@@ -289,5 +290,37 @@
+                       clocks = <&prci PRCI_CLK_PCLK>;
+                       status = "disabled";
+               };
++              pcie@e00000000 {
++                      compatible = "sifive,fu740-pcie";
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++                      #interrupt-cells = <1>;
++                      reg = <0xe 0x00000000 0x0 0x80000000>,
++                            <0xd 0xf0000000 0x0 0x10000000>,
++                            <0x0 0x100d0000 0x0 0x1000>;
++                      reg-names = "dbi", "config", "mgmt";
++                      device_type = "pci";
++                      dma-coherent;
++                      bus-range = <0x0 0xff>;
++                      ranges = <0x81000000  0x0 0x60080000  0x0 0x60080000 0x0 0x10000>,      /* I/O */
++                               <0x82000000  0x0 0x60090000  0x0 0x60090000 0x0 0xff70000>,    /* mem */
++                               <0x82000000  0x0 0x70000000  0x0 0x70000000 0x0 0x1000000>,    /* mem */
++                               <0xc3000000 0x20 0x00000000 0x20 0x00000000 0x20 0x00000000>;  /* mem prefetchable */
++                      num-lanes = <0x8>;
++                      interrupts = <56>, <57>, <58>, <59>, <60>, <61>, <62>, <63>, <64>;
++                      interrupt-names = "msi", "inta", "intb", "intc", "intd";
++                      interrupt-parent = <&plic0>;
++                      interrupt-map-mask = <0x0 0x0 0x0 0x7>;
++                      interrupt-map = <0x0 0x0 0x0 0x1 &plic0 57>,
++                                      <0x0 0x0 0x0 0x2 &plic0 58>,
++                                      <0x0 0x0 0x0 0x3 &plic0 59>,
++                                      <0x0 0x0 0x0 0x4 &plic0 60>;
++                      clock-names = "pcie_aux";
++                      clocks = <&prci PRCI_CLK_PCIE_AUX>;
++                      pwren-gpios = <&gpio 5 0>;
++                      reset-gpios = <&gpio 8 0>;
++                      resets = <&prci 4>;
++                      status = "okay";
++              };
+       };
+ };
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0023-riscv-sifive-unmatched-add-D12-PWM-LED.patch b/target/linux/hifiveu/patches-5.10/0023-riscv-sifive-unmatched-add-D12-PWM-LED.patch
new file mode 100644 (file)
index 0000000..9650bed
--- /dev/null
@@ -0,0 +1,43 @@
+From ce24ba4d603a19690548b986d87ae2d9af26d015 Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <[email protected]>
+Date: Thu, 25 Mar 2021 04:34:52 -0700
+Subject: [PATCH 23/28] riscv: sifive: unmatched: add D12 PWM LED
+
+Signed-off-by: David Abdurachmanov <[email protected]>
+---
+ arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+index e026f60..8461b33 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+@@ -3,6 +3,7 @@
+ #include "fu740-c000.dtsi"
+ #include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/pwm/pwm.h>
+ /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
+ #define RTCCLK_FREQ           1000000
+@@ -30,6 +31,17 @@
+       soc {
+       };
++      pwmleds {
++              compatible = "pwm-leds";
++              d12 {
++                      label = "green:d12";
++                      pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
++                      active-low = <1>;
++                      max-brightness = <255>;
++                      linux,default-trigger = "none";
++              };
++      };
++
+       hfclk: hfclk {
+               #clock-cells = <0>;
+               compatible = "fixed-clock";
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0024-riscv-sifive-unmatched-add-gpio-poweroff-node.patch b/target/linux/hifiveu/patches-5.10/0024-riscv-sifive-unmatched-add-gpio-poweroff-node.patch
new file mode 100644 (file)
index 0000000..a44c774
--- /dev/null
@@ -0,0 +1,37 @@
+From f19634daf24481664cdc89dc0b5abd9b622718f5 Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <[email protected]>
+Date: Thu, 25 Mar 2021 04:37:20 -0700
+Subject: [PATCH 24/28] riscv: sifive: unmatched: add gpio-poweroff node
+
+Signed-off-by: David Abdurachmanov <[email protected]>
+---
+ arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+index 8461b33..9a7fa9b 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+@@ -2,6 +2,7 @@
+ /* Copyright (c) 2020 SiFive, Inc */
+ #include "fu740-c000.dtsi"
++#include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/pwm/pwm.h>
+@@ -55,6 +56,11 @@
+               clock-frequency = <RTCCLK_FREQ>;
+               clock-output-names = "rtcclk";
+       };
++
++      gpio-poweroff {
++              compatible = "gpio-poweroff";
++              gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
++      };
+ };
+ &uart0 {
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0025-riscv-sifive-unmatched-add-D2-RGB-LED.patch b/target/linux/hifiveu/patches-5.10/0025-riscv-sifive-unmatched-add-D2-RGB-LED.patch
new file mode 100644 (file)
index 0000000..ad989eb
--- /dev/null
@@ -0,0 +1,56 @@
+From 2d375478fd6b5eeea711d081502cc8fd1a22987d Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <[email protected]>
+Date: Fri, 2 Apr 2021 06:31:07 -0700
+Subject: [PATCH 25/28] riscv: sifive: unmatched: add D2 RGB LED
+
+Signed-off-by: David Abdurachmanov <[email protected]>
+---
+ .../riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 26 +++++++++++++++++++++-
+ 1 file changed, 25 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+index 9a7fa9b..235f78a 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+@@ -34,13 +34,37 @@
+       pwmleds {
+               compatible = "pwm-leds";
+-              d12 {
++              green-d12 {
+                       label = "green:d12";
+                       pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
+                       active-low = <1>;
+                       max-brightness = <255>;
+                       linux,default-trigger = "none";
+               };
++
++              green-d2 {
++                      label = "green:d2";
++                      pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
++                      active-low = <1>;
++                      max-brightness = <255>;
++                      linux,default-trigger = "none";
++              };
++
++              red-d2 {
++                      label = "red:d2";
++                      pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
++                      active-low = <1>;
++                      max-brightness = <255>;
++                      linux,default-trigger = "none";
++              };
++
++              blue-d2 {
++                      label = "blue:d2";
++                      pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
++                      active-low = <1>;
++                      max-brightness = <255>;
++                      linux,default-trigger = "none";
++              };
+       };
+       hfclk: hfclk {
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0026-riscv-sifive-unmatched-remove-A00-from-model.patch b/target/linux/hifiveu/patches-5.10/0026-riscv-sifive-unmatched-remove-A00-from-model.patch
new file mode 100644 (file)
index 0000000..b3c3483
--- /dev/null
@@ -0,0 +1,26 @@
+From 45ed220373844f72e9ddb05ef0a8f2bd391e0980 Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <[email protected]>
+Date: Tue, 6 Apr 2021 05:00:11 -0700
+Subject: [PATCH 26/28] riscv: sifive: unmatched: remove "A00" from model
+
+Signed-off-by: David Abdurachmanov <[email protected]>
+---
+ arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+index 235f78a..5fdd183 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+@@ -12,7 +12,7 @@
+ / {
+       #address-cells = <2>;
+       #size-cells = <2>;
+-      model = "SiFive HiFive Unmatched A00";
++      model = "SiFive HiFive Unmatched";
+       compatible = "sifive,hifive-unmatched-a00", "sifive,fu740-c000",
+                    "sifive,fu740";
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0027-riscv-sifive-unmatched-define-LEDs-color.patch b/target/linux/hifiveu/patches-5.10/0027-riscv-sifive-unmatched-define-LEDs-color.patch
new file mode 100644 (file)
index 0000000..8d5d606
--- /dev/null
@@ -0,0 +1,57 @@
+From 665297adfa377a3682b261b23f2a6f3ec56daa8b Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <[email protected]>
+Date: Wed, 7 Apr 2021 06:08:33 -0700
+Subject: [PATCH 27/28] riscv: sifive: unmatched: define LEDs color
+
+Signed-off-by: David Abdurachmanov <[email protected]>
+---
+ arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+index 5fdd183..9be0564 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
+@@ -4,6 +4,7 @@
+ #include "fu740-c000.dtsi"
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
++#include <dt-bindings/leds/common.h>
+ #include <dt-bindings/pwm/pwm.h>
+ /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
+@@ -36,6 +37,7 @@
+               compatible = "pwm-leds";
+               green-d12 {
+                       label = "green:d12";
++                      color = <LED_COLOR_ID_GREEN>;
+                       pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
+                       active-low = <1>;
+                       max-brightness = <255>;
+@@ -44,6 +46,7 @@
+               green-d2 {
+                       label = "green:d2";
++                      color = <LED_COLOR_ID_GREEN>;
+                       pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
+                       active-low = <1>;
+                       max-brightness = <255>;
+@@ -52,6 +55,7 @@
+               red-d2 {
+                       label = "red:d2";
++                      color = <LED_COLOR_ID_RED>;
+                       pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
+                       active-low = <1>;
+                       max-brightness = <255>;
+@@ -60,6 +64,7 @@
+               blue-d2 {
+                       label = "blue:d2";
++                      color = <LED_COLOR_ID_BLUE>;
+                       pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
+                       active-low = <1>;
+                       max-brightness = <255>;
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0028-riscv-enable-generic-PCI-resource-mapping.patch b/target/linux/hifiveu/patches-5.10/0028-riscv-enable-generic-PCI-resource-mapping.patch
new file mode 100644 (file)
index 0000000..f27007b
--- /dev/null
@@ -0,0 +1,32 @@
+From 63d7d0e6553ed2990fec51b3f449e50153461650 Mon Sep 17 00:00:00 2001
+From: Stanislaw Kardach <[email protected]>
+Date: Mon, 12 Apr 2021 13:10:12 +0200
+Subject: [PATCH 28/28] riscv: enable generic PCI resource mapping
+
+Enable the PCI resource mapping on RISC-V using the generic framework.
+This allows userspace applications to mmap PCI resources using
+/sys/devices/pci*/*/resource* interface.
+The mmap has been tested with Intel x520-DA2 NIC card on a HiFive
+Unmatched board (SiFive FU740 SoC).
+
+Signed-off-by: Stanislaw Kardach <[email protected]>
+---
+ arch/riscv/include/asm/pci.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/riscv/include/asm/pci.h b/arch/riscv/include/asm/pci.h
+index 1c473a1..46e844f 100644
+--- a/arch/riscv/include/asm/pci.h
++++ b/arch/riscv/include/asm/pci.h
+@@ -18,6 +18,8 @@
+ /* RISC-V shim does not initialize PCI bus */
+ #define pcibios_assign_all_busses() 1
++#define ARCH_GENERIC_PCI_MMAP_RESOURCE 1
++
+ extern int isa_dma_bridge_buggy;
+ #ifdef CONFIG_PCI
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0104-SiFive-Unleashed-CPUFreq.patch b/target/linux/hifiveu/patches-5.10/0104-SiFive-Unleashed-CPUFreq.patch
new file mode 100644 (file)
index 0000000..aab74c0
--- /dev/null
@@ -0,0 +1,129 @@
+From 35f046065b988ea1b29df78728f5dbb6877aadc4 Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <[email protected]>
+Date: Tue, 28 Jan 2020 02:55:56 -0800
+Subject: [PATCH 4/7] SiFive Unleashed CPUFreq
+
+Source: https://github.com/sifive/riscv-linux/commits/dev/paulw/cpufreq-dt-aloe-v5.3-rc4
+
+Signed-off-by: David Abdurachmanov <[email protected]>
+Upstream-Status: Not posted for a review
+---
+ arch/riscv/Kconfig                                 |  8 +++++
+ arch/riscv/boot/dts/sifive/fu540-c000.dtsi         |  5 ++++
+ .../riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 34 ++++++++++++++++++++++
+ arch/riscv/configs/defconfig                       |  5 ++++
+ 4 files changed, 52 insertions(+)
+
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index fa7dc03..73b1138 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -356,6 +356,14 @@ endchoice
+ endmenu
++menu "CPU Power Management"
++
++source "drivers/cpuidle/Kconfig"
++
++source "drivers/cpufreq/Kconfig"
++
++endmenu
++
+ menu "Power management options"
+ source "kernel/power/Kconfig"
+diff --git a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
+index a2e3d54..a380bc7 100644
+--- a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
++++ b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
+@@ -30,6 +30,7 @@
+                       i-cache-size = <16384>;
+                       reg = <0>;
+                       riscv,isa = "rv64imac";
++                      clocks = <&prci PRCI_CLK_COREPLL>;
+                       status = "disabled";
+                       cpu0_intc: interrupt-controller {
+                               #interrupt-cells = <1>;
+@@ -54,6 +55,7 @@
+                       reg = <1>;
+                       riscv,isa = "rv64imafdc";
+                       tlb-split;
++                      clocks = <&prci PRCI_CLK_COREPLL>;
+                       next-level-cache = <&l2cache>;
+                       cpu1_intc: interrupt-controller {
+                               #interrupt-cells = <1>;
+@@ -78,6 +80,7 @@
+                       reg = <2>;
+                       riscv,isa = "rv64imafdc";
+                       tlb-split;
++                      clocks = <&prci PRCI_CLK_COREPLL>;
+                       next-level-cache = <&l2cache>;
+                       cpu2_intc: interrupt-controller {
+                               #interrupt-cells = <1>;
+@@ -102,6 +105,7 @@
+                       reg = <3>;
+                       riscv,isa = "rv64imafdc";
+                       tlb-split;
++                      clocks = <&prci PRCI_CLK_COREPLL>;
+                       next-level-cache = <&l2cache>;
+                       cpu3_intc: interrupt-controller {
+                               #interrupt-cells = <1>;
+@@ -126,6 +130,7 @@
+                       reg = <4>;
+                       riscv,isa = "rv64imafdc";
+                       tlb-split;
++                      clocks = <&prci PRCI_CLK_COREPLL>;
+                       next-level-cache = <&l2cache>;
+                       cpu4_intc: interrupt-controller {
+                               #interrupt-cells = <1>;
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+index 88cfcb9..e1724e3 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+@@ -41,6 +41,40 @@
+               clock-frequency = <RTCCLK_FREQ>;
+               clock-output-names = "rtcclk";
+       };
++
++      fu540_c000_opp_table: opp-table {
++              compatible = "operating-points-v2";
++              opp-shared;
++
++              opp-350000000 {
++                      opp-hz = /bits/ 64 <350000000>;
++              };
++              opp-700000000 {
++                      opp-hz = /bits/ 64 <700000000>;
++              };
++              opp-999999999 {
++                      opp-hz = /bits/ 64 <999999999>;
++              };
++              opp-1400000000 {
++                      opp-hz = /bits/ 64 <1400000000>;
++              };
++      };
++};
++
++&cpu0 {
++      operating-points-v2 = <&fu540_c000_opp_table>;
++};
++&cpu1 {
++      operating-points-v2 = <&fu540_c000_opp_table>;
++};
++&cpu2 {
++      operating-points-v2 = <&fu540_c000_opp_table>;
++};
++&cpu3 {
++      operating-points-v2 = <&fu540_c000_opp_table>;
++};
++&cpu4 {
++      operating-points-v2 = <&fu540_c000_opp_table>;
+ };
+ &uart0 {
+diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
+index e2ff95c..a2fb392 100644
+-- 
+2.7.4
+
diff --git a/target/linux/hifiveu/patches-5.10/0107-Add-PWM-LEDs-D1-D2-D3-D4.patch b/target/linux/hifiveu/patches-5.10/0107-Add-PWM-LEDs-D1-D2-D3-D4.patch
new file mode 100644 (file)
index 0000000..c79d1a1
--- /dev/null
@@ -0,0 +1,66 @@
+From c1c831af223931219b7bf9158b1306b500116167 Mon Sep 17 00:00:00 2001
+From: David Abdurachmanov <[email protected]>
+Date: Fri, 5 Jun 2020 07:02:10 +0000
+Subject: [PATCH] SiFive HiFive Unleashed: Add PWM LEDs (D1, D2, D3, D4)
+
+By default no functions are assigned to LEDs. It's up to user/distribution
+to provide udev rules to configure them.
+
+Signed-off-by: David Abdurachmanov <[email protected]>
+---
+ .../riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 32 ++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+index 6dd6fa4..c8a47bf 100644
+--- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
++++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+@@ -3,6 +3,7 @@
+ #include "fu540-c000.dtsi"
+ #include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/pwm/pwm.h>
+ /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
+ #define RTCCLK_FREQ           1000000
+@@ -27,6 +28,37 @@
+       };
+       soc {
++              pwmleds {
++                      compatible = "pwm-leds";
++                      d1 {
++                              label = "green:d1";
++                              pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
++                              active-low = <1>;
++                              max-brightness = <255>;
++                              linux,default-trigger = "none";
++                      };
++                      d2 {
++                              label = "green:d2";
++                              pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
++                              active-low = <1>;
++                              max-brightness = <255>;
++                              linux,default-trigger = "none";
++                      };
++                      d3 {
++                              label = "green:d3";
++                              pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
++                              active-low = <1>;
++                              max-brightness = <255>;
++                              linux,default-trigger = "none";
++                      };
++                      d4 {
++                              label = "green:d4";
++                              pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
++                              active-low = <1>;
++                              max-brightness = <255>;
++                              linux,default-trigger = "none";
++                      };
++              };
+       };
+       hfclk: hfclk {
+-- 
+2.7.4
+