Re: [PATCH 1/3] nds32: Cleanup deprecated function strlen_user

2021-04-20 Thread Greentime Hu
 於 2021年4月20日 週二 下午9:38寫道:
>
> From: Guo Ren 
>
> $ grep strlen_user * -r
> arch/csky/include/asm/uaccess.h:#define strlen_user(str) strnlen_user(str, 
> 32767)
> arch/csky/lib/usercopy.c: * strlen_user: - Get the size of a string in user 
> space.
> arch/ia64/lib/strlen.S: // Please note that in the case of strlen() as 
> opposed to strlen_user()
> arch/mips/lib/strnlen_user.S: *  make strlen_user and strnlen_user access the 
> first few KSEG0
> arch/nds32/include/asm/uaccess.h:extern __must_check long strlen_user(const 
> char __user * str);
> arch/nios2/include/asm/uaccess.h:extern __must_check long strlen_user(const 
> char __user *str);
> arch/riscv/include/asm/uaccess.h:extern long __must_check strlen_user(const 
> char __user *str);
> kernel/trace/trace_probe_tmpl.h:static nokprobe_inline int 
> fetch_store_strlen_user(unsigned long addr);
> kernel/trace/trace_probe_tmpl.h:ret += 
> fetch_store_strlen_user(val + code->offset);
> kernel/trace/trace_uprobe.c:fetch_store_strlen_user(unsigned long addr)
> kernel/trace/trace_kprobe.c:fetch_store_strlen_user(unsigned long addr)
> kernel/trace/trace_kprobe.c:return fetch_store_strlen_user(addr);
>
> See grep result, nobody uses it.
>
> Signed-off-by: Guo Ren 
> Cc: Arnd Bergmann 
> ---
>  arch/nds32/include/asm/uaccess.h | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/arch/nds32/include/asm/uaccess.h 
> b/arch/nds32/include/asm/uaccess.h
> index 010ba5f..d4cbf06 100644
> --- a/arch/nds32/include/asm/uaccess.h
> +++ b/arch/nds32/include/asm/uaccess.h
> @@ -260,7 +260,6 @@ do {  
>   \
>
>  extern unsigned long __arch_clear_user(void __user * addr, unsigned long n);
>  extern long strncpy_from_user(char *dest, const char __user * src, long 
> count);
> -extern __must_check long strlen_user(const char __user * str);
>  extern __must_check long strnlen_user(const char __user * str, long n);
>  extern unsigned long __arch_copy_from_user(void *to, const void __user * 
> from,
> unsigned long n);

Thank you, Guo.
Acked-by: Greentime Hu 


Re: [PATCH v2 6/6] riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

2021-04-18 Thread Greentime Hu
Greentime Hu  於 2021年4月19日 週一 上午10:43寫道:
>
> Palmer Dabbelt  於 2021年3月31日 週三 上午8:24寫道:
> >
> > On Wed, 17 Mar 2021 23:08:13 PDT (-0700), greentime...@sifive.com wrote:
> > > Signed-off-by: Greentime Hu 
> > > ---
> > >  arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 34 ++
> > >  1 file changed, 34 insertions(+)
> > >
> > > diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi 
> > > b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
> > > index d1bb22b11920..d0839739b425 100644
> > > --- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
> > > +++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
> > > @@ -158,6 +158,7 @@ prci: clock-controller@1000 {
> > >   reg = <0x0 0x1000 0x0 0x1000>;
> > >   clocks = <>, <>;
> > >   #clock-cells = <1>;
> > > + #reset-cells = <1>;
> > >   };
> > >   uart0: serial@1001 {
> > >   compatible = "sifive,fu740-c000-uart", 
> > > "sifive,uart0";
> > > @@ -288,5 +289,38 @@ gpio: gpio@1006 {
> > >   clocks = < PRCI_CLK_PCLK>;
> > >   status = "disabled";
> > >   };
> > > + pcie@e {
> > > + #address-cells = <3>;
> > > + #interrupt-cells = <1>;
> > > + #num-lanes = <8>;
> > > + #size-cells = <2>;
> > > + compatible = "sifive,fu740-pcie";
> > > + reg = <0xe 0x 0x1 0x0
> > > +0xd 0xf000 0x0 0x1000
> > > +0x0 0x100d 0x0 0x1000>;
> > > + reg-names = "dbi", "config", "mgmt";
> > > + device_type = "pci";
> > > + dma-coherent;
> > > + bus-range = <0x0 0xff>;
> > > + ranges = <0x8100  0x0 0x6008  0x0 
> > > 0x6008 0x0 0x1/* I/O */
> > > +   0x8200  0x0 0x6009  0x0 
> > > 0x6009 0x0 0xff7  /* mem */
> > > +   0x8200  0x0 0x7000  0x0 
> > > 0x7000 0x0 0x100  /* mem */
> > > +   0xc300 0x20 0x 0x20 
> > > 0x 0x20 0x>;  /* mem prefetchable */
> > > + num-lanes = <0x8>;
> > > + interrupts = <56 57 58 59 60 61 62 63 64>;
> > > + interrupt-names = "msi", "inta", "intb", "intc", 
> > > "intd";
> > > + interrupt-parent = <>;
> > > + interrupt-map-mask = <0x0 0x0 0x0 0x7>;
> > > + interrupt-map = <0x0 0x0 0x0 0x1  57>,
> > > + <0x0 0x0 0x0 0x2  58>,
> > > + <0x0 0x0 0x0 0x3  59>,
> > > + <0x0 0x0 0x0 0x4  60>;
> > > + clock-names = "pcie_aux";
> > > + clocks = < PRCI_CLK_PCIE_AUX>;
> > > + pwren-gpios = < 5 0>;
> > > + perstn-gpios = < 8 0>;
> > > + resets = < 4>;
> > > + status = "okay";
> > > + };
> > >   };
> > >  };
> >
> > Acked-by: Palmer Dabbelt 
> >
> > I'm happy to take these all through the RISC-V tree if that helps, but
> > as usual I'd like reviews or acks from the subsystem maintainers.  It
> > looks like there are some issues so I'm going to drop this from my
> > inbox.
>
> Hi Palmer,
>
> Since the subsystem maintainer has pick the first 5 patches to his
> branch, would you please help to pick the 6th patch of version 6?

Sorry there is no version 6, I mean version 5. :p

> Thank you. :)
>
> https://www.spinics.net/lists/linux-clk/msg57213.html
> https://patchwork.kernel.org/project/linux-riscv/patch/20210406092634.50465-7-greentime...@sifive.com/


Re: [PATCH v2 6/6] riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

2021-04-18 Thread Greentime Hu
Palmer Dabbelt  於 2021年3月31日 週三 上午8:24寫道:
>
> On Wed, 17 Mar 2021 23:08:13 PDT (-0700), greentime...@sifive.com wrote:
> > Signed-off-by: Greentime Hu 
> > ---
> >  arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 34 ++
> >  1 file changed, 34 insertions(+)
> >
> > diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi 
> > b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
> > index d1bb22b11920..d0839739b425 100644
> > --- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
> > +++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
> > @@ -158,6 +158,7 @@ prci: clock-controller@1000 {
> >   reg = <0x0 0x1000 0x0 0x1000>;
> >   clocks = <>, <>;
> >   #clock-cells = <1>;
> > + #reset-cells = <1>;
> >   };
> >   uart0: serial@1001 {
> >   compatible = "sifive,fu740-c000-uart", "sifive,uart0";
> > @@ -288,5 +289,38 @@ gpio: gpio@1006 {
> >   clocks = < PRCI_CLK_PCLK>;
> >   status = "disabled";
> >   };
> > + pcie@e {
> > + #address-cells = <3>;
> > + #interrupt-cells = <1>;
> > + #num-lanes = <8>;
> > + #size-cells = <2>;
> > + compatible = "sifive,fu740-pcie";
> > + reg = <0xe 0x 0x1 0x0
> > +0xd 0xf000 0x0 0x1000
> > +0x0 0x100d 0x0 0x1000>;
> > + reg-names = "dbi", "config", "mgmt";
> > + device_type = "pci";
> > + dma-coherent;
> > + bus-range = <0x0 0xff>;
> > + ranges = <0x8100  0x0 0x6008  0x0 0x6008 
> > 0x0 0x1/* I/O */
> > +   0x8200  0x0 0x6009  0x0 0x6009 
> > 0x0 0xff7  /* mem */
> > +   0x8200  0x0 0x7000  0x0 0x7000 
> > 0x0 0x100  /* mem */
> > +   0xc300 0x20 0x 0x20 0x 
> > 0x20 0x>;  /* mem prefetchable */
> > + num-lanes = <0x8>;
> > + interrupts = <56 57 58 59 60 61 62 63 64>;
> > + interrupt-names = "msi", "inta", "intb", "intc", 
> > "intd";
> > + interrupt-parent = <>;
> > + interrupt-map-mask = <0x0 0x0 0x0 0x7>;
> > + interrupt-map = <0x0 0x0 0x0 0x1  57>,
> > + <0x0 0x0 0x0 0x2  58>,
> > + <0x0 0x0 0x0 0x3  59>,
> > + <0x0 0x0 0x0 0x4  60>;
> > + clock-names = "pcie_aux";
> > + clocks = < PRCI_CLK_PCIE_AUX>;
> > + pwren-gpios = < 5 0>;
> > + perstn-gpios = < 8 0>;
> > + resets = < 4>;
> > + status = "okay";
> > + };
> >   };
> >  };
>
> Acked-by: Palmer Dabbelt 
>
> I'm happy to take these all through the RISC-V tree if that helps, but
> as usual I'd like reviews or acks from the subsystem maintainers.  It
> looks like there are some issues so I'm going to drop this from my
> inbox.

Hi Palmer,

Since the subsystem maintainer has pick the first 5 patches to his
branch, would you please help to pick the 6th patch of version 6?
Thank you. :)

https://www.spinics.net/lists/linux-clk/msg57213.html
https://patchwork.kernel.org/project/linux-riscv/patch/20210406092634.50465-7-greentime...@sifive.com/


Re: [PATCH v5 0/6] Add SiFive FU740 PCIe host controller driver support

2021-04-11 Thread Greentime Hu
Lorenzo Pieralisi  於 2021年4月9日 週五 下午4:54寫道:
>
> On Tue, 6 Apr 2021 17:26:28 +0800, Greentime Hu wrote:
> > This patchset includes SiFive FU740 PCIe host controller driver. We also
> > add pcie_aux clock and pcie_power_on_reset controller to prci driver for
> > PCIe driver to use it.
> >
> > This is tested with e1000e: Intel(R) PRO/1000 Network Card, AMD Radeon R5
> > 230 graphics card and SP M.2 PCIe Gen 3 SSD in SiFive Unmatched based on
> > v5.11 Linux kernel.
> >
> > [...]
>
> Applied to pci/dwc [dropped patch 6], thanks!
>
> [1/6] clk: sifive: Add pcie_aux clock in prci driver for PCIe driver
>   https://git.kernel.org/lpieralisi/pci/c/f3ce593b1a
> [2/6] clk: sifive: Use reset-simple in prci driver for PCIe driver
>   https://git.kernel.org/lpieralisi/pci/c/0a78fcfd3d
> [3/6] MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver
>   https://git.kernel.org/lpieralisi/pci/c/8bb1c66a90
> [4/6] dt-bindings: PCI: Add SiFive FU740 PCIe host controller
>   https://git.kernel.org/lpieralisi/pci/c/b86d55c107
> [5/6] PCI: fu740: Add SiFive FU740 PCIe host controller driver
>   https://git.kernel.org/lpieralisi/pci/c/327c333a79
>
> Thanks,
> Lorenzo

Hi Palmer,

Since the PCIE driver has been applied, would you please pick patch 6
to RISC-V for-next tree?
Thank you. :)


Re: [PATCH v5 0/6] Add SiFive FU740 PCIe host controller driver support

2021-04-08 Thread Greentime Hu
Lorenzo Pieralisi  於 2021年4月9日 週五 上午12:25寫道:
>
> On Tue, Apr 06, 2021 at 05:26:28PM +0800, Greentime Hu wrote:
> > This patchset includes SiFive FU740 PCIe host controller driver. We also
> > add pcie_aux clock and pcie_power_on_reset controller to prci driver for
> > PCIe driver to use it.
> >
> > This is tested with e1000e: Intel(R) PRO/1000 Network Card, AMD Radeon R5
> > 230 graphics card and SP M.2 PCIe Gen 3 SSD in SiFive Unmatched based on
> > v5.11 Linux kernel.
> >
> > Changes in v5:
> >  - Fix typo in comments
> >  - Keep comments style consistent
> >  - Refine some error handling codes
> >  - Remove unneeded header file including
> >  - Merge fu740_pcie_ltssm_enable implementation to fu740_pcie_start_link
> >
> > Changes in v4:
> >  - Fix Wunused-but-set-variable warning in prci driver
> >
> > Changes in v3:
> >  - Remove items that has been defined
> >  - Refine format of sifive,fu740-pcie.yaml
> >  - Replace perstn-gpios with the common one
> >  - Change DBI mapping space to 2GB from 4GB
> >  - Refine drivers/reset/Kconfig
> >
> > Changes in v2:
> >  - Refine codes based on reviewers' feedback
> >  - Remove define and use the common one
> >  - Replace __raw_writel with writel_relaxed
> >  - Split fu740_phyregreadwrite to write function
> >  - Use readl_poll_timeout in stead of while loop checking
> >  - Use dwc common codes
> >  - Use gpio descriptors and the gpiod_* api.
> >  - Replace devm_ioremap_resource with devm_platform_ioremap_resource_byname
> >  - Replace devm_reset_control_get with devm_reset_control_get_exclusive
> >  - Add more comments for delay and sleep
> >  - Remove "phy ? x : y" expressions
> >  - Refine code logic to remove possible infinite loop
> >  - Replace magic number with meaningful define
> >  - Remove fu740_pcie_pm_ops
> >  - Use builtin_platform_driver
> >
> > Greentime Hu (5):
> >   clk: sifive: Add pcie_aux clock in prci driver for PCIe driver
> >   clk: sifive: Use reset-simple in prci driver for PCIe driver
> >   MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver
> >   dt-bindings: PCI: Add SiFive FU740 PCIe host controller
> >   riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC
> >
> > Paul Walmsley (1):
> >   PCI: fu740: Add SiFive FU740 PCIe host controller driver
>
> I can pull the patches above into the PCI tree (but will drop patch 6 -
> dts changes), is it OK for you ? Please let me know how you would like
> to upstream it.
>

Hi Lorenzo,

Thank you.
I am ok with it. So I should ask Palmer to pick patch 6 dts changes to
RISC-V tree?


[PATCH v5 6/6] riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

2021-04-06 Thread Greentime Hu
Signed-off-by: Greentime Hu 
Acked-by: Palmer Dabbelt 
---
 arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 33 ++
 1 file changed, 33 insertions(+)

diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi 
b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
index d1bb22b11920..b2317c8e3a80 100644
--- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
@@ -158,6 +158,7 @@ prci: clock-controller@1000 {
reg = <0x0 0x1000 0x0 0x1000>;
clocks = <>, <>;
#clock-cells = <1>;
+   #reset-cells = <1>;
};
uart0: serial@1001 {
compatible = "sifive,fu740-c000-uart", "sifive,uart0";
@@ -288,5 +289,37 @@ gpio: gpio@1006 {
clocks = < PRCI_CLK_PCLK>;
status = "disabled";
};
+   pcie@e {
+   compatible = "sifive,fu740-pcie";
+   #address-cells = <3>;
+   #size-cells = <2>;
+   #interrupt-cells = <1>;
+   reg = <0xe 0x 0x0 0x8000>,
+ <0xd 0xf000 0x0 0x1000>,
+ <0x0 0x100d 0x0 0x1000>;
+   reg-names = "dbi", "config", "mgmt";
+   device_type = "pci";
+   dma-coherent;
+   bus-range = <0x0 0xff>;
+   ranges = <0x8100  0x0 0x6008  0x0 0x6008 
0x0 0x1>,  /* I/O */
+<0x8200  0x0 0x6009  0x0 0x6009 
0x0 0xff7>,/* mem */
+<0x8200  0x0 0x7000  0x0 0x7000 
0x0 0x100>,/* mem */
+<0xc300 0x20 0x 0x20 0x 
0x20 0x>;  /* mem prefetchable */
+   num-lanes = <0x8>;
+   interrupts = <56>, <57>, <58>, <59>, <60>, <61>, <62>, 
<63>, <64>;
+   interrupt-names = "msi", "inta", "intb", "intc", "intd";
+   interrupt-parent = <>;
+   interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+   interrupt-map = <0x0 0x0 0x0 0x1  57>,
+   <0x0 0x0 0x0 0x2  58>,
+   <0x0 0x0 0x0 0x3  59>,
+   <0x0 0x0 0x0 0x4  60>;
+   clock-names = "pcie_aux";
+   clocks = < PRCI_CLK_PCIE_AUX>;
+   pwren-gpios = < 5 0>;
+   reset-gpios = < 8 0>;
+   resets = < 4>;
+   status = "okay";
+   };
};
 };
-- 
2.30.2



[PATCH v5 5/6] PCI: fu740: Add SiFive FU740 PCIe host controller driver

2021-04-06 Thread Greentime Hu
From: Paul Walmsley 

Add driver for the SiFive FU740 PCIe host controller.
This controller is based on the DesignWare PCIe core.

Signed-off-by: Paul Walmsley 
Co-developed-by: Henry Styles 
Signed-off-by: Henry Styles 
Co-developed-by: Erik Danie 
Signed-off-by: Erik Danie 
Co-developed-by: Greentime Hu 
Signed-off-by: Greentime Hu 
---
 drivers/pci/controller/dwc/Kconfig  |   9 +
 drivers/pci/controller/dwc/Makefile |   1 +
 drivers/pci/controller/dwc/pcie-fu740.c | 308 
 3 files changed, 318 insertions(+)
 create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c

diff --git a/drivers/pci/controller/dwc/Kconfig 
b/drivers/pci/controller/dwc/Kconfig
index 22c5529e9a65..0a37d21ed64e 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -318,4 +318,13 @@ config PCIE_AL
  required only for DT-based platforms. ACPI platforms with the
  Annapurna Labs PCIe controller don't need to enable this.
 
+config PCIE_FU740
+   bool "SiFive FU740 PCIe host controller"
+   depends on PCI_MSI_IRQ_DOMAIN
+   depends on SOC_SIFIVE || COMPILE_TEST
+   select PCIE_DW_HOST
+   help
+ Say Y here if you want PCIe controller support for the SiFive
+ FU740.
+
 endmenu
diff --git a/drivers/pci/controller/dwc/Makefile 
b/drivers/pci/controller/dwc/Makefile
index a751553fa0db..625f6aaeb5b8 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
 obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
+obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
 obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
diff --git a/drivers/pci/controller/dwc/pcie-fu740.c 
b/drivers/pci/controller/dwc/pcie-fu740.c
new file mode 100644
index ..f8abb08095aa
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-fu740.c
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FU740 DesignWare PCIe Controller integration
+ * Copyright (C) 2019-2021 SiFive, Inc.
+ * Paul Walmsley
+ * Greentime Hu
+ *
+ * Based in part on the i.MX6 PCIe host controller shim which is:
+ *
+ * Copyright (C) 2013 Kosagi
+ * https://www.kosagi.com
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pcie-designware.h"
+
+#define to_fu740_pcie(x)   dev_get_drvdata((x)->dev)
+
+struct fu740_pcie {
+   struct dw_pcie pci;
+   void __iomem *mgmt_base;
+   struct gpio_desc *reset;
+   struct gpio_desc *pwren;
+   struct clk *pcie_aux;
+   struct reset_control *rst;
+};
+
+#define SIFIVE_DEVICESRESETREG 0x28
+
+#define PCIEX8MGMT_PERST_N 0x0
+#define PCIEX8MGMT_APP_LTSSM_ENABLE0x10
+#define PCIEX8MGMT_APP_HOLD_PHY_RST0x18
+#define PCIEX8MGMT_DEVICE_TYPE 0x708
+#define PCIEX8MGMT_PHY0_CR_PARA_ADDR   0x860
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN  0x870
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA0x878
+#define PCIEX8MGMT_PHY0_CR_PARA_SEL0x880
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA0x888
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN  0x890
+#define PCIEX8MGMT_PHY0_CR_PARA_ACK0x898
+#define PCIEX8MGMT_PHY1_CR_PARA_ADDR   0x8a0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN  0x8b0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA0x8b8
+#define PCIEX8MGMT_PHY1_CR_PARA_SEL0x8c0
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA0x8c8
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN  0x8d0
+#define PCIEX8MGMT_PHY1_CR_PARA_ACK0x8d8
+
+#define PCIEX8MGMT_PHY_CDR_TRACK_ENBIT(0)
+#define PCIEX8MGMT_PHY_LOS_THRSHLD BIT(5)
+#define PCIEX8MGMT_PHY_TERM_EN BIT(9)
+#define PCIEX8MGMT_PHY_TERM_ACDC   BIT(10)
+#define PCIEX8MGMT_PHY_EN  BIT(11)
+#define PCIEX8MGMT_PHY_INIT_VAL(PCIEX8MGMT_PHY_CDR_TRACK_EN|\
+PCIEX8MGMT_PHY_LOS_THRSHLD|\
+PCIEX8MGMT_PHY_TERM_EN|\
+PCIEX8MGMT_PHY_TERM_ACDC|\
+PCIEX8MGMT_PHY_EN)
+
+#define PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 0x1008
+#define PCIEX8MGMT_PHY_LANE_OFF0x100
+#define PCIEX8MGMT_PHY_LANE0_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 0)
+#define PCIEX8MGMT_PHY_LANE1_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 1)
+#define PCIEX8MGMT_PHY_LANE2_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 2)
+#define PCIEX8MGMT_PHY_LANE3_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 3)
+
+static void fu740_pcie_assert_reset(struct fu740_pcie *afp)
+{
+  

[PATCH v5 4/6] dt-bindings: PCI: Add SiFive FU740 PCIe host controller

2021-04-06 Thread Greentime Hu
Add PCIe host controller DT bindings of SiFive FU740.

Signed-off-by: Greentime Hu 
---
 .../bindings/pci/sifive,fu740-pcie.yaml   | 113 ++
 1 file changed, 113 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml 
b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
new file mode 100644
index ..b03cbb9b6602
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
@@ -0,0 +1,113 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/sifive,fu740-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive FU740 PCIe host controller
+
+description: |+
+  SiFive FU740 PCIe host controller is based on the Synopsys DesignWare
+  PCI core. It shares common features with the PCIe DesignWare core and
+  inherits common properties defined in
+  Documentation/devicetree/bindings/pci/designware-pcie.txt.
+
+maintainers:
+  - Paul Walmsley 
+  - Greentime Hu 
+
+allOf:
+  - $ref: /schemas/pci/pci-bus.yaml#
+
+properties:
+  compatible:
+const: sifive,fu740-pcie
+
+  reg:
+maxItems: 3
+
+  reg-names:
+items:
+  - const: dbi
+  - const: config
+  - const: mgmt
+
+  num-lanes:
+const: 8
+
+  msi-parent: true
+
+  interrupt-names:
+items:
+  - const: msi
+  - const: inta
+  - const: intb
+  - const: intc
+  - const: intd
+
+  resets:
+description: A phandle to the PCIe power up reset line.
+maxItems: 1
+
+  pwren-gpios:
+description: Should specify the GPIO for controlling the PCI bus device 
power on.
+maxItems: 1
+
+  reset-gpios:
+maxItems: 1
+
+required:
+  - dma-coherent
+  - num-lanes
+  - interrupts
+  - interrupt-names
+  - interrupt-parent
+  - interrupt-map-mask
+  - interrupt-map
+  - clock-names
+  - clocks
+  - resets
+  - pwren-gpios
+  - reset-gpios
+
+unevaluatedProperties: false
+
+examples:
+  - |
+bus {
+#address-cells = <2>;
+#size-cells = <2>;
+#include 
+
+pcie@e {
+compatible = "sifive,fu740-pcie";
+#address-cells = <3>;
+#size-cells = <2>;
+#interrupt-cells = <1>;
+reg = <0xe 0x 0x0 0x8000>,
+  <0xd 0xf000 0x0 0x1000>,
+  <0x0 0x100d 0x0 0x1000>;
+reg-names = "dbi", "config", "mgmt";
+device_type = "pci";
+dma-coherent;
+bus-range = <0x0 0xff>;
+ranges = <0x8100  0x0 0x6008  0x0 0x6008 0x0 0x1>, 
 /* I/O */
+ <0x8200  0x0 0x6009  0x0 0x6009 0x0 
0xff7>,/* mem */
+ <0x8200  0x0 0x7000  0x0 0x7000 0x0 
0x100>,/* mem */
+ <0xc300 0x20 0x 0x20 0x 0x20 
0x>;  /* mem prefetchable */
+num-lanes = <0x8>;
+interrupts = <56>, <57>, <58>, <59>, <60>, <61>, <62>, <63>, <64>;
+interrupt-names = "msi", "inta", "intb", "intc", "intd";
+interrupt-parent = <>;
+interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+interrupt-map = <0x0 0x0 0x0 0x1  57>,
+<0x0 0x0 0x0 0x2  58>,
+<0x0 0x0 0x0 0x3  59>,
+<0x0 0x0 0x0 0x4  60>;
+clock-names = "pcie_aux";
+clocks = < PRCI_CLK_PCIE_AUX>;
+resets = < 4>;
+pwren-gpios = < 5 0>;
+reset-gpios = < 8 0>;
+};
+};
-- 
2.30.2



[PATCH v5 3/6] MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver

2021-04-06 Thread Greentime Hu
Here add maintainer information for SiFive FU740 PCIe driver.

Signed-off-by: Greentime Hu 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index bfc1b86e3e73..4da888be6e80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13592,6 +13592,14 @@ S: Maintained
 F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 F: drivers/pci/controller/dwc/*imx6*
 
+PCI DRIVER FOR FU740
+M: Paul Walmsley 
+M: Greentime Hu 
+L: linux-...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
+F: drivers/pci/controller/dwc/pcie-fu740.c
+
 PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
 M: Jonathan Derrick 
 L: linux-...@vger.kernel.org
-- 
2.30.2



[PATCH v5 2/6] clk: sifive: Use reset-simple in prci driver for PCIe driver

2021-04-06 Thread Greentime Hu
We use reset-simple in this patch so that pcie driver can use
devm_reset_control_get() to get this reset data structure and use
reset_control_deassert() to deassert pcie_power_up_rst_n.

Signed-off-by: Greentime Hu 
Reviewed-by: Philipp Zabel 
Acked-by: Stephen Boyd 
---
 drivers/clk/sifive/Kconfig   |  2 ++
 drivers/clk/sifive/sifive-prci.c | 13 +
 drivers/clk/sifive/sifive-prci.h |  4 
 drivers/reset/Kconfig|  1 +
 4 files changed, 20 insertions(+)

diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
index 1c14eb20c066..9132c3c4aa86 100644
--- a/drivers/clk/sifive/Kconfig
+++ b/drivers/clk/sifive/Kconfig
@@ -10,6 +10,8 @@ if CLK_SIFIVE
 
 config CLK_SIFIVE_PRCI
bool "PRCI driver for SiFive SoCs"
+   select RESET_CONTROLLER
+   select RESET_SIMPLE
select CLK_ANALOGBITS_WRPLL_CLN28HPC
help
  Supports the Power Reset Clock interface (PRCI) IP block found in
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index 8fdba5da2902..0704fddba6b9 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -583,6 +583,19 @@ static int sifive_prci_probe(struct platform_device *pdev)
if (IS_ERR(pd->va))
return PTR_ERR(pd->va);
 
+   pd->reset.rcdev.owner = THIS_MODULE;
+   pd->reset.rcdev.nr_resets = PRCI_RST_NR;
+   pd->reset.rcdev.ops = _simple_ops;
+   pd->reset.rcdev.of_node = pdev->dev.of_node;
+   pd->reset.active_low = true;
+   pd->reset.membase = pd->va + PRCI_DEVICESRESETREG_OFFSET;
+   spin_lock_init(>reset.lock);
+
+   r = devm_reset_controller_register(>dev, >reset.rcdev);
+   if (r) {
+   dev_err(dev, "could not register reset controller: %d\n", r);
+   return r;
+   }
r = __prci_register_clocks(dev, pd, desc);
if (r) {
dev_err(dev, "could not register clocks: %d\n", r);
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index 022c67cf053c..91658a88af4e 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -121,6 +122,8 @@
 #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK   \
(0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
 
+#define PRCI_RST_NR7
+
 /* CLKMUXSTATUSREG */
 #define PRCI_CLKMUXSTATUSREG_OFFSET0x2c
 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
@@ -221,6 +224,7 @@
  */
 struct __prci_data {
void __iomem *va;
+   struct reset_simple_data reset;
struct clk_hw_onecell_data hw_clks;
 };
 
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 71ab75a46491..d0f5d0afc240 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -187,6 +187,7 @@ config RESET_SIMPLE
   - RCC reset controller in STM32 MCUs
   - Allwinner SoCs
   - ZTE's zx2967 family
+  - SiFive FU740 SoCs
 
 config RESET_STM32MP157
bool "STM32MP157 Reset Driver" if COMPILE_TEST
-- 
2.30.2



[PATCH v5 1/6] clk: sifive: Add pcie_aux clock in prci driver for PCIe driver

2021-04-06 Thread Greentime Hu
We add pcie_aux clock in this patch so that pcie driver can use
clk_prepare_enable() and clk_disable_unprepare() to enable and disable
pcie_aux clock.

Signed-off-by: Greentime Hu 
Acked-by: Stephen Boyd 
---
 drivers/clk/sifive/fu740-prci.c   | 11 +
 drivers/clk/sifive/fu740-prci.h   |  2 +-
 drivers/clk/sifive/sifive-prci.c  | 41 +++
 drivers/clk/sifive/sifive-prci.h  |  9 
 include/dt-bindings/clock/sifive-fu740-prci.h |  1 +
 5 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index 764d1097aa51..53f6e00a03b9 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -72,6 +72,12 @@ static const struct clk_ops 
sifive_fu740_prci_hfpclkplldiv_clk_ops = {
.recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
 };
 
+static const struct clk_ops sifive_fu740_prci_pcie_aux_clk_ops = {
+   .enable = sifive_prci_pcie_aux_clock_enable,
+   .disable = sifive_prci_pcie_aux_clock_disable,
+   .is_enabled = sifive_prci_pcie_aux_clock_is_enabled,
+};
+
 /* List of clock controls provided by the PRCI */
 struct __prci_clock __prci_init_clocks_fu740[] = {
[PRCI_CLK_COREPLL] = {
@@ -120,4 +126,9 @@ struct __prci_clock __prci_init_clocks_fu740[] = {
.parent_name = "hfpclkpll",
.ops = _fu740_prci_hfpclkplldiv_clk_ops,
},
+   [PRCI_CLK_PCIE_AUX] = {
+   .name = "pcie_aux",
+   .parent_name = "hfclk",
+   .ops = _fu740_prci_pcie_aux_clk_ops,
+   },
 };
diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h
index 13ef971f7764..511a0bf7ba2b 100644
--- a/drivers/clk/sifive/fu740-prci.h
+++ b/drivers/clk/sifive/fu740-prci.h
@@ -9,7 +9,7 @@
 
 #include "sifive-prci.h"
 
-#define NUM_CLOCK_FU7408
+#define NUM_CLOCK_FU7409
 
 extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740];
 
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index c78b042750e2..8fdba5da2902 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -448,6 +448,47 @@ void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct 
__prci_data *pd)
r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
 }
 
+/* PCIE AUX clock APIs for enable, disable. */
+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r;
+
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET);
+
+   if (r & PRCI_PCIE_AUX_EN_MASK)
+   return 1;
+   else
+   return 0;
+}
+
+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r __maybe_unused;
+
+   if (sifive_prci_pcie_aux_clock_is_enabled(hw))
+   return 0;
+
+   __prci_writel(1, PRCI_PCIE_AUX_OFFSET, pd);
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
+
+   return 0;
+}
+
+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r __maybe_unused;
+
+   __prci_writel(0, PRCI_PCIE_AUX_OFFSET, pd);
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
+
+}
+
 /**
  * __prci_register_clocks() - register clock controls in the PRCI
  * @dev: Linux struct device
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index dbdbd1722688..022c67cf053c 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -67,6 +67,11 @@
 #define PRCI_DDRPLLCFG1_CKE_SHIFT  31
 #define PRCI_DDRPLLCFG1_CKE_MASK   (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
 
+/* PCIEAUX */
+#define PRCI_PCIE_AUX_OFFSET   0x14
+#define PRCI_PCIE_AUX_EN_SHIFT 0
+#define PRCI_PCIE_AUX_EN_MASK  (0x1 << PRCI_PCIE_AUX_EN_SHIFT)
+
 /* GEMGXLPLLCFG0 */
 #define PRCI_GEMGXLPLLCFG0_OFFSET  0x1c
 #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT  0
@@ -296,4 +301,8 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct 
clk_hw *hw,
 unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
   unsigned long parent_rate);
 
+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
+
 #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
diff --git a/include/dt-bindings/clock/sifive-fu740-prci.h 
b/include/dt-bindings/clock/sifive-fu740-prci.h
index cd7706ea5677..7899b7fee7db 100644
--- a/include/dt-bindings/clock/sifive-fu740-prci.h
+

[PATCH v5 0/6] Add SiFive FU740 PCIe host controller driver support

2021-04-06 Thread Greentime Hu
This patchset includes SiFive FU740 PCIe host controller driver. We also
add pcie_aux clock and pcie_power_on_reset controller to prci driver for
PCIe driver to use it.

This is tested with e1000e: Intel(R) PRO/1000 Network Card, AMD Radeon R5
230 graphics card and SP M.2 PCIe Gen 3 SSD in SiFive Unmatched based on
v5.11 Linux kernel.

Changes in v5:
 - Fix typo in comments
 - Keep comments style consistent
 - Refine some error handling codes
 - Remove unneeded header file including
 - Merge fu740_pcie_ltssm_enable implementation to fu740_pcie_start_link

Changes in v4:
 - Fix Wunused-but-set-variable warning in prci driver

Changes in v3:
 - Remove items that has been defined
 - Refine format of sifive,fu740-pcie.yaml
 - Replace perstn-gpios with the common one
 - Change DBI mapping space to 2GB from 4GB
 - Refine drivers/reset/Kconfig

Changes in v2:
 - Refine codes based on reviewers' feedback
 - Remove define and use the common one
 - Replace __raw_writel with writel_relaxed
 - Split fu740_phyregreadwrite to write function
 - Use readl_poll_timeout in stead of while loop checking
 - Use dwc common codes
 - Use gpio descriptors and the gpiod_* api.
 - Replace devm_ioremap_resource with devm_platform_ioremap_resource_byname
 - Replace devm_reset_control_get with devm_reset_control_get_exclusive
 - Add more comments for delay and sleep
 - Remove "phy ? x : y" expressions
 - Refine code logic to remove possible infinite loop
 - Replace magic number with meaningful define
 - Remove fu740_pcie_pm_ops
 - Use builtin_platform_driver

Greentime Hu (5):
  clk: sifive: Add pcie_aux clock in prci driver for PCIe driver
  clk: sifive: Use reset-simple in prci driver for PCIe driver
  MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver
  dt-bindings: PCI: Add SiFive FU740 PCIe host controller
  riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

Paul Walmsley (1):
  PCI: fu740: Add SiFive FU740 PCIe host controller driver

 .../bindings/pci/sifive,fu740-pcie.yaml   | 113 +++
 MAINTAINERS   |   8 +
 arch/riscv/boot/dts/sifive/fu740-c000.dtsi|  33 ++
 drivers/clk/sifive/Kconfig|   2 +
 drivers/clk/sifive/fu740-prci.c   |  11 +
 drivers/clk/sifive/fu740-prci.h   |   2 +-
 drivers/clk/sifive/sifive-prci.c  |  54 +++
 drivers/clk/sifive/sifive-prci.h  |  13 +
 drivers/pci/controller/dwc/Kconfig|   9 +
 drivers/pci/controller/dwc/Makefile   |   1 +
 drivers/pci/controller/dwc/pcie-fu740.c   | 308 ++
 drivers/reset/Kconfig |   1 +
 include/dt-bindings/clock/sifive-fu740-prci.h |   1 +
 13 files changed, 555 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
 create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c

-- 
2.30.2



Re: [PATCH v2 0/6] Add SiFive FU740 PCIe host controller driver support

2021-04-01 Thread Greentime Hu
Stephen Boyd  於 2021年3月30日 週二 上午3:12寫道:
>
> Quoting Greentime Hu (2021-03-17 23:08:07)
> > This patchset includes SiFive FU740 PCIe host controller driver. We also
> > add pcie_aux clock and pcie_power_on_reset controller to prci driver for
> > PCIe driver to use it.
> >
> > This is tested with e1000e: Intel(R) PRO/1000 Network Card, AMD Radeon R5
> > 230 graphics card and SP M.2 PCIe Gen 3 SSD in SiFive Unmatched based on
> > v5.11 Linux kernel.
>
> Can I merge the clk patches to clk-next? Or is the dts patch going to be
> sent in for the merge window? I'd like to merge the clk patches if the
> other patches are going to miss the next merge window.

Hi Stephen,

Thank you for reviewing. I am ok with either way. :)


[PATCH v4 6/6] riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

2021-04-01 Thread Greentime Hu
Signed-off-by: Greentime Hu 
Acked-by: Palmer Dabbelt 
---
 arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 33 ++
 1 file changed, 33 insertions(+)

diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi 
b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
index d1bb22b11920..b2317c8e3a80 100644
--- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
@@ -158,6 +158,7 @@ prci: clock-controller@1000 {
reg = <0x0 0x1000 0x0 0x1000>;
clocks = <>, <>;
#clock-cells = <1>;
+   #reset-cells = <1>;
};
uart0: serial@1001 {
compatible = "sifive,fu740-c000-uart", "sifive,uart0";
@@ -288,5 +289,37 @@ gpio: gpio@1006 {
clocks = < PRCI_CLK_PCLK>;
status = "disabled";
};
+   pcie@e {
+   compatible = "sifive,fu740-pcie";
+   #address-cells = <3>;
+   #size-cells = <2>;
+   #interrupt-cells = <1>;
+   reg = <0xe 0x 0x0 0x8000>,
+ <0xd 0xf000 0x0 0x1000>,
+ <0x0 0x100d 0x0 0x1000>;
+   reg-names = "dbi", "config", "mgmt";
+   device_type = "pci";
+   dma-coherent;
+   bus-range = <0x0 0xff>;
+   ranges = <0x8100  0x0 0x6008  0x0 0x6008 
0x0 0x1>,  /* I/O */
+<0x8200  0x0 0x6009  0x0 0x6009 
0x0 0xff7>,/* mem */
+<0x8200  0x0 0x7000  0x0 0x7000 
0x0 0x100>,/* mem */
+<0xc300 0x20 0x 0x20 0x 
0x20 0x>;  /* mem prefetchable */
+   num-lanes = <0x8>;
+   interrupts = <56>, <57>, <58>, <59>, <60>, <61>, <62>, 
<63>, <64>;
+   interrupt-names = "msi", "inta", "intb", "intc", "intd";
+   interrupt-parent = <>;
+   interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+   interrupt-map = <0x0 0x0 0x0 0x1  57>,
+   <0x0 0x0 0x0 0x2  58>,
+   <0x0 0x0 0x0 0x3  59>,
+   <0x0 0x0 0x0 0x4  60>;
+   clock-names = "pcie_aux";
+   clocks = < PRCI_CLK_PCIE_AUX>;
+   pwren-gpios = < 5 0>;
+   reset-gpios = < 8 0>;
+   resets = < 4>;
+   status = "okay";
+   };
};
 };
-- 
2.30.2



[PATCH v4 5/6] PCI: fu740: Add SiFive FU740 PCIe host controller driver

2021-04-01 Thread Greentime Hu
From: Paul Walmsley 

Add driver for the SiFive FU740 PCIe host controller.
This controller is based on the DesignWare PCIe core.

Signed-off-by: Paul Walmsley 
Co-developed-by: Henry Styles 
Signed-off-by: Henry Styles 
Co-developed-by: Erik Danie 
Signed-off-by: Erik Danie 
Co-developed-by: Greentime Hu 
Signed-off-by: Greentime Hu 
---
 drivers/pci/controller/dwc/Kconfig  |   9 +
 drivers/pci/controller/dwc/Makefile |   1 +
 drivers/pci/controller/dwc/pcie-fu740.c | 324 
 3 files changed, 334 insertions(+)
 create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c

diff --git a/drivers/pci/controller/dwc/Kconfig 
b/drivers/pci/controller/dwc/Kconfig
index 22c5529e9a65..0a37d21ed64e 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -318,4 +318,13 @@ config PCIE_AL
  required only for DT-based platforms. ACPI platforms with the
  Annapurna Labs PCIe controller don't need to enable this.
 
+config PCIE_FU740
+   bool "SiFive FU740 PCIe host controller"
+   depends on PCI_MSI_IRQ_DOMAIN
+   depends on SOC_SIFIVE || COMPILE_TEST
+   select PCIE_DW_HOST
+   help
+ Say Y here if you want PCIe controller support for the SiFive
+ FU740.
+
 endmenu
diff --git a/drivers/pci/controller/dwc/Makefile 
b/drivers/pci/controller/dwc/Makefile
index a751553fa0db..625f6aaeb5b8 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
 obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
+obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
 obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
diff --git a/drivers/pci/controller/dwc/pcie-fu740.c 
b/drivers/pci/controller/dwc/pcie-fu740.c
new file mode 100644
index ..ebbcbda97490
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-fu740.c
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FU740 DesignWare PCIe Controller integration
+ * Copyright (C) 2019-2021 SiFive, Inc.
+ * Paul Walmsley
+ * Greentime Hu
+ *
+ * Based in part on the i.MX6 PCIe host controller shim which is:
+ *
+ * Copyright (C) 2013 Kosagi
+ * https://www.kosagi.com
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pcie-designware.h"
+
+#define to_fu740_pcie(x)   dev_get_drvdata((x)->dev)
+
+struct fu740_pcie {
+   struct dw_pcie pci;
+   void __iomem *mgmt_base;
+   struct gpio_desc *reset;
+   struct gpio_desc *pwren;
+   struct clk *pcie_aux;
+   struct reset_control *rst;
+};
+
+#define SIFIVE_DEVICESRESETREG 0x28
+
+#define PCIEX8MGMT_PERST_N 0x0
+#define PCIEX8MGMT_APP_LTSSM_ENABLE0x10
+#define PCIEX8MGMT_APP_HOLD_PHY_RST0x18
+#define PCIEX8MGMT_DEVICE_TYPE 0x708
+#define PCIEX8MGMT_PHY0_CR_PARA_ADDR   0x860
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN  0x870
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA0x878
+#define PCIEX8MGMT_PHY0_CR_PARA_SEL0x880
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA0x888
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN  0x890
+#define PCIEX8MGMT_PHY0_CR_PARA_ACK0x898
+#define PCIEX8MGMT_PHY1_CR_PARA_ADDR   0x8a0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN  0x8b0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA0x8b8
+#define PCIEX8MGMT_PHY1_CR_PARA_SEL0x8c0
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA0x8c8
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN  0x8d0
+#define PCIEX8MGMT_PHY1_CR_PARA_ACK0x8d8
+
+#define PCIEX8MGMT_PHY_CDR_TRACK_ENBIT(0)
+#define PCIEX8MGMT_PHY_LOS_THRSHLD BIT(5)
+#define PCIEX8MGMT_PHY_TERM_EN BIT(9)
+#define PCIEX8MGMT_PHY_TERM_ACDC   BIT(10)
+#define PCIEX8MGMT_PHY_EN  BIT(11)
+#define PCIEX8MGMT_PHY_INIT_VAL(PCIEX8MGMT_PHY_CDR_TRACK_EN|\
+PCIEX8MGMT_PHY_LOS_THRSHLD|\
+PCIEX8MGMT_PHY_TERM_EN|\
+PCIEX8MGMT_PHY_TERM_ACDC|\
+PCIEX8MGMT_PHY_EN)
+
+#define PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 0x1008
+#define PCIEX8MGMT_PHY_LANE_OFF0x100
+#define PCIEX8MGMT_PHY_LANE0_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 0)
+#define PCIEX8MGMT_PHY_LANE1_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 1)
+#define PCIEX8MGMT_PHY_LANE2_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 2)
+#define PCIEX8MGMT_PHY_LANE3_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 3)
+
+static void fu740_pcie_assert_

[PATCH v4 4/6] dt-bindings: PCI: Add SiFive FU740 PCIe host controller

2021-04-01 Thread Greentime Hu
Add PCIe host controller DT bindings of SiFive FU740.

Signed-off-by: Greentime Hu 
---
 .../bindings/pci/sifive,fu740-pcie.yaml   | 109 ++
 1 file changed, 109 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml 
b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
new file mode 100644
index ..ccb58e5f06d4
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/sifive,fu740-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive FU740 PCIe host controller
+
+description: |+
+  SiFive FU740 PCIe host controller is based on the Synopsys DesignWare
+  PCI core. It shares common features with the PCIe DesignWare core and
+  inherits common properties defined in
+  Documentation/devicetree/bindings/pci/designware-pcie.txt.
+
+maintainers:
+  - Paul Walmsley 
+  - Greentime Hu 
+
+allOf:
+  - $ref: /schemas/pci/pci-bus.yaml#
+
+properties:
+  compatible:
+const: sifive,fu740-pcie
+
+  reg:
+maxItems: 3
+
+  reg-names:
+items:
+  - const: dbi
+  - const: config
+  - const: mgmt
+
+  num-lanes:
+const: 8
+
+  msi-parent: true
+
+  interrupt-names:
+items:
+  - const: msi
+  - const: inta
+  - const: intb
+  - const: intc
+  - const: intd
+
+  resets:
+description: A phandle to the PCIe power up reset line.
+
+  pwren-gpios:
+description: Should specify the GPIO for controlling the PCI bus device 
power on.
+maxItems: 1
+
+required:
+  - dma-coherent
+  - num-lanes
+  - interrupts
+  - interrupt-names
+  - interrupt-parent
+  - interrupt-map-mask
+  - interrupt-map
+  - clock-names
+  - clocks
+  - resets
+  - pwren-gpios
+  - reset-gpios
+
+unevaluatedProperties: false
+
+examples:
+  - |
+bus {
+#address-cells = <2>;
+#size-cells = <2>;
+#include 
+
+pcie@e {
+compatible = "sifive,fu740-pcie";
+#address-cells = <3>;
+#size-cells = <2>;
+#interrupt-cells = <1>;
+reg = <0xe 0x 0x0 0x8000>,
+  <0xd 0xf000 0x0 0x1000>,
+  <0x0 0x100d 0x0 0x1000>;
+reg-names = "dbi", "config", "mgmt";
+device_type = "pci";
+dma-coherent;
+bus-range = <0x0 0xff>;
+ranges = <0x8100  0x0 0x6008  0x0 0x6008 0x0 0x1>, 
 /* I/O */
+ <0x8200  0x0 0x6009  0x0 0x6009 0x0 
0xff7>,/* mem */
+ <0x8200  0x0 0x7000  0x0 0x7000 0x0 
0x100>,/* mem */
+ <0xc300 0x20 0x 0x20 0x 0x20 
0x>;  /* mem prefetchable */
+num-lanes = <0x8>;
+interrupts = <56>, <57>, <58>, <59>, <60>, <61>, <62>, <63>, <64>;
+interrupt-names = "msi", "inta", "intb", "intc", "intd";
+interrupt-parent = <>;
+interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+interrupt-map = <0x0 0x0 0x0 0x1  57>,
+<0x0 0x0 0x0 0x2  58>,
+<0x0 0x0 0x0 0x3  59>,
+<0x0 0x0 0x0 0x4  60>;
+clock-names = "pcie_aux";
+clocks = < PRCI_CLK_PCIE_AUX>;
+resets = < 4>;
+pwren-gpios = < 5 0>;
+reset-gpios = < 8 0>;
+};
+};
-- 
2.30.2



[PATCH v4 2/6] clk: sifive: Use reset-simple in prci driver for PCIe driver

2021-04-01 Thread Greentime Hu
We use reset-simple in this patch so that pcie driver can use
devm_reset_control_get() to get this reset data structure and use
reset_control_deassert() to deassert pcie_power_up_rst_n.

Signed-off-by: Greentime Hu 
Reviewed-by: Philipp Zabel 
Acked-by: Stephen Boyd 
---
 drivers/clk/sifive/Kconfig   |  2 ++
 drivers/clk/sifive/sifive-prci.c | 13 +
 drivers/clk/sifive/sifive-prci.h |  4 
 drivers/reset/Kconfig|  1 +
 4 files changed, 20 insertions(+)

diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
index 1c14eb20c066..9132c3c4aa86 100644
--- a/drivers/clk/sifive/Kconfig
+++ b/drivers/clk/sifive/Kconfig
@@ -10,6 +10,8 @@ if CLK_SIFIVE
 
 config CLK_SIFIVE_PRCI
bool "PRCI driver for SiFive SoCs"
+   select RESET_CONTROLLER
+   select RESET_SIMPLE
select CLK_ANALOGBITS_WRPLL_CLN28HPC
help
  Supports the Power Reset Clock interface (PRCI) IP block found in
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index 8fdba5da2902..0704fddba6b9 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -583,6 +583,19 @@ static int sifive_prci_probe(struct platform_device *pdev)
if (IS_ERR(pd->va))
return PTR_ERR(pd->va);
 
+   pd->reset.rcdev.owner = THIS_MODULE;
+   pd->reset.rcdev.nr_resets = PRCI_RST_NR;
+   pd->reset.rcdev.ops = _simple_ops;
+   pd->reset.rcdev.of_node = pdev->dev.of_node;
+   pd->reset.active_low = true;
+   pd->reset.membase = pd->va + PRCI_DEVICESRESETREG_OFFSET;
+   spin_lock_init(>reset.lock);
+
+   r = devm_reset_controller_register(>dev, >reset.rcdev);
+   if (r) {
+   dev_err(dev, "could not register reset controller: %d\n", r);
+   return r;
+   }
r = __prci_register_clocks(dev, pd, desc);
if (r) {
dev_err(dev, "could not register clocks: %d\n", r);
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index 022c67cf053c..91658a88af4e 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -121,6 +122,8 @@
 #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK   \
(0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
 
+#define PRCI_RST_NR7
+
 /* CLKMUXSTATUSREG */
 #define PRCI_CLKMUXSTATUSREG_OFFSET0x2c
 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
@@ -221,6 +224,7 @@
  */
 struct __prci_data {
void __iomem *va;
+   struct reset_simple_data reset;
struct clk_hw_onecell_data hw_clks;
 };
 
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 71ab75a46491..d0f5d0afc240 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -187,6 +187,7 @@ config RESET_SIMPLE
   - RCC reset controller in STM32 MCUs
   - Allwinner SoCs
   - ZTE's zx2967 family
+  - SiFive FU740 SoCs
 
 config RESET_STM32MP157
bool "STM32MP157 Reset Driver" if COMPILE_TEST
-- 
2.30.2



[PATCH v4 3/6] MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver

2021-04-01 Thread Greentime Hu
Here add maintainer information for SiFive FU740 PCIe driver.

Signed-off-by: Greentime Hu 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index bfc1b86e3e73..4da888be6e80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13592,6 +13592,14 @@ S: Maintained
 F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 F: drivers/pci/controller/dwc/*imx6*
 
+PCI DRIVER FOR FU740
+M: Paul Walmsley 
+M: Greentime Hu 
+L: linux-...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
+F: drivers/pci/controller/dwc/pcie-fu740.c
+
 PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
 M: Jonathan Derrick 
 L: linux-...@vger.kernel.org
-- 
2.30.2



[PATCH v4 1/6] clk: sifive: Add pcie_aux clock in prci driver for PCIe driver

2021-04-01 Thread Greentime Hu
We add pcie_aux clock in this patch so that pcie driver can use
clk_prepare_enable() and clk_disable_unprepare() to enable and disable
pcie_aux clock.

Signed-off-by: Greentime Hu 
Acked-by: Stephen Boyd 
---
 drivers/clk/sifive/fu740-prci.c   | 11 +
 drivers/clk/sifive/fu740-prci.h   |  2 +-
 drivers/clk/sifive/sifive-prci.c  | 41 +++
 drivers/clk/sifive/sifive-prci.h  |  9 
 include/dt-bindings/clock/sifive-fu740-prci.h |  1 +
 5 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index 764d1097aa51..53f6e00a03b9 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -72,6 +72,12 @@ static const struct clk_ops 
sifive_fu740_prci_hfpclkplldiv_clk_ops = {
.recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
 };
 
+static const struct clk_ops sifive_fu740_prci_pcie_aux_clk_ops = {
+   .enable = sifive_prci_pcie_aux_clock_enable,
+   .disable = sifive_prci_pcie_aux_clock_disable,
+   .is_enabled = sifive_prci_pcie_aux_clock_is_enabled,
+};
+
 /* List of clock controls provided by the PRCI */
 struct __prci_clock __prci_init_clocks_fu740[] = {
[PRCI_CLK_COREPLL] = {
@@ -120,4 +126,9 @@ struct __prci_clock __prci_init_clocks_fu740[] = {
.parent_name = "hfpclkpll",
.ops = _fu740_prci_hfpclkplldiv_clk_ops,
},
+   [PRCI_CLK_PCIE_AUX] = {
+   .name = "pcie_aux",
+   .parent_name = "hfclk",
+   .ops = _fu740_prci_pcie_aux_clk_ops,
+   },
 };
diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h
index 13ef971f7764..511a0bf7ba2b 100644
--- a/drivers/clk/sifive/fu740-prci.h
+++ b/drivers/clk/sifive/fu740-prci.h
@@ -9,7 +9,7 @@
 
 #include "sifive-prci.h"
 
-#define NUM_CLOCK_FU7408
+#define NUM_CLOCK_FU7409
 
 extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740];
 
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index c78b042750e2..8fdba5da2902 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -448,6 +448,47 @@ void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct 
__prci_data *pd)
r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
 }
 
+/* PCIE AUX clock APIs for enable, disable. */
+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r;
+
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET);
+
+   if (r & PRCI_PCIE_AUX_EN_MASK)
+   return 1;
+   else
+   return 0;
+}
+
+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r __maybe_unused;
+
+   if (sifive_prci_pcie_aux_clock_is_enabled(hw))
+   return 0;
+
+   __prci_writel(1, PRCI_PCIE_AUX_OFFSET, pd);
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
+
+   return 0;
+}
+
+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r __maybe_unused;
+
+   __prci_writel(0, PRCI_PCIE_AUX_OFFSET, pd);
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
+
+}
+
 /**
  * __prci_register_clocks() - register clock controls in the PRCI
  * @dev: Linux struct device
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index dbdbd1722688..022c67cf053c 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -67,6 +67,11 @@
 #define PRCI_DDRPLLCFG1_CKE_SHIFT  31
 #define PRCI_DDRPLLCFG1_CKE_MASK   (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
 
+/* PCIEAUX */
+#define PRCI_PCIE_AUX_OFFSET   0x14
+#define PRCI_PCIE_AUX_EN_SHIFT 0
+#define PRCI_PCIE_AUX_EN_MASK  (0x1 << PRCI_PCIE_AUX_EN_SHIFT)
+
 /* GEMGXLPLLCFG0 */
 #define PRCI_GEMGXLPLLCFG0_OFFSET  0x1c
 #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT  0
@@ -296,4 +301,8 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct 
clk_hw *hw,
 unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
   unsigned long parent_rate);
 
+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
+
 #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
diff --git a/include/dt-bindings/clock/sifive-fu740-prci.h 
b/include/dt-bindings/clock/sifive-fu740-prci.h
index cd7706ea5677..7899b7fee7db 100644
--- a/include/dt-bindings/clock/sifive-fu740-prci.h
+

[PATCH v4 0/6] Add SiFive FU740 PCIe host controller driver support

2021-04-01 Thread Greentime Hu
This patchset includes SiFive FU740 PCIe host controller driver. We also
add pcie_aux clock and pcie_power_on_reset controller to prci driver for
PCIe driver to use it.

This is tested with e1000e: Intel(R) PRO/1000 Network Card, AMD Radeon R5
230 graphics card and SP M.2 PCIe Gen 3 SSD in SiFive Unmatched based on
v5.11 Linux kernel.

Changes in v4:
 - Fix Wunused-but-set-variable warning in prci driver

Changes in v3:
 - Remove items that has been defined
 - Refine format of sifive,fu740-pcie.yaml
 - Replace perstn-gpios with the common one
 - Change DBI mapping space to 2GB from 4GB
 - Refine drivers/reset/Kconfig

Changes in v2:
 - Refine codes based on reviewers' feedback
 - Remove define and use the common one
 - Replace __raw_writel with writel_relaxed
 - Split fu740_phyregreadwrite to write function
 - Use readl_poll_timeout in stead of while loop checking
 - Use dwc common codes
 - Use gpio descriptors and the gpiod_* api.
 - Replace devm_ioremap_resource with devm_platform_ioremap_resource_byname
 - Replace devm_reset_control_get with devm_reset_control_get_exclusive
 - Add more comments for delay and sleep
 - Remove "phy ? x : y" expressions
 - Refine code logic to remove possible infinite loop
 - Replace magic number with meaningful define
 - Remove fu740_pcie_pm_ops
 - Use builtin_platform_driver

Greentime Hu (5):
  clk: sifive: Add pcie_aux clock in prci driver for PCIe driver
  clk: sifive: Use reset-simple in prci driver for PCIe driver
  MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver
  dt-bindings: PCI: Add SiFive FU740 PCIe host controller
  riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

Paul Walmsley (1):
  PCI: fu740: Add SiFive FU740 PCIe host controller driver

 .../bindings/pci/sifive,fu740-pcie.yaml   | 109 ++
 MAINTAINERS   |   8 +
 arch/riscv/boot/dts/sifive/fu740-c000.dtsi|  33 ++
 drivers/clk/sifive/Kconfig|   2 +
 drivers/clk/sifive/fu740-prci.c   |  11 +
 drivers/clk/sifive/fu740-prci.h   |   2 +-
 drivers/clk/sifive/sifive-prci.c  |  54 +++
 drivers/clk/sifive/sifive-prci.h  |  13 +
 drivers/pci/controller/dwc/Kconfig|   9 +
 drivers/pci/controller/dwc/Makefile   |   1 +
 drivers/pci/controller/dwc/pcie-fu740.c   | 324 ++
 drivers/reset/Kconfig |   1 +
 include/dt-bindings/clock/sifive-fu740-prci.h |   1 +
 13 files changed, 567 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
 create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c

-- 
2.30.2



[PATCH v3 6/6] riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

2021-03-31 Thread Greentime Hu
Signed-off-by: Greentime Hu 
---
 arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 33 ++
 1 file changed, 33 insertions(+)

diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi 
b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
index d1bb22b11920..b2317c8e3a80 100644
--- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
@@ -158,6 +158,7 @@ prci: clock-controller@1000 {
reg = <0x0 0x1000 0x0 0x1000>;
clocks = <>, <>;
#clock-cells = <1>;
+   #reset-cells = <1>;
};
uart0: serial@1001 {
compatible = "sifive,fu740-c000-uart", "sifive,uart0";
@@ -288,5 +289,37 @@ gpio: gpio@1006 {
clocks = < PRCI_CLK_PCLK>;
status = "disabled";
};
+   pcie@e {
+   compatible = "sifive,fu740-pcie";
+   #address-cells = <3>;
+   #size-cells = <2>;
+   #interrupt-cells = <1>;
+   reg = <0xe 0x 0x0 0x8000>,
+ <0xd 0xf000 0x0 0x1000>,
+ <0x0 0x100d 0x0 0x1000>;
+   reg-names = "dbi", "config", "mgmt";
+   device_type = "pci";
+   dma-coherent;
+   bus-range = <0x0 0xff>;
+   ranges = <0x8100  0x0 0x6008  0x0 0x6008 
0x0 0x1>,  /* I/O */
+<0x8200  0x0 0x6009  0x0 0x6009 
0x0 0xff7>,/* mem */
+<0x8200  0x0 0x7000  0x0 0x7000 
0x0 0x100>,/* mem */
+<0xc300 0x20 0x 0x20 0x 
0x20 0x>;  /* mem prefetchable */
+   num-lanes = <0x8>;
+   interrupts = <56>, <57>, <58>, <59>, <60>, <61>, <62>, 
<63>, <64>;
+   interrupt-names = "msi", "inta", "intb", "intc", "intd";
+   interrupt-parent = <>;
+   interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+   interrupt-map = <0x0 0x0 0x0 0x1  57>,
+   <0x0 0x0 0x0 0x2  58>,
+   <0x0 0x0 0x0 0x3  59>,
+   <0x0 0x0 0x0 0x4  60>;
+   clock-names = "pcie_aux";
+   clocks = < PRCI_CLK_PCIE_AUX>;
+   pwren-gpios = < 5 0>;
+   reset-gpios = < 8 0>;
+   resets = < 4>;
+   status = "okay";
+   };
};
 };
-- 
2.30.2



[PATCH v3 5/6] PCI: fu740: Add SiFive FU740 PCIe host controller driver

2021-03-31 Thread Greentime Hu
From: Paul Walmsley 

Add driver for the SiFive FU740 PCIe host controller.
This controller is based on the DesignWare PCIe core.

Signed-off-by: Paul Walmsley 
Co-developed-by: Henry Styles 
Signed-off-by: Henry Styles 
Co-developed-by: Erik Danie 
Signed-off-by: Erik Danie 
Co-developed-by: Greentime Hu 
Signed-off-by: Greentime Hu 
---
 drivers/pci/controller/dwc/Kconfig  |   9 +
 drivers/pci/controller/dwc/Makefile |   1 +
 drivers/pci/controller/dwc/pcie-fu740.c | 324 
 3 files changed, 334 insertions(+)
 create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c

diff --git a/drivers/pci/controller/dwc/Kconfig 
b/drivers/pci/controller/dwc/Kconfig
index 22c5529e9a65..0a37d21ed64e 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -318,4 +318,13 @@ config PCIE_AL
  required only for DT-based platforms. ACPI platforms with the
  Annapurna Labs PCIe controller don't need to enable this.
 
+config PCIE_FU740
+   bool "SiFive FU740 PCIe host controller"
+   depends on PCI_MSI_IRQ_DOMAIN
+   depends on SOC_SIFIVE || COMPILE_TEST
+   select PCIE_DW_HOST
+   help
+ Say Y here if you want PCIe controller support for the SiFive
+ FU740.
+
 endmenu
diff --git a/drivers/pci/controller/dwc/Makefile 
b/drivers/pci/controller/dwc/Makefile
index a751553fa0db..625f6aaeb5b8 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
 obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
+obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
 obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
diff --git a/drivers/pci/controller/dwc/pcie-fu740.c 
b/drivers/pci/controller/dwc/pcie-fu740.c
new file mode 100644
index ..ebbcbda97490
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-fu740.c
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FU740 DesignWare PCIe Controller integration
+ * Copyright (C) 2019-2021 SiFive, Inc.
+ * Paul Walmsley
+ * Greentime Hu
+ *
+ * Based in part on the i.MX6 PCIe host controller shim which is:
+ *
+ * Copyright (C) 2013 Kosagi
+ * https://www.kosagi.com
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pcie-designware.h"
+
+#define to_fu740_pcie(x)   dev_get_drvdata((x)->dev)
+
+struct fu740_pcie {
+   struct dw_pcie pci;
+   void __iomem *mgmt_base;
+   struct gpio_desc *reset;
+   struct gpio_desc *pwren;
+   struct clk *pcie_aux;
+   struct reset_control *rst;
+};
+
+#define SIFIVE_DEVICESRESETREG 0x28
+
+#define PCIEX8MGMT_PERST_N 0x0
+#define PCIEX8MGMT_APP_LTSSM_ENABLE0x10
+#define PCIEX8MGMT_APP_HOLD_PHY_RST0x18
+#define PCIEX8MGMT_DEVICE_TYPE 0x708
+#define PCIEX8MGMT_PHY0_CR_PARA_ADDR   0x860
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN  0x870
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA0x878
+#define PCIEX8MGMT_PHY0_CR_PARA_SEL0x880
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA0x888
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN  0x890
+#define PCIEX8MGMT_PHY0_CR_PARA_ACK0x898
+#define PCIEX8MGMT_PHY1_CR_PARA_ADDR   0x8a0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN  0x8b0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA0x8b8
+#define PCIEX8MGMT_PHY1_CR_PARA_SEL0x8c0
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA0x8c8
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN  0x8d0
+#define PCIEX8MGMT_PHY1_CR_PARA_ACK0x8d8
+
+#define PCIEX8MGMT_PHY_CDR_TRACK_ENBIT(0)
+#define PCIEX8MGMT_PHY_LOS_THRSHLD BIT(5)
+#define PCIEX8MGMT_PHY_TERM_EN BIT(9)
+#define PCIEX8MGMT_PHY_TERM_ACDC   BIT(10)
+#define PCIEX8MGMT_PHY_EN  BIT(11)
+#define PCIEX8MGMT_PHY_INIT_VAL(PCIEX8MGMT_PHY_CDR_TRACK_EN|\
+PCIEX8MGMT_PHY_LOS_THRSHLD|\
+PCIEX8MGMT_PHY_TERM_EN|\
+PCIEX8MGMT_PHY_TERM_ACDC|\
+PCIEX8MGMT_PHY_EN)
+
+#define PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 0x1008
+#define PCIEX8MGMT_PHY_LANE_OFF0x100
+#define PCIEX8MGMT_PHY_LANE0_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 0)
+#define PCIEX8MGMT_PHY_LANE1_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 1)
+#define PCIEX8MGMT_PHY_LANE2_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 2)
+#define PCIEX8MGMT_PHY_LANE3_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 3)
+
+static void fu740_pcie_assert_

[PATCH v3 3/6] MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver

2021-03-31 Thread Greentime Hu
Here add maintainer information for SiFive FU740 PCIe driver.

Signed-off-by: Greentime Hu 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index bfc1b86e3e73..4da888be6e80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13592,6 +13592,14 @@ S: Maintained
 F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 F: drivers/pci/controller/dwc/*imx6*
 
+PCI DRIVER FOR FU740
+M: Paul Walmsley 
+M: Greentime Hu 
+L: linux-...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
+F: drivers/pci/controller/dwc/pcie-fu740.c
+
 PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
 M: Jonathan Derrick 
 L: linux-...@vger.kernel.org
-- 
2.30.2



[PATCH v3 4/6] dt-bindings: PCI: Add SiFive FU740 PCIe host controller

2021-03-31 Thread Greentime Hu
Add PCIe host controller DT bindings of SiFive FU740.

Signed-off-by: Greentime Hu 
---
 .../bindings/pci/sifive,fu740-pcie.yaml   | 109 ++
 1 file changed, 109 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml 
b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
new file mode 100644
index ..ccb58e5f06d4
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/sifive,fu740-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive FU740 PCIe host controller
+
+description: |+
+  SiFive FU740 PCIe host controller is based on the Synopsys DesignWare
+  PCI core. It shares common features with the PCIe DesignWare core and
+  inherits common properties defined in
+  Documentation/devicetree/bindings/pci/designware-pcie.txt.
+
+maintainers:
+  - Paul Walmsley 
+  - Greentime Hu 
+
+allOf:
+  - $ref: /schemas/pci/pci-bus.yaml#
+
+properties:
+  compatible:
+const: sifive,fu740-pcie
+
+  reg:
+maxItems: 3
+
+  reg-names:
+items:
+  - const: dbi
+  - const: config
+  - const: mgmt
+
+  num-lanes:
+const: 8
+
+  msi-parent: true
+
+  interrupt-names:
+items:
+  - const: msi
+  - const: inta
+  - const: intb
+  - const: intc
+  - const: intd
+
+  resets:
+description: A phandle to the PCIe power up reset line.
+
+  pwren-gpios:
+description: Should specify the GPIO for controlling the PCI bus device 
power on.
+maxItems: 1
+
+required:
+  - dma-coherent
+  - num-lanes
+  - interrupts
+  - interrupt-names
+  - interrupt-parent
+  - interrupt-map-mask
+  - interrupt-map
+  - clock-names
+  - clocks
+  - resets
+  - pwren-gpios
+  - reset-gpios
+
+unevaluatedProperties: false
+
+examples:
+  - |
+bus {
+#address-cells = <2>;
+#size-cells = <2>;
+#include 
+
+pcie@e {
+compatible = "sifive,fu740-pcie";
+#address-cells = <3>;
+#size-cells = <2>;
+#interrupt-cells = <1>;
+reg = <0xe 0x 0x0 0x8000>,
+  <0xd 0xf000 0x0 0x1000>,
+  <0x0 0x100d 0x0 0x1000>;
+reg-names = "dbi", "config", "mgmt";
+device_type = "pci";
+dma-coherent;
+bus-range = <0x0 0xff>;
+ranges = <0x8100  0x0 0x6008  0x0 0x6008 0x0 0x1>, 
 /* I/O */
+ <0x8200  0x0 0x6009  0x0 0x6009 0x0 
0xff7>,/* mem */
+ <0x8200  0x0 0x7000  0x0 0x7000 0x0 
0x100>,/* mem */
+ <0xc300 0x20 0x 0x20 0x 0x20 
0x>;  /* mem prefetchable */
+num-lanes = <0x8>;
+interrupts = <56>, <57>, <58>, <59>, <60>, <61>, <62>, <63>, <64>;
+interrupt-names = "msi", "inta", "intb", "intc", "intd";
+interrupt-parent = <>;
+interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+interrupt-map = <0x0 0x0 0x0 0x1  57>,
+<0x0 0x0 0x0 0x2  58>,
+<0x0 0x0 0x0 0x3  59>,
+<0x0 0x0 0x0 0x4  60>;
+clock-names = "pcie_aux";
+clocks = < PRCI_CLK_PCIE_AUX>;
+resets = < 4>;
+pwren-gpios = < 5 0>;
+reset-gpios = < 8 0>;
+};
+};
-- 
2.30.2



[PATCH v3 2/6] clk: sifive: Use reset-simple in prci driver for PCIe driver

2021-03-31 Thread Greentime Hu
We use reset-simple in this patch so that pcie driver can use
devm_reset_control_get() to get this reset data structure and use
reset_control_deassert() to deassert pcie_power_up_rst_n.

Reviewed-by: Philipp Zabel 
Signed-off-by: Greentime Hu 
---
 drivers/clk/sifive/Kconfig   |  2 ++
 drivers/clk/sifive/sifive-prci.c | 13 +
 drivers/clk/sifive/sifive-prci.h |  4 
 drivers/reset/Kconfig|  1 +
 4 files changed, 20 insertions(+)

diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
index 1c14eb20c066..9132c3c4aa86 100644
--- a/drivers/clk/sifive/Kconfig
+++ b/drivers/clk/sifive/Kconfig
@@ -10,6 +10,8 @@ if CLK_SIFIVE
 
 config CLK_SIFIVE_PRCI
bool "PRCI driver for SiFive SoCs"
+   select RESET_CONTROLLER
+   select RESET_SIMPLE
select CLK_ANALOGBITS_WRPLL_CLN28HPC
help
  Supports the Power Reset Clock interface (PRCI) IP block found in
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index baf7313dac92..871ccb287993 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -583,6 +583,19 @@ static int sifive_prci_probe(struct platform_device *pdev)
if (IS_ERR(pd->va))
return PTR_ERR(pd->va);
 
+   pd->reset.rcdev.owner = THIS_MODULE;
+   pd->reset.rcdev.nr_resets = PRCI_RST_NR;
+   pd->reset.rcdev.ops = _simple_ops;
+   pd->reset.rcdev.of_node = pdev->dev.of_node;
+   pd->reset.active_low = true;
+   pd->reset.membase = pd->va + PRCI_DEVICESRESETREG_OFFSET;
+   spin_lock_init(>reset.lock);
+
+   r = devm_reset_controller_register(>dev, >reset.rcdev);
+   if (r) {
+   dev_err(dev, "could not register reset controller: %d\n", r);
+   return r;
+   }
r = __prci_register_clocks(dev, pd, desc);
if (r) {
dev_err(dev, "could not register clocks: %d\n", r);
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index 022c67cf053c..91658a88af4e 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -121,6 +122,8 @@
 #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK   \
(0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
 
+#define PRCI_RST_NR7
+
 /* CLKMUXSTATUSREG */
 #define PRCI_CLKMUXSTATUSREG_OFFSET0x2c
 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
@@ -221,6 +224,7 @@
  */
 struct __prci_data {
void __iomem *va;
+   struct reset_simple_data reset;
struct clk_hw_onecell_data hw_clks;
 };
 
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 71ab75a46491..d0f5d0afc240 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -187,6 +187,7 @@ config RESET_SIMPLE
   - RCC reset controller in STM32 MCUs
   - Allwinner SoCs
   - ZTE's zx2967 family
+  - SiFive FU740 SoCs
 
 config RESET_STM32MP157
bool "STM32MP157 Reset Driver" if COMPILE_TEST
-- 
2.30.2



[PATCH v3 1/6] clk: sifive: Add pcie_aux clock in prci driver for PCIe driver

2021-03-31 Thread Greentime Hu
We add pcie_aux clock in this patch so that pcie driver can use
clk_prepare_enable() and clk_disable_unprepare() to enable and disable
pcie_aux clock.

Signed-off-by: Greentime Hu 
---
 drivers/clk/sifive/fu740-prci.c   | 11 +
 drivers/clk/sifive/fu740-prci.h   |  2 +-
 drivers/clk/sifive/sifive-prci.c  | 41 +++
 drivers/clk/sifive/sifive-prci.h  |  9 
 include/dt-bindings/clock/sifive-fu740-prci.h |  1 +
 5 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index 764d1097aa51..53f6e00a03b9 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -72,6 +72,12 @@ static const struct clk_ops 
sifive_fu740_prci_hfpclkplldiv_clk_ops = {
.recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
 };
 
+static const struct clk_ops sifive_fu740_prci_pcie_aux_clk_ops = {
+   .enable = sifive_prci_pcie_aux_clock_enable,
+   .disable = sifive_prci_pcie_aux_clock_disable,
+   .is_enabled = sifive_prci_pcie_aux_clock_is_enabled,
+};
+
 /* List of clock controls provided by the PRCI */
 struct __prci_clock __prci_init_clocks_fu740[] = {
[PRCI_CLK_COREPLL] = {
@@ -120,4 +126,9 @@ struct __prci_clock __prci_init_clocks_fu740[] = {
.parent_name = "hfpclkpll",
.ops = _fu740_prci_hfpclkplldiv_clk_ops,
},
+   [PRCI_CLK_PCIE_AUX] = {
+   .name = "pcie_aux",
+   .parent_name = "hfclk",
+   .ops = _fu740_prci_pcie_aux_clk_ops,
+   },
 };
diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h
index 13ef971f7764..511a0bf7ba2b 100644
--- a/drivers/clk/sifive/fu740-prci.h
+++ b/drivers/clk/sifive/fu740-prci.h
@@ -9,7 +9,7 @@
 
 #include "sifive-prci.h"
 
-#define NUM_CLOCK_FU7408
+#define NUM_CLOCK_FU7409
 
 extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740];
 
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index c78b042750e2..baf7313dac92 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -448,6 +448,47 @@ void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct 
__prci_data *pd)
r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
 }
 
+/* PCIE AUX clock APIs for enable, disable. */
+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r;
+
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET);
+
+   if (r & PRCI_PCIE_AUX_EN_MASK)
+   return 1;
+   else
+   return 0;
+}
+
+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r;
+
+   if (sifive_prci_pcie_aux_clock_is_enabled(hw))
+   return 0;
+
+   __prci_writel(1, PRCI_PCIE_AUX_OFFSET, pd);
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
+
+   return 0;
+}
+
+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r;
+
+   __prci_writel(0, PRCI_PCIE_AUX_OFFSET, pd);
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
+
+}
+
 /**
  * __prci_register_clocks() - register clock controls in the PRCI
  * @dev: Linux struct device
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index dbdbd1722688..022c67cf053c 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -67,6 +67,11 @@
 #define PRCI_DDRPLLCFG1_CKE_SHIFT  31
 #define PRCI_DDRPLLCFG1_CKE_MASK   (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
 
+/* PCIEAUX */
+#define PRCI_PCIE_AUX_OFFSET   0x14
+#define PRCI_PCIE_AUX_EN_SHIFT 0
+#define PRCI_PCIE_AUX_EN_MASK  (0x1 << PRCI_PCIE_AUX_EN_SHIFT)
+
 /* GEMGXLPLLCFG0 */
 #define PRCI_GEMGXLPLLCFG0_OFFSET  0x1c
 #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT  0
@@ -296,4 +301,8 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct 
clk_hw *hw,
 unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
   unsigned long parent_rate);
 
+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
+
 #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
diff --git a/include/dt-bindings/clock/sifive-fu740-prci.h 
b/include/dt-bindings/clock/sifive-fu740-prci.h
index cd7706ea5677..7899b7fee7db 100644
--- a/include/dt-bindings/clock/sifive-fu740-prci.h
+++ b/include/dt-bindings/clock/sifive-fu740-prci.h
@@

[PATCH v3 0/6] Add SiFive FU740 PCIe host controller driver support

2021-03-31 Thread Greentime Hu
This patchset includes SiFive FU740 PCIe host controller driver. We also
add pcie_aux clock and pcie_power_on_reset controller to prci driver for
PCIe driver to use it.

This is tested with e1000e: Intel(R) PRO/1000 Network Card, AMD Radeon R5
230 graphics card and SP M.2 PCIe Gen 3 SSD in SiFive Unmatched based on
v5.11 Linux kernel.

Changes in v3:
 - Remove items that has been defined
 - Refine format of sifive,fu740-pcie.yaml
 - Replace perstn-gpios with the common one
 - Change DBI mapping space to 2GB from 4GB
 - Refine drivers/reset/Kconfig

Changes in v2:
 - Refine codes based on reviewers' feedback
 - Remove define and use the common one
 - Replace __raw_writel with writel_relaxed
 - Split fu740_phyregreadwrite to write function
 - Use readl_poll_timeout in stead of while loop checking
 - Use dwc common codes
 - Use gpio descriptors and the gpiod_* api.
 - Replace devm_ioremap_resource with devm_platform_ioremap_resource_byname
 - Replace devm_reset_control_get with devm_reset_control_get_exclusive
 - Add more comments for delay and sleep
 - Remove "phy ? x : y" expressions
 - Refine code logic to remove possible infinite loop
 - Replace magic number with meaningful define
 - Remove fu740_pcie_pm_ops
 - Use builtin_platform_driver

Greentime Hu (5):
  clk: sifive: Add pcie_aux clock in prci driver for PCIe driver
  clk: sifive: Use reset-simple in prci driver for PCIe driver
  MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver
  dt-bindings: PCI: Add SiFive FU740 PCIe host controller
  riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

Paul Walmsley (1):
  PCI: fu740: Add SiFive FU740 PCIe host controller driver

 .../bindings/pci/sifive,fu740-pcie.yaml   | 109 ++
 MAINTAINERS   |   8 +
 arch/riscv/boot/dts/sifive/fu740-c000.dtsi|  33 ++
 drivers/clk/sifive/Kconfig|   2 +
 drivers/clk/sifive/fu740-prci.c   |  11 +
 drivers/clk/sifive/fu740-prci.h   |   2 +-
 drivers/clk/sifive/sifive-prci.c  |  54 +++
 drivers/clk/sifive/sifive-prci.h  |  13 +
 drivers/pci/controller/dwc/Kconfig|   9 +
 drivers/pci/controller/dwc/Makefile   |   1 +
 drivers/pci/controller/dwc/pcie-fu740.c   | 324 ++
 drivers/reset/Kconfig |   1 +
 include/dt-bindings/clock/sifive-fu740-prci.h |   1 +
 13 files changed, 567 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
 create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c

-- 
2.30.2



Re: [PATCH] nds32: flush_dcache_page: use page_mapping_file to avoid races with swapoff

2021-03-31 Thread Greentime Hu
Greentime Hu  於 2021年3月31日 週三 下午3:30寫道:
>
> Matthew Wilcox  於 2021年3月31日 週三 上午2:14寫道:
> >
> > On Tue, Mar 30, 2021 at 08:51:26PM +0300, Mike Rapoport wrote:
> > > From: Mike Rapoport 
> > >
> > > Commit cb9f753a3731 ("mm: fix races between swapoff and flush dcache")
> > > updated flush_dcache_page implementations on several architectures to use
> > > page_mapping_file() in order to avoid races between page_mapping() and
> > > swapoff().
> > >
> > > This update missed arch/nds32 and there is a possibility of a race there.
> > >
> > > Replace page_mapping() with page_mapping_file() in nds32 implementation of
> > > flush_dcache_page().
> > >
> > > Fixes: cb9f753a3731 ("mm: fix races between swapoff and flush dcache")
> > > Signed-off-by: Mike Rapoport 
> >
> > Reviewed-by: Matthew Wilcox (Oracle) 
>
> Acked-by: Greentiime Hu 
Typo.
Acked-by: Greentime Hu 


Re: [PATCH] nds32: flush_dcache_page: use page_mapping_file to avoid races with swapoff

2021-03-31 Thread Greentime Hu
Matthew Wilcox  於 2021年3月31日 週三 上午2:14寫道:
>
> On Tue, Mar 30, 2021 at 08:51:26PM +0300, Mike Rapoport wrote:
> > From: Mike Rapoport 
> >
> > Commit cb9f753a3731 ("mm: fix races between swapoff and flush dcache")
> > updated flush_dcache_page implementations on several architectures to use
> > page_mapping_file() in order to avoid races between page_mapping() and
> > swapoff().
> >
> > This update missed arch/nds32 and there is a possibility of a race there.
> >
> > Replace page_mapping() with page_mapping_file() in nds32 implementation of
> > flush_dcache_page().
> >
> > Fixes: cb9f753a3731 ("mm: fix races between swapoff and flush dcache")
> > Signed-off-by: Mike Rapoport 
>
> Reviewed-by: Matthew Wilcox (Oracle) 

Acked-by: Greentiime Hu 


Re: [PATCH v2 2/6] clk: sifive: Use reset-simple in prci driver for PCIe driver

2021-03-29 Thread Greentime Hu
Stephen Boyd  於 2021年3月30日 週二 上午3:14寫道:
>
> Quoting Greentime Hu (2021-03-17 23:08:09)
> > diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
> > index 71ab75a46491..f094df93d911 100644
> > --- a/drivers/reset/Kconfig
> > +++ b/drivers/reset/Kconfig
> > @@ -173,7 +173,7 @@ config RESET_SCMI
> >
> >  config RESET_SIMPLE
> > bool "Simple Reset Controller Driver" if COMPILE_TEST
> > -   default ARCH_AGILEX || ARCH_ASPEED || ARCH_BITMAIN || ARCH_REALTEK 
> > || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARC
> > +   default ARCH_AGILEX || ARCH_ASPEED || ARCH_BITMAIN || ARCH_REALTEK 
> > || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARC || RISCV
>
> This conflicts. Can this default be part of the riscv defconfig instead?
>

Maybe I should remove this since it has been selected by CLK_SIFIVE_PRCI?

 config CLK_SIFIVE_PRCI
bool "PRCI driver for SiFive SoCs"
+   select RESET_CONTROLLER
+   select RESET_SIMPLE

> > help
> >   This enables a simple reset controller driver for reset lines that
> >   that can be asserted and deasserted by toggling bits in a 
> > contiguous,
> > @@ -187,6 +187,7 @@ config RESET_SIMPLE
> >- RCC reset controller in STM32 MCUs
> >- Allwinner SoCs
> >- ZTE's zx2967 family
> > +  - SiFive FU740 SoCs
> >
> >  config RESET_STM32MP157
> > bool "STM32MP157 Reset Driver" if COMPILE_TEST


Re: [PATCH v2 4/6] dt-bindings: PCI: Add SiFive FU740 PCIe host controller

2021-03-28 Thread Greentime Hu
Rob Herring  於 2021年3月24日 週三 上午4:35寫道:
>
> On Thu, Mar 18, 2021 at 02:08:11PM +0800, Greentime Hu wrote:
> > Add PCIe host controller DT bindings of SiFive FU740.
> >
> > Signed-off-by: Greentime Hu 
> > ---
> >  .../bindings/pci/sifive,fu740-pcie.yaml   | 119 ++
> >  1 file changed, 119 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
[...]
> > +examples:
> > +  - |
> > +pcie@e {
> > +#address-cells = <3>;
> > +#interrupt-cells = <1>;
> > +#size-cells = <2>;
> > +compatible = "sifive,fu740-pcie";
> > +reg = <0xe 0x 0x1 0x0
>
> Humm, 4GB for DBI space? The DWC controller doesn't have that much
> space, and the kernel will map *all* of that. That's not an
> insignificant amount of memory just for page tables.

Thank you for review and point this out. :)

I check the spec description for DBI in DWC_pcie_ctl_dm_databook.pdf
section 3.15 3.16 and table 3-17.

I think CX_SRIOV_ENABLE and CX_ARI_ENABLE will be set to 0 because
these 2 are endpoint mode features.
Single Root I/O Virtualization (SR-IOV) This section describes the
SR-IOV features implemented in EP mode. The parameter for enabling
SR-IOV is CX_SRIOV_ENABLE
Alternative Routing-ID Interpretation (ARI) ARI allows an endpoint to
support more than eight physical functions (PFs). ARI is enabled by
the CX_ARI_ENABLE parameter.

So based on Table 3-17, we will need to map 2GB(bit30) instead of 4GB(bit31).


[PATCH v2 0/6] Add SiFive FU740 PCIe host controller driver support

2021-03-18 Thread Greentime Hu
This patchset includes SiFive FU740 PCIe host controller driver. We also
add pcie_aux clock and pcie_power_on_reset controller to prci driver for
PCIe driver to use it.

This is tested with e1000e: Intel(R) PRO/1000 Network Card, AMD Radeon R5
230 graphics card and SP M.2 PCIe Gen 3 SSD in SiFive Unmatched based on
v5.11 Linux kernel.

Changes in v2:
 - Refine codes based on reviewers' feedback
 - Remove define and use the common one
 - Replace __raw_writel with writel_relaxed
 - Split fu740_phyregreadwrite to write function
 - Use readl_poll_timeout in stead of while loop checking
 - Use dwc common codes
 - Use gpio descriptors and the gpiod_* api.
 - Replace devm_ioremap_resource with devm_platform_ioremap_resource_byname
 - Replace devm_reset_control_get with devm_reset_control_get_exclusive
 - Add more comments for delay and sleep
 - Remove "phy ? x : y" expressions
 - Refine code logic to remove possible infinite loop
 - Replace magic number with meaningful define
 - Remove fu740_pcie_pm_ops
 - Use builtin_platform_driver

Greentime Hu (5):
  clk: sifive: Add pcie_aux clock in prci driver for PCIe driver
  clk: sifive: Use reset-simple in prci driver for PCIe driver
  MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver
  dt-bindings: PCI: Add SiFive FU740 PCIe host controller
  riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

Paul Walmsley (1):
  PCI: fu740: Add SiFive FU740 PCIe host controller driver

 .../bindings/pci/sifive,fu740-pcie.yaml   | 119 +++
 MAINTAINERS   |   8 +
 arch/riscv/boot/dts/sifive/fu740-c000.dtsi|  34 ++
 drivers/clk/sifive/Kconfig|   2 +
 drivers/clk/sifive/fu740-prci.c   |  11 +
 drivers/clk/sifive/fu740-prci.h   |   2 +-
 drivers/clk/sifive/sifive-prci.c  |  54 +++
 drivers/clk/sifive/sifive-prci.h  |  13 +
 drivers/pci/controller/dwc/Kconfig|   9 +
 drivers/pci/controller/dwc/Makefile   |   1 +
 drivers/pci/controller/dwc/pcie-fu740.c   | 324 ++
 drivers/reset/Kconfig |   3 +-
 include/dt-bindings/clock/sifive-fu740-prci.h |   1 +
 13 files changed, 579 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
 create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c

-- 
2.30.2



[PATCH v2 3/6] MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver

2021-03-18 Thread Greentime Hu
Here add maintainer information for SiFive FU740 PCIe driver.

Signed-off-by: Greentime Hu 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index bfc1b86e3e73..4da888be6e80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13592,6 +13592,14 @@ S: Maintained
 F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 F: drivers/pci/controller/dwc/*imx6*
 
+PCI DRIVER FOR FU740
+M: Paul Walmsley 
+M: Greentime Hu 
+L: linux-...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
+F: drivers/pci/controller/dwc/pcie-fu740.c
+
 PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
 M: Jonathan Derrick 
 L: linux-...@vger.kernel.org
-- 
2.30.2



[PATCH v2 6/6] riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

2021-03-18 Thread Greentime Hu
Signed-off-by: Greentime Hu 
---
 arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi 
b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
index d1bb22b11920..d0839739b425 100644
--- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
@@ -158,6 +158,7 @@ prci: clock-controller@1000 {
reg = <0x0 0x1000 0x0 0x1000>;
clocks = <>, <>;
#clock-cells = <1>;
+   #reset-cells = <1>;
};
uart0: serial@1001 {
compatible = "sifive,fu740-c000-uart", "sifive,uart0";
@@ -288,5 +289,38 @@ gpio: gpio@1006 {
clocks = < PRCI_CLK_PCLK>;
status = "disabled";
};
+   pcie@e {
+   #address-cells = <3>;
+   #interrupt-cells = <1>;
+   #num-lanes = <8>;
+   #size-cells = <2>;
+   compatible = "sifive,fu740-pcie";
+   reg = <0xe 0x 0x1 0x0
+  0xd 0xf000 0x0 0x1000
+  0x0 0x100d 0x0 0x1000>;
+   reg-names = "dbi", "config", "mgmt";
+   device_type = "pci";
+   dma-coherent;
+   bus-range = <0x0 0xff>;
+   ranges = <0x8100  0x0 0x6008  0x0 0x6008 
0x0 0x1/* I/O */
+ 0x8200  0x0 0x6009  0x0 0x6009 
0x0 0xff7  /* mem */
+ 0x8200  0x0 0x7000  0x0 0x7000 
0x0 0x100  /* mem */
+ 0xc300 0x20 0x 0x20 0x 
0x20 0x>;  /* mem prefetchable */
+   num-lanes = <0x8>;
+   interrupts = <56 57 58 59 60 61 62 63 64>;
+   interrupt-names = "msi", "inta", "intb", "intc", "intd";
+   interrupt-parent = <>;
+   interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+   interrupt-map = <0x0 0x0 0x0 0x1  57>,
+   <0x0 0x0 0x0 0x2  58>,
+   <0x0 0x0 0x0 0x3  59>,
+   <0x0 0x0 0x0 0x4  60>;
+   clock-names = "pcie_aux";
+   clocks = < PRCI_CLK_PCIE_AUX>;
+   pwren-gpios = < 5 0>;
+   perstn-gpios = < 8 0>;
+   resets = < 4>;
+   status = "okay";
+   };
};
 };
-- 
2.30.2



[PATCH v2 4/6] dt-bindings: PCI: Add SiFive FU740 PCIe host controller

2021-03-18 Thread Greentime Hu
Add PCIe host controller DT bindings of SiFive FU740.

Signed-off-by: Greentime Hu 
---
 .../bindings/pci/sifive,fu740-pcie.yaml   | 119 ++
 1 file changed, 119 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml 
b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
new file mode 100644
index ..c25a91b18cd7
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/sifive,fu740-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive fu740 PCIe host controller
+
+description:
+  SiFive fu740 PCIe host controller is based on the Synopsys DesignWare
+  PCI core. It shares common features with the PCIe DesignWare core and
+  inherits common properties defined in
+  Documentation/devicetree/bindings/pci/designware-pcie.txt.
+
+maintainers:
+  - Paul Walmsley 
+  - Greentime Hu 
+
+allOf:
+  - $ref: /schemas/pci/pci-bus.yaml#
+
+properties:
+  compatible:
+const: sifive,fu740-pcie
+
+  reg:
+maxItems: 4
+
+  reg-names:
+items:
+  - const: dbi
+  - const: config
+  - const: mgmt
+
+  device_type:
+const: pci
+
+  dma-coherent:
+description: Indicates that the PCIe IP block can ensure the coherency
+
+  bus-range:
+description: Range of bus numbers associated with this controller.
+
+  num-lanes: true
+
+  msi-parent: true
+
+  interrupt-names:
+items:
+  - const: msi
+  - const: inta
+  - const: intb
+  - const: intc
+  - const: intd
+
+  resets:
+description: A phandle to the PCIe power up reset line
+
+  pwren-gpios:
+description: Should specify the GPIO for controlling the PCI bus device 
power on
+
+  perstn-gpios:
+description: Should specify the GPIO for controlling the PCI bus device 
reset
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - device_type
+  - dma-coherent
+  - bus-range
+  - ranges
+  - num-lanes
+  - interrupts
+  - interrupt-names
+  - interrupt-parent
+  - interrupt-map-mask
+  - interrupt-map
+  - clock-names
+  - clocks
+  - resets
+  - pwren-gpios
+  - perstn-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+pcie@e {
+#address-cells = <3>;
+#interrupt-cells = <1>;
+#size-cells = <2>;
+compatible = "sifive,fu740-pcie";
+reg = <0xe 0x 0x1 0x0
+   0xd 0xf000 0x0 0x1000
+   0x0 0x100d 0x0 0x1000>;
+reg-names = "dbi", "config", "mgmt";
+device_type = "pci";
+dma-coherent;
+bus-range = <0x0 0xff>;
+ranges = <0x8100  0x0 0x6008  0x0 0x6008 0x0 0x1   
 /* I/O */
+  0x8200  0x0 0x6009  0x0 0x6009 0x0 0xff7 
 /* mem */
+  0x8200  0x0 0x7000  0x0 0x7000 0x0 0x100 
 /* mem */
+  0xc300 0x20 0x 0x20 0x 0x20 0x>; 
 /* mem prefetchable */
+num-lanes = <0x8>;
+interrupts = <56 57 58 59 60 61 62 63 64>;
+interrupt-names = "msi", "inta", "intb", "intc", "intd";
+interrupt-parent = <>;
+interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+interrupt-map = <0x0 0x0 0x0 0x1  57>,
+<0x0 0x0 0x0 0x2  58>,
+<0x0 0x0 0x0 0x3  59>,
+<0x0 0x0 0x0 0x4  60>;
+clock-names = "pcie_aux";
+clocks = < PRCI_CLK_PCIE_AUX>;
+resets = < 4>;
+pwren-gpios = < 5 0>;
+perstn-gpios = < 8 0>;
+};
-- 
2.30.2



[PATCH v2 5/6] PCI: fu740: Add SiFive FU740 PCIe host controller driver

2021-03-18 Thread Greentime Hu
From: Paul Walmsley 

Add driver for the SiFive FU740 PCIe host controller.
This controller is based on the DesignWare PCIe core.

Signed-off-by: Paul Walmsley 
Co-developed-by: Henry Styles 
Signed-off-by: Henry Styles 
Co-developed-by: Erik Danie 
Signed-off-by: Erik Danie 
Co-developed-by: Greentime Hu 
Signed-off-by: Greentime Hu 
---
 drivers/pci/controller/dwc/Kconfig  |   9 +
 drivers/pci/controller/dwc/Makefile |   1 +
 drivers/pci/controller/dwc/pcie-fu740.c | 324 
 3 files changed, 334 insertions(+)
 create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c

diff --git a/drivers/pci/controller/dwc/Kconfig 
b/drivers/pci/controller/dwc/Kconfig
index 22c5529e9a65..0a37d21ed64e 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -318,4 +318,13 @@ config PCIE_AL
  required only for DT-based platforms. ACPI platforms with the
  Annapurna Labs PCIe controller don't need to enable this.
 
+config PCIE_FU740
+   bool "SiFive FU740 PCIe host controller"
+   depends on PCI_MSI_IRQ_DOMAIN
+   depends on SOC_SIFIVE || COMPILE_TEST
+   select PCIE_DW_HOST
+   help
+ Say Y here if you want PCIe controller support for the SiFive
+ FU740.
+
 endmenu
diff --git a/drivers/pci/controller/dwc/Makefile 
b/drivers/pci/controller/dwc/Makefile
index a751553fa0db..625f6aaeb5b8 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
 obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
+obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
 obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
diff --git a/drivers/pci/controller/dwc/pcie-fu740.c 
b/drivers/pci/controller/dwc/pcie-fu740.c
new file mode 100644
index ..65ca4c212fc3
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-fu740.c
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FU740 DesignWare PCIe Controller integration
+ * Copyright (C) 2019-2021 SiFive, Inc.
+ * Paul Walmsley
+ * Greentime Hu
+ *
+ * Based in part on the i.MX6 PCIe host controller shim which is:
+ *
+ * Copyright (C) 2013 Kosagi
+ * https://www.kosagi.com
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pcie-designware.h"
+
+#define to_fu740_pcie(x)   dev_get_drvdata((x)->dev)
+
+struct fu740_pcie {
+   struct dw_pcie pci;
+   void __iomem *mgmt_base;
+   struct gpio_desc *perstn;
+   struct gpio_desc *pwren;
+   struct clk *pcie_aux;
+   struct reset_control *rst;
+};
+
+#define SIFIVE_DEVICESRESETREG 0x28
+
+#define PCIEX8MGMT_PERST_N 0x0
+#define PCIEX8MGMT_APP_LTSSM_ENABLE0x10
+#define PCIEX8MGMT_APP_HOLD_PHY_RST0x18
+#define PCIEX8MGMT_DEVICE_TYPE 0x708
+#define PCIEX8MGMT_PHY0_CR_PARA_ADDR   0x860
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN  0x870
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA0x878
+#define PCIEX8MGMT_PHY0_CR_PARA_SEL0x880
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA0x888
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN  0x890
+#define PCIEX8MGMT_PHY0_CR_PARA_ACK0x898
+#define PCIEX8MGMT_PHY1_CR_PARA_ADDR   0x8a0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN  0x8b0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA0x8b8
+#define PCIEX8MGMT_PHY1_CR_PARA_SEL0x8c0
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA0x8c8
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN  0x8d0
+#define PCIEX8MGMT_PHY1_CR_PARA_ACK0x8d8
+
+#define PCIEX8MGMT_PHY_CDR_TRACK_ENBIT(0)
+#define PCIEX8MGMT_PHY_LOS_THRSHLD BIT(5)
+#define PCIEX8MGMT_PHY_TERM_EN BIT(9)
+#define PCIEX8MGMT_PHY_TERM_ACDC   BIT(10)
+#define PCIEX8MGMT_PHY_EN  BIT(11)
+#define PCIEX8MGMT_PHY_INIT_VAL(PCIEX8MGMT_PHY_CDR_TRACK_EN|\
+PCIEX8MGMT_PHY_LOS_THRSHLD|\
+PCIEX8MGMT_PHY_TERM_EN|\
+PCIEX8MGMT_PHY_TERM_ACDC|\
+PCIEX8MGMT_PHY_EN)
+
+#define PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 0x1008
+#define PCIEX8MGMT_PHY_LANE_OFF0x100
+#define PCIEX8MGMT_PHY_LANE0_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 0)
+#define PCIEX8MGMT_PHY_LANE1_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 1)
+#define PCIEX8MGMT_PHY_LANE2_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 2)
+#define PCIEX8MGMT_PHY_LANE3_BASE  
(PCIEX8MGMT_PHY_LANEN_DIG_ASIC_RX_OVRD_IN_3 + 0x100 * 3)
+
+static void fu740_pc

[PATCH v2 2/6] clk: sifive: Use reset-simple in prci driver for PCIe driver

2021-03-18 Thread Greentime Hu
We use reset-simple in this patch so that pcie driver can use
devm_reset_control_get() to get this reset data structure and use
reset_control_deassert() to deassert pcie_power_up_rst_n.

Reviewed-by: Philipp Zabel 
Signed-off-by: Greentime Hu 
---
 drivers/clk/sifive/Kconfig   |  2 ++
 drivers/clk/sifive/sifive-prci.c | 13 +
 drivers/clk/sifive/sifive-prci.h |  4 
 drivers/reset/Kconfig|  3 ++-
 4 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
index 1c14eb20c066..9132c3c4aa86 100644
--- a/drivers/clk/sifive/Kconfig
+++ b/drivers/clk/sifive/Kconfig
@@ -10,6 +10,8 @@ if CLK_SIFIVE
 
 config CLK_SIFIVE_PRCI
bool "PRCI driver for SiFive SoCs"
+   select RESET_CONTROLLER
+   select RESET_SIMPLE
select CLK_ANALOGBITS_WRPLL_CLN28HPC
help
  Supports the Power Reset Clock interface (PRCI) IP block found in
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index baf7313dac92..871ccb287993 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -583,6 +583,19 @@ static int sifive_prci_probe(struct platform_device *pdev)
if (IS_ERR(pd->va))
return PTR_ERR(pd->va);
 
+   pd->reset.rcdev.owner = THIS_MODULE;
+   pd->reset.rcdev.nr_resets = PRCI_RST_NR;
+   pd->reset.rcdev.ops = _simple_ops;
+   pd->reset.rcdev.of_node = pdev->dev.of_node;
+   pd->reset.active_low = true;
+   pd->reset.membase = pd->va + PRCI_DEVICESRESETREG_OFFSET;
+   spin_lock_init(>reset.lock);
+
+   r = devm_reset_controller_register(>dev, >reset.rcdev);
+   if (r) {
+   dev_err(dev, "could not register reset controller: %d\n", r);
+   return r;
+   }
r = __prci_register_clocks(dev, pd, desc);
if (r) {
dev_err(dev, "could not register clocks: %d\n", r);
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index 022c67cf053c..91658a88af4e 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -121,6 +122,8 @@
 #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK   \
(0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
 
+#define PRCI_RST_NR7
+
 /* CLKMUXSTATUSREG */
 #define PRCI_CLKMUXSTATUSREG_OFFSET0x2c
 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
@@ -221,6 +224,7 @@
  */
 struct __prci_data {
void __iomem *va;
+   struct reset_simple_data reset;
struct clk_hw_onecell_data hw_clks;
 };
 
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 71ab75a46491..f094df93d911 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -173,7 +173,7 @@ config RESET_SCMI
 
 config RESET_SIMPLE
bool "Simple Reset Controller Driver" if COMPILE_TEST
-   default ARCH_AGILEX || ARCH_ASPEED || ARCH_BITMAIN || ARCH_REALTEK || 
ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARC
+   default ARCH_AGILEX || ARCH_ASPEED || ARCH_BITMAIN || ARCH_REALTEK || 
ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARC || RISCV
help
  This enables a simple reset controller driver for reset lines that
  that can be asserted and deasserted by toggling bits in a contiguous,
@@ -187,6 +187,7 @@ config RESET_SIMPLE
   - RCC reset controller in STM32 MCUs
   - Allwinner SoCs
   - ZTE's zx2967 family
+  - SiFive FU740 SoCs
 
 config RESET_STM32MP157
bool "STM32MP157 Reset Driver" if COMPILE_TEST
-- 
2.30.2



[PATCH v2 1/6] clk: sifive: Add pcie_aux clock in prci driver for PCIe driver

2021-03-18 Thread Greentime Hu
We add pcie_aux clock in this patch so that pcie driver can use
clk_prepare_enable() and clk_disable_unprepare() to enable and disable
pcie_aux clock.

Signed-off-by: Greentime Hu 
---
 drivers/clk/sifive/fu740-prci.c   | 11 +
 drivers/clk/sifive/fu740-prci.h   |  2 +-
 drivers/clk/sifive/sifive-prci.c  | 41 +++
 drivers/clk/sifive/sifive-prci.h  |  9 
 include/dt-bindings/clock/sifive-fu740-prci.h |  1 +
 5 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index 764d1097aa51..53f6e00a03b9 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -72,6 +72,12 @@ static const struct clk_ops 
sifive_fu740_prci_hfpclkplldiv_clk_ops = {
.recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
 };
 
+static const struct clk_ops sifive_fu740_prci_pcie_aux_clk_ops = {
+   .enable = sifive_prci_pcie_aux_clock_enable,
+   .disable = sifive_prci_pcie_aux_clock_disable,
+   .is_enabled = sifive_prci_pcie_aux_clock_is_enabled,
+};
+
 /* List of clock controls provided by the PRCI */
 struct __prci_clock __prci_init_clocks_fu740[] = {
[PRCI_CLK_COREPLL] = {
@@ -120,4 +126,9 @@ struct __prci_clock __prci_init_clocks_fu740[] = {
.parent_name = "hfpclkpll",
.ops = _fu740_prci_hfpclkplldiv_clk_ops,
},
+   [PRCI_CLK_PCIE_AUX] = {
+   .name = "pcie_aux",
+   .parent_name = "hfclk",
+   .ops = _fu740_prci_pcie_aux_clk_ops,
+   },
 };
diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h
index 13ef971f7764..511a0bf7ba2b 100644
--- a/drivers/clk/sifive/fu740-prci.h
+++ b/drivers/clk/sifive/fu740-prci.h
@@ -9,7 +9,7 @@
 
 #include "sifive-prci.h"
 
-#define NUM_CLOCK_FU7408
+#define NUM_CLOCK_FU7409
 
 extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740];
 
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index c78b042750e2..baf7313dac92 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -448,6 +448,47 @@ void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct 
__prci_data *pd)
r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
 }
 
+/* PCIE AUX clock APIs for enable, disable. */
+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r;
+
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET);
+
+   if (r & PRCI_PCIE_AUX_EN_MASK)
+   return 1;
+   else
+   return 0;
+}
+
+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r;
+
+   if (sifive_prci_pcie_aux_clock_is_enabled(hw))
+   return 0;
+
+   __prci_writel(1, PRCI_PCIE_AUX_OFFSET, pd);
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
+
+   return 0;
+}
+
+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r;
+
+   __prci_writel(0, PRCI_PCIE_AUX_OFFSET, pd);
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
+
+}
+
 /**
  * __prci_register_clocks() - register clock controls in the PRCI
  * @dev: Linux struct device
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index dbdbd1722688..022c67cf053c 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -67,6 +67,11 @@
 #define PRCI_DDRPLLCFG1_CKE_SHIFT  31
 #define PRCI_DDRPLLCFG1_CKE_MASK   (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
 
+/* PCIEAUX */
+#define PRCI_PCIE_AUX_OFFSET   0x14
+#define PRCI_PCIE_AUX_EN_SHIFT 0
+#define PRCI_PCIE_AUX_EN_MASK  (0x1 << PRCI_PCIE_AUX_EN_SHIFT)
+
 /* GEMGXLPLLCFG0 */
 #define PRCI_GEMGXLPLLCFG0_OFFSET  0x1c
 #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT  0
@@ -296,4 +301,8 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct 
clk_hw *hw,
 unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
   unsigned long parent_rate);
 
+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
+
 #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
diff --git a/include/dt-bindings/clock/sifive-fu740-prci.h 
b/include/dt-bindings/clock/sifive-fu740-prci.h
index cd7706ea5677..7899b7fee7db 100644
--- a/include/dt-bindings/clock/sifive-fu740-prci.h
+++ b/include/dt-bindings/clock/sifive-fu740-prci.h
@@

Re: [RFC PATCH 2/6] clk: sifive: Use reset-simple in prci driver for PCIe driver

2021-03-08 Thread Greentime Hu
Philipp Zabel  於 2021年3月4日 週四 下午7:58寫道:
>
> On Tue, 2021-03-02 at 18:59 +0800, Greentime Hu wrote:
> > We use reset-simple in this patch so that pcie driver can use
> > devm_reset_control_get() to get this reset data structure and use
> > reset_control_deassert() to deassert pcie_power_up_rst_n.
> >
> > Signed-off-by: Greentime Hu 
> > ---
> >  drivers/clk/sifive/Kconfig   |  2 ++
> >  drivers/clk/sifive/sifive-prci.c | 14 ++
> >  drivers/clk/sifive/sifive-prci.h |  4 
> >  drivers/reset/Kconfig|  3 ++-
> >  4 files changed, 22 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
> > index 1c14eb20c066..9132c3c4aa86 100644
> > --- a/drivers/clk/sifive/Kconfig
> > +++ b/drivers/clk/sifive/Kconfig
> > @@ -10,6 +10,8 @@ if CLK_SIFIVE
> >
> >  config CLK_SIFIVE_PRCI
> >   bool "PRCI driver for SiFive SoCs"
> > + select RESET_CONTROLLER
> > + select RESET_SIMPLE
> >   select CLK_ANALOGBITS_WRPLL_CLN28HPC
> >   help
> > Supports the Power Reset Clock interface (PRCI) IP block found in
> > diff --git a/drivers/clk/sifive/sifive-prci.c 
> > b/drivers/clk/sifive/sifive-prci.c
> > index baf7313dac92..925affc6de55 100644
> > --- a/drivers/clk/sifive/sifive-prci.c
> > +++ b/drivers/clk/sifive/sifive-prci.c
> > @@ -583,7 +583,21 @@ static int sifive_prci_probe(struct platform_device 
> > *pdev)
> >   if (IS_ERR(pd->va))
> >   return PTR_ERR(pd->va);
> >
> > + pd->reset.rcdev.owner = THIS_MODULE;
> > + pd->reset.rcdev.nr_resets = PRCI_RST_NR;
> > + pd->reset.rcdev.ops = _simple_ops;
> > + pd->reset.rcdev.of_node = pdev->dev.of_node;
> > + pd->reset.active_low = true;
> > + pd->reset.membase = pd->va + PRCI_DEVICESRESETREG_OFFSET;
> > + spin_lock_init(>reset.lock);
> > +
> > + r = devm_reset_controller_register(>dev, >reset.rcdev);
> > + if (r) {
> > + dev_err(dev, "could not register reset controller: %d\n", r);
> > + return r;
> > + }
> >   r = __prci_register_clocks(dev, pd, desc);
> > +
>
> Accidental whitespace?
>
> Otherwise,
>
> Reviewed-by: Philipp Zabel 

Thank you, Philipp.
Yes, it is an accidental whitespace. I'll remove it in my next version patch.


[RFC PATCH 5/6] PCI: designware: Add SiFive FU740 PCIe host controller driver

2021-03-02 Thread Greentime Hu
From: Paul Walmsley 

Add driver for the SiFive FU740 PCIe host controller.
This controller is based on the DesignWare PCIe core.

Co-developed-by: Henry Styles 
Signed-off-by: Henry Styles 
Co-developed-by: Erik Danie 
Signed-off-by: Erik Danie 
Co-developed-by: Greentime Hu 
Signed-off-by: Greentime Hu 
Signed-off-by: Paul Walmsley 
---
 drivers/pci/controller/dwc/Kconfig  |   9 +
 drivers/pci/controller/dwc/Makefile |   1 +
 drivers/pci/controller/dwc/pcie-fu740.c | 455 
 3 files changed, 465 insertions(+)
 create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c

diff --git a/drivers/pci/controller/dwc/Kconfig 
b/drivers/pci/controller/dwc/Kconfig
index 22c5529e9a65..0a37d21ed64e 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -318,4 +318,13 @@ config PCIE_AL
  required only for DT-based platforms. ACPI platforms with the
  Annapurna Labs PCIe controller don't need to enable this.
 
+config PCIE_FU740
+   bool "SiFive FU740 PCIe host controller"
+   depends on PCI_MSI_IRQ_DOMAIN
+   depends on SOC_SIFIVE || COMPILE_TEST
+   select PCIE_DW_HOST
+   help
+ Say Y here if you want PCIe controller support for the SiFive
+ FU740.
+
 endmenu
diff --git a/drivers/pci/controller/dwc/Makefile 
b/drivers/pci/controller/dwc/Makefile
index a751553fa0db..625f6aaeb5b8 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
 obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
+obj-$(CONFIG_PCIE_FU740) += pcie-fu740.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
 obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
diff --git a/drivers/pci/controller/dwc/pcie-fu740.c 
b/drivers/pci/controller/dwc/pcie-fu740.c
new file mode 100644
index ..6916eea40ea5
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-fu740.c
@@ -0,0 +1,455 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * FU740 DesignWare PCIe Controller integration
+ * Copyright (C) 2019-2021 SiFive, Inc.
+ * Paul Walmsley
+ * Greentime Hu
+ *
+ * Based in part on the i.MX6 PCIe host controller shim which is:
+ *
+ * Copyright (C) 2013 Kosagi
+ * https://www.kosagi.com
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "pcie-designware.h"
+
+#define to_fu740_pcie(x)   dev_get_drvdata((x)->dev)
+
+struct fu740_pcie {
+   struct dw_pcie *pci;
+   void __iomem *mgmt_base;
+   int perstn_gpio;
+   int pwren_gpio;
+   struct clk *pcie_aux;
+   struct reset_control *rst;
+};
+
+#define SIFIVE_DEVICESRESETREG 0x28
+
+#define PCIEX8MGMT_PERST_N 0x0
+#define PCIEX8MGMT_APP_LTSSM_ENABLE0x10
+#define PCIEX8MGMT_APP_HOLD_PHY_RST0x18
+#define PCIEX8MGMT_DEVICE_TYPE 0x708
+#define PCIEX8MGMT_PHY0_CR_PARA_ADDR   0x860
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_EN  0x870
+#define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA0x878
+#define PCIEX8MGMT_PHY0_CR_PARA_SEL0x880
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA0x888
+#define PCIEX8MGMT_PHY0_CR_PARA_WR_EN  0x890
+#define PCIEX8MGMT_PHY0_CR_PARA_ACK0x898
+#define PCIEX8MGMT_PHY1_CR_PARA_ADDR   0x8a0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_EN  0x8b0
+#define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA0x8b8
+#define PCIEX8MGMT_PHY1_CR_PARA_SEL0x8c0
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA0x8c8
+#define PCIEX8MGMT_PHY1_CR_PARA_WR_EN  0x8d0
+#define PCIEX8MGMT_PHY1_CR_PARA_ACK0x8d8
+
+/* PCIe Port Logic registers (memory-mapped) */
+#define PL_OFFSET  0x700
+#define PCIE_PL_GEN2_CTRL_OFF  (PL_OFFSET + 0x10c)
+#define PCIE_PL_DIRECTED_SPEED_CHANGE_OFF  0x2
+
+#define PCIE_PHY_MAX_RETRY_CNT 1000
+
+static void fu740_pcie_assert_perstn(struct fu740_pcie *afp)
+{
+   /* PERST_N GPIO */
+   if (gpio_is_valid(afp->perstn_gpio))
+   gpio_direction_output(afp->perstn_gpio, 0);
+
+   /* Controller PERST_N */
+   __raw_writel(0x0, afp->mgmt_base + PCIEX8MGMT_PERST_N);
+}
+
+static void fu740_pcie_deassert_perstn(struct fu740_pcie *afp)
+{
+   /* Controller PERST_N */
+   __raw_writel(0x1, afp->mgmt_base + PCIEX8MGMT_PERST_N);
+   /* PERST_N GPIO */
+   if (gpio_is_valid(afp->perstn_gpio))
+   gpio_direction_output(afp->perstn_gpio, 1);
+}
+
+static void fu740_pcie_power_on(struct fu740_pcie *afp)
+{

[RFC PATCH 6/6] riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

2021-03-02 Thread Greentime Hu
Signed-off-by: Greentime Hu 
---
 arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi 
b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
index d1bb22b11920..d0839739b425 100644
--- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
@@ -158,6 +158,7 @@ prci: clock-controller@1000 {
reg = <0x0 0x1000 0x0 0x1000>;
clocks = <>, <>;
#clock-cells = <1>;
+   #reset-cells = <1>;
};
uart0: serial@1001 {
compatible = "sifive,fu740-c000-uart", "sifive,uart0";
@@ -288,5 +289,38 @@ gpio: gpio@1006 {
clocks = < PRCI_CLK_PCLK>;
status = "disabled";
};
+   pcie@e {
+   #address-cells = <3>;
+   #interrupt-cells = <1>;
+   #num-lanes = <8>;
+   #size-cells = <2>;
+   compatible = "sifive,fu740-pcie";
+   reg = <0xe 0x 0x1 0x0
+  0xd 0xf000 0x0 0x1000
+  0x0 0x100d 0x0 0x1000>;
+   reg-names = "dbi", "config", "mgmt";
+   device_type = "pci";
+   dma-coherent;
+   bus-range = <0x0 0xff>;
+   ranges = <0x8100  0x0 0x6008  0x0 0x6008 
0x0 0x1/* I/O */
+ 0x8200  0x0 0x6009  0x0 0x6009 
0x0 0xff7  /* mem */
+ 0x8200  0x0 0x7000  0x0 0x7000 
0x0 0x100  /* mem */
+ 0xc300 0x20 0x 0x20 0x 
0x20 0x>;  /* mem prefetchable */
+   num-lanes = <0x8>;
+   interrupts = <56 57 58 59 60 61 62 63 64>;
+   interrupt-names = "msi", "inta", "intb", "intc", "intd";
+   interrupt-parent = <>;
+   interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+   interrupt-map = <0x0 0x0 0x0 0x1  57>,
+   <0x0 0x0 0x0 0x2  58>,
+   <0x0 0x0 0x0 0x3  59>,
+   <0x0 0x0 0x0 0x4  60>;
+   clock-names = "pcie_aux";
+   clocks = < PRCI_CLK_PCIE_AUX>;
+   pwren-gpios = < 5 0>;
+   perstn-gpios = < 8 0>;
+   resets = < 4>;
+   status = "okay";
+   };
};
 };
-- 
2.30.0



[RFC PATCH 4/6] dt-bindings: PCI: Add SiFive FU740 PCIe host controller

2021-03-02 Thread Greentime Hu
Add PCIe host controller DT bindings of SiFive FU740.

Signed-off-by: Greentime Hu 
---
 .../bindings/pci/sifive,fu740-pcie.yaml   | 119 ++
 1 file changed, 119 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml 
b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
new file mode 100644
index ..879ab4f80456
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/sifive,fu740-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive fu740 PCIe host controller
+
+description: |
+  SiFive fu740 PCIe host controller is based on the Synopsys DesignWare
+  PCI core. It shares common features with the PCIe DesignWare core and
+  inherits common properties defined in
+  Documentation/devicetree/bindings/pci/designware-pcie.txt.
+
+maintainers:
+  - Paul Walmsley 
+  - Greentime Hu 
+
+allOf:
+  - $ref: /schemas/pci/pci-bus.yaml#
+
+properties:
+  compatible:
+const: sifive,fu740-pcie
+
+  reg:
+maxItems: 4
+
+  reg-names:
+items:
+  - const: dbi
+  - const: config
+  - const: mgmt
+
+  device_type:
+const: pci
+
+  dma-coherent:
+description: Indicates that the PCIe IP block can ensure the coherency
+
+  bus-range:
+description: Range of bus numbers associated with this controller.
+
+  num-lanes: true
+
+  msi-parent: true
+
+  interrupt-names:
+items:
+  - const: msi
+  - const: inta
+  - const: intb
+  - const: intc
+  - const: intd
+
+  resets:
+description: A phandle to the PCIe power up reset line
+
+  pwren-gpios:
+description: Should specify the GPIO for controlling the PCI bus device 
power on
+
+  perstn-gpios:
+description: Should specify the GPIO for controlling the PCI bus device 
reset
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - device_type
+  - dma-coherent
+  - bus-range
+  - ranges
+  - num-lanes
+  - interrupts
+  - interrupt-names
+  - interrupt-parent
+  - interrupt-map-mask
+  - interrupt-map
+  - clock-names
+  - clocks
+  - resets
+  - pwren-gpios
+  - perstn-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+pcie@e {
+#address-cells = <3>;
+#interrupt-cells = <1>;
+#size-cells = <2>;
+compatible = "sifive,fu740-pcie";
+reg = <0xe 0x 0x1 0x0
+   0xd 0xf000 0x0 0x1000
+   0x0 0x100d 0x0 0x1000>;
+reg-names = "dbi", "config", "mgmt";
+device_type = "pci";
+dma-coherent;
+bus-range = <0x0 0xff>;
+ranges = <0x8100  0x0 0x6008  0x0 0x6008 0x0 0x1   
 /* I/O */
+  0x8200  0x0 0x6009  0x0 0x6009 0x0 0xff7 
 /* mem */
+  0x8200  0x0 0x7000  0x0 0x7000 0x0 0x100 
 /* mem */
+  0xc300 0x20 0x 0x20 0x 0x20 0x>; 
 /* mem prefetchable */
+num-lanes = <0x8>;
+interrupts = <56 57 58 59 60 61 62 63 64>;
+interrupt-names = "msi", "inta", "intb", "intc", "intd";
+interrupt-parent = <>;
+interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+interrupt-map = <0x0 0x0 0x0 0x1  57>,
+<0x0 0x0 0x0 0x2  58>,
+<0x0 0x0 0x0 0x3  59>,
+<0x0 0x0 0x0 0x4  60>;
+   clock-names = "pcie_aux";
+clocks = < PRCI_CLK_PCIE_AUX>;
+resets = < 4>;
+pwren-gpios = < 5 0>;
+perstn-gpios = < 8 0>;
+};
-- 
2.30.0



[RFC PATCH 2/6] clk: sifive: Use reset-simple in prci driver for PCIe driver

2021-03-02 Thread Greentime Hu
We use reset-simple in this patch so that pcie driver can use
devm_reset_control_get() to get this reset data structure and use
reset_control_deassert() to deassert pcie_power_up_rst_n.

Signed-off-by: Greentime Hu 
---
 drivers/clk/sifive/Kconfig   |  2 ++
 drivers/clk/sifive/sifive-prci.c | 14 ++
 drivers/clk/sifive/sifive-prci.h |  4 
 drivers/reset/Kconfig|  3 ++-
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sifive/Kconfig b/drivers/clk/sifive/Kconfig
index 1c14eb20c066..9132c3c4aa86 100644
--- a/drivers/clk/sifive/Kconfig
+++ b/drivers/clk/sifive/Kconfig
@@ -10,6 +10,8 @@ if CLK_SIFIVE
 
 config CLK_SIFIVE_PRCI
bool "PRCI driver for SiFive SoCs"
+   select RESET_CONTROLLER
+   select RESET_SIMPLE
select CLK_ANALOGBITS_WRPLL_CLN28HPC
help
  Supports the Power Reset Clock interface (PRCI) IP block found in
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index baf7313dac92..925affc6de55 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -583,7 +583,21 @@ static int sifive_prci_probe(struct platform_device *pdev)
if (IS_ERR(pd->va))
return PTR_ERR(pd->va);
 
+   pd->reset.rcdev.owner = THIS_MODULE;
+   pd->reset.rcdev.nr_resets = PRCI_RST_NR;
+   pd->reset.rcdev.ops = _simple_ops;
+   pd->reset.rcdev.of_node = pdev->dev.of_node;
+   pd->reset.active_low = true;
+   pd->reset.membase = pd->va + PRCI_DEVICESRESETREG_OFFSET;
+   spin_lock_init(>reset.lock);
+
+   r = devm_reset_controller_register(>dev, >reset.rcdev);
+   if (r) {
+   dev_err(dev, "could not register reset controller: %d\n", r);
+   return r;
+   }
r = __prci_register_clocks(dev, pd, desc);
+
if (r) {
dev_err(dev, "could not register clocks: %d\n", r);
return r;
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index 022c67cf053c..91658a88af4e 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -11,6 +11,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -121,6 +122,8 @@
 #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK   \
(0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT)
 
+#define PRCI_RST_NR7
+
 /* CLKMUXSTATUSREG */
 #define PRCI_CLKMUXSTATUSREG_OFFSET0x2c
 #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1
@@ -221,6 +224,7 @@
  */
 struct __prci_data {
void __iomem *va;
+   struct reset_simple_data reset;
struct clk_hw_onecell_data hw_clks;
 };
 
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 71ab75a46491..f094df93d911 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -173,7 +173,7 @@ config RESET_SCMI
 
 config RESET_SIMPLE
bool "Simple Reset Controller Driver" if COMPILE_TEST
-   default ARCH_AGILEX || ARCH_ASPEED || ARCH_BITMAIN || ARCH_REALTEK || 
ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARC
+   default ARCH_AGILEX || ARCH_ASPEED || ARCH_BITMAIN || ARCH_REALTEK || 
ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARC || RISCV
help
  This enables a simple reset controller driver for reset lines that
  that can be asserted and deasserted by toggling bits in a contiguous,
@@ -187,6 +187,7 @@ config RESET_SIMPLE
   - RCC reset controller in STM32 MCUs
   - Allwinner SoCs
   - ZTE's zx2967 family
+  - SiFive FU740 SoCs
 
 config RESET_STM32MP157
bool "STM32MP157 Reset Driver" if COMPILE_TEST
-- 
2.30.0



[RFC PATCH 3/6] MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver

2021-03-02 Thread Greentime Hu
Here add maintainer information for SiFive FU740 PCIe driver.

Signed-off-by: Greentime Hu 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index bfc1b86e3e73..4da888be6e80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13592,6 +13592,14 @@ S: Maintained
 F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt
 F: drivers/pci/controller/dwc/*imx6*
 
+PCI DRIVER FOR FU740
+M: Paul Walmsley 
+M: Greentime Hu 
+L: linux-...@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
+F: drivers/pci/controller/dwc/pcie-fu740.c
+
 PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD)
 M: Jonathan Derrick 
 L: linux-...@vger.kernel.org
-- 
2.30.0



[RFC PATCH 0/6] Add SiFive FU740 PCIe host controller driver support

2021-03-02 Thread Greentime Hu
This patchset includes SiFive FU740 PCIe host controller driver. We also
add pcie_aux clock and pcie_power_on_reset controller to prci driver for
PCIe driver to use it.

This is tested with e1000e: Intel(R) PRO/1000 Network Card and SP M.2 PCIe
Gen 3 SSD in SiFive Unmatched.

Greentime Hu (5):
  clk: sifive: Add pcie_aux clock in prci driver for PCIe driver
  clk: sifive: Use reset-simple in prci driver for PCIe driver
  MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver
  dt-bindings: PCI: Add SiFive FU740 PCIe host controller
  riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC

Paul Walmsley (1):
  PCI: designware: Add SiFive FU740 PCIe host controller driver

 .../bindings/pci/sifive,fu740-pcie.yaml   | 119 +
 MAINTAINERS   |   8 +
 arch/riscv/boot/dts/sifive/fu740-c000.dtsi|  34 ++
 drivers/clk/sifive/Kconfig|   2 +
 drivers/clk/sifive/fu740-prci.c   |  11 +
 drivers/clk/sifive/fu740-prci.h   |   2 +-
 drivers/clk/sifive/sifive-prci.c  |  55 +++
 drivers/clk/sifive/sifive-prci.h  |  13 +
 drivers/pci/controller/dwc/Kconfig|   9 +
 drivers/pci/controller/dwc/Makefile   |   1 +
 drivers/pci/controller/dwc/pcie-fu740.c   | 455 ++
 drivers/reset/Kconfig |   3 +-
 include/dt-bindings/clock/sifive-fu740-prci.h |   1 +
 13 files changed, 711 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
 create mode 100644 drivers/pci/controller/dwc/pcie-fu740.c

-- 
2.30.0



[RFC PATCH 1/6] clk: sifive: Add pcie_aux clock in prci driver for PCIe driver

2021-03-02 Thread Greentime Hu
We add pcie_aux clock in this patch so that pcie driver can use
clk_prepare_enable() and clk_disable_unprepare() to enable and disable
pcie_aux clock.

Signed-off-by: Greentime Hu 
---
 drivers/clk/sifive/fu740-prci.c   | 11 +
 drivers/clk/sifive/fu740-prci.h   |  2 +-
 drivers/clk/sifive/sifive-prci.c  | 41 +++
 drivers/clk/sifive/sifive-prci.h  |  9 
 include/dt-bindings/clock/sifive-fu740-prci.h |  1 +
 5 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c
index 764d1097aa51..53f6e00a03b9 100644
--- a/drivers/clk/sifive/fu740-prci.c
+++ b/drivers/clk/sifive/fu740-prci.c
@@ -72,6 +72,12 @@ static const struct clk_ops 
sifive_fu740_prci_hfpclkplldiv_clk_ops = {
.recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate,
 };
 
+static const struct clk_ops sifive_fu740_prci_pcie_aux_clk_ops = {
+   .enable = sifive_prci_pcie_aux_clock_enable,
+   .disable = sifive_prci_pcie_aux_clock_disable,
+   .is_enabled = sifive_prci_pcie_aux_clock_is_enabled,
+};
+
 /* List of clock controls provided by the PRCI */
 struct __prci_clock __prci_init_clocks_fu740[] = {
[PRCI_CLK_COREPLL] = {
@@ -120,4 +126,9 @@ struct __prci_clock __prci_init_clocks_fu740[] = {
.parent_name = "hfpclkpll",
.ops = _fu740_prci_hfpclkplldiv_clk_ops,
},
+   [PRCI_CLK_PCIE_AUX] = {
+   .name = "pcie_aux",
+   .parent_name = "hfclk",
+   .ops = _fu740_prci_pcie_aux_clk_ops,
+   },
 };
diff --git a/drivers/clk/sifive/fu740-prci.h b/drivers/clk/sifive/fu740-prci.h
index 13ef971f7764..511a0bf7ba2b 100644
--- a/drivers/clk/sifive/fu740-prci.h
+++ b/drivers/clk/sifive/fu740-prci.h
@@ -9,7 +9,7 @@
 
 #include "sifive-prci.h"
 
-#define NUM_CLOCK_FU7408
+#define NUM_CLOCK_FU7409
 
 extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740];
 
diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c
index c78b042750e2..baf7313dac92 100644
--- a/drivers/clk/sifive/sifive-prci.c
+++ b/drivers/clk/sifive/sifive-prci.c
@@ -448,6 +448,47 @@ void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct 
__prci_data *pd)
r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */
 }
 
+/* PCIE AUX clock APIs for enable, disable. */
+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r;
+
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET);
+
+   if (r & PRCI_PCIE_AUX_EN_MASK)
+   return 1;
+   else
+   return 0;
+}
+
+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r;
+
+   if (sifive_prci_pcie_aux_clock_is_enabled(hw))
+   return 0;
+
+   __prci_writel(1, PRCI_PCIE_AUX_OFFSET, pd);
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
+
+   return 0;
+}
+
+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw)
+{
+   struct __prci_clock *pc = clk_hw_to_prci_clock(hw);
+   struct __prci_data *pd = pc->pd;
+   u32 r;
+
+   __prci_writel(0, PRCI_PCIE_AUX_OFFSET, pd);
+   r = __prci_readl(pd, PRCI_PCIE_AUX_OFFSET); /* barrier */
+
+}
+
 /**
  * __prci_register_clocks() - register clock controls in the PRCI
  * @dev: Linux struct device
diff --git a/drivers/clk/sifive/sifive-prci.h b/drivers/clk/sifive/sifive-prci.h
index dbdbd1722688..022c67cf053c 100644
--- a/drivers/clk/sifive/sifive-prci.h
+++ b/drivers/clk/sifive/sifive-prci.h
@@ -67,6 +67,11 @@
 #define PRCI_DDRPLLCFG1_CKE_SHIFT  31
 #define PRCI_DDRPLLCFG1_CKE_MASK   (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT)
 
+/* PCIEAUX */
+#define PRCI_PCIE_AUX_OFFSET   0x14
+#define PRCI_PCIE_AUX_EN_SHIFT 0
+#define PRCI_PCIE_AUX_EN_MASK  (0x1 << PRCI_PCIE_AUX_EN_SHIFT)
+
 /* GEMGXLPLLCFG0 */
 #define PRCI_GEMGXLPLLCFG0_OFFSET  0x1c
 #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT  0
@@ -296,4 +301,8 @@ unsigned long sifive_prci_tlclksel_recalc_rate(struct 
clk_hw *hw,
 unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw,
   unsigned long parent_rate);
 
+int sifive_prci_pcie_aux_clock_is_enabled(struct clk_hw *hw);
+int sifive_prci_pcie_aux_clock_enable(struct clk_hw *hw);
+void sifive_prci_pcie_aux_clock_disable(struct clk_hw *hw);
+
 #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
diff --git a/include/dt-bindings/clock/sifive-fu740-prci.h 
b/include/dt-bindings/clock/sifive-fu740-prci.h
index cd7706ea5677..7899b7fee7db 100644
--- a/include/dt-bindings/clock/sifive-fu740-prci.h
+++ b/include/dt-bindings/clock/sifive-fu740-prci.h
@@

[GIT PULL] nds32 patches for 5.12-rc1

2021-02-24 Thread Greentime Hu
Hi Linus

Please pull the arch/nds32 updates for v5.12-rc1.
Thank you.

The following changes since commit f40ddce88593482919761f74910f42f4b84c004b:

  Linux 5.11 (2021-02-14 14:32:24 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/greentime/linux.git
tags/nds32-for-linux-5.12

for you to fetch changes up to 40e0dd851e7b7afe219820fb270b09016e41d4fc:

  nds32: Fix bogus reference to  (2021-02-25 14:31:49 +0800)


nds32 patches for 5.12

Here is the nds32 patchset based on 5.11
Contained in here are
1. code clean up
2. code refine


Christoph Hellwig (2):
  nds32: remove dump_instr
  nds32: use get_kernel_nofault in dump_mem

Geert Uytterhoeven (2):
  nds32: Replace  by 
  nds32: Fix bogus reference to 

Krzysztof Kozlowski (1):
  nds32: configs: Cleanup CONFIG_CROSS_COMPILE

 arch/nds32/configs/defconfig |  1 -
 arch/nds32/kernel/setup.c|  2 +-
 arch/nds32/kernel/time.c |  2 +-
 arch/nds32/kernel/traps.c| 50
+++---
 4 files changed, 5 insertions(+), 50 deletions(-)


Re: [PATCH 2/2] nds32: use get_kernel_nofault in dump_mem

2021-02-24 Thread Greentime Hu
Christoph Hellwig  於 2021年2月24日 週三 下午3:47寫道:
>
> On Thu, Jan 28, 2021 at 11:16:33AM +0100, Christoph Hellwig wrote:
> > On Tue, Jul 21, 2020 at 01:28:00PM +0200, Christoph Hellwig wrote:
> > > Can you pich the patches up in the nds32 tree for Linus?  There are
> > > not short-term dependencies on them.
> >
> > It seems like these patches are still sitting in linux-next and never
> > made it to Linus/
>
> ping?

Sorry for late.
Acked-by: Greentime Hu 


Re: [PATCH v3 0/5] Improve kernel section protections

2020-11-23 Thread Greentime Hu
Atish Patra  於 2020年11月5日 週四 上午8:05寫道:
>
> This series aims at improving kernel permissions by doing following things.
>
> 1. Protect kernel sections early instead of after /init.
> 2. Protect .init.text & .init.data sections with appropriate permissions.
> 3. Move dynamic relocation section to _init.
> 4. Moved .init sections after .text. This is what most of the other archs
>are also doing.
>
> After applying this patch, here are the linear mapped sections with non-uefi 
> boot.
>
> ---[ Linear mapping ]---
> 0xffe0-0xffe000800x8020 8M PMD
>  D A . . X . R V
> 0xffe00080-0xffe000c00x80a0 4M PMD
>  D A . . . W R V
> 0xffe000c0-0xffe001200x80e0 6M PMD
>  D A . . . . R V
> 0xffe00120-0xffe03fe00x8140  1004M PMD
>  D A . . . W R V
>
> Linear mapping with uefi boot.
>
> ---[ Linear mapping ]---
> 0xffe0-0xffe000800x8020 8M PTE
>  D A . . X . R V
> 0xffe00080-0xffe000c00x80a0 4M PTE
>  D A . . . W R V
> 0xffe000c0-0xffe001200x80e0 6M PTE
>  D A . . . . R V
> 0xffe00120-0xffe03e5340000x8140   1002704K PTE
>  D A . . . W R V
> 0xffe03e538000-0xffe03e5390000xbe738000 4K PTE
>  D A . . . W R V
> 0xffe03e53a000-0xffe03e53c0000xbe73a000 8K PTE
>  D A . . . W R V
> 0xffe03e54-0xffe03e5410000xbe74 4K PTE
>  D A . . . W R V
> 0xffe03e545000-0xffe03e5460000xbe745000 4K PTE
>  D A . . . W R V
> 0xffe03e549000-0xffe03e54a0000xbe749000 4K PTE
>  D A . . . W R V
> 0xffe03e54b000-0xffe03fd6d0000xbe74b000 24712K PTE
>  D A . . . W R V
> 0xffe03fd6e000-0xffe03fdee0000xbff6e000   512K PTE
>  D A . . . W R V
>
>
> Changes from v2->v3:
> 1. Added few extra comments to clarify rodata permissions.
> 2. Changed the name of the functions set_memory_default to set_memory_rw_nx.
> 3. Squashed patch 3&5 together as they depend on each other to allow
>bisectability.
> 4. Removed redundant arguments in protect_kernel_text_data.
>
> Changes from v1->v2:
> 1. .init.text section is aligned with SECTION_ALIGN.
> 2. .init.text is moved to below of .text so that .head.text & .text are in
>one section.
> 3. We don't need Guo's fix for static object issue.
> 4. Rebased on 5.10-rc1.
>
> Atish Patra (5):
> RISC-V: Move __start_kernel to .head.text
> RISC-V: Initialize SBI early
> RISC-V: Align the .init.text section
> RISC-V: Protect all kernel sections including init early
> RISC-V: Move dynamic relocation section under __init
>
> arch/riscv/include/asm/sections.h   |  2 +
> arch/riscv/include/asm/set_memory.h |  4 ++
> arch/riscv/kernel/head.S|  1 -
> arch/riscv/kernel/setup.c   | 19 +++--
> arch/riscv/kernel/vmlinux.lds.S | 63 +++++----
> arch/riscv/mm/init.c| 21 +++---
> arch/riscv/mm/pageattr.c|  6 +++
> 7 files changed, 80 insertions(+), 36 deletions(-)
>

Test this series in v5.10-rc3 in Qemu and it works.
Tested-by: Greentime Hu 

Thank you. :)


Re: [PATCH v3] gpio: sifive: To get gpio irq offset from device tree data

2020-11-13 Thread Greentime Hu
Bartosz Golaszewski  於 2020年11月13日 週五 下午5:00寫道:
>
> On Fri, Nov 13, 2020 at 3:34 AM Greentime Hu  wrote:
> >
> > We can get hwirq number of the gpio by its irq_data->hwirq so that we don't
> > need to add more macros for different platforms. This patch is tested in
> > SiFive Unleashed board and SiFive Unmatched board.
> >
> > Signed-off-by: Greentime Hu 
> > ---
>
> Please list the changes between versions of patches. What has changed since 
> v2?

changes in v3:
  Add 2 newlines
changes in v2:
  Use irqd_to_hwirq() instead of d->hwirq and platform_get_irq()
instead of  irq_of_parse_and_map()


[PATCH v3] gpio: sifive: To get gpio irq offset from device tree data

2020-11-12 Thread Greentime Hu
We can get hwirq number of the gpio by its irq_data->hwirq so that we don't
need to add more macros for different platforms. This patch is tested in
SiFive Unleashed board and SiFive Unmatched board.

Signed-off-by: Greentime Hu 
---
 drivers/gpio/gpio-sifive.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
index c54dd08f2cbf..630bddec48e5 100644
--- a/drivers/gpio/gpio-sifive.c
+++ b/drivers/gpio/gpio-sifive.c
@@ -29,7 +29,6 @@
 #define SIFIVE_GPIO_OUTPUT_XOR 0x40
 
 #define SIFIVE_GPIO_MAX32
-#define SIFIVE_GPIO_IRQ_OFFSET 7
 
 struct sifive_gpio {
void __iomem*base;
@@ -37,7 +36,7 @@ struct sifive_gpio {
struct regmap   *regs;
unsigned long   irq_state;
unsigned inttrigger[SIFIVE_GPIO_MAX];
-   unsigned intirq_parent[SIFIVE_GPIO_MAX];
+   unsigned intirq_number[SIFIVE_GPIO_MAX];
 };
 
 static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
@@ -144,8 +143,12 @@ static int sifive_gpio_child_to_parent_hwirq(struct 
gpio_chip *gc,
 unsigned int *parent,
 unsigned int *parent_type)
 {
+   struct sifive_gpio *chip = gpiochip_get_data(gc);
+   struct irq_data *d = irq_get_irq_data(chip->irq_number[child]);
+
*parent_type = IRQ_TYPE_NONE;
-   *parent = child + SIFIVE_GPIO_IRQ_OFFSET;
+   *parent = irqd_to_hwirq(d);
+
return 0;
 }
 
@@ -165,7 +168,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
struct irq_domain *parent;
struct gpio_irq_chip *girq;
struct sifive_gpio *chip;
-   int ret, ngpio;
+   int ret, ngpio, i;
 
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
@@ -200,6 +203,9 @@ static int sifive_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
 
+   for (i = 0; i < ngpio; i++)
+   chip->irq_number[i] = platform_get_irq(pdev, i);
+
ret = bgpio_init(>gc, dev, 4,
 chip->base + SIFIVE_GPIO_INPUT_VAL,
 chip->base + SIFIVE_GPIO_OUTPUT_VAL,
-- 
2.29.2



[PATCH] gpio: sifive: To get gpio irq offset from device tree data

2020-11-08 Thread Greentime Hu
We can get hwirq number of the gpio by its irq_data->hwirq so that we don't
need to add more macros for different platforms. This patch is tested in
SiFive Unleashed board and SiFive Unmatched board.

Signed-off-by: Greentime Hu 
---
 drivers/gpio/gpio-sifive.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
index c54dd08f2cbf..bfb915bf5d78 100644
--- a/drivers/gpio/gpio-sifive.c
+++ b/drivers/gpio/gpio-sifive.c
@@ -29,7 +29,6 @@
 #define SIFIVE_GPIO_OUTPUT_XOR 0x40
 
 #define SIFIVE_GPIO_MAX32
-#define SIFIVE_GPIO_IRQ_OFFSET 7
 
 struct sifive_gpio {
void __iomem*base;
@@ -37,7 +36,7 @@ struct sifive_gpio {
struct regmap   *regs;
unsigned long   irq_state;
unsigned inttrigger[SIFIVE_GPIO_MAX];
-   unsigned intirq_parent[SIFIVE_GPIO_MAX];
+   unsigned intirq_number[SIFIVE_GPIO_MAX];
 };
 
 static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
@@ -144,8 +143,10 @@ static int sifive_gpio_child_to_parent_hwirq(struct 
gpio_chip *gc,
 unsigned int *parent,
 unsigned int *parent_type)
 {
+   struct sifive_gpio *chip = gpiochip_get_data(gc);
+   struct irq_data *d = irq_get_irq_data(chip->irq_number[child]);
+   *parent = irqd_to_hwirq(d);
*parent_type = IRQ_TYPE_NONE;
-   *parent = child + SIFIVE_GPIO_IRQ_OFFSET;
return 0;
 }
 
@@ -165,7 +166,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
struct irq_domain *parent;
struct gpio_irq_chip *girq;
struct sifive_gpio *chip;
-   int ret, ngpio;
+   int ret, ngpio, i;
 
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
@@ -200,6 +201,9 @@ static int sifive_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
 
+   for (i = 0; i < ngpio; i++)
+   chip->irq_number[i] = platform_get_irq(pdev, i);
+
ret = bgpio_init(>gc, dev, 4,
 chip->base + SIFIVE_GPIO_INPUT_VAL,
 chip->base + SIFIVE_GPIO_OUTPUT_VAL,
-- 
2.29.2



Re: [PATCH v8 1/7] RISC-V: Move DT mapping outof fixmap

2020-11-08 Thread Greentime Hu
Atish Patra  於 2020年9月18日 週五 上午6:37寫道:
>
> From: Anup Patel 
>
> Currently, RISC-V reserves 1MB of fixmap memory for device tree. However,
> it maps only single PMD (2MB) space for fixmap which leaves only < 1MB space
> left for other kernel features such as early ioremap which requires fixmap
> as well. The fixmap size can be increased by another 2MB but it brings
> additional complexity and changes the virtual memory layout as well.
> If we require some additional feature requiring fixmap again, it has to be
> moved again.
>
> Technically, DT doesn't need a fixmap as the memory occupied by the DT is
> only used during boot. That's why, We map device tree in early page table
> using two consecutive PGD mappings at lower addresses (< PAGE_OFFSET).
> This frees lot of space in fixmap and also makes maximum supported
> device tree size supported as PGDIR_SIZE. Thus, init memory section can be 
> used
> for the same purpose as well. This simplifies fixmap implementation.
>
> Signed-off-by: Anup Patel 
> Signed-off-by: Atish Patra 
> Reviewed-by: Palmer Dabbelt 
> Signed-off-by: Palmer Dabbelt 
> ---
>  arch/riscv/include/asm/fixmap.h  |  3 ---
>  arch/riscv/include/asm/pgtable.h |  1 +
>  arch/riscv/kernel/head.S |  1 -
>  arch/riscv/kernel/head.h |  2 --
>  arch/riscv/kernel/setup.c|  9 +++--
>  arch/riscv/mm/init.c | 26 --
>  6 files changed, 20 insertions(+), 22 deletions(-)
>
> diff --git a/arch/riscv/include/asm/fixmap.h b/arch/riscv/include/asm/fixmap.h
> index 1ff075a8dfc7..11613f38228a 100644
> --- a/arch/riscv/include/asm/fixmap.h
> +++ b/arch/riscv/include/asm/fixmap.h
> @@ -22,9 +22,6 @@
>   */
>  enum fixed_addresses {
> FIX_HOLE,
> -#define FIX_FDT_SIZE   SZ_1M
> -   FIX_FDT_END,
> -   FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1,
> FIX_PTE,
> FIX_PMD,
> FIX_TEXT_POKE1,
> diff --git a/arch/riscv/include/asm/pgtable.h 
> b/arch/riscv/include/asm/pgtable.h
> index eaea1f717010..815f8c959dd4 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -464,6 +464,7 @@ static inline void __kernel_map_pages(struct page *page, 
> int numpages, int enabl
>  #define kern_addr_valid(addr)   (1) /* FIXME */
>
>  extern void *dtb_early_va;
> +extern uintptr_t dtb_early_pa;
>  void setup_bootmem(void);
>  void paging_init(void);
>
> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> index 0a4e81b8dc79..c6a37e8231a8 100644
> --- a/arch/riscv/kernel/head.S
> +++ b/arch/riscv/kernel/head.S
> @@ -259,7 +259,6 @@ clear_bss_done:
>  #endif
> /* Start the kernel */
> call soc_early_init
> -   call parse_dtb
> tail start_kernel
>
>  .Lsecondary_start:
> diff --git a/arch/riscv/kernel/head.h b/arch/riscv/kernel/head.h
> index 105fb0496b24..b48dda3d04f6 100644
> --- a/arch/riscv/kernel/head.h
> +++ b/arch/riscv/kernel/head.h
> @@ -16,6 +16,4 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa);
>  extern void *__cpu_up_stack_pointer[];
>  extern void *__cpu_up_task_pointer[];
>
> -void __init parse_dtb(void);
> -
>  #endif /* __ASM_HEAD_H */
> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> index 2c6dd329312b..edea7ef88402 100644
> --- a/arch/riscv/kernel/setup.c
> +++ b/arch/riscv/kernel/setup.c
> @@ -48,8 +48,9 @@ atomic_t hart_lottery __section(.sdata);
>  unsigned long boot_cpu_hartid;
>  static DEFINE_PER_CPU(struct cpu, cpu_devices);
>
> -void __init parse_dtb(void)
> +static void __init parse_dtb(void)
>  {
> +   /* Early scan of device tree from init memory */
> if (early_init_dt_scan(dtb_early_va))
> return;
>
> @@ -62,6 +63,7 @@ void __init parse_dtb(void)
>
>  void __init setup_arch(char **cmdline_p)
>  {
> +   parse_dtb();
> init_mm.start_code = (unsigned long) _stext;
> init_mm.end_code   = (unsigned long) _etext;
> init_mm.end_data   = (unsigned long) _edata;
> @@ -76,7 +78,10 @@ void __init setup_arch(char **cmdline_p)
>  #if IS_ENABLED(CONFIG_BUILTIN_DTB)
> unflatten_and_copy_device_tree();
>  #else
> -   unflatten_device_tree();
> +   if (early_init_dt_verify(__va(dtb_early_pa)))
> +   unflatten_device_tree();
> +   else
> +   pr_err("No DTB found in kernel mappings\n");
>  #endif
>
>  #ifdef CONFIG_SWIOTLB
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 787c75f751a5..2b651f63f5c4 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -28,7 +28,9 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned 
> long)]
>  EXPORT_SYMBOL(empty_zero_page);
>
>  extern char _start[];
> -void *dtb_early_va;
> +#define DTB_EARLY_BASE_VA  PGDIR_SIZE
> +void *dtb_early_va __initdata;
> +uintptr_t dtb_early_pa __initdata;
>
>  static void __init zone_sizes_init(void)
>  {
> @@ -141,8 +143,6 @@ static void __init setup_initrd(void)
>  }
>  #endif /* CONFIG_BLK_DEV_INITRD 

Re: [RFC PATCH 1/1] gpio: sifive: To get gpio irq offset from device tree data

2020-11-06 Thread Greentime Hu
Andy Shevchenko  於 2020年11月6日 週五 下午5:25寫道:
>
> On Fri, Nov 6, 2020 at 4:59 AM Greentime Hu  wrote:
> >
> > We can get hwirq number of the gpio by its irq_data->hwirq so that we don't
> > need to add more macros for different platforms. This patch is tested in
> > SiFive Unleashed board and SiFive Unmatched board.
>
> ...
>
> > +   struct sifive_gpio *chip = gpiochip_get_data(gc);
> > +   struct irq_data *d = irq_get_irq_data(chip->irq_number[child]);
>
> > +   *parent = d->hwirq;
>
> There is an API to get hwirq.
>
> ...
>
> > +   for (i = 0; i < ngpio; i++)
> > +   chip->irq_number[i] = irq_of_parse_and_map(node, i);
>
> Can't you use platform_get_irq_optional()?
>

Thank you for reviewing.
I would change it like this.

diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
index e8cd8741dbae..bfb915bf5d78 100644
--- a/drivers/gpio/gpio-sifive.c
+++ b/drivers/gpio/gpio-sifive.c
@@ -145,7 +145,7 @@ static int
sifive_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
 {
struct sifive_gpio *chip = gpiochip_get_data(gc);
struct irq_data *d = irq_get_irq_data(chip->irq_number[child]);
-   *parent = d->hwirq;
+   *parent = irqd_to_hwirq(d);
*parent_type = IRQ_TYPE_NONE;
return 0;
 }
@@ -202,7 +202,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
}

for (i = 0; i < ngpio; i++)
-   chip->irq_number[i] = irq_of_parse_and_map(node, i);
+   chip->irq_number[i] = platform_get_irq(pdev, i);

ret = bgpio_init(>gc, dev, 4,
 chip->base + SIFIVE_GPIO_INPUT_VAL,


[RFC PATCH 1/1] gpio: sifive: To get gpio irq offset from device tree data

2020-11-05 Thread Greentime Hu
We can get hwirq number of the gpio by its irq_data->hwirq so that we don't
need to add more macros for different platforms. This patch is tested in
SiFive Unleashed board and SiFive Unmatched board.

Signed-off-by: Greentime Hu 
Reviewed-by: Yash Shah 
---
 drivers/gpio/gpio-sifive.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
index c54dd08f2cbf..e8cd8741dbae 100644
--- a/drivers/gpio/gpio-sifive.c
+++ b/drivers/gpio/gpio-sifive.c
@@ -29,7 +29,6 @@
 #define SIFIVE_GPIO_OUTPUT_XOR 0x40
 
 #define SIFIVE_GPIO_MAX32
-#define SIFIVE_GPIO_IRQ_OFFSET 7
 
 struct sifive_gpio {
void __iomem*base;
@@ -37,7 +36,7 @@ struct sifive_gpio {
struct regmap   *regs;
unsigned long   irq_state;
unsigned inttrigger[SIFIVE_GPIO_MAX];
-   unsigned intirq_parent[SIFIVE_GPIO_MAX];
+   unsigned intirq_number[SIFIVE_GPIO_MAX];
 };
 
 static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
@@ -144,8 +143,10 @@ static int sifive_gpio_child_to_parent_hwirq(struct 
gpio_chip *gc,
 unsigned int *parent,
 unsigned int *parent_type)
 {
+   struct sifive_gpio *chip = gpiochip_get_data(gc);
+   struct irq_data *d = irq_get_irq_data(chip->irq_number[child]);
+   *parent = d->hwirq;
*parent_type = IRQ_TYPE_NONE;
-   *parent = child + SIFIVE_GPIO_IRQ_OFFSET;
return 0;
 }
 
@@ -165,7 +166,7 @@ static int sifive_gpio_probe(struct platform_device *pdev)
struct irq_domain *parent;
struct gpio_irq_chip *girq;
struct sifive_gpio *chip;
-   int ret, ngpio;
+   int ret, ngpio, i;
 
chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
@@ -200,6 +201,9 @@ static int sifive_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
 
+   for (i = 0; i < ngpio; i++)
+   chip->irq_number[i] = irq_of_parse_and_map(node, i);
+
ret = bgpio_init(>gc, dev, 4,
 chip->base + SIFIVE_GPIO_INPUT_VAL,
 chip->base + SIFIVE_GPIO_OUTPUT_VAL,
-- 
2.29.2



[tip: irq/urgent] irqchip/sifive-plic: Fix broken irq_set_affinity() callback

2020-11-01 Thread tip-bot2 for Greentime Hu
The following commit has been merged into the irq/urgent branch of tip:

Commit-ID: a7480c5d725c4ecfc627e70960f249c34f5d13e8
Gitweb:
https://git.kernel.org/tip/a7480c5d725c4ecfc627e70960f249c34f5d13e8
Author:Greentime Hu 
AuthorDate:Tue, 20 Oct 2020 16:15:32 +08:00
Committer: Marc Zyngier 
CommitterDate: Sun, 25 Oct 2020 12:33:07 

irqchip/sifive-plic: Fix broken irq_set_affinity() callback

An interrupt submitted to an affinity change will always be left enabled
after plic_set_affinity() has been called, while the expectation is that
it should stay in whatever state it was before the call.

Preserving the configuration fixes a PWM hang issue on the Unleashed
board.

[  919.015783] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[  919.020922] rcu: 0-...0: (0 ticks this GP)
idle=7d2/1/0x4002 softirq=1424/1424 fqs=105807
[  919.030295]  (detected by 1, t=225825 jiffies, g=1561, q=3496)
[  919.036109] Task dump for CPU 0:
[  919.039321] kworker/0:1 R  running task030  2 0x0008
[  919.046359] Workqueue: events set_brightness_delayed
[  919.051302] Call Trace:
[  919.053738] [] __schedule+0x194/0x4de
[  982.035783] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[  982.040923] rcu: 0-...0: (0 ticks this GP)
idle=7d2/1/0x4002 softirq=1424/1424 fqs=113325
[  982.050294]  (detected by 1, t=241580 jiffies, g=1561, q=3509)
[  982.056108] Task dump for CPU 0:
[  982.059321] kworker/0:1 R  running task030  2 0x0008
[  982.066359] Workqueue: events set_brightness_delayed
[  982.071302] Call Trace:
[  982.073739] [] __schedule+0x194/0x4de
[..]

Fixes: bb0fed1c60cc ("irqchip/sifive-plic: Switch to fasteoi flow")
Signed-off-by: Greentime Hu 
[maz: tidy-up commit message]
Signed-off-by: Marc Zyngier 
Reviewed-by: Anup Patel 
Link: https://lore.kernel.org/r/20201020081532.2377-1-greentime...@sifive.com
---
 drivers/irqchip/irq-sifive-plic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c 
b/drivers/irqchip/irq-sifive-plic.c
index eaa3e9f..4048657 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -151,7 +151,7 @@ static int plic_set_affinity(struct irq_data *d,
return -EINVAL;
 
plic_irq_toggle(>lmask, d, 0);
-   plic_irq_toggle(cpumask_of(cpu), d, 1);
+   plic_irq_toggle(cpumask_of(cpu), d, !irqd_irq_masked(d));
 
irq_data_update_effective_affinity(d, cpumask_of(cpu));
 


[tip: irq/urgent] irqchip/sifive-plic: Fix chip_data access within a hierarchy

2020-11-01 Thread tip-bot2 for Greentime Hu
The following commit has been merged into the irq/urgent branch of tip:

Commit-ID: f9ac7bbd6e4540dcc6df621b9c9b6eb2e26ded1d
Gitweb:
https://git.kernel.org/tip/f9ac7bbd6e4540dcc6df621b9c9b6eb2e26ded1d
Author:Greentime Hu 
AuthorDate:Thu, 29 Oct 2020 10:37:38 +08:00
Committer: Marc Zyngier 
CommitterDate: Sun, 01 Nov 2020 11:52:27 

irqchip/sifive-plic: Fix chip_data access within a hierarchy

The plic driver crashes in plic_irq_unmask() when the interrupt is within a
hierarchy, as it picks the top-level chip_data instead of its local one.

Using irq_data_get_irq_chip_data() instead of irq_get_chip_data() solves
the issue for good.

Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs")
Signed-off-by: Greentime Hu 
[maz: rewrote commit message]
Signed-off-by: Marc Zyngier 
Reviewed-by: Anup Patel 
Reviewed-by: Atish Patra 
Link: https://lore.kernel.org/r/20201029023738.127472-1-greentime...@sifive.com
---
 drivers/irqchip/irq-sifive-plic.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c 
b/drivers/irqchip/irq-sifive-plic.c
index 4048657..6f432d2 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -99,7 +99,7 @@ static inline void plic_irq_toggle(const struct cpumask *mask,
   struct irq_data *d, int enable)
 {
int cpu;
-   struct plic_priv *priv = irq_get_chip_data(d->irq);
+   struct plic_priv *priv = irq_data_get_irq_chip_data(d);
 
writel(enable, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID);
for_each_cpu(cpu, mask) {
@@ -115,7 +115,7 @@ static void plic_irq_unmask(struct irq_data *d)
 {
struct cpumask amask;
unsigned int cpu;
-   struct plic_priv *priv = irq_get_chip_data(d->irq);
+   struct plic_priv *priv = irq_data_get_irq_chip_data(d);
 
cpumask_and(, >lmask, cpu_online_mask);
cpu = cpumask_any_and(irq_data_get_affinity_mask(d),
@@ -127,7 +127,7 @@ static void plic_irq_unmask(struct irq_data *d)
 
 static void plic_irq_mask(struct irq_data *d)
 {
-   struct plic_priv *priv = irq_get_chip_data(d->irq);
+   struct plic_priv *priv = irq_data_get_irq_chip_data(d);
 
plic_irq_toggle(>lmask, d, 0);
 }
@@ -138,7 +138,7 @@ static int plic_set_affinity(struct irq_data *d,
 {
unsigned int cpu;
struct cpumask amask;
-   struct plic_priv *priv = irq_get_chip_data(d->irq);
+   struct plic_priv *priv = irq_data_get_irq_chip_data(d);
 
cpumask_and(, >lmask, mask_val);
 


[RFC PATCH] irqchip/sifive-plic: Fix getting wrong chip_data when interrupt is hierarchy

2020-10-28 Thread Greentime Hu
This oops is caused by a wrong chip_data and it is because plic_irq_unmask
uses irq_get_chip_data(irq_data->irq) to get the chip_data. However it may
get another irq_data with the same irq_data->irq if it is hierarchy.

In this case, it will get irq_data of sifive_gpio_irqchip instead of
plic_chip so that it will get a wrong chip_data and then the wrong lmask
of it to cause this oops.

To fix this issue, we can use irq_data_get_irq_chip_data(irq_data) to get
the correct chip_data of plic_chip.

(gdb) p d
$11 = (struct irq_data *) 0xffe1f695f620
(gdb) p *d
$9 = {
  mask = 0,
  irq = 57,
  hwirq = 6,
  common = 0xffe1f695f600,
  chip = 0xffe0018b5630 ,
  domain = 0xffe1f692c400,
  parent_data = 0xffe1f68482c0,
  chip_data = 0xffe1f564a820
}

(gdb) p d
$6 = (struct irq_data *) 0xffe1f68482c0
(gdb) p *d
$7 = {
  mask = 0,
  irq = 57,
  hwirq = 29,
  common = 0xffe1f695f600,
  chip = 0xffe0018b5070 ,
  domain = 0xffe1f6635e00,
  parent_data = 0x0,
  chip_data = 0xffe1f660f1a0
}

[3.030165] [ cut here ]
[3.034614] WARNING: CPU: 1 PID: 1 at drivers/irqchip/irq-sifive-plic.c:125 
plic_irq_unmask+0xc4/0x114
[3.043887] Modules linked in:
[3.046932] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.9.0 #1
[3.052748] epc: ffe000588e90 ra : ffe000588e88 sp : ffe1f6753940
[3.059869]  gp : ffe001978f48 tp : ffe1f6748000 t0 : 
ffe001995cb0
[3.067080]  t1 : ffe001995be8 t2 : 73616d61202c343a s0 : 
ffe1f67539a0
[3.074288]  s1 : ffe1f4968140 a0 : 00b2 a1 : 

[3.081497]  a2 : 00c2 a3 :  a4 : 
381c5a89432fe900
[3.088707]  a5 : 0004 a6 :  a7 : 
01aa
[3.095916]  s2 : ffe1f5901020 s3 : ffe00197a0a8 s4 : 
ffe001978b0c
[3.103125]  s5 : ffe00197a1f0 s6 : 0008 s7 : 
ffe1f4983c9c
[3.110335]  s8 : ffe1f4983c68 s9 : ffe1f4983c00 s10: 
ffe0117c
[3.117544]  s11:  t3 : 0007 t4 : 

[3.124753]  t5 : 663a6b73 t6 : ffe001988479
[3.130052] status: 00020100 badaddr: ffe001978b0c cause: 
0003
[3.137959] ---[ end trace dbc1129f842ecba3 ]---

Fixes: f1ad1133b18f ("irqchip/sifive-plic: Add support for multiple PLICs")
Signed-off-by: Greentime Hu 
---
 drivers/irqchip/irq-sifive-plic.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c 
b/drivers/irqchip/irq-sifive-plic.c
index 4048657ece0a..6f432d2a5ceb 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -99,7 +99,7 @@ static inline void plic_irq_toggle(const struct cpumask *mask,
   struct irq_data *d, int enable)
 {
int cpu;
-   struct plic_priv *priv = irq_get_chip_data(d->irq);
+   struct plic_priv *priv = irq_data_get_irq_chip_data(d);
 
writel(enable, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID);
for_each_cpu(cpu, mask) {
@@ -115,7 +115,7 @@ static void plic_irq_unmask(struct irq_data *d)
 {
struct cpumask amask;
unsigned int cpu;
-   struct plic_priv *priv = irq_get_chip_data(d->irq);
+   struct plic_priv *priv = irq_data_get_irq_chip_data(d);
 
cpumask_and(, >lmask, cpu_online_mask);
cpu = cpumask_any_and(irq_data_get_affinity_mask(d),
@@ -127,7 +127,7 @@ static void plic_irq_unmask(struct irq_data *d)
 
 static void plic_irq_mask(struct irq_data *d)
 {
-   struct plic_priv *priv = irq_get_chip_data(d->irq);
+   struct plic_priv *priv = irq_data_get_irq_chip_data(d);
 
plic_irq_toggle(>lmask, d, 0);
 }
@@ -138,7 +138,7 @@ static int plic_set_affinity(struct irq_data *d,
 {
unsigned int cpu;
struct cpumask amask;
-   struct plic_priv *priv = irq_get_chip_data(d->irq);
+   struct plic_priv *priv = irq_data_get_irq_chip_data(d);
 
cpumask_and(, >lmask, mask_val);
 
-- 
2.28.0



[PATCH] irqchip/sifive-plic: Fix broken irq_set_affinity() callback

2020-10-20 Thread Greentime Hu
It will always enable the interrupt after calling plic_set_affinity()
however it should set to it previous setting. Staying disabled or enabled.

This patch can also fix this pwm hang issue in Unleashed board.

[  919.015783] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[  919.020922] rcu: 0-...0: (0 ticks this GP)
idle=7d2/1/0x4002 softirq=1424/1424 fqs=105807
[  919.030295]  (detected by 1, t=225825 jiffies, g=1561, q=3496)
[  919.036109] Task dump for CPU 0:
[  919.039321] kworker/0:1 R  running task030  2 0x0008
[  919.046359] Workqueue: events set_brightness_delayed
[  919.051302] Call Trace:
[  919.053738] [] __schedule+0x194/0x4de
[  982.035783] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[  982.040923] rcu: 0-...0: (0 ticks this GP)
idle=7d2/1/0x4002 softirq=1424/1424 fqs=113325
[  982.050294]  (detected by 1, t=241580 jiffies, g=1561, q=3509)
[  982.056108] Task dump for CPU 0:
[  982.059321] kworker/0:1 R  running task030  2 0x0008
[  982.066359] Workqueue: events set_brightness_delayed
[  982.071302] Call Trace:
[  982.073739] [] __schedule+0x194/0x4de
[..]

Fixes: bb0fed1c60cc ("irqchip/sifive-plic: Switch to fasteoi flow")
Signed-off-by: Greentime Hu 
---
 drivers/irqchip/irq-sifive-plic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c 
b/drivers/irqchip/irq-sifive-plic.c
index eaa3e9fe54e9..4048657ece0a 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -151,7 +151,7 @@ static int plic_set_affinity(struct irq_data *d,
return -EINVAL;
 
plic_irq_toggle(>lmask, d, 0);
-   plic_irq_toggle(cpumask_of(cpu), d, 1);
+   plic_irq_toggle(cpumask_of(cpu), d, !irqd_irq_masked(d));
 
irq_data_update_effective_affinity(d, cpumask_of(cpu));
 
-- 
2.28.0



Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-12 Thread Greentime Hu
Atish Patra  於 2020年10月13日 週二 上午9:28寫道:
>
> On Mon, Oct 12, 2020 at 4:26 PM Atish Patra  wrote:
> >
> > On Mon, Oct 12, 2020 at 6:15 AM Greentime Hu  
> > wrote:
> > >
> > > Atish Patra  於 2020年10月10日 週六 上午5:13寫道:
> > > >
> > > > Currently, .init.text & .init.data are intermixed which makes it 
> > > > impossible
> > > > apply different permissions to them. .init.data shouldn't need exec
> > > > permissions while .init.text shouldn't have write permission.
> > > >
> > > > Keep them in separate sections so that different permissions are 
> > > > applied to
> > > > each section. This improves the kernel protection under
> > > > CONFIG_STRICT_KERNEL_RWX. We also need to restore the permissions for 
> > > > the
> > > > entire _init section after it is freed so that those pages can be used 
> > > > for
> > > > other purpose.
> > > >
> > > > Signed-off-by: Atish Patra 
> > > > ---
> > > >  arch/riscv/include/asm/sections.h   |  2 ++
> > > >  arch/riscv/include/asm/set_memory.h |  2 ++
> > > >  arch/riscv/kernel/setup.c   |  4 
> > > >  arch/riscv/kernel/vmlinux.lds.S | 10 +-
> > > >  arch/riscv/mm/init.c|  6 ++
> > > >  arch/riscv/mm/pageattr.c|  6 ++
> > > >  6 files changed, 29 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/arch/riscv/include/asm/sections.h 
> > > > b/arch/riscv/include/asm/sections.h
> > > > index d60802bfafbc..730d2c4a844d 100644
> > > > --- a/arch/riscv/include/asm/sections.h
> > > > +++ b/arch/riscv/include/asm/sections.h
> > > > @@ -10,6 +10,8 @@
> > > >  #include 
> > > >  extern char _start[];
> > > >  extern char _start_kernel[];
> > > > +extern char __init_data_begin[], __init_data_end[];
> > > > +extern char __init_text_begin[], __init_text_end[];
> > > >
> > > >  extern bool init_mem_is_free;
> > > >
> > > > diff --git a/arch/riscv/include/asm/set_memory.h 
> > > > b/arch/riscv/include/asm/set_memory.h
> > > > index 4cc3a4e2afd3..913429c9c1ae 100644
> > > > --- a/arch/riscv/include/asm/set_memory.h
> > > > +++ b/arch/riscv/include/asm/set_memory.h
> > > > @@ -15,6 +15,7 @@ int set_memory_ro(unsigned long addr, int numpages);
> > > >  int set_memory_rw(unsigned long addr, int numpages);
> > > >  int set_memory_x(unsigned long addr, int numpages);
> > > >  int set_memory_nx(unsigned long addr, int numpages);
> > > > +int set_memory_default(unsigned long addr, int numpages);
> > > >  void protect_kernel_text_data(void);
> > > >  #else
> > > >  static inline int set_memory_ro(unsigned long addr, int numpages) { 
> > > > return 0; }
> > > > @@ -22,6 +23,7 @@ static inline int set_memory_rw(unsigned long addr, 
> > > > int numpages) { return 0; }
> > > >  static inline int set_memory_x(unsigned long addr, int numpages) { 
> > > > return 0; }
> > > >  static inline int set_memory_nx(unsigned long addr, int numpages) { 
> > > > return 0; }
> > > >  static inline void protect_kernel_text_data(void) {};
> > > > +static inline int set_memory_default(unsigned long addr, int numpages) 
> > > > { return 0; }
> > > >  #endif
> > > >
> > > >  int set_direct_map_invalid_noflush(struct page *page);
> > > > diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> > > > index 4176a2affd1d..b8a35ef0eab0 100644
> > > > --- a/arch/riscv/kernel/setup.c
> > > > +++ b/arch/riscv/kernel/setup.c
> > > > @@ -129,6 +129,10 @@ bool init_mem_is_free = false;
> > > >
> > > >  void free_initmem(void)
> > > >  {
> > > > +   unsigned long init_begin = (unsigned long)__init_begin;
> > > > +   unsigned long init_end = (unsigned long)__init_end;
> > > > +
> > > > +   set_memory_default(init_begin, (init_end - init_begin) >> 
> > > > PAGE_SHIFT);
> > > > free_initmem_default(POISON_FREE_INITMEM);
> > > > init_mem_is_free = true;
> > > >  }
> > > > diff --git a/arch/riscv/kernel/vmlinux.lds.S 
> > > > b/arch/riscv/kernel/vmlinux.lds.S
> > > > index 0807633f0dc8..

[PATCH 1/2] irqchip/sifive-plic: Enable or disable interrupt based on its previous setting

2020-10-12 Thread Greentime Hu
It will always enable the interrupt after calling plic_set_affinity()
however it should set to its previous setting. Staying disabled or enabled.

This patch can also fix this pwm hang issue in Unleashed board.

[  919.015783] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[  919.020922] rcu: 0-...0: (0 ticks this GP)
idle=7d2/1/0x4002 softirq=1424/1424 fqs=105807
[  919.030295]  (detected by 1, t=225825 jiffies, g=1561, q=3496)
[  919.036109] Task dump for CPU 0:
[  919.039321] kworker/0:1 R  running task030  2 0x0008
[  919.046359] Workqueue: events set_brightness_delayed
[  919.051302] Call Trace:
[  919.053738] [] __schedule+0x194/0x4de
[  982.035783] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[  982.040923] rcu: 0-...0: (0 ticks this GP)
idle=7d2/1/0x4002 softirq=1424/1424 fqs=113325
[  982.050294]  (detected by 1, t=241580 jiffies, g=1561, q=3509)
[  982.056108] Task dump for CPU 0:
[  982.059321] kworker/0:1 R  running task030  2 0x0008
[  982.066359] Workqueue: events set_brightness_delayed
[  982.071302] Call Trace:
[  982.073739] [] __schedule+0x194/0x4de
[..]

Fixes: bb0fed1c60cc ("irqchip/sifive-plic: Switch to fasteoi flow")
Signed-off-by: Greentime Hu 
---
 drivers/irqchip/irq-sifive-plic.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-sifive-plic.c 
b/drivers/irqchip/irq-sifive-plic.c
index eaa3e9fe54e9..4cc8a2657a6d 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -137,6 +137,7 @@ static int plic_set_affinity(struct irq_data *d,
 const struct cpumask *mask_val, bool force)
 {
unsigned int cpu;
+   bool enable;
struct cpumask amask;
struct plic_priv *priv = irq_get_chip_data(d->irq);
 
@@ -150,8 +151,10 @@ static int plic_set_affinity(struct irq_data *d,
if (cpu >= nr_cpu_ids)
return -EINVAL;
 
+   enable = !irqd_irq_disabled(d);
plic_irq_toggle(>lmask, d, 0);
-   plic_irq_toggle(cpumask_of(cpu), d, 1);
+   /* Keep its original setting. */
+   plic_irq_toggle(cpumask_of(cpu), d, enable);
 
irq_data_update_effective_affinity(d, cpumask_of(cpu));
 
-- 
2.28.0



[PATCH 2/2] irqchip/sifive-plic: Fix the interrupt was enabled accidentally issue.

2020-10-12 Thread Greentime Hu
In commit 2ca0b460bbcb ("genirq/affinity: Make affinity setting if activated 
opt-in"),
it added irqd_affinity_on_activate() checking in the function
irq_set_affinity_deactivated() so it will return false here.
In that case, it will call irq_try_set_affinity() -> plic_irq_toggle()
which will enable the interrupt to cause the CPU hang.

if (irq_set_affinity_deactivated())
return 0;
...
irq_try_set_affinity(data, mask, force);

[  919.015783] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[  919.020922] rcu: 0-...0: (0 ticks this GP)
idle=7d2/1/0x4002 softirq=1424/1424 fqs=105807
[  919.030295]  (detected by 1, t=225825 jiffies, g=1561, q=3496)
[  919.036109] Task dump for CPU 0:
[  919.039321] kworker/0:1 R  running task030  2 0x0008
[  919.046359] Workqueue: events set_brightness_delayed
[  919.051302] Call Trace:
[  919.053738] [] __schedule+0x194/0x4de
[  982.035783] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[  982.040923] rcu: 0-...0: (0 ticks this GP)
idle=7d2/1/0x4002 softirq=1424/1424 fqs=113325
[  982.050294]  (detected by 1, t=241580 jiffies, g=1561, q=3509)
[  982.056108] Task dump for CPU 0:
[  982.059321] kworker/0:1 R  running task030  2 0x0008
[  982.066359] Workqueue: events set_brightness_delayed
[  982.071302] Call Trace:
[  982.073739] [] __schedule+0x194/0x4de
[..]

After applying this patch, the CPU hang issue can be fixed.

Signed-off-by: Greentime Hu 
---
 drivers/irqchip/irq-sifive-plic.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/irqchip/irq-sifive-plic.c 
b/drivers/irqchip/irq-sifive-plic.c
index 4cc8a2657a6d..8a673d9cff69 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -183,10 +183,14 @@ static int plic_irqdomain_map(struct irq_domain *d, 
unsigned int irq,
  irq_hw_number_t hwirq)
 {
struct plic_priv *priv = d->host_data;
+   struct irq_data *irqd;
 
irq_domain_set_info(d, irq, hwirq, _chip, d->host_data,
handle_fasteoi_irq, NULL, NULL);
irq_set_noprobe(irq);
+   irqd = irq_get_irq_data(irq);
+   irqd_set_single_target(irqd);
+   irqd_set_affinity_on_activate(irqd);
irq_set_affinity(irq, >lmask);
return 0;
 }
-- 
2.28.0



Re: [PATCH 4/5] RISC-V: Protect .init.text & .init.data

2020-10-12 Thread Greentime Hu
Atish Patra  於 2020年10月10日 週六 上午5:13寫道:
>
> Currently, .init.text & .init.data are intermixed which makes it impossible
> apply different permissions to them. .init.data shouldn't need exec
> permissions while .init.text shouldn't have write permission.
>
> Keep them in separate sections so that different permissions are applied to
> each section. This improves the kernel protection under
> CONFIG_STRICT_KERNEL_RWX. We also need to restore the permissions for the
> entire _init section after it is freed so that those pages can be used for
> other purpose.
>
> Signed-off-by: Atish Patra 
> ---
>  arch/riscv/include/asm/sections.h   |  2 ++
>  arch/riscv/include/asm/set_memory.h |  2 ++
>  arch/riscv/kernel/setup.c   |  4 
>  arch/riscv/kernel/vmlinux.lds.S | 10 +-
>  arch/riscv/mm/init.c|  6 ++
>  arch/riscv/mm/pageattr.c|  6 ++
>  6 files changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/include/asm/sections.h 
> b/arch/riscv/include/asm/sections.h
> index d60802bfafbc..730d2c4a844d 100644
> --- a/arch/riscv/include/asm/sections.h
> +++ b/arch/riscv/include/asm/sections.h
> @@ -10,6 +10,8 @@
>  #include 
>  extern char _start[];
>  extern char _start_kernel[];
> +extern char __init_data_begin[], __init_data_end[];
> +extern char __init_text_begin[], __init_text_end[];
>
>  extern bool init_mem_is_free;
>
> diff --git a/arch/riscv/include/asm/set_memory.h 
> b/arch/riscv/include/asm/set_memory.h
> index 4cc3a4e2afd3..913429c9c1ae 100644
> --- a/arch/riscv/include/asm/set_memory.h
> +++ b/arch/riscv/include/asm/set_memory.h
> @@ -15,6 +15,7 @@ int set_memory_ro(unsigned long addr, int numpages);
>  int set_memory_rw(unsigned long addr, int numpages);
>  int set_memory_x(unsigned long addr, int numpages);
>  int set_memory_nx(unsigned long addr, int numpages);
> +int set_memory_default(unsigned long addr, int numpages);
>  void protect_kernel_text_data(void);
>  #else
>  static inline int set_memory_ro(unsigned long addr, int numpages) { return 
> 0; }
> @@ -22,6 +23,7 @@ static inline int set_memory_rw(unsigned long addr, int 
> numpages) { return 0; }
>  static inline int set_memory_x(unsigned long addr, int numpages) { return 0; 
> }
>  static inline int set_memory_nx(unsigned long addr, int numpages) { return 
> 0; }
>  static inline void protect_kernel_text_data(void) {};
> +static inline int set_memory_default(unsigned long addr, int numpages) { 
> return 0; }
>  #endif
>
>  int set_direct_map_invalid_noflush(struct page *page);
> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> index 4176a2affd1d..b8a35ef0eab0 100644
> --- a/arch/riscv/kernel/setup.c
> +++ b/arch/riscv/kernel/setup.c
> @@ -129,6 +129,10 @@ bool init_mem_is_free = false;
>
>  void free_initmem(void)
>  {
> +   unsigned long init_begin = (unsigned long)__init_begin;
> +   unsigned long init_end = (unsigned long)__init_end;
> +
> +   set_memory_default(init_begin, (init_end - init_begin) >> PAGE_SHIFT);
> free_initmem_default(POISON_FREE_INITMEM);
> init_mem_is_free = true;
>  }
> diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
> index 0807633f0dc8..15b9882588ae 100644
> --- a/arch/riscv/kernel/vmlinux.lds.S
> +++ b/arch/riscv/kernel/vmlinux.lds.S
> @@ -30,8 +30,8 @@ SECTIONS
> . = ALIGN(PAGE_SIZE);
>
> __init_begin = .;
> +   __init_text_begin = .;
> INIT_TEXT_SECTION(PAGE_SIZE)
> -   INIT_DATA_SECTION(16)
> . = ALIGN(8);
> __soc_early_init_table : {
> __soc_early_init_table_start = .;
> @@ -48,11 +48,19 @@ SECTIONS
> {
> EXIT_TEXT
> }
> +
> +   __init_text_end = .;
> +   . = ALIGN(SECTION_ALIGN);
> +   /* Start of init data section */
> +   __init_data_begin = .;
> +   INIT_DATA_SECTION(16)
> .exit.data :
> {
> EXIT_DATA
> }
> PERCPU_SECTION(L1_CACHE_BYTES)
> +
> +   __init_data_end = .;
> __init_end = .;
>
> . = ALIGN(SECTION_ALIGN);
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 7859a1d1b34d..3ef0eafcc7c7 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -627,11 +627,17 @@ void protect_kernel_text_data(void)
>  {
> unsigned long text_start = (unsigned long)_text;
> unsigned long text_end = (unsigned long)_etext;
> +   unsigned long init_text_start = (unsigned long)__init_text_begin;
> +   unsigned long init_text_end = (unsigned long)__init_text_end;
> +   unsigned long init_data_start = (unsigned long)__init_data_begin;
> +   unsigned long init_data_end = (unsigned long)__init_data_end;
> unsigned long rodata_start = (unsigned long)__start_rodata;
> unsigned long data_start = (unsigned long)_data;
> unsigned long max_low = (unsigned long)(__va(PFN_PHYS(max_low_pfn)));
>
> +   

Re: [PATCH] riscv: Add sfence.vma after page table changed

2020-09-14 Thread Greentime Hu
Palmer Dabbelt  於 2020年8月5日 週三 上午10:03寫道:
>
> On Mon, 03 Aug 2020 20:29:32 PDT (-0700), a...@brainfault.org wrote:
> > On Tue, Aug 4, 2020 at 8:32 AM Greentime Hu  wrote:
> >>
> >> This patch addes local_flush_tlb_page(addr) to use sfence.vma after the
> >
> > s/addes/adds
> >
> >> page table changed. That address will be used immediately in
> >> memset(nextp, 0, PAGE_SIZE) to cause this issue so we should add the
> >> sfence.vma before we use it.
> >
> > Alternate version of this commit description can be:
> >
> > Invalidate local TLB after both set_pet() and clear_pte() because the
> > address can be used immediately after page table change.
> >
> >> Fixes: f2c17aabc917 ("RISC-V: Implement compile-time fixed mappings")
> >>
> >> Reported-by: Syven Wang 
> >> Signed-off-by: Syven Wang 
> >> Signed-off-by: Greentime Hu 
> >> ---
> >>  arch/riscv/mm/init.c | 7 +++
> >>  1 file changed, 3 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> >> index f4adb3684f3d..29b0f7108054 100644
> >> --- a/arch/riscv/mm/init.c
> >> +++ b/arch/riscv/mm/init.c
> >> @@ -202,12 +202,11 @@ void __set_fixmap(enum fixed_addresses idx, 
> >> phys_addr_t phys, pgprot_t prot)
> >>
> >> ptep = _pte[pte_index(addr)];
> >>
> >> -   if (pgprot_val(prot)) {
> >> +   if (pgprot_val(prot))
> >> set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
> >> -   } else {
> >> +   else
> >> pte_clear(_mm, addr, ptep);
> >> -   local_flush_tlb_page(addr);
> >> -   }
> >> +   local_flush_tlb_page(addr);
> >>  }
>
> arm64 appears to be upgrading all set_pte()s on valid kernel mappings to
> include the fence.  It looks like the message from 7f0b1bf04511 ("arm64: Fix
> barriers used for page table modifications") is out of date, as I can't find
> create_mapping() any more.  If that was some generic kernel thing then we
> should probably upgrade ours as well, but if it was arch/arm64/ code then this
> approach seems fine as __set_fixmap() isn't on the hot path -- I guess this is
> fine either way, but there may be other issues that the arm64 approach fixes.
>
> Do you guys happen to remember what was going on here?

Hi Palmer,

Some architectures add cache writeback in set_pte(), just like nds32, csky.

https://github.com/torvalds/linux/blob/master/arch/nds32/include/asm/pgtable.h#L213
https://github.com/torvalds/linux/blob/master/arch/csky/include/asm/pgtable.h#L104

Would you like to pick this patch or should I send another patch to
implement it in set_pte()?


Re: [RFC/RFT PATCH v2 3/5] riscv: Separate memory init from paging init

2020-09-11 Thread Greentime Hu
Atish Patra  於 2020年9月12日 週六 上午9:34寫道:
>
> Currently, we perform some memory init functions in paging init. But,
> that will be an issue for NUMA support where DT needs to be flattened
> before numa initialization and memblock_present can only be called
> after numa initialization.
>
> Move memory initialization related functions to a separate function.
>
> Signed-off-by: Atish Patra 
> ---
>  arch/riscv/include/asm/pgtable.h | 1 +
>  arch/riscv/kernel/setup.c| 1 +
>  arch/riscv/mm/init.c | 6 +-
>  3 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/arch/riscv/include/asm/pgtable.h 
> b/arch/riscv/include/asm/pgtable.h
> index eaea1f717010..515b42f98d34 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -466,6 +466,7 @@ static inline void __kernel_map_pages(struct page *page, 
> int numpages, int enabl
>  extern void *dtb_early_va;
>  void setup_bootmem(void);
>  void paging_init(void);
> +void misc_mem_init(void);
>
>  #define FIRST_USER_ADDRESS  0
>
> diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
> index 2c6dd329312b..07fa6d13367e 100644
> --- a/arch/riscv/kernel/setup.c
> +++ b/arch/riscv/kernel/setup.c
> @@ -78,6 +78,7 @@ void __init setup_arch(char **cmdline_p)
>  #else
> unflatten_device_tree();
>  #endif
> +   misc_mem_init();
>
>  #ifdef CONFIG_SWIOTLB
> swiotlb_init(1);
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 188281fc2816..8f31a5428ce4 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -568,8 +568,12 @@ static void __init resource_init(void)
>  void __init paging_init(void)
>  {
> setup_vm_final();
> -   sparse_init();
> setup_zero_page();
> +}
> +
> +void __init misc_mem_init(void)
> +{
> +   sparse_init();
> zone_sizes_init();
> resource_init();
>  }

Thank you, Atish.
Reviewed-by: Greentime Hu 


[RFC PATCH v7 15/21] riscv: Use CSR_STATUS to replace sstatus in vector.S

2020-09-10 Thread Greentime Hu
It should use the same logic here in both m-mode and s-mode.

Signed-off-by: Greentime Hu 
---
 arch/riscv/kernel/vector.S | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/kernel/vector.S b/arch/riscv/kernel/vector.S
index 4c880b1c32aa..4f0c5a166e4e 100644
--- a/arch/riscv/kernel/vector.S
+++ b/arch/riscv/kernel/vector.S
@@ -32,7 +32,7 @@
 
 ENTRY(__vstate_save)
li  status, SR_VS
-   csrssstatus, status
+   csrsCSR_STATUS, status
 
csrrx_vstart, CSR_VSTART
csrrx_vtype, CSR_VTYPE
@@ -53,13 +53,13 @@ ENTRY(__vstate_save)
REG_S   x_vl, RISCV_V_STATE_VL(vstatep)
REG_S   x_vcsr, RISCV_V_STATE_VCSR(vstatep)
 
-   csrcsstatus, status
+   csrcCSR_STATUS, status
ret
 ENDPROC(__vstate_save)
 
 ENTRY(__vstate_restore)
li  status, SR_VS
-   csrssstatus, status
+   csrsCSR_STATUS, status
 
li  m_one, -1
vsetvli incr, m_one, e8, m8
@@ -79,6 +79,6 @@ ENTRY(__vstate_restore)
csrwCSR_VSTART, x_vstart
csrwCSR_VCSR, x_vcsr
 
-   csrcsstatus, status
+   csrcCSR_STATUS, status
ret
 ENDPROC(__vstate_restore)
-- 
2.28.0



[RFC PATCH v7 21/21] riscv: Optimize task switch codes of vector

2020-09-10 Thread Greentime Hu
This patch replacees 2 instructions with 1 instruction to do the same thing
. rs1=x0 with rd != x0 is a special form of the instruction that sets vl to
MAXVL.

Suggested-by: Andrew Waterman 
Signed-off-by: Greentime Hu 
---
 arch/riscv/kernel/vector.S | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/riscv/kernel/vector.S b/arch/riscv/kernel/vector.S
index 4f0c5a166e4e..f7223c81b11a 100644
--- a/arch/riscv/kernel/vector.S
+++ b/arch/riscv/kernel/vector.S
@@ -27,8 +27,7 @@
 #define x_vl t2
 #define x_vcsr   t3
 #define incr t4
-#define m_onet5
-#define status   t6
+#define status   t5
 
 ENTRY(__vstate_save)
li  status, SR_VS
@@ -38,8 +37,7 @@ ENTRY(__vstate_save)
csrrx_vtype, CSR_VTYPE
csrrx_vl, CSR_VL
csrrx_vcsr, CSR_VCSR
-   li  m_one, -1
-   vsetvli incr, m_one, e8, m8
+   vsetvli incr, x0, e8, m8
vse8.v   v0, (datap)
add datap, datap, incr
vse8.v   v8, (datap)
@@ -61,8 +59,7 @@ ENTRY(__vstate_restore)
li  status, SR_VS
csrsCSR_STATUS, status
 
-   li  m_one, -1
-   vsetvli incr, m_one, e8, m8
+   vsetvli incr, x0, e8, m8
vle8.v   v0, (datap)
add datap, datap, incr
vle8.v   v8, (datap)
-- 
2.28.0



[RFC PATCH v7 20/21] riscv: Allocate space for vector registers in start_thread()

2020-09-10 Thread Greentime Hu
It allocates memory space for vector registers in start_thread() instead of
allocating in vstate_restore() in this patch. We can allocate memory here
so that it will be more readable.

Signed-off-by: Greentime Hu 
Signed-off-by: Vincent Chen 
---
 arch/riscv/include/asm/switch_to.h | 7 +--
 arch/riscv/kernel/process.c| 8 
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/riscv/include/asm/switch_to.h 
b/arch/riscv/include/asm/switch_to.h
index d33a86a48f0d..58898d33bf28 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -98,12 +98,6 @@ static inline void vstate_restore(struct task_struct *task,
 {
if ((regs->status & SR_VS) != SR_VS_OFF) {
struct __riscv_v_state *vstate = &(task->thread.vstate);
-
-   /* Allocate space for vector registers. */
-   if (!vstate->datap) {
-   vstate->datap = kzalloc(riscv_vsize, GFP_ATOMIC);
-   vstate->size = riscv_vsize;
-   }
__vstate_restore(vstate, vstate->datap);
__vstate_clean(regs);
}
@@ -122,6 +116,7 @@ static inline void __switch_to_vector(struct task_struct 
*prev,
 
 #else
 #define has_vector false
+#define riscv_vsize (0)
 #define vstate_save(task, regs) do { } while (0)
 #define vstate_restore(task, regs) do { } while (0)
 #define __switch_to_vector(__prev, __next) do { } while (0)
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index fb485c9bceee..009ab4849fce 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -84,7 +84,15 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
}
 
if (has_vector) {
+   struct __riscv_v_state *vstate = &(current->thread.vstate);
+
+   /* Enable vector and allocate memory for vector registers. */
+   vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
+   if (WARN_ON(!vstate->datap))
+   return;
+   vstate->size = riscv_vsize;
regs->status |= SR_VS_INITIAL;
+
/*
 * Restore the initial value to the vector register
 * before starting the user program.
-- 
2.28.0



[RFC PATCH v7 18/21] riscv: Optimize vector registers initialization

2020-09-10 Thread Greentime Hu
This patch optimizes the initialization or invalidation of vector
registers. It can reduce the code sizes of vector_flush_cpu_state()
and reset_regs().

Signed-off-by: Greentime Hu 
Signed-off-by: Han-Kuan Chen 
---
 arch/riscv/kernel/head.S   | 30 +---
 arch/riscv/kernel/kernel_mode_vector.c | 32 ++
 2 files changed, 3 insertions(+), 59 deletions(-)

diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 74f2fd8430e0..2fbb4df368b1 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -375,39 +375,11 @@ ENTRY(reset_regs)
 
li  t1, SR_VS
csrsCSR_STATUS, t1
-   vsetvli t1, x0, e8, m1
+   vsetvli t1, x0, e8, m8
vmv.v.i v0, 0
-   vmv.v.i v1, 0
-   vmv.v.i v2, 0
-   vmv.v.i v3, 0
-   vmv.v.i v4, 0
-   vmv.v.i v5, 0
-   vmv.v.i v6, 0
-   vmv.v.i v7, 0
vmv.v.i v8, 0
-   vmv.v.i v9, 0
-   vmv.v.i v10, 0
-   vmv.v.i v11, 0
-   vmv.v.i v12, 0
-   vmv.v.i v13, 0
-   vmv.v.i v14, 0
-   vmv.v.i v15, 0
vmv.v.i v16, 0
-   vmv.v.i v17, 0
-   vmv.v.i v18, 0
-   vmv.v.i v19, 0
-   vmv.v.i v20, 0
-   vmv.v.i v21, 0
-   vmv.v.i v22, 0
-   vmv.v.i v23, 0
vmv.v.i v24, 0
-   vmv.v.i v25, 0
-   vmv.v.i v26, 0
-   vmv.v.i v27, 0
-   vmv.v.i v28, 0
-   vmv.v.i v29, 0
-   vmv.v.i v30, 0
-   vmv.v.i v31, 0
/* note that the caller must clear SR_VS */
 #endif /* CONFIG_VECTOR */
 
diff --git a/arch/riscv/kernel/kernel_mode_vector.c 
b/arch/riscv/kernel/kernel_mode_vector.c
index 108cfafe7496..b84618630edf 100644
--- a/arch/riscv/kernel/kernel_mode_vector.c
+++ b/arch/riscv/kernel/kernel_mode_vector.c
@@ -86,39 +86,11 @@ static void vector_flush_cpu_state(void)
long tmp;
 
__asm__ __volatile__ (
-   "vsetvli %0, x0, e8, m1\n"
+   "vsetvli %0, x0, e8, m8\n"
"vmv.v.i v0, 0\n"
-   "vmv.v.i v1, 0\n"
-   "vmv.v.i v2, 0\n"
-   "vmv.v.i v3, 0\n"
-   "vmv.v.i v4, 0\n"
-   "vmv.v.i v5, 0\n"
-   "vmv.v.i v6, 0\n"
-   "vmv.v.i v7, 0\n"
"vmv.v.i v8, 0\n"
-   "vmv.v.i v9, 0\n"
-   "vmv.v.i v10, 0\n"
-   "vmv.v.i v11, 0\n"
-   "vmv.v.i v12, 0\n"
-   "vmv.v.i v13, 0\n"
-   "vmv.v.i v14, 0\n"
-   "vmv.v.i v15, 0\n"
"vmv.v.i v16, 0\n"
-   "vmv.v.i v17, 0\n"
-   "vmv.v.i v18, 0\n"
-   "vmv.v.i v19, 0\n"
-   "vmv.v.i v20, 0\n"
-   "vmv.v.i v21, 0\n"
-   "vmv.v.i v22, 0\n"
-   "vmv.v.i v23, 0\n"
-   "vmv.v.i v24, 0\n"
-   "vmv.v.i v25, 0\n"
-   "vmv.v.i v26, 0\n"
-   "vmv.v.i v27, 0\n"
-   "vmv.v.i v28, 0\n"
-   "vmv.v.i v29, 0\n"
-   "vmv.v.i v30, 0\n"
-   "vmv.v.i v31, 0\n":"=r"(tmp)::);
+   "vmv.v.i v24, 0\n":"=r"(tmp)::);
 }
 
 /*
-- 
2.28.0



[RFC PATCH v7 19/21] riscv: Fix an illegal instruction exception when accessing vlenb without enable vector first

2020-09-10 Thread Greentime Hu
It triggered an illegal instruction exception when accessing vlenb CSR
without enable vector first. To fix this issue, we should enable vector
before using it and disable vector after using it.

Signed-off-by: Greentime Hu 
---
 arch/riscv/include/asm/vector.h| 2 ++
 arch/riscv/kernel/cpufeature.c | 3 +++
 arch/riscv/kernel/kernel_mode_vector.c | 6 --
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index 3fc8d84e23c6..a99bbda7f4ba 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -10,6 +10,8 @@
 
 #include 
 
+void rvv_enable(void);
+void rvv_disable(void);
 void kernel_rvv_begin(void);
 void kernel_rvv_end(void);
 
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 4d4f78f6a5db..817980d38603 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -22,6 +22,7 @@ static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) 
__read_mostly;
 bool has_fpu __read_mostly;
 #endif
 #ifdef CONFIG_VECTOR
+#include 
 bool has_vector __read_mostly;
 unsigned long riscv_vsize __read_mostly;
 #endif
@@ -158,7 +159,9 @@ void riscv_fill_hwcap(void)
if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
has_vector = true;
/* There are 32 vector registers with vlenb length. */
+   rvv_enable();
riscv_vsize = csr_read(CSR_VLENB) * 32;
+   rvv_disable();
}
 #endif
 }
diff --git a/arch/riscv/kernel/kernel_mode_vector.c 
b/arch/riscv/kernel/kernel_mode_vector.c
index b84618630edf..0d990bd8b8dd 100644
--- a/arch/riscv/kernel/kernel_mode_vector.c
+++ b/arch/riscv/kernel/kernel_mode_vector.c
@@ -71,15 +71,17 @@ static void put_cpu_vector_context(void)
preempt_enable();
 }
 
-static void rvv_enable(void)
+void rvv_enable(void)
 {
csr_set(CSR_STATUS, SR_VS);
 }
+EXPORT_SYMBOL(rvv_enable);
 
-static void rvv_disable(void)
+void rvv_disable(void)
 {
csr_clear(CSR_STATUS, SR_VS);
 }
+EXPORT_SYMBOL(rvv_disable);
 
 static void vector_flush_cpu_state(void)
 {
-- 
2.28.0



[RFC PATCH v7 16/21] riscv: Add vector extension XOR implementation

2020-09-10 Thread Greentime Hu
This patch adds support for vector optimized XOR it is tested in spike and
qemu.

Logs in spike:
[0.008365] xor: measuring software checksum speed
[0.048885]8regs :  1719.000 MB/sec
[0.089080]32regs:  1717.000 MB/sec
[0.129275]rvv   :  7043.000 MB/sec
[0.129525] xor: using function: rvv (7043.000 MB/sec)

Logs in qemu:
[0.098943] xor: measuring software checksum speed
[0.139391]8regs :  2911.000 MB/sec
[0.181079]32regs:  2813.000 MB/sec
[0.224260]rvv   :45.000 MB/sec
[0.225586] xor: using function: 8regs (2911.000 MB/sec)

Signed-off-by: Han-Kuan Chen 
Signed-off-by: Greentime Hu 
---
 arch/riscv/include/asm/xor.h | 74 
 arch/riscv/lib/Makefile  |  1 +
 arch/riscv/lib/xor.S | 81 
 3 files changed, 156 insertions(+)
 create mode 100644 arch/riscv/include/asm/xor.h
 create mode 100644 arch/riscv/lib/xor.S

diff --git a/arch/riscv/include/asm/xor.h b/arch/riscv/include/asm/xor.h
new file mode 100644
index ..60ee0224913d
--- /dev/null
+++ b/arch/riscv/include/asm/xor.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 SiFive
+ */
+
+#include 
+#include 
+#ifdef CONFIG_VECTOR
+#include 
+
+extern void xor_regs_2_(unsigned long bytes, unsigned long *p1,
+   unsigned long *p2);
+extern void xor_regs_3_(unsigned long bytes, unsigned long *p1,
+   unsigned long *p2, unsigned long *p3);
+extern void xor_regs_4_(unsigned long bytes, unsigned long *p1,
+   unsigned long *p2, unsigned long *p3,
+   unsigned long *p4);
+extern void xor_regs_5_(unsigned long bytes, unsigned long *p1,
+   unsigned long *p2, unsigned long *p3, unsigned long *p4,
+   unsigned long *p5);
+
+static void xor_rvv_2(unsigned long bytes, unsigned long *p1, unsigned long 
*p2)
+{
+   kernel_rvv_begin();
+   xor_regs_2_(bytes, p1, p2);
+   kernel_rvv_end();
+}
+
+static void
+xor_rvv_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3)
+{
+   kernel_rvv_begin();
+   xor_regs_3_(bytes, p1, p2, p3);
+   kernel_rvv_end();
+}
+
+static void
+xor_rvv_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3, unsigned long *p4)
+{
+   kernel_rvv_begin();
+   xor_regs_4_(bytes, p1, p2, p3, p4);
+   kernel_rvv_end();
+}
+
+static void
+xor_rvv_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3, unsigned long *p4, unsigned long *p5)
+{
+   kernel_rvv_begin();
+   xor_regs_5_(bytes, p1, p2, p3, p4, p5);
+   kernel_rvv_end();
+}
+
+static struct xor_block_template xor_block_rvv = {
+   .name = "rvv",
+   .do_2 = xor_rvv_2,
+   .do_3 = xor_rvv_3,
+   .do_4 = xor_rvv_4,
+   .do_5 = xor_rvv_5
+};
+
+extern bool has_vector;
+#undef XOR_TRY_TEMPLATES
+#define XOR_TRY_TEMPLATES   \
+   do {\
+   xor_speed(_block_8regs);\
+   xor_speed(_block_32regs);\
+   if (has_vector) { \
+   xor_speed(_block_rvv);\
+   } \
+   } while (0)
+#endif
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 0d0db80800c4..cedf8d573dc3 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -4,3 +4,4 @@ lib-y   += memcpy.o
 lib-y  += memset.o
 lib-y  += uaccess.o
 lib-$(CONFIG_64BIT)+= tishift.o
+lib-$(CONFIG_VECTOR)   += xor.o
diff --git a/arch/riscv/lib/xor.S b/arch/riscv/lib/xor.S
new file mode 100644
index ..de2e234c39ed
--- /dev/null
+++ b/arch/riscv/lib/xor.S
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 SiFive
+ */
+#include 
+#include 
+#include 
+
+ENTRY(xor_regs_2_)
+   vsetvli a3, a0, e8, m8
+   vle8.v v0, (a1)
+   vle8.v v8, (a2)
+   sub a0, a0, a3
+   vxor.vv v16, v0, v8
+   add a2, a2, a3
+   vse8.v v16, (a1)
+   add a1, a1, a3
+   bnez a0, xor_regs_2_
+   ret
+END(xor_regs_2_)
+EXPORT_SYMBOL(xor_regs_2_)
+
+ENTRY(xor_regs_3_)
+   vsetvli a4, a0, e8, m8
+   vle8.v v0, (a1)
+   vle8.v v8, (a2)
+   sub a0, a0, a4
+   vxor.vv v0, v0, v8
+   vle8.v v16, (a3)
+   add a2, a2, a4
+   vxor.vv v16, v0, v16
+   add a3, a3, a4
+   vse8.v v16, (a1)
+   add a1, a1, a4
+   bnez a0, xor_regs_3_
+   ret
+END(xor_regs_3_)
+EXPORT_SYMBOL(xor_regs_3_)
+
+ENTRY(xor_regs_4_)
+   vsetvli a5, a0, e8, m8
+   vle8.v v0, (a1)
+   vle8.v v8, (a2)
+   sub a0, a0, a5
+   vxor.vv v0, v0, v8
+   vle8.v v16, (a3)
+   add a2, a2, a5
+   vxor.vv v0, v0, v16
+   vle8.v v24, (a4)
+   add a3, a3, a5
+   vxor.vv v1

[RFC PATCH v7 17/21] riscv: Initialize vector registers with proper vsetvli then it can work normally

2020-09-10 Thread Greentime Hu
It may cause an illegal instruction exception if it doesn't use vsetvli
before vmv.v.i v0, 0.

Signed-off-by: Han-Kuan Chen 
Signed-off-by: Greentime Hu 
---
 arch/riscv/kernel/head.S | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index e97c7915ae27..74f2fd8430e0 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -375,6 +375,7 @@ ENTRY(reset_regs)
 
li  t1, SR_VS
csrsCSR_STATUS, t1
+   vsetvli t1, x0, e8, m1
vmv.v.i v0, 0
vmv.v.i v1, 0
vmv.v.i v2, 0
-- 
2.28.0



[RFC PATCH v7 14/21] riscv: Add support for kernel mode vector

2020-09-10 Thread Greentime Hu
Add  containing kernel_rvv_begin()/kernel_rvv_end() function
declarations and corresponding definitions in kernel_mode_vector.c

These are needed to wrap uses of vector in kernel mode.

Signed-off-by: Greentime Hu 
---
 arch/riscv/include/asm/vector.h|  16 +++
 arch/riscv/kernel/Makefile |   6 +
 arch/riscv/kernel/kernel_mode_vector.c | 184 +
 3 files changed, 206 insertions(+)
 create mode 100644 arch/riscv/include/asm/vector.h
 create mode 100644 arch/riscv/kernel/kernel_mode_vector.c

diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
new file mode 100644
index ..3fc8d84e23c6
--- /dev/null
+++ b/arch/riscv/include/asm/vector.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * linux/arch/riscv/include/asm/vector.h
+ *
+ * Copyright (C) 2020 SiFive
+ */
+
+#ifndef __ASM_RISCV_VECTOR_H
+#define __ASM_RISCV_VECTOR_H
+
+#include 
+
+void kernel_rvv_begin(void);
+void kernel_rvv_end(void);
+
+#endif /* ! __ASM_RISCV_VECTOR_H */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 3a166c21ea49..09f092f54d48 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -34,6 +34,12 @@ obj-$(CONFIG_MMU) += vdso.o vdso/
 obj-$(CONFIG_RISCV_M_MODE) += traps_misaligned.o
 obj-$(CONFIG_FPU)  += fpu.o
 obj-$(CONFIG_VECTOR)   += vector.o
+obj-$(CONFIG_VECTOR)   += kernel_mode_vector.o
+riscv-march-cflags-$(CONFIG_ARCH_RV32I):= rv32ima
+riscv-march-cflags-$(CONFIG_ARCH_RV64I):= rv64ima
+riscv-march-cflags-$(CONFIG_RISCV_ISA_C)   := $(riscv-march-cflags-y)c
+riscv-march-cflags-$(CONFIG_VECTOR):= $(riscv-march-cflags-y)v
+CFLAGS_kernel_mode_vector.o+= -march=$(riscv-march-cflags-y)
 obj-$(CONFIG_SMP)  += smpboot.o
 obj-$(CONFIG_SMP)  += smp.o
 obj-$(CONFIG_SMP)  += cpu_ops.o
diff --git a/arch/riscv/kernel/kernel_mode_vector.c 
b/arch/riscv/kernel/kernel_mode_vector.c
new file mode 100644
index ..108cfafe7496
--- /dev/null
+++ b/arch/riscv/kernel/kernel_mode_vector.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ * Author: Catalin Marinas 
+ * Copyright (C) 2017 Linaro Ltd. 
+ * Copyright (C) 2020 SiFive
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+DECLARE_PER_CPU(bool, vector_context_busy);
+DEFINE_PER_CPU(bool, vector_context_busy);
+
+/*
+ * may_use_vector - whether it is allowable at this time to issue vector
+ *instructions or access the vector register file
+ *
+ * Callers must not assume that the result remains true beyond the next
+ * preempt_enable() or return from softirq context.
+ */
+static __must_check inline bool may_use_vector(void)
+{
+   /*
+* vector_context_busy is only set while preemption is disabled,
+* and is clear whenever preemption is enabled. Since
+* this_cpu_read() is atomic w.r.t. preemption, vector_context_busy
+* cannot change under our feet -- if it's set we cannot be
+* migrated, and if it's clear we cannot be migrated to a CPU
+* where it is set.
+*/
+   return !in_irq() && !irqs_disabled() && !in_nmi() &&
+  !this_cpu_read(vector_context_busy);
+}
+
+
+
+/*
+ * Claim ownership of the CPU vector context for use by the calling context.
+ *
+ * The caller may freely manipulate the vector context metadata until
+ * put_cpu_vector_context() is called.
+ */
+static void get_cpu_vector_context(void)
+{
+   bool busy;
+
+   preempt_disable();
+   busy = __this_cpu_xchg(vector_context_busy, true);
+
+   WARN_ON(busy);
+}
+
+/*
+ * Release the CPU vector context.
+ *
+ * Must be called from a context in which get_cpu_vector_context() was
+ * previously called, with no call to put_cpu_vector_context() in the
+ * meantime.
+ */
+static void put_cpu_vector_context(void)
+{
+   bool busy = __this_cpu_xchg(vector_context_busy, false);
+
+   WARN_ON(!busy);
+   preempt_enable();
+}
+
+static void rvv_enable(void)
+{
+   csr_set(CSR_STATUS, SR_VS);
+}
+
+static void rvv_disable(void)
+{
+   csr_clear(CSR_STATUS, SR_VS);
+}
+
+static void vector_flush_cpu_state(void)
+{
+   long tmp;
+
+   __asm__ __volatile__ (
+   "vsetvli %0, x0, e8, m1\n"
+   "vmv.v.i v0, 0\n"
+   "vmv.v.i v1, 0\n"
+   "vmv.v.i v2, 0\n"
+   "vmv.v.i v3, 0\n"
+   "vmv.v.i v4, 0\n"
+   "vmv.v.i v5, 0\n"
+   "vmv.v.i v6, 0\n"
+   "vmv.v.i v7, 0\n"
+   "vmv.v.i v8, 0\n"
+   "vmv.v.i v9, 0\n"
+   "vmv.v.i v10, 0\n"
+   "vmv.v.i

[RFC PATCH v7 11/21] riscv: Add ptrace vector support

2020-09-10 Thread Greentime Hu
This patch adds ptrace support for riscv vector. The vector registers will
be saved in datap pointer of __riscv_v_state. This pointer will be set
right after the __riscv_v_state data structure then it will be put in ubuf
for ptrace system call to get or set. It will check if the datap got from
ubuf is set to the correct address or not when the ptrace system call is
trying to set the vector registers.

[guo...@linux.alibaba.com: Add the first version porting to support vector
of ptrace]
Signed-off-by: Greentime Hu 
Signed-off-by: Guo Ren 
---
 arch/riscv/include/uapi/asm/ptrace.h | 18 +++
 arch/riscv/kernel/ptrace.c   | 74 
 include/uapi/linux/elf.h |  1 +
 3 files changed, 93 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/ptrace.h 
b/arch/riscv/include/uapi/asm/ptrace.h
index 661b0466b850..42144fe6acee 100644
--- a/arch/riscv/include/uapi/asm/ptrace.h
+++ b/arch/riscv/include/uapi/asm/ptrace.h
@@ -80,16 +80,34 @@ union __riscv_fp_state {
 struct __riscv_v_state {
__u32 magic;
__u32 size;
+   /*
+* This is the size of vector registers not including
+* __riscv_v_state itself.
+*/
unsigned long vstart;
unsigned long vl;
unsigned long vtype;
unsigned long vcsr;
void *datap;
+   /*
+* In signal handler, datap will be set a correct user stack offset
+* and vector registers will be copied to the address of datap
+* pointer.
+*
+* In ptrace syscall, datap will be set to zero and the vector
+* registers will be copied to the address right after this
+* structure.
+*/
 #if __riscv_xlen == 32
__u32 __padding;
 #endif
 } __attribute__((aligned(16)));
 
+/*
+ * To define a practical maximum vlenb for ptrace and it may need to be
+ * extended someday.
+ */
+#define RISCV_MAX_VLENB (16384)
 #endif /* __ASSEMBLY__ */
 
 #endif /* _UAPI_ASM_RISCV_PTRACE_H */
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 2d6395f5ad54..c5f96b4e3df9 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -26,6 +27,9 @@ enum riscv_regset {
 #ifdef CONFIG_FPU
REGSET_F,
 #endif
+#ifdef CONFIG_VECTOR
+   REGSET_V,
+#endif
 };
 
 static int riscv_gpr_get(struct task_struct *target,
@@ -81,6 +85,66 @@ static int riscv_fpr_set(struct task_struct *target,
 }
 #endif
 
+#ifdef CONFIG_VECTOR
+static int riscv_vr_get(struct task_struct *target,
+   const struct user_regset *regset,
+   struct membuf to)
+{
+   struct __riscv_v_state *vstate = >thread.vstate;
+   __u32 magic = RVV_MAGIC;
+
+   /* Copy magic number */
+   membuf_store(, magic);
+   /* Copy vector header from vstate. */
+   membuf_write(, &(vstate->size), RISCV_V_STATE_DATAP - 
RISCV_V_STATE_SIZE);
+   membuf_zero(, sizeof(void *));
+#if __riscv_xlen == 32
+   membuf_zero(, sizeof(__u32));
+#endif
+   /* Copy all the vector registers from vstate. */
+   return membuf_write(, vstate->datap, vstate->size);
+}
+
+static int riscv_vr_set(struct task_struct *target,
+const struct user_regset *regset,
+unsigned int pos, unsigned int count,
+const void *kbuf, const void __user *ubuf)
+{
+   int ret, size;
+   struct __riscv_v_state *vstate = >thread.vstate;
+
+   /* Skip copy magic because kernel doesn't need to use it. */
+   size = sizeof(vstate->magic);
+   pos += size;
+   count -= size;
+   ubuf += size;
+
+   /* Copy rest of the vstate except datap and __padding. */
+   ret = user_regset_copyin(, , , , vstate, 0,
+RISCV_V_STATE_DATAP);
+   if (unlikely(ret))
+   return ret;
+
+   /* Skip copy datap. */
+   size = sizeof(vstate->datap);
+   count -= size;
+   ubuf += size;
+
+#if __riscv_xlen == 32
+   /* Skip copy _padding. */
+   size = sizeof(vstate->__padding);
+   count -= size;
+   ubuf += size;
+#endif
+
+   /* Copy all the vector registers. */
+   pos = 0;
+   ret = user_regset_copyin(, , , , vstate->datap,
+0, vstate->size);
+   return ret;
+}
+#endif
+
 static const struct user_regset riscv_user_regset[] = {
[REGSET_X] = {
.core_note_type = NT_PRSTATUS,
@@ -100,6 +164,16 @@ static const struct user_regset riscv_user_regset[] = {
.set = riscv_fpr_set,
},
 #endif
+#ifdef CONFIG_VECTOR
+   [REGSET_V] = {
+   .core_note_type = NT_RISCV_VECTOR,
+   .align = 16,
+   .n = (32 * RISCV_MAX_VLENB)/sizeof(__u32),
+   .size = sizeof(__u32),
+   .regset_get = 

[RFC PATCH v7 13/21] riscv: signal: Report signal frame size to userspace via auxv

2020-09-10 Thread Greentime Hu
From: Vincent Chen 

The vector register belongs to the signal context. They need to be stored
and restored as entering and leaving the signal handler. According to the
V-extension specification, the maximum length of the vector registers can
be 2^(XLEN-1). Hence, if userspace refers to the MINSIGSTKSZ #define
(2KB) to create a sigframe, it may not be enough. To resolve this problem,
this patch refers to the commit 94b07c1f8c39c
("arm64: signal: Report signal frame size to userspace via auxv") to enable
userspace to know the minimum required sigframe size through the auxiliary
vector and use it to allocate enough memory for signal context.

Signed-off-by: Vincent Chen 
---
 arch/riscv/include/asm/elf.h | 17 +
 arch/riscv/include/asm/processor.h   |  2 ++
 arch/riscv/include/uapi/asm/auxvec.h |  2 ++
 arch/riscv/kernel/setup.c|  5 +
 arch/riscv/kernel/signal.c   | 16 
 5 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index d83a4efd052b..b6b15fc5f784 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -57,10 +57,19 @@ extern unsigned long elf_hwcap;
 #define ELF_PLATFORM   (NULL)
 
 #ifdef CONFIG_MMU
-#define ARCH_DLINFO\
-do {   \
-   NEW_AUX_ENT(AT_SYSINFO_EHDR,\
-   (elf_addr_t)current->mm->context.vdso); \
+#define ARCH_DLINFO \
+do {\
+   NEW_AUX_ENT(AT_SYSINFO_EHDR, \
+   (elf_addr_t)current->mm->context.vdso);  \
+   /*   \
+* Should always be nonzero unless there's a kernel bug. \
+* If we haven't determined a sensible value to give to  \
+* userspace, omit the entry:\
+*/  \
+   if (likely(signal_minsigstksz))  \
+   NEW_AUX_ENT(AT_MINSIGSTKSZ, signal_minsigstksz); \
+   else \
+   NEW_AUX_ENT(AT_IGNORE, 0);   \
 } while (0)
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
 struct linux_binprm;
diff --git a/arch/riscv/include/asm/processor.h 
b/arch/riscv/include/asm/processor.h
index a66a5d4ee5ad..bcf004435f26 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -7,6 +7,7 @@
 #define _ASM_RISCV_PROCESSOR_H
 
 #include 
+#include 
 
 #include 
 
@@ -72,6 +73,7 @@ int riscv_of_parent_hartid(struct device_node *node);
 
 extern void riscv_fill_hwcap(void);
 
+extern unsigned long signal_minsigstksz __ro_after_init;
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_RISCV_PROCESSOR_H */
diff --git a/arch/riscv/include/uapi/asm/auxvec.h 
b/arch/riscv/include/uapi/asm/auxvec.h
index d86cb17bbabe..9745a01e5e61 100644
--- a/arch/riscv/include/uapi/asm/auxvec.h
+++ b/arch/riscv/include/uapi/asm/auxvec.h
@@ -10,4 +10,6 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR 33
 
+#define AT_MINSIGSTKSZ 51
+
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index 2c6dd329312b..f020fd627202 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -60,6 +61,8 @@ void __init parse_dtb(void)
 #endif
 }
 
+extern void __init minsigstksz_setup(void);
+
 void __init setup_arch(char **cmdline_p)
 {
init_mm.start_code = (unsigned long) _stext;
@@ -96,6 +99,8 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
riscv_fill_hwcap();
+
+   minsigstksz_setup();
 }
 
 static int __init topology_init(void)
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index d27bd39a3490..b3f5375267cd 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -404,3 +404,19 @@ asmlinkage __visible void do_notify_resume(struct pt_regs 
*regs,
tracehook_notify_resume(regs);
}
 }
+
+unsigned long __ro_after_init signal_minsigstksz;
+
+/*
+ * Determine the stack space required for guaranteed signal devliery.
+ * This function is used to populate AT_MINSIGSTKSZ at process startup.
+ * cpufeatures setup is assumed to be complete.
+ */
+void __init minsigstksz_setup(void)
+{
+   signal_minsigstksz = sizeof(struct rt_sigframe);
+#ifdef CONFIG_VECTOR
+   if (has_vector)
+   signal_minsigstksz += riscv_vsize;
+#endif
+}
-- 
2.28.0



[RFC PATCH v7 08/21] riscv: Add vector struct and assembler definitions

2020-09-10 Thread Greentime Hu
Add vector state context struct in struct thread and asm-offsets.c
definitions.

The vector registers will be saved in datap pointer of __riscv_v_state. It
will be dynamically allocated in kernel space. It will be put right after
the __riscv_v_state data structure in user space.

[guo...@linux.alibaba.com: first version vector porting]
Signed-off-by: Greentime Hu 
Signed-off-by: Guo Ren 
---
 arch/riscv/include/asm/processor.h   |  1 +
 arch/riscv/include/uapi/asm/ptrace.h | 13 +
 arch/riscv/kernel/asm-offsets.c  |  8 
 3 files changed, 22 insertions(+)

diff --git a/arch/riscv/include/asm/processor.h 
b/arch/riscv/include/asm/processor.h
index bdddcd5c1b71..a66a5d4ee5ad 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -34,6 +34,7 @@ struct thread_struct {
unsigned long sp;   /* Kernel mode stack */
unsigned long s[12];/* s[0]: frame pointer */
struct __riscv_d_ext_state fstate;
+   struct __riscv_v_state vstate;
 };
 
 #define INIT_THREAD {  \
diff --git a/arch/riscv/include/uapi/asm/ptrace.h 
b/arch/riscv/include/uapi/asm/ptrace.h
index 882547f6bd5c..661b0466b850 100644
--- a/arch/riscv/include/uapi/asm/ptrace.h
+++ b/arch/riscv/include/uapi/asm/ptrace.h
@@ -77,6 +77,19 @@ union __riscv_fp_state {
struct __riscv_q_ext_state q;
 };
 
+struct __riscv_v_state {
+   __u32 magic;
+   __u32 size;
+   unsigned long vstart;
+   unsigned long vl;
+   unsigned long vtype;
+   unsigned long vcsr;
+   void *datap;
+#if __riscv_xlen == 32
+   __u32 __padding;
+#endif
+} __attribute__((aligned(16)));
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _UAPI_ASM_RISCV_PTRACE_H */
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index db203442c08f..f6fa65a6aaf0 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -67,6 +67,14 @@ void asm_offsets(void)
OFFSET(TASK_THREAD_F31, task_struct, thread.fstate.f[31]);
OFFSET(TASK_THREAD_FCSR, task_struct, thread.fstate.fcsr);
 
+   OFFSET(RISCV_V_STATE_MAGIC, __riscv_v_state, magic);
+   OFFSET(RISCV_V_STATE_SIZE, __riscv_v_state, size);
+   OFFSET(RISCV_V_STATE_VSTART, __riscv_v_state, vstart);
+   OFFSET(RISCV_V_STATE_VL, __riscv_v_state, vl);
+   OFFSET(RISCV_V_STATE_VTYPE, __riscv_v_state, vtype);
+   OFFSET(RISCV_V_STATE_VCSR, __riscv_v_state, vcsr);
+   OFFSET(RISCV_V_STATE_DATAP, __riscv_v_state, datap);
+
DEFINE(PT_SIZE, sizeof(struct pt_regs));
OFFSET(PT_EPC, pt_regs, epc);
OFFSET(PT_RA, pt_regs, ra);
-- 
2.28.0



[RFC PATCH v7 12/21] riscv: Add sigcontext save/restore for vector

2020-09-10 Thread Greentime Hu
This patch adds sigcontext save/restore for vector. The vector registers
will be saved in datap pointer. The datap pointer will be allocaed
dynamically when the task needs in kernel space. The datap pointer will
be set right after the __riscv_v_state data structure to save all the
vector registers in the signal handler stack.

[guo...@linux.alibaba.com: add the first porting for vector signal and
sigcontext support]
Signed-off-by: Greentime Hu 
Signed-off-by: Guo Ren 
---
 arch/riscv/include/uapi/asm/sigcontext.h |  2 +
 arch/riscv/kernel/signal.c   | 92 +++-
 2 files changed, 91 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/include/uapi/asm/sigcontext.h 
b/arch/riscv/include/uapi/asm/sigcontext.h
index 84f2dfcfdbce..4217f3f1c8ba 100644
--- a/arch/riscv/include/uapi/asm/sigcontext.h
+++ b/arch/riscv/include/uapi/asm/sigcontext.h
@@ -8,6 +8,7 @@
 
 #include 
 
+#define RVV_MAGIC  0x53465457
 /*
  * Signal context structure
  *
@@ -17,6 +18,7 @@
 struct sigcontext {
struct user_regs_struct sc_regs;
union __riscv_fp_state sc_fpregs;
+   struct __riscv_v_state sc_vregs;
 };
 
 #endif /* _UAPI_ASM_RISCV_SIGCONTEXT_H */
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index e996e08f1061..d27bd39a3490 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -83,6 +83,80 @@ static long save_fp_state(struct pt_regs *regs,
 #define restore_fp_state(task, regs) (0)
 #endif
 
+#ifdef CONFIG_VECTOR
+static long restore_v_state(struct pt_regs *regs, struct sigcontext *sc)
+{
+   long err;
+   struct __riscv_v_state __user *state = >sc_vregs;
+   void *datap;
+   __u32 magic;
+
+   /* Get magic number and check it. */
+   err = __get_user(magic, >magic);
+   if (unlikely(err))
+   return err;
+
+   if (magic != RVV_MAGIC)
+   return -EINVAL;
+
+   /* Copy everything of __riscv_v_state except datap. */
+   err = __copy_from_user(>thread.vstate, state,
+  RISCV_V_STATE_DATAP);
+   if (unlikely(err))
+   return err;
+
+   /* Copy the pointer datap itself. */
+   err = __get_user(datap, >datap);
+   if (unlikely(err))
+   return err;
+
+
+   /* Copy the whole vector content from user space datap. */
+   err = __copy_from_user(current->thread.vstate.datap, datap,
+  current->thread.vstate.size);
+   if (unlikely(err))
+   return err;
+
+   vstate_restore(current, regs);
+
+   return err;
+}
+
+static long save_v_state(struct pt_regs *regs, struct sigcontext *sc)
+{
+   long err;
+   struct __riscv_v_state __user *state = >sc_vregs;
+   /* Set the datap right after the sigcntext structure. */
+   void *datap = sc + 1;
+
+   vstate_save(current, regs);
+   /* Copy everything of vstate but datap. */
+   err = __copy_to_user(state, >thread.vstate,
+RISCV_V_STATE_DATAP);
+   if (unlikely(err))
+   return err;
+
+   /* Copy the magic number. */
+   err = __put_user(RVV_MAGIC, >magic);
+   if (unlikely(err))
+   return err;
+
+   /* Copy the pointer datap itself. */
+   err = __put_user(datap, >datap);
+   if (unlikely(err))
+   return err;
+
+   /* Copy the whole vector content to user space datap. */
+   err = __copy_to_user(datap, current->thread.vstate.datap,
+current->thread.vstate.size);
+
+   return err;
+}
+#else
+#define save_v_state(task, regs) (0)
+#define restore_v_state(task, regs) (0)
+#endif
+
 static long restore_sigcontext(struct pt_regs *regs,
struct sigcontext __user *sc)
 {
@@ -92,6 +166,9 @@ static long restore_sigcontext(struct pt_regs *regs,
/* Restore the floating-point state. */
if (has_fpu)
err |= restore_fp_state(regs, >sc_fpregs);
+   /* Restore the vector state. */
+   if (has_vector)
+   err |= restore_v_state(regs, sc);
return err;
 }
 
@@ -101,13 +178,16 @@ SYSCALL_DEFINE0(rt_sigreturn)
struct rt_sigframe __user *frame;
struct task_struct *task;
sigset_t set;
+   size_t frame_size = sizeof(*frame);
 
/* Always make any pending restarted system calls return -EINTR */
current->restart_block.fn = do_no_restart_syscall;
 
frame = (struct rt_sigframe __user *)regs->sp;
 
-   if (!access_ok(frame, sizeof(*frame)))
+   if (has_vector)
+   frame_size += current->thread.vstate.size;
+   if (!access_ok(frame, frame_size))
goto badframe;
 
if (__copy_from_user(, >uc.uc_sigmask, sizeof(set)))
@@ -145,6 +225,9 @@ static long setup_sigcontext(struct rt_sigframe __user 
*frame,
/* Save the floating-point state. */
if (has_fpu)
  

[RFC PATCH v7 10/21] riscv: Add task switch support for vector

2020-09-10 Thread Greentime Hu
This patch adds task switch support for vector. It supports partial lazy
save and restore mechanism. It also supports all lengths of vlen.

[guo...@linux.alibaba.com: First available porting to support vector
context switching]
[nick.kni...@sifive.com: Rewrite vector.S to support dynamic vlen, xlen and
code refine]
[vincent.c...@sifive.co: Fix the might_sleep issue in vstate_save,
vstate_restore]
Signed-off-by: Nick Knight 
Signed-off-by: Greentime Hu 
Signed-off-by: Guo Ren 
Signed-off-by: Vincent Chen 
---
 arch/riscv/include/asm/switch_to.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/riscv/include/asm/switch_to.h 
b/arch/riscv/include/asm/switch_to.h
index 2afd0124701a..d33a86a48f0d 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -87,6 +87,7 @@ static inline void vstate_save(struct task_struct *task,
 {
if ((regs->status & SR_VS) == SR_VS_DIRTY) {
struct __riscv_v_state *vstate = &(task->thread.vstate);
+
__vstate_save(vstate, vstate->datap);
__vstate_clean(regs);
}
-- 
2.28.0



[RFC PATCH v7 09/21] riscv: Add task switch support for vector

2020-09-10 Thread Greentime Hu
This patch adds task switch support for vector. It supports partial lazy
save and restore mechanism. It also supports all lengths of vlen.

[guo...@linux.alibaba.com: First available porting to support vector
context switching]
[nick.kni...@sifive.com: Rewrite vector.S to support dynamic vlen, xlen and
code refine]
[vincent.c...@sifive.co: Fix the might_sleep issue in vstate_save,
vstate_restore]
Signed-off-by: Nick Knight 
Signed-off-by: Greentime Hu 
Signed-off-by: Guo Ren 
Signed-off-by: Vincent Chen 
---
 arch/riscv/include/asm/switch_to.h | 65 +++
 arch/riscv/kernel/Makefile |  1 +
 arch/riscv/kernel/process.c| 40 ++
 arch/riscv/kernel/vector.S | 84 ++
 4 files changed, 190 insertions(+)
 create mode 100644 arch/riscv/kernel/vector.S

diff --git a/arch/riscv/include/asm/switch_to.h 
b/arch/riscv/include/asm/switch_to.h
index b9234e7178d0..2afd0124701a 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -6,10 +6,12 @@
 #ifndef _ASM_RISCV_SWITCH_TO_H
 #define _ASM_RISCV_SWITCH_TO_H
 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_FPU
 extern void __fstate_save(struct task_struct *save_to);
@@ -63,6 +65,67 @@ extern bool has_fpu;
 #define __switch_to_fpu(__prev, __next) do { } while (0)
 #endif
 
+#ifdef CONFIG_VECTOR
+extern bool has_vector;
+extern unsigned long riscv_vsize;
+extern void __vstate_save(struct __riscv_v_state *save_to, void *datap);
+extern void __vstate_restore(struct __riscv_v_state *restore_from, void 
*datap);
+
+static inline void __vstate_clean(struct pt_regs *regs)
+{
+   regs->status = (regs->status & ~(SR_VS)) | SR_VS_CLEAN;
+}
+
+static inline void vstate_off(struct task_struct *task,
+ struct pt_regs *regs)
+{
+   regs->status = (regs->status & ~SR_VS) | SR_VS_OFF;
+}
+
+static inline void vstate_save(struct task_struct *task,
+  struct pt_regs *regs)
+{
+   if ((regs->status & SR_VS) == SR_VS_DIRTY) {
+   struct __riscv_v_state *vstate = &(task->thread.vstate);
+   __vstate_save(vstate, vstate->datap);
+   __vstate_clean(regs);
+   }
+}
+
+static inline void vstate_restore(struct task_struct *task,
+ struct pt_regs *regs)
+{
+   if ((regs->status & SR_VS) != SR_VS_OFF) {
+   struct __riscv_v_state *vstate = &(task->thread.vstate);
+
+   /* Allocate space for vector registers. */
+   if (!vstate->datap) {
+   vstate->datap = kzalloc(riscv_vsize, GFP_ATOMIC);
+   vstate->size = riscv_vsize;
+   }
+   __vstate_restore(vstate, vstate->datap);
+   __vstate_clean(regs);
+   }
+}
+
+static inline void __switch_to_vector(struct task_struct *prev,
+  struct task_struct *next)
+{
+   struct pt_regs *regs;
+
+   regs = task_pt_regs(prev);
+   if (unlikely(regs->status & SR_SD))
+   vstate_save(prev, regs);
+   vstate_restore(next, task_pt_regs(next));
+}
+
+#else
+#define has_vector false
+#define vstate_save(task, regs) do { } while (0)
+#define vstate_restore(task, regs) do { } while (0)
+#define __switch_to_vector(__prev, __next) do { } while (0)
+#endif
+
 extern struct task_struct *__switch_to(struct task_struct *,
   struct task_struct *);
 
@@ -72,6 +135,8 @@ do { \
struct task_struct *__next = (next);\
if (has_fpu)\
__switch_to_fpu(__prev, __next);\
+   if (has_vector) \
+   __switch_to_vector(__prev, __next); \
((last) = __switch_to(__prev, __next)); \
 } while (0)
 
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index dc93710f0b2f..3a166c21ea49 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_MMU) += vdso.o vdso/
 
 obj-$(CONFIG_RISCV_M_MODE) += traps_misaligned.o
 obj-$(CONFIG_FPU)  += fpu.o
+obj-$(CONFIG_VECTOR)   += vector.o
 obj-$(CONFIG_SMP)  += smpboot.o
 obj-$(CONFIG_SMP)  += smp.o
 obj-$(CONFIG_SMP)  += cpu_ops.o
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 2b97c493427c..fb485c9bceee 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -82,6 +82,16 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
 */
fstate_restore(current, regs);
}
+
+   if (has_vector) {
+   regs->status |= SR_VS_INITIAL;
+   /*
+* R

[RFC PATCH v7 07/21] riscv: Reset vector register

2020-09-10 Thread Greentime Hu
From: Guo Ren 

Reset vector registers at boot-time and disable vector instructions
execution for kernel mode.

[greentime...@sifive.com: add comments]
Signed-off-by: Greentime Hu 
Signed-off-by: Guo Ren 
---
 arch/riscv/kernel/entry.S |  6 ++---
 arch/riscv/kernel/head.S  | 49 +--
 2 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 524d918f3601..c905efb6c998 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -67,10 +67,10 @@ _save_context:
 * Disable user-mode memory access as it should only be set in the
 * actual user copy routines.
 *
-* Disable the FPU to detect illegal usage of floating point in kernel
-* space.
+* Disable the FPU/Vector to detect illegal usage of floating point
+* or vector in kernel space.
 */
-   li t0, SR_SUM | SR_FS
+   li t0, SR_SUM | SR_FS | SR_VS
 
REG_L s0, TASK_TI_USER_SP(tp)
csrrc s1, CSR_STATUS, t0
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 0a4e81b8dc79..e97c7915ae27 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -204,10 +204,10 @@ pmp_done:
 .option pop
 
/*
-* Disable FPU to detect illegal usage of
+* Disable FPU & VECTOR to detect illegal usage of
 * floating point in kernel space
 */
-   li t0, SR_FS
+   li t0, SR_FS | SR_VS
csrc CSR_STATUS, t0
 
 #ifdef CONFIG_SMP
@@ -365,6 +365,51 @@ ENTRY(reset_regs)
csrwfcsr, 0
/* note that the caller must clear SR_FS */
 #endif /* CONFIG_FPU */
+
+#ifdef CONFIG_VECTOR
+   csrrt0, CSR_MISA
+   li  t1, (COMPAT_HWCAP_ISA_V >> 16)
+   sllit1, t1, 16
+   and t0, t0, t1
+   beqzt0, .Lreset_regs_done
+
+   li  t1, SR_VS
+   csrsCSR_STATUS, t1
+   vmv.v.i v0, 0
+   vmv.v.i v1, 0
+   vmv.v.i v2, 0
+   vmv.v.i v3, 0
+   vmv.v.i v4, 0
+   vmv.v.i v5, 0
+   vmv.v.i v6, 0
+   vmv.v.i v7, 0
+   vmv.v.i v8, 0
+   vmv.v.i v9, 0
+   vmv.v.i v10, 0
+   vmv.v.i v11, 0
+   vmv.v.i v12, 0
+   vmv.v.i v13, 0
+   vmv.v.i v14, 0
+   vmv.v.i v15, 0
+   vmv.v.i v16, 0
+   vmv.v.i v17, 0
+   vmv.v.i v18, 0
+   vmv.v.i v19, 0
+   vmv.v.i v20, 0
+   vmv.v.i v21, 0
+   vmv.v.i v22, 0
+   vmv.v.i v23, 0
+   vmv.v.i v24, 0
+   vmv.v.i v25, 0
+   vmv.v.i v26, 0
+   vmv.v.i v27, 0
+   vmv.v.i v28, 0
+   vmv.v.i v29, 0
+   vmv.v.i v30, 0
+   vmv.v.i v31, 0
+   /* note that the caller must clear SR_VS */
+#endif /* CONFIG_VECTOR */
+
 .Lreset_regs_done:
ret
 END(reset_regs)
-- 
2.28.0



[RFC PATCH v7 05/21] riscv: Add vector feature to compile

2020-09-10 Thread Greentime Hu
From: Guo Ren 

This patch adds a new config option which could enable assembler's
vector feature.

Signed-off-by: Guo Ren 
Reviewed-by: Greentime Hu 
---
 arch/riscv/Kconfig  | 9 +
 arch/riscv/Makefile | 1 +
 2 files changed, 10 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index df18372861d8..58673089c900 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -327,6 +327,15 @@ config FPU
 
  If you don't know what to do here, say Y.
 
+config VECTOR
+   bool "VECTOR support"
+   default n
+   help
+ Say N here if you want to disable all vector related procedure
+ in the kernel.
+
+ If you don't know what to do here, say Y.
+
 endmenu
 
 menu "Kernel features"
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 957d064bead0..7c80c95582e3 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -46,6 +46,7 @@ riscv-march-aflags-$(CONFIG_ARCH_RV32I)   := 
rv32ima
 riscv-march-aflags-$(CONFIG_ARCH_RV64I):= rv64ima
 riscv-march-aflags-$(CONFIG_FPU)   := $(riscv-march-aflags-y)fd
 riscv-march-aflags-$(CONFIG_RISCV_ISA_C)   := $(riscv-march-aflags-y)c
+riscv-march-aflags-$(CONFIG_VECTOR):= $(riscv-march-aflags-y)v
 
 KBUILD_CFLAGS += -march=$(riscv-march-cflags-y)
 KBUILD_AFLAGS += -march=$(riscv-march-aflags-y)
-- 
2.28.0



[RFC PATCH v7 06/21] riscv: Add has_vector/riscv_vsize to save vector features.

2020-09-10 Thread Greentime Hu
This patch is used to detect vector support status of CPU and use
riscv_vsize to save the size of all the vector registers. It assumes
all harts has the same capabilities in SMP system.

[guo...@linux.alibaba.com: add has_vector checking]
Signed-off-by: Greentime Hu 
Signed-off-by: Guo Ren 
---
 arch/riscv/kernel/cpufeature.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index f11ada3fa906..4d4f78f6a5db 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -21,6 +21,10 @@ static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) 
__read_mostly;
 #ifdef CONFIG_FPU
 bool has_fpu __read_mostly;
 #endif
+#ifdef CONFIG_VECTOR
+bool has_vector __read_mostly;
+unsigned long riscv_vsize __read_mostly;
+#endif
 
 /**
  * riscv_isa_extension_base() - Get base extension word
@@ -149,4 +153,12 @@ void riscv_fill_hwcap(void)
if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D))
has_fpu = true;
 #endif
+
+#ifdef CONFIG_VECTOR
+   if (elf_hwcap & COMPAT_HWCAP_ISA_V) {
+   has_vector = true;
+   /* There are 32 vector registers with vlenb length. */
+   riscv_vsize = csr_read(CSR_VLENB) * 32;
+   }
+#endif
 }
-- 
2.28.0



[RFC PATCH v7 04/21] riscv: Add new csr defines related to vector extension

2020-09-10 Thread Greentime Hu
Follow the riscv vector spec to add new csr numbers.

[guo...@linux.alibaba.com: first porting for new vector related csr]
Signed-off-by: Greentime Hu 
Signed-off-by: Guo Ren 
Acked-by: Guo Ren 
---
 arch/riscv/include/asm/csr.h | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index cec462e198ce..0d4c89fb97b5 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -24,6 +24,12 @@
 #define SR_FS_CLEAN_AC(0x4000, UL)
 #define SR_FS_DIRTY_AC(0x6000, UL)
 
+#define SR_VS   _AC(0x0600, UL) /* Vector Status */
+#define SR_VS_OFF   _AC(0x, UL)
+#define SR_VS_INITIAL   _AC(0x0200, UL)
+#define SR_VS_CLEAN _AC(0x0400, UL)
+#define SR_VS_DIRTY _AC(0x0600, UL)
+
 #define SR_XS  _AC(0x00018000, UL) /* Extension Status */
 #define SR_XS_OFF  _AC(0x, UL)
 #define SR_XS_INITIAL  _AC(0x8000, UL)
@@ -31,9 +37,9 @@
 #define SR_XS_DIRTY_AC(0x00018000, UL)
 
 #ifndef CONFIG_64BIT
-#define SR_SD  _AC(0x8000, UL) /* FS/XS dirty */
+#define SR_SD  _AC(0x8000, UL) /* FS/VS/XS dirty */
 #else
-#define SR_SD  _AC(0x8000, UL) /* FS/XS dirty */
+#define SR_SD  _AC(0x8000, UL) /* FS/VS/XS dirty */
 #endif
 
 /* SATP flags */
@@ -111,6 +117,12 @@
 #define CSR_PMPADDR0   0x3b0
 #define CSR_MHARTID0xf14
 
+#define CSR_VSTART 0x8
+#define CSR_VCSR   0xf
+#define CSR_VL 0xc20
+#define CSR_VTYPE  0xc21
+#define CSR_VLENB  0xc22
+
 #ifdef CONFIG_RISCV_M_MODE
 # define CSR_STATUSCSR_MSTATUS
 # define CSR_IECSR_MIE
-- 
2.28.0



[RFC PATCH v7 03/21] riscv: Extending cpufeature.c to detect V-extension

2020-09-10 Thread Greentime Hu
From: Guo Ren 

Current cpufeature.c doesn't support detecting V-extension, because
"rv64" also contain a 'v' letter and we need to skip it.

Signed-off-by: Guo Ren 
Reviewed-by: Anup Patel 
Reviewed-by: Greentime Hu 
---
 arch/riscv/include/uapi/asm/hwcap.h | 1 +
 arch/riscv/kernel/cpufeature.c  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/riscv/include/uapi/asm/hwcap.h 
b/arch/riscv/include/uapi/asm/hwcap.h
index 46dc3f5ee99f..c52bb7bbbabe 100644
--- a/arch/riscv/include/uapi/asm/hwcap.h
+++ b/arch/riscv/include/uapi/asm/hwcap.h
@@ -21,5 +21,6 @@
 #define COMPAT_HWCAP_ISA_F (1 << ('F' - 'A'))
 #define COMPAT_HWCAP_ISA_D (1 << ('D' - 'A'))
 #define COMPAT_HWCAP_ISA_C (1 << ('C' - 'A'))
+#define COMPAT_HWCAP_ISA_V (1 << ('V' - 'A'))
 
 #endif /* _UAPI_ASM_RISCV_HWCAP_H */
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index ac202f44a670..f11ada3fa906 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -73,6 +73,7 @@ void riscv_fill_hwcap(void)
isa2hwcap['f'] = isa2hwcap['F'] = COMPAT_HWCAP_ISA_F;
isa2hwcap['d'] = isa2hwcap['D'] = COMPAT_HWCAP_ISA_D;
isa2hwcap['c'] = isa2hwcap['C'] = COMPAT_HWCAP_ISA_C;
+   isa2hwcap['v'] = isa2hwcap['V'] = COMPAT_HWCAP_ISA_V;
 
elf_hwcap = 0;
 
-- 
2.28.0



[RFC PATCH v7 01/21] riscv: Separate patch for cflags and aflags

2020-09-10 Thread Greentime Hu
From: Guo Ren 

From: Guo Ren 

Use "subst fd" in Makefile is a hack way and it's not convenient
to add new ISA feature. Just separate them into riscv-march-cflags
and riscv-march-aflags.

Signed-off-by: Guo Ren 
---
 arch/riscv/Makefile | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index fb6e37db836d..957d064bead0 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -37,12 +37,18 @@ else
 endif
 
 # ISA string setting
-riscv-march-$(CONFIG_ARCH_RV32I)   := rv32ima
-riscv-march-$(CONFIG_ARCH_RV64I)   := rv64ima
-riscv-march-$(CONFIG_FPU)  := $(riscv-march-y)fd
-riscv-march-$(CONFIG_RISCV_ISA_C)  := $(riscv-march-y)c
-KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y))
-KBUILD_AFLAGS += -march=$(riscv-march-y)
+riscv-march-cflags-$(CONFIG_ARCH_RV32I):= rv32ima
+riscv-march-cflags-$(CONFIG_ARCH_RV64I):= rv64ima
+riscv-march-$(CONFIG_FPU)  := $(riscv-march-y)fd
+riscv-march-cflags-$(CONFIG_RISCV_ISA_C)   := $(riscv-march-cflags-y)c
+
+riscv-march-aflags-$(CONFIG_ARCH_RV32I):= rv32ima
+riscv-march-aflags-$(CONFIG_ARCH_RV64I):= rv64ima
+riscv-march-aflags-$(CONFIG_FPU)   := $(riscv-march-aflags-y)fd
+riscv-march-aflags-$(CONFIG_RISCV_ISA_C)   := $(riscv-march-aflags-y)c
+
+KBUILD_CFLAGS += -march=$(riscv-march-cflags-y)
+KBUILD_AFLAGS += -march=$(riscv-march-aflags-y)
 
 KBUILD_CFLAGS += -mno-save-restore
 KBUILD_CFLAGS += -DCONFIG_PAGE_OFFSET=$(CONFIG_PAGE_OFFSET)
-- 
2.28.0



[RFC PATCH v7 02/21] riscv: Rename __switch_to_aux -> fpu

2020-09-10 Thread Greentime Hu
From: Guo Ren 

From: Guo Ren 

The name of __switch_to_aux is not clear and rename it with the
determine function: __switch_to_fpu. Next we could add other regs'
switch.

Signed-off-by: Guo Ren 
Reviewed-by: Anup Patel 
Reviewed-by: Greentime Hu 
---
 arch/riscv/include/asm/switch_to.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/include/asm/switch_to.h 
b/arch/riscv/include/asm/switch_to.h
index 407bcc96a710..b9234e7178d0 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -44,7 +44,7 @@ static inline void fstate_restore(struct task_struct *task,
}
 }
 
-static inline void __switch_to_aux(struct task_struct *prev,
+static inline void __switch_to_fpu(struct task_struct *prev,
   struct task_struct *next)
 {
struct pt_regs *regs;
@@ -60,7 +60,7 @@ extern bool has_fpu;
 #define has_fpu false
 #define fstate_save(task, regs) do { } while (0)
 #define fstate_restore(task, regs) do { } while (0)
-#define __switch_to_aux(__prev, __next) do { } while (0)
+#define __switch_to_fpu(__prev, __next) do { } while (0)
 #endif
 
 extern struct task_struct *__switch_to(struct task_struct *,
@@ -71,7 +71,7 @@ do {  \
struct task_struct *__prev = (prev);\
struct task_struct *__next = (next);\
if (has_fpu)\
-   __switch_to_aux(__prev, __next);\
+   __switch_to_fpu(__prev, __next);\
((last) = __switch_to(__prev, __next)); \
 } while (0)
 
-- 
2.28.0



[RFC PATCH v7 00/21] riscv: Add vector ISA support

2020-09-10 Thread Greentime Hu
This patchset is implemented based on vector 0.9+ spec to add vector support
in riscv Linux kernel. To make this happen, we defined a new structure
__riscv_v_state to save the vector related registers. It is used for both
kernel space and user space. In kernel space, the datap pointer in
__riscv_v_state will be allocated dynamically to save vector registers.
In signal handler of user space, datap will point to the address right
after the __riscv_v_state data structure to save vector registers in stack.
In ptrace, the data will be put in ubuf in which we can get/put the
__riscv_v_state data structure from/to it, datap pointer would be zeroed and
vector registers will be copied to the address right after the
__riscv_v_state structure in ubuf. This patchset also adds support for kernel
mode vector, kernel XOR implementation with vector ISA and includes several
bug fixes and code refinement.

This patchset is rebased to v5.9-rc4 and it is tested by running several
vector programs simultaneously. It also can get the correct ucontext_t in
signal handler and restore correct context after sigreturn. It is also
tested with ptrace() syscall to use PTRACE_GETREGSET/PTRACE_SETREGSET to
get/set the vector registers. I have tested vlen=128 and vlen=256 cases in
spike machine of qemu-system-riscv64 provided by Zhiwei Lui and Frank Chang
and also tested in spike with vlen=64 to vlen=4096 settings.

We also sent patches to glibc mailing list for ifunc support and sigcontext
changes.

 [1] https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc
 [2] https://github.com/sifive/qemu/tree/rvv-1.0-upstream-v4
 [3] https://blog.linuxplumbersconf.org/2017/ocw/sessions/4671.html
 [4] https://sourceware.org/pipermail/libc-alpha/2020-July/116059.html
 [5] https://sourceware.org/pipermail/libc-alpha/2020-July/116108.html
 [6] https://linuxplumbersconf.org/event/7/contributions/811/

---
Changelog V7
 - Add support for kernel mode vector
 - Add vector extension XOR implementation
 - Optimize task switch codes of vector
 - Allocate space for vector registers in start_thread()
 - Fix an illegal instruction exception when accessing vlenb
 - Optimize vector registers initialization
 - Initialize vector registers with proper vsetvli then it can work normally
 - Refine ptrace porting due to generic API changed
 - Code clean up

Changelog V6
 - Replace vle.v/vse.v instructions with vle8.v/vse8.v based on 0.9 spec
 - Add comments based on mailinglist feedback
 - Fix rv32 build error

Changelog V5
 - Using regset_size() correctly in generic ptrace
 - Fix the ptrace porting
 - Fix compile warning

Changelog V4
 - Support dynamic vlen
 - Fix bugs: lazy save/resotre, not saving vtype
 - Update VS bit offset based on latest vector spec
 - Add new vector csr based on latest vector spec
 - Code refine and removed unused macros

Changelog V3
 - Rebase linux-5.6-rc3 and tested with qemu
 - Seperate patches with Anup's advice
 - Give out a ABI puzzle with unlimited vlen

Changelog V2
 - Fixup typo "vecotr, fstate_save->vstate_save".
 - Fixup wrong saved registers' length in vector.S.
 - Seperate unrelated patches from this one.

Greentime Hu (16):
  riscv: Extending cpufeature.c to detect V-extension
  riscv: Add new csr defines related to vector extension
  riscv: Add has_vector/riscv_vsize to save vector features.
  riscv: Add vector struct and assembler definitions
  riscv: Add task switch support for vector
  riscv: Add task switch support for vector
  riscv: Add ptrace vector support
  riscv: Add sigcontext save/restore for vector
  riscv: Add support for kernel mode vector
  riscv: Use CSR_STATUS to replace sstatus in vector.S
  riscv: Add vector extension XOR implementation
  riscv: Initialize vector registers with proper vsetvli then it can
work normally
  riscv: Optimize vector registers initialization
  riscv: Fix an illegal instruction exception when accessing vlenb
without enable vector first
  riscv: Allocate space for vector registers in start_thread()
  riscv: Optimize task switch codes of vector

Guo Ren (4):
  riscv: Separate patch for cflags and aflags
  riscv: Rename __switch_to_aux -> fpu
  riscv: Add vector feature to compile
  riscv: Reset vector register

Vincent Chen (1):
  riscv: signal: Report signal frame size to userspace via auxv

 arch/riscv/Kconfig   |   9 ++
 arch/riscv/Makefile  |  19 ++-
 arch/riscv/include/asm/csr.h |  16 ++-
 arch/riscv/include/asm/elf.h |  17 ++-
 arch/riscv/include/asm/processor.h   |   3 +
 arch/riscv/include/asm/switch_to.h   |  67 +-
 arch/riscv/include/asm/vector.h  |  18 +++
 arch/riscv/include/asm/xor.h |  74 +++
 arch/riscv/include/uapi/asm/auxvec.h |   2 +
 arch/riscv/include/uapi/asm/hwcap.h  |   1 +
 arch/riscv/include/uapi/asm/ptrace.h |  31 +
 arch/riscv/include/uapi/asm/sigcontext.h |   2 +
 arch/riscv/kernel/Makefile

Re: [PATCH] arch: vdso: add vdso linker script to 'targets' instead of extra-y

2020-09-01 Thread Greentime Hu
Masahiro Yamada  於 2020年9月1日 週二 上午2:23寫道:
>
> The vdso linker script is preprocessed on demand.
> Adding it to 'targets' is enough to include the .cmd file.
>
> Signed-off-by: Masahiro Yamada 
> ---
>
>  arch/arm64/kernel/vdso/Makefile | 2 +-
>  arch/arm64/kernel/vdso32/Makefile   | 2 +-
>  arch/nds32/kernel/vdso/Makefile | 2 +-
>  arch/powerpc/kernel/vdso32/Makefile | 2 +-
>  arch/powerpc/kernel/vdso64/Makefile | 2 +-
>  arch/s390/kernel/vdso64/Makefile| 2 +-
>  6 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
> index 45d5cfe46429..7cd8aafbe96e 100644
> --- a/arch/arm64/kernel/vdso/Makefile
> +++ b/arch/arm64/kernel/vdso/Makefile
> @@ -54,7 +54,7 @@ endif
>  GCOV_PROFILE := n
>
>  obj-y += vdso.o
> -extra-y += vdso.lds
> +targets += vdso.lds
>  CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
>
>  # Force dependency (incbin is bad)
> diff --git a/arch/arm64/kernel/vdso32/Makefile 
> b/arch/arm64/kernel/vdso32/Makefile
> index d6adb4677c25..572475b7b7ed 100644
> --- a/arch/arm64/kernel/vdso32/Makefile
> +++ b/arch/arm64/kernel/vdso32/Makefile
> @@ -155,7 +155,7 @@ asm-obj-vdso := $(addprefix $(obj)/, $(asm-obj-vdso))
>  obj-vdso := $(c-obj-vdso) $(c-obj-vdso-gettimeofday) $(asm-obj-vdso)
>
>  obj-y += vdso.o
> -extra-y += vdso.lds
> +targets += vdso.lds
>  CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
>
>  # Force dependency (vdso.s includes vdso.so through incbin)
> diff --git a/arch/nds32/kernel/vdso/Makefile b/arch/nds32/kernel/vdso/Makefile
> index 7c3c1ccb196e..55df25ef0057 100644
> --- a/arch/nds32/kernel/vdso/Makefile
> +++ b/arch/nds32/kernel/vdso/Makefile
> @@ -20,7 +20,7 @@ GCOV_PROFILE := n
>
>
>  obj-y += vdso.o
> -extra-y += vdso.lds
> +targets += vdso.lds
>  CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
>
>  # Force dependency
> diff --git a/arch/powerpc/kernel/vdso32/Makefile 
> b/arch/powerpc/kernel/vdso32/Makefile
> index 87ab1152d5ce..fd5072a4c73c 100644
> --- a/arch/powerpc/kernel/vdso32/Makefile
> +++ b/arch/powerpc/kernel/vdso32/Makefile
> @@ -29,7 +29,7 @@ ccflags-y := -shared -fno-common -fno-builtin -nostdlib \
>  asflags-y := -D__VDSO32__ -s
>
>  obj-y += vdso32_wrapper.o
> -extra-y += vdso32.lds
> +targets += vdso32.lds
>  CPPFLAGS_vdso32.lds += -P -C -Upowerpc
>
>  # Force dependency (incbin is bad)
> diff --git a/arch/powerpc/kernel/vdso64/Makefile 
> b/arch/powerpc/kernel/vdso64/Makefile
> index 38c317f25141..c737b3ea3207 100644
> --- a/arch/powerpc/kernel/vdso64/Makefile
> +++ b/arch/powerpc/kernel/vdso64/Makefile
> @@ -17,7 +17,7 @@ ccflags-y := -shared -fno-common -fno-builtin -nostdlib \
>  asflags-y := -D__VDSO64__ -s
>
>  obj-y += vdso64_wrapper.o
> -extra-y += vdso64.lds
> +targets += vdso64.lds
>  CPPFLAGS_vdso64.lds += -P -C -U$(ARCH)
>
>  # Force dependency (incbin is bad)
> diff --git a/arch/s390/kernel/vdso64/Makefile 
> b/arch/s390/kernel/vdso64/Makefile
> index 4a66a1cb919b..d0d406cfffa9 100644
> --- a/arch/s390/kernel/vdso64/Makefile
> +++ b/arch/s390/kernel/vdso64/Makefile
> @@ -25,7 +25,7 @@ $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = 
> $(KBUILD_CFLAGS_64)
>  $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64)
>
>  obj-y += vdso64_wrapper.o
> -extra-y += vdso64.lds
> +targets += vdso64.lds
>  CPPFLAGS_vdso64.lds += -P -C -U$(ARCH)
>
>  # Disable gcov profiling, ubsan and kasan for VDSO code

For nds32:

Acked-by: Greentime Hu 


Re: [PATCH v2 12/23] nds32: use asm-generic/mmu_context.h for no-op implementations

2020-08-28 Thread Greentime Hu
Nicholas Piggin  於 2020年8月26日 週三 下午10:53寫道:
>
> Cc: Nick Hu 
> Cc: Greentime Hu 
> Cc: Vincent Chen 
> Signed-off-by: Nicholas Piggin 
> ---
>  arch/nds32/include/asm/mmu_context.h | 10 ++
>  1 file changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/arch/nds32/include/asm/mmu_context.h 
> b/arch/nds32/include/asm/mmu_context.h
> index b8fd3d189fdc..c651bc8cacdc 100644
> --- a/arch/nds32/include/asm/mmu_context.h
> +++ b/arch/nds32/include/asm/mmu_context.h
> @@ -9,6 +9,7 @@
>  #include 
>  #include 
>
> +#define init_new_context init_new_context
>  static inline int
>  init_new_context(struct task_struct *tsk, struct mm_struct *mm)
>  {
> @@ -16,8 +17,6 @@ init_new_context(struct task_struct *tsk, struct mm_struct 
> *mm)
> return 0;
>  }
>
> -#define destroy_context(mm)do { } while(0)
> -
>  #define CID_BITS   9
>  extern spinlock_t cid_lock;
>  extern unsigned int cpu_last_cid;
> @@ -47,10 +46,6 @@ static inline void check_context(struct mm_struct *mm)
> __new_context(mm);
>  }
>
> -static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct 
> *tsk)
> -{
> -}
> -
>  static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
>  struct task_struct *tsk)
>  {
> @@ -62,7 +57,6 @@ static inline void switch_mm(struct mm_struct *prev, struct 
> mm_struct *next,
> }
>  }
>
> -#define deactivate_mm(tsk,mm)  do { } while (0)
> -#define activate_mm(prev,next) switch_mm(prev, next, NULL)
> +#include 
>
>  #endif

Acked-by: Greentime Hu 
Thank you. :)


Re: [PATCH] nds32: Fix bogus reference to

2020-08-28 Thread Greentime Hu
Geert Uytterhoeven  於 2020年8月27日 週四 下午9:24寫道:
>
> Andestech(nds32) never had .
>
> Signed-off-by: Geert Uytterhoeven 
> ---
>  arch/nds32/kernel/setup.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/nds32/kernel/setup.c b/arch/nds32/kernel/setup.c
> index a066efbe53c0c098..3671129e205852b7 100644
> --- a/arch/nds32/kernel/setup.c
> +++ b/arch/nds32/kernel/setup.c
> @@ -52,7 +52,7 @@ EXPORT_SYMBOL(elf_hwcap);
>
>  /*
>   * The following string table, must sync with HWCAP_xx bitmask,
> - * which is defined in 
> + * which is defined above
>   */
>  static const char *hwcap_str[] = {
> "mfusr_pc",

Thank you, Geert.
Acked-by: Greentime Hu 
I'll put it in the next branch.


[PATCH] riscv: Add sfence.vma after page table changed

2020-08-03 Thread Greentime Hu
This patch addes local_flush_tlb_page(addr) to use sfence.vma after the
page table changed. That address will be used immediately in
memset(nextp, 0, PAGE_SIZE) to cause this issue so we should add the
sfence.vma before we use it.

Fixes: f2c17aabc917 ("RISC-V: Implement compile-time fixed mappings")

Reported-by: Syven Wang 
Signed-off-by: Syven Wang 
Signed-off-by: Greentime Hu 
---
 arch/riscv/mm/init.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index f4adb3684f3d..29b0f7108054 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -202,12 +202,11 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t 
phys, pgprot_t prot)
 
ptep = _pte[pte_index(addr)];
 
-   if (pgprot_val(prot)) {
+   if (pgprot_val(prot))
set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
-   } else {
+   else
pte_clear(_mm, addr, ptep);
-   local_flush_tlb_page(addr);
-   }
+   local_flush_tlb_page(addr);
 }
 
 static pte_t *__init get_pte_virt(phys_addr_t pa)
-- 
2.28.0



Re: [PATCH 5/6] uaccess: add force_uaccess_{begin,end} helpers

2020-07-13 Thread Greentime Hu
Christoph Hellwig  於 2020年7月10日 週五 下午9:57寫道:
>
> Add helpers to wraper the get_fs/set_fs magic for undoing any damange
> done by set_fs(KERNEL_DS).  There is no real functional benefit, but this
> documents the intent of these calls better, and will allow stubbing the
> functions out easily for kernels builds that do not allow address space
> overrides in the future.
>
> Signed-off-by: Christoph Hellwig 
> ---
>  arch/arm64/kernel/sdei.c |  2 +-
>  arch/m68k/include/asm/tlbflush.h | 12 ++--
>  arch/mips/kernel/unaligned.c | 27 +--
>  arch/nds32/mm/alignment.c|  7 +++
>  arch/sh/kernel/traps_32.c| 18 --
>  drivers/firmware/arm_sdei.c  |  5 ++---
>  include/linux/uaccess.h  | 18 ++
>  kernel/events/callchain.c|  5 ++---
>  kernel/events/core.c |  5 ++---
>  kernel/kthread.c |  5 ++---
>  kernel/stacktrace.c  |  5 ++---
>  mm/maccess.c | 22 ++
>  12 files changed, 69 insertions(+), 62 deletions(-)
>
[...]
> diff --git a/arch/nds32/mm/alignment.c b/arch/nds32/mm/alignment.c
> index c8b9061a2ee3d5..1eb7ded6992b57 100644
> --- a/arch/nds32/mm/alignment.c
> +++ b/arch/nds32/mm/alignment.c
> @@ -512,7 +512,7 @@ int do_unaligned_access(unsigned long addr, struct 
> pt_regs *regs)
>  {
> unsigned long inst;
> int ret = -EFAULT;
> -   mm_segment_t seg = get_fs();
> +   mm_segment_t seg;
>
> inst = get_inst(regs->ipc);
>
> @@ -520,13 +520,12 @@ int do_unaligned_access(unsigned long addr, struct 
> pt_regs *regs)
>   "Faulting addr: 0x%08lx, pc: 0x%08lx [inst: 0x%08lx ]\n", addr,
>   regs->ipc, inst);
>
> -   set_fs(USER_DS);
> -
> +   seg = force_uaccess_begin();
> if (inst & NDS32_16BIT_INSTRUCTION)
> ret = do_16((inst >> 16) & 0x, regs);
> else
> ret = do_32(inst, regs);
> -   set_fs(seg);
> +   force_uaccess_end(seg);
>
> return ret;
>  }

Hi Christoph, Thank you.
Acked-by: Greentime Hu 


Re: [PATCH 4/6] uaccess: remove segment_eq

2020-07-13 Thread Greentime Hu
Christoph Hellwig  於 2020年7月10日 週五 下午9:57寫道:
>
> segment_eq is only used to implement uaccess_kernel.  Just open code
> uaccess_kernel in the arch uaccess headers and remove one layer of
> indirection.
>
> Signed-off-by: Christoph Hellwig 
> ---
>  arch/alpha/include/asm/uaccess.h  | 2 +-
>  arch/arc/include/asm/segment.h| 3 +--
>  arch/arm/include/asm/uaccess.h| 4 ++--
>  arch/arm64/include/asm/uaccess.h  | 2 +-
>  arch/csky/include/asm/segment.h   | 2 +-
>  arch/h8300/include/asm/segment.h  | 2 +-
>  arch/ia64/include/asm/uaccess.h   | 2 +-
>  arch/m68k/include/asm/segment.h   | 2 +-
>  arch/microblaze/include/asm/uaccess.h | 2 +-
>  arch/mips/include/asm/uaccess.h   | 2 +-
>  arch/nds32/include/asm/uaccess.h  | 2 +-
>  arch/nios2/include/asm/uaccess.h  | 2 +-
>  arch/openrisc/include/asm/uaccess.h   | 2 +-
>  arch/parisc/include/asm/uaccess.h | 2 +-
>  arch/powerpc/include/asm/uaccess.h| 3 +--
>  arch/riscv/include/asm/uaccess.h  | 4 +---
>  arch/s390/include/asm/uaccess.h   | 2 +-
>  arch/sh/include/asm/segment.h | 3 +--
>  arch/sparc/include/asm/uaccess_32.h   | 2 +-
>  arch/sparc/include/asm/uaccess_64.h   | 2 +-
>  arch/x86/include/asm/uaccess.h| 2 +-
>  arch/xtensa/include/asm/uaccess.h | 2 +-
>  include/asm-generic/uaccess.h | 4 ++--
>  include/linux/uaccess.h   | 2 --
>  24 files changed, 25 insertions(+), 32 deletions(-)
>
[...]
> diff --git a/arch/nds32/include/asm/uaccess.h 
> b/arch/nds32/include/asm/uaccess.h
> index 3a9219f53ee0d8..010ba5f1d7dd6b 100644
> --- a/arch/nds32/include/asm/uaccess.h
> +++ b/arch/nds32/include/asm/uaccess.h
> @@ -44,7 +44,7 @@ static inline void set_fs(mm_segment_t fs)
> current_thread_info()->addr_limit = fs;
>  }
>
> -#define segment_eq(a, b)   ((a) == (b))
> +#define uaccess_kernel()   (get_fs() == KERNEL_DS)
>
>  #define __range_ok(addr, size) (size <= get_fs() && addr <= (get_fs() -size))
>
Hi Christoph, Thank you.
Acked-by: Greentime Hu 


Re: [PATCH 2/6] nds32: use uaccess_kernel in show_regs

2020-07-13 Thread Greentime Hu
Christoph Hellwig  於 2020年7月10日 週五 下午9:57寫道:
>
> Use the uaccess_kernel helper instead of duplicating it.
>
> Signed-off-by: Christoph Hellwig 
> ---
>  arch/nds32/kernel/process.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/nds32/kernel/process.c b/arch/nds32/kernel/process.c
> index 9712fd474f2ca3..f06265949ec28b 100644
> --- a/arch/nds32/kernel/process.c
> +++ b/arch/nds32/kernel/process.c
> @@ -121,7 +121,7 @@ void show_regs(struct pt_regs *regs)
> regs->uregs[3], regs->uregs[2], regs->uregs[1], 
> regs->uregs[0]);
> pr_info("  IRQs o%s  Segment %s\n",
> interrupts_enabled(regs) ? "n" : "ff",
> -   segment_eq(get_fs(), KERNEL_DS)? "kernel" : "user");
> +   uaccess_kernel() ? "kernel" : "user");
>  }
>
>  EXPORT_SYMBOL(show_regs);

Hi Christoph, Thank you.
Acked-by: Greentime Hu 


[PATCH 1/2] riscv: Fix building error in entry.S when CONFIG_RISCV_M_MODE is enabled

2020-07-13 Thread Greentime Hu
arch/riscv/kernel/entry.S: Assembler messages:
arch/riscv/kernel/entry.S:106: Error: illegal operands `andi a0,s1,0x1800'

This building error is because of the SR_MPP value is too large to be used
as an immediate value for andi. To fix this issue I use li to set the
immediate value to t0, then it can use t0 and s1 to do and operation.

Reported-by: kernel test robot 
Signed-off-by: Greentime Hu 
---
 arch/riscv/kernel/entry.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 6ed579fc1073..000984695cd6 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -99,7 +99,8 @@ _save_context:
 
 #ifdef CONFIG_CONTEXT_TRACKING
/* If previous state is in user mode, call context_tracking_user_exit. 
*/
-   andi a0, s1, SR_SPP
+   li t0, SR_PP
+   and a0, s1, t0
bnez a0, skip_context_tracking
call context_tracking_user_exit
 
-- 
2.27.0



[PATCH 2/2] riscv: Simplify the checking for SR_PP

2020-07-13 Thread Greentime Hu
This patch simplifies the checking for SR_MPP and SR_SPP. It uses SR_PP in the
code flow for both m-mode and s-mode then we can remove the ifdef here.

Signed-off-by: Greentime Hu 
---
 arch/riscv/kernel/entry.S | 7 +--
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 000984695cd6..597beae0d238 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -210,13 +210,8 @@ ret_from_syscall_rejected:
 ret_from_exception:
REG_L s0, PT_STATUS(sp)
csrc CSR_STATUS, SR_IE
-#ifdef CONFIG_RISCV_M_MODE
-   /* the MPP value is too large to be used as an immediate arg for addi */
-   li t0, SR_MPP
+   li t0, SR_PP
and s0, s0, t0
-#else
-   andi s0, s0, SR_SPP
-#endif
bnez s0, resume_kernel
 
 resume_userspace:
-- 
2.27.0



Re: [PATCH v2 2/2] riscv: Enable context tracking

2020-07-10 Thread Greentime Hu
Palmer Dabbelt  於 2020年7月11日 週六 上午1:30寫道:
>
> On Wed, 24 Jun 2020 02:03:16 PDT (-0700), greentime...@sifive.com wrote:
> > This patch implements and enables context tracking for riscv (which is a
> > prerequisite for CONFIG_NO_HZ_FULL support)
> >
> > It adds checking for previous state in the entry that all excepttions and
> > interrupts goes to and calls context_tracking_user_exit() if it comes from
> > user space. It also calls context_tracking_user_enter() if it will return
> > to user space before restore_all.
> >
> > This patch is tested with the dynticks-testing testcase in
> > qemu-system-riscv64 virt machine and Unleashed board.
> > git://git.kernel.org/pub/scm/linux/kernel/git/frederic/dynticks-testing.git
> >
> > We can see the log here. The tick got mostly stopped during the execution
> > of the user loop.
> >
> > _-=> irqs-off
> >/ _=> need-resched
> >   | / _---=> hardirq/softirq
> >   || / _--=> preempt-depth
> >   ||| / delay
> >  TASK-PID   CPU#  TIMESTAMP  FUNCTION
> > | |   |      | |
> >-0 [001] d..2   604.183512: sched_switch: prev_comm=swapper/1 
> > prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=taskset next_pid=273 
> > next_prio=120
> > user_loop-273   [001] d.h1   604.184788: hrtimer_expire_entry: 
> > hrtimer=2eda5fab function=tick_sched_timer now=604176096300
> > user_loop-273   [001] d.s2   604.184897: workqueue_queue_work: work 
> > struct=383402c2 function=vmstat_update workqueue=f36d35d4 
> > req_cpu=1 cpu=1
> > user_loop-273   [001] dns2   604.185039: tick_stop: success=0 
> > dependency=SCHED
> > user_loop-273   [001] dn.1   604.185103: tick_stop: success=0 
> > dependency=SCHED
> > user_loop-273   [001] d..2   604.185154: sched_switch: prev_comm=taskset 
> > prev_pid=273 prev_prio=120 prev_state=R+ ==> next_comm=kworker/1:1 
> > next_pid=46 next_prio=120
> > <...>-46[001]    604.185194: workqueue_execute_start: work 
> > struct 383402c2: function vmstat_update
> > <...>-46[001] d..2   604.185266: sched_switch: 
> > prev_comm=kworker/1:1 prev_pid=46 prev_prio=120 prev_state=I ==> 
> > next_comm=taskset next_pid=273 next_prio=120
> > user_loop-273   [001] d.h1   604.188812: hrtimer_expire_entry: 
> > hrtimer=2eda5fab function=tick_sched_timer now=604180133400
> > user_loop-273   [001] d..1   604.189050: tick_stop: success=1 
> > dependency=NONE
> > user_loop-273   [001] d..2   614.251386: sched_switch: prev_comm=user_loop 
> > prev_pid=273 prev_prio=120 prev_state=X ==> next_comm=swapper/1 next_pid=0 
> > next_prio=120
> >-0 [001] d..2   614.315391: sched_switch: prev_comm=swapper/1 
> > prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=taskset next_pid=276 
> > next_prio=120
> >
> > Signed-off-by: Greentime Hu 
> > ---
> >  arch/riscv/Kconfig|  1 +
> >  arch/riscv/kernel/entry.S | 23 +++
> >  2 files changed, 24 insertions(+)
> >
> > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> > index 128192e14ff2..17520e11815b 100644
> > --- a/arch/riscv/Kconfig
> > +++ b/arch/riscv/Kconfig
> > @@ -52,6 +52,7 @@ config RISCV
> >   select HAVE_ARCH_SECCOMP_FILTER
> >   select HAVE_ARCH_TRACEHOOK
> >   select HAVE_ASM_MODVERSIONS
> > + select HAVE_CONTEXT_TRACKING
> >   select HAVE_COPY_THREAD_TLS
> >   select HAVE_DMA_CONTIGUOUS if MMU
> >   select HAVE_EBPF_JIT if MMU
> > diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
> > index cae7e6d4c7ef..6ed579fc1073 100644
> > --- a/arch/riscv/kernel/entry.S
> > +++ b/arch/riscv/kernel/entry.S
> > @@ -97,6 +97,14 @@ _save_context:
> >   la gp, __global_pointer$
> >  .option pop
> >
> > +#ifdef CONFIG_CONTEXT_TRACKING
> > + /* If previous state is in user mode, call 
> > context_tracking_user_exit. */
> > + andi a0, s1, SR_SPP
>
> I've changed that to SR_PP, as I don't see any reason why this should depend 
> on
> MMU.
>
> I think this is correct: we're using scratch==0 elsewhere to detect recursive
> traps, but we've blown that away by this point so it's not an option.  I don't
> know of any reason why PP wouldn't be accurate.

Hi Palmer,

Thank you. That makes sense to me.

>
> > + bnez a0, skip_context_tracking
> > + call contex

Re: [PATCH 0/3] Dynamic CPU frequency switching for the HiFive

2020-06-29 Thread Greentime Hu
Yash Shah  於 2020年6月16日 週二 下午8:01寫道:
>
> The patch series adds the support for dynamic CPU frequency switching
> for FU540-C000 SoC on the HiFive Unleashed board. All the patches are
> based on Paul Walmsley's work.
>
> This series is based on Linux v5.7 and tested on HiFive unleashed board.
>
> Yash Shah (3):
>   riscv: defconfig, Kconfig: enable CPU power management
>   riscv: dts: fu540-c000: define hart clocks
>   riscv: dts: HiFive Unleashed: define a default set of CPU OPPs
>
>  arch/riscv/Kconfig |  8 +
>  arch/riscv/boot/dts/sifive/fu540-c000.dtsi |  5 +++
>  .../riscv/boot/dts/sifive/hifive-unleashed-a00.dts | 38 
> ++
>  arch/riscv/configs/defconfig   |  5 +++
>  4 files changed, 56 insertions(+)
>

Hi Yash,

Thank you for the patch. It works for me to test with cpufreq-ljt-stress-test.
Here is my log.

CPU stress test, which is doing JPEG decoding by libjpeg-turbo
at different cpufreq operating points.

Testing CPU 0
 1400 MHz  OK
  999 MHz  OK
  700 MHz  OK
  350 MHz  OK

Testing CPU 1
 1400 MHz  OK
  999 MHz  OK
  700 MHz  OK
  350 MHz  OK

Testing CPU 2
 1400 MHz  OK
  999 MHz  OK
  700 MHz  OK
  350 MHz  OK

Testing CPU 3
 1400 MHz  OK
  999 MHz  OK
  700 MHz  OK
  350 MHz .... OK

Overall result : PASSED

Tested-by: Greentime Hu 


Re: [PATCH 2/2] riscv: Enable context tracking

2020-06-28 Thread Greentime Hu
guoren  於 2020年6月27日 週六 上午12:29寫道:
>
> Hi Greentime,
>
> On 2020/6/23 9:28 下午, Greentime Hu wrote:
> > This patch implements and enables context tracking for riscv (which is a
> > prerequisite for CONFIG_NO_HZ_FULL support)
> >
> > It adds checking for previous state in the entry that all excepttions and
> > interrupts goes to and calls context_tracking_user_exit() if it comes from
> > user space. It also calls context_tracking_user_enter() if it will return
> > to user space before restore_all.
> >
> > This patch is tested with the dynticks-testing testcase in
> > qemu-system-riscv64 virt machine and Unleashed board.
> > git://git.kernel.org/pub/scm/linux/kernel/git/frederic/dynticks-testing.git
> >
> > We can see the log here. The tick got mostly stopped during the execution
> > of the user loop.
> >
> >  _-=> irqs-off
> > / _=> need-resched
> >| / _---=> hardirq/softirq
> >|| / _--=> preempt-depth
> >||| / delay
> >   TASK-PID   CPU#  TIMESTAMP  FUNCTION
> >  | |   |      | |
> > -0 [001] d..2   604.183512: sched_switch: prev_comm=swapper/1 
> > prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=taskset next_pid=273 
> > next_prio=120
> > user_loop-273   [001] d.h1   604.184788: hrtimer_expire_entry: 
> > hrtimer=2eda5fab function=tick_sched_timer now=604176096300
> > user_loop-273   [001] d.s2   604.184897: workqueue_queue_work: work 
> > struct=383402c2 function=vmstat_update workqueue=f36d35d4 
> > req_cpu=1 cpu=1
> > user_loop-273   [001] dns2   604.185039: tick_stop: success=0 
> > dependency=SCHED
> > user_loop-273   [001] dn.1   604.185103: tick_stop: success=0 
> > dependency=SCHED
> > user_loop-273   [001] d..2   604.185154: sched_switch: prev_comm=taskset 
> > prev_pid=273 prev_prio=120 prev_state=R+ ==> next_comm=kworker/1:1 
> > next_pid=46 next_prio=120
> >  <...>-46[001]    604.185194: workqueue_execute_start: work 
> > struct 383402c2: function vmstat_update
> >  <...>-46[001] d..2   604.185266: sched_switch: 
> > prev_comm=kworker/1:1 prev_pid=46 prev_prio=120 prev_state=I ==> 
> > next_comm=taskset next_pid=273 next_prio=120
> > user_loop-273   [001] d.h1   604.188812: hrtimer_expire_entry: 
> > hrtimer=2eda5fab function=tick_sched_timer now=604180133400
> > user_loop-273   [001] d..1   604.189050: tick_stop: success=1 
> > dependency=NONE
> > user_loop-273   [001] d..2   614.251386: sched_switch: prev_comm=user_loop 
> > prev_pid=273 prev_prio=120 prev_state=X ==> next_comm=swapper/1 next_pid=0 
> > next_prio=120
> > -0 [001] d..2   614.315391: sched_switch: prev_comm=swapper/1 
> > prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=taskset next_pid=276 
> > next_prio=120
> >
> > Signed-off-by: Greentime Hu
> > ---
> >   arch/riscv/Kconfig|  1 +
> >   arch/riscv/kernel/entry.S | 23 +++
> >   2 files changed, 24 insertions(+)
> >
> > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> > index 128192e14ff2..17520e11815b 100644
> > --- a/arch/riscv/Kconfig
> > +++ b/arch/riscv/Kconfig
> > @@ -52,6 +52,7 @@ config RISCV
> >   select HAVE_ARCH_SECCOMP_FILTER
> >   select HAVE_ARCH_TRACEHOOK
> >   select HAVE_ASM_MODVERSIONS
> > + select HAVE_CONTEXT_TRACKING
> >   select HAVE_COPY_THREAD_TLS
> >   select HAVE_DMA_CONTIGUOUS if MMU
> >   select HAVE_EBPF_JIT if MMU
> > diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
> > index cae7e6d4c7ef..6ed579fc1073 100644
> > --- a/arch/riscv/kernel/entry.S
> > +++ b/arch/riscv/kernel/entry.S
> > @@ -97,6 +97,14 @@ _save_context:
> >   la gp, __global_pointer$
> >   .option pop
> >
> > +#ifdef CONFIG_CONTEXT_TRACKING
> > + /* If previous state is in user mode, call 
> > context_tracking_user_exit. */
> > + andi a0, s1, SR_SPP
> > + bnez a0, skip_context_tracking
> > + call context_tracking_user_exit
>
> It will destroy s1-s5 which are used in entry.S like these:
>
>  REG_S s0, PT_SP(sp)
>  REG_S s1, PT_STATUS(sp)
>  REG_S s2, PT_EPC(sp)
>  REG_S s3, PT_BADADDR(sp)
>  REG_S s4, PT_CAUSE(sp)
>  REG_S s5, PT_TP(sp)
> ...
>  /*
>   * MSB of cause differentiates

Re: [PATCH 12/26] mm/nds32: Use general page fault accounting

2020-06-26 Thread Greentime Hu
Peter Xu  於 2020年6月27日 週六 上午6:31寫道:
>
> Use the general page fault accounting by passing regs into handle_mm_fault().
> It naturally solve the issue of multiple page fault accounting when page fault
> retry happened.
>
> Fix PERF_COUNT_SW_PAGE_FAULTS perf event manually for page fault retries, by
> moving it before taking mmap_sem.
>
> CC: Nick Hu 
> CC: Greentime Hu 
> CC: Vincent Chen 
> Signed-off-by: Peter Xu 
> ---
>  arch/nds32/mm/fault.c | 19 +++
>  1 file changed, 3 insertions(+), 16 deletions(-)
>
> diff --git a/arch/nds32/mm/fault.c b/arch/nds32/mm/fault.c
> index 22527129025c..e730623c 100644
> --- a/arch/nds32/mm/fault.c
> +++ b/arch/nds32/mm/fault.c
> @@ -122,6 +122,8 @@ void do_page_fault(unsigned long entry, unsigned long 
> addr,
> if (unlikely(faulthandler_disabled() || !mm))
> goto no_context;
>
> +   perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
> +
> /*
>  * As per x86, we may deadlock here. However, since the kernel only
>  * validly references user space from well defined areas of the code,
> @@ -207,7 +209,7 @@ void do_page_fault(unsigned long entry, unsigned long 
> addr,
>  * the fault.
>  */
>
> -   fault = handle_mm_fault(vma, addr, flags, NULL);
> +   fault = handle_mm_fault(vma, addr, flags, regs);
>
> /*
>  * If we need to retry but a fatal signal is pending, handle the
> @@ -229,22 +231,7 @@ void do_page_fault(unsigned long entry, unsigned long 
> addr,
> goto bad_area;
> }
>
> -   /*
> -* Major/minor page fault accounting is only done on the initial
> -* attempt. If we go through a retry, it is extremely likely that the
> -* page will be found in page cache at that point.
> -*/
> -   perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
> if (flags & FAULT_FLAG_ALLOW_RETRY) {
> -   if (fault & VM_FAULT_MAJOR) {
> -   tsk->maj_flt++;
> -   perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
> - 1, regs, addr);
> -   } else {
> -   tsk->min_flt++;
> -   perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
> -         1, regs, addr);
> -   }
> if (fault & VM_FAULT_RETRY) {
> flags |= FAULT_FLAG_TRIED;
>

Hi Peter,

Thank you.
Acked-by: Greentime Hu 


  1   2   3   4   5   6   7   8   9   10   >