Re: [PATCH v7 0/5] clk: add driver for the SiFive FU740

2021-04-14 Thread Zong Li
On Mon, Apr 12, 2021 at 7:31 PM Andreas Schwab  wrote:
>
> On Mär 31 2021, Zong Li wrote:
>
> > I found that the gemgxlpll was disabled immediately by power
> > management after macb driver install. The mainline's defconfig doesn't
> > enable CONFIG_PM, so the network is fine on it. The opensuse defconfig
> > enables CONFIG_PM, and the patch
> > 732374a0b440d9a79c8412f318a25cd37ba6f4e2 added the enable/disable
> > callback functions, so the gemgxlpll PLL, I have no idea why power
> > management disable it, I would keep trace it.
>
> Does that mean that CONFIG_PM also affects the FU740?
>

Yes, we got the same problem on the FU740. We are checking the issue.

> Andreas.
>
> --
> Andreas Schwab, sch...@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."


Re: [PATCH v7 0/5] clk: add driver for the SiFive FU740

2021-03-31 Thread Zong Li
On Mon, Mar 29, 2021 at 6:37 PM Andreas Schwab  wrote:
>
> On Mär 29 2021, Zong Li wrote:
>
> > Yes, I could get the network problem by using the defconfig you
> > provided, the system hung up when executing 'ifconfig' immediately
> > after installing macb driver module, the network can work by only
> > reverting the commit 732374a0b440d9a79c8412f318a25cd37ba6f4e2. But the
> > network is fine by using the mainline's defconfig, this is a little
> > bit weird, I will check that and try to find the difference.
>
> My guess would be that it is an init dependency problem between the phy
> driver and the clock driver, which causes the clock to be enabled too
> late.
>

I found that the gemgxlpll was disabled immediately by power
management after macb driver install. The mainline's defconfig doesn't
enable CONFIG_PM, so the network is fine on it. The opensuse defconfig
enables CONFIG_PM, and the patch
732374a0b440d9a79c8412f318a25cd37ba6f4e2 added the enable/disable
callback functions, so the gemgxlpll PLL, I have no idea why power
management disable it, I would keep trace it.

By the way, I tried to disable CONFIG_PM on oenpsuse defconfig, the
system didn't hang anymore, on the contrary, I enable CONFIG_PM on
mainline's defconfig, I expect that the system would hang up as well,
unfortunately, I cannot boot successfully by just enabling CONFIG_PM
easily.


> Andreas.
>
> --
> Andreas Schwab, sch...@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."


Re: [PATCH v7 0/5] clk: add driver for the SiFive FU740

2021-03-29 Thread Zong Li
On Fri, Mar 26, 2021 at 5:24 PM Andreas Schwab  wrote:
>
> On Mär 26 2021, Zong Li wrote:
>
> > 1. Boot on openSUSE-Tumbleweed-RISC-V-JeOS-hifiveunleashed.riscv64.raw.xz
> > w/ plugging ethernet cable
> >   - It seems that I encountered a different situation with you, my
> > system hung up and I didn't see the boot message you mentioned yet.
>
> That's exactly the issue.  The process is stuck in D.
>

Yes, I could get the network problem by using the defconfig you
provided, the system hung up when executing 'ifconfig' immediately
after installing macb driver module, the network can work by only
reverting the commit 732374a0b440d9a79c8412f318a25cd37ba6f4e2. But the
network is fine by using the mainline's defconfig, this is a little
bit weird, I will check that and try to find the difference.

> Andreas.
>
> --
> Andreas Schwab, sch...@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."


Re: [PATCH v7 0/5] clk: add driver for the SiFive FU740

2021-03-26 Thread Zong Li
On Thu, Mar 25, 2021 at 5:22 PM Andreas Schwab  wrote:
>
> On Mär 25 2021, Zong Li wrote:
>
> > take a look at this again. Could you also let me know which bootloader
> > you used (FSBL or U-boot-SPL)? Thanks.
>
> U-Boot SPL
>
> Please try this image:
>
> http://download.opensuse.org/ports/riscv/tumbleweed/images/openSUSE-Tumbleweed-RISC-V-JeOS-hifiveunleashed.riscv64.raw.xz
>

Hi Andreas,

The following is the result of the test so far. I would continue to
see what happened there.

1. Boot on openSUSE-Tumbleweed-RISC-V-JeOS-hifiveunleashed.riscv64.raw.xz
w/ plugging ethernet cable
  - It seems that I encountered a different situation with you, my
system hung up and I didn't see the boot message you mentioned yet.

[  OK  ] Finished Generate issue file for login session.
[  OK  ] Finished Apply settings from /etc/sysconfig/keyboard.
[  OK  ] Started User Login Management.
[  *** ] (3 of 3) A start job is running for…upplicant service (58s / 1min 51s)
[**] (3 of 3) A start job is running for…cant service (1min 28s / 1min 51s)
[   ***] (2 of 3) A start job is running for…cant service (1min 58s / 3min 21s)
[   ***] (1 of 3) A start job is running for…cant service (2min 28s / 3min 21s)
[**] (3 of 3) A start job is running for…cant service (2min 58s / 3min 21s)
[ ***  ] (2 of 3) A start job is running for…cant service (3min 28s / 4min 51s)
[ *] (1 of 3) A start job is running for…cant service (3min 58s / 4min 51s)
[ ***  ] (3 of 3) A start job is running for…cant service (4min 28s / 4min 51s)
[***   ] (2 of 3) A start job is running for…cant service (4min 59s / 6min 22s)
[**] (1 of 3) A start job is running for…cant service (5min 29s / 6min 22s)
[  *** ] (3 of 3) A start job is running for…cant service (5min 59s / 6min 22s)
[* ] (2 of 3) A start job is running for…cant service (6min 29s / 7min 52s)
[  *** ] (1 of 3) A start job is running for…cant service (6min 59s / 7min 52s)
[**] (3 of 3) A start job is running for…cant service (7min 29s / 7min 52s)
[FAILED] Failed to start wicked AutoIPv4 supplicant service.
See 'systemctl status wickedd-auto4.service' for details.
[FAILED] Failed to start wicked DHCPv4 supplicant service.
See 'systemctl status wickedd-dhcp4.service' for details.
[FAILED] Failed to start wicked DHCPv6 supplicant service.
See 'systemctl status wickedd-dhcp6.service' for details.
 Starting wicked network management service daemon...
[**] A start job is running for wicked n…rvice daemon (7min 59s / 9min 22s)
[***   ] A start job is running for wicked n…rvice daemon (8min 29s / 9min 22s)
[  603.364988] BUG: workqueue lockup - pool cpus=1 node=0 flags=0x0
nice=0 stuck for 36s!
[***   ] A start job is running for wicked n…rvice daemon (8min 59s / 9min 22s)
[  633.444986] BUG: workqueue lockup - pool cpus=1 node=0 flags=0x0
nice=0 stuck for 66s!
 Stopping Flush Journal to Persistent Storage...
[  OK  ] Stopped Flush Journal to Persistent Storage.
[  OK  ] Stopped Journal Service.


2. Boot on kernel image which built by opensuse defconfig with
changing CONFIG_MACB to y instead of m
 - Although I got some problem for mounting the root filesystem on
this image now, but I didn't hang up at the message you mentioned, I
could go through after macb driver initialization

[2.350309] libphy: Fixed MDIO Bus: probed
[2.354476] macb 1009.ethernet: Registered clk switch
'sifive-gemgxl-mgmt'
[2.358752] macb 1009.ethernet: GEM doesn't support hardware ptp.
[2.361464] libphy: MACB_mii_bus: probed
[2.366289] macb 1009.ethernet eth0: Cadence GEM rev 0x10070109
at 0x1009 irq 16 (70:b3:d5:92:f2:6c)
[2.375570] e1000e: Intel(R) PRO/1000 Network Driver
[2.380323] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[2.386338] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
...
[2.687447] Waiting for root device /dev/mmcblk0p4...

3. I check the patch set of supporting fu740, it shouldn't impact
fu540, I'm going to dump and comparing the prci content and give more
testing.


> Andreas.
>
> --
> Andreas Schwab, sch...@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."


Re: [PATCH v7 0/5] clk: add driver for the SiFive FU740

2021-03-24 Thread Zong Li
On Wed, Mar 24, 2021 at 6:36 PM Andreas Schwab  wrote:
>
> Were you able to reproduce the problem?
>

Hi Andreas,

Sorry, I'm not available past few days, I'm just coming back, I would
take a look at this again. Could you also let me know which bootloader
you used (FSBL or U-boot-SPL)? Thanks.

> Andreas.
>
> --
> Andreas Schwab, sch...@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."


Re: [PATCH v7 0/5] clk: add driver for the SiFive FU740

2021-03-19 Thread Zong Li
On Thu, Mar 18, 2021 at 10:07 AM Zong Li  wrote:
>
> On Wed, Mar 17, 2021 at 3:45 AM Andreas Schwab  wrote:
> >
> > On Dez 09 2020, Zong Li wrote:
> >
> > > Add a driver for the SiFive FU740 PRCI IP block, which handles more
> > > clocks than FU540. These patches also refactor the original
> > > implementation by spliting the dependent-code of fu540 and fu740
> > > respectively.
> >
> > That breaks ethernet on the fu540.
> >
>
> I would check that, thanks for the report.
>

Hi Andreas,

Could you please point me out how to test the ethernet from your side?
I had tried to quick test by using iperf and wget, the ethernet seems
to work fine to me.

Thanks.

> > Andreas.
> >
> > --
> > Andreas Schwab, sch...@linux-m68k.org
> > GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> > "And now for something completely different."


Re: [PATCH v7 0/5] clk: add driver for the SiFive FU740

2021-03-17 Thread Zong Li
On Wed, Mar 17, 2021 at 3:45 AM Andreas Schwab  wrote:
>
> On Dez 09 2020, Zong Li wrote:
>
> > Add a driver for the SiFive FU740 PRCI IP block, which handles more
> > clocks than FU540. These patches also refactor the original
> > implementation by spliting the dependent-code of fu540 and fu740
> > respectively.
>
> That breaks ethernet on the fu540.
>

I would check that, thanks for the report.

> Andreas.
>
> --
> Andreas Schwab, sch...@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."


[PATCH v7 5/5] clk: sifive: Add clock enable and disable ops

2020-12-09 Thread Zong Li
From: Pragnesh Patel 

Add new functions "sifive_prci_clock_enable(), sifive_prci_clock_disable()
and sifive_clk_is_enabled()" to enable or disable the PRCI clock

Signed-off-by: Pragnesh Patel 
Tested-by: Zong Li 
---
 drivers/clk/sifive/fu540-prci.c  |  6 +++
 drivers/clk/sifive/fu740-prci.c  |  9 
 drivers/clk/sifive/sifive-prci.c | 77 
 drivers/clk/sifive/sifive-prci.h | 10 +
 4 files changed, 93 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
index e2353dee8c52..3b558835984b 100644
--- a/drivers/clk/sifive/fu540-prci.c
+++ b/drivers/clk/sifive/fu540-prci.c
@@ -24,16 +24,19 @@
 
 static struct __prci_wrpll_data __prci_corepll_data = {
.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_COREPLLCFG1_OFFSET,
.enable_bypass = sifive_prci_coreclksel_use_hfclk,
.disable_bypass = sifive_prci_coreclksel_use_corepll,
 };
 
 static struct __prci_wrpll_data __prci_ddrpll_data = {
.cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
 };
 
 static struct __prci_wrpll_data __prci_gemgxlpll_data = {
.cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
 };
 
 /* Linux clock framework integration */
@@ -42,6 +45,9 @@ static const struct clk_ops sifive_fu540_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,
+   .enable = sifive_prci_clock_enable,
+   .disable = sifive_prci_clock_disable,
+   .is_enabled = sifive_clk_is_enabled,
 };
 
 static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = {
diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index 41ddd4431497..db8300223745 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -12,32 +12,38 @@
 
 static struct __prci_wrpll_data __prci_corepll_data = {
.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_COREPLLCFG1_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,
+   .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
 };
 
 static struct __prci_wrpll_data __prci_gemgxlpll_data = {
.cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
 };
 
 static struct __prci_wrpll_data __prci_dvfscorepll_data = {
.cfg0_offs = PRCI_DVFSCOREPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_DVFSCOREPLLCFG1_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,
+   .cfg1_offs = PRCI_HFPCLKPLLCFG1_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,
+   .cfg1_offs = PRCI_CLTXPLLCFG1_OFFSET,
 };
 
 /* Linux clock framework integration */
@@ -46,6 +52,9 @@ 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,
+   .enable = sifive_prci_clock_enable,
+   .disable = sifive_prci_clock_disable,
+   .is_enabled = sifive_clk_is_enabled,
 };
 
 static const struct clk_ops sifive_fu740_prci_wrpll_ro_clk_ops = {
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index cc4b4c6b4437..c78b042750e2 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -113,7 +113,7 @@ static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
 }
 
 /**
- * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI
+ * __prci_wrpll_read_cfg0() - read the WRPLL configuration from the PRCI
  * @pd: PRCI context
  * @pwd: PRCI WRPLL metadata
  *
@@ -124,14 +124,14 @@ static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
  * 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)
+static void __prci_wrpll_read_cfg0(struct __prci_data *pd,
+  struct __prci_wrpll_data *pwd)
 {
__prci_wrpll_unpack(>c, __prci_readl(pd, pwd->cfg0_offs));
 }
 
 /**
- * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI
+ * __prci_wrpll_write_cfg0() - write WRPLL configuration into the PR

[PATCH v7 3/5] clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

2020-12-09 Thread Zong Li
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.

The link of unmatched as follow, and the U740-C000 manual would
be present in the same page as soon.
https://www.sifive.com/boards/hifive-unmatched

This driver contains bug fixes and contributions from
Henry Styles 
Erik Danie 
Pragnesh Patel 

Signed-off-by: Zong Li 
Reviewed-by: Pragnesh Patel 
Acked-by: Palmer Dabbelt 
Cc: Henry Styles 
Cc: Erik Danie 
Cc: Pragnesh Patel 
---
 drivers/clk/sifive/Kconfig|   4 +-
 drivers/clk/sifive/Makefile   |   2 +-
 drivers/clk/sifive/fu740-prci.c   | 111 
 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, 366 insertions(+), 3 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 3074cdbc6009..7b06fc04e6b3 100644
--- a/drivers/clk/sifive/Makefile
+++ b/drivers/clk/sifive/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_CLK_SIFIVE_PRCI)  += sifive-prci.o fu540-prci.o
+obj-$(CONFIG_CLK_SIFIVE_PRCI)  += sifive-prci.o fu540-prci.o fu740-prci.o
diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
new file mode 100644
index ..41ddd4431497
--- /dev/null
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 SiFive, Inc.
+ * Copyright (C) 2020 Zong Li
+ */
+
+#include 
+#include 
+#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 = _fu740_prci_wrpll_clk_ops,
+   .pwd = &__prci_corepll_data,
+   },
+   [PRCI_CLK_DDRPLL] = {
+   .name = "ddrpll",
+   .parent_name = "hfclk",
+   .ops = _fu740_prci_wrpll_ro_clk_ops,
+   .pwd = &__prci_ddrpll_data,
+   },
+   [PRCI_CLK_GEMGXLPLL] = {
+   .name = "gemgxlpll

[PATCH v7 4/5] clk: sifive: Fix the wrong bit field shift

2020-12-09 Thread Zong Li
The clk enable bit should be 31 instead of 24.

Signed-off-by: Zong Li 
Reported-by: Pragnesh Patel 
---
 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 7e509dfb72d1..88493f3b9edf 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 PRCI_GEMGXLPLLCFG1_CKE_SHIFT   24
+#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT   31
 #define PRCI_GEMGXLPLLCFG1_CKE_MASK(0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
 
 /* CORECLKSEL */
-- 
2.29.2



[PATCH v7 2/5] clk: sifive: Use common name for prci configuration

2020-12-09 Thread Zong Li
Use generic name CLK_SIFIVE_PRCI instead of CLK_SIFIVE_FU540_PRCI. This
patch is prepared for fu740 support.

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
Acked-by: Palmer Dabbelt 
Reviewed-by: Pragnesh Patel 
---
 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 51b6ebc359e4..3074cdbc6009 100644
--- a/drivers/clk/sifive/Makefile
+++ b/drivers/clk/sifive/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI)+= sifive-prci.o fu540-prci.o
+obj-$(CONFIG_CLK_SIFIVE_PRCI)  += sifive-prci.o fu540-prci.o
-- 
2.29.2



[PATCH v7 0/5] clk: add driver for the SiFive FU740

2020-12-09 Thread Zong Li
Add a driver for the SiFive FU740 PRCI IP block, which handles more
clocks than FU540. These patches also refactor the original
implementation by spliting the dependent-code of fu540 and fu740
respectively.

We also add a separate patch for DT binding documentation of FU740 PRCI:
https://patchwork.kernel.org/project/linux-riscv/patch/20201126030043.67390-1-zong...@sifive.com/

Changed in v7:
 - Pick changes in v5 back up into this patch series.

Changed in v6:
 - Modify the patch "Add clock enable and disable ops"
   by Pragnesh. The changes as follows:
   - Remove spin lock in enable and disable functions
   - Call enable_bypass() before PLL output disable
 - Rebase code to Linux v5.10-rc7

Changed in v5:
 - Fix copyright format
 - Add a link of documentation in commit message
 - Modify build dependency for sifive-prci.c
 - Add enable and disable functions by Pragnesh Patel

Changed in v4:
 - Fix the wrong enable bit field shift for FU540 and FU740.

Changed in v3:
 - Fix the wrong enable bit field shift for FU740.

Changed in v2:
 - Remove the macro definition for __prci_clock_array.
 - Indicate the functional changes in commit message.
 - Using option -M and -C to create patches.
 - Rebase code to kernel v5.10-rc3.

Pragnesh Patel (1):
  clk: sifive: Add clock enable and disable ops

Zong Li (4):
  clk: sifive: Extract prci core to common base
  clk: sifive: Use common name for prci configuration
  clk: sifive: Add a driver for the SiFive FU740 PRCI IP block
  clk: sifive: Fix the wrong bit field shift

 arch/riscv/Kconfig.socs   |   2 +-
 drivers/clk/sifive/Kconfig|   8 +-
 drivers/clk/sifive/Makefile   |   2 +-
 drivers/clk/sifive/fu540-prci.c   | 598 +-
 drivers/clk/sifive/fu540-prci.h   |  21 +
 drivers/clk/sifive/fu740-prci.c   | 120 
 drivers/clk/sifive/fu740-prci.h   |  21 +
 drivers/clk/sifive/sifive-prci.c  | 574 +
 drivers/clk/sifive/sifive-prci.h  | 299 +
 include/dt-bindings/clock/sifive-fu740-prci.h |  23 +
 10 files changed, 1091 insertions(+), 577 deletions(-)
 create mode 100644 drivers/clk/sifive/fu540-prci.h
 create mode 100644 drivers/clk/sifive/fu740-prci.c
 create mode 100644 drivers/clk/sifive/fu740-prci.h
 create mode 100644 drivers/clk/sifive/sifive-prci.c
 create mode 100644 drivers/clk/sifive/sifive-prci.h
 create mode 100644 include/dt-bindings/clock/sifive-fu740-prci.h

-- 
2.29.2



[PATCH v7 1/5] clk: sifive: Extract prci core to common base

2020-12-09 Thread Zong Li
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 
Reviewed-by: Pragnesh Patel 
Acked-by: Palmer Dabbelt 
---
 drivers/clk/sifive/Makefile   |   2 +-
 drivers/clk/sifive/fu540-prci.c   | 592 +-
 drivers/clk/sifive/fu540-prci.h   |  21 +
 .../sifive/{fu540-prci.c => sifive-prci.c}| 401 +++-
 drivers/clk/sifive/sifive-prci.h  | 201 ++
 5 files changed, 327 insertions(+), 890 deletions(-)
 create mode 100644 drivers/clk/sifive/fu540-prci.h
 copy drivers/clk/sifive/{fu540-prci.c => sifive-prci.c} (41%)
 create mode 100644 drivers/clk/sifive/sifive-prci.h

diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
index 0797f14fef6b..51b6ebc359e4 100644
--- a/drivers/clk/sifive/Makefile
+++ b/drivers/clk/sifive/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI)+= fu540-prci.o
+obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI)+= sifive-prci.o fu540-prci.o
diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
index a8901f90a61a..e2353dee8c52 100644
--- a/drivers/clk/sifive/fu540-prci.c
+++ b/drivers/clk/sifive/fu540-prci.c
@@ -1,17 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2018-2019 SiFive, Inc.
- * Wesley Terpstra
- * Paul Walmsley
- *
- * 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.
+ * Copyright (C) 2018-2019 Wesley Terpstra
+ * Copyright (C) 2018-2019 Paul Walmsley
+ * Copyright (C) 2020 Zong Li
  *
  * The FU540 PRCI implements clock and reset control for the SiFive
  * FU540-C000 chip.  This driver assumes that it has sole control
@@ -25,463 +17,43 @@
  */
 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-
-/*
- * 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_OFFSET0x4
-# 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_SHIFT25
-# 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_SHIFT0
-# define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << 
PRCI_DDRPLLCFG0_DIVR_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVF_SHIFT6
-# define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << 
PRCI_DDRPLLCFG0_DIVF_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVQ_SHIFT15
-# 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_SHIFT31
-# define PRCI_DDRPLLCFG0_LOCK_MASK (0x1 << 
PRCI_DDRPLLCFG0_LOCK_SHIFT)
+#include "sifive-prci.h"
 
-/* DDRPLLCFG1 */
-#define PRCI

Re: [PATCH v6 1/5] clk: sifive: Extract prci core to common base

2020-12-08 Thread Zong Li
On Wed, Dec 9, 2020 at 1:08 AM kernel test robot  wrote:
>
> Hi Zong,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on clk/clk-next]
> [also build test ERROR on robh/for-next linux/master linus/master v5.10-rc7 
> next-20201208]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:
> https://github.com/0day-ci/linux/commits/Zong-Li/clk-add-driver-for-the-SiFive-FU740/20201208-151711
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
> config: x86_64-randconfig-a016-20201208 (attached as .config)
> compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 
> a2f922140f5380571fb74179f2bf622b3b925697)
> reproduce (this is a W=1 build):
> wget 
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
> ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # install x86_64 cross compiling tool for clang build
> # apt-get install binutils-x86-64-linux-gnu
> # 
> https://github.com/0day-ci/linux/commit/5bfdddc125b80d4541a5a925918efec9b6fe0282
> git remote add linux-review https://github.com/0day-ci/linux
> git fetch --no-tags linux-review 
> Zong-Li/clk-add-driver-for-the-SiFive-FU740/20201208-151711
> git checkout 5bfdddc125b80d4541a5a925918efec9b6fe0282
> # save the attached .config to linux build tree
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot 
>
> All errors (new ones prefixed by >>):
>
> >> ld.lld: error: undefined symbol: wrpll_configure_for_rate
>>>> referenced by sifive-prci.c
>>>> clk/sifive/sifive-prci.o:(sifive_prci_wrpll_round_rate) in archive 
> drivers/built-in.a
>>>> referenced by sifive-prci.c
>>>> clk/sifive/sifive-prci.o:(sifive_prci_wrpll_set_rate) in archive 
> drivers/built-in.a
> --
> >> ld.lld: error: undefined symbol: wrpll_calc_output_rate
>>>> referenced by sifive-prci.c
>>>> clk/sifive/sifive-prci.o:(sifive_prci_wrpll_round_rate) in archive 
> drivers/built-in.a
>>>> referenced by sifive-prci.c
>>>> clk/sifive/sifive-prci.o:(sifive_prci_wrpll_recalc_rate) in archive 
> drivers/built-in.a
> --
> >> ld.lld: error: undefined symbol: wrpll_calc_max_lock_us
>>>> referenced by sifive-prci.c
>>>> clk/sifive/sifive-prci.o:(sifive_prci_wrpll_set_rate) in archive 
> drivers/built-in.a
> --
> >> ld.lld: error: undefined symbol: __prci_init_clocks_fu540
>>>> referenced by sifive-prci.c
>>>> clk/sifive/sifive-prci.o:(prci_clk_fu540) in archive drivers/built-in.a
>
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org

This issue should be fixed in the v5 version, it seems to be a mess in
our v6 internal branch, I would rebase the codebase and send the v7
patches.


[PATCH v6 4/5] clk: sifive: Fix the wrong bit field shift

2020-12-07 Thread Zong Li
The clk enable bit should be 31 instead of 24.

Signed-off-by: Zong Li 
Reported-by: Pragnesh Patel 
---
 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_SHIFT24
+#define RCI_GEMGXLPLLCFG1_CKE_SHIFT31
 #define PRCI_GEMGXLPLLCFG1_CKE_MASK(0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
 
 /* CORECLKSEL */
-- 
2.29.2



[PATCH v6 3/5] clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

2020-12-07 Thread Zong Li
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.

The link of unmatched as follow, and the U740-C000 manual would
be present in the same page as soon.
https://www.sifive.com/boards/hifive-unmatched

This driver contains bug fixes and contributions from
Henry Styles 
Erik Danie 
Pragnesh Patel 

Signed-off-by: Zong Li 
Reviewed-by: Pragnesh Patel 
Acked-by: Palmer Dabbelt 
Cc: Henry Styles 
Cc: Erik Danie 
Cc: Pragnesh Patel 
---
 drivers/clk/sifive/Kconfig|   4 +-
 drivers/clk/sifive/Makefile   |   1 +
 drivers/clk/sifive/fu740-prci.c   | 111 
 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, 366 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 ..41ddd4431497
--- /dev/null
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 SiFive, Inc.
+ * Copyright (C) 2020 Zong Li
+ */
+
+#include 
+#include 
+#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 = _fu740_prci_wrpll_clk_ops,
+   .pwd = &__prci_corepll_data,
+   },
+   [PRCI_CLK_DDRPLL] = {
+   .name = "ddrpll",
+   .parent_name = "hfclk",
+   .ops = _fu740_prci_wrpll_ro_clk_ops,
+   .pwd = &__prci_ddrpll_data,
+   },
+   [PRCI_CLK_GEMGXLPLL] = {
+   .name = "gemgxlpll",
+   .parent_name = "hfclk

[PATCH v6 2/5] clk: sifive: Use common name for prci configuration

2020-12-07 Thread Zong Li
Use generic name CLK_SIFIVE_PRCI instead of CLK_SIFIVE_FU540_PRCI. This
patch is prepared for fu740 support.

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
Acked-by: Palmer Dabbelt 
Reviewed-by: Pragnesh Patel 
---
 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
-- 
2.29.2



[PATCH v6 5/5] clk: sifive: Add clock enable and disable ops

2020-12-07 Thread Zong Li
From: Pragnesh Patel 

Add new functions "sifive_prci_clock_enable(), sifive_prci_clock_disable()
and sifive_clk_is_enabled()" to enable or disable the PRCI clock

Signed-off-by: Pragnesh Patel 
Tested-by: Zong Li 
---
 drivers/clk/sifive/fu540-prci.c  |  6 +++
 drivers/clk/sifive/fu740-prci.c  |  9 
 drivers/clk/sifive/sifive-prci.c | 77 
 drivers/clk/sifive/sifive-prci.h | 10 +
 4 files changed, 93 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
index 34dc4ea6a3af..3fbee1da9701 100644
--- a/drivers/clk/sifive/fu540-prci.c
+++ b/drivers/clk/sifive/fu540-prci.c
@@ -33,16 +33,19 @@
 
 static struct __prci_wrpll_data __prci_corepll_data = {
.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_COREPLLCFG1_OFFSET,
.enable_bypass = sifive_prci_coreclksel_use_hfclk,
.disable_bypass = sifive_prci_coreclksel_use_corepll,
 };
 
 static struct __prci_wrpll_data __prci_ddrpll_data = {
.cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
 };
 
 static struct __prci_wrpll_data __prci_gemgxlpll_data = {
.cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
 };
 
 /* Linux clock framework integration */
@@ -51,6 +54,9 @@ static const struct clk_ops sifive_fu540_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,
+   .enable = sifive_prci_clock_enable,
+   .disable = sifive_prci_clock_disable,
+   .is_enabled = sifive_clk_is_enabled,
 };
 
 static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = {
diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index 41ddd4431497..db8300223745 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -12,32 +12,38 @@
 
 static struct __prci_wrpll_data __prci_corepll_data = {
.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_COREPLLCFG1_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,
+   .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
 };
 
 static struct __prci_wrpll_data __prci_gemgxlpll_data = {
.cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
 };
 
 static struct __prci_wrpll_data __prci_dvfscorepll_data = {
.cfg0_offs = PRCI_DVFSCOREPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_DVFSCOREPLLCFG1_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,
+   .cfg1_offs = PRCI_HFPCLKPLLCFG1_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,
+   .cfg1_offs = PRCI_CLTXPLLCFG1_OFFSET,
 };
 
 /* Linux clock framework integration */
@@ -46,6 +52,9 @@ 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,
+   .enable = sifive_prci_clock_enable,
+   .disable = sifive_prci_clock_disable,
+   .is_enabled = sifive_clk_is_enabled,
 };
 
 static const struct clk_ops sifive_fu740_prci_wrpll_ro_clk_ops = {
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index f4bab45509b3..4698dba0ac86 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -113,7 +113,7 @@ static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
 }
 
 /**
- * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI
+ * __prci_wrpll_read_cfg0() - read the WRPLL configuration from the PRCI
  * @pd: PRCI context
  * @pwd: PRCI WRPLL metadata
  *
@@ -124,14 +124,14 @@ static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
  * 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)
+static void __prci_wrpll_read_cfg0(struct __prci_data *pd,
+  struct __prci_wrpll_data *pwd)
 {
__prci_wrpll_unpack(>c, __prci_readl(pd, pwd->cfg0_offs));
 }
 
 /**
- * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI
+ * __prci_wrpll_write_cfg0() - write WRPLL configuration into the PR

[PATCH v6 0/5] clk: add driver for the SiFive FU740

2020-12-07 Thread Zong Li
Add a driver for the SiFive FU740 PRCI IP block, which handles more
clocks than FU540. These patches also refactor the original
implementation by spliting the dependent-code of fu540 and fu740
respectively.

We also add a separate patch for DT binding documentation of FU740 PRCI:
https://patchwork.kernel.org/project/linux-riscv/patch/20201126030043.67390-1-zong...@sifive.com/

Changed in v6:
 - Modify the patch "Add clock enable and disable ops"
   by Pragnesh. The changes as follows:
   - Remove spin lock in enable and disable functions
   - Call enable_bypass() before PLL output disable

Changed in v5:
 - Fix copyright format
 - Add a link of documentation in commit message
 - Modify build dependency for sifive-prci.c
 - Add enable and disable functions by Pragnesh Patel

Changed in v4:
 - Fix the wrong enable bit field shift for FU540 and FU740.

Changed in v3:
 - Fix the wrong enable bit field shift for FU740.

Changed in v2:
 - Remove the macro definition for __prci_clock_array.
 - Indicate the functional changes in commit message.
 - Using option -M and -C to create patches.
 - Rebase code to kernel v5.10-rc3.

Pragnesh Patel (1):
  clk: sifive: Add clock enable and disable ops

Zong Li (4):
  clk: sifive: Extract prci core to common base
  clk: sifive: Use common name for prci configuration
  clk: sifive: Add a driver for the SiFive FU740 PRCI IP block
  clk: sifive: Fix the wrong bit field shift

 arch/riscv/Kconfig.socs   |   2 +-
 drivers/clk/sifive/Kconfig|   8 +-
 drivers/clk/sifive/Makefile   |   5 +-
 drivers/clk/sifive/fu540-prci.c   | 585 +-
 drivers/clk/sifive/fu540-prci.h   |  21 +
 drivers/clk/sifive/fu740-prci.c   | 120 
 drivers/clk/sifive/fu740-prci.h   |  21 +
 drivers/clk/sifive/sifive-prci.c  | 571 +
 drivers/clk/sifive/sifive-prci.h  | 299 +
 include/dt-bindings/clock/sifive-fu740-prci.h |  23 +
 10 files changed, 1089 insertions(+), 566 deletions(-)
 create mode 100644 drivers/clk/sifive/fu540-prci.h
 create mode 100644 drivers/clk/sifive/fu740-prci.c
 create mode 100644 drivers/clk/sifive/fu740-prci.h
 create mode 100644 drivers/clk/sifive/sifive-prci.c
 create mode 100644 drivers/clk/sifive/sifive-prci.h
 create mode 100644 include/dt-bindings/clock/sifive-fu740-prci.h

-- 
2.29.2



[PATCH v6 1/5] clk: sifive: Extract prci core to common base

2020-12-07 Thread Zong Li
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 
Reviewed-by: Pragnesh Patel 
Acked-by: Palmer Dabbelt 
---
 drivers/clk/sifive/Makefile   |   2 +
 drivers/clk/sifive/fu540-prci.c   | 579 +-
 drivers/clk/sifive/fu540-prci.h   |  21 +
 .../sifive/{fu540-prci.c => sifive-prci.c}| 396 +++-
 drivers/clk/sifive/sifive-prci.h  | 201 ++
 5 files changed, 322 insertions(+), 877 deletions(-)
 create mode 100644 drivers/clk/sifive/fu540-prci.h
 copy drivers/clk/sifive/{fu540-prci.c => sifive-prci.c} (41%)
 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..34dc4ea6a3af 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
@@ -25,463 +26,43 @@
  */
 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
+#include "sifive-prci.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_OFFSET0x4
-# 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_SHIFT25
-# 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_SHIFT0
-# define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << 
PRCI_DDRPLLCFG0_DIVR_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVF_SHIFT6
-# define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << 
PRCI_DDRPLLCFG0_DIVF_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVQ_SHIFT15
-# 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_SHIFT31
-# 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

[PATCH v5 5/5] clk: sifive: Add clock enable and disable ops

2020-11-30 Thread Zong Li
From: Pragnesh Patel 

Add new functions "sifive_prci_clock_enable(), sifive_prci_clock_disable()
and sifive_clk_is_enabled()" to enable or disable the PRCI clock

Signed-off-by: Pragnesh Patel 
---
 drivers/clk/sifive/fu540-prci.c  |  6 +++
 drivers/clk/sifive/fu740-prci.c  |  9 
 drivers/clk/sifive/sifive-prci.c | 91 
 drivers/clk/sifive/sifive-prci.h | 12 +
 4 files changed, 109 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
index 34dc4ea6a3af..3fbee1da9701 100644
--- a/drivers/clk/sifive/fu540-prci.c
+++ b/drivers/clk/sifive/fu540-prci.c
@@ -33,16 +33,19 @@
 
 static struct __prci_wrpll_data __prci_corepll_data = {
.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_COREPLLCFG1_OFFSET,
.enable_bypass = sifive_prci_coreclksel_use_hfclk,
.disable_bypass = sifive_prci_coreclksel_use_corepll,
 };
 
 static struct __prci_wrpll_data __prci_ddrpll_data = {
.cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
 };
 
 static struct __prci_wrpll_data __prci_gemgxlpll_data = {
.cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
 };
 
 /* Linux clock framework integration */
@@ -51,6 +54,9 @@ static const struct clk_ops sifive_fu540_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,
+   .enable = sifive_prci_clock_enable,
+   .disable = sifive_prci_clock_disable,
+   .is_enabled = sifive_clk_is_enabled,
 };
 
 static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = {
diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index 41ddd4431497..db8300223745 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -12,32 +12,38 @@
 
 static struct __prci_wrpll_data __prci_corepll_data = {
.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_COREPLLCFG1_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,
+   .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
 };
 
 static struct __prci_wrpll_data __prci_gemgxlpll_data = {
.cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
 };
 
 static struct __prci_wrpll_data __prci_dvfscorepll_data = {
.cfg0_offs = PRCI_DVFSCOREPLLCFG0_OFFSET,
+   .cfg1_offs = PRCI_DVFSCOREPLLCFG1_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,
+   .cfg1_offs = PRCI_HFPCLKPLLCFG1_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,
+   .cfg1_offs = PRCI_CLTXPLLCFG1_OFFSET,
 };
 
 /* Linux clock framework integration */
@@ -46,6 +52,9 @@ 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,
+   .enable = sifive_prci_clock_enable,
+   .disable = sifive_prci_clock_disable,
+   .is_enabled = sifive_clk_is_enabled,
 };
 
 static const struct clk_ops sifive_fu740_prci_wrpll_ro_clk_ops = {
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index cc4b4c6b4437..5922be9edc17 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -113,7 +113,7 @@ static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
 }
 
 /**
- * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI
+ * __prci_wrpll_read_cfg0() - read the WRPLL configuration from the PRCI
  * @pd: PRCI context
  * @pwd: PRCI WRPLL metadata
  *
@@ -124,14 +124,14 @@ static u32 __prci_wrpll_pack(const struct wrpll_cfg *c)
  * 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)
+static void __prci_wrpll_read_cfg0(struct __prci_data *pd,
+  struct __prci_wrpll_data *pwd)
 {
__prci_wrpll_unpack(>c, __prci_readl(pd, pwd->cfg0_offs));
 }
 
 /**
- * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI
+ * __prci_wrpll_write_cfg0() - write WRPLL configuration into the PRCI
  * @pd: PRCI context
  * @pwd: PRCI 

[PATCH v5 3/5] clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

2020-11-30 Thread Zong Li
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.

The link of unmatched as follow, and the U740-C000 manual would
be present in the same page as soon.
https://www.sifive.com/boards/hifive-unmatched

This driver contains bug fixes and contributions from
Henry Styles 
Erik Danie 
Pragnesh Patel 

Signed-off-by: Zong Li 
Reviewed-by: Pragnesh Patel 
Acked-by: Palmer Dabbelt 
Cc: Henry Styles 
Cc: Erik Danie 
Cc: Pragnesh Patel 
---
 drivers/clk/sifive/Kconfig|   4 +-
 drivers/clk/sifive/Makefile   |   2 +-
 drivers/clk/sifive/fu740-prci.c   | 111 
 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, 366 insertions(+), 3 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 3074cdbc6009..7b06fc04e6b3 100644
--- a/drivers/clk/sifive/Makefile
+++ b/drivers/clk/sifive/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_CLK_SIFIVE_PRCI)  += sifive-prci.o fu540-prci.o
+obj-$(CONFIG_CLK_SIFIVE_PRCI)  += sifive-prci.o fu540-prci.o fu740-prci.o
diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
new file mode 100644
index ..41ddd4431497
--- /dev/null
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 SiFive, Inc.
+ * Copyright (C) 2020 Zong Li
+ */
+
+#include 
+#include 
+#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 = _fu740_prci_wrpll_clk_ops,
+   .pwd = &__prci_corepll_data,
+   },
+   [PRCI_CLK_DDRPLL] = {
+   .name = "ddrpll",
+   .parent_name = "hfclk",
+   .ops = _fu740_prci_wrpll_ro_clk_ops,
+   .pwd = &__prci_ddrpll_data,
+   },
+   [PRCI_CLK_GEMGXLPLL] = {
+   .name = "gemgxlpll

[PATCH v5 4/5] clk: sifive: Fix the wrong bit field shift

2020-11-30 Thread Zong Li
The clk enable bit should be 31 instead of 24.

Signed-off-by: Zong Li 
Reported-by: Pragnesh Patel 
---
 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 7e509dfb72d1..88493f3b9edf 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 PRCI_GEMGXLPLLCFG1_CKE_SHIFT   24
+#define PRCI_GEMGXLPLLCFG1_CKE_SHIFT   31
 #define PRCI_GEMGXLPLLCFG1_CKE_MASK(0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
 
 /* CORECLKSEL */
-- 
2.29.2



[PATCH v5 2/5] clk: sifive: Use common name for prci configuration

2020-11-30 Thread Zong Li
Use generic name CLK_SIFIVE_PRCI instead of CLK_SIFIVE_FU540_PRCI. This
patch is prepared for fu740 support.

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
Acked-by: Palmer Dabbelt 
Reviewed-by: Pragnesh Patel 
---
 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 51b6ebc359e4..3074cdbc6009 100644
--- a/drivers/clk/sifive/Makefile
+++ b/drivers/clk/sifive/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI)+= sifive-prci.o fu540-prci.o
+obj-$(CONFIG_CLK_SIFIVE_PRCI)  += sifive-prci.o fu540-prci.o
-- 
2.29.2



[PATCH v5 0/5] clk: add driver for the SiFive FU740

2020-11-30 Thread Zong Li
Add a driver for the SiFive FU740 PRCI IP block, which handles more
clocks than FU540. These patches also refactor the original
implementation by spliting the dependent-code of fu540 and fu740
respectively. In v3 and v4 patch set, it fix the wrong clk enable bit
field which reported by Pragnesh.

We also add a separate patch for DT binding documentation of FU740 PRCI:
https://patchwork.kernel.org/project/linux-riscv/patch/20201126030043.67390-1-zong...@sifive.com/

Changed in v5:
 - Fix copyright format
 - Add a link of documentation in commit message
 - Modify build dependency for sifive-prci.c
 - Add enable and disable functions by Pragnesh Patel

Changed in v4:
 - Fix the wrong enable bit field shift for FU540 and FU740.

Changed in v3:
 - Fix the wrong enable bit field shift for FU740.

Changed in v2:
 - Remove the macro definition for __prci_clock_array.
 - Indicate the functional changes in commit message.
 - Using option -M and -C to create patches.
 - Rebase code to kernel v5.10-rc3.

Pragnesh Patel (1):
  clk: sifive: Add clock enable and disable ops

Zong Li (4):
  clk: sifive: Extract prci core to common base
  clk: sifive: Use common name for prci configuration
  clk: sifive: Add a driver for the SiFive FU740 PRCI IP block
  clk: sifive: Fix the wrong bit field shift

 arch/riscv/Kconfig.socs   |   2 +-
 drivers/clk/sifive/Kconfig|   8 +-
 drivers/clk/sifive/Makefile   |   2 +-
 drivers/clk/sifive/fu540-prci.c   | 585 +
 drivers/clk/sifive/fu540-prci.h   |  21 +
 drivers/clk/sifive/fu740-prci.c   | 120 
 drivers/clk/sifive/fu740-prci.h   |  21 +
 drivers/clk/sifive/sifive-prci.c  | 588 ++
 drivers/clk/sifive/sifive-prci.h  | 301 +
 include/dt-bindings/clock/sifive-fu740-prci.h |  23 +
 10 files changed, 1105 insertions(+), 566 deletions(-)
 create mode 100644 drivers/clk/sifive/fu540-prci.h
 create mode 100644 drivers/clk/sifive/fu740-prci.c
 create mode 100644 drivers/clk/sifive/fu740-prci.h
 create mode 100644 drivers/clk/sifive/sifive-prci.c
 create mode 100644 drivers/clk/sifive/sifive-prci.h
 create mode 100644 include/dt-bindings/clock/sifive-fu740-prci.h

-- 
2.29.2



[PATCH v5 1/5] clk: sifive: Extract prci core to common base

2020-11-30 Thread Zong Li
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 
Reviewed-by: Pragnesh Patel 
Acked-by: Palmer Dabbelt 
---
 drivers/clk/sifive/Makefile   |   2 +-
 drivers/clk/sifive/fu540-prci.c   | 579 +-
 drivers/clk/sifive/fu540-prci.h   |  21 +
 .../sifive/{fu540-prci.c => sifive-prci.c}| 401 +++-
 drivers/clk/sifive/sifive-prci.h  | 201 ++
 5 files changed, 325 insertions(+), 879 deletions(-)
 create mode 100644 drivers/clk/sifive/fu540-prci.h
 copy drivers/clk/sifive/{fu540-prci.c => sifive-prci.c} (41%)
 create mode 100644 drivers/clk/sifive/sifive-prci.h

diff --git a/drivers/clk/sifive/Makefile b/drivers/clk/sifive/Makefile
index 0797f14fef6b..51b6ebc359e4 100644
--- a/drivers/clk/sifive/Makefile
+++ b/drivers/clk/sifive/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI)+= fu540-prci.o
+obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI)+= sifive-prci.o fu540-prci.o
diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
index a8901f90a61a..34dc4ea6a3af 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
@@ -25,463 +26,43 @@
  */
 
 #include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
+#include "sifive-prci.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_OFFSET0x4
-# 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_SHIFT25
-# 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_SHIFT0
-# define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << 
PRCI_DDRPLLCFG0_DIVR_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVF_SHIFT6
-# define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << 
PRCI_DDRPLLCFG0_DIVF_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVQ_SHIFT15
-# 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_SHIFT31
-# 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_D

Re: [PATCH v4 1/4] clk: sifive: Extract prci core to common base

2020-11-25 Thread Zong Li
On Wed, Nov 25, 2020 at 2:43 AM kernel test robot  wrote:
>
> Hi Zong,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on clk/clk-next]
> [also build test ERROR on robh/for-next linus/master linux/master v5.10-rc5 
> next-20201124]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:
> https://github.com/0day-ci/linux/commits/Zong-Li/clk-add-driver-for-the-SiFive-FU740/2020-180900
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
> config: riscv-randconfig-r003-20201124 (attached as .config)
> compiler: riscv32-linux-gcc (GCC) 9.3.0
> reproduce (this is a W=1 build):
> wget 
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
> ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # 
> https://github.com/0day-ci/linux/commit/f08e191181ee40e21d9c1d63cfa4d894bc86ff27
> git remote add linux-review https://github.com/0day-ci/linux
> git fetch --no-tags linux-review 
> Zong-Li/clk-add-driver-for-the-SiFive-FU740/2020-180900
> git checkout f08e191181ee40e21d9c1d63cfa4d894bc86ff27
> # save the attached .config to linux build tree
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross 
> ARCH=riscv
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot 
>
> All errors (new ones prefixed by >>):
>
>riscv32-linux-ld: drivers/clk/sifive/sifive-prci.o: in function 
> `sifive_prci_wrpll_recalc_rate':
> >> sifive-prci.c:(.text+0x398): undefined reference to 
> >> `wrpll_calc_output_rate'
>riscv32-linux-ld: drivers/clk/sifive/sifive-prci.o: in function 
> `sifive_prci_wrpll_round_rate':
> >> sifive-prci.c:(.text+0x41a): undefined reference to 
> >> `wrpll_configure_for_rate'
> >> riscv32-linux-ld: sifive-prci.c:(.text+0x428): undefined reference to 
> >> `wrpll_calc_output_rate'
>riscv32-linux-ld: drivers/clk/sifive/sifive-prci.o: in function 
> `sifive_prci_wrpll_set_rate':
>sifive-prci.c:(.text+0x480): undefined reference to 
> `wrpll_configure_for_rate'
> >> riscv32-linux-ld: sifive-prci.c:(.text+0x4ee): undefined reference to 
> >> `wrpll_calc_max_lock_us'
> >> riscv32-linux-ld: drivers/clk/sifive/sifive-prci.o:(.srodata+0x0): 
> >> undefined reference to `__prci_init_clocks_fu540'
>

Fix the dependency of sifive-prci.c in the next version patch set by
following, only build core code if CONFIG_CLK_SIFIVE_PRCI is selected.

- obj-y  += sifive-prci.o
+ obj-$(CONFIG_CLK_SIFIVE_PRCI)   += sifive-prci.o

> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


[PATCH] dt-bindings: fu740: prci: add YAML documentation for the FU740 PRCI

2020-11-25 Thread Zong Li
Add YAML DT binding documentation for the SiFive FU740 PRCI. The
link of unmatched board as follow, the U740-C000 manual would be present
in the same page later.

https://www.sifive.com/boards/hifive-unmatched

Passes dt_binding_check.

Signed-off-by: Zong Li 
---
 .../bindings/clock/sifive/fu740-prci.yaml | 60 +++
 1 file changed, 60 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/sifive/fu740-prci.yaml

diff --git a/Documentation/devicetree/bindings/clock/sifive/fu740-prci.yaml 
b/Documentation/devicetree/bindings/clock/sifive/fu740-prci.yaml
new file mode 100644
index ..e17143cac316
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sifive/fu740-prci.yaml
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2020 SiFive, Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/sifive/fu740-prci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive FU740 Power Reset Clock Interrupt Controller (PRCI)
+
+maintainers:
+  - Zong Li 
+  - Paul Walmsley  
+
+description:
+  On the FU740 family of SoCs, most system-wide clock and reset integration
+  is via the PRCI IP block.
+  The clock consumer should specify the desired clock via the clock ID
+  macros defined in include/dt-bindings/clock/sifive-fu740-prci.h.
+  These macros begin with PRCI_CLK_.
+
+  The hfclk and rtcclk nodes are required, and represent physical
+  crystals or resonators located on the PCB.  These nodes should be present
+  underneath /, rather than /soc.
+
+properties:
+  compatible:
+const: sifive,fu740-c000-prci
+
+  reg:
+maxItems: 1
+
+  clocks:
+items:
+  - description: high frequency clock.
+  - description: RTL clock.
+
+  clock-names:
+items:
+  - const: hfclk
+  - const: rtcclk
+
+  "#clock-cells":
+const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+prci: clock-controller@1000 {
+  compatible = "sifive,fu740-c000-prci";
+  reg = <0x1000 0x1000>;
+  clocks = <>, <>;
+  #clock-cells = <1>;
+};
-- 
2.29.2



Re: [PATCH v4 3/4] clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

2020-11-22 Thread Zong Li
On Sat, Nov 21, 2020 at 9:29 AM Palmer Dabbelt  wrote:
>
> On Wed, 11 Nov 2020 02:06:07 PST (-0800), zong...@sifive.com wrote:
> > 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 
> > Erik Danie 
> > Pragnesh Patel 
> >
> > Signed-off-by: Zong Li 
> > Reviewed-by: Pragnesh Patel 
> > Cc: Henry Styles 
> > Cc: Erik Danie 
> > Cc: Pragnesh Patel 
> > ---
> >  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 
>
> I don't see the bindings in Documentation, but assuming they're in flight

Yash is working on some DT bindings, but he suggests that I could
integrate PRCI's binding in this patch set, and rename the prci
binding file, so I would add the binding in the next version.


>
> Acked-by: Palmer Dabbelt 
>
> Thanks!
>
> >  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 ..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 
> > +#include 
> > +#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,
> > +};
&g

Re: [PATCH v4 3/4] clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

2020-11-22 Thread Zong Li
On Sat, Nov 21, 2020 at 9:29 AM Palmer Dabbelt  wrote:
>
> On Wed, 11 Nov 2020 02:06:07 PST (-0800), zong...@sifive.com wrote:
> > 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 
> > Erik Danie 
> > Pragnesh Patel 
>
> Is there a datasheet for this chip?  It's geneally best to link to one, in 
> case
> someone needs to sort out issues in the future.
>

We have a product brief as follow in public now, I would add the link
of it in the next version patch. Thanks.
https://sifive.cdn.prismic.io/sifive/c05b8ddd-e043-45a6-8a29-2a137090236f_HiFive+Unmatched+Product+Brief+%28released%29.pdf

> >
> > Signed-off-by: Zong Li 
> > Reviewed-by: Pragnesh Patel 
> > Cc: Henry Styles 
> > Cc: Erik Danie 
> > Cc: Pragnesh Patel 
> > ---
> >  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 ..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
>
> Presumably it's copyright 2020 as well, as that's the current year?  Also, 
> IIUC
> the copyright lines should be independent from each other.  In other words,
> rather than
>
>
>C ... 2020 SiFive
>Zong
>
> this should be
>
>C ... 2020 SiFive
>C ... 2020 Zong
>
> and the rest of this should be dropped in favor of the SPDX.

Ok, many thanks for correcting that, I would modify it in the next
version patch.


>
> > + * 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 
> > +#include 
> > +#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_ddrpl

Re: [PATCH v4 4/4] clk: sifive: Fix the wrong bit field shift

2020-11-22 Thread Zong Li
On Sat, Nov 21, 2020 at 9:29 AM Palmer Dabbelt  wrote:
>
> On Wed, 11 Nov 2020 02:06:08 PST (-0800), zong...@sifive.com wrote:
> > The clk enable bit should be 31 instead of 24.
> >
> > Signed-off-by: Zong Li 
> > Reported-by: Pragnesh Patel 
> > ---
> >  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_SHIFT24
> > +#define PRCI_DDRPLLCFG1_CKE_SHIFT31
> >  #define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
> >
> >  /* GEMGXLPLLCFG0 */
> > @@ -81,7 +81,7 @@
> >
> >  /* GEMGXLPLLCFG1 */
> >  #define PRCI_GEMGXLPLLCFG1_OFFSET0x20
> > -#define RCI_GEMGXLPLLCFG1_CKE_SHIFT  24
> > +#define RCI_GEMGXLPLLCFG1_CKE_SHIFT  31
> >  #define PRCI_GEMGXLPLLCFG1_CKE_MASK  (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
> >
> >  /* CORECLKSEL */
>
> Section 7.3 of v1.0 of the FU540 manual says that bit 24 contains the PLL 
> clock
> enable for both of these.  I don't know if that's accurate, but if it is then 
> I
> believe this would break the FU540.  Don't have one to test on, though.

Yes, the manual seems to be wrong and should be corrected. It doesn't
break the FU540 yet because we don't use these fields in s-mode Linux
driver, we set them in m-mode FSBL/U-boot-SPL bootloader during boot
time, and the implementation of FSBL and U-boot-SPL both are correct.
The following link is the U-boot SPL source:

https://github.com/u-boot/u-boot/blob/da09b99ea572cec9a114872e480b798db11f9c6e/drivers/clk/sifive/fu540-prci.c#L128


Re: [PATCH v4 2/4] clk: sifive: Use common name for prci configuration

2020-11-22 Thread Zong Li
On Sat, Nov 21, 2020 at 9:29 AM Palmer Dabbelt  wrote:
>
> On Wed, 11 Nov 2020 02:06:06 PST (-0800), zong...@sifive.com wrote:
> > Use generic name CLK_SIFIVE_PRCI instead of CLK_SIFIVE_FU540_PRCI. This
> > patch is prepared for fu740 support.
> >
> > Signed-off-by: Zong Li 
> > Reviewed-by: Palmer Dabbelt 
> > Acked-by: Palmer Dabbelt 
> > Reviewed-by: Pragnesh Patel 
> > ---
> >  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,
>
> This just removes the double-space.  Presumably in should also remove the
> "FU540", as this clock driver will now function for multiple SiFive SOCs?
>

I'd like to list the support SoCs here, so in the third patch, I list
the FU740 in the description as well. I would remove the SoC names if
it is better by using a generic term. What do you think about that?

> > 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
>
> Probably best to rename the source file as well.

I added fu740-prci.c in the third patch, these two files fu740-prci.c
and fu540-prci.c hold the soc-dependent code, and sifive-prci.c is the
core of this driver.


Re: [PATCH v3 1/3] clk: sifive: Extract prci core to common base

2020-11-15 Thread Zong Li
On Thu, Nov 12, 2020 at 2:02 PM Stephen Boyd  wrote:
>
> Quoting Pragnesh Patel (2020-11-11 01:51:17)
> > >+#define RCI_GEMGXLPLLCFG1_CKE_SHIFT   24
> > >+#define PRCI_GEMGXLPLLCFG1_CKE_MASK   (0x1 <<
> > >PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
> >
> > Same here, Other than this
> >
> > Reviewed-by: Pragnesh Patel 
> >
>
> Please trim your replies

In v4 patch version, I change the definition of macros to 31 from 24 as follows:
- PRCI_CLTXPLLCFG1_CKE_SHIFT
- PRCI_DVFSCOREPLLCFG1_CKE_SHIFT
- PRCI_HFPCLKPLLCFG1_CKE_SHIFT
- PRCI_DDRPLLCFG1_CKE_SHIFT
- RCI_GEMGXLPLLCFG1_CKE_SHIFT


[PATCH v4 0/4] clk: add driver for the SiFive FU740

2020-11-11 Thread Zong Li
Add a driver for the SiFive FU740 PRCI IP block, which handles more
clocks than FU540. These patches also refactor the original
implementation by spliting the dependent-code of fu540 and fu740
respectively. In v3 and v4 patch set, it fix the wrong clk enable bit
field which reported by Pragnesh.

Changed in v4:
 - Fix the wrong enable bit field shift for FU540 and FU740.

Changed in v3:
 - Fix the wrong enable bit field shift for FU740.

Changed in v2:
 - Remove the macro definition for __prci_clock_array.
 - Indicate the functional changes in commit message.
 - Using option -M and -C to create patches.
 - Rebase code to kernel v5.10-rc3.

Zong Li (4):
  clk: sifive: Extract prci core to common base
  clk: sifive: Use common name for prci configuration
  clk: sifive: Add a driver for the SiFive FU740 PRCI IP block
  clk: sifive: Fix the wrong bit field shift

 arch/riscv/Kconfig.socs   |   2 +-
 drivers/clk/sifive/Kconfig|   8 +-
 drivers/clk/sifive/Makefile   |   5 +-
 drivers/clk/sifive/fu540-prci.c   | 586 +-
 drivers/clk/sifive/fu540-prci.h   |  21 +
 drivers/clk/sifive/fu740-prci.c   | 122 
 drivers/clk/sifive/fu740-prci.h   |  21 +
 .../sifive/{fu540-prci.c => sifive-prci.c}| 499 ++-
 drivers/clk/sifive/sifive-prci.h  | 289 +
 include/dt-bindings/clock/sifive-fu740-prci.h |  23 +
 10 files changed, 703 insertions(+), 873 deletions(-)
 create mode 100644 drivers/clk/sifive/fu540-prci.h
 create mode 100644 drivers/clk/sifive/fu740-prci.c
 create mode 100644 drivers/clk/sifive/fu740-prci.h
 copy drivers/clk/sifive/{fu540-prci.c => sifive-prci.c} (45%)
 create mode 100644 drivers/clk/sifive/sifive-prci.h
 create mode 100644 include/dt-bindings/clock/sifive-fu740-prci.h

-- 
2.29.2



[PATCH v4 3/4] clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

2020-11-11 Thread Zong Li
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 
Erik Danie 
Pragnesh Patel 

Signed-off-by: Zong Li 
Reviewed-by: Pragnesh Patel 
Cc: Henry Styles 
Cc: Erik Danie 
Cc: Pragnesh Patel 
---
 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 ..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 
+#include 
+#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 = _fu740_prci_wrpll_clk_ops,
+   .pwd = &__prci_corepll_data,
+   },
+   [PRCI_CLK_DDRPLL] = {
+   .name = "ddrpll&

[PATCH v4 2/4] clk: sifive: Use common name for prci configuration

2020-11-11 Thread Zong Li
Use generic name CLK_SIFIVE_PRCI instead of CLK_SIFIVE_FU540_PRCI. This
patch is prepared for fu740 support.

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
Acked-by: Palmer Dabbelt 
Reviewed-by: Pragnesh Patel 
---
 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
-- 
2.29.2



[PATCH v4 1/4] clk: sifive: Extract prci core to common base

2020-11-11 Thread Zong Li
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 
Reviewed-by: Pragnesh Patel 
---
 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 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-
-/*
- * 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_OFFSET0x4
-# 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_SHIFT25
-# 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_SHIFT0
-# define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << 
PRCI_DDRPLLCFG0_DIVR_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVF_SHIFT6
-# define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << 
PRCI_DDRPLLCFG0_DIVF_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVQ_SHIFT15
-# 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_SHIFT31
-# 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

[PATCH v4 4/4] clk: sifive: Fix the wrong bit field shift

2020-11-11 Thread Zong Li
The clk enable bit should be 31 instead of 24.

Signed-off-by: Zong Li 
Reported-by: Pragnesh Patel 
---
 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_SHIFT24
+#define RCI_GEMGXLPLLCFG1_CKE_SHIFT31
 #define PRCI_GEMGXLPLLCFG1_CKE_MASK(0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT)
 
 /* CORECLKSEL */
-- 
2.29.2



Re: [PATCH v3 1/3] clk: sifive: Extract prci core to common base

2020-11-11 Thread Zong Li
On Wed, Nov 11, 2020 at 5:51 PM Pragnesh Patel
 wrote:
>
> Hi Zong,
>
> >-Original Message-
> >From: Zong Li 
> >Sent: 11 November 2020 15:05
> >To: Paul Walmsley ( Sifive) ; pal...@dabbelt.com;
> >sb...@kernel.org; sch...@linux-m68k.org; Pragnesh Patel
> >; a...@eecs.berkeley.edu;
> >mturque...@baylibre.com; Yash Shah ; linux-
> >ker...@vger.kernel.org; linux-...@vger.kernel.org; linux-
> >ri...@lists.infradead.org
> >Cc: Zong Li 
> >Subject: [PATCH v3 1/3] clk: sifive: Extract prci core to common base
> >
> >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 
> >---
> > 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 
> >-#include 
> >-#include 
> >-#include 
> >-#include 
> >-#include 
> >-#include 
> > #include 
> >-#include 
> >-#include 
> >-#include 
> >-#include 
> >-
> >-/*
> >- * 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_SHIFT24
> >-# define PRCI_COREPLLCFG0_BYPASS_MASK (0x1 <<
> >PRCI_COREPLLCFG0_BYPASS_SHIFT)
> >-# define PRCI_COREPLLCFG0_FS

[PATCH v3 1/3] clk: sifive: Extract prci core to common base

2020-11-11 Thread Zong Li
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 
---
 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 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-
-/*
- * 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_OFFSET0x4
-# 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_SHIFT25
-# 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_SHIFT0
-# define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << 
PRCI_DDRPLLCFG0_DIVR_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVF_SHIFT6
-# define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << 
PRCI_DDRPLLCFG0_DIVF_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVQ_SHIFT15
-# 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_SHIFT31
-# 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

[PATCH v3 0/3] clk: add driver for the SiFive FU740

2020-11-11 Thread Zong Li
Add a driver for the SiFive FU740 PRCI IP block, which handles more
clocks than FU540. These patches also refactor the original
implementation by spliting the dependent-code of fu540 and fu740
respectively.

Changed in v3:
 - Fix the worng bit field shift.

Changed in v2:
 - Remove the macro definition for __prci_clock_array.
 - Indicate the functional changes in commit message.
 - Using option -M and -C to create patches.
 - Rebase code to kernel v5.10-rc3.

Zong Li (3):
  clk: sifive: Extract prci core to common base
  clk: sifive: Use common name for prci configuration
  clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

 arch/riscv/Kconfig.socs   |   2 +-
 drivers/clk/sifive/Kconfig|   8 +-
 drivers/clk/sifive/Makefile   |   5 +-
 drivers/clk/sifive/fu540-prci.c   | 586 +-
 drivers/clk/sifive/fu540-prci.h   |  21 +
 drivers/clk/sifive/fu740-prci.c   | 122 
 drivers/clk/sifive/fu740-prci.h   |  21 +
 .../sifive/{fu540-prci.c => sifive-prci.c}| 499 ++-
 drivers/clk/sifive/sifive-prci.h  | 289 +
 include/dt-bindings/clock/sifive-fu740-prci.h |  23 +
 10 files changed, 703 insertions(+), 873 deletions(-)
 create mode 100644 drivers/clk/sifive/fu540-prci.h
 create mode 100644 drivers/clk/sifive/fu740-prci.c
 create mode 100644 drivers/clk/sifive/fu740-prci.h
 copy drivers/clk/sifive/{fu540-prci.c => sifive-prci.c} (45%)
 create mode 100644 drivers/clk/sifive/sifive-prci.h
 create mode 100644 include/dt-bindings/clock/sifive-fu740-prci.h

-- 
2.29.2



[PATCH v3 2/3] clk: sifive: Use common name for prci configuration

2020-11-11 Thread Zong Li
Use generic name CLK_SIFIVE_PRCI instead of CLK_SIFIVE_FU540_PRCI. This
patch is prepared for fu740 support.

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
Acked-by: Palmer Dabbelt 
Reviewed-by: Pragnesh Patel 
---
 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
-- 
2.29.2



[PATCH v3 3/3] clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

2020-11-11 Thread Zong Li
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 
Erik Danie 
Pragnesh Patel 

Signed-off-by: Zong Li 
Cc: Henry Styles 
Cc: Erik Danie 
Cc: Pragnesh Patel 
---
 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 ..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 
+#include 
+#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 = _fu740_prci_wrpll_clk_ops,
+   .pwd = &__prci_corepll_data,
+   },
+   [PRCI_CLK_DDRPLL] = {
+   .name = "ddrpll",
+   

Re: [PATCH v2 3/3] clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

2020-11-11 Thread Zong Li
On Wed, Nov 11, 2020 at 1:47 PM Pragnesh Patel
 wrote:
>
> Hi Zong,
>
> >-Original Message-
> >From: linux-riscv  On Behalf Of 
> >Zong Li
> >Sent: 10 November 2020 12:58
> >To: Paul Walmsley ( Sifive) ; pal...@dabbelt.com;
> >sb...@kernel.org; sch...@linux-m68k.org; a...@eecs.berkeley.edu;
> >mturque...@baylibre.com; Yash Shah ; linux-
> >ker...@vger.kernel.org; linux-...@vger.kernel.org; linux-
> >ri...@lists.infradead.org
> >Cc: Erik Danie ; Henry Styles ( Sifive) 
> >;
> >Zong Li 
> >Subject: [PATCH v2 3/3] clk: sifive: Add a driver for the SiFive FU740 PRCI 
> >IP
> >block
> >
> >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
> > and Erik Danie .
> >
> >Signed-off-by: Zong Li 
> >Cc: Henry Styles 
> >Cc: Erik Danie 
> >---
> > 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 ..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 
> >+#include 
> >+#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 = sif

[PATCH v2 2/3] clk: sifive: Use common name for prci configuration

2020-11-09 Thread Zong Li
Use generic name CLK_SIFIVE_PRCI instead of CLK_SIFIVE_FU540_PRCI. This
patch is prepared for fu740 support.

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
Acked-by: Palmer Dabbelt 
---
 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
-- 
2.29.2



[PATCH v2 3/3] clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

2020-11-09 Thread Zong Li
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  and Erik Danie .

Signed-off-by: Zong Li 
Cc: Henry Styles 
Cc: Erik Danie 
---
 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 ..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 
+#include 
+#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 = _fu740_prci_wrpll_clk_ops,
+   .pwd = &__prci_corepll_data,
+   },
+   [PRCI_CLK_DDRPLL] = {
+   .name = "ddrpll",
+   .parent_name = "hfclk",
+   .op

[PATCH v2 0/3] clk: add driver for the SiFive FU740

2020-11-09 Thread Zong Li
Add a driver for the SiFive FU740 PRCI IP block, which handles more
clocks than FU540. These patches also refactor the original
implementation by spliting the dependent-code of fu540 and fu740
respectively.

Changed in v2:
 - Remove the macro definition for __prci_clock_array.
 - Indicate the functional changes in commit message.
 - Using option -M and -C to create patches.
 - Rebase code to kernel v5.10-rc3

Zong Li (3):
  clk: sifive: Extract prci core to common base
  clk: sifive: Use common name for prci configuration
  clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

 arch/riscv/Kconfig.socs   |   2 +-
 drivers/clk/sifive/Kconfig|   8 +-
 drivers/clk/sifive/Makefile   |   5 +-
 drivers/clk/sifive/fu540-prci.c   | 586 +-
 drivers/clk/sifive/fu540-prci.h   |  21 +
 drivers/clk/sifive/fu740-prci.c   | 122 
 drivers/clk/sifive/fu740-prci.h   |  21 +
 .../sifive/{fu540-prci.c => sifive-prci.c}| 499 ++-
 drivers/clk/sifive/sifive-prci.h  | 289 +
 include/dt-bindings/clock/sifive-fu740-prci.h |  23 +
 10 files changed, 703 insertions(+), 873 deletions(-)
 create mode 100644 drivers/clk/sifive/fu540-prci.h
 create mode 100644 drivers/clk/sifive/fu740-prci.c
 create mode 100644 drivers/clk/sifive/fu740-prci.h
 copy drivers/clk/sifive/{fu540-prci.c => sifive-prci.c} (45%)
 create mode 100644 drivers/clk/sifive/sifive-prci.h
 create mode 100644 include/dt-bindings/clock/sifive-fu740-prci.h

-- 
2.29.2



[PATCH v2 1/3] clk: sifive: Extract prci core to common base

2020-11-09 Thread Zong Li
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 
---
 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 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-
-/*
- * 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_OFFSET0x4
-# 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_SHIFT25
-# 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_SHIFT0
-# define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << 
PRCI_DDRPLLCFG0_DIVR_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVF_SHIFT6
-# define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << 
PRCI_DDRPLLCFG0_DIVF_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVQ_SHIFT15
-# 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_SHIFT31
-# 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

Re: [PATCH 1/4] clk: sifive: Extract prci core to common base

2020-11-05 Thread Zong Li
On Thu, Nov 5, 2020 at 5:19 PM Andreas Schwab  wrote:
>
> On Nov 05 2020, Zong Li wrote:
>
> > I tried to add -M and -C option to find renames and copies, but it
> > doesn't detect anything here.
>
> -C40 finds a copy drivers/clk/sifive/{fu540-prci.c => sifive-prci.c}.

Thanks! I used the default value of these options, I would create the
patch with -C40 in the next version.

>
> Andreas.
>
> --
> Andreas Schwab, sch...@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."


Re: [PATCH 1/4] clk: sifive: Extract prci core to common base

2020-11-04 Thread Zong Li
On Thu, Nov 5, 2020 at 10:45 AM Stephen Boyd  wrote:
>
> Quoting Zong Li (2020-10-16 02:18:23)
> > 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.
>
> Please indicate if there are any functional changes or this is just code
> movement.

There are some changes for common use, not just code movement or
copies, I would figure out the changes in the commit message  in the
next version.

>
> >
> > Signed-off-by: Zong Li 
> > ---
> >  drivers/clk/sifive/Makefile  |   2 +
> >  drivers/clk/sifive/fu540-prci.c  | 586 +--
> >  drivers/clk/sifive/fu540-prci.h  |  21 ++
> >  drivers/clk/sifive/sifive-prci.c | 409 +
> >  drivers/clk/sifive/sifive-prci.h | 201 +++
>
> How much of this is a copy/pastes? Can you generate patches with
> format-patch -M -C to try to find copies and renames?

I tried to add -M and -C option to find renames and copies, but it
doesn't detect anything here.

>
> >  5 files changed, 652 insertions(+), 567 deletions(-)
> >  create mode 100644 drivers/clk/sifive/fu540-prci.h
> >  create mode 100644 drivers/clk/sifive/sifive-prci.c
> >  create mode 100644 drivers/clk/sifive/sifive-prci.h
> >


Re: [PATCH 4/4] clk: sifive: Refactor __prci_clock array by using macro

2020-11-04 Thread Zong Li
On Thu, Nov 5, 2020 at 10:50 AM Stephen Boyd  wrote:
>
> Quoting Zong Li (2020-10-16 02:18:26)
> > Refactor code by using DEFINE_PRCI_CLOCK to define each clock
> > and reduce duplicate code.
>
> What is duplicate?

Sorry for unclear description, actually, I want to say that we can
remove the repeating code about initializing the data member of
structure.

>
> >
> > Signed-off-by: Zong Li 
> > ---
> >  drivers/clk/sifive/fu540-prci.c  | 38 ++--
> >  drivers/clk/sifive/fu540-prci.h  |  2 +-
> >  drivers/clk/sifive/fu740-prci.c  | 74 
> >  drivers/clk/sifive/fu740-prci.h  |  2 +-
> >  drivers/clk/sifive/sifive-prci.c |  2 +-
> >  drivers/clk/sifive/sifive-prci.h | 10 -
> >  6 files changed, 53 insertions(+), 75 deletions(-)
> >
> > diff --git a/drivers/clk/sifive/fu540-prci.c 
> > b/drivers/clk/sifive/fu540-prci.c
> > index 840b97bfff85..d43b9a9984f6 100644
> > --- a/drivers/clk/sifive/fu540-prci.c
> > +++ b/drivers/clk/sifive/fu540-prci.c
> > @@ -54,29 +54,19 @@ static const struct clk_ops 
> > sifive_fu540_prci_tlclksel_clk_ops = {
> > .recalc_rate = sifive_prci_tlclksel_recalc_rate,
> >  };
> >
> > +DEFINE_PRCI_CLOCK(fu540, corepll, hfclk,
> > + _fu540_prci_wrpll_clk_ops, &__prci_corepll_data);
> > +DEFINE_PRCI_CLOCK(fu540, ddrpll, hfclk,
> > + _fu540_prci_wrpll_ro_clk_ops, &__prci_ddrpll_data);
> > +DEFINE_PRCI_CLOCK(fu540, gemgxlpll, hfclk,
> > + _fu540_prci_wrpll_clk_ops, &__prci_gemgxlpll_data);
> > +DEFINE_PRCI_CLOCK(fu540, tlclk, corepll,
> > + _fu540_prci_tlclksel_clk_ops, NULL);
>
> Readability looks to decrease with this change. Why should all us code
> reviewers suffer because the code author wants to type a few less
> characters? Named initializers are useful so we don't have to hold each
> macro argument in our head and map it to the struct member that is being
> initialized.

Ok, as you mentioned, macro reduce the readability, let me remove this
change in the next version.

>
> > +
> >  /* List of clock controls provided by the PRCI */
> > -struct __prci_clock __prci_init_clocks_fu540[] = {
> > -   [PRCI_CLK_COREPLL] = {
> > -   .name = "corepll",
> > -   .parent_name = "hfclk",
> > -   .ops = _fu540_prci_wrpll_clk_ops,
> > -   .pwd = &__prci_corepll_data,
> > -   },
> > -   [PRCI_CLK_DDRPLL] = {
> > -   .name = "ddrpll",
> > -   .parent_name = "hfclk",
> > -   .ops = _fu540_prci_wrpll_ro_clk_ops,
> > -   .pwd = &__prci_ddrpll_data,
> > -   },
> > -   [PRCI_CLK_GEMGXLPLL] = {
> > -   .name = "gemgxlpll",
> > -   .parent_name = "hfclk",
> > -   .ops = _fu540_prci_wrpll_clk_ops,
> > -   .pwd = &__prci_gemgxlpll_data,
> > -   },
> > -   [PRCI_CLK_TLCLK] = {
> > -   .name = "tlclk",
> > -   .parent_name = "corepll",
> > -   .ops = _fu540_prci_tlclksel_clk_ops,
> > -   },
> > +struct __prci_clock *__prci_init_clocks_fu540[] = {
> > +   [PRCI_CLK_COREPLL]  = _corepll,
> > +   [PRCI_CLK_DDRPLL]   = _ddrpll,
> > +   [PRCI_CLK_GEMGXLPLL]= _gemgxlpll,
> > +   [PRCI_CLK_TLCLK]= _tlclk,
> >  };
> > diff --git a/drivers/clk/sifive/fu540-prci.h 
> > b/drivers/clk/sifive/fu540-prci.h
> > index c8271efa7bdc..281200cd8848 100644
> > --- a/drivers/clk/sifive/fu540-prci.h
> > +++ b/drivers/clk/sifive/fu540-prci.h
> > @@ -11,7 +11,7 @@
> >
> >  #define NUM_CLOCK_FU5404
> >
> > -extern struct __prci_clock __prci_init_clocks_fu540[NUM_CLOCK_FU540];
> > +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,
> > diff --git a/drivers/clk/sifive/fu740-prci.c 
> > b/drivers/clk/sifive/fu740-prci.c
> > index 3b87e273c3eb..676cad2c3886 100644
> > --- a/drivers/clk/sifive/fu740-prci.c
> > +++ b/drivers/clk/sifive/fu740-prci.c
> > @@ -71,52 +71,32 @@ static const struct clk_ops 
> > sifive_fu740_prci_hfpclkplldiv_clk_ops = {
> > .recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
> >  };
> >
> > +
> > +DEFINE_PRCI_CLOCK(fu740, corepll, hfclk,
> &g

Re: [PATCH 2/4] clk: sifive: Use common name for prci configuration

2020-11-04 Thread Zong Li
On Thu, Nov 5, 2020 at 10:46 AM Stephen Boyd  wrote:
>
> Quoting Zong Li (2020-10-16 02:18:24)
> > Use generic name CLK_SIFIVE_PRCI instead of CLK_SIFIVE_FU540_PRCI. This
> > patch is prepared for fu740 support.
> >
> > Signed-off-by: Zong Li 
> > ---
>
> Looks ok but needs an ack from riscv maintainers to go through clk
> tree. I was worried it would break defconfigs but it seems that the arch
> selects the config so this should be OK, right?

Yes, this config is selected by arch, the defconfig won't be impacted.

>
> >  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.


Re: [PATCH 0/4] clk: add driver for the SiFive FU740

2020-11-03 Thread Zong Li
On Fri, Oct 16, 2020 at 10:56 PM Zong Li  wrote:
>
> On Fri, Oct 16, 2020 at 10:17 PM Sean Anderson  wrote:
> >
> > On 10/16/20 5:18 AM, Zong Li wrote:
> > > Add a driver for the SiFive FU740 PRCI IP block, which handles more
> > > clocks than FU540. These patches also refactor the original
> > > implementation by spliting the dependent-code of fu540 and fu740
> > > respectively.
> > >
> > > Zong Li (4):
> > >   clk: sifive: Extract prci core to common base
> >
> > I don't see this patch, and it isn't listed on the web archive. Was it
> > not CC'd to this list?
> >
> > --Sean
> >
>
> There is a problem on linux-riscv mailing list for the first one
> patch, the size of it is too big, it needs to be approved and posted
> on the list by moderator.
>
> This patch set is also sent to clk mailing list, and I can see it on that:
> https://patchwork.kernel.org/project/linux-clk/patch/b10784643665ad56ca41ea6754c7f28f8be1c7ca.1602838910.git.zong...@sifive.com/
>
>
>
>
> > >   clk: sifive: Use common name for prci configuration
> > >   clk: sifive: Add a driver for the SiFive FU740 PRCI IP block
> > >   clk: sifive: Refactor __prci_clock array by using macro
> > >
> > >  arch/riscv/Kconfig.socs   |   2 +-
> > >  drivers/clk/sifive/Kconfig|   8 +-
> > >  drivers/clk/sifive/Makefile   |   5 +-
> > >  drivers/clk/sifive/fu540-prci.c   | 618 +-
> > >  drivers/clk/sifive/fu540-prci.h   |  21 +
> > >  drivers/clk/sifive/fu740-prci.c   | 102 +++
> > >  drivers/clk/sifive/fu740-prci.h   |  21 +
> > >  drivers/clk/sifive/sifive-prci.c  | 529 +++
> > >  drivers/clk/sifive/sifive-prci.h  | 297 +
> > >  include/dt-bindings/clock/sifive-fu740-prci.h |  23 +
> > >  10 files changed, 1032 insertions(+), 594 deletions(-)
> > >  create mode 100644 drivers/clk/sifive/fu540-prci.h
> > >  create mode 100644 drivers/clk/sifive/fu740-prci.c
> > >  create mode 100644 drivers/clk/sifive/fu740-prci.h
> > >  create mode 100644 drivers/clk/sifive/sifive-prci.c
> > >  create mode 100644 drivers/clk/sifive/sifive-prci.h
> > >  create mode 100644 include/dt-bindings/clock/sifive-fu740-prci.h
> > >
> >

ping


Re: [PATCH] stop_machine: Mark functions as notrace

2020-10-28 Thread Zong Li
On Thu, Oct 29, 2020 at 8:23 AM Atish Patra  wrote:
>
> On Wed, Oct 28, 2020 at 8:44 AM Guo Ren  wrote:
> >
> > Hi Zong & Atish,
> >
> > In our 2 harts c910 chip, we found:
> >
> > echo function > /sys/kernel/debug/tracing/current_tracer
> > echo function_graph > /sys/kernel/debug/tracing/current_tracer
> > echo function > /sys/kernel/debug/tracing/current_tracer
> > echo function_graph > /sys/kernel/debug/tracing/current_tracer
> >
> > Then one core halted at stop_machine_yield:
> > arch_cpu_idle () at arch/riscv/kernel/process.c:39
> > 39  local_irq_enable();
> > (gdb) i th
> >   Id   Target Id Frame
> > * 1Thread 1 (CPU#0)  arch_cpu_idle () at arch/riscv/kernel/process.c:39
> >   2Thread 2 (CPU#1)  stop_machine_yield
> > (cpumask=0xffe001371fa8 <__cpu_online_mask>) at
> > ./arch/riscv/include/asm/vdso/processor.h:12
> > (gdb) thread 2
> > [Switching to thread 2 (Thread 2)]
> > #0  stop_machine_yield (cpumask=0xffe001371fa8
> > <__cpu_online_mask>) at ./arch/riscv/include/asm/vdso/processor.h:12
> > 12  __asm__ __volatile__ ("div %0, %0, zero" : "=r" (dummy));
> >
> > With your patch, it's solved. For this patch, I'll give:
> > Tested by: Guo Ren 
> >
> > But that's not enough, we still need:
> >
> > diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
> > index 226ccce..12b8808 100644
> > --- a/arch/riscv/kernel/sbi.c
> > +++ b/arch/riscv/kernel/sbi.c
> > @@ -376,7 +376,7 @@ EXPORT_SYMBOL(sbi_send_ipi);
> >   *
> >   * Return: None
> >   */
> > -void sbi_remote_fence_i(const unsigned long *hart_mask)
> > +void notrace sbi_remote_fence_i(const unsigned long *hart_mask)
> >  {
> > __sbi_rfence(SBI_EXT_RFENCE_REMOTE_FENCE_I,
> >  hart_mask, 0, 0, 0, 0);
> > diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
> > index 400b945d..9467d987 100644
> > --- a/arch/riscv/mm/cacheflush.c
> > +++ b/arch/riscv/mm/cacheflush.c
> > @@ -9,12 +9,12 @@
> >
> >  #include 
> >
> > -static void ipi_remote_fence_i(void *info)
> > +static void notrace ipi_remote_fence_i(void *info)
> >  {
> > return local_flush_icache_all();
> >  }
> >
> > -void flush_icache_all(void)
> > +void notrace flush_icache_all(void)
> >  {
> > if (IS_ENABLED(CONFIG_RISCV_SBI))
> > sbi_remote_fence_i(NULL);
> >
>
> Did you see any issue if these functions are not marked as notrace ?
>
> As per Zong's explanation, the issue was that the other harts already
> fetched the next 2 nops and
> executed 1 while kernel patching replaced other with one of the auipc
> + jalr pair.
>
> @Zong can correct me if I am wrong.
>
> These functions are too far ahead. Can it cause such issues ? If yes,
> then we need to mark each and every function
> that can be invoked from patch_text_nosync and are not inlined.
>
> That includes copy_to_kernel_nofault, __sbi_rfence_v02,
> __sbi_rfence_v02_call, sbi_ecall.
>
> Few of these functions may be inlined by compiler. Can we depend on that ?
>
> > Because:
> > (gdb) bt
> > #0  flush_icache_all () at arch/riscv/mm/cacheflush.c:20
> > #1  0xffe00020473a in patch_text_nosync (addr=, insns=
> > , len=) at arch/riscv/kernel/patch.c:96
> > #2  0xffe000206792 in ftrace_make_call (rec=,
> > addr=) at arch/riscv/kernel/ftrace.c:109
> > #3  0xffe0002c9be4 in __ftrace_replace_code (rec=0xffe01ae40020, e
> > nable=true) at kernel/trace/ftrace.c:2503
> > #4  0xffe0002ca092 in ftrace_replace_code (mod_flags= > out>) at kernel/trace/ftrace.c:2530
> > #5  0xffe0002ca24a in ftrace_modify_all_code (command=9) at kernel
> >/trace/ftrace.c:2677
> > #6  0xffe0002ca2ee in __ftrace_modify_code (data=) at
> >kernel/trace/ftrace.c:2703
> > #7  0xffe0002c1390 in multi_cpu_stop (data=0x0) at kernel/stop_machin
> >e.c:224
> > #8  0xffe0002c0fbe in cpu_stopper_thread (cpu=) at kern
> >el/stop_machine.c:491
> > #9  0xffe0002343be in smpboot_thread_fn (data=0x0) at kernel/smpboot.
> >c:165
> > #10 0xffe00022f894 in kthread (_create=0xffe01af13040) at kern
> >el/kthread.c:292
> > #11 0xffe000201fac in handle_exception () at 
> > arch/riscv/kernel/entry.S:236
> >

It seems to me that the problem happens on the waiting threads, it
doesn't cause the issue on the patching code thread, so it is OK that
these func

[tip: smp/urgent] stop_machine, rcu: Mark functions as notrace

2020-10-26 Thread tip-bot2 for Zong Li
The following commit has been merged into the smp/urgent branch of tip:

Commit-ID: 4230e2deaa484b385aa01d598b2aea8e7f2660a6
Gitweb:
https://git.kernel.org/tip/4230e2deaa484b385aa01d598b2aea8e7f2660a6
Author:Zong Li 
AuthorDate:Wed, 21 Oct 2020 15:38:39 +08:00
Committer: Thomas Gleixner 
CommitterDate: Mon, 26 Oct 2020 12:12:27 +01:00

stop_machine, rcu: Mark functions as notrace

Some architectures assume that the stopped CPUs don't make function calls
to traceable functions when they are in the stopped state. See also commit
cb9d7fd51d9f ("watchdog: Mark watchdog touch functions as notrace").

Violating this assumption causes kernel crashes when switching tracer on
RISC-V.

Mark rcu_momentary_dyntick_idle() and stop_machine_yield() notrace to
prevent this.

Fixes: 4ecf0a43e729 ("processor: get rid of cpu_relax_yield")
Fixes: 366237e7b083 ("stop_machine: Provide RCU quiescent state in 
multi_cpu_stop()")
Signed-off-by: Zong Li 
Signed-off-by: Thomas Gleixner 
Tested-by: Atish Patra 
Tested-by: Colin Ian King 
Acked-by: Steven Rostedt (VMware) 
Acked-by: Paul E. McKenney 
Cc: sta...@vger.kernel.org
Link: https://lore.kernel.org/r/20201021073839.43935-1-zong...@sifive.com
---
 kernel/rcu/tree.c | 2 +-
 kernel/stop_machine.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 06895ef..2a52f42 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -409,7 +409,7 @@ bool rcu_eqs_special_set(int cpu)
  *
  * The caller must have disabled interrupts and must not be idle.
  */
-void rcu_momentary_dyntick_idle(void)
+notrace void rcu_momentary_dyntick_idle(void)
 {
int special;
 
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index 865bb02..890b79c 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -178,7 +178,7 @@ static void ack_state(struct multi_stop_data *msdata)
set_state(msdata, msdata->state + 1);
 }
 
-void __weak stop_machine_yield(const struct cpumask *cpumask)
+notrace void __weak stop_machine_yield(const struct cpumask *cpumask)
 {
cpu_relax();
 }


Re: [PATCH] stop_machine: Mark functions as notrace

2020-10-25 Thread Zong Li
On Sat, Oct 24, 2020 at 3:29 AM Colin Ian King  wrote:
>
> On 21/10/2020 08:38, Zong Li wrote:
> > Like the commit cb9d7fd51d9f ("watchdog: Mark watchdog touch functions
> > as notrace"), some architectures assume that the stopped CPUs don't make
> > function calls to traceable functions when they are in the stopped
> > state. For example, it causes unexpected kernel crashed when switching
> > tracer on RISC-V.
> >
> > The following patches added calls to these two functions, fix it by
> > adding the notrace annotations.
> >
> > Fixes: 4ecf0a43e729 ("processor: get rid of cpu_relax_yield")
> > Fixes: 366237e7b083 ("stop_machine: Provide RCU quiescent state in
> > multi_cpu_stop()")
> >
> > Signed-off-by: Zong Li 
> > ---
> >  kernel/rcu/tree.c | 2 +-
> >  kernel/stop_machine.c | 2 +-
> >  2 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
> > index 06895ef85d69..2a52f42f64b6 100644
> > --- a/kernel/rcu/tree.c
> > +++ b/kernel/rcu/tree.c
> > @@ -409,7 +409,7 @@ bool rcu_eqs_special_set(int cpu)
> >   *
> >   * The caller must have disabled interrupts and must not be idle.
> >   */
> > -void rcu_momentary_dyntick_idle(void)
> > +notrace void rcu_momentary_dyntick_idle(void)
> >  {
> >   int special;
> >
> > diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
> > index 865bb0228ab6..890b79cf0e7c 100644
> > --- a/kernel/stop_machine.c
> > +++ b/kernel/stop_machine.c
> > @@ -178,7 +178,7 @@ static void ack_state(struct multi_stop_data *msdata)
> >   set_state(msdata, msdata->state + 1);
> >  }
> >
> > -void __weak stop_machine_yield(const struct cpumask *cpumask)
> > +notrace void __weak stop_machine_yield(const struct cpumask *cpumask)
> >  {
> >   cpu_relax();
> >  }
> >
>
> Apologies for taking so long to reply, I needed to test this on several
> devices.
>
> This not only fixes the ftrace issue I see on RISC-V but also a ftrace
> hang issue on ARM64 in 5.8 too.
>
> Tested-by: Colin Ian King 
>
> Many thanks!

Many thanks all for reviewing and testing.

Hi Palmer,
As Steven suggested, could you help to pick up this patch in RISC-V tree?


[PATCH] stop_machine: Mark functions as notrace

2020-10-21 Thread Zong Li
Like the commit cb9d7fd51d9f ("watchdog: Mark watchdog touch functions
as notrace"), some architectures assume that the stopped CPUs don't make
function calls to traceable functions when they are in the stopped
state. For example, it causes unexpected kernel crashed when switching
tracer on RISC-V.

The following patches added calls to these two functions, fix it by
adding the notrace annotations.

Fixes: 4ecf0a43e729 ("processor: get rid of cpu_relax_yield")
Fixes: 366237e7b083 ("stop_machine: Provide RCU quiescent state in
multi_cpu_stop()")

Signed-off-by: Zong Li 
---
 kernel/rcu/tree.c | 2 +-
 kernel/stop_machine.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 06895ef85d69..2a52f42f64b6 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -409,7 +409,7 @@ bool rcu_eqs_special_set(int cpu)
  *
  * The caller must have disabled interrupts and must not be idle.
  */
-void rcu_momentary_dyntick_idle(void)
+notrace void rcu_momentary_dyntick_idle(void)
 {
int special;
 
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index 865bb0228ab6..890b79cf0e7c 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -178,7 +178,7 @@ static void ack_state(struct multi_stop_data *msdata)
set_state(msdata, msdata->state + 1);
 }
 
-void __weak stop_machine_yield(const struct cpumask *cpumask)
+notrace void __weak stop_machine_yield(const struct cpumask *cpumask)
 {
cpu_relax();
 }
-- 
2.28.0



Re: [PATCH v4 9/9] riscv: Fixup lockdep_assert_held(_mutex) in patch_insn_write

2020-10-21 Thread Zong Li
On Wed, Oct 21, 2020 at 4:41 AM Steven Rostedt  wrote:
>
> On Tue, 20 Oct 2020 19:18:01 +0800
> Guo Ren  wrote:
>
> > > What platform are you testing ? We are seeing a crash while enabling
> > > any of the tracers multiple times
> > > on Qemu/HiFive Unleashed.
> > I use qemu for testing. I've changed dynamic ftrace mechanism from
> > mcount to -fpatchable-entry.
> >
> > The problem is made by the lockdep checking of text_mutex.
>
> If you are switching to "patchable-entry" you shouldn't need to use
> stop_machine for the updates. No?
>
> -- Steve

Hi all,

I'm going to send the patch to fix the problem. Ftrace was broken from
v5.3 kernel version, and only happen on SMP. The problem is caused by
the following two patches:

Commit 4ecf0a43e729a7e641d800c294faabe87378fc05 ("processor: get rid
of cpu_relax_yield")
and
Commit 366237e7b0833faa2d8da7a8d7d7da8c3ca802e5 ("stop_machine:
Provide RCU quiescent state in multi_cpu_stop()")

We have to mark these two functions as notrace. The stopped CPUs
cannot make function calls to traceable functions on RISC-V, the
function call instruction pattern needs two instructions (auipc,
jalr), so there is a change to execute the (auipc + nop) or (nop,
jalr) when patching code.

There is a similar fix as follow:
Commit cb9d7fd51d9fbb329d182423bd7b92d0f8cb0e01 ("watchdog: Mark
watchdog touch functions as notrace")

I have verified my patches, and I'm going to send it to the mailing
list these few days.


Re: [PATCH 0/4] clk: add driver for the SiFive FU740

2020-10-16 Thread Zong Li
On Fri, Oct 16, 2020 at 10:17 PM Sean Anderson  wrote:
>
> On 10/16/20 5:18 AM, Zong Li wrote:
> > Add a driver for the SiFive FU740 PRCI IP block, which handles more
> > clocks than FU540. These patches also refactor the original
> > implementation by spliting the dependent-code of fu540 and fu740
> > respectively.
> >
> > Zong Li (4):
> >   clk: sifive: Extract prci core to common base
>
> I don't see this patch, and it isn't listed on the web archive. Was it
> not CC'd to this list?
>
> --Sean
>

There is a problem on linux-riscv mailing list for the first one
patch, the size of it is too big, it needs to be approved and posted
on the list by moderator.

This patch set is also sent to clk mailing list, and I can see it on that:
https://patchwork.kernel.org/project/linux-clk/patch/b10784643665ad56ca41ea6754c7f28f8be1c7ca.1602838910.git.zong...@sifive.com/




> >   clk: sifive: Use common name for prci configuration
> >   clk: sifive: Add a driver for the SiFive FU740 PRCI IP block
> >   clk: sifive: Refactor __prci_clock array by using macro
> >
> >  arch/riscv/Kconfig.socs   |   2 +-
> >  drivers/clk/sifive/Kconfig|   8 +-
> >  drivers/clk/sifive/Makefile   |   5 +-
> >  drivers/clk/sifive/fu540-prci.c   | 618 +-
> >  drivers/clk/sifive/fu540-prci.h   |  21 +
> >  drivers/clk/sifive/fu740-prci.c   | 102 +++
> >  drivers/clk/sifive/fu740-prci.h   |  21 +
> >  drivers/clk/sifive/sifive-prci.c  | 529 +++
> >  drivers/clk/sifive/sifive-prci.h  | 297 +
> >  include/dt-bindings/clock/sifive-fu740-prci.h |  23 +
> >  10 files changed, 1032 insertions(+), 594 deletions(-)
> >  create mode 100644 drivers/clk/sifive/fu540-prci.h
> >  create mode 100644 drivers/clk/sifive/fu740-prci.c
> >  create mode 100644 drivers/clk/sifive/fu740-prci.h
> >  create mode 100644 drivers/clk/sifive/sifive-prci.c
> >  create mode 100644 drivers/clk/sifive/sifive-prci.h
> >  create mode 100644 include/dt-bindings/clock/sifive-fu740-prci.h
> >
>


[PATCH 4/4] clk: sifive: Refactor __prci_clock array by using macro

2020-10-16 Thread Zong Li
Refactor code by using DEFINE_PRCI_CLOCK to define each clock
and reduce duplicate code.

Signed-off-by: Zong Li 
---
 drivers/clk/sifive/fu540-prci.c  | 38 ++--
 drivers/clk/sifive/fu540-prci.h  |  2 +-
 drivers/clk/sifive/fu740-prci.c  | 74 
 drivers/clk/sifive/fu740-prci.h  |  2 +-
 drivers/clk/sifive/sifive-prci.c |  2 +-
 drivers/clk/sifive/sifive-prci.h | 10 -
 6 files changed, 53 insertions(+), 75 deletions(-)

diff --git a/drivers/clk/sifive/fu540-prci.c b/drivers/clk/sifive/fu540-prci.c
index 840b97bfff85..d43b9a9984f6 100644
--- a/drivers/clk/sifive/fu540-prci.c
+++ b/drivers/clk/sifive/fu540-prci.c
@@ -54,29 +54,19 @@ static const struct clk_ops 
sifive_fu540_prci_tlclksel_clk_ops = {
.recalc_rate = sifive_prci_tlclksel_recalc_rate,
 };
 
+DEFINE_PRCI_CLOCK(fu540, corepll, hfclk,
+ _fu540_prci_wrpll_clk_ops, &__prci_corepll_data);
+DEFINE_PRCI_CLOCK(fu540, ddrpll, hfclk,
+ _fu540_prci_wrpll_ro_clk_ops, &__prci_ddrpll_data);
+DEFINE_PRCI_CLOCK(fu540, gemgxlpll, hfclk,
+ _fu540_prci_wrpll_clk_ops, &__prci_gemgxlpll_data);
+DEFINE_PRCI_CLOCK(fu540, tlclk, corepll,
+ _fu540_prci_tlclksel_clk_ops, NULL);
+
 /* List of clock controls provided by the PRCI */
-struct __prci_clock __prci_init_clocks_fu540[] = {
-   [PRCI_CLK_COREPLL] = {
-   .name = "corepll",
-   .parent_name = "hfclk",
-   .ops = _fu540_prci_wrpll_clk_ops,
-   .pwd = &__prci_corepll_data,
-   },
-   [PRCI_CLK_DDRPLL] = {
-   .name = "ddrpll",
-   .parent_name = "hfclk",
-   .ops = _fu540_prci_wrpll_ro_clk_ops,
-   .pwd = &__prci_ddrpll_data,
-   },
-   [PRCI_CLK_GEMGXLPLL] = {
-   .name = "gemgxlpll",
-   .parent_name = "hfclk",
-   .ops = _fu540_prci_wrpll_clk_ops,
-   .pwd = &__prci_gemgxlpll_data,
-   },
-   [PRCI_CLK_TLCLK] = {
-   .name = "tlclk",
-   .parent_name = "corepll",
-   .ops = _fu540_prci_tlclksel_clk_ops,
-   },
+struct __prci_clock *__prci_init_clocks_fu540[] = {
+   [PRCI_CLK_COREPLL]  = _corepll,
+   [PRCI_CLK_DDRPLL]   = _ddrpll,
+   [PRCI_CLK_GEMGXLPLL]= _gemgxlpll,
+   [PRCI_CLK_TLCLK]= _tlclk,
 };
diff --git a/drivers/clk/sifive/fu540-prci.h b/drivers/clk/sifive/fu540-prci.h
index c8271efa7bdc..281200cd8848 100644
--- a/drivers/clk/sifive/fu540-prci.h
+++ b/drivers/clk/sifive/fu540-prci.h
@@ -11,7 +11,7 @@
 
 #define NUM_CLOCK_FU5404
 
-extern struct __prci_clock __prci_init_clocks_fu540[NUM_CLOCK_FU540];
+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,
diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index 3b87e273c3eb..676cad2c3886 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -71,52 +71,32 @@ static const struct clk_ops 
sifive_fu740_prci_hfpclkplldiv_clk_ops = {
.recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
 };
 
+
+DEFINE_PRCI_CLOCK(fu740, corepll, hfclk,
+ _fu740_prci_wrpll_clk_ops, &__prci_corepll_data);
+DEFINE_PRCI_CLOCK(fu740, ddrpll, hfclk,
+ _fu740_prci_wrpll_ro_clk_ops, &__prci_ddrpll_data);
+DEFINE_PRCI_CLOCK(fu740, gemgxlpll, hfclk,
+ _fu740_prci_wrpll_clk_ops, &__prci_gemgxlpll_data);
+DEFINE_PRCI_CLOCK(fu740, dvfscorepll, hfclk,
+ _fu740_prci_wrpll_clk_ops, &__prci_dvfscorepll_data);
+DEFINE_PRCI_CLOCK(fu740, hfpclkpll, hfclk,
+ _fu740_prci_wrpll_clk_ops, &__prci_hfpclkpll_data);
+DEFINE_PRCI_CLOCK(fu740, cltxpll, hfclk,
+ _fu740_prci_wrpll_clk_ops, &__prci_cltxpll_data);
+DEFINE_PRCI_CLOCK(fu740, tlclk, corepll,
+ _fu740_prci_tlclksel_clk_ops, NULL);
+DEFINE_PRCI_CLOCK(fu740, pclk, hfpclkpll,
+ _fu740_prci_hfpclkplldiv_clk_ops, NULL);
+
 /* List of clock controls provided by the PRCI */
-struct __prci_clock __prci_init_clocks_fu740[] = {
-   [PRCI_CLK_COREPLL] = {
-   .name = "corepll",
-   .parent_name = "hfclk",
-   .ops = _fu740_prci_wrpll_clk_ops,
-   .pwd = &__prci_corepll_data,
-   },
-   [PRCI_CLK_DDRPLL] = {
-   .name = "ddrpll",
-   .parent_name = "hfclk",
-   .ops = _fu740_prci_wrpll_ro_clk_ops,
-   .pwd = &__prci_ddrpll_data,
-   },
-   [PRCI_CLK_GEMGXLPLL] = {
-   .name = "gemgxlpll",
-   .parent_name = "hfclk",
-   .ops = 

[PATCH 1/4] clk: sifive: Extract prci core to common base

2020-10-16 Thread Zong Li
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.

Signed-off-by: Zong Li 
---
 drivers/clk/sifive/Makefile  |   2 +
 drivers/clk/sifive/fu540-prci.c  | 586 +--
 drivers/clk/sifive/fu540-prci.h  |  21 ++
 drivers/clk/sifive/sifive-prci.c | 409 +
 drivers/clk/sifive/sifive-prci.h | 201 +++
 5 files changed, 652 insertions(+), 567 deletions(-)
 create mode 100644 drivers/clk/sifive/fu540-prci.h
 create mode 100644 drivers/clk/sifive/sifive-prci.c
 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 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
-#include 
-#include 
-#include 
-#include 
-
-/*
- * 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_OFFSET0x4
-# 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_SHIFT25
-# 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_SHIFT0
-# define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << 
PRCI_DDRPLLCFG0_DIVR_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVF_SHIFT6
-# define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << 
PRCI_DDRPLLCFG0_DIVF_SHIFT)
-# define PRCI_DDRPLLCFG0_DIVQ_SHIFT15
-# 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_SHIFT31
-# 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

[PATCH 0/4] clk: add driver for the SiFive FU740

2020-10-16 Thread Zong Li
Add a driver for the SiFive FU740 PRCI IP block, which handles more
clocks than FU540. These patches also refactor the original
implementation by spliting the dependent-code of fu540 and fu740
respectively.

Zong Li (4):
  clk: sifive: Extract prci core to common base
  clk: sifive: Use common name for prci configuration
  clk: sifive: Add a driver for the SiFive FU740 PRCI IP block
  clk: sifive: Refactor __prci_clock array by using macro

 arch/riscv/Kconfig.socs   |   2 +-
 drivers/clk/sifive/Kconfig|   8 +-
 drivers/clk/sifive/Makefile   |   5 +-
 drivers/clk/sifive/fu540-prci.c   | 618 +-
 drivers/clk/sifive/fu540-prci.h   |  21 +
 drivers/clk/sifive/fu740-prci.c   | 102 +++
 drivers/clk/sifive/fu740-prci.h   |  21 +
 drivers/clk/sifive/sifive-prci.c  | 529 +++
 drivers/clk/sifive/sifive-prci.h  | 297 +
 include/dt-bindings/clock/sifive-fu740-prci.h |  23 +
 10 files changed, 1032 insertions(+), 594 deletions(-)
 create mode 100644 drivers/clk/sifive/fu540-prci.h
 create mode 100644 drivers/clk/sifive/fu740-prci.c
 create mode 100644 drivers/clk/sifive/fu740-prci.h
 create mode 100644 drivers/clk/sifive/sifive-prci.c
 create mode 100644 drivers/clk/sifive/sifive-prci.h
 create mode 100644 include/dt-bindings/clock/sifive-fu740-prci.h

-- 
2.28.0



[PATCH 2/4] clk: sifive: Use common name for prci configuration

2020-10-16 Thread Zong Li
Use generic name CLK_SIFIVE_PRCI instead of CLK_SIFIVE_FU540_PRCI. This
patch is prepared for fu740 support.

Signed-off-by: Zong Li 
---
 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
-- 
2.28.0



[PATCH 3/4] clk: sifive: Add a driver for the SiFive FU740 PRCI IP block

2020-10-16 Thread Zong Li
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  and Erik Danie .

Signed-off-by: Zong Li 
Cc: Henry Styles 
Cc: Erik Danie 
---
 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 ..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 
+#include 
+#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 = _fu740_prci_wrpll_clk_ops,
+   .pwd = &__prci_corepll_data,
+   },
+   [PRCI_CLK_DDRPLL] = {
+   .name = "ddrpll",
+   .parent_name = "hfclk",
+   .op

Re: [Bug 209317] ftrace kernel self test failure on RISC-V on 5.8, regression from 5.4.0

2020-10-05 Thread Zong Li
Hi Atish,

I can take out some time to take a look at it together, if anyone here
fixes it or has ideas, please share the information, thanks.

On Sun, Oct 4, 2020 at 1:33 AM Atish Patra  wrote:
>
> Hi Alan and Zong,
> I initially suspected ftrace is broken between v5.6 & v5.7 as Kolin pointed 
> out.
> I couldn't find any reason how the HSM patch is related. Zong's ftrace
> patching code was also merged in that release.
> However, I was able to reproduce the issue in the older kernel(v5.4)
> as well on both Qemu & Unleashed hardware.
> Here are the steps:
>
> mount -t debugfs none /sys/kernel/debug/
> cd /sys/kernel/debug/tracing
> echo function_graph > current_tracer
> echo function > current_tracer
>
> It works for the first time with function_graph but writing any other
> tracer crashes immediately.
> Can you take a look to check if the bug is in ftrace infrastructure code ?
>
> On Mon, Sep 28, 2020 at 10:25 AM Atish Patra  wrote:
> >
> > On Mon, 2020-09-28 at 11:13 -0400, Steven Rostedt wrote:
> > > On Sat, 26 Sep 2020 22:02:35 +
> > > bugzilla-dae...@bugzilla.kernel.org wrote:
> > >
> > > > https://bugzilla.kernel.org/show_bug.cgi?id=209317
> > > >
> > > > --- Comment #4 from Colin Ian King (colin.k...@canonical.com) ---
> > > > Issue still in 5.9-rc6
> > > >
> > >
> > > Atish,
> > >
> > > As the issues bisects down to your commit, care to take a look at
> > > this.
> > > (And take ownership of this bug)
> > >
> >
> > Yes. I am already looking into this. Colin informed me about the bug
> > over the weekend.
> >
> > I couldn't change the ownership as I am not part of the editbugs group.
> > I have sent an email to helpd...@kernel.org for access.
> >
> > > -- Steve
> >
> > --
> > Regards,
> > Atish
> > ___
> > linux-riscv mailing list
> > linux-ri...@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-riscv
>
>
>
> --
> Regards,
> Atish


[PATCH v4 2/3] riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO

2020-08-31 Thread Zong Li
AT_VECTOR_SIZE_ARCH should be defined with the maximum number of
NEW_AUX_ENT entries that ARCH_DLINFO can contain, but it wasn't defined
for RISC-V at all even though ARCH_DLINFO will contain one NEW_AUX_ENT
for the VDSO address.

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
---
 arch/riscv/include/uapi/asm/auxvec.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/auxvec.h 
b/arch/riscv/include/uapi/asm/auxvec.h
index d86cb17bbabe..22e0ae888406 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,4 +10,7 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+/* entries in ARCH_DLINFO */
+#define AT_VECTOR_SIZE_ARCH1
+
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
-- 
2.28.0



[PATCH v4 1/3] riscv: Set more data to cacheinfo

2020-08-31 Thread Zong Li
Set cacheinfo.{size,sets,line_size} for each cache node, then we can
get these information from userland through auxiliary vector.

Signed-off-by: Zong Li 
---
 arch/riscv/kernel/cacheinfo.c | 66 +++
 1 file changed, 51 insertions(+), 15 deletions(-)

diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
index bd0f122965c3..291d7d8f748b 100644
--- a/arch/riscv/kernel/cacheinfo.c
+++ b/arch/riscv/kernel/cacheinfo.c
@@ -25,12 +25,53 @@ cache_get_priv_group(struct cacheinfo *this_leaf)
return NULL;
 }
 
-static void ci_leaf_init(struct cacheinfo *this_leaf,
-struct device_node *node,
-enum cache_type type, unsigned int level)
+static void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type,
+unsigned int level, unsigned int size,
+unsigned int sets, unsigned int line_size)
 {
this_leaf->level = level;
this_leaf->type = type;
+   this_leaf->size = size;
+   this_leaf->number_of_sets = sets;
+   this_leaf->coherency_line_size = line_size;
+
+   /*
+* If the cache is fully associative, there is no need to
+* check the other properties.
+*/
+   if (sets == 1)
+   return;
+
+   /*
+* Set the ways number for n-ways associative, make sure
+* all properties are big than zero.
+*/
+   if (sets > 0 && size > 0 && line_size > 0)
+   this_leaf->ways_of_associativity = (size / sets) / line_size;
+}
+
+static void fill_cacheinfo(struct cacheinfo **this_leaf,
+  struct device_node *node, unsigned int level)
+{
+   unsigned int size, sets, line_size;
+
+   if (!of_property_read_u32(node, "cache-size", ) &&
+   !of_property_read_u32(node, "cache-block-size", _size) &&
+   !of_property_read_u32(node, "cache-sets", )) {
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_UNIFIED, level, size, 
sets, line_size);
+   }
+
+   if (!of_property_read_u32(node, "i-cache-size", ) &&
+   !of_property_read_u32(node, "i-cache-sets", ) &&
+   !of_property_read_u32(node, "i-cache-block-size", _size)) {
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_INST, level, size, 
sets, line_size);
+   }
+
+   if (!of_property_read_u32(node, "d-cache-size", ) &&
+   !of_property_read_u32(node, "d-cache-sets", ) &&
+   !of_property_read_u32(node, "d-cache-block-size", _size)) {
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_DATA, level, size, 
sets, line_size);
+   }
 }
 
 static int __init_cache_level(unsigned int cpu)
@@ -83,29 +124,24 @@ static int __populate_cache_leaves(unsigned int cpu)
struct device_node *prev = NULL;
int levels = 1, level = 1;
 
-   if (of_property_read_bool(np, "cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
-   if (of_property_read_bool(np, "i-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
-   if (of_property_read_bool(np, "d-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
+   /* Level 1 caches in cpu node */
+   fill_cacheinfo(_leaf, np, level);
 
+   /* Next level caches in cache nodes */
prev = np;
while ((np = of_find_next_cache_node(np))) {
of_node_put(prev);
prev = np;
+
if (!of_device_is_compatible(np, "cache"))
break;
if (of_property_read_u32(np, "cache-level", ))
break;
if (level <= levels)
break;
-   if (of_property_read_bool(np, "cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, 
level);
-   if (of_property_read_bool(np, "i-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
-   if (of_property_read_bool(np, "d-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
+
+   fill_cacheinfo(_leaf, np, level);
+
levels = level;
}
of_node_put(np);
-- 
2.28.0



[PATCH v4 0/3] Get cache information from userland

2020-08-31 Thread Zong Li
There are no standard CSR registers to provide cache information, the
way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
could use them to get information of cache through AUX vector. We
exploit 'struct cacheinfo' to obtain the information of cache, then we
don't need additional variable or data structure to record it.

We also need some works in glibc, but we have to support the function in
kernel first by rule of glibc, then post the patch to glibc site.

The result of 'getconf -a' as follows:

LEVEL1_ICACHE_SIZE 32768
LEVEL1_ICACHE_ASSOC8
LEVEL1_ICACHE_LINESIZE 64
LEVEL1_DCACHE_SIZE 32768
LEVEL1_DCACHE_ASSOC8
LEVEL1_DCACHE_LINESIZE 64
LEVEL2_CACHE_SIZE  2097152
LEVEL2_CACHE_ASSOC 32
LEVEL2_CACHE_LINESIZE  64

Changed in v4:
  - Check null pointer before use.
  - Re-write the code for readability.
  - Rebase source to v5.9-rc3.

Changed in v3:
  - Fix sparse warning: Use NULL instead of integer 0.

Changed in v2:
  - Add error checking for parsing cache properties.

Zong Li (3):
  riscv: Set more data to cacheinfo
  riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
  riscv: Add cache information in AUX vector

 arch/riscv/include/asm/cacheinfo.h   |  5 ++
 arch/riscv/include/asm/elf.h | 13 
 arch/riscv/include/uapi/asm/auxvec.h | 24 +++
 arch/riscv/kernel/cacheinfo.c| 98 +++-
 4 files changed, 124 insertions(+), 16 deletions(-)

-- 
2.28.0



[PATCH v4 3/3] riscv: Add cache information in AUX vector

2020-08-31 Thread Zong Li
There are no standard CSR registers to provide cache information, the
way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
could use them to get information of cache through AUX vector.

The result of 'getconf -a' as follows:
LEVEL1_ICACHE_SIZE 32768
LEVEL1_ICACHE_ASSOC8
LEVEL1_ICACHE_LINESIZE 64
LEVEL1_DCACHE_SIZE 32768
LEVEL1_DCACHE_ASSOC8
LEVEL1_DCACHE_LINESIZE 64
LEVEL2_CACHE_SIZE  2097152
LEVEL2_CACHE_ASSOC 32
LEVEL2_CACHE_LINESIZE  64

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
---
 arch/riscv/include/asm/cacheinfo.h   |  5 +
 arch/riscv/include/asm/elf.h | 13 +++
 arch/riscv/include/uapi/asm/auxvec.h | 23 +++-
 arch/riscv/kernel/cacheinfo.c| 32 +++-
 4 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/cacheinfo.h 
b/arch/riscv/include/asm/cacheinfo.h
index 5d9662e9aba8..d1a365215ec0 100644
--- a/arch/riscv/include/asm/cacheinfo.h
+++ b/arch/riscv/include/asm/cacheinfo.h
@@ -1,4 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 SiFive
+ */
 
 #ifndef _ASM_RISCV_CACHEINFO_H
 #define _ASM_RISCV_CACHEINFO_H
@@ -11,5 +14,7 @@ struct riscv_cacheinfo_ops {
 };
 
 void riscv_set_cacheinfo_ops(struct riscv_cacheinfo_ops *ops);
+uintptr_t get_cache_size(u32 level, enum cache_type type);
+uintptr_t get_cache_geometry(u32 level, enum cache_type type);
 
 #endif /* _ASM_RISCV_CACHEINFO_H */
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index d83a4efd052b..5c725e1df58b 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * These are used to set parameters in the core dumps.
@@ -61,6 +62,18 @@ extern unsigned long elf_hwcap;
 do {   \
NEW_AUX_ENT(AT_SYSINFO_EHDR,\
(elf_addr_t)current->mm->context.vdso); \
+   NEW_AUX_ENT(AT_L1I_CACHESIZE,   \
+   get_cache_size(1, CACHE_TYPE_INST));\
+   NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY,   \
+   get_cache_geometry(1, CACHE_TYPE_INST));\
+   NEW_AUX_ENT(AT_L1D_CACHESIZE,   \
+   get_cache_size(1, CACHE_TYPE_DATA));\
+   NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY,   \
+   get_cache_geometry(1, CACHE_TYPE_DATA));\
+   NEW_AUX_ENT(AT_L2_CACHESIZE,\
+   get_cache_size(2, CACHE_TYPE_UNIFIED)); \
+   NEW_AUX_ENT(AT_L2_CACHEGEOMETRY,\
+   get_cache_geometry(2, CACHE_TYPE_UNIFIED)); \
 } while (0)
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
 struct linux_binprm;
diff --git a/arch/riscv/include/uapi/asm/auxvec.h 
b/arch/riscv/include/uapi/asm/auxvec.h
index 22e0ae888406..32c73ba1d531 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,7 +10,28 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+/*
+ * The set of entries below represent more extensive information
+ * about the caches, in the form of two entry per cache type,
+ * one entry containing the cache size in bytes, and the other
+ * containing the cache line size in bytes in the bottom 16 bits
+ * and the cache associativity in the next 16 bits.
+ *
+ * The associativity is such that if N is the 16-bit value, the
+ * cache is N way set associative. A value if 0x means fully
+ * associative, a value of 1 means directly mapped.
+ *
+ * For all these fields, a value of 0 means that the information
+ * is not known.
+ */
+#define AT_L1I_CACHESIZE   40
+#define AT_L1I_CACHEGEOMETRY   41
+#define AT_L1D_CACHESIZE   42
+#define AT_L1D_CACHEGEOMETRY   43
+#define AT_L2_CACHESIZE44
+#define AT_L2_CACHEGEOMETRY45
+
 /* entries in ARCH_DLINFO */
-#define AT_VECTOR_SIZE_ARCH1
+#define AT_VECTOR_SIZE_ARCH7
 
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
index 291d7d8f748b..de59dd457b41 100644
--- a/arch/riscv/kernel/cacheinfo.c
+++ b/arch/riscv/kernel/cacheinfo.c
@@ -3,7 +3,6 @@
  * Copyright (C) 2017 SiFive
  */
 
-#include 
 #include 
 #include 
 #include 
@@ -25,6 +24,37 @@ cache_get_priv_group(struct cacheinfo *this_leaf)
return NULL;
 }
 
+static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type)
+{
+   struct cpu_cacheinfo *this_cpu_ci = 
get_cpu_cacheinfo(smp_processor_id());
+   struct cacheinfo *this_leaf;
+   int index;
+
+   for (index = 0; index < this_cpu_ci->num_l

Re: [PATCH v3 1/3] riscv: Set more data to cacheinfo

2020-08-31 Thread Zong Li
On Mon, Aug 31, 2020 at 3:00 PM Pekka Enberg  wrote:
>
> Hi,
>
> On Mon, Aug 31, 2020 at 9:15 AM Zong Li  wrote:
> > If the sets is one, it means that the cache is fully associative, then
> > we don't need to fill the ways number, just keep way number as zero,
> > so here we want to find the fully associative case first and make the
> > if expression fail at the beginning. We might also rewrite it as
> > follow:
>
> [snip]
>
> Thanks for the explanation! The rewritten version is much easier to
> read, at least to me.
>

Let me change it for readability in the next version, thanks.

> - Pekka


Re: [PATCH v3 3/3] riscv: Add cache information in AUX vector

2020-08-31 Thread Zong Li
On Sun, Aug 30, 2020 at 4:01 PM Pekka Enberg  wrote:
>
> On Fri, Aug 28, 2020 at 10:09 AM Zong Li  wrote:
> > +uintptr_t get_cache_geometry(u32 level, enum cache_type type)
> > +{
> > +   struct cacheinfo *this_leaf = get_cacheinfo(level, type);
> > +   uintptr_t ret = (this_leaf->ways_of_associativity << 16 |
> > +this_leaf->coherency_line_size);
>
> You are dereferencing "this_leaf" without checking if it's NULL here.
>

oh yeah, it should check the pointer first here. Fix it in the next
version, thanks.

> > +
> > +   return this_leaf ? ret : 0;
> > +}
>
> - Pekka


Re: [PATCH v3 1/3] riscv: Set more data to cacheinfo

2020-08-31 Thread Zong Li
On Sun, Aug 30, 2020 at 3:54 PM Pekka Enberg  wrote:
>
> Hi,
>
> On Fri, Aug 28, 2020 at 10:09 AM Zong Li  wrote:
> >
> > Set cacheinfo.{size,sets,line_size} for each cache node, then we can
> > get these information from userland through auxiliary vector.
> >
> > Signed-off-by: Zong Li 
> > ---
> >  arch/riscv/kernel/cacheinfo.c | 59 ++-
> >  1 file changed, 44 insertions(+), 15 deletions(-)
> >
> > diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
> > index bd0f122965c3..8b85abfbd77a 100644
> > --- a/arch/riscv/kernel/cacheinfo.c
> > +++ b/arch/riscv/kernel/cacheinfo.c
> > @@ -25,12 +25,46 @@ cache_get_priv_group(struct cacheinfo *this_leaf)
> > return NULL;
> >  }
> >
> > -static void ci_leaf_init(struct cacheinfo *this_leaf,
> > -struct device_node *node,
> > -enum cache_type type, unsigned int level)
> > +static void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type,
> > +unsigned int level, unsigned int size,
> > +unsigned int sets, unsigned int line_size)
> >  {
> > this_leaf->level = level;
> > this_leaf->type = type;
> > +   this_leaf->size = size;
> > +   this_leaf->number_of_sets = sets;
> > +   this_leaf->coherency_line_size = line_size;
> > +
> > +   /*
> > +* If the cache is fully associative, there is no need to
> > +* check the other properties.
> > +*/
> > +   if (!(sets == 1) && (sets > 0 && size > 0 && line_size > 0))
>
> Can you explain what this is attempting to do? AFAICT, the if
> expression can be reduced to "sets > 1 && size > 0 && size > 0", but
> what do you mean with the comment about fully associative caches?

If the sets is one, it means that the cache is fully associative, then
we don't need to fill the ways number, just keep way number as zero,
so here we want to find the fully associative case first and make the
if expression fail at the beginning. We might also rewrite it as
follow:

/* Fully associative */
if (sets == 1)
return;

/* n-ways associative, make sure all properties are big than zero, it
is meaningless when one of them are zero.  Full associative case is
filtered by the condition above, so we don't need to consider sets ==
1 again. */
if (sets > 0 && size > 0 && line_size >0)
this_leaf->ways_of_associativity = (size / sets) / line_size;

>
> > +   this_leaf->ways_of_associativity = (size / sets) / 
> > line_size;
> > +}


[PATCH v3 3/3] riscv: Add cache information in AUX vector

2020-08-28 Thread Zong Li
There are no standard CSR registers to provide cache information, the
way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
could use them to get information of cache through AUX vector.

The result of 'getconf -a' as follows:
LEVEL1_ICACHE_SIZE 32768
LEVEL1_ICACHE_ASSOC8
LEVEL1_ICACHE_LINESIZE 64
LEVEL1_DCACHE_SIZE 32768
LEVEL1_DCACHE_ASSOC8
LEVEL1_DCACHE_LINESIZE 64
LEVEL2_CACHE_SIZE  2097152
LEVEL2_CACHE_ASSOC 32
LEVEL2_CACHE_LINESIZE  64

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
---
 arch/riscv/include/asm/cacheinfo.h   |  5 +
 arch/riscv/include/asm/elf.h | 13 +++
 arch/riscv/include/uapi/asm/auxvec.h | 23 +++-
 arch/riscv/kernel/cacheinfo.c| 32 +++-
 4 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/cacheinfo.h 
b/arch/riscv/include/asm/cacheinfo.h
index 5d9662e9aba8..d1a365215ec0 100644
--- a/arch/riscv/include/asm/cacheinfo.h
+++ b/arch/riscv/include/asm/cacheinfo.h
@@ -1,4 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 SiFive
+ */
 
 #ifndef _ASM_RISCV_CACHEINFO_H
 #define _ASM_RISCV_CACHEINFO_H
@@ -11,5 +14,7 @@ struct riscv_cacheinfo_ops {
 };
 
 void riscv_set_cacheinfo_ops(struct riscv_cacheinfo_ops *ops);
+uintptr_t get_cache_size(u32 level, enum cache_type type);
+uintptr_t get_cache_geometry(u32 level, enum cache_type type);
 
 #endif /* _ASM_RISCV_CACHEINFO_H */
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index d83a4efd052b..5c725e1df58b 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * These are used to set parameters in the core dumps.
@@ -61,6 +62,18 @@ extern unsigned long elf_hwcap;
 do {   \
NEW_AUX_ENT(AT_SYSINFO_EHDR,\
(elf_addr_t)current->mm->context.vdso); \
+   NEW_AUX_ENT(AT_L1I_CACHESIZE,   \
+   get_cache_size(1, CACHE_TYPE_INST));\
+   NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY,   \
+   get_cache_geometry(1, CACHE_TYPE_INST));\
+   NEW_AUX_ENT(AT_L1D_CACHESIZE,   \
+   get_cache_size(1, CACHE_TYPE_DATA));\
+   NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY,   \
+   get_cache_geometry(1, CACHE_TYPE_DATA));\
+   NEW_AUX_ENT(AT_L2_CACHESIZE,\
+   get_cache_size(2, CACHE_TYPE_UNIFIED)); \
+   NEW_AUX_ENT(AT_L2_CACHEGEOMETRY,\
+   get_cache_geometry(2, CACHE_TYPE_UNIFIED)); \
 } while (0)
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
 struct linux_binprm;
diff --git a/arch/riscv/include/uapi/asm/auxvec.h 
b/arch/riscv/include/uapi/asm/auxvec.h
index 22e0ae888406..32c73ba1d531 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,7 +10,28 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+/*
+ * The set of entries below represent more extensive information
+ * about the caches, in the form of two entry per cache type,
+ * one entry containing the cache size in bytes, and the other
+ * containing the cache line size in bytes in the bottom 16 bits
+ * and the cache associativity in the next 16 bits.
+ *
+ * The associativity is such that if N is the 16-bit value, the
+ * cache is N way set associative. A value if 0x means fully
+ * associative, a value of 1 means directly mapped.
+ *
+ * For all these fields, a value of 0 means that the information
+ * is not known.
+ */
+#define AT_L1I_CACHESIZE   40
+#define AT_L1I_CACHEGEOMETRY   41
+#define AT_L1D_CACHESIZE   42
+#define AT_L1D_CACHEGEOMETRY   43
+#define AT_L2_CACHESIZE44
+#define AT_L2_CACHEGEOMETRY45
+
 /* entries in ARCH_DLINFO */
-#define AT_VECTOR_SIZE_ARCH1
+#define AT_VECTOR_SIZE_ARCH7
 
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
index 8b85abfbd77a..ee6ec91260b3 100644
--- a/arch/riscv/kernel/cacheinfo.c
+++ b/arch/riscv/kernel/cacheinfo.c
@@ -3,7 +3,6 @@
  * Copyright (C) 2017 SiFive
  */
 
-#include 
 #include 
 #include 
 #include 
@@ -25,6 +24,37 @@ cache_get_priv_group(struct cacheinfo *this_leaf)
return NULL;
 }
 
+static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type)
+{
+   struct cpu_cacheinfo *this_cpu_ci = 
get_cpu_cacheinfo(smp_processor_id());
+   struct cacheinfo *this_leaf;
+   int index;
+
+   for (index = 0; index < this_cpu_ci->num_l

[PATCH v3 2/3] riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO

2020-08-28 Thread Zong Li
AT_VECTOR_SIZE_ARCH should be defined with the maximum number of
NEW_AUX_ENT entries that ARCH_DLINFO can contain, but it wasn't defined
for RISC-V at all even though ARCH_DLINFO will contain one NEW_AUX_ENT
for the VDSO address.

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
---
 arch/riscv/include/uapi/asm/auxvec.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/auxvec.h 
b/arch/riscv/include/uapi/asm/auxvec.h
index d86cb17bbabe..22e0ae888406 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,4 +10,7 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+/* entries in ARCH_DLINFO */
+#define AT_VECTOR_SIZE_ARCH1
+
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
-- 
2.28.0



[PATCH v3 1/3] riscv: Set more data to cacheinfo

2020-08-28 Thread Zong Li
Set cacheinfo.{size,sets,line_size} for each cache node, then we can
get these information from userland through auxiliary vector.

Signed-off-by: Zong Li 
---
 arch/riscv/kernel/cacheinfo.c | 59 ++-
 1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
index bd0f122965c3..8b85abfbd77a 100644
--- a/arch/riscv/kernel/cacheinfo.c
+++ b/arch/riscv/kernel/cacheinfo.c
@@ -25,12 +25,46 @@ cache_get_priv_group(struct cacheinfo *this_leaf)
return NULL;
 }
 
-static void ci_leaf_init(struct cacheinfo *this_leaf,
-struct device_node *node,
-enum cache_type type, unsigned int level)
+static void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type,
+unsigned int level, unsigned int size,
+unsigned int sets, unsigned int line_size)
 {
this_leaf->level = level;
this_leaf->type = type;
+   this_leaf->size = size;
+   this_leaf->number_of_sets = sets;
+   this_leaf->coherency_line_size = line_size;
+
+   /*
+* If the cache is fully associative, there is no need to
+* check the other properties.
+*/
+   if (!(sets == 1) && (sets > 0 && size > 0 && line_size > 0))
+   this_leaf->ways_of_associativity = (size / sets) / line_size;
+}
+
+static void fill_cacheinfo(struct cacheinfo **this_leaf,
+  struct device_node *node, unsigned int level)
+{
+   unsigned int size, sets, line_size;
+
+   if (!of_property_read_u32(node, "cache-size", ) &&
+   !of_property_read_u32(node, "cache-block-size", _size) &&
+   !of_property_read_u32(node, "cache-sets", )) {
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_UNIFIED, level, size, 
sets, line_size);
+   }
+
+   if (!of_property_read_u32(node, "i-cache-size", ) &&
+   !of_property_read_u32(node, "i-cache-sets", ) &&
+   !of_property_read_u32(node, "i-cache-block-size", _size)) {
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_INST, level, size, 
sets, line_size);
+   }
+
+   if (!of_property_read_u32(node, "d-cache-size", ) &&
+   !of_property_read_u32(node, "d-cache-sets", ) &&
+   !of_property_read_u32(node, "d-cache-block-size", _size)) {
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_DATA, level, size, 
sets, line_size);
+   }
 }
 
 static int __init_cache_level(unsigned int cpu)
@@ -83,29 +117,24 @@ static int __populate_cache_leaves(unsigned int cpu)
struct device_node *prev = NULL;
int levels = 1, level = 1;
 
-   if (of_property_read_bool(np, "cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
-   if (of_property_read_bool(np, "i-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
-   if (of_property_read_bool(np, "d-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
+   /* Level 1 caches in cpu node */
+   fill_cacheinfo(_leaf, np, level);
 
+   /* Next level caches in cache nodes */
prev = np;
while ((np = of_find_next_cache_node(np))) {
of_node_put(prev);
prev = np;
+
if (!of_device_is_compatible(np, "cache"))
break;
if (of_property_read_u32(np, "cache-level", ))
break;
if (level <= levels)
break;
-   if (of_property_read_bool(np, "cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, 
level);
-   if (of_property_read_bool(np, "i-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
-   if (of_property_read_bool(np, "d-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
+
+   fill_cacheinfo(_leaf, np, level);
+
levels = level;
}
of_node_put(np);
-- 
2.28.0



[PATCH v3 0/3] Get cache information from userland

2020-08-28 Thread Zong Li
There are no standard CSR registers to provide cache information, the
way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
could use them to get information of cache through AUX vector. We
exploit 'struct cacheinfo' to obtain the information of cache, then we
don't need additional variable or data structure to record it.

We also need some works in glibc, but we have to support the function in
kernel first by rule of glibc, then post the patch to glibc site.

The result of 'getconf -a' as follows:

LEVEL1_ICACHE_SIZE 32768
LEVEL1_ICACHE_ASSOC8
LEVEL1_ICACHE_LINESIZE 64
LEVEL1_DCACHE_SIZE 32768
LEVEL1_DCACHE_ASSOC8
LEVEL1_DCACHE_LINESIZE 64
LEVEL2_CACHE_SIZE  2097152
LEVEL2_CACHE_ASSOC 32
LEVEL2_CACHE_LINESIZE  64

Changed in v3:
  - Fix sparse warning: Use NULL instead of integer 0

Changed in v2:
  - Add error checking for parsing cache properties.

Zong Li (3):
  riscv: Set more data to cacheinfo
  riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
  riscv: Add cache information in AUX vector

 arch/riscv/include/asm/cacheinfo.h   |  5 ++
 arch/riscv/include/asm/elf.h | 13 
 arch/riscv/include/uapi/asm/auxvec.h | 24 
 arch/riscv/kernel/cacheinfo.c| 91 +++-
 4 files changed, 117 insertions(+), 16 deletions(-)

-- 
2.28.0



[PATCH v2 2/3] riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO

2020-08-27 Thread Zong Li
AT_VECTOR_SIZE_ARCH should be defined with the maximum number of
NEW_AUX_ENT entries that ARCH_DLINFO can contain, but it wasn't defined
for RISC-V at all even though ARCH_DLINFO will contain one NEW_AUX_ENT
for the VDSO address.

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
---
 arch/riscv/include/uapi/asm/auxvec.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/auxvec.h 
b/arch/riscv/include/uapi/asm/auxvec.h
index d86cb17bbabe..22e0ae888406 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,4 +10,7 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+/* entries in ARCH_DLINFO */
+#define AT_VECTOR_SIZE_ARCH1
+
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
-- 
2.28.0



Re: [PATCH 0/3] Get cache information from userland

2020-08-27 Thread Zong Li
On Fri, Aug 21, 2020 at 4:45 AM Palmer Dabbelt  wrote:
>
> On Fri, 03 Jul 2020 01:57:52 PDT (-0700), zong...@sifive.com wrote:
> > There are no standard CSR registers to provide cache information, the
> > way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
> > AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
> > could use them to get information of cache through AUX vector. We
> > exploit 'struct cacheinfo' to obtain the information of cache, then we
> > don't need additional variable or data structure to record it.
> >
> > We also need some works in glibc, but we have to support the function in
> > kernel first by rule of glibc, then post the patch to glibc site.
> >
> > The result of 'getconf -a' as follows:
> >
> > LEVEL1_ICACHE_SIZE 32768
> > LEVEL1_ICACHE_ASSOC8
> > LEVEL1_ICACHE_LINESIZE 64
> > LEVEL1_DCACHE_SIZE 32768
> > LEVEL1_DCACHE_ASSOC8
> > LEVEL1_DCACHE_LINESIZE 64
> > LEVEL2_CACHE_SIZE      2097152
> > LEVEL2_CACHE_ASSOC 32
> > LEVEL2_CACHE_LINESIZE  64
> >
> > Zong Li (3):
> >   riscv: Set more data to cacheinfo
> >   riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
> >   riscv: Add cache information in AUX vector
> >
> >  arch/riscv/include/asm/cacheinfo.h   | 14 +
> >  arch/riscv/include/asm/elf.h | 13 
> >  arch/riscv/include/uapi/asm/auxvec.h | 24 
> >  arch/riscv/kernel/cacheinfo.c| 92 +++-
> >  4 files changed, 127 insertions(+), 16 deletions(-)
> >  create mode 100644 arch/riscv/include/asm/cacheinfo.h
>
> Sorry, I lost track of these.  There's a little issue in #1, LMK if you want 
> to
> send another version or if you want me to just fix it.

Sorry for being late here, I have sent the second version patches to
fix it, thanks for your reviewing.


[PATCH v2 0/3] Get cache information from userland

2020-08-27 Thread Zong Li
There are no standard CSR registers to provide cache information, the
way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
could use them to get information of cache through AUX vector. We
exploit 'struct cacheinfo' to obtain the information of cache, then we
don't need additional variable or data structure to record it.

We also need some works in glibc, but we have to support the function in
kernel first by rule of glibc, then post the patch to glibc site.

The result of 'getconf -a' as follows:

LEVEL1_ICACHE_SIZE 32768
LEVEL1_ICACHE_ASSOC8
LEVEL1_ICACHE_LINESIZE 64
LEVEL1_DCACHE_SIZE 32768
LEVEL1_DCACHE_ASSOC8
LEVEL1_DCACHE_LINESIZE 64
LEVEL2_CACHE_SIZE  2097152
LEVEL2_CACHE_ASSOC 32
LEVEL2_CACHE_LINESIZE  64

Changed in v2:
  - Add error checking for parsing cache properties.

Zong Li (3):
  riscv: Set more data to cacheinfo
  riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
  riscv: Add cache information in AUX vector

 arch/riscv/include/asm/cacheinfo.h   |  5 ++
 arch/riscv/include/asm/elf.h | 13 
 arch/riscv/include/uapi/asm/auxvec.h | 24 
 arch/riscv/kernel/cacheinfo.c| 91 +++-
 4 files changed, 117 insertions(+), 16 deletions(-)

-- 
2.28.0



[PATCH v2 1/3] riscv: Set more data to cacheinfo

2020-08-27 Thread Zong Li
Set cacheinfo.{size,sets,line_size} for each cache node, then we can
get these information from userland through auxiliary vector.

Signed-off-by: Zong Li 
---
 arch/riscv/kernel/cacheinfo.c | 59 ++-
 1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
index bd0f122965c3..8b85abfbd77a 100644
--- a/arch/riscv/kernel/cacheinfo.c
+++ b/arch/riscv/kernel/cacheinfo.c
@@ -25,12 +25,46 @@ cache_get_priv_group(struct cacheinfo *this_leaf)
return NULL;
 }
 
-static void ci_leaf_init(struct cacheinfo *this_leaf,
-struct device_node *node,
-enum cache_type type, unsigned int level)
+static void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type,
+unsigned int level, unsigned int size,
+unsigned int sets, unsigned int line_size)
 {
this_leaf->level = level;
this_leaf->type = type;
+   this_leaf->size = size;
+   this_leaf->number_of_sets = sets;
+   this_leaf->coherency_line_size = line_size;
+
+   /*
+* If the cache is fully associative, there is no need to
+* check the other properties.
+*/
+   if (!(sets == 1) && (sets > 0 && size > 0 && line_size > 0))
+   this_leaf->ways_of_associativity = (size / sets) / line_size;
+}
+
+static void fill_cacheinfo(struct cacheinfo **this_leaf,
+  struct device_node *node, unsigned int level)
+{
+   unsigned int size, sets, line_size;
+
+   if (!of_property_read_u32(node, "cache-size", ) &&
+   !of_property_read_u32(node, "cache-block-size", _size) &&
+   !of_property_read_u32(node, "cache-sets", )) {
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_UNIFIED, level, size, 
sets, line_size);
+   }
+
+   if (!of_property_read_u32(node, "i-cache-size", ) &&
+   !of_property_read_u32(node, "i-cache-sets", ) &&
+   !of_property_read_u32(node, "i-cache-block-size", _size)) {
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_INST, level, size, 
sets, line_size);
+   }
+
+   if (!of_property_read_u32(node, "d-cache-size", ) &&
+   !of_property_read_u32(node, "d-cache-sets", ) &&
+   !of_property_read_u32(node, "d-cache-block-size", _size)) {
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_DATA, level, size, 
sets, line_size);
+   }
 }
 
 static int __init_cache_level(unsigned int cpu)
@@ -83,29 +117,24 @@ static int __populate_cache_leaves(unsigned int cpu)
struct device_node *prev = NULL;
int levels = 1, level = 1;
 
-   if (of_property_read_bool(np, "cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
-   if (of_property_read_bool(np, "i-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
-   if (of_property_read_bool(np, "d-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
+   /* Level 1 caches in cpu node */
+   fill_cacheinfo(_leaf, np, level);
 
+   /* Next level caches in cache nodes */
prev = np;
while ((np = of_find_next_cache_node(np))) {
of_node_put(prev);
prev = np;
+
if (!of_device_is_compatible(np, "cache"))
break;
if (of_property_read_u32(np, "cache-level", ))
break;
if (level <= levels)
break;
-   if (of_property_read_bool(np, "cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, 
level);
-   if (of_property_read_bool(np, "i-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
-   if (of_property_read_bool(np, "d-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
+
+   fill_cacheinfo(_leaf, np, level);
+
levels = level;
}
of_node_put(np);
-- 
2.28.0



[PATCH v2 3/3] riscv: Add cache information in AUX vector

2020-08-27 Thread Zong Li
There are no standard CSR registers to provide cache information, the
way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
could use them to get information of cache through AUX vector.

The result of 'getconf -a' as follows:
LEVEL1_ICACHE_SIZE 32768
LEVEL1_ICACHE_ASSOC8
LEVEL1_ICACHE_LINESIZE 64
LEVEL1_DCACHE_SIZE 32768
LEVEL1_DCACHE_ASSOC8
LEVEL1_DCACHE_LINESIZE 64
LEVEL2_CACHE_SIZE  2097152
LEVEL2_CACHE_ASSOC 32
LEVEL2_CACHE_LINESIZE  64

Signed-off-by: Zong Li 
Reviewed-by: Palmer Dabbelt 
---
 arch/riscv/include/asm/cacheinfo.h   |  5 +
 arch/riscv/include/asm/elf.h | 13 +++
 arch/riscv/include/uapi/asm/auxvec.h | 23 +++-
 arch/riscv/kernel/cacheinfo.c| 32 +++-
 4 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/cacheinfo.h 
b/arch/riscv/include/asm/cacheinfo.h
index 5d9662e9aba8..d1a365215ec0 100644
--- a/arch/riscv/include/asm/cacheinfo.h
+++ b/arch/riscv/include/asm/cacheinfo.h
@@ -1,4 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 SiFive
+ */
 
 #ifndef _ASM_RISCV_CACHEINFO_H
 #define _ASM_RISCV_CACHEINFO_H
@@ -11,5 +14,7 @@ struct riscv_cacheinfo_ops {
 };
 
 void riscv_set_cacheinfo_ops(struct riscv_cacheinfo_ops *ops);
+uintptr_t get_cache_size(u32 level, enum cache_type type);
+uintptr_t get_cache_geometry(u32 level, enum cache_type type);
 
 #endif /* _ASM_RISCV_CACHEINFO_H */
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index d83a4efd052b..5c725e1df58b 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * These are used to set parameters in the core dumps.
@@ -61,6 +62,18 @@ extern unsigned long elf_hwcap;
 do {   \
NEW_AUX_ENT(AT_SYSINFO_EHDR,\
(elf_addr_t)current->mm->context.vdso); \
+   NEW_AUX_ENT(AT_L1I_CACHESIZE,   \
+   get_cache_size(1, CACHE_TYPE_INST));\
+   NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY,   \
+   get_cache_geometry(1, CACHE_TYPE_INST));\
+   NEW_AUX_ENT(AT_L1D_CACHESIZE,   \
+   get_cache_size(1, CACHE_TYPE_DATA));\
+   NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY,   \
+   get_cache_geometry(1, CACHE_TYPE_DATA));\
+   NEW_AUX_ENT(AT_L2_CACHESIZE,\
+   get_cache_size(2, CACHE_TYPE_UNIFIED)); \
+   NEW_AUX_ENT(AT_L2_CACHEGEOMETRY,\
+   get_cache_geometry(2, CACHE_TYPE_UNIFIED)); \
 } while (0)
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
 struct linux_binprm;
diff --git a/arch/riscv/include/uapi/asm/auxvec.h 
b/arch/riscv/include/uapi/asm/auxvec.h
index 22e0ae888406..32c73ba1d531 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,7 +10,28 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+/*
+ * The set of entries below represent more extensive information
+ * about the caches, in the form of two entry per cache type,
+ * one entry containing the cache size in bytes, and the other
+ * containing the cache line size in bytes in the bottom 16 bits
+ * and the cache associativity in the next 16 bits.
+ *
+ * The associativity is such that if N is the 16-bit value, the
+ * cache is N way set associative. A value if 0x means fully
+ * associative, a value of 1 means directly mapped.
+ *
+ * For all these fields, a value of 0 means that the information
+ * is not known.
+ */
+#define AT_L1I_CACHESIZE   40
+#define AT_L1I_CACHEGEOMETRY   41
+#define AT_L1D_CACHESIZE   42
+#define AT_L1D_CACHEGEOMETRY   43
+#define AT_L2_CACHESIZE44
+#define AT_L2_CACHEGEOMETRY45
+
 /* entries in ARCH_DLINFO */
-#define AT_VECTOR_SIZE_ARCH1
+#define AT_VECTOR_SIZE_ARCH7
 
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
index 8b85abfbd77a..13cd23cb8548 100644
--- a/arch/riscv/kernel/cacheinfo.c
+++ b/arch/riscv/kernel/cacheinfo.c
@@ -3,7 +3,6 @@
  * Copyright (C) 2017 SiFive
  */
 
-#include 
 #include 
 #include 
 #include 
@@ -25,6 +24,37 @@ cache_get_priv_group(struct cacheinfo *this_leaf)
return NULL;
 }
 
+static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type)
+{
+   struct cpu_cacheinfo *this_cpu_ci = 
get_cpu_cacheinfo(smp_processor_id());
+   struct cacheinfo *this_leaf;
+   int index;
+
+   for (index = 0; index < this_cpu_ci->num_l

Re: [PATCH 0/3] Get cache information from userland

2020-07-26 Thread Zong Li
On Fri, Jul 3, 2020 at 4:57 PM Zong Li  wrote:
>
> There are no standard CSR registers to provide cache information, the
> way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
> AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
> could use them to get information of cache through AUX vector. We
> exploit 'struct cacheinfo' to obtain the information of cache, then we
> don't need additional variable or data structure to record it.
>
> We also need some works in glibc, but we have to support the function in
> kernel first by rule of glibc, then post the patch to glibc site.
>
> The result of 'getconf -a' as follows:
>
> LEVEL1_ICACHE_SIZE 32768
> LEVEL1_ICACHE_ASSOC8
> LEVEL1_ICACHE_LINESIZE 64
> LEVEL1_DCACHE_SIZE 32768
> LEVEL1_DCACHE_ASSOC8
> LEVEL1_DCACHE_LINESIZE 64
> LEVEL2_CACHE_SIZE  2097152
> LEVEL2_CACHE_ASSOC     32
> LEVEL2_CACHE_LINESIZE  64
>
> Zong Li (3):
>   riscv: Set more data to cacheinfo
>   riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
>   riscv: Add cache information in AUX vector
>
>  arch/riscv/include/asm/cacheinfo.h   | 14 +
>  arch/riscv/include/asm/elf.h | 13 
>  arch/riscv/include/uapi/asm/auxvec.h | 24 
>  arch/riscv/kernel/cacheinfo.c| 92 +++-
>  4 files changed, 127 insertions(+), 16 deletions(-)
>  create mode 100644 arch/riscv/include/asm/cacheinfo.h
>
> --
> 2.27.0
>

ping


[PATCH v2 0/2] Fix some build warnings when W=1

2020-07-16 Thread Zong Li
These patches fix some build warnings when W=1, the most of warnings are
missing prototype as follows:

arch/riscv/mm/init.c:520:13: warning: no previous prototype for 'resource_init' 
[-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:130:5: warning: no previous prototype for 
'set_memory_ro' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:136:5: warning: no previous prototype for 
'set_memory_rw' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:142:5: warning: no previous prototype for 
'set_memory_x' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:147:5: warning: no previous prototype for 
'set_memory_nx' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:152:5: warning: no previous prototype for 
'set_direct_map_invalid_noflush' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:169:5: warning: no previous prototype for 
'set_direct_map_default_noflush' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:97:1: warning: 'static' is not at beginning of 
declaration [-Wold-style-declaration]

Changed in v2:
 - Modify the patch description

Zong Li (2):
  riscv: Fix build warning for mm/init
  riscv: Fix build warning for mm/pageattr

 arch/riscv/mm/init.c | 2 +-
 arch/riscv/mm/pageattr.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

-- 
2.27.0



[PATCH v2 2/2] riscv: Fix build warning for mm/pageattr

2020-07-16 Thread Zong Li
Add header for missing prototype. Also, static keyword should be at
beginning of declaration.

The warning messages as follows (with W=1 build):

arch/riscv/mm/pageattr.c:130:5:
warning: no previous prototype for 'set_memory_ro' [-Wmissing-prototypes]

arch/riscv/mm/pageattr.c:136:5:
warning: no previous prototype for 'set_memory_rw' [-Wmissing-prototypes]

arch/riscv/mm/pageattr.c:142:5:
warning: no previous prototype for 'set_memory_x' [-Wmissing-prototypes]

arch/riscv/mm/pageattr.c:147:5:
warning: no previous prototype for 'set_memory_nx' [-Wmissing-prototypes]

arch/riscv/mm/pageattr.c:152:5:
warning: no previous prototype for 'set_direct_map_invalid_noflush' 
[-Wmissing-prototypes]

arch/riscv/mm/pageattr.c:169:5:
warning: no previous prototype for 'set_direct_map_default_noflush' 
[-Wmissing-prototypes]

arch/riscv/mm/pageattr.c:97:1:
warning: 'static' is not at beginning of declaration [-Wold-style-declaration]

Signed-off-by: Zong Li 
Reviewed-by: Pekka Enberg 
---
 arch/riscv/mm/pageattr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
index 289a9a5ea5b5..19fecb362d81 100644
--- a/arch/riscv/mm/pageattr.c
+++ b/arch/riscv/mm/pageattr.c
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct pageattr_masks {
pgprot_t set_mask;
@@ -94,7 +95,7 @@ static int pageattr_pte_hole(unsigned long addr, unsigned 
long next,
return 0;
 }
 
-const static struct mm_walk_ops pageattr_ops = {
+static const struct mm_walk_ops pageattr_ops = {
.pgd_entry = pageattr_pgd_entry,
.p4d_entry = pageattr_p4d_entry,
.pud_entry = pageattr_pud_entry,
-- 
2.27.0



[PATCH v2 1/2] riscv: Fix build warning for mm/init

2020-07-16 Thread Zong Li
Add static keyword for resource_init, this function is only used in this
object file.

The warning message as follow (with W=1 build):

arch/riscv/mm/init.c:520:13:
warning: no previous prototype for 'resource_init' [-Wmissing-prototypes]

Signed-off-by: Zong Li 
---
 arch/riscv/mm/init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 92002952c621..66f5952f39c0 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -517,7 +517,7 @@ void mark_rodata_ro(void)
 }
 #endif
 
-void __init resource_init(void)
+static void __init resource_init(void)
 {
struct memblock_region *region;
 
-- 
2.27.0



Re: [PATCH 2/2] riscv: fix build warning of mm/pageattr

2020-07-16 Thread Zong Li
On Thu, Jul 16, 2020 at 3:24 PM Andreas Schwab  wrote:
>
> On Jul 16 2020, Zong Li wrote:
>
> > Add hearder for missing prototype. Also, static keyword should be at
>
> s/hearder/header/
>
> Andreas.
>
> --
> Andreas Schwab, sch...@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."

Hi all,

Let me describe the details in the commit message and fix the typo in
the next version.
Thanks for reviewing.


[PATCH 0/2] Fix some build warnings when W=1

2020-07-16 Thread Zong Li
These patches fix some build warnings when W=1, the most of warnings are
missing prototype as follows:

arch/riscv/mm/init.c:520:13: warning: no previous prototype for 'resource_init' 
[-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:130:5: warning: no previous prototype for 
'set_memory_ro' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:136:5: warning: no previous prototype for 
'set_memory_rw' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:142:5: warning: no previous prototype for 
'set_memory_x' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:147:5: warning: no previous prototype for 
'set_memory_nx' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:152:5: warning: no previous prototype for 
'set_direct_map_invalid_noflush' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:169:5: warning: no previous prototype for 
'set_direct_map_default_noflush' [-Wmissing-prototypes]
arch/riscv/mm/pageattr.c:97:1: warning: 'static' is not at beginning of 
declaration [-Wold-style-declaration]

Zong Li (2):
  riscv: Fix build warning for mm/init
  riscv: fix build warning of mm/pageattr

 arch/riscv/mm/init.c | 2 +-
 arch/riscv/mm/pageattr.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

-- 
2.27.0



[PATCH 1/2] riscv: Fix build warning for mm/init

2020-07-16 Thread Zong Li
Add static keyword for resource_init, this function is only used in this
object file.

Signed-off-by: Zong Li 
---
 arch/riscv/mm/init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 92002952c621..66f5952f39c0 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -517,7 +517,7 @@ void mark_rodata_ro(void)
 }
 #endif
 
-void __init resource_init(void)
+static void __init resource_init(void)
 {
struct memblock_region *region;
 
-- 
2.27.0



[PATCH 2/2] riscv: fix build warning of mm/pageattr

2020-07-16 Thread Zong Li
Add hearder for missing prototype. Also, static keyword should be at
beginning of declaration.

Signed-off-by: Zong Li 
---
 arch/riscv/mm/pageattr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
index 289a9a5ea5b5..19fecb362d81 100644
--- a/arch/riscv/mm/pageattr.c
+++ b/arch/riscv/mm/pageattr.c
@@ -7,6 +7,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct pageattr_masks {
pgprot_t set_mask;
@@ -94,7 +95,7 @@ static int pageattr_pte_hole(unsigned long addr, unsigned 
long next,
return 0;
 }
 
-const static struct mm_walk_ops pageattr_ops = {
+static const struct mm_walk_ops pageattr_ops = {
.pgd_entry = pageattr_pgd_entry,
.p4d_entry = pageattr_p4d_entry,
.pud_entry = pageattr_pud_entry,
-- 
2.27.0



Re: [PATCH 2/2] riscv: Support CONFIG_STRICT_DEVMEM

2020-07-09 Thread Zong Li
On Fri, Jul 10, 2020 at 4:08 AM Palmer Dabbelt  wrote:
>
> On Tue, 16 Jun 2020 00:45:47 PDT (-0700), zong...@sifive.com wrote:
> > Implement the 'devmem_is_allowed()' interface for RISC-V, like some of
> > other architectures have done. It will be called from range_is_allowed()
> > when userpsace attempts to access /dev/mem.
>
> In fact, it's exactly the same (down to a few words of the comment) to the
> others that I checked.  I'm going to put a generic version in lib/ instead,
> I've sent out the patches.
>

OK, no problem, thanks for improving it.

> > Access to exclusive IOMEM and kernel RAM is denied unless
> > CONFIG_STRICT_DEVMEM is set to 'n'.
> >
> > Test it by devmem, the result as follows:
> >
> >  - CONFIG_STRICT_DEVMEM=y
> >   $ devmem 0x1001
> >   0x
> >   $ devmem 0x8020
> >   0x106F
> >
> >  - CONFIG_STRICT_DEVMEM is not set
> >   $ devmem 0x1001
> >   devmem: mmap: Operation not permitted
> >   $ devmem 0x8020
> >   devmem: mmap: Operation not permitted
> >
> > Signed-off-by: Zong Li 
> > ---
> >  arch/riscv/Kconfig  |  1 +
> >  arch/riscv/include/asm/io.h |  2 ++
> >  arch/riscv/mm/init.c| 19 +++
> >  3 files changed, 22 insertions(+)
> >
> > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> > index 128192e14ff2..ffd7841ede4c 100644
> > --- a/arch/riscv/Kconfig
> > +++ b/arch/riscv/Kconfig
> > @@ -16,6 +16,7 @@ config RISCV
> >   select ARCH_HAS_BINFMT_FLAT
> >   select ARCH_HAS_DEBUG_VIRTUAL if MMU
> >   select ARCH_HAS_DEBUG_WX
> > + select ARCH_HAS_DEVMEM_IS_ALLOWED
> >   select ARCH_HAS_GCOV_PROFILE_ALL
> >   select ARCH_HAS_GIGANTIC_PAGE
> >   select ARCH_HAS_MMIOWB
> > diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
> > index 3835c3295dc5..04ac65ab93ce 100644
> > --- a/arch/riscv/include/asm/io.h
> > +++ b/arch/riscv/include/asm/io.h
> > @@ -147,4 +147,6 @@ __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw())
> >
> >  #include 
> >
> > +extern int devmem_is_allowed(unsigned long pfn);
> > +
> >  #endif /* _ASM_RISCV_IO_H */
> > diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> > index bbe816e03b2f..5e7e61519acc 100644
> > --- a/arch/riscv/mm/init.c
> > +++ b/arch/riscv/mm/init.c
> > @@ -517,6 +517,25 @@ void mark_rodata_ro(void)
> >  }
> >  #endif
> >
> > +#ifdef CONFIG_STRICT_DEVMEM
> > +#include 
> > +/*
> > + * devmem_is_allowed() checks to see if /dev/mem access to a certain 
> > address
> > + * is valid. The argument is a physical page number.
> > + *
> > + * Disallow access to system RAM as well as device-exclusive MMIO regions.
> > + * This effectively disable read()/write() on /dev/mem.
> > + */
> > +int devmem_is_allowed(unsigned long pfn)
> > +{
> > + if (iomem_is_exclusive(pfn << PAGE_SHIFT))
> > + return 0;
> > + if (!page_is_ram(pfn))
> > + return 1;
> > + return 0;
> > +}
> > +#endif
> > +
> >  void __init resource_init(void)
> >  {
> >   struct memblock_region *region;


Re: [PATCH v5 1/4] riscv: Move kernel mapping to vmalloc zone

2020-07-09 Thread Zong Li
On Thu, Jul 9, 2020 at 1:05 PM Palmer Dabbelt  wrote:
>
> On Sun, 07 Jun 2020 00:59:46 PDT (-0700), a...@ghiti.fr wrote:
> > This is a preparatory patch for relocatable kernel.
> >
> > The kernel used to be linked at PAGE_OFFSET address and used to be loaded
> > physically at the beginning of the main memory. Therefore, we could use
> > the linear mapping for the kernel mapping.
> >
> > But the relocated kernel base address will be different from PAGE_OFFSET
> > and since in the linear mapping, two different virtual addresses cannot
> > point to the same physical address, the kernel mapping needs to lie outside
> > the linear mapping.
>
> I know it's been a while, but I keep opening this up to review it and just
> can't get over how ugly it is to put the kernel's linear map in the vmalloc
> region.
>
> I guess I don't understand why this is necessary at all.  Specifically: why
> can't we just relocate the kernel within the linear map?  That would let the
> bootloader put the kernel wherever it wants, modulo the physical memory size 
> we
> support.  We'd need to handle the regions that are coupled to the kernel's
> execution address, but we could just put them in an explicit memory region
> which is what we should probably be doing anyway.

The original implementation of relocation doesn't move the kernel's linear map
to the vmalloc region, and I also give the KASLR RFC patch [1] based on that.
In original, we relocate the kernel in the linear map region, we would
calculate a
random value first as the offset, then we move the kernel image to the
new target
address which is obtained by adding this offset to it's VA and PA.
It's enough for
randomizing the kernel, but it seems to me if we want to decouple the kernel's
linear mapping, the physical mapping of RAM and virtual mapping of RAM,
it might be good to move the kernel's mapping out from the linear region.
Even so, it is still an intrusive change. As far as I know, only arm64
does something
like that.

[1]  https://patchwork.kernel.org/project/linux-riscv/list/?series=260615



>
> > In addition, because modules and BPF must be close to the kernel (inside
> > +-2GB window), the kernel is placed at the end of the vmalloc zone minus
> > 2GB, which leaves room for modules and BPF. The kernel could not be
> > placed at the beginning of the vmalloc zone since other vmalloc
> > allocations from the kernel could get all the +-2GB window around the
> > kernel which would prevent new modules and BPF programs to be loaded.
>
> Well, that's not enough to make sure this doesn't happen -- it's just enough 
> to
> make sure it doesn't happen very quickily.  That's the same boat we're already
> in, though, so it's not like it's worse.
>
> > Signed-off-by: Alexandre Ghiti 
> > Reviewed-by: Zong Li 
> > ---
> >  arch/riscv/boot/loader.lds.S |  3 +-
> >  arch/riscv/include/asm/page.h| 10 +-
> >  arch/riscv/include/asm/pgtable.h | 38 ++---
> >  arch/riscv/kernel/head.S |  3 +-
> >  arch/riscv/kernel/module.c   |  4 +--
> >  arch/riscv/kernel/vmlinux.lds.S  |  3 +-
> >  arch/riscv/mm/init.c | 58 +---
> >  arch/riscv/mm/physaddr.c |  2 +-
> >  8 files changed, 88 insertions(+), 33 deletions(-)
> >
> > diff --git a/arch/riscv/boot/loader.lds.S b/arch/riscv/boot/loader.lds.S
> > index 47a5003c2e28..62d94696a19c 100644
> > --- a/arch/riscv/boot/loader.lds.S
> > +++ b/arch/riscv/boot/loader.lds.S
> > @@ -1,13 +1,14 @@
> >  /* SPDX-License-Identifier: GPL-2.0 */
> >
> >  #include 
> > +#include 
> >
> >  OUTPUT_ARCH(riscv)
> >  ENTRY(_start)
> >
> >  SECTIONS
> >  {
> > - . = PAGE_OFFSET;
> > + . = KERNEL_LINK_ADDR;
> >
> >   .payload : {
> >   *(.payload)
> > diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
> > index 2d50f76efe48..48bb09b6a9b7 100644
> > --- a/arch/riscv/include/asm/page.h
> > +++ b/arch/riscv/include/asm/page.h
> > @@ -90,18 +90,26 @@ typedef struct page *pgtable_t;
> >
> >  #ifdef CONFIG_MMU
> >  extern unsigned long va_pa_offset;
> > +extern unsigned long va_kernel_pa_offset;
> >  extern unsigned long pfn_base;
> >  #define ARCH_PFN_OFFSET  (pfn_base)
> >  #else
> >  #define va_pa_offset 0
> > +#define va_kernel_pa_offset  0
> >  #define ARCH_PFN_OFFSET  (PAGE_OFFSET >> PAGE_SHIFT)
> >  #endif /* CONFIG_MMU */
> >
> >  extern unsigned long max_low_pfn;
> >  extern unsigned long min_low_pfn;

Re: [PATCH] riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO

2020-07-07 Thread Zong Li
On Tue, Jun 23, 2020 at 4:02 PM Zong Li  wrote:
>
> AT_VECTOR_SIZE_ARCH should be defined with the maximum number of
> NEW_AUX_ENT entries that ARCH_DLINFO can contain, but it wasn't defined
> for RISC-V at all even though ARCH_DLINFO will contain one NEW_AUX_ENT
> for the VDSO address.
>
> Signed-off-by: Zong Li 
> ---
>  arch/riscv/include/uapi/asm/auxvec.h | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/arch/riscv/include/uapi/asm/auxvec.h 
> b/arch/riscv/include/uapi/asm/auxvec.h
> index d86cb17bbabe..22e0ae888406 100644
> --- a/arch/riscv/include/uapi/asm/auxvec.h
> +++ b/arch/riscv/include/uapi/asm/auxvec.h
> @@ -10,4 +10,7 @@
>  /* vDSO location */
>  #define AT_SYSINFO_EHDR 33
>
> +/* entries in ARCH_DLINFO */
> +#define AT_VECTOR_SIZE_ARCH1
> +
>  #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
> --
> 2.27.0
>

Hi all,

I put this patch into other patch series. Please ignore this single one. Thanks.
http://lists.infradead.org/pipermail/linux-riscv/2020-July/000882.html


Re: [PATCH V1 4/5] riscv: Add kprobes supported

2020-07-07 Thread Zong Li
On Mon, Jul 6, 2020 at 6:12 PM Masami Hiramatsu  wrote:
>
> Hi Guo,
>
> On Sat,  4 Jul 2020 03:34:18 +
> guo...@kernel.org wrote:
>
> > From: Guo Ren 
> >
> > This patch enables "kprobe & kretprobe" to work with ftrace
> > interface. It utilized software breakpoint as single-step
> > mechanism.
> >
> > Some instructions which can't be single-step executed must be
> > simulated in kernel execution slot, such as: branch, jal, auipc,
> > la ...
> >
> > Some instructions should be rejected for probing and we use a
> > blacklist to filter, such as: ecall, ebreak, ...
> >
> > We use ebreak & c.ebreak to replace origin instruction and the
> > kprobe handler prepares an executable memory slot for out-of-line
> > execution with a copy of the original instruction being probed.
> > In execution slot we add ebreak behind original instruction to
> > simulate a single-setp mechanism.
> >
> > The patch is based on packi's work [1] and csky's work [2].
> >  - The kprobes_trampoline.S is all from packi's patch
> >  - The single-step mechanism is new designed for riscv without hw
> >single-step trap
> >  - The simulation codes are from csky
> >  - Frankly, all codes refer to other archs' implementation
> >
> >  [1] https://lore.kernel.org/linux-riscv/20181113195804.22825-1...@packi.ch/
> >  [2] 
> > https://lore.kernel.org/linux-csky/20200403044150.20562-9-guo...@kernel.org/
> >
>
> This looks good to me. Thanks for updating !
>
> Acked-by: Masami Hiramatsu 
>
> Thank you,
>

It works to me. Thanks!

Tested-by: Zong Li 

>
> > Signed-off-by: Guo Ren 
> > Co-Developed-by: Patrick Stählin 
> > Cc: Patrick Stählin 
> > Cc: Masami Hiramatsu 
> > Cc: Palmer Dabbelt 
> > Cc: Björn Töpel 
> > ---
> >  arch/riscv/Kconfig|   2 +
> >  arch/riscv/include/asm/kprobes.h  |  40 +++
> >  arch/riscv/include/asm/probes.h   |  24 ++
> >  arch/riscv/kernel/Makefile|   1 +
> >  arch/riscv/kernel/probes/Makefile |   4 +
> >  arch/riscv/kernel/probes/decode-insn.c|  48 +++
> >  arch/riscv/kernel/probes/decode-insn.h|  18 +
> >  arch/riscv/kernel/probes/kprobes.c| 471 
> > ++
> >  arch/riscv/kernel/probes/kprobes_trampoline.S |  93 +
> >  arch/riscv/kernel/probes/simulate-insn.c  |  85 +
> >  arch/riscv/kernel/probes/simulate-insn.h  |  47 +++
> >  arch/riscv/kernel/traps.c |   9 +
> >  arch/riscv/mm/fault.c |   4 +
> >  13 files changed, 846 insertions(+)
> >  create mode 100644 arch/riscv/include/asm/probes.h
> >  create mode 100644 arch/riscv/kernel/probes/Makefile
> >  create mode 100644 arch/riscv/kernel/probes/decode-insn.c
> >  create mode 100644 arch/riscv/kernel/probes/decode-insn.h
> >  create mode 100644 arch/riscv/kernel/probes/kprobes.c
> >  create mode 100644 arch/riscv/kernel/probes/kprobes_trampoline.S
> >  create mode 100644 arch/riscv/kernel/probes/simulate-insn.c
> >  create mode 100644 arch/riscv/kernel/probes/simulate-insn.h
> >
> > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> > index 58d6f66..a295f0b 100644
> > --- a/arch/riscv/Kconfig
> > +++ b/arch/riscv/Kconfig
> > @@ -57,6 +57,8 @@ config RISCV
> >   select HAVE_EBPF_JIT if MMU
> >   select HAVE_FUTEX_CMPXCHG if FUTEX
> >   select HAVE_GENERIC_VDSO if MMU && 64BIT
> > + select HAVE_KPROBES
> > + select HAVE_KRETPROBES
> >   select HAVE_PCI
> >   select HAVE_PERF_EVENTS
> >   select HAVE_PERF_REGS
> > diff --git a/arch/riscv/include/asm/kprobes.h 
> > b/arch/riscv/include/asm/kprobes.h
> > index 56a98ea3..4647d38 100644
> > --- a/arch/riscv/include/asm/kprobes.h
> > +++ b/arch/riscv/include/asm/kprobes.h
> > @@ -11,4 +11,44 @@
> >
> >  #include 
> >
> > +#ifdef CONFIG_KPROBES
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define __ARCH_WANT_KPROBES_INSN_SLOT
> > +#define MAX_INSN_SIZE2
> > +
> > +#define flush_insn_slot(p)   do { } while (0)
> > +#define kretprobe_blacklist_size 0
> > +
> > +#include 
> > +
> > +struct prev_kprobe {
> > + struct kprobe *kp;
> > + unsigned int status;
> > +};
> > +
> > +/* Single step context for kprobe */
> > +struct kprobe_step_ctx {
> > + unsigned

Re: [PATCH V1 2/5] RISC-V: Implement ptrace regs and stack API

2020-07-07 Thread Zong Li
   REG_OFFSET_NAME(status),
> +   REG_OFFSET_NAME(badaddr),
> +   REG_OFFSET_NAME(cause),
> +   REG_OFFSET_NAME(orig_a0),
> +   REG_OFFSET_END,
> +};
> +
> +/**
> + * regs_query_register_offset() - query register offset from its name
> + * @name:  the name of a register
> + *
> + * regs_query_register_offset() returns the offset of a register in struct
> + * pt_regs from its name. If the name is invalid, this returns -EINVAL;
> + */
> +int regs_query_register_offset(const char *name)
> +{
> +   const struct pt_regs_offset *roff;
> +
> +   for (roff = regoffset_table; roff->name != NULL; roff++)
> +   if (!strcmp(roff->name, name))
> +   return roff->offset;
> +   return -EINVAL;
> +}
> +
> +/**
> + * regs_within_kernel_stack() - check the address in the stack
> + * @regs:  pt_regs which contains kernel stack pointer.
> + * @addr:  address which is checked.
> + *
> + * regs_within_kernel_stack() checks @addr is within the kernel stack 
> page(s).
> + * If @addr is within the kernel stack, it returns true. If not, returns 
> false.
> + */
> +static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long 
> addr)
> +{
> +   return (addr & ~(THREAD_SIZE - 1))  ==
> +   (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1));
> +}
> +
> +/**
> + * regs_get_kernel_stack_nth() - get Nth entry of the stack
> + * @regs:  pt_regs which contains kernel stack pointer.
> + * @n: stack entry number.
> + *
> + * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
> + * is specified by @regs. If the @n th entry is NOT in the kernel stack,
> + * this returns 0.
> + */
> +unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
> +{
> +   unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
> +
> +   addr += n;
> +   if (regs_within_kernel_stack(regs, (unsigned long)addr))
> +   return *addr;
> +   else
> +   return 0;
> +}
> +
>  void ptrace_disable(struct task_struct *child)
>  {
> clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
> --
> 2.7.4
>

Looks good to me.

Reviewed-by: Zong Li 


Re: [PATCH] scripts/Lindent: increase the maximum line length to 100

2020-07-03 Thread Zong Li
On Fri, Jul 3, 2020 at 5:51 PM Joe Perches  wrote:
>
> On Fri, 2020-07-03 at 11:41 +0200, Miguel Ojeda wrote:
> > On Fri, Jul 3, 2020 at 10:51 AM Joe Perches  wrote:
> > > I'd prefer to delete Lindent instead.
> >
> > +1, especially since there is `clang-format` now.

Agree, it is often used.

>
> Awhile back I did send a patch:
> https://lore.kernel.org/lkml/1360610974.28491.6.camel@joe-AO722/
>
>

Cool, let us go the patch above.


Re: [PATCH] scripts/Lindent: increase the maximum line length to 100

2020-07-03 Thread Zong Li
On Fri, Jul 3, 2020 at 4:51 PM Joe Perches  wrote:
>
> On Fri, 2020-07-03 at 16:08 +0800, Zong Li wrote:
> > As the patch 'bdc48fa11e46 ("checkpatch/coding-style: deprecate
> > 80-column warning")', increase the default limit to 100 characters,
> > we also increase the maximum line length to 100 for indent script.
>
> I'd prefer to delete Lindent instead.
>
> Also any reformatting tool like this will
> _always_ use up to whatever the maximum
> line length is rather than use a preferred
> length of 80 and and only use the allowed
> maximum length of 100 when necessary for
> human readability.
>

Yes, as you mentioned, the reformatting tool uses up to the maximum line length,
it seems to me that we don't go this patch if you plan to post the
patch to delete it,
otherwise, we could consider to change it to 100.

> > Signed-off-by: Zong Li 
> > ---
> >  scripts/Lindent | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/scripts/Lindent b/scripts/Lindent
> > index 1688c44c2df6..11f14a4f2048 100755
> > --- a/scripts/Lindent
> > +++ b/scripts/Lindent
> > @@ -1,7 +1,7 @@
> >  #!/bin/sh
> >  # SPDX-License-Identifier: GPL-2.0
> >
> > -PARAM="-npro -kr -i8 -ts8 -sob -l80 -ss -ncs -cp1"
> > +PARAM="-npro -kr -i8 -ts8 -sob -l100 -ss -ncs -cp1"
> >
> >  RES=`indent --version | cut -d' ' -f3`
> >  if [ "$RES" = "" ]; then
>


[PATCH 1/3] riscv: Set more data to cacheinfo

2020-07-03 Thread Zong Li
Set cacheinfo.{size,sets,line_size} for each cache node, then we can
get these information from userland through auxiliary vector.

Signed-off-by: Zong Li 
---
 arch/riscv/kernel/cacheinfo.c | 59 ++-
 1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
index 4c90c07d8c39..cdd35e53fd98 100644
--- a/arch/riscv/kernel/cacheinfo.c
+++ b/arch/riscv/kernel/cacheinfo.c
@@ -8,12 +8,46 @@
 #include 
 #include 
 
-static void ci_leaf_init(struct cacheinfo *this_leaf,
-struct device_node *node,
-enum cache_type type, unsigned int level)
+static void ci_leaf_init(struct cacheinfo *this_leaf, enum cache_type type,
+unsigned int level, unsigned int size,
+unsigned int sets, unsigned int line_size)
 {
this_leaf->level = level;
this_leaf->type = type;
+   this_leaf->size = size;
+   this_leaf->number_of_sets = sets;
+   this_leaf->coherency_line_size = line_size;
+
+   /*
+* If the cache is fully associative, there is no need to
+* check the other properties.
+*/
+   if (!(sets == 1) && (sets > 0 && size > 0 && line_size > 0))
+   this_leaf->ways_of_associativity = (size / sets) / line_size;
+}
+
+static void fill_cacheinfo(struct cacheinfo **this_leaf,
+  struct device_node *node, unsigned int level)
+{
+   unsigned int size, sets, line_size;
+
+   if (!of_property_read_u32(node, "cache-size", )) {
+   of_property_read_u32(node, "cache-block-size", _size);
+   of_property_read_u32(node, "cache-sets", );
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_UNIFIED, level, size, 
sets, line_size);
+   }
+
+   if (!of_property_read_u32(node, "i-cache-size", )) {
+   of_property_read_u32(node, "i-cache-sets", );
+   of_property_read_u32(node, "i-cache-block-size", _size);
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_INST, level, size, 
sets, line_size);
+   }
+
+   if (!of_property_read_u32(node, "d-cache-size", )) {
+   of_property_read_u32(node, "d-cache-sets", );
+   of_property_read_u32(node, "d-cache-block-size", _size);
+   ci_leaf_init((*this_leaf)++, CACHE_TYPE_DATA, level, size, 
sets, line_size);
+   }
 }
 
 static int __init_cache_level(unsigned int cpu)
@@ -66,29 +100,24 @@ static int __populate_cache_leaves(unsigned int cpu)
struct device_node *prev = NULL;
int levels = 1, level = 1;
 
-   if (of_property_read_bool(np, "cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
-   if (of_property_read_bool(np, "i-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
-   if (of_property_read_bool(np, "d-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
+   /* Level 1 caches in cpu node */
+   fill_cacheinfo(_leaf, np, level);
 
+   /* Next level caches in cache nodes */
prev = np;
while ((np = of_find_next_cache_node(np))) {
of_node_put(prev);
prev = np;
+
if (!of_device_is_compatible(np, "cache"))
break;
if (of_property_read_u32(np, "cache-level", ))
break;
if (level <= levels)
break;
-   if (of_property_read_bool(np, "cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, 
level);
-   if (of_property_read_bool(np, "i-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
-   if (of_property_read_bool(np, "d-cache-size"))
-   ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
+
+   fill_cacheinfo(_leaf, np, level);
+
levels = level;
}
of_node_put(np);
-- 
2.27.0



[PATCH 2/3] riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO

2020-07-03 Thread Zong Li
AT_VECTOR_SIZE_ARCH should be defined with the maximum number of
NEW_AUX_ENT entries that ARCH_DLINFO can contain, but it wasn't defined
for RISC-V at all even though ARCH_DLINFO will contain one NEW_AUX_ENT
for the VDSO address.

Signed-off-by: Zong Li 
---
 arch/riscv/include/uapi/asm/auxvec.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/auxvec.h 
b/arch/riscv/include/uapi/asm/auxvec.h
index d86cb17bbabe..22e0ae888406 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,4 +10,7 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+/* entries in ARCH_DLINFO */
+#define AT_VECTOR_SIZE_ARCH1
+
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
-- 
2.27.0



[PATCH 0/3] Get cache information from userland

2020-07-03 Thread Zong Li
There are no standard CSR registers to provide cache information, the
way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
could use them to get information of cache through AUX vector. We
exploit 'struct cacheinfo' to obtain the information of cache, then we
don't need additional variable or data structure to record it.

We also need some works in glibc, but we have to support the function in
kernel first by rule of glibc, then post the patch to glibc site.

The result of 'getconf -a' as follows:

LEVEL1_ICACHE_SIZE 32768
LEVEL1_ICACHE_ASSOC8
LEVEL1_ICACHE_LINESIZE 64
LEVEL1_DCACHE_SIZE 32768
LEVEL1_DCACHE_ASSOC8
LEVEL1_DCACHE_LINESIZE 64
LEVEL2_CACHE_SIZE  2097152
LEVEL2_CACHE_ASSOC 32
LEVEL2_CACHE_LINESIZE  64

Zong Li (3):
  riscv: Set more data to cacheinfo
  riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO
  riscv: Add cache information in AUX vector

 arch/riscv/include/asm/cacheinfo.h   | 14 +
 arch/riscv/include/asm/elf.h | 13 
 arch/riscv/include/uapi/asm/auxvec.h | 24 
 arch/riscv/kernel/cacheinfo.c| 92 +++-
 4 files changed, 127 insertions(+), 16 deletions(-)
 create mode 100644 arch/riscv/include/asm/cacheinfo.h

-- 
2.27.0



[PATCH 3/3] riscv: Add cache information in AUX vector

2020-07-03 Thread Zong Li
There are no standard CSR registers to provide cache information, the
way for RISC-V is to get this information from DT. Currently, AT_L1I_X,
AT_L1D_X and AT_L2_X are present in glibc header, and sysconf syscall
could use them to get information of cache through AUX vector.

The result of 'getconf -a' as follows:
LEVEL1_ICACHE_SIZE 32768
LEVEL1_ICACHE_ASSOC8
LEVEL1_ICACHE_LINESIZE 64
LEVEL1_DCACHE_SIZE 32768
LEVEL1_DCACHE_ASSOC8
LEVEL1_DCACHE_LINESIZE 64
LEVEL2_CACHE_SIZE  2097152
LEVEL2_CACHE_ASSOC 32
LEVEL2_CACHE_LINESIZE  64

Signed-off-by: Zong Li 
---
 arch/riscv/include/asm/cacheinfo.h   | 14 
 arch/riscv/include/asm/elf.h | 13 +++
 arch/riscv/include/uapi/asm/auxvec.h | 23 ++-
 arch/riscv/kernel/cacheinfo.c| 33 +++-
 4 files changed, 81 insertions(+), 2 deletions(-)
 create mode 100644 arch/riscv/include/asm/cacheinfo.h

diff --git a/arch/riscv/include/asm/cacheinfo.h 
b/arch/riscv/include/asm/cacheinfo.h
new file mode 100644
index ..ba179cd198b9
--- /dev/null
+++ b/arch/riscv/include/asm/cacheinfo.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 SiFive
+ */
+
+#ifndef _ASM_RISCV_CACHEINFO_H
+#define _ASM_RISCV_CACHEINFO_H
+
+#include 
+
+uintptr_t get_cache_size(u32 level, enum cache_type type);
+uintptr_t get_cache_geometry(u32 level, enum cache_type type);
+
+#endif /* _ASM_RISCV_CACHEINFO_H */
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index d83a4efd052b..5c725e1df58b 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /*
  * These are used to set parameters in the core dumps.
@@ -61,6 +62,18 @@ extern unsigned long elf_hwcap;
 do {   \
NEW_AUX_ENT(AT_SYSINFO_EHDR,\
(elf_addr_t)current->mm->context.vdso); \
+   NEW_AUX_ENT(AT_L1I_CACHESIZE,   \
+   get_cache_size(1, CACHE_TYPE_INST));\
+   NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY,   \
+   get_cache_geometry(1, CACHE_TYPE_INST));\
+   NEW_AUX_ENT(AT_L1D_CACHESIZE,   \
+   get_cache_size(1, CACHE_TYPE_DATA));\
+   NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY,   \
+   get_cache_geometry(1, CACHE_TYPE_DATA));\
+   NEW_AUX_ENT(AT_L2_CACHESIZE,\
+   get_cache_size(2, CACHE_TYPE_UNIFIED)); \
+   NEW_AUX_ENT(AT_L2_CACHEGEOMETRY,\
+   get_cache_geometry(2, CACHE_TYPE_UNIFIED)); \
 } while (0)
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
 struct linux_binprm;
diff --git a/arch/riscv/include/uapi/asm/auxvec.h 
b/arch/riscv/include/uapi/asm/auxvec.h
index 22e0ae888406..32c73ba1d531 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,7 +10,28 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+/*
+ * The set of entries below represent more extensive information
+ * about the caches, in the form of two entry per cache type,
+ * one entry containing the cache size in bytes, and the other
+ * containing the cache line size in bytes in the bottom 16 bits
+ * and the cache associativity in the next 16 bits.
+ *
+ * The associativity is such that if N is the 16-bit value, the
+ * cache is N way set associative. A value if 0x means fully
+ * associative, a value of 1 means directly mapped.
+ *
+ * For all these fields, a value of 0 means that the information
+ * is not known.
+ */
+#define AT_L1I_CACHESIZE   40
+#define AT_L1I_CACHEGEOMETRY   41
+#define AT_L1D_CACHESIZE   42
+#define AT_L1D_CACHEGEOMETRY   43
+#define AT_L2_CACHESIZE44
+#define AT_L2_CACHEGEOMETRY45
+
 /* entries in ARCH_DLINFO */
-#define AT_VECTOR_SIZE_ARCH1
+#define AT_VECTOR_SIZE_ARCH7
 
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
index cdd35e53fd98..263335def44b 100644
--- a/arch/riscv/kernel/cacheinfo.c
+++ b/arch/riscv/kernel/cacheinfo.c
@@ -3,10 +3,41 @@
  * Copyright (C) 2017 SiFive
  */
 
-#include 
 #include 
 #include 
 #include 
+#include 
+
+static struct cacheinfo *get_cacheinfo(u32 level, enum cache_type type)
+{
+   struct cpu_cacheinfo *this_cpu_ci = 
get_cpu_cacheinfo(smp_processor_id());
+   struct cacheinfo *this_leaf;
+   int index;
+
+   for (index = 0; index < this_cpu_ci->num_leaves; index++) {
+   this_leaf = this_cpu_ci->info_list + index;
+   if (this_leaf->level == level &&am

  1   2   3   4   5   >