[PATCH v8 2/2] clk: hisilicon: Add clock driver for hi3559A SoC

2021-03-23 Thread Dongjiu Geng
From: Dongjiu Geng 

Add clock drivers for hi3559A SoC, this driver
controls the SoC registers to supply different
clocks to different IPs in the SoC.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/Kconfig   |   7 +
 drivers/clk/hisilicon/Makefile  |   1 +
 drivers/clk/hisilicon/clk-hi3559a.c | 847 
 drivers/clk/hisilicon/clk.c |   2 +-
 drivers/clk/hisilicon/clk.h |   2 +-
 5 files changed, 857 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 6a9e93a..5ecc37a 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
help
  Build the clock driver for hi3519.
 
+config COMMON_CLK_HI3559A
+   bool "Hi3559A Clock Driver"
+   depends on ARCH_HISI || COMPILE_TEST
+   default ARCH_HISI
+   help
+ Build the clock driver for hi3559a.
+
 config COMMON_CLK_HI3660
bool "Hi3660 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index b2441b9..2978e56 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_HIP04)  += clk-hip04.o
 obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o
 obj-$(CONFIG_COMMON_CLK_HI3516CV300)   += crg-hi3516cv300.o
 obj-$(CONFIG_COMMON_CLK_HI3519)+= clk-hi3519.o
+obj-$(CONFIG_COMMON_CLK_HI3559A)   += clk-hi3559a.o
 obj-$(CONFIG_COMMON_CLK_HI3660) += clk-hi3660.o
 obj-$(CONFIG_COMMON_CLK_HI3670) += clk-hi3670.o
 obj-$(CONFIG_COMMON_CLK_HI3798CV200)   += crg-hi3798cv200.o
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
b/drivers/clk/hisilicon/clk-hi3559a.c
new file mode 100644
index 000..a47df96
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -0,0 +1,847 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Hisilicon Hi3559A clock driver
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "crg.h"
+#include "reset.h"
+
+#define CRG_BASE_ADDR  0x1802
+#define PLL_MASK_WIDTH 24
+
+struct hi3559av100_pll_clock {
+   u32 id;
+   const char  *name;
+   const char  *parent_name;
+   const u32   ctrl_reg1;
+   const u8frac_shift;
+   const u8frac_width;
+   const u8postdiv1_shift;
+   const u8postdiv1_width;
+   const u8postdiv2_shift;
+   const u8postdiv2_width;
+   const u32   ctrl_reg2;
+   const u8fbdiv_shift;
+   const u8fbdiv_width;
+   const u8refdiv_shift;
+   const u8refdiv_width;
+};
+
+struct hi3559av100_clk_pll {
+   struct clk_hw   hw;
+   u32 id;
+   void __iomem*ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   void __iomem*ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+/* soc clk config */
+static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = {
+   { HI3559AV100_FIXED_1188M, "1188m", NULL, 0, 118800, },
+   { HI3559AV100_FIXED_1000M, "1000m", NULL, 0, 10, },
+   { HI3559AV100_FIXED_842M, "842m", NULL, 0, 84200, },
+   { HI3559AV100_FIXED_792M, "792m", NULL, 0, 79200, },
+   { HI3559AV100_FIXED_750M, "750m", NULL, 0, 75000, },
+   { HI3559AV100_FIXED_710M, "710m", NULL, 0, 71000, },
+   { HI3559AV100_FIXED_680M, "680m", NULL, 0, 68000, },
+   { HI3559AV100_FIXED_667M, "667m", NULL, 0, 66700, },
+   { HI3559AV100_FIXED_631M, "631m", NULL, 0, 63100, },
+   { HI3559AV100_FIXED_600M, "600m", NULL, 0, 6, },
+   { HI3559AV100_FIXED_568M, "568m", NULL, 0, 56800, },
+   { HI3559AV100_FIXED_500M, "500m", NULL, 0, 5, },
+   { HI3559AV100_FIXED_475M, "475m", NULL, 0, 47500, },
+   { HI3559AV100_FIXED_428M, "428m", NULL, 0, 42800, },
+   { HI3559AV100_FIXED_400M, "400m", NULL, 0, 4, },
+   { HI3559AV100_FIXED_396M, "396m", NULL, 0, 39600, },
+   { HI3559AV100_FIXED_300M, "300m", NULL, 0, 3, },
+   { HI3559AV100_FIXED_250M, "250m", NULL, 0, 25000, },
+   { HI3559AV100_FIXED_200M, "200m", NULL, 0, 2, },
+   { HI3559AV100_FI

[PATCH v8 1/2] dt-bindings: Document the hi3559a clock bindings

2021-03-23 Thread Dongjiu Geng
From: Dongjiu Geng 

Add DT bindings documentation for hi3559a SoC clock.

Signed-off-by: Dongjiu Geng 
Reviewed-by: Rob Herring 
---
 .../clock/hisilicon,hi3559av100-clock.yaml |  59 
 include/dt-bindings/clock/hi3559av100-clock.h  | 165 +
 2 files changed, 224 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

diff --git 
a/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml 
b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
new file mode 100644
index 000..3ceb29c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/hisilicon,hi3559av100-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hisilicon SOC Clock for HI3559AV100
+
+maintainers:
+  - Dongjiu Geng 
+
+description: |
+  Hisilicon SOC clock control module which supports the clocks, resets and
+  power domains on HI3559AV100.
+
+  See also:
+dt-bindings/clock/hi3559av100-clock.h
+
+properties:
+  compatible:
+enum:
+  - hisilicon,hi3559av100-clock
+  - hisilicon,hi3559av100-shub-clock
+
+  reg:
+minItems: 1
+maxItems: 2
+
+  '#clock-cells':
+const: 1
+
+  '#reset-cells':
+const: 2
+description: |
+  First cell is reset request register offset.
+  Second cell is bit offset in reset request register.
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+clock-controller@1201 {
+compatible = "hisilicon,hi3559av100-clock";
+#clock-cells = <1>;
+#reset-cells = <2>;
+reg = <0x0 0x1201 0x0 0x1>;
+};
+};
+...
diff --git a/include/dt-bindings/clock/hi3559av100-clock.h 
b/include/dt-bindings/clock/hi3559av100-clock.h
new file mode 100644
index 000..5fe7689
--- /dev/null
+++ b/include/dt-bindings/clock/hi3559av100-clock.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+/*
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#ifndef __DTS_HI3559AV100_CLOCK_H
+#define __DTS_HI3559AV100_CLOCK_H
+
+/*  fixed   rate*/
+#define HI3559AV100_FIXED_1188M 1
+#define HI3559AV100_FIXED_1000M 2
+#define HI3559AV100_FIXED_842M  3
+#define HI3559AV100_FIXED_792M  4
+#define HI3559AV100_FIXED_750M  5
+#define HI3559AV100_FIXED_710M  6
+#define HI3559AV100_FIXED_680M  7
+#define HI3559AV100_FIXED_667M  8
+#define HI3559AV100_FIXED_631M  9
+#define HI3559AV100_FIXED_600M  10
+#define HI3559AV100_FIXED_568M  11
+#define HI3559AV100_FIXED_500M  12
+#define HI3559AV100_FIXED_475M  13
+#define HI3559AV100_FIXED_428M  14
+#define HI3559AV100_FIXED_400M  15
+#define HI3559AV100_FIXED_396M  16
+#define HI3559AV100_FIXED_300M  17
+#define HI3559AV100_FIXED_250M  18
+#define HI3559AV100_FIXED_198M  19
+#define HI3559AV100_FIXED_187p5M20
+#define HI3559AV100_FIXED_150M  21
+#define HI3559AV100_FIXED_148p5M22
+#define HI3559AV100_FIXED_125M  23
+#define HI3559AV100_FIXED_107M  24
+#define HI3559AV100_FIXED_100M  25
+#define HI3559AV100_FIXED_99M   26
+#define HI3559AV100_FIXED_74p25M27
+#define HI3559AV100_FIXED_72M   28
+#define HI3559AV100_FIXED_60M   29
+#define HI3559AV100_FIXED_54M   30
+#define HI3559AV100_FIXED_50M   31
+#define HI3559AV100_FIXED_49p5M 32
+#define HI3559AV100_FIXED_37p125M   33
+#define HI3559AV100_FIXED_36M   34
+#define HI3559AV100_FIXED_32p4M 35
+#define HI3559AV100_FIXED_27M   36
+#define HI3559AV100_FIXED_25M   37
+#define HI3559AV100_FIXED_24M   38
+#define HI3559AV100_FIXED_12M   39
+#define HI3559AV100_FIXED_3M40
+#define HI3559AV100_FIXED_1p6M  41
+#define HI3559AV100_FIXED_400K  42
+#define HI3559AV100_FIXED_100K  43
+#define HI3559AV100_FIXED_200M  44
+#define HI3559AV100_FIXED_75M   75
+
+#define HI3559AV100_I2C0_CLK50
+#define HI3559AV100_I2C1_CLK51
+#define HI3559AV100_I2C2_CLK52
+#define HI3559AV100_I2C3_CLK53
+#define HI3559AV100_I2C4_CLK54
+#define HI3559AV100_I2C5_CLK55
+#define HI3559AV100_I2C6_CLK56
+#define HI3559AV100_I2C7_CLK57
+#define HI3559AV100_I2C8_CLK58
+#define HI3559AV100_I2C9_CLK59
+#define HI3559AV100_I2C10_CLK   60
+#define HI3559AV100_I2C11_CLK   61
+
+#define HI3559AV100_SPI0_CLK62
+#define HI3559AV100_SPI1_CLK63
+#define HI3559AV100_SPI2_CLK64
+#define HI3559AV100_

[PATCH v8 0/2] Enable Hi3559A SOC clock

2021-03-23 Thread Dongjiu Geng
This patchset is separated  from this series: 
https://lore.kernel.org/patchwork/cover/1353321/

v7->v8:
Mainly address Stephen's comments
1. Add const for some function and variables
2. Remove the useless function and variables
3. Add a define for a mask width

Dongjiu Geng (2):
  dt-bindings: Document the hi3559a clock bindings
  clk: hisilicon: Add clock driver for hi3559A SoC

 .../clock/hisilicon,hi3559av100-clock.yaml |  59 ++
 drivers/clk/hisilicon/Kconfig  |   7 +
 drivers/clk/hisilicon/Makefile |   1 +
 drivers/clk/hisilicon/clk-hi3559a.c| 847 +
 drivers/clk/hisilicon/clk.c|   2 +-
 drivers/clk/hisilicon/clk.h|   2 +-
 include/dt-bindings/clock/hi3559av100-clock.h  | 165 
 7 files changed, 1081 insertions(+), 2 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

-- 
2.7.4



Re: [PATCH v7 0/4] Enable Hi3559A SOC clock and HiSilicon Hiedma Controller

2021-01-12 Thread Dongjiu Geng
On 2021/1/12 18:40, Vinod Koul wrote:
> On 15-12-20, 11:09, Dongjiu Geng wrote:
>> v6->v7:
>> 1. rename hisi,misc-control to hisi,misc-control to hisilicon,misc-control
>>
>> v5->v6:
>> 1. Drop #size-cells and #address-cell in the hisilicon,hi3559av100-clock.yaml
>> 2. Add discription for #reset-cells in the hisilicon,hi3559av100-clock.yaml
>> 3. Remove #clock-cells in hisilicon,hiedmacv310.yaml 
>> 4. Merge property misc_ctrl_base and misc_regmap together for hiedmacv310 
>> driver
>>
>> v4->v5:
>> 1. change the patch author mail name
>>
>> v3->v4:
>> 1. fix the 'make dt_binding_check' issues.
>> 2. Combine the 'Enable HiSilicon Hiedma Controller' series patches to this 
>> series.
>> 3. fix the 'make dt_binding_check' issues in 'Enable HiSilicon Hiedma 
>> Controller' patchset
>>
>> v2->v3:
>> 1. change dt-bindings documents from txt to yaml format.
>> 2. Add SHUB clock to access the devices of m7
>>
>> Dongjiu Geng (4):
>>   dt-bindings: Document the hi3559a clock bindings
>>   clk: hisilicon: Add clock driver for hi3559A SoC
>>   dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller
>>   dmaengine: dma: Add Hiedma Controller v310 Device Driver
> 
> Is there a reason to have dma and clk drivers in a single series..? I am
> sure I have skipping few versions thinking this is clock driver series..
> 
> Unless there is a dependency please split up.. If there is a dependency
> please specify that

Thank you very much for your pointing out.  I will split up.

> 
> 
>>
>>  .../clock/hisilicon,hi3559av100-clock.yaml|   59 +
>>  .../bindings/dma/hisilicon,hiedmacv310.yaml   |   94 ++
>>  drivers/clk/hisilicon/Kconfig |7 +
>>  drivers/clk/hisilicon/Makefile|1 +
>>  drivers/clk/hisilicon/clk-hi3559a.c   |  865 ++
>>  drivers/dma/Kconfig   |   14 +
>>  drivers/dma/Makefile  |1 +
>>  drivers/dma/hiedmacv310.c | 1442 +
>>  drivers/dma/hiedmacv310.h |  136 ++
>>  include/dt-bindings/clock/hi3559av100-clock.h |  165 ++
>>  10 files changed, 2784 insertions(+)
>>  create mode 100644 
>> Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
>>  create mode 100644 
>> Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
>>  create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
>>  create mode 100644 drivers/dma/hiedmacv310.c
>>  create mode 100644 drivers/dma/hiedmacv310.h
>>  create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h
>>
>> -- 
>> 2.17.1
> 


Re: [PATCH v7 1/4] dt-bindings: Document the hi3559a clock bindings

2021-01-06 Thread Dongjiu Geng



On 2020/12/22 2:54, Rob Herring wrote:
> On Tue, 15 Dec 2020 11:09:44 +0000, Dongjiu Geng wrote:
>> Add DT bindings documentation for hi3559a SoC clock.
>>
>> Signed-off-by: Dongjiu Geng 
>> ---
>>  .../clock/hisilicon,hi3559av100-clock.yaml|  59 +++
>>  include/dt-bindings/clock/hi3559av100-clock.h | 165 ++
>>  2 files changed, 224 insertions(+)
>>  create mode 100644 
>> Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
>>  create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h
>>
> 
> Reviewed-by: Rob Herring 
Thanks a lot for the Reviewed-by.
Whether this series patches can be queued to mainline?

> .
> 


[PATCH v7 3/4] dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller

2020-12-14 Thread Dongjiu Geng
The Hiedma Controller v310 Provides eight DMA channels, each
channel can be configured for one-way transfer. The data can
be transferred in 8-bit, 16-bit, 32-bit, or 64-bit mode. This
documentation describes DT bindings of this controller.

Signed-off-by: Dongjiu Geng 
---
 .../bindings/dma/hisilicon,hiedmacv310.yaml   | 94 +++
 1 file changed, 94 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml

diff --git a/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml 
b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
new file mode 100644
index ..06a1ebe76360
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
@@ -0,0 +1,94 @@
+# SPDX-License-Identifier:  GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/hisilicon,hiedmacv310.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon Hiedma Controller v310 Device Tree Bindings
+
+description: |
+  These bindings describe the DMA engine included in the HiSilicon Hiedma
+  Controller v310 Device.
+
+maintainers:
+  - Dongjiu Geng 
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+const: 2
+
+  compatible:
+const: hisilicon,hiedmacv310
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  hisilicon,misc-control:
+$ref: /schemas/types.yaml#definitions/phandle-array
+description: phandle pointing to the misc controller provider node and 
base register.
+
+  clocks:
+items:
+  - description: apb clock
+  - description: axi clock
+
+  clock-names:
+items:
+  - const: apb_pclk
+  - const: axi_aclk
+
+  resets:
+description: phandle pointing to the dma reset controller provider node.
+
+  reset-names:
+items:
+  - const: dma-reset
+
+  dma-requests:
+maximum: 32
+
+  dma-channels:
+maximum: 8
+
+
+required:
+  - "#dma-cells"
+  - compatible
+  - hisilicon,misc-control
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - dma-requests
+  - dma-channels
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+dma: dma-controller@1004 {
+  compatible = "hisilicon,hiedmacv310";
+  reg = <0x1004 0x1000>;
+  hisilicon,misc-control = <&misc_ctrl 0x144>;
+  interrupts = <0 82 4>;
+  clocks = <&clock HI3559AV100_EDMAC1_CLK>, <&clock 
HI3559AV100_EDMAC1_AXICLK>;
+  clock-names = "apb_pclk", "axi_aclk";
+  resets = <&clock 0x16c 7>;
+  reset-names = "dma-reset";
+  dma-requests = <32>;
+  dma-channels = <8>;
+  #dma-cells = <2>;
+};
+
+...
-- 
2.17.1



Re: [PATCH RESEND v6 3/4] dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller

2020-12-14 Thread Dongjiu Geng
On 2020/12/12 4:57, Rob Herring wrote:
> On Sat, 12 Dec 2020 13:11:14 +0000, Dongjiu Geng wrote:
>> The Hiedma Controller v310 Provides eight DMA channels, each
>> channel can be configured for one-way transfer. The data can
>> be transferred in 8-bit, 16-bit, 32-bit, or 64-bit mode. This
>> documentation describes DT bindings of this controller.
>>
>> Signed-off-by: Dongjiu Geng 
>> ---
>>  .../bindings/dma/hisilicon,hiedmacv310.yaml   | 94 +++
>>  1 file changed, 94 insertions(+)
>>  create mode 100644 
>> Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
>>
> 
> 
> My bot found errors running 'make dt_binding_check' on your patch:
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.example.dt.yaml:
>  dma-controller@1004: 'hisi,misc-control' does not match any of the 
> regexes: '^#.*', 
> '^(at25|devbus|dmacap|dsa|exynos|fsi[ab]|gpio-fan|gpio|gpmc|hdmi|i2c-gpio),.*',
>  '^(keypad|m25p|max8952|max8997|max8998|mpmc),.*', 
> '^(pinctrl-single|#pinctrl-single|PowerPC),.*', 
> '^(pl022|pxa-mmc|rcar_sound|rotary-encoder|s5m8767|sdhci),.*', 
> '^(simple-audio-card|st-plgpio|st-spics|ts),.*', '^70mai,.*', '^GEFanuc,.*', 
> '^ORCL,.*', '^SUNW,.*', '^[a-zA-Z0-9#_][a-zA-Z0-9+\\-._@]{0,63}$', 
> '^[a-zA-Z0-9+\\-._]*@[0-9a-zA-Z,]*$', '^abilis,.*', '^abracon,.*', 
> '^acer,.*', '^acme,.*', '^actions,.*', '^active-semi,.*', '^ad,.*', 
> '^adafruit,.*', '^adapteva,.*', '^adaptrum,.*', '^adh,.*', '^adi,.*', 
> '^advantech,.*', '^aeroflexgaisler,.*', '^al,.*', '^allegro,.*', '^allo,.*', 
> '^allwinner,.*', '^alphascale,.*', '^alps,.*', '^altr,.*', '^amarula,.*', 
> '^amazon,.*', '^amcc,.*', '^amd,.*', '^amediatech,.*', '^amlogic,.*', 
> '^ampire,.*', '^ams,.*', '^amstaos,.*', '^analogix,.*', '^andestech,.*', 
> '^anvo,.*', '^apm,.*', '^aptina,.*', '^arasan,.*', '^archermind,.*', 
> '^arctic,.*', '^arcx,.*', '^aries,.*', '^arm,.*', '^armadeus,.*', 
> '^arrow,.*', '^artesyn,.*', '^asahi-kasei,.*', '^asc,.*', '^aspeed,.*', 
> '^asus,.*', '^atlas,.*', '^atmel,.*', '^auo,.*', '^auvidea,.*', '^avago,.*', 
> '^avia,.*', '^avic,.*', '^avnet,.*', '^awinic,.*', '^axentia,.*', '^axis,.*', 
> '^azoteq,.*', '^azw,.*', '^baikal,.*', '^bananapi,.*', '^beacon,.*', 
> '^beagle,.*', '^bhf,.*', '^bitmain,.*', '^boe,.*', '^bosch,.*', 
> '^boundary,.*', '^brcm,.*', '^broadmobi,.*', '^bticino,.*', '^buffalo,.*', 
> '^bur,.*', '^calaosystems,.*', '^calxeda,.*', '^caninos,.*', '^capella,.*', 
> '^cascoda,.*', '^catalyst,.*', '^cavium,.*', '^cdns,.*', '^cdtech,.*', 
> '^cellwise,.*', '^ceva,.*', '^checkpoint,.*', '^chefree,.*', '^chipidea,.*', 
> '^chipone,.*', '^chipspark,.*', '^chrontel,.*', '^chrp,.*', '^chunghwa,.*', 
> '^chuwi,.*', '^ciaa,.*', '^cirrus,.*', '^cloudengines,.*', '^cnm,.*', 
> '^cnxt,.*', '^colorfly,.*', '^compulab,.*', '^coreriver,.*', '^corpro,.*', 
> '^cortina,.*', '^cosmic,.*', '^crane,.*', '^creative,.*', '^crystalfontz,.*', 
> '^csky,.*', '^csq,.*', '^cubietech,.*', '^cypress,.*', '^cznic,.*', 
> '^dallas,.*', '^dataimage,.*', '^davicom,.*', '^dell,.*', '^delta,.*', 
> '^denx,.*', '^devantech,.*', '^dfi,.*', '^dh,.*', '^difrnce,.*', '^digi,.*', 
> '^digilent,.*', '^dioo,.*', '^dlc,.*', '^dlg,.*', '^dlink,.*', '^dmo,.*', 
> '^domintech,.*&#

[PATCH v7 2/4] clk: hisilicon: Add clock driver for hi3559A SoC

2020-12-14 Thread Dongjiu Geng
Add clock drivers for hi3559A SoC, this driver
controls the SoC registers to supply different
clocks to different IPs in the SoC.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/Kconfig   |   7 +
 drivers/clk/hisilicon/Makefile  |   1 +
 drivers/clk/hisilicon/clk-hi3559a.c | 865 
 3 files changed, 873 insertions(+)
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 6a9e93a0bb95..5ecc37aaa118 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
help
  Build the clock driver for hi3519.
 
+config COMMON_CLK_HI3559A
+   bool "Hi3559A Clock Driver"
+   depends on ARCH_HISI || COMPILE_TEST
+   default ARCH_HISI
+   help
+ Build the clock driver for hi3559a.
+
 config COMMON_CLK_HI3660
bool "Hi3660 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index b2441b99f3d5..bc101833b35e 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_COMMON_CLK_HI6220)   += clk-hi6220.o
 obj-$(CONFIG_RESET_HISI)   += reset.o
 obj-$(CONFIG_STUB_CLK_HI6220)  += clk-hi6220-stub.o
 obj-$(CONFIG_STUB_CLK_HI3660)  += clk-hi3660-stub.o
+obj-$(CONFIG_COMMON_CLK_HI3559A)   += clk-hi3559a.o
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
b/drivers/clk/hisilicon/clk-hi3559a.c
new file mode 100644
index ..d7693e488006
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Hisilicon Hi3559A clock driver
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "crg.h"
+#include "reset.h"
+
+#define CRG_BASE_ADDR  0x1802
+
+struct hi3559av100_pll_clock {
+   u32 id;
+   const char  *name;
+   const char  *parent_name;
+   u32 ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   u32 ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+struct hi3559av100_clk_pll {
+   struct clk_hw   hw;
+   u32 id;
+   void __iomem*ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   void __iomem*ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+/* soc clk config */
+static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = {
+   { HI3559AV100_FIXED_1188M, "1188m",   NULL, 0, 118800, },
+   { HI3559AV100_FIXED_1000M, "1000m",   NULL, 0, 10, },
+   { HI3559AV100_FIXED_842M, "842m",NULL, 0, 84200, },
+   { HI3559AV100_FIXED_792M, "792m",NULL, 0, 79200, },
+   { HI3559AV100_FIXED_750M, "750m",NULL, 0, 75000, },
+   { HI3559AV100_FIXED_710M, "710m",NULL, 0, 71000, },
+   { HI3559AV100_FIXED_680M, "680m",NULL, 0, 68000, },
+   { HI3559AV100_FIXED_667M, "667m",NULL, 0, 66700, },
+   { HI3559AV100_FIXED_631M, "631m",NULL, 0, 63100, },
+   { HI3559AV100_FIXED_600M, "600m",NULL, 0, 6, },
+   { HI3559AV100_FIXED_568M, "568m",NULL, 0, 56800, },
+   { HI3559AV100_FIXED_500M, "500m",NULL, 0, 5, },
+   { HI3559AV100_FIXED_475M, "475m",NULL, 0, 47500, },
+   { HI3559AV100_FIXED_428M, "428m",NULL, 0, 42800, },
+   { HI3559AV100_FIXED_400M, "400m",NULL, 0, 4, },
+   { HI3559AV100_FIXED_396M, "396m",NULL, 0, 39600, },
+   { HI3559AV100_FIXED_300M, "300m",NULL, 0, 3, },
+   { HI3559AV100_FIXED_250M, "250m",NULL, 0, 25000, },
+   { HI3559AV100_FIXED_200M, "200m",NULL, 0, 2, },
+   { HI3559AV100_FIXED_198M, "198m",NULL, 0, 19800, },
+   { HI3559AV100_FIXED_187p5M, "187p5m",  NULL, 0, 18750, },
+   { HI3559AV100_FIXED_150M, "150m",NULL, 0, 15000, },
+   { HI3559AV100_FIXED_148p5M, "148p5m",  NULL, 0, 148500, },
+   { HI3559AV100_FIXED_125M, "125m&quo

[PATCH v7 0/4] Enable Hi3559A SOC clock and HiSilicon Hiedma Controller

2020-12-14 Thread Dongjiu Geng
v6->v7:
1. rename hisi,misc-control to hisi,misc-control to hisilicon,misc-control

v5->v6:
1. Drop #size-cells and #address-cell in the hisilicon,hi3559av100-clock.yaml
2. Add discription for #reset-cells in the hisilicon,hi3559av100-clock.yaml
3. Remove #clock-cells in hisilicon,hiedmacv310.yaml 
4. Merge property misc_ctrl_base and misc_regmap together for hiedmacv310 driver

v4->v5:
1. change the patch author mail name

v3->v4:
1. fix the 'make dt_binding_check' issues.
2. Combine the 'Enable HiSilicon Hiedma Controller' series patches to this 
series.
3. fix the 'make dt_binding_check' issues in 'Enable HiSilicon Hiedma 
Controller' patchset

v2->v3:
1. change dt-bindings documents from txt to yaml format.
2. Add SHUB clock to access the devices of m7

Dongjiu Geng (4):
  dt-bindings: Document the hi3559a clock bindings
  clk: hisilicon: Add clock driver for hi3559A SoC
  dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller
  dmaengine: dma: Add Hiedma Controller v310 Device Driver

 .../clock/hisilicon,hi3559av100-clock.yaml|   59 +
 .../bindings/dma/hisilicon,hiedmacv310.yaml   |   94 ++
 drivers/clk/hisilicon/Kconfig |7 +
 drivers/clk/hisilicon/Makefile|1 +
 drivers/clk/hisilicon/clk-hi3559a.c   |  865 ++
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 ++
 include/dt-bindings/clock/hi3559av100-clock.h |  165 ++
 10 files changed, 2784 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

-- 
2.17.1



[PATCH v7 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-12-14 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1593 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..c0df5088a6a1
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1442 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

[PATCH v7 1/4] dt-bindings: Document the hi3559a clock bindings

2020-12-14 Thread Dongjiu Geng
Add DT bindings documentation for hi3559a SoC clock.

Signed-off-by: Dongjiu Geng 
---
 .../clock/hisilicon,hi3559av100-clock.yaml|  59 +++
 include/dt-bindings/clock/hi3559av100-clock.h | 165 ++
 2 files changed, 224 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

diff --git 
a/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml 
b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
new file mode 100644
index ..3ceb29cec704
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/hisilicon,hi3559av100-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hisilicon SOC Clock for HI3559AV100
+
+maintainers:
+  - Dongjiu Geng 
+
+description: |
+  Hisilicon SOC clock control module which supports the clocks, resets and
+  power domains on HI3559AV100.
+
+  See also:
+dt-bindings/clock/hi3559av100-clock.h
+
+properties:
+  compatible:
+enum:
+  - hisilicon,hi3559av100-clock
+  - hisilicon,hi3559av100-shub-clock
+
+  reg:
+minItems: 1
+maxItems: 2
+
+  '#clock-cells':
+const: 1
+
+  '#reset-cells':
+const: 2
+description: |
+  First cell is reset request register offset.
+  Second cell is bit offset in reset request register.
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+clock-controller@1201 {
+compatible = "hisilicon,hi3559av100-clock";
+#clock-cells = <1>;
+#reset-cells = <2>;
+reg = <0x0 0x1201 0x0 0x1>;
+};
+};
+...
diff --git a/include/dt-bindings/clock/hi3559av100-clock.h 
b/include/dt-bindings/clock/hi3559av100-clock.h
new file mode 100644
index ..5fe7689010a0
--- /dev/null
+++ b/include/dt-bindings/clock/hi3559av100-clock.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+/*
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#ifndef __DTS_HI3559AV100_CLOCK_H
+#define __DTS_HI3559AV100_CLOCK_H
+
+/*  fixed   rate*/
+#define HI3559AV100_FIXED_1188M 1
+#define HI3559AV100_FIXED_1000M 2
+#define HI3559AV100_FIXED_842M  3
+#define HI3559AV100_FIXED_792M  4
+#define HI3559AV100_FIXED_750M  5
+#define HI3559AV100_FIXED_710M  6
+#define HI3559AV100_FIXED_680M  7
+#define HI3559AV100_FIXED_667M  8
+#define HI3559AV100_FIXED_631M  9
+#define HI3559AV100_FIXED_600M  10
+#define HI3559AV100_FIXED_568M  11
+#define HI3559AV100_FIXED_500M  12
+#define HI3559AV100_FIXED_475M  13
+#define HI3559AV100_FIXED_428M  14
+#define HI3559AV100_FIXED_400M  15
+#define HI3559AV100_FIXED_396M  16
+#define HI3559AV100_FIXED_300M  17
+#define HI3559AV100_FIXED_250M  18
+#define HI3559AV100_FIXED_198M  19
+#define HI3559AV100_FIXED_187p5M20
+#define HI3559AV100_FIXED_150M  21
+#define HI3559AV100_FIXED_148p5M22
+#define HI3559AV100_FIXED_125M  23
+#define HI3559AV100_FIXED_107M  24
+#define HI3559AV100_FIXED_100M  25
+#define HI3559AV100_FIXED_99M   26
+#define HI3559AV100_FIXED_74p25M27
+#define HI3559AV100_FIXED_72M   28
+#define HI3559AV100_FIXED_60M   29
+#define HI3559AV100_FIXED_54M   30
+#define HI3559AV100_FIXED_50M   31
+#define HI3559AV100_FIXED_49p5M 32
+#define HI3559AV100_FIXED_37p125M   33
+#define HI3559AV100_FIXED_36M   34
+#define HI3559AV100_FIXED_32p4M 35
+#define HI3559AV100_FIXED_27M   36
+#define HI3559AV100_FIXED_25M   37
+#define HI3559AV100_FIXED_24M   38
+#define HI3559AV100_FIXED_12M   39
+#define HI3559AV100_FIXED_3M40
+#define HI3559AV100_FIXED_1p6M  41
+#define HI3559AV100_FIXED_400K  42
+#define HI3559AV100_FIXED_100K  43
+#define HI3559AV100_FIXED_200M  44
+#define HI3559AV100_FIXED_75M   75
+
+#define HI3559AV100_I2C0_CLK50
+#define HI3559AV100_I2C1_CLK51
+#define HI3559AV100_I2C2_CLK52
+#define HI3559AV100_I2C3_CLK53
+#define HI3559AV100_I2C4_CLK54
+#define HI3559AV100_I2C5_CLK55
+#define HI3559AV100_I2C6_CLK56
+#define HI3559AV100_I2C7_CLK57
+#define HI3559AV100_I2C8_CLK58
+#define HI3559AV100_I2C9_CLK59
+#define HI3559AV100_I2C10_CLK   60
+#define HI3559AV100_I2C11_CLK   61
+
+#define HI3559AV100_SPI0_CLK62
+#define HI3559AV100_SPI1_CLK63
+#define HI3559AV100_SPI2_CLK64
+#define HI3559AV100_SPI3_CLK65
+#define HI3559AV100_SPI4_C

[PATCH RESEND v6 3/4] dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller

2020-12-11 Thread Dongjiu Geng
The Hiedma Controller v310 Provides eight DMA channels, each
channel can be configured for one-way transfer. The data can
be transferred in 8-bit, 16-bit, 32-bit, or 64-bit mode. This
documentation describes DT bindings of this controller.

Signed-off-by: Dongjiu Geng 
---
 .../bindings/dma/hisilicon,hiedmacv310.yaml   | 94 +++
 1 file changed, 94 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml

diff --git a/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml 
b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
new file mode 100644
index ..f57703fbbe7b
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
@@ -0,0 +1,94 @@
+# SPDX-License-Identifier:  GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/hisilicon,hiedmacv310.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon Hiedma Controller v310 Device Tree Bindings
+
+description: |
+  These bindings describe the DMA engine included in the HiSilicon Hiedma
+  Controller v310 Device.
+
+maintainers:
+  - Dongjiu Geng 
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+const: 2
+
+  compatible:
+const: hisilicon,hiedmacv310
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  hisi,misc-control:
+$ref: /schemas/types.yaml#definitions/phandle-array
+description: phandle pointing to the misc controller provider node and 
base register.
+
+  clocks:
+items:
+  - description: apb clock
+  - description: axi clock
+
+  clock-names:
+items:
+  - const: apb_pclk
+  - const: axi_aclk
+
+  resets:
+description: phandle pointing to the dma reset controller provider node.
+
+  reset-names:
+items:
+  - const: dma-reset
+
+  dma-requests:
+maximum: 32
+
+  dma-channels:
+maximum: 8
+
+
+required:
+  - "#dma-cells"
+  - compatible
+  - hisi,misc-control
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - dma-requests
+  - dma-channels
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+dma: dma-controller@1004 {
+  compatible = "hisilicon,hiedmacv310";
+  reg = <0x1004 0x1000>;
+  hisi,misc-control = <&misc_ctrl 0x144>;
+  interrupts = <0 82 4>;
+  clocks = <&clock HI3559AV100_EDMAC1_CLK>, <&clock 
HI3559AV100_EDMAC1_AXICLK>;
+  clock-names = "apb_pclk", "axi_aclk";
+  resets = <&clock 0x16c 7>;
+  reset-names = "dma-reset";
+  dma-requests = <32>;
+  dma-channels = <8>;
+  #dma-cells = <2>;
+};
+
+...
-- 
2.17.1



[PATCH RESEND v6 1/4] dt-bindings: Document the hi3559a clock bindings

2020-12-11 Thread Dongjiu Geng
Add DT bindings documentation for hi3559a SoC clock.

Signed-off-by: Dongjiu Geng 
---
 .../clock/hisilicon,hi3559av100-clock.yaml|  59 +++
 include/dt-bindings/clock/hi3559av100-clock.h | 165 ++
 2 files changed, 224 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

diff --git 
a/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml 
b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
new file mode 100644
index ..3ceb29cec704
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/hisilicon,hi3559av100-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hisilicon SOC Clock for HI3559AV100
+
+maintainers:
+  - Dongjiu Geng 
+
+description: |
+  Hisilicon SOC clock control module which supports the clocks, resets and
+  power domains on HI3559AV100.
+
+  See also:
+dt-bindings/clock/hi3559av100-clock.h
+
+properties:
+  compatible:
+enum:
+  - hisilicon,hi3559av100-clock
+  - hisilicon,hi3559av100-shub-clock
+
+  reg:
+minItems: 1
+maxItems: 2
+
+  '#clock-cells':
+const: 1
+
+  '#reset-cells':
+const: 2
+description: |
+  First cell is reset request register offset.
+  Second cell is bit offset in reset request register.
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+clock-controller@1201 {
+compatible = "hisilicon,hi3559av100-clock";
+#clock-cells = <1>;
+#reset-cells = <2>;
+reg = <0x0 0x1201 0x0 0x1>;
+};
+};
+...
diff --git a/include/dt-bindings/clock/hi3559av100-clock.h 
b/include/dt-bindings/clock/hi3559av100-clock.h
new file mode 100644
index ..5fe7689010a0
--- /dev/null
+++ b/include/dt-bindings/clock/hi3559av100-clock.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+/*
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#ifndef __DTS_HI3559AV100_CLOCK_H
+#define __DTS_HI3559AV100_CLOCK_H
+
+/*  fixed   rate*/
+#define HI3559AV100_FIXED_1188M 1
+#define HI3559AV100_FIXED_1000M 2
+#define HI3559AV100_FIXED_842M  3
+#define HI3559AV100_FIXED_792M  4
+#define HI3559AV100_FIXED_750M  5
+#define HI3559AV100_FIXED_710M  6
+#define HI3559AV100_FIXED_680M  7
+#define HI3559AV100_FIXED_667M  8
+#define HI3559AV100_FIXED_631M  9
+#define HI3559AV100_FIXED_600M  10
+#define HI3559AV100_FIXED_568M  11
+#define HI3559AV100_FIXED_500M  12
+#define HI3559AV100_FIXED_475M  13
+#define HI3559AV100_FIXED_428M  14
+#define HI3559AV100_FIXED_400M  15
+#define HI3559AV100_FIXED_396M  16
+#define HI3559AV100_FIXED_300M  17
+#define HI3559AV100_FIXED_250M  18
+#define HI3559AV100_FIXED_198M  19
+#define HI3559AV100_FIXED_187p5M20
+#define HI3559AV100_FIXED_150M  21
+#define HI3559AV100_FIXED_148p5M22
+#define HI3559AV100_FIXED_125M  23
+#define HI3559AV100_FIXED_107M  24
+#define HI3559AV100_FIXED_100M  25
+#define HI3559AV100_FIXED_99M   26
+#define HI3559AV100_FIXED_74p25M27
+#define HI3559AV100_FIXED_72M   28
+#define HI3559AV100_FIXED_60M   29
+#define HI3559AV100_FIXED_54M   30
+#define HI3559AV100_FIXED_50M   31
+#define HI3559AV100_FIXED_49p5M 32
+#define HI3559AV100_FIXED_37p125M   33
+#define HI3559AV100_FIXED_36M   34
+#define HI3559AV100_FIXED_32p4M 35
+#define HI3559AV100_FIXED_27M   36
+#define HI3559AV100_FIXED_25M   37
+#define HI3559AV100_FIXED_24M   38
+#define HI3559AV100_FIXED_12M   39
+#define HI3559AV100_FIXED_3M40
+#define HI3559AV100_FIXED_1p6M  41
+#define HI3559AV100_FIXED_400K  42
+#define HI3559AV100_FIXED_100K  43
+#define HI3559AV100_FIXED_200M  44
+#define HI3559AV100_FIXED_75M   75
+
+#define HI3559AV100_I2C0_CLK50
+#define HI3559AV100_I2C1_CLK51
+#define HI3559AV100_I2C2_CLK52
+#define HI3559AV100_I2C3_CLK53
+#define HI3559AV100_I2C4_CLK54
+#define HI3559AV100_I2C5_CLK55
+#define HI3559AV100_I2C6_CLK56
+#define HI3559AV100_I2C7_CLK57
+#define HI3559AV100_I2C8_CLK58
+#define HI3559AV100_I2C9_CLK59
+#define HI3559AV100_I2C10_CLK   60
+#define HI3559AV100_I2C11_CLK   61
+
+#define HI3559AV100_SPI0_CLK62
+#define HI3559AV100_SPI1_CLK63
+#define HI3559AV100_SPI2_CLK64
+#define HI3559AV100_SPI3_CLK65
+#define HI3559AV100_SPI4_C

[PATCH RESEND v6 2/4] clk: hisilicon: Add clock driver for hi3559A SoC

2020-12-11 Thread Dongjiu Geng
Add clock drivers for hi3559A SoC, this driver
controls the SoC registers to supply different
clocks to different IPs in the SoC.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/Kconfig   |   7 +
 drivers/clk/hisilicon/Makefile  |   1 +
 drivers/clk/hisilicon/clk-hi3559a.c | 865 
 3 files changed, 873 insertions(+)
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 6a9e93a0bb95..5ecc37aaa118 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
help
  Build the clock driver for hi3519.
 
+config COMMON_CLK_HI3559A
+   bool "Hi3559A Clock Driver"
+   depends on ARCH_HISI || COMPILE_TEST
+   default ARCH_HISI
+   help
+ Build the clock driver for hi3559a.
+
 config COMMON_CLK_HI3660
bool "Hi3660 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index b2441b99f3d5..bc101833b35e 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_COMMON_CLK_HI6220)   += clk-hi6220.o
 obj-$(CONFIG_RESET_HISI)   += reset.o
 obj-$(CONFIG_STUB_CLK_HI6220)  += clk-hi6220-stub.o
 obj-$(CONFIG_STUB_CLK_HI3660)  += clk-hi3660-stub.o
+obj-$(CONFIG_COMMON_CLK_HI3559A)   += clk-hi3559a.o
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
b/drivers/clk/hisilicon/clk-hi3559a.c
new file mode 100644
index ..d7693e488006
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Hisilicon Hi3559A clock driver
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "crg.h"
+#include "reset.h"
+
+#define CRG_BASE_ADDR  0x1802
+
+struct hi3559av100_pll_clock {
+   u32 id;
+   const char  *name;
+   const char  *parent_name;
+   u32 ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   u32 ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+struct hi3559av100_clk_pll {
+   struct clk_hw   hw;
+   u32 id;
+   void __iomem*ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   void __iomem*ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+/* soc clk config */
+static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = {
+   { HI3559AV100_FIXED_1188M, "1188m",   NULL, 0, 118800, },
+   { HI3559AV100_FIXED_1000M, "1000m",   NULL, 0, 10, },
+   { HI3559AV100_FIXED_842M, "842m",NULL, 0, 84200, },
+   { HI3559AV100_FIXED_792M, "792m",NULL, 0, 79200, },
+   { HI3559AV100_FIXED_750M, "750m",NULL, 0, 75000, },
+   { HI3559AV100_FIXED_710M, "710m",NULL, 0, 71000, },
+   { HI3559AV100_FIXED_680M, "680m",NULL, 0, 68000, },
+   { HI3559AV100_FIXED_667M, "667m",NULL, 0, 66700, },
+   { HI3559AV100_FIXED_631M, "631m",NULL, 0, 63100, },
+   { HI3559AV100_FIXED_600M, "600m",NULL, 0, 6, },
+   { HI3559AV100_FIXED_568M, "568m",NULL, 0, 56800, },
+   { HI3559AV100_FIXED_500M, "500m",NULL, 0, 5, },
+   { HI3559AV100_FIXED_475M, "475m",NULL, 0, 47500, },
+   { HI3559AV100_FIXED_428M, "428m",NULL, 0, 42800, },
+   { HI3559AV100_FIXED_400M, "400m",NULL, 0, 4, },
+   { HI3559AV100_FIXED_396M, "396m",NULL, 0, 39600, },
+   { HI3559AV100_FIXED_300M, "300m",NULL, 0, 3, },
+   { HI3559AV100_FIXED_250M, "250m",NULL, 0, 25000, },
+   { HI3559AV100_FIXED_200M, "200m",NULL, 0, 2, },
+   { HI3559AV100_FIXED_198M, "198m",NULL, 0, 19800, },
+   { HI3559AV100_FIXED_187p5M, "187p5m",  NULL, 0, 18750, },
+   { HI3559AV100_FIXED_150M, "150m",NULL, 0, 15000, },
+   { HI3559AV100_FIXED_148p5M, "148p5m",  NULL, 0, 148500, },
+   { HI3559AV100_FIXED_125M, "125m&quo

[PATCH v6 RESEND 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-12-11 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1593 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..ddf9b5d85a27
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1442 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

[PATCH RESEND v6 0/4] Enable Hi3559A SOC clock and HiSilicon Hiedma Controller

2020-12-11 Thread Dongjiu Geng
v5->v6:
1. Drop #size-cells and #address-cell in the hisilicon,hi3559av100-clock.yaml
2. Add discription for #reset-cells in the hisilicon,hi3559av100-clock.yaml
3. Remove #clock-cells in hisilicon,hiedmacv310.yaml 
4. Merge property misc_ctrl_base and misc_regmap together for hiedmacv310 driver

v4->v5:
1. change the patch author mail name

v3->v4:
1. fix the 'make dt_binding_check' issues.
2. Combine the 'Enable HiSilicon Hiedma Controller' series patches to this 
series.
3. fix the 'make dt_binding_check' issues in 'Enable HiSilicon Hiedma 
Controller' patchset


v2->v3:
1. change dt-bindings documents from txt to yaml format.
2. Add SHUB clock to access the devices of m7

Dongjiu Geng (4):
  dt-bindings: Document the hi3559a clock bindings
  clk: hisilicon: Add clock driver for hi3559A SoC
  dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller
  dmaengine: dma: Add Hiedma Controller v310 Device Driver

 .../clock/hisilicon,hi3559av100-clock.yaml|   59 +
 .../bindings/dma/hisilicon,hiedmacv310.yaml   |   94 ++
 drivers/clk/hisilicon/Kconfig |7 +
 drivers/clk/hisilicon/Makefile|1 +
 drivers/clk/hisilicon/clk-hi3559a.c   |  865 ++
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 ++
 include/dt-bindings/clock/hi3559av100-clock.h |  165 ++
 10 files changed, 2784 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

-- 
2.17.1



[PATCH v6 0/4] Enable Hi3559A SOC clock and HiSilicon Hiedma Controller

2020-12-11 Thread Dongjiu Geng
v5->v6:
1. Drop #size-cells and #address-cell in the hisilicon,hi3559av100-clock.yaml
2. Add discription for #reset-cells in the hisilicon,hi3559av100-clock.yaml
3. Remove #clock-cells in hisilicon,hiedmacv310.yaml 
4. Merge property misc_ctrl_base and misc_regmap together for hiedmacv310 driver

v4->v5:
1. change the patch author mail name

v3->v4:
1. fix the 'make dt_binding_check' issues.
2. Combine the 'Enable HiSilicon Hiedma Controller' series patches to this 
series.
3. fix the 'make dt_binding_check' issues in 'Enable HiSilicon Hiedma 
Controller' patchset


v2->v3:
1. change dt-bindings documents from txt to yaml format.
2. Add SHUB clock to access the devices of m7

Dongjiu Geng (4):
  dt-bindings: Document the hi3559a clock bindings
  clk: hisilicon: Add clock driver for hi3559A SoC
  dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller
  dmaengine: dma: Add Hiedma Controller v310 Device Driver

 .../clock/hisilicon,hi3559av100-clock.yaml|   59 +
 .../bindings/dma/hisilicon,hiedmacv310.yaml   |   94 ++
 drivers/clk/hisilicon/Kconfig |7 +
 drivers/clk/hisilicon/Makefile|1 +
 drivers/clk/hisilicon/clk-hi3559a.c   |  865 ++
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 ++
 include/dt-bindings/clock/hi3559av100-clock.h |  165 ++
 10 files changed, 2784 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

-- 
2.17.1



[PATCH v6 1/4] dt-bindings: Document the hi3559a clock bindings

2020-12-11 Thread Dongjiu Geng
Add DT bindings documentation for hi3559a SoC clock.

Signed-off-by: Dongjiu Geng 
---
 .../clock/hisilicon,hi3559av100-clock.yaml|  59 +++
 include/dt-bindings/clock/hi3559av100-clock.h | 165 ++
 2 files changed, 224 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

diff --git 
a/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml 
b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
new file mode 100644
index ..3ceb29cec704
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/hisilicon,hi3559av100-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hisilicon SOC Clock for HI3559AV100
+
+maintainers:
+  - Dongjiu Geng 
+
+description: |
+  Hisilicon SOC clock control module which supports the clocks, resets and
+  power domains on HI3559AV100.
+
+  See also:
+dt-bindings/clock/hi3559av100-clock.h
+
+properties:
+  compatible:
+enum:
+  - hisilicon,hi3559av100-clock
+  - hisilicon,hi3559av100-shub-clock
+
+  reg:
+minItems: 1
+maxItems: 2
+
+  '#clock-cells':
+const: 1
+
+  '#reset-cells':
+const: 2
+description: |
+  First cell is reset request register offset.
+  Second cell is bit offset in reset request register.
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+clock-controller@1201 {
+compatible = "hisilicon,hi3559av100-clock";
+#clock-cells = <1>;
+#reset-cells = <2>;
+reg = <0x0 0x1201 0x0 0x1>;
+};
+};
+...
diff --git a/include/dt-bindings/clock/hi3559av100-clock.h 
b/include/dt-bindings/clock/hi3559av100-clock.h
new file mode 100644
index ..5fe7689010a0
--- /dev/null
+++ b/include/dt-bindings/clock/hi3559av100-clock.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+/*
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#ifndef __DTS_HI3559AV100_CLOCK_H
+#define __DTS_HI3559AV100_CLOCK_H
+
+/*  fixed   rate*/
+#define HI3559AV100_FIXED_1188M 1
+#define HI3559AV100_FIXED_1000M 2
+#define HI3559AV100_FIXED_842M  3
+#define HI3559AV100_FIXED_792M  4
+#define HI3559AV100_FIXED_750M  5
+#define HI3559AV100_FIXED_710M  6
+#define HI3559AV100_FIXED_680M  7
+#define HI3559AV100_FIXED_667M  8
+#define HI3559AV100_FIXED_631M  9
+#define HI3559AV100_FIXED_600M  10
+#define HI3559AV100_FIXED_568M  11
+#define HI3559AV100_FIXED_500M  12
+#define HI3559AV100_FIXED_475M  13
+#define HI3559AV100_FIXED_428M  14
+#define HI3559AV100_FIXED_400M  15
+#define HI3559AV100_FIXED_396M  16
+#define HI3559AV100_FIXED_300M  17
+#define HI3559AV100_FIXED_250M  18
+#define HI3559AV100_FIXED_198M  19
+#define HI3559AV100_FIXED_187p5M20
+#define HI3559AV100_FIXED_150M  21
+#define HI3559AV100_FIXED_148p5M22
+#define HI3559AV100_FIXED_125M  23
+#define HI3559AV100_FIXED_107M  24
+#define HI3559AV100_FIXED_100M  25
+#define HI3559AV100_FIXED_99M   26
+#define HI3559AV100_FIXED_74p25M27
+#define HI3559AV100_FIXED_72M   28
+#define HI3559AV100_FIXED_60M   29
+#define HI3559AV100_FIXED_54M   30
+#define HI3559AV100_FIXED_50M   31
+#define HI3559AV100_FIXED_49p5M 32
+#define HI3559AV100_FIXED_37p125M   33
+#define HI3559AV100_FIXED_36M   34
+#define HI3559AV100_FIXED_32p4M 35
+#define HI3559AV100_FIXED_27M   36
+#define HI3559AV100_FIXED_25M   37
+#define HI3559AV100_FIXED_24M   38
+#define HI3559AV100_FIXED_12M   39
+#define HI3559AV100_FIXED_3M40
+#define HI3559AV100_FIXED_1p6M  41
+#define HI3559AV100_FIXED_400K  42
+#define HI3559AV100_FIXED_100K  43
+#define HI3559AV100_FIXED_200M  44
+#define HI3559AV100_FIXED_75M   75
+
+#define HI3559AV100_I2C0_CLK50
+#define HI3559AV100_I2C1_CLK51
+#define HI3559AV100_I2C2_CLK52
+#define HI3559AV100_I2C3_CLK53
+#define HI3559AV100_I2C4_CLK54
+#define HI3559AV100_I2C5_CLK55
+#define HI3559AV100_I2C6_CLK56
+#define HI3559AV100_I2C7_CLK57
+#define HI3559AV100_I2C8_CLK58
+#define HI3559AV100_I2C9_CLK59
+#define HI3559AV100_I2C10_CLK   60
+#define HI3559AV100_I2C11_CLK   61
+
+#define HI3559AV100_SPI0_CLK62
+#define HI3559AV100_SPI1_CLK63
+#define HI3559AV100_SPI2_CLK64
+#define HI3559AV100_SPI3_CLK65
+#define HI3559AV100_SPI4_C

[PATCH v6 3/4] dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller

2020-12-11 Thread Dongjiu Geng
The Hiedma Controller v310 Provides eight DMA channels, each
channel can be configured for one-way transfer. The data can
be transferred in 8-bit, 16-bit, 32-bit, or 64-bit mode. This
documentation describes DT bindings of this controller.

Signed-off-by: Dongjiu Geng 
---
 .../bindings/dma/hisilicon,hiedmacv310.yaml   | 94 +++
 1 file changed, 94 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml

diff --git a/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml 
b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
new file mode 100644
index ..f57703fbbe7b
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
@@ -0,0 +1,94 @@
+# SPDX-License-Identifier:  GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/hisilicon,hiedmacv310.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon Hiedma Controller v310 Device Tree Bindings
+
+description: |
+  These bindings describe the DMA engine included in the HiSilicon Hiedma
+  Controller v310 Device.
+
+maintainers:
+  - Dongjiu Geng 
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+const: 2
+
+  compatible:
+const: hisilicon,hiedmacv310
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  hisi,misc-control:
+$ref: /schemas/types.yaml#definitions/phandle-array
+description: phandle pointing to the misc controller provider node and 
base register.
+
+  clocks:
+items:
+  - description: apb clock
+  - description: axi clock
+
+  clock-names:
+items:
+  - const: apb_pclk
+  - const: axi_aclk
+
+  resets:
+description: phandle pointing to the dma reset controller provider node.
+
+  reset-names:
+items:
+  - const: dma-reset
+
+  dma-requests:
+maximum: 32
+
+  dma-channels:
+maximum: 8
+
+
+required:
+  - "#dma-cells"
+  - compatible
+  - hisi,misc-control
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - dma-requests
+  - dma-channels
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+dma: dma-controller@1004 {
+  compatible = "hisilicon,hiedmacv310";
+  reg = <0x1004 0x1000>;
+  hisi,misc-control = <&misc_ctrl 0x144>;
+  interrupts = <0 82 4>;
+  clocks = <&clock HI3559AV100_EDMAC1_CLK>, <&clock 
HI3559AV100_EDMAC1_AXICLK>;
+  clock-names = "apb_pclk", "axi_aclk";
+  resets = <&clock 0x16c 7>;
+  reset-names = "dma-reset";
+  dma-requests = <32>;
+  dma-channels = <8>;
+  #dma-cells = <2>;
+};
+
+...
-- 
2.17.1



[PATCH v6 2/4] clk: hisilicon: Add clock driver for hi3559A SoC

2020-12-11 Thread Dongjiu Geng
Add clock drivers for hi3559A SoC, this driver
controls the SoC registers to supply different
clocks to different IPs in the SoC.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/Kconfig   |   7 +
 drivers/clk/hisilicon/Makefile  |   1 +
 drivers/clk/hisilicon/clk-hi3559a.c | 865 
 3 files changed, 873 insertions(+)
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 6a9e93a0bb95..5ecc37aaa118 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
help
  Build the clock driver for hi3519.
 
+config COMMON_CLK_HI3559A
+   bool "Hi3559A Clock Driver"
+   depends on ARCH_HISI || COMPILE_TEST
+   default ARCH_HISI
+   help
+ Build the clock driver for hi3559a.
+
 config COMMON_CLK_HI3660
bool "Hi3660 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index b2441b99f3d5..bc101833b35e 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_COMMON_CLK_HI6220)   += clk-hi6220.o
 obj-$(CONFIG_RESET_HISI)   += reset.o
 obj-$(CONFIG_STUB_CLK_HI6220)  += clk-hi6220-stub.o
 obj-$(CONFIG_STUB_CLK_HI3660)  += clk-hi3660-stub.o
+obj-$(CONFIG_COMMON_CLK_HI3559A)   += clk-hi3559a.o
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
b/drivers/clk/hisilicon/clk-hi3559a.c
new file mode 100644
index ..d7693e488006
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Hisilicon Hi3559A clock driver
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "crg.h"
+#include "reset.h"
+
+#define CRG_BASE_ADDR  0x1802
+
+struct hi3559av100_pll_clock {
+   u32 id;
+   const char  *name;
+   const char  *parent_name;
+   u32 ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   u32 ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+struct hi3559av100_clk_pll {
+   struct clk_hw   hw;
+   u32 id;
+   void __iomem*ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   void __iomem*ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+/* soc clk config */
+static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = {
+   { HI3559AV100_FIXED_1188M, "1188m",   NULL, 0, 118800, },
+   { HI3559AV100_FIXED_1000M, "1000m",   NULL, 0, 10, },
+   { HI3559AV100_FIXED_842M, "842m",NULL, 0, 84200, },
+   { HI3559AV100_FIXED_792M, "792m",NULL, 0, 79200, },
+   { HI3559AV100_FIXED_750M, "750m",NULL, 0, 75000, },
+   { HI3559AV100_FIXED_710M, "710m",NULL, 0, 71000, },
+   { HI3559AV100_FIXED_680M, "680m",NULL, 0, 68000, },
+   { HI3559AV100_FIXED_667M, "667m",NULL, 0, 66700, },
+   { HI3559AV100_FIXED_631M, "631m",NULL, 0, 63100, },
+   { HI3559AV100_FIXED_600M, "600m",NULL, 0, 6, },
+   { HI3559AV100_FIXED_568M, "568m",NULL, 0, 56800, },
+   { HI3559AV100_FIXED_500M, "500m",NULL, 0, 5, },
+   { HI3559AV100_FIXED_475M, "475m",NULL, 0, 47500, },
+   { HI3559AV100_FIXED_428M, "428m",NULL, 0, 42800, },
+   { HI3559AV100_FIXED_400M, "400m",NULL, 0, 4, },
+   { HI3559AV100_FIXED_396M, "396m",NULL, 0, 39600, },
+   { HI3559AV100_FIXED_300M, "300m",NULL, 0, 3, },
+   { HI3559AV100_FIXED_250M, "250m",NULL, 0, 25000, },
+   { HI3559AV100_FIXED_200M, "200m",NULL, 0, 2, },
+   { HI3559AV100_FIXED_198M, "198m",NULL, 0, 19800, },
+   { HI3559AV100_FIXED_187p5M, "187p5m",  NULL, 0, 18750, },
+   { HI3559AV100_FIXED_150M, "150m",NULL, 0, 15000, },
+   { HI3559AV100_FIXED_148p5M, "148p5m",  NULL, 0, 148500, },
+   { HI3559AV100_FIXED_125M, "125m&quo

[PATCH v6 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-12-11 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1593 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..ddf9b5d85a27
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1442 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

[PATCH v6 1/4] dt-bindings: Document the hi3559a clock bindings

2020-12-11 Thread Dongjiu Geng
Add DT bindings documentation for hi3559a SoC clock.

Signed-off-by: Dongjiu Geng 
---
 .../clock/hisilicon,hi3559av100-clock.yaml|  59 +++
 include/dt-bindings/clock/hi3559av100-clock.h | 165 ++
 2 files changed, 224 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

diff --git 
a/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml 
b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
new file mode 100644
index ..3ceb29cec704
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/hisilicon,hi3559av100-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hisilicon SOC Clock for HI3559AV100
+
+maintainers:
+  - Dongjiu Geng 
+
+description: |
+  Hisilicon SOC clock control module which supports the clocks, resets and
+  power domains on HI3559AV100.
+
+  See also:
+dt-bindings/clock/hi3559av100-clock.h
+
+properties:
+  compatible:
+enum:
+  - hisilicon,hi3559av100-clock
+  - hisilicon,hi3559av100-shub-clock
+
+  reg:
+minItems: 1
+maxItems: 2
+
+  '#clock-cells':
+const: 1
+
+  '#reset-cells':
+const: 2
+description: |
+  First cell is reset request register offset.
+  Second cell is bit offset in reset request register.
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+clock-controller@1201 {
+compatible = "hisilicon,hi3559av100-clock";
+#clock-cells = <1>;
+#reset-cells = <2>;
+reg = <0x0 0x1201 0x0 0x1>;
+};
+};
+...
diff --git a/include/dt-bindings/clock/hi3559av100-clock.h 
b/include/dt-bindings/clock/hi3559av100-clock.h
new file mode 100644
index ..5fe7689010a0
--- /dev/null
+++ b/include/dt-bindings/clock/hi3559av100-clock.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+/*
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#ifndef __DTS_HI3559AV100_CLOCK_H
+#define __DTS_HI3559AV100_CLOCK_H
+
+/*  fixed   rate*/
+#define HI3559AV100_FIXED_1188M 1
+#define HI3559AV100_FIXED_1000M 2
+#define HI3559AV100_FIXED_842M  3
+#define HI3559AV100_FIXED_792M  4
+#define HI3559AV100_FIXED_750M  5
+#define HI3559AV100_FIXED_710M  6
+#define HI3559AV100_FIXED_680M  7
+#define HI3559AV100_FIXED_667M  8
+#define HI3559AV100_FIXED_631M  9
+#define HI3559AV100_FIXED_600M  10
+#define HI3559AV100_FIXED_568M  11
+#define HI3559AV100_FIXED_500M  12
+#define HI3559AV100_FIXED_475M  13
+#define HI3559AV100_FIXED_428M  14
+#define HI3559AV100_FIXED_400M  15
+#define HI3559AV100_FIXED_396M  16
+#define HI3559AV100_FIXED_300M  17
+#define HI3559AV100_FIXED_250M  18
+#define HI3559AV100_FIXED_198M  19
+#define HI3559AV100_FIXED_187p5M20
+#define HI3559AV100_FIXED_150M  21
+#define HI3559AV100_FIXED_148p5M22
+#define HI3559AV100_FIXED_125M  23
+#define HI3559AV100_FIXED_107M  24
+#define HI3559AV100_FIXED_100M  25
+#define HI3559AV100_FIXED_99M   26
+#define HI3559AV100_FIXED_74p25M27
+#define HI3559AV100_FIXED_72M   28
+#define HI3559AV100_FIXED_60M   29
+#define HI3559AV100_FIXED_54M   30
+#define HI3559AV100_FIXED_50M   31
+#define HI3559AV100_FIXED_49p5M 32
+#define HI3559AV100_FIXED_37p125M   33
+#define HI3559AV100_FIXED_36M   34
+#define HI3559AV100_FIXED_32p4M 35
+#define HI3559AV100_FIXED_27M   36
+#define HI3559AV100_FIXED_25M   37
+#define HI3559AV100_FIXED_24M   38
+#define HI3559AV100_FIXED_12M   39
+#define HI3559AV100_FIXED_3M40
+#define HI3559AV100_FIXED_1p6M  41
+#define HI3559AV100_FIXED_400K  42
+#define HI3559AV100_FIXED_100K  43
+#define HI3559AV100_FIXED_200M  44
+#define HI3559AV100_FIXED_75M   75
+
+#define HI3559AV100_I2C0_CLK50
+#define HI3559AV100_I2C1_CLK51
+#define HI3559AV100_I2C2_CLK52
+#define HI3559AV100_I2C3_CLK53
+#define HI3559AV100_I2C4_CLK54
+#define HI3559AV100_I2C5_CLK55
+#define HI3559AV100_I2C6_CLK56
+#define HI3559AV100_I2C7_CLK57
+#define HI3559AV100_I2C8_CLK58
+#define HI3559AV100_I2C9_CLK59
+#define HI3559AV100_I2C10_CLK   60
+#define HI3559AV100_I2C11_CLK   61
+
+#define HI3559AV100_SPI0_CLK62
+#define HI3559AV100_SPI1_CLK63
+#define HI3559AV100_SPI2_CLK64
+#define HI3559AV100_SPI3_CLK65
+#define HI3559AV100_SPI4_C

[PATCH v6 3/4] dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller

2020-12-11 Thread Dongjiu Geng
The Hiedma Controller v310 Provides eight DMA channels, each
channel can be configured for one-way transfer. The data can
be transferred in 8-bit, 16-bit, 32-bit, or 64-bit mode. This
documentation describes DT bindings of this controller.

Signed-off-by: Dongjiu Geng 
---
 .../bindings/dma/hisilicon,hiedmacv310.yaml   | 94 +++
 1 file changed, 94 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml

diff --git a/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml 
b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
new file mode 100644
index ..f57703fbbe7b
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
@@ -0,0 +1,94 @@
+# SPDX-License-Identifier:  GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/hisilicon,hiedmacv310.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon Hiedma Controller v310 Device Tree Bindings
+
+description: |
+  These bindings describe the DMA engine included in the HiSilicon Hiedma
+  Controller v310 Device.
+
+maintainers:
+  - Dongjiu Geng 
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+const: 2
+
+  compatible:
+const: hisilicon,hiedmacv310
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  hisi,misc-control:
+$ref: /schemas/types.yaml#definitions/phandle-array
+description: phandle pointing to the misc controller provider node and 
base register.
+
+  clocks:
+items:
+  - description: apb clock
+  - description: axi clock
+
+  clock-names:
+items:
+  - const: apb_pclk
+  - const: axi_aclk
+
+  resets:
+description: phandle pointing to the dma reset controller provider node.
+
+  reset-names:
+items:
+  - const: dma-reset
+
+  dma-requests:
+maximum: 32
+
+  dma-channels:
+maximum: 8
+
+
+required:
+  - "#dma-cells"
+  - compatible
+  - hisi,misc-control
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - dma-requests
+  - dma-channels
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+dma: dma-controller@1004 {
+  compatible = "hisilicon,hiedmacv310";
+  reg = <0x1004 0x1000>;
+  hisi,misc-control = <&misc_ctrl 0x144>;
+  interrupts = <0 82 4>;
+  clocks = <&clock HI3559AV100_EDMAC1_CLK>, <&clock 
HI3559AV100_EDMAC1_AXICLK>;
+  clock-names = "apb_pclk", "axi_aclk";
+  resets = <&clock 0x16c 7>;
+  reset-names = "dma-reset";
+  dma-requests = <32>;
+  dma-channels = <8>;
+  #dma-cells = <2>;
+};
+
+...
-- 
2.17.1



[PATCH v6 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-12-11 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1593 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..ddf9b5d85a27
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1442 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

[PATCH v6 2/4] clk: hisilicon: Add clock driver for hi3559A SoC

2020-12-11 Thread Dongjiu Geng
Add clock drivers for hi3559A SoC, this driver
controls the SoC registers to supply different
clocks to different IPs in the SoC.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/Kconfig   |   7 +
 drivers/clk/hisilicon/Makefile  |   1 +
 drivers/clk/hisilicon/clk-hi3559a.c | 865 
 3 files changed, 873 insertions(+)
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 6a9e93a0bb95..5ecc37aaa118 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
help
  Build the clock driver for hi3519.
 
+config COMMON_CLK_HI3559A
+   bool "Hi3559A Clock Driver"
+   depends on ARCH_HISI || COMPILE_TEST
+   default ARCH_HISI
+   help
+ Build the clock driver for hi3559a.
+
 config COMMON_CLK_HI3660
bool "Hi3660 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index b2441b99f3d5..bc101833b35e 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_COMMON_CLK_HI6220)   += clk-hi6220.o
 obj-$(CONFIG_RESET_HISI)   += reset.o
 obj-$(CONFIG_STUB_CLK_HI6220)  += clk-hi6220-stub.o
 obj-$(CONFIG_STUB_CLK_HI3660)  += clk-hi3660-stub.o
+obj-$(CONFIG_COMMON_CLK_HI3559A)   += clk-hi3559a.o
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
b/drivers/clk/hisilicon/clk-hi3559a.c
new file mode 100644
index ..d7693e488006
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Hisilicon Hi3559A clock driver
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "crg.h"
+#include "reset.h"
+
+#define CRG_BASE_ADDR  0x1802
+
+struct hi3559av100_pll_clock {
+   u32 id;
+   const char  *name;
+   const char  *parent_name;
+   u32 ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   u32 ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+struct hi3559av100_clk_pll {
+   struct clk_hw   hw;
+   u32 id;
+   void __iomem*ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   void __iomem*ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+/* soc clk config */
+static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = {
+   { HI3559AV100_FIXED_1188M, "1188m",   NULL, 0, 118800, },
+   { HI3559AV100_FIXED_1000M, "1000m",   NULL, 0, 10, },
+   { HI3559AV100_FIXED_842M, "842m",NULL, 0, 84200, },
+   { HI3559AV100_FIXED_792M, "792m",NULL, 0, 79200, },
+   { HI3559AV100_FIXED_750M, "750m",NULL, 0, 75000, },
+   { HI3559AV100_FIXED_710M, "710m",NULL, 0, 71000, },
+   { HI3559AV100_FIXED_680M, "680m",NULL, 0, 68000, },
+   { HI3559AV100_FIXED_667M, "667m",NULL, 0, 66700, },
+   { HI3559AV100_FIXED_631M, "631m",NULL, 0, 63100, },
+   { HI3559AV100_FIXED_600M, "600m",NULL, 0, 6, },
+   { HI3559AV100_FIXED_568M, "568m",NULL, 0, 56800, },
+   { HI3559AV100_FIXED_500M, "500m",NULL, 0, 5, },
+   { HI3559AV100_FIXED_475M, "475m",NULL, 0, 47500, },
+   { HI3559AV100_FIXED_428M, "428m",NULL, 0, 42800, },
+   { HI3559AV100_FIXED_400M, "400m",NULL, 0, 4, },
+   { HI3559AV100_FIXED_396M, "396m",NULL, 0, 39600, },
+   { HI3559AV100_FIXED_300M, "300m",NULL, 0, 3, },
+   { HI3559AV100_FIXED_250M, "250m",NULL, 0, 25000, },
+   { HI3559AV100_FIXED_200M, "200m",NULL, 0, 2, },
+   { HI3559AV100_FIXED_198M, "198m",NULL, 0, 19800, },
+   { HI3559AV100_FIXED_187p5M, "187p5m",  NULL, 0, 18750, },
+   { HI3559AV100_FIXED_150M, "150m",NULL, 0, 15000, },
+   { HI3559AV100_FIXED_148p5M, "148p5m",  NULL, 0, 148500, },
+   { HI3559AV100_FIXED_125M, "125m&quo

[PATCH v6 0/4] Enable Hi3559A SOC clock and HiSilicon Hiedma Controller

2020-12-11 Thread Dongjiu Geng
From: g00384164 

v5->v6:
1. Drop #size-cells and #address-cell in the hisilicon,hi3559av100-clock.yaml
2. Add discription for #reset-cells in the hisilicon,hi3559av100-clock.yaml
3. Remove #clock-cells in hisilicon,hiedmacv310.yaml 
4. Merge property misc_ctrl_base and misc_regmap together for hiedmacv310 driver

v4->v5:
1. change the patch author mail name

v3->v4:
1. fix the 'make dt_binding_check' issues.
2. Combine the 'Enable HiSilicon Hiedma Controller' series patches to this 
series.
3. fix the 'make dt_binding_check' issues in 'Enable HiSilicon Hiedma 
Controller' patchset


v2->v3:
1. change dt-bindings documents from txt to yaml format.
2. Add SHUB clock to access the devices of m7

Dongjiu Geng (4):
  dt-bindings: Document the hi3559a clock bindings
  clk: hisilicon: Add clock driver for hi3559A SoC
  dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller
  dmaengine: dma: Add Hiedma Controller v310 Device Driver

 .../clock/hisilicon,hi3559av100-clock.yaml|   59 +
 .../bindings/dma/hisilicon,hiedmacv310.yaml   |   94 ++
 drivers/clk/hisilicon/Kconfig |7 +
 drivers/clk/hisilicon/Makefile|1 +
 drivers/clk/hisilicon/clk-hi3559a.c   |  865 ++
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1442 +
 drivers/dma/hiedmacv310.h |  136 ++
 include/dt-bindings/clock/hi3559av100-clock.h |  165 ++
 10 files changed, 2784 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

-- 
2.17.1



Re: [PATCH v5 1/4] dt-bindings: Document the hi3559a clock bindings

2020-12-07 Thread Dongjiu Geng
On 2020/12/1 6:07, Rob Herring wrote:
> On Thu, Nov 19, 2020 at 08:01:26PM +0000, Dongjiu Geng wrote:
>> Add DT bindings documentation for hi3559a SoC clock.
>>
>> Signed-off-by: Dongjiu Geng 
>> ---
>>  .../clock/hisilicon,hi3559av100-clock.yaml|  66 +++
>>  include/dt-bindings/clock/hi3559av100-clock.h | 165 ++
>>  2 files changed, 231 insertions(+)
>>  create mode 100644 
>> Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
>>  create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h
>>
>> diff --git 
>> a/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml 
>> b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
>> new file mode 100644
>> index ..0f531e8186d2
>> --- /dev/null
>> +++ 
>> b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
>> @@ -0,0 +1,66 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/hisilicon,hi3559av100-clock.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Hisilicon SOC Clock for HI3559AV100
>> +
>> +maintainers:
>> +  - Dongjiu Geng 
>> +
>> +description: |
>> +  Hisilicon SOC clock control module which supports the clocks, resets and
>> +  power domains on HI3559AV100.
>> +
>> +  See also:
>> +dt-bindings/clock/hi3559av100-clock.h
>> +
>> +properties:
>> +  compatible:
>> +enum:
>> +  - hisilicon,hi3559av100-clock
>> +  - hisilicon,hi3559av100-shub-clock
>> +
>> +  reg:
>> +minItems: 1
>> +maxItems: 2
>> +
>> +  '#clock-cells':
>> +const: 1
>> +
>> +  '#reset-cells':
>> +const: 2
> 
> What's in each cell?

I will add description for each cell.

> 
>> +
>> +  '#address-cells':
>> +const: 2
>> +
>> +  '#size-cells':
>> +const: 2
> 
> #address-cells and #size-cells are for child nodes, but you have none so 
> drop them.

Ok, thanks for the reminder.

> 
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - '#clock-cells'
>> +  - '#reset-cells'
>> +  - '#address-cells'
>> +  - '#size-cells'
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +soc {
>> +#address-cells = <2>;
>> +#size-cells = <2>;
>> +
>> +clock: clock0@1201 {
> 
> clock-controller@...

  ok.

> 
>> +compatible = "hisilicon,hi3559av100-clock";
>> +#address-cells = <2>;
>> +#size-cells = <2>;
>> +#clock-cells = <1>;
>> +#reset-cells = <2>;
>> +reg = <0x0 0x1201 0x0 0x1>;
>> +};
>> +};
>> +...
>> diff --git a/include/dt-bindings/clock/hi3559av100-clock.h 
>> b/include/dt-bindings/clock/hi3559av100-clock.h
>> new file mode 100644
>> index ..88baa86cff85
>> --- /dev/null
>> +++ b/include/dt-bindings/clock/hi3559av100-clock.h
>> @@ -0,0 +1,165 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
> 
> Don't care about non-GPL OS/users?
will fix it.

I will modify it to "GPL-2.0-only OR BSD-2-Clause"

> 
>> +/*
>> + * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
>> + *
>> + * Author: Dongjiu Geng 
>> + */
>> +
>> +#ifndef __DTS_HI3559AV100_CLOCK_H
>> +#define __DTS_HI3559AV100_CLOCK_H
>> +
>> +/*  fixed   rate*/
>> +#define HI3559AV100_FIXED_1188M 1
>> +#define HI3559AV100_FIXED_1000M 2
>> +#define HI3559AV100_FIXED_842M  3
>> +#define HI3559AV100_FIXED_792M  4
>> +#define HI3559AV100_FIXED_750M  5
>> +#define HI3559AV100_FIXED_710M  6
>> +#define HI3559AV100_FIXED_680M  7
>> +#define HI3559AV100_FIXED_667M  8
>> +#define HI3559AV100_FIXED_631M  9
>> +#define HI3559AV100_FIXED_600M  10
>> +#define HI3559AV100_FIXED_568M  11
>> +#define HI3559AV100_FIXED_500M  12
>> +#define HI3559AV100_FIXED_475M  13
>> +#define HI3559AV100_FIXED_428M  14
>> +#define HI3559AV100_FIXED_400M  15
>> +#define HI3559AV100_FIXED_396M  16
>> +#define HI3559AV100_FIXED_300M  17
>> +#define HI3559AV100_FIXED_250M  18
>> 

Re: [PATCH v5 0/4] Enable Hi3559A SOC clock and HiSilicon Hiedma Controller

2020-11-28 Thread Dongjiu Geng
ping, sorry for the noise.


On 2020/11/20 4:01, Dongjiu Geng wrote:
> v4->v5:
> 1. change the patch author mail name
> 
> v3->v4:
> 1. fix the 'make dt_binding_check' issues.
> 2. Combine the 'Enable HiSilicon Hiedma Controller' series patches to this 
> series.
> 3. fix the 'make dt_binding_check' issues in 'Enable HiSilicon Hiedma 
> Controller' patchset
> 
> 
> v2->v3:
> 1. change dt-bindings documents from txt to yaml format.
> 2. Add SHUB clock to access the devices of m7
> 
> Dongjiu Geng (4):
>   dt-bindings: Document the hi3559a clock bindings
>   clk: hisilicon: Add clock driver for hi3559A SoC
>   dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller
>   dmaengine: dma: Add Hiedma Controller v310 Device Driver
> 
>  .../clock/hisilicon,hi3559av100-clock.yaml|   66 +
>  .../bindings/dma/hisilicon,hiedmacv310.yaml   |  103 ++
>  drivers/clk/hisilicon/Kconfig |7 +
>  drivers/clk/hisilicon/Makefile|1 +
>  drivers/clk/hisilicon/clk-hi3559a.c   |  865 ++
>  drivers/dma/Kconfig   |   14 +
>  drivers/dma/Makefile  |1 +
>  drivers/dma/hiedmacv310.c | 1441 +
>  drivers/dma/hiedmacv310.h |  136 ++
>  include/dt-bindings/clock/hi3559av100-clock.h |  165 ++
>  10 files changed, 2799 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
>  create mode 100644 
> Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
>  create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
>  create mode 100644 drivers/dma/hiedmacv310.c
>  create mode 100644 drivers/dma/hiedmacv310.h
>  create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h
> 


[PATCH v4] clk: hisilicon: refine hi3620_mmc_clk_init() and fix memory leak issues

2020-11-19 Thread Dongjiu Geng
Refine hi3620_mmc_clk_init() to use of_clk_add_hw_provider()
instead of of_clk_add_provider(), the called function hisi_register_clk_mmc()
returns 'clk_hw *' to adapt to this change.  Also free memory mapping and
free hw_data if clock initialization is failed.

Fix the memory leak issues in hisi_clk_init().

Fixes: 75af25f581b1 ("clk: hisi: remove static variable")
Fixes: 62ac983b6141 ("clk: hisilicon: add hi3620_mmc_clks")
Cc: Markus Elfring 
Signed-off-by: Dongjiu Geng 
---
v3->v4:
1. omit a blank in hisi_register_clk_mmc()
2. Further need to do:
consider adjust also such a function call for the of_clk_add_provider()

v2->v3:
1. Refind hi3620_mmc_clk_init() and hisi_register_clk_mmc() in order to use
   of_clk_add_hw_provider().
2. Fix the issue that incorrectly free data even clock is initialized
   successfully.
---
 drivers/clk/hisilicon/clk-hi3620.c | 43 ++
 drivers/clk/hisilicon/clk.c| 11 
 2 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/drivers/clk/hisilicon/clk-hi3620.c 
b/drivers/clk/hisilicon/clk-hi3620.c
index a3d04c7c3da8..af4587245c72 100644
--- a/drivers/clk/hisilicon/clk-hi3620.c
+++ b/drivers/clk/hisilicon/clk-hi3620.c
@@ -408,12 +408,13 @@ static const struct clk_ops clk_mmc_ops = {
.recalc_rate = mmc_clk_recalc_rate,
 };
 
-static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
+static struct clk_hw *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
void __iomem *base, struct device_node *np)
 {
struct clk_mmc *mclk;
-   struct clk *clk;
+   struct clk_hw *hw;
struct clk_init_data init;
+   int err;
 
mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
if (!mclk)
@@ -439,17 +440,21 @@ static struct clk *hisi_register_clk_mmc(struct 
hisi_mmc_clock *mmc_clk,
mclk->sam_off = mmc_clk->sam_off;
mclk->sam_bits = mmc_clk->sam_bits;
 
-   clk = clk_register(NULL, &mclk->hw);
-   if (WARN_ON(IS_ERR(clk)))
+   hw = &mclk->hw;
+   err = clk_hw_register(NULL, hw);
+   if (err) {
kfree(mclk);
-   return clk;
+   return ERR_PTR(err);
+   }
+
+   return hw;
 }
 
 static void __init hi3620_mmc_clk_init(struct device_node *node)
 {
void __iomem *base;
-   int i, num = ARRAY_SIZE(hi3620_mmc_clks);
-   struct clk_onecell_data *clk_data;
+   int i, ret, num = ARRAY_SIZE(hi3620_mmc_clks);
+   struct clk_hw_onecell_data *hw_data;
 
if (!node) {
pr_err("failed to find pctrl node in DTS\n");
@@ -462,22 +467,26 @@ static void __init hi3620_mmc_clk_init(struct device_node 
*node)
return;
}
 
-   clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
-   if (WARN_ON(!clk_data))
-   return;
-
-   clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL);
-   if (!clk_data->clks)
-   return;
+   hw_data = kzalloc(struct_size(hw_data, hws, num), GFP_KERNEL);
+   if (WARN_ON(!hw_data))
+   goto unmap_io;
 
for (i = 0; i < num; i++) {
struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
-   clk_data->clks[mmc_clk->id] =
+   hw_data->hws[mmc_clk->id] =
hisi_register_clk_mmc(mmc_clk, base, node);
}
 
-   clk_data->clk_num = num;
-   of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+   hw_data->num = num;
+   ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, hw_data);
+   if (ret < 0)
+   goto free_hw_data;
+   return;
+
+free_hw_data:
+   kfree(hw_data);
+unmap_io:
+   iounmap(base);
 }
 
 CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", 
hi3620_mmc_clk_init);
diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index 54d9fdc93599..da655683710f 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -65,25 +65,26 @@ struct hisi_clock_data *hisi_clk_init(struct device_node 
*np,
base = of_iomap(np, 0);
if (!base) {
pr_err("%s: failed to map clock registers\n", __func__);
-   goto err;
+   return NULL;
}
 
clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
if (!clk_data)
-   goto err;
+   goto unmap_io;
 
clk_data->base = base;
clk_table = kcalloc(nr_clks, sizeof(*clk_table), GFP_KERNEL);
if (!clk_table)
-   goto err_data;
+   goto free_clk_data;
 
clk_data->clk_data.clks = clk_table;
clk_data->clk_data.clk_num = nr_clks;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
return clk_data;
-err_data:
+free_clk_data:
kfree(clk_data);
-err:
+unmap_io:
+   iounmap(base);
return NULL;
 }
 EXPORT_SYMBOL_GPL(hisi_clk_init);
-- 
2.17.1



Re: [v3] clk: hisilicon: refine hi3620_mmc_clk_init() and fix memory leak issues

2020-11-19 Thread Dongjiu Geng
On 2020/11/19 22:40, Markus Elfring wrote:
>> How about we adjust such a function call in another series patches?
> 
> You can try to offer desirable changes also in a corresponding patch series 
> as usual.

sure, ok

> 
> Regards,
> Markus
> .
> 


Re: [PATCH v3] clk: hisilicon: refine hi3620_mmc_clk_init() and fix memory leak issues

2020-11-19 Thread Dongjiu Geng
On 2020/11/19 17:07, Markus Elfring wrote:
>> Refine hi3620_mmc_clk_init() to use of_clk_add_hw_provider()
>> instead of of_clk_add_provider(), …
> 
> …
>> +++ b/drivers/clk/hisilicon/clk-hi3620.c
> …
>> @@ -439,17 +440,22 @@  static struct clk *hisi_register_clk_mmc(struct 
>> hisi_mmc_clock *mmc_clk,
> …
>> +err = clk_hw_register(NULL, hw);
>> +
>> +if (err) {
> 
> I suggest to omit a blank line here.
> 
> 
> …
>> +++ b/drivers/clk/hisilicon/clk.c
>> @@ -65,25 +65,26 @@  struct hisi_clock_data *hisi_clk_init(struct 
>> device_node *np,
> …
>>  of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
>>  return clk_data;
>> -err_data:
>> +free_clk_data:
> 
> How do you think about to adjust also such a function call for this function 
> implementation?
> 
> Will further collateral evolution become interesting?
> https://elixir.bootlin.com/linux/v5.10-rc4/C/ident/of_clk_add_provider
Thanks for the review.

How about we adjust such a function call in another series patches?  I suggest 
do it in another series.
For this patch, how about we firstly merge it after I fix the above 
comments(omit a blank line)?

> 
> Regards,
> Markus
> .
> 


Re: [PATCH 1/2] dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller

2020-11-19 Thread Dongjiu Geng
On 2020/11/16 23:27, Rob Herring wrote:
> On Sat, 14 Nov 2020 00:34:39 +0000, Dongjiu Geng wrote:
>> The Hiedma Controller v310 Provides eight DMA channels, each
>> channel can be configured for one-way transfer. The data can
>> be transferred in 8-bit, 16-bit, 32-bit, or 64-bit mode. This
>> documentation describes DT bindings of this controller.
>>
>> Signed-off-by: Dongjiu Geng 
>> ---
>>  .../bindings/dma/hisilicon,hiedmacv310.yaml   | 80 +++
>>  1 file changed, 80 insertions(+)
>>  create mode 100644 
>> Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
>>
> 
> 
> My bot found errors running 'make dt_binding_check' on your patch:
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.example.dts:20:18:
>  fatal error: dt-bindings/clock/hi3559av100-clock.h: No such file or directory
>20 | #include 
>   |  ^~~
> compilation terminated.
> make[1]: *** [scripts/Makefile.lib:342: 
> Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.example.dt.yaml] 
> Error 1
> make[1]: *** Waiting for unfinished jobs
> make: *** [Makefile:1364: dt_binding_check] Error 2

Rob,
  Because it needs to include“#include 
”, so I combine the new modified series 
patches to this series "[PATCH v4 0/4] Enable Hi3559A SOC clock and HiSilicon 
Hiedma Controller"

See https://lore.kernel.org/patchwork/cover/1341544/

> 
> 
> See https://patchwork.ozlabs.org/patch/1399915
> 
> The base for the patch is generally the last rc1. Any dependencies
> should be noted.
> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.
> 
> .
> 


[PATCH v5 3/4] dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller

2020-11-19 Thread Dongjiu Geng
The Hiedma Controller v310 Provides eight DMA channels, each
channel can be configured for one-way transfer. The data can
be transferred in 8-bit, 16-bit, 32-bit, or 64-bit mode. This
documentation describes DT bindings of this controller.

Signed-off-by: Dongjiu Geng 
---
 .../bindings/dma/hisilicon,hiedmacv310.yaml   | 103 ++
 1 file changed, 103 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml

diff --git a/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml 
b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
new file mode 100644
index ..fe5c5af4d3e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier:  GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/hisilicon,hiedmacv310.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon Hiedma Controller v310 Device Tree Bindings
+
+description: |
+  These bindings describe the DMA engine included in the HiSilicon Hiedma
+  Controller v310 Device.
+
+maintainers:
+  - Dongjiu Geng 
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+const: 2
+
+  "#clock-cells":
+const: 2
+
+  compatible:
+const: hisilicon,hiedmacv310
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  misc_regmap:
+description: phandle pointing to the misc controller provider node.
+
+  misc_ctrl_base:
+maxItems: 1
+
+  clocks:
+items:
+  - description: apb clock
+  - description: axi clock
+
+  clock-names:
+items:
+  - const: apb_pclk
+  - const: axi_aclk
+
+  resets:
+description: phandle pointing to the dma reset controller provider node.
+
+  reset-names:
+items:
+  - const: dma-reset
+
+  dma-requests:
+maximum: 32
+
+  dma-channels:
+maximum: 8
+
+
+required:
+  - "#dma-cells"
+  - "#clock-cells"
+  - compatible
+  - misc_regmap
+  - misc_ctrl_base
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - dma-requests
+  - dma-channels
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+dma: dma-controller@1004 {
+  compatible = "hisilicon,hiedmacv310";
+  reg = <0x1004 0x1000>;
+  misc_regmap = <&misc_ctrl>;
+  misc_ctrl_base = <0x144>;
+  interrupts = <0 82 4>;
+  clocks = <&clock HI3559AV100_EDMAC1_CLK>, <&clock 
HI3559AV100_EDMAC1_AXICLK>;
+  clock-names = "apb_pclk", "axi_aclk";
+  #clock-cells = <2>;
+  resets = <&clock 0x16c 7>;
+  reset-names = "dma-reset";
+  dma-requests = <32>;
+  dma-channels = <8>;
+  #dma-cells = <2>;
+};
+
+...
-- 
2.17.1



[PATCH v5 2/4] clk: hisilicon: Add clock driver for hi3559A SoC

2020-11-19 Thread Dongjiu Geng
Add clock drivers for hi3559A SoC, this driver
controls the SoC registers to supply different
clocks to different IPs in the SoC.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/Kconfig   |   7 +
 drivers/clk/hisilicon/Makefile  |   1 +
 drivers/clk/hisilicon/clk-hi3559a.c | 865 
 3 files changed, 873 insertions(+)
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 6a9e93a0bb95..5ecc37aaa118 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
help
  Build the clock driver for hi3519.
 
+config COMMON_CLK_HI3559A
+   bool "Hi3559A Clock Driver"
+   depends on ARCH_HISI || COMPILE_TEST
+   default ARCH_HISI
+   help
+ Build the clock driver for hi3559a.
+
 config COMMON_CLK_HI3660
bool "Hi3660 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index b2441b99f3d5..bc101833b35e 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_COMMON_CLK_HI6220)   += clk-hi6220.o
 obj-$(CONFIG_RESET_HISI)   += reset.o
 obj-$(CONFIG_STUB_CLK_HI6220)  += clk-hi6220-stub.o
 obj-$(CONFIG_STUB_CLK_HI3660)  += clk-hi3660-stub.o
+obj-$(CONFIG_COMMON_CLK_HI3559A)   += clk-hi3559a.o
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
b/drivers/clk/hisilicon/clk-hi3559a.c
new file mode 100644
index ..d7693e488006
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Hisilicon Hi3559A clock driver
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "crg.h"
+#include "reset.h"
+
+#define CRG_BASE_ADDR  0x1802
+
+struct hi3559av100_pll_clock {
+   u32 id;
+   const char  *name;
+   const char  *parent_name;
+   u32 ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   u32 ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+struct hi3559av100_clk_pll {
+   struct clk_hw   hw;
+   u32 id;
+   void __iomem*ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   void __iomem*ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+/* soc clk config */
+static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = {
+   { HI3559AV100_FIXED_1188M, "1188m",   NULL, 0, 118800, },
+   { HI3559AV100_FIXED_1000M, "1000m",   NULL, 0, 10, },
+   { HI3559AV100_FIXED_842M, "842m",NULL, 0, 84200, },
+   { HI3559AV100_FIXED_792M, "792m",NULL, 0, 79200, },
+   { HI3559AV100_FIXED_750M, "750m",NULL, 0, 75000, },
+   { HI3559AV100_FIXED_710M, "710m",NULL, 0, 71000, },
+   { HI3559AV100_FIXED_680M, "680m",NULL, 0, 68000, },
+   { HI3559AV100_FIXED_667M, "667m",NULL, 0, 66700, },
+   { HI3559AV100_FIXED_631M, "631m",NULL, 0, 63100, },
+   { HI3559AV100_FIXED_600M, "600m",NULL, 0, 6, },
+   { HI3559AV100_FIXED_568M, "568m",NULL, 0, 56800, },
+   { HI3559AV100_FIXED_500M, "500m",NULL, 0, 5, },
+   { HI3559AV100_FIXED_475M, "475m",NULL, 0, 47500, },
+   { HI3559AV100_FIXED_428M, "428m",NULL, 0, 42800, },
+   { HI3559AV100_FIXED_400M, "400m",NULL, 0, 4, },
+   { HI3559AV100_FIXED_396M, "396m",NULL, 0, 39600, },
+   { HI3559AV100_FIXED_300M, "300m",NULL, 0, 3, },
+   { HI3559AV100_FIXED_250M, "250m",NULL, 0, 25000, },
+   { HI3559AV100_FIXED_200M, "200m",NULL, 0, 2, },
+   { HI3559AV100_FIXED_198M, "198m",NULL, 0, 19800, },
+   { HI3559AV100_FIXED_187p5M, "187p5m",  NULL, 0, 18750, },
+   { HI3559AV100_FIXED_150M, "150m",NULL, 0, 15000, },
+   { HI3559AV100_FIXED_148p5M, "148p5m",  NULL, 0, 148500, },
+   { HI3559AV100_FIXED_125M, "125m&quo

[PATCH v5 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-11-19 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1441 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1592 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..23814f3f2305
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1441 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

[PATCH v5 1/4] dt-bindings: Document the hi3559a clock bindings

2020-11-19 Thread Dongjiu Geng
Add DT bindings documentation for hi3559a SoC clock.

Signed-off-by: Dongjiu Geng 
---
 .../clock/hisilicon,hi3559av100-clock.yaml|  66 +++
 include/dt-bindings/clock/hi3559av100-clock.h | 165 ++
 2 files changed, 231 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

diff --git 
a/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml 
b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
new file mode 100644
index ..0f531e8186d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/hisilicon,hi3559av100-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hisilicon SOC Clock for HI3559AV100
+
+maintainers:
+  - Dongjiu Geng 
+
+description: |
+  Hisilicon SOC clock control module which supports the clocks, resets and
+  power domains on HI3559AV100.
+
+  See also:
+dt-bindings/clock/hi3559av100-clock.h
+
+properties:
+  compatible:
+enum:
+  - hisilicon,hi3559av100-clock
+  - hisilicon,hi3559av100-shub-clock
+
+  reg:
+minItems: 1
+maxItems: 2
+
+  '#clock-cells':
+const: 1
+
+  '#reset-cells':
+const: 2
+
+  '#address-cells':
+const: 2
+
+  '#size-cells':
+const: 2
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#address-cells'
+  - '#size-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+clock: clock0@1201 {
+compatible = "hisilicon,hi3559av100-clock";
+#address-cells = <2>;
+#size-cells = <2>;
+#clock-cells = <1>;
+#reset-cells = <2>;
+reg = <0x0 0x1201 0x0 0x1>;
+};
+};
+...
diff --git a/include/dt-bindings/clock/hi3559av100-clock.h 
b/include/dt-bindings/clock/hi3559av100-clock.h
new file mode 100644
index ..88baa86cff85
--- /dev/null
+++ b/include/dt-bindings/clock/hi3559av100-clock.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#ifndef __DTS_HI3559AV100_CLOCK_H
+#define __DTS_HI3559AV100_CLOCK_H
+
+/*  fixed   rate*/
+#define HI3559AV100_FIXED_1188M 1
+#define HI3559AV100_FIXED_1000M 2
+#define HI3559AV100_FIXED_842M  3
+#define HI3559AV100_FIXED_792M  4
+#define HI3559AV100_FIXED_750M  5
+#define HI3559AV100_FIXED_710M  6
+#define HI3559AV100_FIXED_680M  7
+#define HI3559AV100_FIXED_667M  8
+#define HI3559AV100_FIXED_631M  9
+#define HI3559AV100_FIXED_600M  10
+#define HI3559AV100_FIXED_568M  11
+#define HI3559AV100_FIXED_500M  12
+#define HI3559AV100_FIXED_475M  13
+#define HI3559AV100_FIXED_428M  14
+#define HI3559AV100_FIXED_400M  15
+#define HI3559AV100_FIXED_396M  16
+#define HI3559AV100_FIXED_300M  17
+#define HI3559AV100_FIXED_250M  18
+#define HI3559AV100_FIXED_198M  19
+#define HI3559AV100_FIXED_187p5M20
+#define HI3559AV100_FIXED_150M  21
+#define HI3559AV100_FIXED_148p5M22
+#define HI3559AV100_FIXED_125M  23
+#define HI3559AV100_FIXED_107M  24
+#define HI3559AV100_FIXED_100M  25
+#define HI3559AV100_FIXED_99M   26
+#define HI3559AV100_FIXED_74p25M27
+#define HI3559AV100_FIXED_72M   28
+#define HI3559AV100_FIXED_60M   29
+#define HI3559AV100_FIXED_54M   30
+#define HI3559AV100_FIXED_50M   31
+#define HI3559AV100_FIXED_49p5M 32
+#define HI3559AV100_FIXED_37p125M   33
+#define HI3559AV100_FIXED_36M   34
+#define HI3559AV100_FIXED_32p4M 35
+#define HI3559AV100_FIXED_27M   36
+#define HI3559AV100_FIXED_25M   37
+#define HI3559AV100_FIXED_24M   38
+#define HI3559AV100_FIXED_12M   39
+#define HI3559AV100_FIXED_3M40
+#define HI3559AV100_FIXED_1p6M  41
+#define HI3559AV100_FIXED_400K  42
+#define HI3559AV100_FIXED_100K  43
+#define HI3559AV100_FIXED_200M  44
+#define HI3559AV100_FIXED_75M   75
+
+#define HI3559AV100_I2C0_CLK50
+#define HI3559AV100_I2C1_CLK51
+#define HI3559AV100_I2C2_CLK52
+#define HI3559AV100_I2C3_CLK53
+#define HI3559AV100_I2C4_CLK54
+#define HI3559AV100_I2C5_CLK55
+#define HI3559AV100_I2C6_CLK56
+#define HI3559AV100_I2C7_CLK57
+#define HI3559AV100_I2C8_CLK58
+#define HI3559AV100_I2C9_CLK59
+#define HI3559AV100_I2C10_CLK   60
+#define HI3559AV100_I2C11_CLK   61
+
+#define HI3559AV100_SPI0_CLK62
+#define HI3559AV100_SPI1_CLK63
+#define HI3559AV100

[PATCH v5 0/4] Enable Hi3559A SOC clock and HiSilicon Hiedma Controller

2020-11-19 Thread Dongjiu Geng
v4->v5:
1. change the patch author mail name

v3->v4:
1. fix the 'make dt_binding_check' issues.
2. Combine the 'Enable HiSilicon Hiedma Controller' series patches to this 
series.
3. fix the 'make dt_binding_check' issues in 'Enable HiSilicon Hiedma 
Controller' patchset


v2->v3:
1. change dt-bindings documents from txt to yaml format.
2. Add SHUB clock to access the devices of m7

Dongjiu Geng (4):
  dt-bindings: Document the hi3559a clock bindings
  clk: hisilicon: Add clock driver for hi3559A SoC
  dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller
  dmaengine: dma: Add Hiedma Controller v310 Device Driver

 .../clock/hisilicon,hi3559av100-clock.yaml|   66 +
 .../bindings/dma/hisilicon,hiedmacv310.yaml   |  103 ++
 drivers/clk/hisilicon/Kconfig |7 +
 drivers/clk/hisilicon/Makefile|1 +
 drivers/clk/hisilicon/clk-hi3559a.c   |  865 ++
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1441 +
 drivers/dma/hiedmacv310.h |  136 ++
 include/dt-bindings/clock/hi3559av100-clock.h |  165 ++
 10 files changed, 2799 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

-- 
2.17.1



[PATCH v4 1/4] dt-bindings: Document the hi3559a clock bindings

2020-11-19 Thread Dongjiu Geng
Add DT bindings documentation for hi3559a SoC clock.

Signed-off-by: Dongjiu Geng 
---
 .../clock/hisilicon,hi3559av100-clock.yaml|  66 +++
 include/dt-bindings/clock/hi3559av100-clock.h | 165 ++
 2 files changed, 231 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

diff --git 
a/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml 
b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
new file mode 100644
index ..0f531e8186d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/hisilicon,hi3559av100-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hisilicon SOC Clock for HI3559AV100
+
+maintainers:
+  - Dongjiu Geng 
+
+description: |
+  Hisilicon SOC clock control module which supports the clocks, resets and
+  power domains on HI3559AV100.
+
+  See also:
+dt-bindings/clock/hi3559av100-clock.h
+
+properties:
+  compatible:
+enum:
+  - hisilicon,hi3559av100-clock
+  - hisilicon,hi3559av100-shub-clock
+
+  reg:
+minItems: 1
+maxItems: 2
+
+  '#clock-cells':
+const: 1
+
+  '#reset-cells':
+const: 2
+
+  '#address-cells':
+const: 2
+
+  '#size-cells':
+const: 2
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#address-cells'
+  - '#size-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+soc {
+#address-cells = <2>;
+#size-cells = <2>;
+
+clock: clock0@1201 {
+compatible = "hisilicon,hi3559av100-clock";
+#address-cells = <2>;
+#size-cells = <2>;
+#clock-cells = <1>;
+#reset-cells = <2>;
+reg = <0x0 0x1201 0x0 0x1>;
+};
+};
+...
diff --git a/include/dt-bindings/clock/hi3559av100-clock.h 
b/include/dt-bindings/clock/hi3559av100-clock.h
new file mode 100644
index ..88baa86cff85
--- /dev/null
+++ b/include/dt-bindings/clock/hi3559av100-clock.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#ifndef __DTS_HI3559AV100_CLOCK_H
+#define __DTS_HI3559AV100_CLOCK_H
+
+/*  fixed   rate*/
+#define HI3559AV100_FIXED_1188M 1
+#define HI3559AV100_FIXED_1000M 2
+#define HI3559AV100_FIXED_842M  3
+#define HI3559AV100_FIXED_792M  4
+#define HI3559AV100_FIXED_750M  5
+#define HI3559AV100_FIXED_710M  6
+#define HI3559AV100_FIXED_680M  7
+#define HI3559AV100_FIXED_667M  8
+#define HI3559AV100_FIXED_631M  9
+#define HI3559AV100_FIXED_600M  10
+#define HI3559AV100_FIXED_568M  11
+#define HI3559AV100_FIXED_500M  12
+#define HI3559AV100_FIXED_475M  13
+#define HI3559AV100_FIXED_428M  14
+#define HI3559AV100_FIXED_400M  15
+#define HI3559AV100_FIXED_396M  16
+#define HI3559AV100_FIXED_300M  17
+#define HI3559AV100_FIXED_250M  18
+#define HI3559AV100_FIXED_198M  19
+#define HI3559AV100_FIXED_187p5M20
+#define HI3559AV100_FIXED_150M  21
+#define HI3559AV100_FIXED_148p5M22
+#define HI3559AV100_FIXED_125M  23
+#define HI3559AV100_FIXED_107M  24
+#define HI3559AV100_FIXED_100M  25
+#define HI3559AV100_FIXED_99M   26
+#define HI3559AV100_FIXED_74p25M27
+#define HI3559AV100_FIXED_72M   28
+#define HI3559AV100_FIXED_60M   29
+#define HI3559AV100_FIXED_54M   30
+#define HI3559AV100_FIXED_50M   31
+#define HI3559AV100_FIXED_49p5M 32
+#define HI3559AV100_FIXED_37p125M   33
+#define HI3559AV100_FIXED_36M   34
+#define HI3559AV100_FIXED_32p4M 35
+#define HI3559AV100_FIXED_27M   36
+#define HI3559AV100_FIXED_25M   37
+#define HI3559AV100_FIXED_24M   38
+#define HI3559AV100_FIXED_12M   39
+#define HI3559AV100_FIXED_3M40
+#define HI3559AV100_FIXED_1p6M  41
+#define HI3559AV100_FIXED_400K  42
+#define HI3559AV100_FIXED_100K  43
+#define HI3559AV100_FIXED_200M  44
+#define HI3559AV100_FIXED_75M   75
+
+#define HI3559AV100_I2C0_CLK50
+#define HI3559AV100_I2C1_CLK51
+#define HI3559AV100_I2C2_CLK52
+#define HI3559AV100_I2C3_CLK53
+#define HI3559AV100_I2C4_CLK54
+#define HI3559AV100_I2C5_CLK55
+#define HI3559AV100_I2C6_CLK56
+#define HI3559AV100_I2C7_CLK57
+#define HI3559AV100_I2C8_CLK58
+#define HI3559AV100_I2C9_CLK59
+#define HI3559AV100_I2C10_CLK   60
+#define HI3559AV100_I2C11_CLK   61
+
+#define HI3559AV100_SPI0_CLK62
+#define HI3559AV100_SPI1_CLK63
+#define HI3559AV100

[PATCH v4 3/4] dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller

2020-11-19 Thread Dongjiu Geng
The Hiedma Controller v310 Provides eight DMA channels, each
channel can be configured for one-way transfer. The data can
be transferred in 8-bit, 16-bit, 32-bit, or 64-bit mode. This
documentation describes DT bindings of this controller.

Signed-off-by: Dongjiu Geng 
---
 .../bindings/dma/hisilicon,hiedmacv310.yaml   | 103 ++
 1 file changed, 103 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml

diff --git a/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml 
b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
new file mode 100644
index ..fe5c5af4d3e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier:  GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/hisilicon,hiedmacv310.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon Hiedma Controller v310 Device Tree Bindings
+
+description: |
+  These bindings describe the DMA engine included in the HiSilicon Hiedma
+  Controller v310 Device.
+
+maintainers:
+  - Dongjiu Geng 
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+const: 2
+
+  "#clock-cells":
+const: 2
+
+  compatible:
+const: hisilicon,hiedmacv310
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  misc_regmap:
+description: phandle pointing to the misc controller provider node.
+
+  misc_ctrl_base:
+maxItems: 1
+
+  clocks:
+items:
+  - description: apb clock
+  - description: axi clock
+
+  clock-names:
+items:
+  - const: apb_pclk
+  - const: axi_aclk
+
+  resets:
+description: phandle pointing to the dma reset controller provider node.
+
+  reset-names:
+items:
+  - const: dma-reset
+
+  dma-requests:
+maximum: 32
+
+  dma-channels:
+maximum: 8
+
+
+required:
+  - "#dma-cells"
+  - "#clock-cells"
+  - compatible
+  - misc_regmap
+  - misc_ctrl_base
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - dma-requests
+  - dma-channels
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+dma: dma-controller@1004 {
+  compatible = "hisilicon,hiedmacv310";
+  reg = <0x1004 0x1000>;
+  misc_regmap = <&misc_ctrl>;
+  misc_ctrl_base = <0x144>;
+  interrupts = <0 82 4>;
+  clocks = <&clock HI3559AV100_EDMAC1_CLK>, <&clock 
HI3559AV100_EDMAC1_AXICLK>;
+  clock-names = "apb_pclk", "axi_aclk";
+  #clock-cells = <2>;
+  resets = <&clock 0x16c 7>;
+  reset-names = "dma-reset";
+  dma-requests = <32>;
+  dma-channels = <8>;
+  #dma-cells = <2>;
+};
+
+...
-- 
2.17.1



[PATCH v4 4/4] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-11-19 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Reported-by: kernel test robot 
Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1441 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1592 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..23814f3f2305
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1441 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+static void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_

[PATCH v4 2/4] clk: hisilicon: Add clock driver for hi3559A SoC

2020-11-19 Thread Dongjiu Geng
Add clock drivers for hi3559A SoC, this driver
controls the SoC registers to supply different
clocks to different IPs in the SoC.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/Kconfig   |   7 +
 drivers/clk/hisilicon/Makefile  |   1 +
 drivers/clk/hisilicon/clk-hi3559a.c | 865 
 3 files changed, 873 insertions(+)
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 6a9e93a0bb95..5ecc37aaa118 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
help
  Build the clock driver for hi3519.
 
+config COMMON_CLK_HI3559A
+   bool "Hi3559A Clock Driver"
+   depends on ARCH_HISI || COMPILE_TEST
+   default ARCH_HISI
+   help
+ Build the clock driver for hi3559a.
+
 config COMMON_CLK_HI3660
bool "Hi3660 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index b2441b99f3d5..bc101833b35e 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_COMMON_CLK_HI6220)   += clk-hi6220.o
 obj-$(CONFIG_RESET_HISI)   += reset.o
 obj-$(CONFIG_STUB_CLK_HI6220)  += clk-hi6220-stub.o
 obj-$(CONFIG_STUB_CLK_HI3660)  += clk-hi3660-stub.o
+obj-$(CONFIG_COMMON_CLK_HI3559A)   += clk-hi3559a.o
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
b/drivers/clk/hisilicon/clk-hi3559a.c
new file mode 100644
index ..d7693e488006
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Hisilicon Hi3559A clock driver
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "crg.h"
+#include "reset.h"
+
+#define CRG_BASE_ADDR  0x1802
+
+struct hi3559av100_pll_clock {
+   u32 id;
+   const char  *name;
+   const char  *parent_name;
+   u32 ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   u32 ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+struct hi3559av100_clk_pll {
+   struct clk_hw   hw;
+   u32 id;
+   void __iomem*ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   void __iomem*ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+/* soc clk config */
+static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = {
+   { HI3559AV100_FIXED_1188M, "1188m",   NULL, 0, 118800, },
+   { HI3559AV100_FIXED_1000M, "1000m",   NULL, 0, 10, },
+   { HI3559AV100_FIXED_842M, "842m",NULL, 0, 84200, },
+   { HI3559AV100_FIXED_792M, "792m",NULL, 0, 79200, },
+   { HI3559AV100_FIXED_750M, "750m",NULL, 0, 75000, },
+   { HI3559AV100_FIXED_710M, "710m",NULL, 0, 71000, },
+   { HI3559AV100_FIXED_680M, "680m",NULL, 0, 68000, },
+   { HI3559AV100_FIXED_667M, "667m",NULL, 0, 66700, },
+   { HI3559AV100_FIXED_631M, "631m",NULL, 0, 63100, },
+   { HI3559AV100_FIXED_600M, "600m",NULL, 0, 6, },
+   { HI3559AV100_FIXED_568M, "568m",NULL, 0, 56800, },
+   { HI3559AV100_FIXED_500M, "500m",NULL, 0, 5, },
+   { HI3559AV100_FIXED_475M, "475m",NULL, 0, 47500, },
+   { HI3559AV100_FIXED_428M, "428m",NULL, 0, 42800, },
+   { HI3559AV100_FIXED_400M, "400m",NULL, 0, 4, },
+   { HI3559AV100_FIXED_396M, "396m",NULL, 0, 39600, },
+   { HI3559AV100_FIXED_300M, "300m",NULL, 0, 3, },
+   { HI3559AV100_FIXED_250M, "250m",NULL, 0, 25000, },
+   { HI3559AV100_FIXED_200M, "200m",NULL, 0, 2, },
+   { HI3559AV100_FIXED_198M, "198m",NULL, 0, 19800, },
+   { HI3559AV100_FIXED_187p5M, "187p5m",  NULL, 0, 18750, },
+   { HI3559AV100_FIXED_150M, "150m",NULL, 0, 15000, },
+   { HI3559AV100_FIXED_148p5M, "148p5m",  NULL, 0, 148500, },
+   { HI3559AV100_FIXED_125M, "125m&quo

[PATCH v4 0/4] Enable Hi3559A SOC clock and HiSilicon Hiedma Controller

2020-11-19 Thread Dongjiu Geng
From: g00384164 

v3->v4:
1. fix the 'make dt_binding_check' issues.
2. Combine the 'Enable HiSilicon Hiedma Controller' series patches to this 
series.
3. fix the 'make dt_binding_check' issues in 'Enable HiSilicon Hiedma 
Controller' patchset


v2->v3:
1. change dt-bindings documents from txt to yaml format.
2. Add SHUB clock to access the devices of m7

Dongjiu Geng (4):
  dt-bindings: Document the hi3559a clock bindings
  clk: hisilicon: Add clock driver for hi3559A SoC
  dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller
  dmaengine: dma: Add Hiedma Controller v310 Device Driver

 .../clock/hisilicon,hi3559av100-clock.yaml|   66 +
 .../bindings/dma/hisilicon,hiedmacv310.yaml   |  103 ++
 drivers/clk/hisilicon/Kconfig |7 +
 drivers/clk/hisilicon/Makefile|1 +
 drivers/clk/hisilicon/clk-hi3559a.c   |  865 ++
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1441 +
 drivers/dma/hiedmacv310.h |  136 ++
 include/dt-bindings/clock/hi3559av100-clock.h |  165 ++
 10 files changed, 2799 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

-- 
2.17.1



Re: [PATCH V3] clk: hisilicon: refine hi3620_mmc_clk_init() and fix memory leak issues

2020-11-18 Thread Dongjiu Geng
ping, sorry for this noise.

On 2020/11/13 3:22, Dongjiu Geng wrote:
> Refine hi3620_mmc_clk_init() to use of_clk_add_hw_provider()
> instead of of_clk_add_provider(), the called function hisi_register_clk_mmc()
> returns 'clk_hw *' to adapt to this change.  Also free memory mapping and
> free hw_data if clock initialization is failed.
> 
> Fix the memory leak issues in hisi_clk_init().
> 
> Fixes: 75af25f581b1 ("clk: hisi: remove static variable")
> Fixes: 62ac983b6141 ("clk: hisilicon: add hi3620_mmc_clks")
> Cc: Markus Elfring 
> Signed-off-by: Dongjiu Geng 
> ---
> v2->v3:
> 1. Refind hi3620_mmc_clk_init() and hisi_register_clk_mmc() in order to use
>of_clk_add_hw_provider().
> 2. Fix the issue that incorrectly free data even clock is initialized
>successfully.
> ---
>  drivers/clk/hisilicon/clk-hi3620.c | 44 ++
>  drivers/clk/hisilicon/clk.c| 11 
>  2 files changed, 33 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/clk/hisilicon/clk-hi3620.c 
> b/drivers/clk/hisilicon/clk-hi3620.c
> index a3d04c7c3da8..3dec48174560 100644
> --- a/drivers/clk/hisilicon/clk-hi3620.c
> +++ b/drivers/clk/hisilicon/clk-hi3620.c
> @@ -408,12 +408,13 @@ static const struct clk_ops clk_mmc_ops = {
>   .recalc_rate = mmc_clk_recalc_rate,
>  };
>  
> -static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
> +static struct clk_hw *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
>   void __iomem *base, struct device_node *np)
>  {
>   struct clk_mmc *mclk;
> - struct clk *clk;
> + struct clk_hw *hw;
>   struct clk_init_data init;
> + int err;
>  
>   mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
>   if (!mclk)
> @@ -439,17 +440,22 @@ static struct clk *hisi_register_clk_mmc(struct 
> hisi_mmc_clock *mmc_clk,
>   mclk->sam_off = mmc_clk->sam_off;
>   mclk->sam_bits = mmc_clk->sam_bits;
>  
> - clk = clk_register(NULL, &mclk->hw);
> - if (WARN_ON(IS_ERR(clk)))
> + hw = &mclk->hw;
> + err = clk_hw_register(NULL, hw);
> +
> + if (err) {
>   kfree(mclk);
> - return clk;
> + return ERR_PTR(err);
> + }
> +
> + return hw;
>  }
>  
>  static void __init hi3620_mmc_clk_init(struct device_node *node)
>  {
>   void __iomem *base;
> - int i, num = ARRAY_SIZE(hi3620_mmc_clks);
> - struct clk_onecell_data *clk_data;
> + int i, ret, num = ARRAY_SIZE(hi3620_mmc_clks);
> + struct clk_hw_onecell_data *hw_data;
>  
>   if (!node) {
>   pr_err("failed to find pctrl node in DTS\n");
> @@ -462,22 +468,26 @@ static void __init hi3620_mmc_clk_init(struct 
> device_node *node)
>   return;
>   }
>  
> - clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
> - if (WARN_ON(!clk_data))
> - return;
> -
> - clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL);
> - if (!clk_data->clks)
> - return;
> + hw_data = kzalloc(struct_size(hw_data, hws, num), GFP_KERNEL);
> + if (WARN_ON(!hw_data))
> + goto unmap_io;
>  
>   for (i = 0; i < num; i++) {
>   struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
> - clk_data->clks[mmc_clk->id] =
> + hw_data->hws[mmc_clk->id] =
>   hisi_register_clk_mmc(mmc_clk, base, node);
>   }
>  
> - clk_data->clk_num = num;
> - of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> + hw_data->num = num;
> + ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, hw_data);
> + if (ret < 0)
> + goto free_hw_data;
> + return;
> +
> +free_hw_data:
> + kfree(hw_data);
> +unmap_io:
> + iounmap(base);
>  }
>  
>  CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", 
> hi3620_mmc_clk_init);
> diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
> index 54d9fdc93599..da655683710f 100644
> --- a/drivers/clk/hisilicon/clk.c
> +++ b/drivers/clk/hisilicon/clk.c
> @@ -65,25 +65,26 @@ struct hisi_clock_data *hisi_clk_init(struct device_node 
> *np,
>   base = of_iomap(np, 0);
>   if (!base) {
>   pr_err("%s: failed to map clock registers\n", __func__);
> - goto err;
> + return NULL;
>   }
>  
>   clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
>   if (!clk_data)
> - goto err;
> + goto unmap_io;
>

Re: [PATCH v3 1/2] dt-bindings: Document the hi3559a clock bindings

2020-11-16 Thread Dongjiu Geng



On 2020/11/16 23:02, Rob Herring wrote:
> On Sat, 14 Nov 2020 00:22:36 +0000, Dongjiu Geng wrote:
>> Add DT bindings documentation for hi3559a SoC clock.
>>
>> Signed-off-by: Dongjiu Geng 
>> ---
>>  .../clock/hisilicon,hi3559av100-clock.yaml|  65 +++
>>  include/dt-bindings/clock/hi3559av100-clock.h | 165 ++
>>  2 files changed, 230 insertions(+)
>>  create mode 100644 
>> Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
>>  create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h
>>
> 
> 
> My bot found errors running 'make dt_binding_check' on your patch
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.example.dts:20.23-27.11:
>  Warning (unit_address_vs_reg): /example-0/clock0: node has a reg or ranges 
> property, but no unit name
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.example.dt.yaml:
>  clock0: compatible: ['hisilicon,hi3559av100-clock', 'syscon'] is too long
>   From schema: 
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.example.dt.yaml:
>  clock0: compatible: Additional items are not allowed ('syscon' was 
> unexpected)
>   From schema: 
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.example.dt.yaml:
>  clock0: #reset-cells:0:0: 1 was expected
>   From schema: 
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
> 
> 
> See https://patchwork.ozlabs.org/patch/1399891
> 
> The base for the patch is generally the last rc1. Any dependencies
> should be noted.
> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.
ok, thanks a lot for the reminder.

> 
> .
> 


[PATCH 2/2] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-11-13 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1452 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1603 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..cd1fe30538ee
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1452 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   unsigned int id;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "lli num = 0%d", num);
+  

[PATCH 1/2] dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller

2020-11-13 Thread Dongjiu Geng
The Hiedma Controller v310 Provides eight DMA channels, each
channel can be configured for one-way transfer. The data can
be transferred in 8-bit, 16-bit, 32-bit, or 64-bit mode. This
documentation describes DT bindings of this controller.

Signed-off-by: Dongjiu Geng 
---
 .../bindings/dma/hisilicon,hiedmacv310.yaml   | 80 +++
 1 file changed, 80 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml

diff --git a/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml 
b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
new file mode 100644
index ..c04603316b40
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/hisilicon,hiedmacv310.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon Hiedma Controller v310 Device Tree Bindings
+
+description: |
+  These bindings describe the DMA engine included in the HiSilicon Hiedma
+  Controller v310 Device.
+
+maintainers:
+  - Dongjiu Geng 
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+const: 2
+
+  compatible:
+const: hisilicon,hiedmacv310_n
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: apb clock
+  - description: axi clock
+
+  clock-names:
+items:
+  - const: apb_pclk
+  - const: axi_aclk
+
+required:
+  - "#dma-cells"
+  - "#clock-cells"
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - dma-requests
+  - dma-channels
+  - devid
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+dma: dma-controller@1004 {
+  compatible = "hisilicon,hiedmacv310_n";
+  reg = <0x1004 0x1000>;
+  misc_regmap = <&misc_ctrl>;
+  misc_ctrl_base = <0x144>;
+  interrupts = <0 82 4>;
+  clocks = <&clock HI3559AV100_EDMAC1_CLK>, <&clock 
HI3559AV100_EDMAC1_AXICLK>;
+  clock-names = "apb_pclk", "axi_aclk";
+  #clock-cells = <2>;
+  resets = <&clock 0x16c 7>;
+  reset-names = "dma-reset";
+  dma-requests = <32>;
+  dma-channels = <8>;
+  devid = <1>;
+  #dma-cells = <2>;
+};
+
+...
-- 
2.17.1



[PATCH 1/2] dt: bindings: dma: Add DT bindings for HiSilicon Hiedma Controller

2020-11-13 Thread Dongjiu Geng
The Hiedma Controller v310 Provides eight DMA channels, each
channel can be configured for one-way transfer. The data can
be transferred in 8-bit, 16-bit, 32-bit, or 64-bit mode. This
documentation describes DT bindings of this controller.

Signed-off-by: Dongjiu Geng 
---
 .../bindings/dma/hisilicon,hiedmacv310.yaml   | 80 +++
 1 file changed, 80 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml

diff --git a/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml 
b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
new file mode 100644
index ..c04603316b40
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/hisilicon,hiedmacv310.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/hisilicon,hiedmacv310.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: HiSilicon Hiedma Controller v310 Device Tree Bindings
+
+description: |
+  These bindings describe the DMA engine included in the HiSilicon Hiedma
+  Controller v310 Device.
+
+maintainers:
+  - Dongjiu Geng 
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+const: 2
+
+  compatible:
+const: hisilicon,hiedmacv310_n
+
+  reg:
+maxItems: 1
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: apb clock
+  - description: axi clock
+
+  clock-names:
+items:
+  - const: apb_pclk
+  - const: axi_aclk
+
+required:
+  - "#dma-cells"
+  - "#clock-cells"
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - dma-requests
+  - dma-channels
+  - devid
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+
+dma: dma-controller@1004 {
+  compatible = "hisilicon,hiedmacv310_n";
+  reg = <0x1004 0x1000>;
+  misc_regmap = <&misc_ctrl>;
+  misc_ctrl_base = <0x144>;
+  interrupts = <0 82 4>;
+  clocks = <&clock HI3559AV100_EDMAC1_CLK>, <&clock 
HI3559AV100_EDMAC1_AXICLK>;
+  clock-names = "apb_pclk", "axi_aclk";
+  #clock-cells = <2>;
+  resets = <&clock 0x16c 7>;
+  reset-names = "dma-reset";
+  dma-requests = <32>;
+  dma-channels = <8>;
+  devid = <1>;
+  #dma-cells = <2>;
+};
+
+...
-- 
2.17.1



[PATCH 2/2] dmaengine: dma: Add Hiedma Controller v310 Device Driver

2020-11-13 Thread Dongjiu Geng
Hisilicon EDMA Controller(EDMAC) directly transfers data
between a memory and a peripheral, between peripherals, or
between memories. This avoids the CPU intervention and reduces
the interrupt handling overhead of the CPU, this driver enables
this controller.

Signed-off-by: Dongjiu Geng 
---
 drivers/dma/Kconfig   |   14 +
 drivers/dma/Makefile  |1 +
 drivers/dma/hiedmacv310.c | 1452 +
 drivers/dma/hiedmacv310.h |  136 
 4 files changed, 1603 insertions(+)
 create mode 100644 drivers/dma/hiedmacv310.c
 create mode 100644 drivers/dma/hiedmacv310.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 90284ffda58a..3e5107120ff1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -327,6 +327,20 @@ config K3_DMA
  Support the DMA engine for Hisilicon K3 platform
  devices.
 
+config HIEDMACV310
+   tristate "Hisilicon EDMAC Controller support"
+   depends on ARCH_HISI
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ The Direction Memory Access(EDMA) is a high-speed data transfer
+ operation. It supports data read/write between peripherals and
+ memories without using the CPU.
+ Hisilicon EDMA Controller(EDMAC) directly transfers data between
+ a memory and a peripheral, between peripherals, or between memories.
+ This avoids the CPU intervention and reduces the interrupt handling
+ overhead of the CPU.
+
 config LPC18XX_DMAMUX
bool "NXP LPC18xx/43xx DMA MUX for PL080"
depends on ARCH_LPC18XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 948a8da05f8b..28c7298b671e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
 obj-$(CONFIG_ZX_DMA) += zx_dma.o
 obj-$(CONFIG_ST_FDMA) += st_fdma.o
 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
 
 obj-y += mediatek/
 obj-y += qcom/
diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
new file mode 100644
index ..cd1fe30538ee
--- /dev/null
+++ b/drivers/dma/hiedmacv310.c
@@ -0,0 +1,1452 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The Hiedma Controller v310 Device Driver for HiSilicon
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "hiedmacv310.h"
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+#define DRIVER_NAME "hiedmacv310"
+
+#define MAX_TSFR_LLIS   512
+#define EDMACV300_LLI_WORDS 64
+#define EDMACV300_POOL_ALIGN64
+#define BITS_PER_HALF_WORD 32
+
+struct hiedmac_lli {
+   u64 next_lli;
+   u32 reserved[5];
+   u32 count;
+   u64 src_addr;
+   u64 dest_addr;
+   u32 config;
+   u32 pad[3];
+};
+
+struct hiedmac_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+struct transfer_desc {
+   struct virt_dma_desc virt_desc;
+   dma_addr_t llis_busaddr;
+   u64 *llis_vaddr;
+   u32 ccfg;
+   size_t size;
+   bool done;
+   bool cyclic;
+};
+
+enum edmac_dma_chan_state {
+   HIEDMAC_CHAN_IDLE,
+   HIEDMAC_CHAN_RUNNING,
+   HIEDMAC_CHAN_PAUSED,
+   HIEDMAC_CHAN_WAITING,
+};
+
+struct hiedmacv310_dma_chan {
+   bool slave;
+   int signal;
+   int id;
+   struct virt_dma_chan virt_chan;
+   struct hiedmacv310_phy_chan *phychan;
+   struct dma_slave_config cfg;
+   struct transfer_desc *at;
+   struct hiedmacv310_driver_data *host;
+   enum edmac_dma_chan_state state;
+};
+
+struct hiedmacv310_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   struct hiedmacv310_dma_chan *serving;
+};
+
+struct hiedmacv310_driver_data {
+   struct platform_device *dev;
+   struct dma_device slave;
+   struct dma_device memcpy;
+   void __iomem *base;
+   struct regmap *misc_regmap;
+   void __iomem *crg_ctrl;
+   struct hiedmacv310_phy_chan *phy_chans;
+   struct dma_pool *pool;
+   unsigned int misc_ctrl_base;
+   int irq;
+   unsigned int id;
+   struct clk *clk;
+   struct clk *axi_clk;
+   struct reset_control *rstc;
+   unsigned int channels;
+   unsigned int slave_requests;
+   unsigned int max_transfer_size;
+};
+
+#ifdef DEBUG_HIEDMAC
+void dump_lli(const u64 *llis_vaddr, unsigned int num)
+{
+   struct hiedmac_lli *plli = (struct hiedmac_lli *)llis_vaddr;
+   unsigned int i;
+
+   hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "lli num = 0%d", num);
+  

[PATCH v3 2/2] clk: hisilicon: Add clock driver for hi3559A SoC

2020-11-13 Thread Dongjiu Geng
Add clock drivers for hi3559A SoC, this driver
controls the SoC registers to supply different
clocks to different IPs in the SoC.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/Kconfig   |   7 +
 drivers/clk/hisilicon/Makefile  |   1 +
 drivers/clk/hisilicon/clk-hi3559a.c | 865 
 3 files changed, 873 insertions(+)
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 6a9e93a0bb95..5ecc37aaa118 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
help
  Build the clock driver for hi3519.
 
+config COMMON_CLK_HI3559A
+   bool "Hi3559A Clock Driver"
+   depends on ARCH_HISI || COMPILE_TEST
+   default ARCH_HISI
+   help
+ Build the clock driver for hi3559a.
+
 config COMMON_CLK_HI3660
bool "Hi3660 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index b2441b99f3d5..bc101833b35e 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_COMMON_CLK_HI6220)   += clk-hi6220.o
 obj-$(CONFIG_RESET_HISI)   += reset.o
 obj-$(CONFIG_STUB_CLK_HI6220)  += clk-hi6220-stub.o
 obj-$(CONFIG_STUB_CLK_HI3660)  += clk-hi3660-stub.o
+obj-$(CONFIG_COMMON_CLK_HI3559A)   += clk-hi3559a.o
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
b/drivers/clk/hisilicon/clk-hi3559a.c
new file mode 100644
index ..d7693e488006
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -0,0 +1,865 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Hisilicon Hi3559A clock driver
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "crg.h"
+#include "reset.h"
+
+#define CRG_BASE_ADDR  0x1802
+
+struct hi3559av100_pll_clock {
+   u32 id;
+   const char  *name;
+   const char  *parent_name;
+   u32 ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   u32 ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+struct hi3559av100_clk_pll {
+   struct clk_hw   hw;
+   u32 id;
+   void __iomem*ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   void __iomem*ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+/* soc clk config */
+static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = {
+   { HI3559AV100_FIXED_1188M, "1188m",   NULL, 0, 118800, },
+   { HI3559AV100_FIXED_1000M, "1000m",   NULL, 0, 10, },
+   { HI3559AV100_FIXED_842M, "842m",NULL, 0, 84200, },
+   { HI3559AV100_FIXED_792M, "792m",NULL, 0, 79200, },
+   { HI3559AV100_FIXED_750M, "750m",NULL, 0, 75000, },
+   { HI3559AV100_FIXED_710M, "710m",NULL, 0, 71000, },
+   { HI3559AV100_FIXED_680M, "680m",NULL, 0, 68000, },
+   { HI3559AV100_FIXED_667M, "667m",NULL, 0, 66700, },
+   { HI3559AV100_FIXED_631M, "631m",NULL, 0, 63100, },
+   { HI3559AV100_FIXED_600M, "600m",NULL, 0, 6, },
+   { HI3559AV100_FIXED_568M, "568m",NULL, 0, 56800, },
+   { HI3559AV100_FIXED_500M, "500m",NULL, 0, 5, },
+   { HI3559AV100_FIXED_475M, "475m",NULL, 0, 47500, },
+   { HI3559AV100_FIXED_428M, "428m",NULL, 0, 42800, },
+   { HI3559AV100_FIXED_400M, "400m",NULL, 0, 4, },
+   { HI3559AV100_FIXED_396M, "396m",NULL, 0, 39600, },
+   { HI3559AV100_FIXED_300M, "300m",NULL, 0, 3, },
+   { HI3559AV100_FIXED_250M, "250m",NULL, 0, 25000, },
+   { HI3559AV100_FIXED_200M, "200m",NULL, 0, 2, },
+   { HI3559AV100_FIXED_198M, "198m",NULL, 0, 19800, },
+   { HI3559AV100_FIXED_187p5M, "187p5m",  NULL, 0, 18750, },
+   { HI3559AV100_FIXED_150M, "150m",NULL, 0, 15000, },
+   { HI3559AV100_FIXED_148p5M, "148p5m",  NULL, 0, 148500, },
+   { HI3559AV100_FIXED_125M, "125m&quo

[PATCH v3 1/2] dt-bindings: Document the hi3559a clock bindings

2020-11-13 Thread Dongjiu Geng
Add DT bindings documentation for hi3559a SoC clock.

Signed-off-by: Dongjiu Geng 
---
 .../clock/hisilicon,hi3559av100-clock.yaml|  65 +++
 include/dt-bindings/clock/hi3559av100-clock.h | 165 ++
 2 files changed, 230 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

diff --git 
a/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml 
b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
new file mode 100644
index ..33d9a20962ae
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/hisilicon,hi3559av100-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Hisilicon SOC Clock for HI3559AV100
+
+maintainers:
+  - Dongjiu Geng 
+
+description: |
+  Hisilicon SOC clock control module which supports the clocks, resets and
+  power domains on HI3559AV100.
+
+  See also:
+dt-bindings/clock/hi3559av100-clock.h
+
+properties:
+  compatible:
+enum:
+  - hisilicon,hi3559av100-clock
+  - hisilicon,hi3559av100-shub-clock
+
+  reg:
+minItems: 1
+maxItems: 2
+items:
+  - description: CFG0 standard config space register
+  - description: CFG1 extended config space register
+
+  '#clock-cells':
+const: 1
+
+  '#reset-cells':
+const: 1
+
+  '#address-cells':
+const: 1
+
+  '#size-cells':
+const: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#address-cells'
+  - '#size-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+clock: clock0 {
+  compatible = "hisilicon,hi3559av100-clock", "syscon";
+  #clock-cells = <1>;
+  #reset-cells = <2>;
+  #address-cells = <1>;
+  #size-cells = <1>;
+  reg = <0x0 0x1201 0x0 0x1>;
+};
+...
diff --git a/include/dt-bindings/clock/hi3559av100-clock.h 
b/include/dt-bindings/clock/hi3559av100-clock.h
new file mode 100644
index ..88baa86cff85
--- /dev/null
+++ b/include/dt-bindings/clock/hi3559av100-clock.h
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#ifndef __DTS_HI3559AV100_CLOCK_H
+#define __DTS_HI3559AV100_CLOCK_H
+
+/*  fixed   rate*/
+#define HI3559AV100_FIXED_1188M 1
+#define HI3559AV100_FIXED_1000M 2
+#define HI3559AV100_FIXED_842M  3
+#define HI3559AV100_FIXED_792M  4
+#define HI3559AV100_FIXED_750M  5
+#define HI3559AV100_FIXED_710M  6
+#define HI3559AV100_FIXED_680M  7
+#define HI3559AV100_FIXED_667M  8
+#define HI3559AV100_FIXED_631M  9
+#define HI3559AV100_FIXED_600M  10
+#define HI3559AV100_FIXED_568M  11
+#define HI3559AV100_FIXED_500M  12
+#define HI3559AV100_FIXED_475M  13
+#define HI3559AV100_FIXED_428M  14
+#define HI3559AV100_FIXED_400M  15
+#define HI3559AV100_FIXED_396M  16
+#define HI3559AV100_FIXED_300M  17
+#define HI3559AV100_FIXED_250M  18
+#define HI3559AV100_FIXED_198M  19
+#define HI3559AV100_FIXED_187p5M20
+#define HI3559AV100_FIXED_150M  21
+#define HI3559AV100_FIXED_148p5M22
+#define HI3559AV100_FIXED_125M  23
+#define HI3559AV100_FIXED_107M  24
+#define HI3559AV100_FIXED_100M  25
+#define HI3559AV100_FIXED_99M   26
+#define HI3559AV100_FIXED_74p25M27
+#define HI3559AV100_FIXED_72M   28
+#define HI3559AV100_FIXED_60M   29
+#define HI3559AV100_FIXED_54M   30
+#define HI3559AV100_FIXED_50M   31
+#define HI3559AV100_FIXED_49p5M 32
+#define HI3559AV100_FIXED_37p125M   33
+#define HI3559AV100_FIXED_36M   34
+#define HI3559AV100_FIXED_32p4M 35
+#define HI3559AV100_FIXED_27M   36
+#define HI3559AV100_FIXED_25M   37
+#define HI3559AV100_FIXED_24M   38
+#define HI3559AV100_FIXED_12M   39
+#define HI3559AV100_FIXED_3M40
+#define HI3559AV100_FIXED_1p6M  41
+#define HI3559AV100_FIXED_400K  42
+#define HI3559AV100_FIXED_100K  43
+#define HI3559AV100_FIXED_200M  44
+#define HI3559AV100_FIXED_75M   75
+
+#define HI3559AV100_I2C0_CLK50
+#define HI3559AV100_I2C1_CLK51
+#define HI3559AV100_I2C2_CLK52
+#define HI3559AV100_I2C3_CLK53
+#define HI3559AV100_I2C4_CLK54
+#define HI3559AV100_I2C5_CLK55
+#define HI3559AV100_I2C6_CLK56
+#define HI3559AV100_I2C7_CLK57
+#define HI3559AV100_I2C8_CLK58
+#define HI3559AV100_I2C9_CLK59
+#define HI3559AV100_I2C10_CLK   60
+#define HI3559AV100_I2C11_CLK   61
+
+#define HI3559AV100_SPI0_CLK62
+#define HI3559AV100_SPI1_CLK63
+#defin

[PATCH v3 0/2] Enable Hi3559A SOC clock

2020-11-13 Thread Dongjiu Geng
v2->v3:
1. change dt-bindings documents from txt to yaml format.
2. Add SHUB clock to access the devices of m7

Dongjiu Geng (2):
  dt-bindings: Document the hi3559a clock bindings
  clk: hisilicon: Add clock driver for hi3559A SoC

 .../clock/hisilicon,hi3559av100-clock.yaml|  65 ++
 drivers/clk/hisilicon/Kconfig |   7 +
 drivers/clk/hisilicon/Makefile|   1 +
 drivers/clk/hisilicon/clk-hi3559a.c   | 865 ++
 include/dt-bindings/clock/hi3559av100-clock.h | 165 
 5 files changed, 1103 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

-- 
2.17.1



[PATCH v2 2/2] clk: hisilicon: Add clock driver for hi3559A SoC

2020-11-12 Thread Dongjiu Geng
Add clock drivers for hi3559A SoC, this driver
controls the SoC registers to supply different
clocks to different IPs in the SoC.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/Kconfig |   7 +
 drivers/clk/hisilicon/Makefile|   1 +
 drivers/clk/hisilicon/clk-hi3559a.c   | 654 ++
 include/dt-bindings/clock/hi3559av100-clock.h | 127 
 4 files changed, 789 insertions(+)
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 6a9e93a0bb95..5ecc37aaa118 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
help
  Build the clock driver for hi3519.
 
+config COMMON_CLK_HI3559A
+   bool "Hi3559A Clock Driver"
+   depends on ARCH_HISI || COMPILE_TEST
+   default ARCH_HISI
+   help
+ Build the clock driver for hi3559a.
+
 config COMMON_CLK_HI3660
bool "Hi3660 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index b2441b99f3d5..bc101833b35e 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_COMMON_CLK_HI6220)   += clk-hi6220.o
 obj-$(CONFIG_RESET_HISI)   += reset.o
 obj-$(CONFIG_STUB_CLK_HI6220)  += clk-hi6220-stub.o
 obj-$(CONFIG_STUB_CLK_HI3660)  += clk-hi3660-stub.o
+obj-$(CONFIG_COMMON_CLK_HI3559A)   += clk-hi3559a.o
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
b/drivers/clk/hisilicon/clk-hi3559a.c
new file mode 100644
index ..e8ac904d240c
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -0,0 +1,654 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Hisilicon Hi3559A clock driver
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "crg.h"
+#include "reset.h"
+
+struct hi3559av100_pll_clock {
+   u32 id;
+   const char  *name;
+   const char  *parent_name;
+   u32 ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   u32 ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+struct hi3559av100_clk_pll {
+   struct clk_hw   hw;
+   u32 id;
+   void __iomem*ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   void __iomem*ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+/* soc clk config */
+static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = {
+   { HI3559AV100_FIXED_1188M, "1188m",   NULL, 0, 118800, },
+   { HI3559AV100_FIXED_1000M, "1000m",   NULL, 0, 10, },
+   { HI3559AV100_FIXED_842M, "842m",NULL, 0, 84200, },
+   { HI3559AV100_FIXED_792M, "792m",NULL, 0, 79200, },
+   { HI3559AV100_FIXED_750M, "750m",NULL, 0, 75000, },
+   { HI3559AV100_FIXED_710M, "710m",NULL, 0, 71000, },
+   { HI3559AV100_FIXED_680M, "680m",NULL, 0, 68000, },
+   { HI3559AV100_FIXED_667M, "667m",NULL, 0, 66700, },
+   { HI3559AV100_FIXED_631M, "631m",NULL, 0, 63100, },
+   { HI3559AV100_FIXED_600M, "600m",NULL, 0, 6, },
+   { HI3559AV100_FIXED_568M, "568m",NULL, 0, 56800, },
+   { HI3559AV100_FIXED_500M, "500m",NULL, 0, 5, },
+   { HI3559AV100_FIXED_475M, "475m",NULL, 0, 47500, },
+   { HI3559AV100_FIXED_428M, "428m",NULL, 0, 42800, },
+   { HI3559AV100_FIXED_400M, "400m",NULL, 0, 4, },
+   { HI3559AV100_FIXED_396M, "396m",NULL, 0, 39600, },
+   { HI3559AV100_FIXED_300M, "300m",NULL, 0, 3, },
+   { HI3559AV100_FIXED_250M, "250m",NULL, 0, 25000, },
+   { HI3559AV100_FIXED_200M, "200m",NULL, 0, 2, },
+   { HI3559AV100_FIXED_198M, "198m",NULL, 0, 19800, },
+   { HI3559AV100_FIXED_187p5M, "187p5m",  NULL, 0, 18750, },
+   { HI3559AV100_FIXED_150M, "150m",NULL, 0, 15000, },
+   { HI3559AV100_FIXED_148p5M, "

[PATCH v2 1/2] dt-bindings: Document the hi3559a clock bindings

2020-11-12 Thread Dongjiu Geng
Add DT bindings documentation for hi3559a SoC clock.

Signed-off-by: Dongjiu Geng 
---
 .../bindings/clock/hi3559av100-clock.txt  | 40 +++
 1 file changed, 40 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hi3559av100-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/hi3559av100-clock.txt 
b/Documentation/devicetree/bindings/clock/hi3559av100-clock.txt
new file mode 100644
index ..0fb4ccc72cfe
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hi3559av100-clock.txt
@@ -0,0 +1,40 @@
+* Hisilicon Hi3559A Clock Controller
+
+The Hi3559A clock controller generates and supplies clock to various
+controllers within the Hi3559A SoC.
+
+Required Properties:
+
+- compatible: the compatible should be one of the following strings to
+   indicate the clock controller functionality.
+
+   - "hisilicon,hi3559av100-clock"
+
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in .
+
+Examples:
+
+   clock: clock0 {
+   compatible = "hisilicon,hi3559av100-clock", "syscon";
+   #clock-cells = <1>;
+   #reset-cells = <2>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   reg = <0x0 0x1201 0x0 0x1>;
+   };
+
+   uart0: uart@1210 {
+   compatible = "arm,pl011", "arm,primecell";
+   reg = <0x1210 0x1000>;
+   interrupts = <0 6 4>;
+   clocks = <&clock HI3559AV100_UART0_CLK>;
+   clock-names = "apb_pclk";
+   };
-- 
2.17.1



[PATCH v2 2/2] clk: hisilicon: Add clock driver for hi3559A SoC

2020-11-12 Thread Dongjiu Geng
Add clock drivers for hi3559A SoC, this driver
controls the SoC registers to supply different
clocks to different IPs in the SoC.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/Kconfig |   7 +
 drivers/clk/hisilicon/Makefile|   1 +
 drivers/clk/hisilicon/clk-hi3559a.c   | 654 ++
 include/dt-bindings/clock/hi3559av100-clock.h | 127 
 4 files changed, 789 insertions(+)
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 6a9e93a0bb95..5ecc37aaa118 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
help
  Build the clock driver for hi3519.
 
+config COMMON_CLK_HI3559A
+   bool "Hi3559A Clock Driver"
+   depends on ARCH_HISI || COMPILE_TEST
+   default ARCH_HISI
+   help
+ Build the clock driver for hi3559a.
+
 config COMMON_CLK_HI3660
bool "Hi3660 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index b2441b99f3d5..bc101833b35e 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_COMMON_CLK_HI6220)   += clk-hi6220.o
 obj-$(CONFIG_RESET_HISI)   += reset.o
 obj-$(CONFIG_STUB_CLK_HI6220)  += clk-hi6220-stub.o
 obj-$(CONFIG_STUB_CLK_HI3660)  += clk-hi3660-stub.o
+obj-$(CONFIG_COMMON_CLK_HI3559A)   += clk-hi3559a.o
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
b/drivers/clk/hisilicon/clk-hi3559a.c
new file mode 100644
index ..e8ac904d240c
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -0,0 +1,654 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Hisilicon Hi3559A clock driver
+ *
+ * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd.
+ *
+ * Author: Dongjiu Geng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "clk.h"
+#include "crg.h"
+#include "reset.h"
+
+struct hi3559av100_pll_clock {
+   u32 id;
+   const char  *name;
+   const char  *parent_name;
+   u32 ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   u32 ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+struct hi3559av100_clk_pll {
+   struct clk_hw   hw;
+   u32 id;
+   void __iomem*ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   void __iomem*ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+/* soc clk config */
+static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = {
+   { HI3559AV100_FIXED_1188M, "1188m",   NULL, 0, 118800, },
+   { HI3559AV100_FIXED_1000M, "1000m",   NULL, 0, 10, },
+   { HI3559AV100_FIXED_842M, "842m",NULL, 0, 84200, },
+   { HI3559AV100_FIXED_792M, "792m",NULL, 0, 79200, },
+   { HI3559AV100_FIXED_750M, "750m",NULL, 0, 75000, },
+   { HI3559AV100_FIXED_710M, "710m",NULL, 0, 71000, },
+   { HI3559AV100_FIXED_680M, "680m",NULL, 0, 68000, },
+   { HI3559AV100_FIXED_667M, "667m",NULL, 0, 66700, },
+   { HI3559AV100_FIXED_631M, "631m",NULL, 0, 63100, },
+   { HI3559AV100_FIXED_600M, "600m",NULL, 0, 6, },
+   { HI3559AV100_FIXED_568M, "568m",NULL, 0, 56800, },
+   { HI3559AV100_FIXED_500M, "500m",NULL, 0, 5, },
+   { HI3559AV100_FIXED_475M, "475m",NULL, 0, 47500, },
+   { HI3559AV100_FIXED_428M, "428m",NULL, 0, 42800, },
+   { HI3559AV100_FIXED_400M, "400m",NULL, 0, 4, },
+   { HI3559AV100_FIXED_396M, "396m",NULL, 0, 39600, },
+   { HI3559AV100_FIXED_300M, "300m",NULL, 0, 3, },
+   { HI3559AV100_FIXED_250M, "250m",NULL, 0, 25000, },
+   { HI3559AV100_FIXED_200M, "200m",NULL, 0, 2, },
+   { HI3559AV100_FIXED_198M, "198m",NULL, 0, 19800, },
+   { HI3559AV100_FIXED_187p5M, "187p5m",  NULL, 0, 18750, },
+   { HI3559AV100_FIXED_150M, "150m",NULL, 0, 15000, },
+   { HI3559AV100_FIXED_148p5M, "

[PATCH v2 1/2] dt-bindings: Document the hi3559a clock bindings

2020-11-12 Thread Dongjiu Geng
Add DT bindings documentation for hi3559a SoC clock.

Signed-off-by: Dongjiu Geng 
---
 .../bindings/clock/hi3559av100-clock.txt  | 40 +++
 1 file changed, 40 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/hi3559av100-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/hi3559av100-clock.txt 
b/Documentation/devicetree/bindings/clock/hi3559av100-clock.txt
new file mode 100644
index ..0fb4ccc72cfe
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/hi3559av100-clock.txt
@@ -0,0 +1,40 @@
+* Hisilicon Hi3559A Clock Controller
+
+The Hi3559A clock controller generates and supplies clock to various
+controllers within the Hi3559A SoC.
+
+Required Properties:
+
+- compatible: the compatible should be one of the following strings to
+   indicate the clock controller functionality.
+
+   - "hisilicon,hi3559av100-clock"
+
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes use this identifier
+to specify the clock which they consume.
+
+All these identifier could be found in .
+
+Examples:
+
+   clock: clock0 {
+   compatible = "hisilicon,hi3559av100-clock", "syscon";
+   #clock-cells = <1>;
+   #reset-cells = <2>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   reg = <0x0 0x1201 0x0 0x1>;
+   };
+
+   uart0: uart@1210 {
+   compatible = "arm,pl011", "arm,primecell";
+   reg = <0x1210 0x1000>;
+   interrupts = <0 6 4>;
+   clocks = <&clock HI3559AV100_UART0_CLK>;
+   clock-names = "apb_pclk";
+   };
-- 
2.17.1



Re: [PATCH V3] clk: hisilicon: refine hi3620_mmc_clk_init() and fix memory leak issues

2020-11-12 Thread Dongjiu Geng
add Markus

On 2020/11/13 3:22, Dongjiu Geng wrote:
> Refine hi3620_mmc_clk_init() to use of_clk_add_hw_provider()
> instead of of_clk_add_provider(), the called function hisi_register_clk_mmc()
> returns 'clk_hw *' to adapt to this change.  Also free memory mapping and
> free hw_data if clock initialization is failed.
> 
> Fix the memory leak issues in hisi_clk_init().
> 
> Fixes: 75af25f581b1 ("clk: hisi: remove static variable")
> Fixes: 62ac983b6141 ("clk: hisilicon: add hi3620_mmc_clks")
> Cc: Markus Elfring 
> Signed-off-by: Dongjiu Geng 
> ---
> v2->v3:
> 1. Refind hi3620_mmc_clk_init() and hisi_register_clk_mmc() in order to use
>of_clk_add_hw_provider().
> 2. Fix the issue that incorrectly free data even clock is initialized
>successfully.
> ---
>  drivers/clk/hisilicon/clk-hi3620.c | 44 ++
>  drivers/clk/hisilicon/clk.c| 11 
>  2 files changed, 33 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/clk/hisilicon/clk-hi3620.c 
> b/drivers/clk/hisilicon/clk-hi3620.c
> index a3d04c7c3da8..3dec48174560 100644
> --- a/drivers/clk/hisilicon/clk-hi3620.c
> +++ b/drivers/clk/hisilicon/clk-hi3620.c
> @@ -408,12 +408,13 @@ static const struct clk_ops clk_mmc_ops = {
>   .recalc_rate = mmc_clk_recalc_rate,
>  };
>  
> -static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
> +static struct clk_hw *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
>   void __iomem *base, struct device_node *np)
>  {
>   struct clk_mmc *mclk;
> - struct clk *clk;
> + struct clk_hw *hw;
>   struct clk_init_data init;
> + int err;
>  
>   mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
>   if (!mclk)
> @@ -439,17 +440,22 @@ static struct clk *hisi_register_clk_mmc(struct 
> hisi_mmc_clock *mmc_clk,
>   mclk->sam_off = mmc_clk->sam_off;
>   mclk->sam_bits = mmc_clk->sam_bits;
>  
> - clk = clk_register(NULL, &mclk->hw);
> - if (WARN_ON(IS_ERR(clk)))
> + hw = &mclk->hw;
> + err = clk_hw_register(NULL, hw);
> +
> + if (err) {
>   kfree(mclk);
> - return clk;
> + return ERR_PTR(err);
> + }
> +
> + return hw;
>  }
>  
>  static void __init hi3620_mmc_clk_init(struct device_node *node)
>  {
>   void __iomem *base;
> - int i, num = ARRAY_SIZE(hi3620_mmc_clks);
> - struct clk_onecell_data *clk_data;
> + int i, ret, num = ARRAY_SIZE(hi3620_mmc_clks);
> + struct clk_hw_onecell_data *hw_data;
>  
>   if (!node) {
>   pr_err("failed to find pctrl node in DTS\n");
> @@ -462,22 +468,26 @@ static void __init hi3620_mmc_clk_init(struct 
> device_node *node)
>   return;
>   }
>  
> - clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
> - if (WARN_ON(!clk_data))
> - return;
> -
> - clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL);
> - if (!clk_data->clks)
> - return;
> + hw_data = kzalloc(struct_size(hw_data, hws, num), GFP_KERNEL);
> + if (WARN_ON(!hw_data))
> + goto unmap_io;
>  
>   for (i = 0; i < num; i++) {
>   struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
> - clk_data->clks[mmc_clk->id] =
> + hw_data->hws[mmc_clk->id] =
>   hisi_register_clk_mmc(mmc_clk, base, node);
>   }
>  
> - clk_data->clk_num = num;
> - of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> + hw_data->num = num;
> + ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, hw_data);
> + if (ret < 0)
> + goto free_hw_data;
> + return;
> +
> +free_hw_data:
> + kfree(hw_data);
> +unmap_io:
> + iounmap(base);
>  }
>  
>  CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", 
> hi3620_mmc_clk_init);
> diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
> index 54d9fdc93599..da655683710f 100644
> --- a/drivers/clk/hisilicon/clk.c
> +++ b/drivers/clk/hisilicon/clk.c
> @@ -65,25 +65,26 @@ struct hisi_clock_data *hisi_clk_init(struct device_node 
> *np,
>   base = of_iomap(np, 0);
>   if (!base) {
>   pr_err("%s: failed to map clock registers\n", __func__);
> - goto err;
> + return NULL;
>   }
>  
>   clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
>   if (!clk_data)
> - goto err;
> + goto unmap_io;
>  
>   clk_data->

[PATCH V3] clk: hisilicon: refine hi3620_mmc_clk_init() and fix memory leak issues

2020-11-12 Thread Dongjiu Geng
Refine hi3620_mmc_clk_init() to use of_clk_add_hw_provider()
instead of of_clk_add_provider(), the called function hisi_register_clk_mmc()
returns 'clk_hw *' to adapt to this change.  Also free memory mapping and
free hw_data if clock initialization is failed.

Fix the memory leak issues in hisi_clk_init().

Fixes: 75af25f581b1 ("clk: hisi: remove static variable")
Fixes: 62ac983b6141 ("clk: hisilicon: add hi3620_mmc_clks")
Cc: Markus Elfring 
Signed-off-by: Dongjiu Geng 
---
v2->v3:
1. Refind hi3620_mmc_clk_init() and hisi_register_clk_mmc() in order to use
   of_clk_add_hw_provider().
2. Fix the issue that incorrectly free data even clock is initialized
   successfully.
---
 drivers/clk/hisilicon/clk-hi3620.c | 44 ++
 drivers/clk/hisilicon/clk.c| 11 
 2 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/drivers/clk/hisilicon/clk-hi3620.c 
b/drivers/clk/hisilicon/clk-hi3620.c
index a3d04c7c3da8..3dec48174560 100644
--- a/drivers/clk/hisilicon/clk-hi3620.c
+++ b/drivers/clk/hisilicon/clk-hi3620.c
@@ -408,12 +408,13 @@ static const struct clk_ops clk_mmc_ops = {
.recalc_rate = mmc_clk_recalc_rate,
 };
 
-static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
+static struct clk_hw *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
void __iomem *base, struct device_node *np)
 {
struct clk_mmc *mclk;
-   struct clk *clk;
+   struct clk_hw *hw;
struct clk_init_data init;
+   int err;
 
mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
if (!mclk)
@@ -439,17 +440,22 @@ static struct clk *hisi_register_clk_mmc(struct 
hisi_mmc_clock *mmc_clk,
mclk->sam_off = mmc_clk->sam_off;
mclk->sam_bits = mmc_clk->sam_bits;
 
-   clk = clk_register(NULL, &mclk->hw);
-   if (WARN_ON(IS_ERR(clk)))
+   hw = &mclk->hw;
+   err = clk_hw_register(NULL, hw);
+
+   if (err) {
kfree(mclk);
-   return clk;
+   return ERR_PTR(err);
+   }
+
+   return hw;
 }
 
 static void __init hi3620_mmc_clk_init(struct device_node *node)
 {
void __iomem *base;
-   int i, num = ARRAY_SIZE(hi3620_mmc_clks);
-   struct clk_onecell_data *clk_data;
+   int i, ret, num = ARRAY_SIZE(hi3620_mmc_clks);
+   struct clk_hw_onecell_data *hw_data;
 
if (!node) {
pr_err("failed to find pctrl node in DTS\n");
@@ -462,22 +468,26 @@ static void __init hi3620_mmc_clk_init(struct device_node 
*node)
return;
}
 
-   clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
-   if (WARN_ON(!clk_data))
-   return;
-
-   clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL);
-   if (!clk_data->clks)
-   return;
+   hw_data = kzalloc(struct_size(hw_data, hws, num), GFP_KERNEL);
+   if (WARN_ON(!hw_data))
+   goto unmap_io;
 
for (i = 0; i < num; i++) {
struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
-   clk_data->clks[mmc_clk->id] =
+   hw_data->hws[mmc_clk->id] =
hisi_register_clk_mmc(mmc_clk, base, node);
}
 
-   clk_data->clk_num = num;
-   of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+   hw_data->num = num;
+   ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, hw_data);
+   if (ret < 0)
+   goto free_hw_data;
+   return;
+
+free_hw_data:
+   kfree(hw_data);
+unmap_io:
+   iounmap(base);
 }
 
 CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", 
hi3620_mmc_clk_init);
diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index 54d9fdc93599..da655683710f 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -65,25 +65,26 @@ struct hisi_clock_data *hisi_clk_init(struct device_node 
*np,
base = of_iomap(np, 0);
if (!base) {
pr_err("%s: failed to map clock registers\n", __func__);
-   goto err;
+   return NULL;
}
 
clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
if (!clk_data)
-   goto err;
+   goto unmap_io;
 
clk_data->base = base;
clk_table = kcalloc(nr_clks, sizeof(*clk_table), GFP_KERNEL);
if (!clk_table)
-   goto err_data;
+   goto free_clk_data;
 
clk_data->clk_data.clks = clk_table;
clk_data->clk_data.clk_num = nr_clks;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
return clk_data;
-err_data:
+free_clk_data:
kfree(clk_data);
-err:
+unmap_io:
+   iounmap(base);
return NULL;
 }
 EXPORT_SYMBOL_GPL(hisi_clk_init);
-- 
2.17.1



[PATCH] clk: hisilicon: refine hi3620_mmc_clk_init() and fix memory leak issues

2020-11-12 Thread Dongjiu Geng
Refine hi3620_mmc_clk_init() to use of_clk_add_hw_provider()
instead of of_clk_add_provider(), the called function hisi_register_clk_mmc()
returns 'clk_hw *' to adapt to this change.  Also free memory mapping and
free hw_data if clock initialization is failed.

Fix the memory leak issues in hisi_clk_init().

Fixes: 75af25f581b1 ("clk: hisi: remove static variable")
Fixes: 62ac983b6141 ("clk: hisilicon: add hi3620_mmc_clks")
Cc: Markus Elfring 
Signed-off-by: Dongjiu Geng 
---
v2->v3:
1. Refind hi3620_mmc_clk_init() and hisi_register_clk_mmc() in order to use
   of_clk_add_hw_provider().
2. Fix the issue that incorrectly free data even clock is initialized
   successfully.
---
 drivers/clk/hisilicon/clk-hi3620.c | 44 ++
 drivers/clk/hisilicon/clk.c| 11 
 2 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/drivers/clk/hisilicon/clk-hi3620.c 
b/drivers/clk/hisilicon/clk-hi3620.c
index a3d04c7c3da8..3dec48174560 100644
--- a/drivers/clk/hisilicon/clk-hi3620.c
+++ b/drivers/clk/hisilicon/clk-hi3620.c
@@ -408,12 +408,13 @@ static const struct clk_ops clk_mmc_ops = {
.recalc_rate = mmc_clk_recalc_rate,
 };
 
-static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
+static struct clk_hw *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk,
void __iomem *base, struct device_node *np)
 {
struct clk_mmc *mclk;
-   struct clk *clk;
+   struct clk_hw *hw;
struct clk_init_data init;
+   int err;
 
mclk = kzalloc(sizeof(*mclk), GFP_KERNEL);
if (!mclk)
@@ -439,17 +440,22 @@ static struct clk *hisi_register_clk_mmc(struct 
hisi_mmc_clock *mmc_clk,
mclk->sam_off = mmc_clk->sam_off;
mclk->sam_bits = mmc_clk->sam_bits;
 
-   clk = clk_register(NULL, &mclk->hw);
-   if (WARN_ON(IS_ERR(clk)))
+   hw = &mclk->hw;
+   err = clk_hw_register(NULL, hw);
+
+   if (err) {
kfree(mclk);
-   return clk;
+   return ERR_PTR(err);
+   }
+
+   return hw;
 }
 
 static void __init hi3620_mmc_clk_init(struct device_node *node)
 {
void __iomem *base;
-   int i, num = ARRAY_SIZE(hi3620_mmc_clks);
-   struct clk_onecell_data *clk_data;
+   int i, ret, num = ARRAY_SIZE(hi3620_mmc_clks);
+   struct clk_hw_onecell_data *hw_data;
 
if (!node) {
pr_err("failed to find pctrl node in DTS\n");
@@ -462,22 +468,26 @@ static void __init hi3620_mmc_clk_init(struct device_node 
*node)
return;
}
 
-   clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
-   if (WARN_ON(!clk_data))
-   return;
-
-   clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL);
-   if (!clk_data->clks)
-   return;
+   hw_data = kzalloc(struct_size(hw_data, hws, num), GFP_KERNEL);
+   if (WARN_ON(!hw_data))
+   goto unmap_io;
 
for (i = 0; i < num; i++) {
struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
-   clk_data->clks[mmc_clk->id] =
+   hw_data->hws[mmc_clk->id] =
hisi_register_clk_mmc(mmc_clk, base, node);
}
 
-   clk_data->clk_num = num;
-   of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+   hw_data->num = num;
+   ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, hw_data);
+   if (ret < 0)
+   goto free_hw_data;
+   return;
+
+free_hw_data:
+   kfree(hw_data);
+unmap_io:
+   iounmap(base);
 }
 
 CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", 
hi3620_mmc_clk_init);
diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index 54d9fdc93599..da655683710f 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -65,25 +65,26 @@ struct hisi_clock_data *hisi_clk_init(struct device_node 
*np,
base = of_iomap(np, 0);
if (!base) {
pr_err("%s: failed to map clock registers\n", __func__);
-   goto err;
+   return NULL;
}
 
clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
if (!clk_data)
-   goto err;
+   goto unmap_io;
 
clk_data->base = base;
clk_table = kcalloc(nr_clks, sizeof(*clk_table), GFP_KERNEL);
if (!clk_table)
-   goto err_data;
+   goto free_clk_data;
 
clk_data->clk_data.clks = clk_table;
clk_data->clk_data.clk_num = nr_clks;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
return clk_data;
-err_data:
+free_clk_data:
kfree(clk_data);
-err:
+unmap_io:
+   iounmap(base);
return NULL;
 }
 EXPORT_SYMBOL_GPL(hisi_clk_init);
-- 
2.17.1



Re: [PATCH] clk: hisilicon: Add clock driver for hi3559A SoC

2020-11-11 Thread Dongjiu Geng
On 2020/11/12 6:23, Rob Herring wrote:
> On Mon, Nov 09, 2020 at 08:28:38PM +0000, Dongjiu Geng wrote:
>> Add clock drivers for hi3559A SoC, this driver controls the SoC
>> registers to supply different clocks to different IPs in the SoC.
>>
>> Signed-off-by: Dongjiu Geng 
>> ---
>>  drivers/clk/hisilicon/Kconfig |   7 +
>>  drivers/clk/hisilicon/Makefile|   1 +
>>  drivers/clk/hisilicon/clk-hi3559a.c   | 873 ++
>>  include/dt-bindings/clock/hi3559av100-clock.h | 173 
> 
> Is there a binding for this? The header should be part of it.
yes, I will add it.
Thanks for the pointing out.

> 
>>  4 files changed, 1054 insertions(+)
>>  create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
>>  create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h
>>
>> diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
>> index 6a9e93a0bb95..5ecc37aaa118 100644
>> --- a/drivers/clk/hisilicon/Kconfig
>> +++ b/drivers/clk/hisilicon/Kconfig
>> @@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
>>  help
>>Build the clock driver for hi3519.
>>  
>> +config COMMON_CLK_HI3559A
>> +bool "Hi3559A Clock Driver"
>> +depends on ARCH_HISI || COMPILE_TEST
>> +default ARCH_HISI
>> +help
>> +  Build the clock driver for hi3559a.
>> +
>>  config COMMON_CLK_HI3660
>>  bool "Hi3660 Clock Driver"
>>  depends on ARCH_HISI || COMPILE_TEST
>> diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
>> index b2441b99f3d5..bc101833b35e 100644
>> --- a/drivers/clk/hisilicon/Makefile
>> +++ b/drivers/clk/hisilicon/Makefile
>> @@ -17,3 +17,4 @@ obj-$(CONFIG_COMMON_CLK_HI6220)+= clk-hi6220.o
>>  obj-$(CONFIG_RESET_HISI)+= reset.o
>>  obj-$(CONFIG_STUB_CLK_HI6220)   += clk-hi6220-stub.o
>>  obj-$(CONFIG_STUB_CLK_HI3660)   += clk-hi3660-stub.o
>> +obj-$(CONFIG_COMMON_CLK_HI3559A)+= clk-hi3559a.o
>> diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
>> b/drivers/clk/hisilicon/clk-hi3559a.c
>> new file mode 100644
>> index ..bd3921fc8c8e
>> --- /dev/null
>> +++ b/drivers/clk/hisilicon/clk-hi3559a.c
>> @@ -0,0 +1,873 @@
>> +// SPDX-License-Identifier: GPL-2.0-or-later
>> +/*
>> + * Hisilicon Hi3559A clock driver
>> + *
>> + * Copyright (c) 2019-2020 HiSilicon Technologies Co., Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
> 
> Don't need both this and SPDX tag. Kernel code should be GPL-2.0 (-only) 
> generally.

Ok, I will remove one. thanks.

> 
>> + *
>> + * Author: Dongjiu Geng 
> 
> git will tell us this.
> 
> Same comments apply to the header. Though DT headers should be dual 
> licensed.
> 
> Rob
> .
> 


Re: [PATCH v2] clk: hisilicon: Free clk_data and unmap region obtained by of_iomap

2020-11-10 Thread Dongjiu Geng



On 2020/11/10 1:54, Markus Elfring wrote:
> …
>> +++ b/drivers/clk/hisilicon/clk-hi3620.c
> …
>> @@ -478,6 +478,10 @@ static void __init hi3620_mmc_clk_init(struct 
>> device_node *node)
>>
>>  clk_data->clk_num = num;
>>  of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
>> +free_clk_data:
>> +kfree(clk_data);
> …
> 
> * Should any system resources be kept allocated if the execution
>   of this function implementation succeeded?
> 
> * How do you think about to add the statement “return;”
>   after the call of the function “of_clk_add_provider”?
> 
> * Should another return value be also checked here?

sure.

> 
>   See also:
>   
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clk/clk.c?id=f8394f232b1eab649ce2df5c5f15b0e528c92091#n4414
>   https://elixir.bootlin.com/linux/v5.10-rc2/source/drivers/clk/clk.c#L4414
> 
> * Would you like to use the function “of_clk_add_hw_provider” instead?

How about we still use of_clk_add_provider()? It doesn't seem to make 
difference using of_clk_add_hw_provider().

> 
> Regards,
> Markus


[PATCH] clk: hisilicon: Add clock driver for hi3559A SoC

2020-11-09 Thread Dongjiu Geng
Add clock drivers for hi3559A SoC, this driver controls the SoC
registers to supply different clocks to different IPs in the SoC.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/Kconfig |   7 +
 drivers/clk/hisilicon/Makefile|   1 +
 drivers/clk/hisilicon/clk-hi3559a.c   | 873 ++
 include/dt-bindings/clock/hi3559av100-clock.h | 173 
 4 files changed, 1054 insertions(+)
 create mode 100644 drivers/clk/hisilicon/clk-hi3559a.c
 create mode 100644 include/dt-bindings/clock/hi3559av100-clock.h

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index 6a9e93a0bb95..5ecc37aaa118 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -15,6 +15,13 @@ config COMMON_CLK_HI3519
help
  Build the clock driver for hi3519.
 
+config COMMON_CLK_HI3559A
+   bool "Hi3559A Clock Driver"
+   depends on ARCH_HISI || COMPILE_TEST
+   default ARCH_HISI
+   help
+ Build the clock driver for hi3559a.
+
 config COMMON_CLK_HI3660
bool "Hi3660 Clock Driver"
depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index b2441b99f3d5..bc101833b35e 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_COMMON_CLK_HI6220)   += clk-hi6220.o
 obj-$(CONFIG_RESET_HISI)   += reset.o
 obj-$(CONFIG_STUB_CLK_HI6220)  += clk-hi6220-stub.o
 obj-$(CONFIG_STUB_CLK_HI3660)  += clk-hi3660-stub.o
+obj-$(CONFIG_COMMON_CLK_HI3559A)   += clk-hi3559a.o
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c 
b/drivers/clk/hisilicon/clk-hi3559a.c
new file mode 100644
index ..bd3921fc8c8e
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -0,0 +1,873 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Hisilicon Hi3559A clock driver
+ *
+ * Copyright (c) 2019-2020 HiSilicon Technologies Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Author: Dongjiu Geng 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk.h"
+#include "crg.h"
+#include "reset.h"
+
+struct hi3559av100_pll_clock {
+   u32 id;
+   const char  *name;
+   const char  *parent_name;
+   u32 ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   u32 ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+struct hi3559av100_clk_pll {
+   struct clk_hw   hw;
+   u32 id;
+   void __iomem*ctrl_reg1;
+   u8  frac_shift;
+   u8  frac_width;
+   u8  postdiv1_shift;
+   u8  postdiv1_width;
+   u8  postdiv2_shift;
+   u8  postdiv2_width;
+   void __iomem*ctrl_reg2;
+   u8  fbdiv_shift;
+   u8  fbdiv_width;
+   u8  refdiv_shift;
+   u8  refdiv_width;
+};
+
+/* soc clk config */
+static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = {
+   { HI3559AV100_FIXED_1188M, "1188m",   NULL, 0, 118800, },
+   { HI3559AV100_FIXED_1000M, "1000m",   NULL, 0, 10, },
+   { HI3559AV100_FIXED_842M, "842m",NULL, 0, 84200, },
+   { HI3559AV100_FIXED_792M, "792m",NULL, 0, 79200, },
+   { HI3559AV100_FIXED_750M, "750m",NULL, 0, 75000, },
+   { HI3559AV100_FIXED_710M, "710m",NULL, 0, 71000, },
+   { HI3559AV100_FIXED_680M, "680m",NULL, 0, 68000, },
+   { HI3559AV100_FIXED_667M, "667m",NULL, 0, 66700, },
+   { HI3559AV100_FIXED_631M, "631m",NULL, 0, 63100, },
+   { HI3559AV100_FIXED_600M, "600m",NULL, 0, 6, },
+   { HI3559AV100_FIXED_568M, "568m",NULL, 0, 56800, },
+   { HI3559AV100_FIXED_500M, "500m",NULL, 0, 5, },
+   { HI3559AV100_FIXED_475M, "475m",NULL, 0, 47500, },
+   { HI3559AV100_FIXED_428M, "428m",NULL, 0, 42800, },
+   { HI3559AV100_FIXED_400M, "400m",NULL, 0, 4, },
+   { HI3559AV100_FIXED_396M, "396m",NULL, 0, 39600, },
+   { HI3559AV100_FIXED_300M, "300m",NULL, 0, 3, },
+   { HI3559AV100_FIXED_250M, "250m",NULL, 0, 25000, },
+   { HI3559AV100_FIXED_200M, "200m",NULL, 0, 2, },

Re: [PATCH V2] clk: hisilicon: Free clk_data and unmap region obtained by of_iomap

2020-11-09 Thread Dongjiu Geng
add Markus

On 2020/11/10 2:09, Dongjiu Geng wrote:
> Free memory mapping and free clk_data, if clock initialization
> is not successful.
> 
> Fixes: 75af25f581b1 ("clk: hisi: remove static variable")
> Fixes: 62ac983b6141 ("clk: hisilicon: add hi3620_mmc_clks")
> Signed-off-by: Dongjiu Geng 
> ---
>  drivers/clk/hisilicon/clk-hi3620.c |  8 ++--
>  drivers/clk/hisilicon/clk.c| 11 ++-
>  2 files changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/clk/hisilicon/clk-hi3620.c 
> b/drivers/clk/hisilicon/clk-hi3620.c
> index a3d04c7c3da8..864d2ddfc73c 100644
> --- a/drivers/clk/hisilicon/clk-hi3620.c
> +++ b/drivers/clk/hisilicon/clk-hi3620.c
> @@ -464,11 +464,11 @@ static void __init hi3620_mmc_clk_init(struct 
> device_node *node)
>  
>   clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
>   if (WARN_ON(!clk_data))
> - return;
> + goto unmap_io;
>  
>   clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL);
>   if (!clk_data->clks)
> - return;
> + goto free_clk_data;
>  
>   for (i = 0; i < num; i++) {
>   struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
> @@ -478,6 +478,10 @@ static void __init hi3620_mmc_clk_init(struct 
> device_node *node)
>  
>   clk_data->clk_num = num;
>   of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +free_clk_data:
> + kfree(clk_data);
> +unmap_io:
> + iounmap(base);
>  }
>  
>  CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", 
> hi3620_mmc_clk_init);
> diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
> index 54d9fdc93599..da655683710f 100644
> --- a/drivers/clk/hisilicon/clk.c
> +++ b/drivers/clk/hisilicon/clk.c
> @@ -65,25 +65,26 @@ struct hisi_clock_data *hisi_clk_init(struct device_node 
> *np,
>   base = of_iomap(np, 0);
>   if (!base) {
>   pr_err("%s: failed to map clock registers\n", __func__);
> - goto err;
> + return NULL;
>   }
>  
>   clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
>   if (!clk_data)
> - goto err;
> + goto unmap_io;
>  
>   clk_data->base = base;
>   clk_table = kcalloc(nr_clks, sizeof(*clk_table), GFP_KERNEL);
>   if (!clk_table)
> - goto err_data;
> + goto free_clk_data;
>  
>   clk_data->clk_data.clks = clk_table;
>   clk_data->clk_data.clk_num = nr_clks;
>   of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
>   return clk_data;
> -err_data:
> +free_clk_data:
>   kfree(clk_data);
> -err:
> +unmap_io:
> + iounmap(base);
>   return NULL;
>  }
>  EXPORT_SYMBOL_GPL(hisi_clk_init);
> 


Re: [PATCH] clk: hisilicon: Fix the memory leak issues

2020-11-09 Thread Dongjiu Geng
On 2020/11/8 21:55, Markus Elfring wrote:
>> When return errors, …
> 
> I would find an other wording more appropriate for this change description.
> 
> 
>> …, so fix this issue.
> 
> I suggest to replace this information by an other imperative wording
> and the tag “Fixes”.

OK, done, I have submitted the version 2 patch

> 
> 
> …
>> +++ b/drivers/clk/hisilicon/clk-hi3620.c
>> @@ -463,12 +463,16 @@ static void __init hi3620_mmc_clk_init(struct 
>> device_node *node)
>>  }
>>
>>  clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
>> -if (WARN_ON(!clk_data))
>> +if (WARN_ON(!clk_data)) {
>> +iounmap(base);
> 
> Can a statement like “goto unmap_io;” make sense here?
OK, I have changed it.

> 
> 
>>  return;
>> +}
>>
>>  clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL);
>> -if (!clk_data->clks)
>> +if (!clk_data->clks) {
> 
> How do you think about to add the function call “kfree(clk_data)” in this if 
> branch?
OK, I have changed it.

> 
> 
> …
>> +++ b/drivers/clk/hisilicon/clk.c
> …
>   if (!base) {
>   pr_err("%s: failed to map clock registers\n", __func__);
> - goto err;
> + return NULL;
> 
> 
>> @@ -69,8 +69,10 @@ struct hisi_clock_data *hisi_clk_init(struct device_node 
>> *np,
>>  }
>>
>>  clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
>> -if (!clk_data)
>> +if (!clk_data) {
>> +iounmap(base);
>>  goto err;
> 
> Please use another jump target.
OK, thanks, I have changed it.

> 
> 
>> @@ -82,6 +84,7 @@ struct hisi_clock_data *hisi_clk_init(struct device_node 
>> *np,
>>  of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
>>  return clk_data;
>>  err_data:
>> +iounmap(base);
>>  kfree(clk_data);
>>  err:
>>  return NULL;
> 
> I propose to apply the following code variant.
OK, have modified.

> 
>   return clk_data;
> 
> free_clk_data:
>   kfree(clk_data);
> unmap_io:
>   iounmap(base);
>   return NULL;
> 
> 
> Regards,
> Markus
> .
> 


[PATCH V2] clk: hisilicon: Free clk_data and unmap region obtained by of_iomap

2020-11-09 Thread Dongjiu Geng
Free memory mapping and free clk_data, if clock initialization
is not successful.

Fixes: 75af25f581b1 ("clk: hisi: remove static variable")
Fixes: 62ac983b6141 ("clk: hisilicon: add hi3620_mmc_clks")
Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/clk-hi3620.c |  8 ++--
 drivers/clk/hisilicon/clk.c| 11 ++-
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/hisilicon/clk-hi3620.c 
b/drivers/clk/hisilicon/clk-hi3620.c
index a3d04c7c3da8..864d2ddfc73c 100644
--- a/drivers/clk/hisilicon/clk-hi3620.c
+++ b/drivers/clk/hisilicon/clk-hi3620.c
@@ -464,11 +464,11 @@ static void __init hi3620_mmc_clk_init(struct device_node 
*node)
 
clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
if (WARN_ON(!clk_data))
-   return;
+   goto unmap_io;
 
clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL);
if (!clk_data->clks)
-   return;
+   goto free_clk_data;
 
for (i = 0; i < num; i++) {
struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
@@ -478,6 +478,10 @@ static void __init hi3620_mmc_clk_init(struct device_node 
*node)
 
clk_data->clk_num = num;
of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+free_clk_data:
+   kfree(clk_data);
+unmap_io:
+   iounmap(base);
 }
 
 CLK_OF_DECLARE(hi3620_mmc_clk, "hisilicon,hi3620-mmc-clock", 
hi3620_mmc_clk_init);
diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index 54d9fdc93599..da655683710f 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -65,25 +65,26 @@ struct hisi_clock_data *hisi_clk_init(struct device_node 
*np,
base = of_iomap(np, 0);
if (!base) {
pr_err("%s: failed to map clock registers\n", __func__);
-   goto err;
+   return NULL;
}
 
clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
if (!clk_data)
-   goto err;
+   goto unmap_io;
 
clk_data->base = base;
clk_table = kcalloc(nr_clks, sizeof(*clk_table), GFP_KERNEL);
if (!clk_table)
-   goto err_data;
+   goto free_clk_data;
 
clk_data->clk_data.clks = clk_table;
clk_data->clk_data.clk_num = nr_clks;
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
return clk_data;
-err_data:
+free_clk_data:
kfree(clk_data);
-err:
+unmap_io:
+   iounmap(base);
return NULL;
 }
 EXPORT_SYMBOL_GPL(hisi_clk_init);
-- 
2.17.1



[PATCH] clk: hisilicon: Fix the memory leak issues

2020-11-06 Thread Dongjiu Geng
When return errors, the clock driver does not unmap
the mapped memory, so fix this issue.

Signed-off-by: Dongjiu Geng 
---
 drivers/clk/hisilicon/clk-hi3620.c | 8 ++--
 drivers/clk/hisilicon/clk.c| 5 -
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/hisilicon/clk-hi3620.c 
b/drivers/clk/hisilicon/clk-hi3620.c
index a3d04c7c3da8..d5f1a8df4b1c 100644
--- a/drivers/clk/hisilicon/clk-hi3620.c
+++ b/drivers/clk/hisilicon/clk-hi3620.c
@@ -463,12 +463,16 @@ static void __init hi3620_mmc_clk_init(struct device_node 
*node)
}
 
clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
-   if (WARN_ON(!clk_data))
+   if (WARN_ON(!clk_data)) {
+   iounmap(base);
return;
+   }
 
clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL);
-   if (!clk_data->clks)
+   if (!clk_data->clks) {
+   iounmap(base);
return;
+   }
 
for (i = 0; i < num; i++) {
struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index 54d9fdc93599..53acaff32934 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -69,8 +69,10 @@ struct hisi_clock_data *hisi_clk_init(struct device_node *np,
}
 
clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL);
-   if (!clk_data)
+   if (!clk_data) {
+   iounmap(base);
goto err;
+   }
 
clk_data->base = base;
clk_table = kcalloc(nr_clks, sizeof(*clk_table), GFP_KERNEL);
@@ -82,6 +84,7 @@ struct hisi_clock_data *hisi_clk_init(struct device_node *np,
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
return clk_data;
 err_data:
+   iounmap(base);
kfree(clk_data);
 err:
return NULL;
-- 
2.17.1



Re: Using fixed LPI number for some Device ID

2020-11-02 Thread Dongjiu Geng
On 2020/10/31 17:55, Marc Zyngier wrote:
> Dongjiu,
> 
> On Sat, 31 Oct 2020 02:19:19 +,
> Dongjiu Geng  wrote:
>>
>> Hi Marc,
>> Sorry to disturb you, Currently the LPI number is not fixed for the
>> device. The LPI number is dynamically allocated start from 8092.
>> For two OS which shares the ITS, One OS needs to configure the
>> device interrupt required by another OS, and the other OS uses a
>> fixed interrupt ID to respond the interrupt. Therefore, the LPI IRQ
>> number of the device needed be fixed. I want to upstream this
>> feature that allocate fixed LPI number for the device that is
>> specified through the DTS. What is your meaning?  Thanks
> 
> I think you are starting from the wrong premises.
> 
> You can't "share" an ITS directly between two operating systems. The
> ITS can only be controlled by a single operating system, because its
> function goes way beyond allocating an LPI. How would you deal with
> simple things such as masking an interrupt, which requires:
> 
> - Access to memory (configuration table)
> - Access to the command queue (to insert an invalidation command)
> - Access to MMIO registers (to kick the command queue into action)
> 
> all of which needs to be exclusive of concurrent modifications. How do
> you propose this is implemented in a safe manner by two operating
> systems which, by nature, distrust each other? Allocating LPIs is the
> least of your problems, really.
Yes, I agree with you it . But in my HW platform, using virtualization, the 
performance
deteriorates greatly.  So I distributed the I/O devices to different operation 
systems. During the startup of one OS,
interrupts are bound to different OS in one OS, which can be exclusive of 
concurrent modifications.

In fact it has some limitations as you said, such mask/enable/route Interrupts, 
If want to
mask interrupts, need to mask interrupts on the source device.

If you think it is not a common feature, I will used it as a local 
customization function and not upstream.

> 
> If you need two concurrent OSs taking interrupts, use virtualization.
> That is its purpose. On your HW, you'll even get direct injection.
> 
> Thanks,
> 
>   M.
> 


Re: Using fixed LPI number for some Device ID

2020-11-02 Thread Dongjiu Geng
On 2020/10/31 17:58, Marc Zyngier wrote:
> On Sat, 31 Oct 2020 03:10:24 +,
> Dongjiu Geng  wrote:
> 
> [...]
> 
>>   Sorry for the noise, Because Marc rarely uses the ARM email address,
>>   so I replace to use Marc's kernel.org address instead of ARM email address.
> Rarely is quite the understatement. I left ARM over a year ago, so the
> likelihood of me answering at this address in vanishingly small.

 Thanks for the clarification.

> 
> Maybe in a parallel universe? ;-)
> 
>   M.
> 
> -- Without deviation from the norm, progress is not possible. .


Re: Using fixed LPI number for some Device ID

2020-10-30 Thread Dongjiu Geng
On 2020/10/31 10:59, Thomas Gleixner wrote:
> On Sat, Oct 31 2020 at 10:19, Dongjiu Geng wrote:
>>  Hi Marc,
>> Sorry to disturb you, Currently the LPI number is not fixed for
>>  the device. The LPI number is dynamically allocated start from 8092.
>>  For two OS which shares the ITS, One OS needs to configure the device
>>  interrupt required by another OS, and the other OS uses a fixed
>>  interrupt ID to respond the interrupt. Therefore, the LPI IRQ number
>>  of the device needed be fixed. I want to upstream this feature that
>>  allocate fixed LPI number for the device that is specified through
>>  the DTS. What is your meaning?  Thanks
> 
> What's the purpose of resending the same thing within less than 24
> hours? Do you really expect maintainers to be available 24/7 and being
  Sorry for the noise, Because Marc rarely uses the ARM email address,
  so I replace to use Marc's kernel.org address instead of ARM email address.



> able to respond within less than a day?
> 
> 
> .
> 


Re: Using fixed LPI number for some Device ID

2020-10-30 Thread Dongjiu Geng
 Hi Marc,
Sorry to disturb you, Currently the LPI number is not fixed for the device. 
The LPI number is dynamically allocated start from 8092.
 For two OS which shares the ITS, One OS needs to configure the device 
interrupt required by another OS, and the other OS uses a fixed interrupt
 ID to respond the interrupt. Therefore, the LPI IRQ number of the device 
needed be fixed. I want to upstream this feature that allocate fixed
 LPI number for the device that is specified through the DTS. What is your 
meaning?  Thanks


Using fixed LPI number for some Device ID

2020-10-30 Thread Dongjiu Geng
Hi Marc,
   Sorry to disturb you, Currently the LPI number is not fixed for the device. 
The LPI number is dynamically allocated start from 8092.
For two OS which shares the ITS, One OS needs to configure the device interrupt 
required by another OS, and the other OS uses a fixed interrupt
ID to respond the interrupt. Therefore, the LPI IRQ number of the device needed 
be fixed. I want to upstream this feature that allocate fixed
LPI number for the device that is specified through the DTS. do you agree?  
Thanks!


Re: Adjust interrupt Priority for ARM64 GIC

2020-09-01 Thread Dongjiu Geng



On 2020/9/1 15:48, Marc Zyngier wrote:
> Hi Dongjiu,
> 
> In the future, please use my kernel.org address, as I don't work
> for ARM anymore, and would have missed this email if I wasn't pointed
> to it.
> 
> On 2020-08-14 18:10, Dongjiu Geng wrote:
>> Hi Marc,
>>    In the Linux kernel, we can not adjust the  interrupt Priority, For
>> all the interrupts, the interrupt Priority are fixed to 0xa0.
>> In some scenarios, it needs to change the Priority. so I want to
>> upstream a serie patch to support to change the Priority through
>> procfs. do you agree I upstream this feature? thanks~
> 
> No, that's not something I would ever consider, and for multiple
> reasons:
> 
> - Linux only supports a single priority, meaning that interrupts are
>   themselves aren't preemptable. Dealing with things like (pseudo) NMI
>   is invasive enough, and I can't see a good reason to relax the
>   single priority requirement.
> 
> - Building on top of the above, the whole scheduler and locking model
>   relies on the non-preemptable property of an interrupt.
> 
> - I cannot see a good reason to leave the priority control to userspace.
>   That's a sure recipe for userspace-controlled livelocks.
> 
> Now, I'm sure you want to introduce this for a reason, and you are not
> explaining it ("some scenarios" doesn't quite cut it). If you care to
> explain these "scenarios", maybe there is something we can do.
Marc,
Thanks for answer.
In the real-time system(RTOS), we want the timer tick irq is responded as
soon as possible to trigger kernel do task schedule. Non-preemptable  IRQ 
decreases the Real-Time Performance of Real-Time Operating System

> 
> But please don't waste time implementing any sort of priority change,
> there is no way I'll consider it as such.
> 
> Thanks,
> 
>     M.


[PATCH v2] sched: Add trace for task wake up latency and leave running time

2020-08-21 Thread Dongjiu Geng
1) The perf event sched_switch is used to record scheduling tracks,
   which consumes a large amount of CPU resources and disk space.
   Therefore, a mechanism is required to record only the scheduling
   delay greater than a certain threshold. This patch supports this
   feature. For example, if the threshold is 10 ms, you can run the
   following command to only record the scheduling track with the
   scheduling delay greater than 10 ms.

   echo 'time > 1000' > 
/sys/kernel/debug/tracing/events/sched/sched_wakeup_latency/filter
   echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup_latency/enable

2) Similarly, when tune performance, we usually want to know which
   tasks are not running for a long time that is greater than a
   certain threshold, Use the following commands can easily implement
   it.

   echo 'time > 1000' > 
/sys/kernel/debug/tracing/events/sched/sched_leave_running_time/filter
   echo 1 > 
/sys/kernel/debug/tracing/events/sched/sched_leave_running_time/enable

Signed-off-by: Dongjiu Geng 
---
 include/linux/sched.h|  7 
 include/trace/events/sched.h | 66 
 kernel/sched/core.c  | 20 +++
 3 files changed, 93 insertions(+)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 93ecd930efd3..edb622c40a90 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1324,6 +1324,13 @@ struct task_struct {
/* CPU-specific state of this task: */
struct thread_structthread;
 
+   /* Task wake up time stamp */
+   u64 ts_wakeup;
+   /* Previous task switch out time stamp */
+   u64 pre_ts_end;
+   /* Next task switch in time stamp */
+   u64 next_ts_start;
+   boolwakeup_state;
/*
 * WARNING: on x86, 'thread_struct' contains a variable-sized
 * structure.  It *MUST* be at the end of 'task_struct'.
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index fec25b9cfbaf..e99c6d573a42 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -183,6 +183,72 @@ TRACE_EVENT(sched_switch,
__entry->next_comm, __entry->next_pid, __entry->next_prio)
 );
 
+DECLARE_EVENT_CLASS(sched_latency_template,
+
+   TP_PROTO(bool preempt,
+struct task_struct *prev,
+struct task_struct *next,
+u64 time),
+
+   TP_ARGS(preempt, prev, next, time),
+
+   TP_STRUCT__entry(
+   __array(char,   prev_comm,  TASK_COMM_LEN   )
+   __field(pid_t,  prev_pid)
+   __field(int,prev_prio   )
+   __field(long,   prev_state  )
+   __array(char,   next_comm,  TASK_COMM_LEN   )
+   __field(pid_t,  next_pid)
+   __field(int,next_prio   )
+   __field(u64,time)
+   ),
+
+   TP_fast_assign(
+   memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
+   __entry->prev_pid   = prev->pid;
+   __entry->prev_prio  = prev->prio;
+   __entry->prev_state = __trace_sched_switch_state(preempt, 
prev);
+   memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
+   __entry->next_pid   = next->pid;
+   __entry->next_prio  = next->prio;
+   __entry->time   = time;
+   /* XXX SCHED_DEADLINE */
+   ),
+
+   TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s%s ==> 
next_comm=%s next_pid=%d next_prio=%d passed time=%llu (ns)",
+   __entry->prev_comm, __entry->prev_pid, __entry->prev_prio,
+
+   (__entry->prev_state & (TASK_REPORT_MAX - 1)) ?
+ __print_flags(__entry->prev_state & (TASK_REPORT_MAX - 1), 
"|",
+   { TASK_INTERRUPTIBLE, "S" },
+   { TASK_UNINTERRUPTIBLE, "D" },
+   { __TASK_STOPPED, "T" },
+   { __TASK_TRACED, "t" },
+   { EXIT_DEAD, "X" },
+   { EXIT_ZOMBIE, "Z" },
+   { TASK_PARKED, "P" },
+   { TASK_DEAD, "I" }) :
+ "R",
+
+   __entry->prev_state & TASK_REPORT_MAX ? "+" : "",
+   __entry->next_comm

[PATCH] sched: Add trace for task wake up latency and leave running time

2020-08-21 Thread Dongjiu Geng
1) The perf event sched_switch is used to record scheduling tracks,
   which consumes a large amount of CPU resources and disk space.
   Therefore, a mechanism is required to record only the scheduling
   delay greater than a certain threshold. This patch supports this
   feature. For example, if the threshold is 10 ms, you can run the
   following command to only record the scheduling track with the
   scheduling delay greater than 10 ms.

   echo 'time > 1000' > 
/sys/kernel/debug/tracing/events/sched/sched_wakeup_latency/filter
   echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup_latency/enable

2) Similarly, when tune performance, we usually want to know which
   tasks are not running for a long time, Use the following methods
   to save CPU overhead and storage space.

   echo 'time > 1000' > 
/sys/kernel/debug/tracing/events/sched/sched_leave_running_time/filter
   echo 1 > 
/sys/kernel/debug/tracing/events/sched/sched_leave_running_time/enable

Signed-off-by: Dongjiu Geng 
---
 include/linux/sched.h|  7 
 include/trace/events/sched.h | 66 
 kernel/sched/core.c  | 20 +++
 3 files changed, 93 insertions(+)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 93ecd930efd3..edb622c40a90 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1324,6 +1324,13 @@ struct task_struct {
/* CPU-specific state of this task: */
struct thread_structthread;
 
+   /* Task wake up time stamp */
+   u64 ts_wakeup;
+   /* Previous task switch out time stamp */
+   u64 pre_ts_end;
+   /* Next task switch in time stamp */
+   u64 next_ts_start;
+   boolwakeup_state;
/*
 * WARNING: on x86, 'thread_struct' contains a variable-sized
 * structure.  It *MUST* be at the end of 'task_struct'.
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index fec25b9cfbaf..e99c6d573a42 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -183,6 +183,72 @@ TRACE_EVENT(sched_switch,
__entry->next_comm, __entry->next_pid, __entry->next_prio)
 );
 
+DECLARE_EVENT_CLASS(sched_latency_template,
+
+   TP_PROTO(bool preempt,
+struct task_struct *prev,
+struct task_struct *next,
+u64 time),
+
+   TP_ARGS(preempt, prev, next, time),
+
+   TP_STRUCT__entry(
+   __array(char,   prev_comm,  TASK_COMM_LEN   )
+   __field(pid_t,  prev_pid)
+   __field(int,prev_prio   )
+   __field(long,   prev_state  )
+   __array(char,   next_comm,  TASK_COMM_LEN   )
+   __field(pid_t,  next_pid)
+   __field(int,next_prio   )
+   __field(u64,time)
+   ),
+
+   TP_fast_assign(
+   memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN);
+   __entry->prev_pid   = prev->pid;
+   __entry->prev_prio  = prev->prio;
+   __entry->prev_state = __trace_sched_switch_state(preempt, 
prev);
+   memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN);
+   __entry->next_pid   = next->pid;
+   __entry->next_prio  = next->prio;
+   __entry->time   = time;
+   /* XXX SCHED_DEADLINE */
+   ),
+
+   TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s%s ==> 
next_comm=%s next_pid=%d next_prio=%d passed time=%llu (ns)",
+   __entry->prev_comm, __entry->prev_pid, __entry->prev_prio,
+
+   (__entry->prev_state & (TASK_REPORT_MAX - 1)) ?
+ __print_flags(__entry->prev_state & (TASK_REPORT_MAX - 1), 
"|",
+   { TASK_INTERRUPTIBLE, "S" },
+   { TASK_UNINTERRUPTIBLE, "D" },
+   { __TASK_STOPPED, "T" },
+   { __TASK_TRACED, "t" },
+   { EXIT_DEAD, "X" },
+   { EXIT_ZOMBIE, "Z" },
+   { TASK_PARKED, "P" },
+   { TASK_DEAD, "I" }) :
+ "R",
+
+   __entry->prev_state & TASK_REPORT_MAX ? "+" : "",
+   __entry->next_comm, __entry->next_pid, __entry

Adjust interrupt Priority for ARM64 GIC

2020-08-14 Thread Dongjiu Geng
Hi Marc,
   In the Linux kernel, we can not adjust the  interrupt Priority, For all the 
interrupts, the interrupt Priority are fixed to 0xa0.
In some scenarios, it needs to change the Priority. so I want to upstream a 
serie patch to support to change the Priority through procfs. do you agree I 
upstream this feature? thanks~


[RFC RESEND PATCH] kvm: arm64: export memory error recovery capability to user space

2018-12-14 Thread Dongjiu Geng
When user space do memory recovery, it will check whether KVM and
guest support the error recovery, only when both of them support,
user space will do the error recovery. This patch exports this
capability of KVM to user space.

Cc: Peter Maydell 
Signed-off-by: Dongjiu Geng 
---
User space needs to check this capability of KVM is suggested by Peter[1],
this patch as RFC tag because user space patches are still under review,
so this kernel patch is firstly sent out for review.

[1]: https://patchwork.codeaurora.org/patch/652261/
---
 Documentation/virtual/kvm/api.txt | 9 +
 arch/arm64/kvm/reset.c| 1 +
 include/uapi/linux/kvm.h  | 1 +
 3 files changed, 11 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index cd209f7..241e2e2 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -4895,3 +4895,12 @@ Architectures: x86
 This capability indicates that KVM supports paravirtualized Hyper-V IPI send
 hypercalls:
 HvCallSendSyntheticClusterIpi, HvCallSendSyntheticClusterIpiEx.
+
+8.21 KVM_CAP_ARM_MEMORY_ERROR_RECOVERY
+
+Architectures: arm, arm64
+
+This capability indicates that guest memory error can be detected by the KVM 
which
+supports the error recovery. When user space do recovery, such as QEMU, it will
+check whether KVM and guest support memory error recovery, only when both of 
them
+support, user space will do the error recovery.
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index b72a3dd..90d1d9a 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -82,6 +82,7 @@ int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long 
ext)
r = kvm_arm_support_pmu_v3();
break;
case KVM_CAP_ARM_INJECT_SERROR_ESR:
+   case KVM_CAP_ARM_MEMORY_ERROR_RECOVERY:
r = cpus_have_const_cap(ARM64_HAS_RAS_EXTN);
break;
case KVM_CAP_SET_GUEST_DEBUG:
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 2b7a652..3b19580 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -975,6 +975,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_HYPERV_ENLIGHTENED_VMCS 163
 #define KVM_CAP_EXCEPTION_PAYLOAD 164
 #define KVM_CAP_ARM_VM_IPA_SIZE 165
+#define KVM_CAP_ARM_MEMORY_ERROR_RECOVERY 166
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.7.4



[PATCH RFC] kvm: arm64: export memory error recovery capability to user space

2018-12-13 Thread Dongjiu Geng
When user space do memory recovery, it will check whether KVM and
guest support the error recovery, only when both of them support,
user space will do the error recovery. This patch exports this
capability of KVM to user space.

Cc: Peter Maydell 
Signed-off-by: Dongjiu Geng 
---
User space needs to check this capability of KVM is suggested by Peter[1],
this patch as RFC tag because user space patches are still under review,
so this kernel patch is firstly sent out for review.

[1]: https://patchwork.codeaurora.org/patch/652261/
---
 Documentation/virtual/kvm/api.txt | 9 +
 arch/arm64/kvm/reset.c| 1 +
 include/uapi/linux/kvm.h  | 1 +
 3 files changed, 11 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index cd209f7..241e2e2 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -4895,3 +4895,12 @@ Architectures: x86
 This capability indicates that KVM supports paravirtualized Hyper-V IPI send
 hypercalls:
 HvCallSendSyntheticClusterIpi, HvCallSendSyntheticClusterIpiEx.
+
+8.21 KVM_CAP_ARM_MEMORY_ERROR_RECOVERY
+
+Architectures: arm, arm64
+
+This capability indicates that guest memory error can be detected by the KVM 
which
+supports the error recovery. When user space do recovery, such as QEMU, it will
+check whether KVM and guest support memory error recovery, only when both of 
them
+support, user space will do the error recovery.
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index b72a3dd..90d1d9a 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -82,6 +82,7 @@ int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long 
ext)
r = kvm_arm_support_pmu_v3();
break;
case KVM_CAP_ARM_INJECT_SERROR_ESR:
+   case KVM_CAP_ARM_MEMORY_ERROR_RECOVERY:
r = cpus_have_const_cap(ARM64_HAS_RAS_EXTN);
break;
case KVM_CAP_SET_GUEST_DEBUG:
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 2b7a652..3b19580 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -975,6 +975,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_HYPERV_ENLIGHTENED_VMCS 163
 #define KVM_CAP_EXCEPTION_PAYLOAD 164
 #define KVM_CAP_ARM_VM_IPA_SIZE 165
+#define KVM_CAP_ARM_MEMORY_ERROR_RECOVERY 166
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.7.4



[PATCH v3 0/2] rename function name and enable 32bit vcpu events

2018-10-11 Thread Dongjiu Geng
Rename the kvm_arch_dev_ioctl_check_extension() to 
kvm_arch_vm_ioctl_check_extension, because the name
is not reasonable; 

Enable the 32 bit vcpu events support.

Change since v2:
1. Address Suzuki's comments to update the patch commit messages

change since v1:
1. Update patch commit messages.

Dongjiu Geng (2):
  arm/arm64: KVM: rename function kvm_arch_dev_ioctl_check_extension()
  arm/arm64: KVM: enable 32 bits kvm vcpu events support

 arch/arm/include/asm/kvm_host.h   | 2 +-
 arch/arm64/include/asm/kvm_host.h | 2 +-
 arch/arm64/kvm/reset.c| 5 ++---
 virt/kvm/arm/arm.c| 3 ++-
 4 files changed, 6 insertions(+), 6 deletions(-)

-- 
1.9.1



[PATCH v3 1/2] arm/arm64: KVM: rename function kvm_arch_dev_ioctl_check_extension()

2018-10-11 Thread Dongjiu Geng
Rename kvm_arch_dev_ioctl_check_extension() to
kvm_arch_vm_ioctl_check_extension(), because it does
not have any relationship with device.

Renaming this function can make code readable.

Cc: James Morse 
Reviewed-by: Suzuki K Poulose 
Signed-off-by: Dongjiu Geng 
---
I remeber James also mentioned that rename this function.
---
 arch/arm/include/asm/kvm_host.h   | 2 +-
 arch/arm64/include/asm/kvm_host.h | 2 +-
 arch/arm64/kvm/reset.c| 4 ++--
 virt/kvm/arm/arm.c| 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 3ad482d..3ee29db 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -273,7 +273,7 @@ static inline void __cpu_init_stage2(void)
kvm_call_hyp(__init_stage2_translation);
 }
 
-static inline int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
+static inline int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 {
return 0;
 }
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 3d6d733..c20537f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -53,7 +53,7 @@
 
 int __attribute_const__ kvm_target_cpu(void);
 int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
-int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext);
+int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext);
 void __extended_idmap_trampoline(phys_addr_t boot_pgd, phys_addr_t 
idmap_start);
 
 struct kvm_arch {
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index e37c78b..fd37c53 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -55,12 +55,12 @@ static bool cpu_has_32bit_el1(void)
 }
 
 /**
- * kvm_arch_dev_ioctl_check_extension
+ * kvm_arch_vm_ioctl_check_extension
  *
  * We currently assume that the number of HW registers is uniform
  * across all CPUs (see cpuinfo_sanity_check).
  */
-int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
+int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 {
int r;
 
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index c92053b..40e79ea 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -240,7 +240,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
r = 1;
break;
default:
-   r = kvm_arch_dev_ioctl_check_extension(kvm, ext);
+   r = kvm_arch_vm_ioctl_check_extension(kvm, ext);
break;
}
return r;
-- 
1.9.1



[PATCH v3 2/2] arm/arm64: KVM: enable 32 bits kvm vcpu events support

2018-10-11 Thread Dongjiu Geng
The commit 539aee0edb9f ("KVM: arm64: Share the parts of
get/set events useful to 32bit") shares the get/set events
helper for arm64 and arm32, it is better also share the check
for vcpu events capability to enable 32 bit kvm vcpu events
support.

User space will check whether KVM supports vcpu events by checking
the KVM_CAP_VCPU_EVENTS extension

Cc: James Morse 
Reviewed-by : Suzuki K Poulose 
Signed-off-by: Dongjiu Geng 
---
For the 32 bits kvm migration, it needs to enable the vcpu events,
this patch will enable it. The user space QEMU patch is here:
https://patchwork.ozlabs.org/patch/975615/
---
 arch/arm64/kvm/reset.c | 1 -
 virt/kvm/arm/arm.c | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index fd37c53..e50245e 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -82,7 +82,6 @@ int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long 
ext)
break;
case KVM_CAP_SET_GUEST_DEBUG:
case KVM_CAP_VCPU_ATTRIBUTES:
-   case KVM_CAP_VCPU_EVENTS:
r = 1;
break;
default:
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 40e79ea..64e5d97 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -212,6 +212,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_READONLY_MEM:
case KVM_CAP_MP_STATE:
case KVM_CAP_IMMEDIATE_EXIT:
+   case KVM_CAP_VCPU_EVENTS:
r = 1;
break;
case KVM_CAP_ARM_SET_DEVICE_ADDR:
-- 
1.9.1



[PATCH RESEND v3] arm64: clean the additional checks before calling ghes_notify_sea()

2018-08-10 Thread Dongjiu Geng
In order to remove the additional check before calling the
ghes_notify_sea(), make stub definition when !CONFIG_ACPI_APEI_SEA.

After this cleanup, we can simply call the ghes_notify_sea() to let
APEI driver handle the SEA notification.

CC: Tyler Baicar 
CC: James Morse 
Signed-off-by: Dongjiu Geng 
Acked-by: Will Deacon 
Reviewed-by: Tyler Baicar 
---
This cleanup is ever mentioned by Mark Rutland in [1]

[1]:
https://lkml.org/lkml/2018/5/31/289

change since v2:
1. Add 'Reviewed-by' of Tyler

change since v1:
1. Update the commit messages
2. CC Tyler and James
3. Add 'Acked-by' of Will
---
 arch/arm64/mm/fault.c | 7 +--
 include/acpi/ghes.h   | 4 
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index b8eecc7..9ffe01d 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -727,12 +727,7 @@ static int do_sea(unsigned long addr, unsigned int esr, 
struct pt_regs *regs)
 
 int handle_guest_sea(phys_addr_t addr, unsigned int esr)
 {
-   int ret = -ENOENT;
-
-   if (IS_ENABLED(CONFIG_ACPI_APEI_SEA))
-   ret = ghes_notify_sea();
-
-   return ret;
+   return ghes_notify_sea();
 }
 
 asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 1624e2b..82cb4eb 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -118,6 +118,10 @@ static inline void *acpi_hest_get_next(struct 
acpi_hest_generic_data *gdata)
 (void *)section - (void *)(estatus + 1) < estatus->data_length; \
 section = acpi_hest_get_next(section))
 
+#ifdef CONFIG_ACPI_APEI_SEA
 int ghes_notify_sea(void);
+#else
+static inline int ghes_notify_sea(void) { return -ENOENT; }
+#endif
 
 #endif /* GHES_H */
-- 
1.9.1




[PATCH RESEND v2] arm64: clean the additional checks before calling ghes_notify_sea()

2018-08-07 Thread Dongjiu Geng
In order to remove the additional check before calling the
ghes_notify_sea(), make stub definition when !CONFIG_ACPI_APEI_SEA.

After this cleanup, we can simply call the ghes_notify_sea() to let
APEI driver handle the SEA notification.

CC: Tyler Baicar 
CC: James Morse 
Signed-off-by: Dongjiu Geng 
Acked-by: Will Deacon 
---
This cleanup is ever mentioned by Mark Rutland in [1]

[1]:
https://lkml.org/lkml/2018/5/31/289

Change since v1:
1. Update the commit messages
2. CC Tyler and James
3. Add Acked-by of Will
---
 arch/arm64/mm/fault.c | 7 +--
 include/acpi/ghes.h   | 4 
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index b8eecc7..9ffe01d 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -727,12 +727,7 @@ static int do_sea(unsigned long addr, unsigned int esr, 
struct pt_regs *regs)
 
 int handle_guest_sea(phys_addr_t addr, unsigned int esr)
 {
-   int ret = -ENOENT;
-
-   if (IS_ENABLED(CONFIG_ACPI_APEI_SEA))
-   ret = ghes_notify_sea();
-
-   return ret;
+   return ghes_notify_sea();
 }
 
 asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 1624e2b..82cb4eb 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -118,6 +118,10 @@ static inline void *acpi_hest_get_next(struct 
acpi_hest_generic_data *gdata)
 (void *)section - (void *)(estatus + 1) < estatus->data_length; \
 section = acpi_hest_get_next(section))
 
+#ifdef CONFIG_ACPI_APEI_SEA
 int ghes_notify_sea(void);
+#else
+static inline int ghes_notify_sea(void) { return -ENOENT; }
+#endif
 
 #endif /* GHES_H */
-- 
1.9.1



[PATCH] arm64: clean the additional checks before calling ghes_notify_sea()

2018-07-26 Thread Dongjiu Geng
In order to remove the additional check before calling the
ghes_notify_sea(), make stub definition when !CONFIG_ACPI_APEI_SEA.

Signed-off-by: Dongjiu Geng 
---

This cleanup is ever mentioned by Mark Rutland in [1]

[1]:
https://lkml.org/lkml/2018/5/31/289
---
 arch/arm64/mm/fault.c | 7 +--
 include/acpi/ghes.h   | 4 
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index b8eecc7..9ffe01d 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -727,12 +727,7 @@ static int do_sea(unsigned long addr, unsigned int esr, 
struct pt_regs *regs)
 
 int handle_guest_sea(phys_addr_t addr, unsigned int esr)
 {
-   int ret = -ENOENT;
-
-   if (IS_ENABLED(CONFIG_ACPI_APEI_SEA))
-   ret = ghes_notify_sea();
-
-   return ret;
+   return ghes_notify_sea();
 }
 
 asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 1624e2b..82cb4eb 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -118,6 +118,10 @@ static inline void *acpi_hest_get_next(struct 
acpi_hest_generic_data *gdata)
 (void *)section - (void *)(estatus + 1) < estatus->data_length; \
 section = acpi_hest_get_next(section))
 
+#ifdef CONFIG_ACPI_APEI_SEA
 int ghes_notify_sea(void);
+#else
+static inline int ghes_notify_sea(void) { return -ENOENT; }
+#endif
 
 #endif /* GHES_H */
-- 
1.9.1



[PATCH] arm64: clean the additional checks before calling ghes_notify_sea()

2018-07-26 Thread Dongjiu Geng
In order to remove the additional check before calling the
ghes_notify_sea(), make stub definition when !CONFIG_ACPI_APEI_SEA.

Signed-off-by: Dongjiu Geng 
---

This cleanup is ever mentioned by Mark Rutland in [1]

[1]:
https://lkml.org/lkml/2018/5/31/289
---
 arch/arm64/mm/fault.c | 7 +--
 include/acpi/ghes.h   | 4 
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index b8eecc7..9ffe01d 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -727,12 +727,7 @@ static int do_sea(unsigned long addr, unsigned int esr, 
struct pt_regs *regs)
 
 int handle_guest_sea(phys_addr_t addr, unsigned int esr)
 {
-   int ret = -ENOENT;
-
-   if (IS_ENABLED(CONFIG_ACPI_APEI_SEA))
-   ret = ghes_notify_sea();
-
-   return ret;
+   return ghes_notify_sea();
 }
 
 asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 1624e2b..82cb4eb 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -118,6 +118,10 @@ static inline void *acpi_hest_get_next(struct 
acpi_hest_generic_data *gdata)
 (void *)section - (void *)(estatus + 1) < estatus->data_length; \
 section = acpi_hest_get_next(section))
 
+#ifdef CONFIG_ACPI_APEI_SEA
 int ghes_notify_sea(void);
+#else
+static inline int ghes_notify_sea(void) { return -ENOENT; }
+#endif
 
 #endif /* GHES_H */
-- 
1.9.1



[PATCH v5 1/2] arm/arm64: KVM: Add KVM_GET/SET_VCPU_EVENTS

2018-06-25 Thread Dongjiu Geng
For the migrating VMs, user space may need to know the exception
state. For example, in the machine A, KVM make an SError pending,
when migrate to B, KVM also needs to pend an SError.

This new IOCTL exports user-invisible states related to SError.
Together with appropriate user space changes, user space can get/set
the SError exception state to do migrate/snapshot/suspend.

Signed-off-by: Dongjiu Geng 
---
change since v4:
Address Christoffer's comments, thanks Christoffer's review.
1. Change the 'Capebility' to 'Capability' to fix the typo issue
2. Not wrap the line below 80 chars on a single line in 
kvm_arm_vcpu_get_events()
3. Re-ordere the patch 1 and patch 2

Address Marc's comments, thanks Marc's review
1. Remove the "else" clause in kvm_arm_vcpu_get_events()
2. Check all the padding in the kvm_vcpu_events is set to zero

Address James's comments, thanks James's review
1. Change to "vcpu ioctl" to fix the documentation
2. Using __KVM_HAVE_VCPU_EVENTS to control ARM64 compilation
3. Check the padding[] and reserved[] are zero

Change since v3:
1. Fix the memset() issue in the kvm_arm_vcpu_get_events()

change since v2:
1. Add kvm_vcpu_events structure definition for arm platform to avoid the build 
errors.

change since v1:
Address Marc's comments, thanks Marc's review
1. serror_has_esr always true when ARM64_HAS_RAS_EXTN is set
2. remove Spurious blank line in kvm_arm_vcpu_set_events()
3. rename pend_guest_serror() to kvm_set_sei_esr()
4. Make kvm_arm_vcpu_get_events() did all the work rather than having this 
split responsibility.
5.  using sizeof(events) instead of sizeof(struct kvm_vcpu_events)

this series patch is separated from 
https://www.spinics.net/lists/kvm/msg168917.html
The user space patch is here: 
https://lists.gnu.org/archive/html/qemu-devel/2018-05/msg06965.html

change since V12:
1. change (vcpu->arch.hcr_el2 & HCR_VSE) to !!(vcpu->arch.hcr_el2 & HCR_VSE) in 
kvm_arm_vcpu_get_events()

Change since V11:
Address James's comments, thanks James
1. Align the struct of kvm_vcpu_events to 64 bytes
2. Avoid exposing the stale ESR value in the kvm_arm_vcpu_get_events()
3. Change variables 'injected' name to 'serror_pending' in the 
kvm_arm_vcpu_set_events()
4. Change to sizeof(events) from sizeof(struct kvm_vcpu_events) in 
kvm_arch_vcpu_ioctl()

Change since V10:
Address James's comments, thanks James
1. Merge the helper function with the user.
2. Move the ISS_MASK into pend_guest_serror() to clear top bits
3. Make kvm_vcpu_events struct align to 4 bytes
4. Add something check in the kvm_arm_vcpu_set_events()
5. Check kvm_arm_vcpu_get/set_events()'s return value.
6. Initialise kvm_vcpu_events to 0 so that padding transferred to user-space 
doesn't
   contain kernel stack.
---
 Documentation/virtual/kvm/api.txt| 33 +++
 arch/arm64/include/asm/kvm_emulate.h |  5 +
 arch/arm64/include/asm/kvm_host.h|  7 ++
 arch/arm64/include/uapi/asm/kvm.h| 13 +++
 arch/arm64/kvm/guest.c   | 43 
 arch/arm64/kvm/inject_fault.c|  6 ++---
 arch/arm64/kvm/reset.c   |  1 +
 virt/kvm/arm/arm.c   | 21 ++
 8 files changed, 122 insertions(+), 7 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 758bf40..3732097 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -835,11 +835,13 @@ struct kvm_clock_data {
 
 Capability: KVM_CAP_VCPU_EVENTS
 Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
-Type: vm ioctl
+Architectures: x86, arm64
+Type: vcpu ioctl
 Parameters: struct kvm_vcpu_event (out)
 Returns: 0 on success, -1 on error
 
+X86:
+
 Gets currently pending exceptions, interrupts, and NMIs as well as related
 states of the vcpu.
 
@@ -881,15 +883,32 @@ Only two fields are defined in the flags field:
 - KVM_VCPUEVENT_VALID_SMM may be set in the flags field to signal that
   smi contains a valid state.
 
+ARM64:
+
+Gets currently pending SError exceptions as well as related states of the vcpu.
+
+struct kvm_vcpu_events {
+   struct {
+   __u8 serror_pending;
+   __u8 serror_has_esr;
+   /* Align it to 8 bytes */
+   __u8 pad[6];
+   __u64 serror_esr;
+   } exception;
+   __u32 reserved[12];
+};
+
 4.32 KVM_SET_VCPU_EVENTS
 
 Capability: KVM_CAP_VCPU_EVENTS
 Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
-Type: vm ioctl
+Architectures: x86, arm64
+Type: vcpu ioctl
 Parameters: struct kvm_vcpu_event (in)
 Returns: 0 on success, -1 on error
 
+X86:
+
 Set pending exceptions, interrupts, and NMIs as well as related states of the
 vcpu.
 
@@ -910,6 +929,12 @@ shall be written into the VCPU.
 
 KVM_VCPUEVENT_VALID_SMM can only be set if KVM_CAP_X86_SMM is availabl

[PATCH] usb: xhci: remove the code build warning

2018-06-05 Thread Dongjiu Geng
Initialize the 'err' variate to remove the build warning,
the warning is shown as below:

drivers/usb/host/xhci-tegra.c: In function ‘tegra_xusb_mbox_thread’:
drivers/usb/host/xhci-tegra.c:552:6: warning: ‘err’ may be used uninitialized 
in this function [-Wuninitialized]
drivers/usb/host/xhci-tegra.c:482:6: note: ‘err’ was declared here

Signed-off-by: Dongjiu Geng 
---
How to reproduce:
1. make defconfig ARCH=arm
2. make -j100 CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm

Then you can see below warnings:
drivers/usb/host/xhci-tegra.c: In function ‘tegra_xusb_mbox_thread’:
drivers/usb/host/xhci-tegra.c:552:6: warning: ‘err’ may be used uninitialized 
in this function [-Wuninitialized]
drivers/usb/host/xhci-tegra.c:482:6: note: ‘err’ was declared here
---
 drivers/usb/host/xhci-tegra.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
index 2c076ea..1ed87ce 100644
--- a/drivers/usb/host/xhci-tegra.c
+++ b/drivers/usb/host/xhci-tegra.c
@@ -479,7 +479,7 @@ static void tegra_xusb_mbox_handle(struct tegra_xusb *tegra,
unsigned long mask;
unsigned int port;
bool idle, enable;
-   int err;
+   int err = 0;
 
memset(&rsp, 0, sizeof(rsp));
 
-- 
2.7.4



[PATCH v1 2/2] arm/arm64: KVM: Add KVM_GET/SET_VCPU_EVENTS

2018-05-30 Thread Dongjiu Geng
For the migrating VMs, user space may need to know the exception
state. For example, in the machine A, KVM make an SError pending,
when migrate to B, KVM also needs to pend an SError.

This new IOCTL exports user-invisible states related to SError.
Together with appropriate user space changes, user space can get/set
the SError exception state to do migrate/snapshot/suspend.

Signed-off-by: Dongjiu Geng 
--
this series patch is separated from 
https://www.spinics.net/lists/kvm/msg168917.html
change since V12:
1. change (vcpu->arch.hcr_el2 & HCR_VSE) to !!(vcpu->arch.hcr_el2 & HCR_VSE) in 
kvm_arm_vcpu_get_events()

Change since V11:
Address James's comments, thanks James
1. Align the struct of kvm_vcpu_events to 64 bytes
2. Avoid exposing the stale ESR value in the kvm_arm_vcpu_get_events()
3. Change variables 'injected' name to 'serror_pending' in the 
kvm_arm_vcpu_set_events()
4. Change to sizeof(events) from sizeof(struct kvm_vcpu_events) in 
kvm_arch_vcpu_ioctl()

Change since V10:
Address James's comments, thanks James
1. Merge the helper function with the user.
2. Move the ISS_MASK into pend_guest_serror() to clear top bits
3. Make kvm_vcpu_events struct align to 4 bytes
4. Add something check in the kvm_arm_vcpu_set_events()
5. Check kvm_arm_vcpu_get/set_events()'s return value.
6. Initialise kvm_vcpu_events to 0 so that padding transferred to user-space 
doesn't
   contain kernel stack.
---
 Documentation/virtual/kvm/api.txt| 31 ---
 arch/arm/include/asm/kvm_host.h  |  6 ++
 arch/arm/kvm/guest.c | 12 
 arch/arm64/include/asm/kvm_emulate.h |  5 +
 arch/arm64/include/asm/kvm_host.h|  7 +++
 arch/arm64/include/uapi/asm/kvm.h| 13 +
 arch/arm64/kvm/guest.c   | 36 
 arch/arm64/kvm/inject_fault.c|  7 ++-
 arch/arm64/kvm/reset.c   |  1 +
 virt/kvm/arm/arm.c   | 21 +
 10 files changed, 135 insertions(+), 4 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index fdac969..8896737 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -835,11 +835,13 @@ struct kvm_clock_data {
 
 Capability: KVM_CAP_VCPU_EVENTS
 Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
+Architectures: x86, arm, arm64
 Type: vm ioctl
 Parameters: struct kvm_vcpu_event (out)
 Returns: 0 on success, -1 on error
 
+X86:
+
 Gets currently pending exceptions, interrupts, and NMIs as well as related
 states of the vcpu.
 
@@ -881,15 +883,32 @@ Only two fields are defined in the flags field:
 - KVM_VCPUEVENT_VALID_SMM may be set in the flags field to signal that
   smi contains a valid state.
 
+ARM, ARM64:
+
+Gets currently pending SError exceptions as well as related states of the vcpu.
+
+struct kvm_vcpu_events {
+   struct {
+   __u8 serror_pending;
+   __u8 serror_has_esr;
+   /* Align it to 8 bytes */
+   __u8 pad[6];
+   __u64 serror_esr;
+   } exception;
+   __u32 reserved[12];
+};
+
 4.32 KVM_SET_VCPU_EVENTS
 
-Capability: KVM_CAP_VCPU_EVENTS
+Capebility: KVM_CAP_VCPU_EVENTS
 Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
+Architectures: x86, arm, arm64
 Type: vm ioctl
 Parameters: struct kvm_vcpu_event (in)
 Returns: 0 on success, -1 on error
 
+X86:
+
 Set pending exceptions, interrupts, and NMIs as well as related states of the
 vcpu.
 
@@ -910,6 +929,12 @@ shall be written into the VCPU.
 
 KVM_VCPUEVENT_VALID_SMM can only be set if KVM_CAP_X86_SMM is available.
 
+ARM, ARM64:
+
+Set pending SError exceptions as well as related states of the vcpu.
+
+See KVM_GET_VCPU_EVENTS for the data structure.
+
 
 4.33 KVM_GET_DEBUGREGS
 
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index c7c28c8..39f9901 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -213,6 +213,12 @@ unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu);
 int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
 int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
 int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+   struct kvm_vcpu_events *events);
+
+int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+   struct kvm_vcpu_events *events);
+
 unsigned long kvm_call_hyp(void *hypfn, ...);
 void force_vm_exit(const cpumask_t *mask);
 
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index a18f33e..c685f0e 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -261,6 +261,18 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
return -EINVAL;
 }
 
+int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,

[PATCH v1 0/2] Add NOTIFY_SEI notification type support

2018-05-30 Thread Dongjiu Geng
This series patch is separated from 
https://www.spinics.net/lists/kvm/msg168917.html

1. CPI 6.1 adds support for NOTIFY_SEI as a GHES notification mechanism, so 
this patch supports this
   notification in software

Dongjiu Geng (2):
  ACPI / APEI: Add SEI notification type support for ARMv8
  arm64: handle NOTIFY_SEI notification by the APEI driver

 arch/arm64/kernel/traps.c | 15 ++
 drivers/acpi/apei/Kconfig | 15 ++
 drivers/acpi/apei/ghes.c  | 53 +++
 include/acpi/ghes.h   |  1 +
 4 files changed, 84 insertions(+)

-- 
1.9.1



[PATCH v1 2/2] arm64: handle NOTIFY_SEI notification by the APEI driver

2018-05-30 Thread Dongjiu Geng
When kernel or KVM gets the NOTIFY_SEI notification, it firstly
calls the APEI driver to handle this notification.

Signed-off-by: Dongjiu Geng 
---
 arch/arm64/kernel/traps.c | 15 +++
 1 file changed, 15 insertions(+)
---
change since https://www.spinics.net/lists/kvm/msg168919.html

1. Remove the handle_guest_sei() helper


diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 8bbdc17..676e40c 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static const char *handler[]= {
"Synchronous Abort",
@@ -701,6 +702,20 @@ void __noreturn arm64_serror_panic(struct pt_regs *regs, 
u32 esr)
 bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned int esr)
 {
u32 aet = arm64_ras_serror_get_severity(esr);
+   int ret = -ENOENT;
+
+   if (IS_ENABLED(CONFIG_ACPI_APEI_SEI)) {
+   if (interrupts_enabled(regs))
+   nmi_enter();
+
+   ret = ghes_notify_sei();
+
+   if (interrupts_enabled(regs))
+   nmi_exit();
+
+   if (!ret)
+   return false;
+   }
 
switch (aet) {
case ESR_ELx_AET_CE:/* corrected error */
-- 
1.9.1



[PATCH v1 1/2] ACPI / APEI: Add SEI notification type support for ARMv8

2018-05-30 Thread Dongjiu Geng
ACPI 6.x adds support for NOTIFY_SEI as a GHES notification
mechanism, so add new GHES notification handling functions.
Expose API ghes_notify_sei() to arch code, arch code will call
this API when it gets this NOTIFY_SEI.

Signed-off-by: Dongjiu Geng 
---
Note:
Firmware will follow the SError mask rule, if the SError is masked,
the firmware will not deliver NOTIFY_SEI notification.
---
 drivers/acpi/apei/Kconfig | 15 ++
 drivers/acpi/apei/ghes.c  | 53 +++
 include/acpi/ghes.h   |  1 +
 3 files changed, 69 insertions(+)

diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index 52ae543..ff4afc3 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -55,6 +55,21 @@ config ACPI_APEI_SEA
  option allows the OS to look for such hardware error record, and
  take appropriate action.
 
+config ACPI_APEI_SEI
+   bool "APEI SError(System Error) Interrupt logging/recovering support"
+   depends on ARM64 && ACPI_APEI_GHES
+   default y
+   help
+ This option should be enabled if the system supports
+ firmware first handling of SEI (SError interrupt).
+
+ SEI happens with asynchronous external abort for errors on device
+ memory reads on ARMv8 systems. If a system supports firmware first
+ handling of SEI, the platform analyzes and handles hardware error
+ notifications from SEI, and it may then form a hardware error record 
for
+ the OS to parse and handle. This option allows the OS to look for
+ such hardware error record, and take appropriate action.
+
 config ACPI_APEI_MEMORY_FAILURE
bool "APEI memory error recovering support"
depends on ACPI_APEI && MEMORY_FAILURE
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 1efefe9..33f77ae 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -827,6 +827,46 @@ static inline void ghes_sea_add(struct ghes *ghes) { }
 static inline void ghes_sea_remove(struct ghes *ghes) { }
 #endif /* CONFIG_ACPI_APEI_SEA */
 
+#ifdef CONFIG_ACPI_APEI_SEI
+static LIST_HEAD(ghes_sei);
+
+/*
+ * Return 0 only if one of the SEI error sources successfully reported an error
+ * record sent from the firmware.
+ */
+int ghes_notify_sei(void)
+{
+   struct ghes *ghes;
+   int ret = -ENOENT;
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(ghes, &ghes_sei, list) {
+   if (!ghes_proc(ghes))
+   ret = 0;
+   }
+   rcu_read_unlock();
+   return ret;
+}
+
+static void ghes_sei_add(struct ghes *ghes)
+{
+   mutex_lock(&ghes_list_mutex);
+   list_add_rcu(&ghes->list, &ghes_sei);
+   mutex_unlock(&ghes_list_mutex);
+}
+
+static void ghes_sei_remove(struct ghes *ghes)
+{
+   mutex_lock(&ghes_list_mutex);
+   list_del_rcu(&ghes->list);
+   mutex_unlock(&ghes_list_mutex);
+   synchronize_rcu();
+}
+#else /* CONFIG_ACPI_APEI_SEI */
+static inline void ghes_sei_add(struct ghes *ghes) { }
+static inline void ghes_sei_remove(struct ghes *ghes) { }
+#endif /* CONFIG_ACPI_APEI_SEI */
+
 #ifdef CONFIG_HAVE_ACPI_APEI_NMI
 /*
  * printk is not safe in NMI context.  So in NMI handler, we allocate
@@ -1055,6 +1095,13 @@ static int ghes_probe(struct platform_device *ghes_dev)
goto err;
}
break;
+   case ACPI_HEST_NOTIFY_SEI:
+   if (!IS_ENABLED(CONFIG_ACPI_APEI_SEI)) {
+   pr_warn(GHES_PFX "Generic hardware error source: %d 
notified via SEI is not supported!\n",
+   generic->header.source_id);
+   goto err;
+   }
+   break;
case ACPI_HEST_NOTIFY_NMI:
if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_NMI)) {
pr_warn(GHES_PFX "Generic hardware error source: %d 
notified via NMI interrupt is not supported!\n",
@@ -1126,6 +1173,9 @@ static int ghes_probe(struct platform_device *ghes_dev)
case ACPI_HEST_NOTIFY_SEA:
ghes_sea_add(ghes);
break;
+   case ACPI_HEST_NOTIFY_SEI:
+   ghes_sei_add(ghes);
+   break;
case ACPI_HEST_NOTIFY_NMI:
ghes_nmi_add(ghes);
break;
@@ -1179,6 +1229,9 @@ static int ghes_remove(struct platform_device *ghes_dev)
case ACPI_HEST_NOTIFY_SEA:
ghes_sea_remove(ghes);
break;
+   case ACPI_HEST_NOTIFY_SEI:
+   ghes_sei_remove(ghes);
+   break;
case ACPI_HEST_NOTIFY_NMI:
ghes_nmi_remove(ghes);
break;
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 8feb0c8..9ba59e2 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -120,5 +120,6 @@ static inline void *acpi_hest_get_next(

[PATCH v12 3/4] ACPI / APEI: Add SEI notification type support for ARMv8

2018-05-15 Thread Dongjiu Geng
ACPI 6.x adds support for NOTIFY_SEI as a GHES notification
mechanism, so add new GHES notification handling functions.
Expose API ghes_notify_sei() to arch code, arch code will call
this API when it gets this NOTIFY_SEI.

Signed-off-by: Dongjiu Geng 

Note:
Firmware will follow the SError mask rule, if the SError is masked,
the firmware will not deliver NOTIFY_SEI notification.
---
 drivers/acpi/apei/Kconfig | 15 ++
 drivers/acpi/apei/ghes.c  | 53 +++
 include/acpi/ghes.h   |  1 +
 3 files changed, 69 insertions(+)

diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index 52ae543..ff4afc3 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -55,6 +55,21 @@ config ACPI_APEI_SEA
  option allows the OS to look for such hardware error record, and
  take appropriate action.
 
+config ACPI_APEI_SEI
+   bool "APEI SError(System Error) Interrupt logging/recovering support"
+   depends on ARM64 && ACPI_APEI_GHES
+   default y
+   help
+ This option should be enabled if the system supports
+ firmware first handling of SEI (SError interrupt).
+
+ SEI happens with asynchronous external abort for errors on device
+ memory reads on ARMv8 systems. If a system supports firmware first
+ handling of SEI, the platform analyzes and handles hardware error
+ notifications from SEI, and it may then form a hardware error record 
for
+ the OS to parse and handle. This option allows the OS to look for
+ such hardware error record, and take appropriate action.
+
 config ACPI_APEI_MEMORY_FAILURE
bool "APEI memory error recovering support"
depends on ACPI_APEI && MEMORY_FAILURE
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 1efefe9..33f77ae 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -827,6 +827,46 @@ static inline void ghes_sea_add(struct ghes *ghes) { }
 static inline void ghes_sea_remove(struct ghes *ghes) { }
 #endif /* CONFIG_ACPI_APEI_SEA */
 
+#ifdef CONFIG_ACPI_APEI_SEI
+static LIST_HEAD(ghes_sei);
+
+/*
+ * Return 0 only if one of the SEI error sources successfully reported an error
+ * record sent from the firmware.
+ */
+int ghes_notify_sei(void)
+{
+   struct ghes *ghes;
+   int ret = -ENOENT;
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(ghes, &ghes_sei, list) {
+   if (!ghes_proc(ghes))
+   ret = 0;
+   }
+   rcu_read_unlock();
+   return ret;
+}
+
+static void ghes_sei_add(struct ghes *ghes)
+{
+   mutex_lock(&ghes_list_mutex);
+   list_add_rcu(&ghes->list, &ghes_sei);
+   mutex_unlock(&ghes_list_mutex);
+}
+
+static void ghes_sei_remove(struct ghes *ghes)
+{
+   mutex_lock(&ghes_list_mutex);
+   list_del_rcu(&ghes->list);
+   mutex_unlock(&ghes_list_mutex);
+   synchronize_rcu();
+}
+#else /* CONFIG_ACPI_APEI_SEI */
+static inline void ghes_sei_add(struct ghes *ghes) { }
+static inline void ghes_sei_remove(struct ghes *ghes) { }
+#endif /* CONFIG_ACPI_APEI_SEI */
+
 #ifdef CONFIG_HAVE_ACPI_APEI_NMI
 /*
  * printk is not safe in NMI context.  So in NMI handler, we allocate
@@ -1055,6 +1095,13 @@ static int ghes_probe(struct platform_device *ghes_dev)
goto err;
}
break;
+   case ACPI_HEST_NOTIFY_SEI:
+   if (!IS_ENABLED(CONFIG_ACPI_APEI_SEI)) {
+   pr_warn(GHES_PFX "Generic hardware error source: %d 
notified via SEI is not supported!\n",
+   generic->header.source_id);
+   goto err;
+   }
+   break;
case ACPI_HEST_NOTIFY_NMI:
if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_NMI)) {
pr_warn(GHES_PFX "Generic hardware error source: %d 
notified via NMI interrupt is not supported!\n",
@@ -1126,6 +1173,9 @@ static int ghes_probe(struct platform_device *ghes_dev)
case ACPI_HEST_NOTIFY_SEA:
ghes_sea_add(ghes);
break;
+   case ACPI_HEST_NOTIFY_SEI:
+   ghes_sei_add(ghes);
+   break;
case ACPI_HEST_NOTIFY_NMI:
ghes_nmi_add(ghes);
break;
@@ -1179,6 +1229,9 @@ static int ghes_remove(struct platform_device *ghes_dev)
case ACPI_HEST_NOTIFY_SEA:
ghes_sea_remove(ghes);
break;
+   case ACPI_HEST_NOTIFY_SEI:
+   ghes_sei_remove(ghes);
+   break;
case ACPI_HEST_NOTIFY_NMI:
ghes_nmi_remove(ghes);
break;
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 8feb0c8..9ba59e2 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -120,5 +120,6 @@ static inline void *acpi_hest_get_next(

[PATCH v12 1/4] arm64: KVM: export the capability to set guest SError syndrome

2018-05-15 Thread Dongjiu Geng
For the arm64 RAS Extension, user space can inject a virtual-SError
with specified ESR. So user space needs to know whether KVM support
to inject such SError, this interface adds this query for this capability.

KVM will check whether system support RAS Extension, if supported, KVM
returns true to user space, otherwise returns false.

Signed-off-by: Dongjiu Geng 
Reviewed-by: James Morse 

Change from V11:
1. Change the commit message
2. Update the Documentation/virtual/kvm/api.tx
---
 Documentation/virtual/kvm/api.txt | 11 +++
 arch/arm64/kvm/reset.c|  3 +++
 include/uapi/linux/kvm.h  |  1 +
 3 files changed, 15 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index fc3ae95..66494a5 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -4415,3 +4415,14 @@ Parameters: none
 This capability indicates if the flic device will be able to get/set the
 AIS states for migration via the KVM_DEV_FLIC_AISM_ALL attribute and allows
 to discover this without having to create a flic device.
+
+8.14 KVM_CAP_ARM_SET_SERROR_ESR
+
+Architectures: arm, arm64
+
+This capability indicates that userspace can specify the syndrome value 
reported
+to the guest OS when guest takes a virtual SError interrupt exception.
+If KVM has this capability, userspace can only specify the ISS field for the 
ESR
+syndrome, it can not specify the EC field which is not under control by KVM.
+If this virtual SError is taken to EL1 using AArch64, this value will be 
reported
+in ISS filed of ESR_EL1.
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 3256b92..38c8a64 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -77,6 +77,9 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long 
ext)
case KVM_CAP_ARM_PMU_V3:
r = kvm_arm_support_pmu_v3();
break;
+   case KVM_CAP_ARM_INJECT_SERROR_ESR:
+   r = cpus_have_const_cap(ARM64_HAS_RAS_EXTN);
+   break;
case KVM_CAP_SET_GUEST_DEBUG:
case KVM_CAP_VCPU_ATTRIBUTES:
r = 1;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 8fb90a0..3587b33 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -934,6 +934,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_S390_AIS_MIGRATION 150
 #define KVM_CAP_PPC_GET_CPU_CHAR 151
 #define KVM_CAP_S390_BPB 152
+#define KVM_CAP_ARM_INJECT_SERROR_ESR 153
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
1.9.1



[PATCH v12 4/4] arm64: handle NOTIFY_SEI notification by the APEI driver

2018-05-15 Thread Dongjiu Geng
Add a helper to handle the NOTIFY_SEI notification, when kernel
gets the NOTIFY_SEI notification, call this helper and let APEI
driver to handle this notification.

Signed-off-by: Dongjiu Geng 
---
 arch/arm64/include/asm/system_misc.h |  1 +
 arch/arm64/kernel/traps.c|  4 
 arch/arm64/mm/fault.c| 10 ++
 3 files changed, 15 insertions(+)

diff --git a/arch/arm64/include/asm/system_misc.h 
b/arch/arm64/include/asm/system_misc.h
index 07aa8e3..9ee13ad 100644
--- a/arch/arm64/include/asm/system_misc.h
+++ b/arch/arm64/include/asm/system_misc.h
@@ -57,6 +57,7 @@ void hook_debug_fault_code(int nr, int (*fn)(unsigned long, 
unsigned int,
 })
 
 int handle_guest_sea(phys_addr_t addr, unsigned int esr);
+int handle_guest_sei(void);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index bbb0fde..d888eb2 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -681,6 +681,10 @@ bool arm64_is_fatal_ras_serror(struct pt_regs *regs, 
unsigned int esr)
 {
u32 aet = arm64_ras_serror_get_severity(esr);
 
+   /* The APEI driver may handle this RAS error. */
+   if (!handle_guest_sei())
+   return false;
+
switch (aet) {
case ESR_ELx_AET_CE:/* corrected error */
case ESR_ELx_AET_UEO:   /* restartable, not yet consumed */
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index f76bb2c..8f29bd8 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -683,6 +683,16 @@ int handle_guest_sea(phys_addr_t addr, unsigned int esr)
return ret;
 }
 
+int handle_guest_sei(void)
+{
+   int ret = -ENOENT;
+
+   if (IS_ENABLED(CONFIG_ACPI_APEI_SEI))
+   ret = ghes_notify_sei();
+
+   return ret;
+}
+
 asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
 struct pt_regs *regs)
 {
-- 
1.9.1



[PATCH v12 2/4] arm/arm64: KVM: Add KVM_GET/SET_VCPU_EVENTS

2018-05-15 Thread Dongjiu Geng
For the migrating VMs, user space may need to know the exception
state. For example, in the machine A, KVM make an SError pending,
when migrate to B, KVM also needs to pend an SError.

This new IOCTL exports user-invisible states related to SError.
Together with appropriate user space changes, user space can get/set
the SError exception state to do migrate/snapshot/suspend.

Signed-off-by: Dongjiu Geng 

Change since V11:
Address James's comments, thanks James
1. Align the struct of kvm_vcpu_events to 64 bytes
2. Avoid exposing the stale ESR value in the kvm_arm_vcpu_get_events()
3. Change variables 'injected' name to 'serror_pending' in the 
kvm_arm_vcpu_set_events()
4. change to sizeof(events) from sizeof(struct kvm_vcpu_events) in 
kvm_arch_vcpu_ioctl()

Change since V10:
Address James's comments, thanks James
1. Merge the helper function with the user.
2. Move the ISS_MASK into pend_guest_serror() to clear top bits
3. Make kvm_vcpu_events struct align to 4 bytes
4. Add something check in the kvm_arm_vcpu_set_events()
5. Check kvm_arm_vcpu_get/set_events()'s return value.
6. Initialise kvm_vcpu_events to 0 so that padding transferred to user-space 
doesn't
contain kernel stack.
---
 Documentation/virtual/kvm/api.txt| 31 ---
 arch/arm/include/asm/kvm_host.h  |  6 ++
 arch/arm/kvm/guest.c | 12 
 arch/arm64/include/asm/kvm_emulate.h |  5 +
 arch/arm64/include/asm/kvm_host.h|  7 +++
 arch/arm64/include/uapi/asm/kvm.h| 13 +
 arch/arm64/kvm/guest.c   | 36 
 arch/arm64/kvm/inject_fault.c|  7 ++-
 arch/arm64/kvm/reset.c   |  1 +
 virt/kvm/arm/arm.c   | 21 +
 10 files changed, 135 insertions(+), 4 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 66494a5..36a9dc3 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -819,11 +819,13 @@ struct kvm_clock_data {
 
 Capability: KVM_CAP_VCPU_EVENTS
 Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
+Architectures: x86, arm, arm64
 Type: vm ioctl
 Parameters: struct kvm_vcpu_event (out)
 Returns: 0 on success, -1 on error
 
+X86:
+
 Gets currently pending exceptions, interrupts, and NMIs as well as related
 states of the vcpu.
 
@@ -865,15 +867,32 @@ Only two fields are defined in the flags field:
 - KVM_VCPUEVENT_VALID_SMM may be set in the flags field to signal that
   smi contains a valid state.
 
+ARM, ARM64:
+
+Gets currently pending SError exceptions as well as related states of the vcpu.
+
+struct kvm_vcpu_events {
+   struct {
+   __u8 serror_pending;
+   __u8 serror_has_esr;
+   /* Align it to 8 bytes */
+   __u8 pad[6];
+   __u64 serror_esr;
+   } exception;
+   __u32 reserved[12];
+};
+
 4.32 KVM_SET_VCPU_EVENTS
 
-Capability: KVM_CAP_VCPU_EVENTS
+Capebility: KVM_CAP_VCPU_EVENTS
 Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
+Architectures: x86, arm, arm64
 Type: vm ioctl
 Parameters: struct kvm_vcpu_event (in)
 Returns: 0 on success, -1 on error
 
+X86:
+
 Set pending exceptions, interrupts, and NMIs as well as related states of the
 vcpu.
 
@@ -894,6 +913,12 @@ shall be written into the VCPU.
 
 KVM_VCPUEVENT_VALID_SMM can only be set if KVM_CAP_X86_SMM is available.
 
+ARM, ARM64:
+
+Set pending SError exceptions as well as related states of the vcpu.
+
+See KVM_GET_VCPU_EVENTS for the data structure.
+
 
 4.33 KVM_GET_DEBUGREGS
 
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index ef54013..d81621e 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -211,6 +211,12 @@ struct kvm_vcpu_stat {
 int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
 int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
 int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+   struct kvm_vcpu_events *events);
+
+int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+   struct kvm_vcpu_events *events);
+
 unsigned long kvm_call_hyp(void *hypfn, ...);
 void force_vm_exit(const cpumask_t *mask);
 
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index 1e0784e..39f895d 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -248,6 +248,18 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
return -EINVAL;
 }
 
+int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+   struct kvm_vcpu_events *events)
+{
+   return -EINVAL;
+}
+
+int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+   struct kvm_vcpu_events *events)
+{
+   return -EINVAL;
+}
+
 int __attribute_const__ kvm_target_cpu(

[PATCH v12 0/4] set VSESR_EL2 by user space and support NOTIFY_SEI notification

2018-05-15 Thread Dongjiu Geng
1. Detect whether KVM can set set guest SError syndrome
2. Support to Set VSESR_EL2 and inject SError by user space.
3. Support live migration to keep SError pending state and VSESR_EL2 value.
4. ACPI 6.1 adds support for NOTIFY_SEI as a GHES notification mechanism, so 
support this
   notification in software, KVM or kernel ARCH code call handle_guest_sei() to 
let ACP driver
   to handle this notification.

Change since V11:
Address James's comments, thanks James
1. Align the struct of kvm_vcpu_events to 64 bytes
2. Avoid exposing the stale ESR value in the kvm_arm_vcpu_get_events()
3. Change variables 'injected' name to 'serror_pending' in the 
kvm_arm_vcpu_set_events()
4. Change to sizeof(events) from sizeof(struct kvm_vcpu_events) in 
kvm_arch_vcpu_ioctl()
5. Update the patches commit message and document description


Change since V10:
Address James's comments, thanks James
1. Merge the helper function with the user.
2. Move the ISS_MASK into pend_guest_serror() to clear top bits
3. Make kvm_vcpu_events struct align to 4 bytes
4. Add something check in the kvm_arm_vcpu_set_events()
5. Check kvm_arm_vcpu_get/set_events()'s return value.
6. Initialise kvm_vcpu_events to 0 so that padding transferred to user-space 
doesn't
contain kernel stack.


Dongjiu Geng (4):
  arm64: KVM: export the capability to set guest SError syndrome
  arm/arm64: KVM: Add KVM_GET/SET_VCPU_EVENTS
  ACPI / APEI: Add SEI notification type support for ARMv8
  arm64: handle NOTIFY_SEI notification by the APEI driver

 Documentation/virtual/kvm/api.txt| 42 ++--
 arch/arm/include/asm/kvm_host.h  |  6 
 arch/arm/kvm/guest.c | 12 
 arch/arm64/include/asm/kvm_emulate.h |  5 
 arch/arm64/include/asm/kvm_host.h|  7 +
 arch/arm64/include/asm/system_misc.h |  1 +
 arch/arm64/include/uapi/asm/kvm.h| 13 +
 arch/arm64/kernel/traps.c|  4 +++
 arch/arm64/kvm/guest.c   | 36 
 arch/arm64/kvm/inject_fault.c|  7 -
 arch/arm64/kvm/reset.c   |  4 +++
 arch/arm64/mm/fault.c| 10 +++
 drivers/acpi/apei/Kconfig| 15 ++
 drivers/acpi/apei/ghes.c | 53 
 include/acpi/ghes.h  |  1 +
 include/uapi/linux/kvm.h |  1 +
 virt/kvm/arm/arm.c   | 21 ++
 17 files changed, 234 insertions(+), 4 deletions(-)

-- 
1.9.1



[PATCH v11 4/4] arm64: handle NOTIFY_SEI notification by the APEI driver

2018-04-09 Thread Dongjiu Geng
Add a helper to handle the NOTIFY_SEI notification, when kernel
gets the NOTIFY_SEI notification, call this helper and let APEI
driver to handle this notification.

Signed-off-by: Dongjiu Geng 
---
 arch/arm64/include/asm/system_misc.h |  1 +
 arch/arm64/kernel/traps.c|  4 
 arch/arm64/mm/fault.c| 10 ++
 3 files changed, 15 insertions(+)

diff --git a/arch/arm64/include/asm/system_misc.h 
b/arch/arm64/include/asm/system_misc.h
index 07aa8e3..9ee13ad 100644
--- a/arch/arm64/include/asm/system_misc.h
+++ b/arch/arm64/include/asm/system_misc.h
@@ -57,6 +57,7 @@ void hook_debug_fault_code(int nr, int (*fn)(unsigned long, 
unsigned int,
 })
 
 int handle_guest_sea(phys_addr_t addr, unsigned int esr);
+int handle_guest_sei(void);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index bbb0fde..d888eb2 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -681,6 +681,10 @@ bool arm64_is_fatal_ras_serror(struct pt_regs *regs, 
unsigned int esr)
 {
u32 aet = arm64_ras_serror_get_severity(esr);
 
+   /* The APEI driver may handle this RAS error. */
+   if (!handle_guest_sei())
+   return false;
+
switch (aet) {
case ESR_ELx_AET_CE:/* corrected error */
case ESR_ELx_AET_UEO:   /* restartable, not yet consumed */
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index f76bb2c..8f29bd8 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -683,6 +683,16 @@ int handle_guest_sea(phys_addr_t addr, unsigned int esr)
return ret;
 }
 
+int handle_guest_sei(void)
+{
+   int ret = -ENOENT;
+
+   if (IS_ENABLED(CONFIG_ACPI_APEI_SEI))
+   ret = ghes_notify_sei();
+
+   return ret;
+}
+
 asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
 struct pt_regs *regs)
 {
-- 
1.9.1



[PATCH v11 2/4] arm/arm64: KVM: Add KVM_GET/SET_VCPU_EVENTS

2018-04-09 Thread Dongjiu Geng
This new IOCTL exports user-invisible states related to SError.
Together with appropriate user space changes, it can inject
SError with specified syndrome to guest by setup kvm_vcpu_events
value. Also it can support live migration.

Signed-off-by: Dongjiu Geng 

Change since V10:

Address James's comments, thanks James
1. Merge the helper function with the user.
2. Move the ISS_MASK into pend_guest_serror() to clear top bits
3. Make kvm_vcpu_events struct align to 4 bytes
4. Add something check in the kvm_arm_vcpu_set_events()
5. Check kvm_arm_vcpu_get/set_events()'s return value.
6. Initialise kvm_vcpu_events to 0 so that padding transferred to user-space 
doesn't
contain kernel stack.
---
 Documentation/virtual/kvm/api.txt| 28 ++--
 arch/arm/include/asm/kvm_host.h  |  6 ++
 arch/arm/kvm/guest.c | 12 
 arch/arm64/include/asm/kvm_emulate.h |  5 +
 arch/arm64/include/asm/kvm_host.h|  7 +++
 arch/arm64/include/uapi/asm/kvm.h| 12 
 arch/arm64/kvm/guest.c   | 31 +++
 arch/arm64/kvm/inject_fault.c|  7 ++-
 arch/arm64/kvm/reset.c   |  1 +
 virt/kvm/arm/arm.c   | 21 +
 10 files changed, 127 insertions(+), 3 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 8a3d708..45719b4 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -819,11 +819,13 @@ struct kvm_clock_data {
 
 Capability: KVM_CAP_VCPU_EVENTS
 Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
+Architectures: x86, arm, arm64
 Type: vm ioctl
 Parameters: struct kvm_vcpu_event (out)
 Returns: 0 on success, -1 on error
 
+X86:
+
 Gets currently pending exceptions, interrupts, and NMIs as well as related
 states of the vcpu.
 
@@ -865,15 +867,31 @@ Only two fields are defined in the flags field:
 - KVM_VCPUEVENT_VALID_SMM may be set in the flags field to signal that
   smi contains a valid state.
 
+ARM, ARM64:
+
+Gets currently pending SError exceptions as well as related states of the vcpu.
+
+struct kvm_vcpu_events {
+   struct {
+   __u8 serror_pending;
+   __u8 serror_has_esr;
+   /* Align it to 4 bytes */
+   __u8 pad[2];
+   __u64 serror_esr;
+   } exception;
+};
+
 4.32 KVM_SET_VCPU_EVENTS
 
 Capability: KVM_CAP_VCPU_EVENTS
 Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
+Architectures: x86, arm, arm64
 Type: vm ioctl
 Parameters: struct kvm_vcpu_event (in)
 Returns: 0 on success, -1 on error
 
+X86:
+
 Set pending exceptions, interrupts, and NMIs as well as related states of the
 vcpu.
 
@@ -894,6 +912,12 @@ shall be written into the VCPU.
 
 KVM_VCPUEVENT_VALID_SMM can only be set if KVM_CAP_X86_SMM is available.
 
+ARM, ARM64:
+
+Set pending SError exceptions as well as related states of the vcpu.
+
+See KVM_GET_VCPU_EVENTS for the data structure.
+
 
 4.33 KVM_GET_DEBUGREGS
 
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index ef54013..d81621e 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -211,6 +211,12 @@ struct kvm_vcpu_stat {
 int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *indices);
 int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
 int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+   struct kvm_vcpu_events *events);
+
+int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+   struct kvm_vcpu_events *events);
+
 unsigned long kvm_call_hyp(void *hypfn, ...);
 void force_vm_exit(const cpumask_t *mask);
 
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index 1e0784e..39f895d 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -248,6 +248,18 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
return -EINVAL;
 }
 
+int kvm_arm_vcpu_get_events(struct kvm_vcpu *vcpu,
+   struct kvm_vcpu_events *events)
+{
+   return -EINVAL;
+}
+
+int kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
+   struct kvm_vcpu_events *events)
+{
+   return -EINVAL;
+}
+
 int __attribute_const__ kvm_target_cpu(void)
 {
switch (read_cpuid_part()) {
diff --git a/arch/arm64/include/asm/kvm_emulate.h 
b/arch/arm64/include/asm/kvm_emulate.h
index 413dc82..3294885 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -71,6 +71,11 @@ static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, 
unsigned long hcr)
vcpu->arch.hcr_el2 = hcr;
 }
 
+static inline unsigned long vcpu_get_vsesr(struct kvm_vcpu *vcpu)
+{
+   return vcpu->arch.vsesr_el2;
+}
+
 static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
 {
vcpu->arch

[PATCH v11 3/4] ACPI / APEI: Add SEI notification type support for ARMv8

2018-04-09 Thread Dongjiu Geng
ACPI 6.x adds support for NOTIFY_SEI as a GHES notification
mechanism, so add new GHES notification handling functions.
Expose API ghes_notify_sei() to arch code, arch code will call
this API when it gets this NOTIFY_SEI.

Signed-off-by: Dongjiu Geng 
---
 drivers/acpi/apei/Kconfig | 15 ++
 drivers/acpi/apei/ghes.c  | 53 +++
 include/acpi/ghes.h   |  1 +
 3 files changed, 69 insertions(+)

diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index 52ae543..ff4afc3 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -55,6 +55,21 @@ config ACPI_APEI_SEA
  option allows the OS to look for such hardware error record, and
  take appropriate action.
 
+config ACPI_APEI_SEI
+   bool "APEI SError(System Error) Interrupt logging/recovering support"
+   depends on ARM64 && ACPI_APEI_GHES
+   default y
+   help
+ This option should be enabled if the system supports
+ firmware first handling of SEI (SError interrupt).
+
+ SEI happens with asynchronous external abort for errors on device
+ memory reads on ARMv8 systems. If a system supports firmware first
+ handling of SEI, the platform analyzes and handles hardware error
+ notifications from SEI, and it may then form a hardware error record 
for
+ the OS to parse and handle. This option allows the OS to look for
+ such hardware error record, and take appropriate action.
+
 config ACPI_APEI_MEMORY_FAILURE
bool "APEI memory error recovering support"
depends on ACPI_APEI && MEMORY_FAILURE
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 1efefe9..33f77ae 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -827,6 +827,46 @@ static inline void ghes_sea_add(struct ghes *ghes) { }
 static inline void ghes_sea_remove(struct ghes *ghes) { }
 #endif /* CONFIG_ACPI_APEI_SEA */
 
+#ifdef CONFIG_ACPI_APEI_SEI
+static LIST_HEAD(ghes_sei);
+
+/*
+ * Return 0 only if one of the SEI error sources successfully reported an error
+ * record sent from the firmware.
+ */
+int ghes_notify_sei(void)
+{
+   struct ghes *ghes;
+   int ret = -ENOENT;
+
+   rcu_read_lock();
+   list_for_each_entry_rcu(ghes, &ghes_sei, list) {
+   if (!ghes_proc(ghes))
+   ret = 0;
+   }
+   rcu_read_unlock();
+   return ret;
+}
+
+static void ghes_sei_add(struct ghes *ghes)
+{
+   mutex_lock(&ghes_list_mutex);
+   list_add_rcu(&ghes->list, &ghes_sei);
+   mutex_unlock(&ghes_list_mutex);
+}
+
+static void ghes_sei_remove(struct ghes *ghes)
+{
+   mutex_lock(&ghes_list_mutex);
+   list_del_rcu(&ghes->list);
+   mutex_unlock(&ghes_list_mutex);
+   synchronize_rcu();
+}
+#else /* CONFIG_ACPI_APEI_SEI */
+static inline void ghes_sei_add(struct ghes *ghes) { }
+static inline void ghes_sei_remove(struct ghes *ghes) { }
+#endif /* CONFIG_ACPI_APEI_SEI */
+
 #ifdef CONFIG_HAVE_ACPI_APEI_NMI
 /*
  * printk is not safe in NMI context.  So in NMI handler, we allocate
@@ -1055,6 +1095,13 @@ static int ghes_probe(struct platform_device *ghes_dev)
goto err;
}
break;
+   case ACPI_HEST_NOTIFY_SEI:
+   if (!IS_ENABLED(CONFIG_ACPI_APEI_SEI)) {
+   pr_warn(GHES_PFX "Generic hardware error source: %d 
notified via SEI is not supported!\n",
+   generic->header.source_id);
+   goto err;
+   }
+   break;
case ACPI_HEST_NOTIFY_NMI:
if (!IS_ENABLED(CONFIG_HAVE_ACPI_APEI_NMI)) {
pr_warn(GHES_PFX "Generic hardware error source: %d 
notified via NMI interrupt is not supported!\n",
@@ -1126,6 +1173,9 @@ static int ghes_probe(struct platform_device *ghes_dev)
case ACPI_HEST_NOTIFY_SEA:
ghes_sea_add(ghes);
break;
+   case ACPI_HEST_NOTIFY_SEI:
+   ghes_sei_add(ghes);
+   break;
case ACPI_HEST_NOTIFY_NMI:
ghes_nmi_add(ghes);
break;
@@ -1179,6 +1229,9 @@ static int ghes_remove(struct platform_device *ghes_dev)
case ACPI_HEST_NOTIFY_SEA:
ghes_sea_remove(ghes);
break;
+   case ACPI_HEST_NOTIFY_SEI:
+   ghes_sei_remove(ghes);
+   break;
case ACPI_HEST_NOTIFY_NMI:
ghes_nmi_remove(ghes);
break;
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 8feb0c8..9ba59e2 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -120,5 +120,6 @@ static inline void *acpi_hest_get_next(struct 
acpi_hest_generic_data *gdata)
 section = acpi_hest_get_next(section))
 
 int ghes_notify_sea(void);
+int ghes_notify_sei(void);
 
 #endif /* GHES_H */
-- 
1.9.1



[PATCH v11 0/4] set VSESR_EL2 by user space and support NOTIFY_SEI notification

2018-04-09 Thread Dongjiu Geng
1. Detect whether KVM can set set guest SError syndrome
2. Support to Set VSESR_EL2 and inject SError by user space.
3. Support live migration to keep SError pending state and VSESR_EL2 value.
4. ACPI 6.1 adds support for NOTIFY_SEI as a GHES notification mechanism, so 
support this
   notification in software, KVM or kernel ARCH code call handle_guest_sei() to 
let ACP driver
   to handle this notification.

Change since V10:

Address James's comments, thanks James
1. Merge the helper function with the user.
2. Move the ISS_MASK into pend_guest_serror() to clear top bits
3. Make kvm_vcpu_events struct align to 4 bytes
4. Add something check in the kvm_arm_vcpu_set_events()
5. Check kvm_arm_vcpu_get/set_events()'s return value.
6. Initialise kvm_vcpu_events to 0 so that padding transferred to user-space 
doesn't
contain kernel stack.

Dongjiu Geng (4):
  arm64: KVM: export the capability to set guest SError syndrome
  arm/arm64: KVM: Add KVM_GET/SET_VCPU_EVENTS
  ACPI / APEI: Add SEI notification type support for ARMv8
  arm64: handle NOTIFY_SEI notification by the APEI driver

 Documentation/virtual/kvm/api.txt| 39 --
 arch/arm/include/asm/kvm_host.h  |  6 
 arch/arm/kvm/guest.c | 12 
 arch/arm64/include/asm/kvm_emulate.h |  5 
 arch/arm64/include/asm/kvm_host.h|  7 +
 arch/arm64/include/asm/system_misc.h |  1 +
 arch/arm64/include/uapi/asm/kvm.h| 12 
 arch/arm64/kernel/traps.c|  4 +++
 arch/arm64/kvm/guest.c   | 31 +
 arch/arm64/kvm/inject_fault.c|  7 -
 arch/arm64/kvm/reset.c   |  4 +++
 arch/arm64/mm/fault.c| 10 +++
 drivers/acpi/apei/Kconfig| 15 ++
 drivers/acpi/apei/ghes.c | 53 
 include/acpi/ghes.h  |  1 +
 include/uapi/linux/kvm.h |  1 +
 virt/kvm/arm/arm.c   | 21 ++
 17 files changed, 226 insertions(+), 3 deletions(-)

-- 
1.9.1



[PATCH v11 1/4] arm64: KVM: export the capability to set guest SError syndrome

2018-04-09 Thread Dongjiu Geng
Before user space injects a SError, it needs to know whether it can
specify the guest Exception Syndrome, so KVM should tell user space
whether it has such capability.

Signed-off-by: Dongjiu Geng 
---
 Documentation/virtual/kvm/api.txt | 11 +++
 arch/arm64/kvm/reset.c|  3 +++
 include/uapi/linux/kvm.h  |  1 +
 3 files changed, 15 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index fc3ae95..8a3d708 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -4415,3 +4415,14 @@ Parameters: none
 This capability indicates if the flic device will be able to get/set the
 AIS states for migration via the KVM_DEV_FLIC_AISM_ALL attribute and allows
 to discover this without having to create a flic device.
+
+8.14 KVM_CAP_ARM_SET_SERROR_ESR
+
+Architectures: arm, arm64
+
+This capability indicates that userspace can specify syndrome value reported to
+guest OS when guest takes a virtual SError interrupt exception.
+If KVM has this capability, userspace can only specify the ISS field for the 
ESR
+syndrome, can not specify the EC field which is not under control by KVM.
+If this virtual SError is taken to EL1 using AArch64, this value will be 
reported
+into ISS filed of ESR_EL1.
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 3256b92..38c8a64 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -77,6 +77,9 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long 
ext)
case KVM_CAP_ARM_PMU_V3:
r = kvm_arm_support_pmu_v3();
break;
+   case KVM_CAP_ARM_INJECT_SERROR_ESR:
+   r = cpus_have_const_cap(ARM64_HAS_RAS_EXTN);
+   break;
case KVM_CAP_SET_GUEST_DEBUG:
case KVM_CAP_VCPU_ATTRIBUTES:
r = 1;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 8fb90a0..3587b33 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -934,6 +934,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_S390_AIS_MIGRATION 150
 #define KVM_CAP_PPC_GET_CPU_CHAR 151
 #define KVM_CAP_S390_BPB 152
+#define KVM_CAP_ARM_INJECT_SERROR_ESR 153
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
1.9.1



[PATCH v10 2/5] arm64: KVM: export the capability to set guest SError syndrome

2018-03-03 Thread Dongjiu Geng
Before user space injects a SError, it needs to know whether it can
specify the guest Exception Syndrome, so KVM should tell user space
whether it has such capability.

Signed-off-by: Dongjiu Geng 
---
 Documentation/virtual/kvm/api.txt | 11 +++
 arch/arm64/kvm/reset.c|  3 +++
 include/uapi/linux/kvm.h  |  1 +
 3 files changed, 15 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index fc3ae95..8a3d708 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -4415,3 +4415,14 @@ Parameters: none
 This capability indicates if the flic device will be able to get/set the
 AIS states for migration via the KVM_DEV_FLIC_AISM_ALL attribute and allows
 to discover this without having to create a flic device.
+
+8.14 KVM_CAP_ARM_SET_SERROR_ESR
+
+Architectures: arm, arm64
+
+This capability indicates that userspace can specify syndrome value reported to
+guest OS when guest takes a virtual SError interrupt exception.
+If KVM has this capability, userspace can only specify the ISS field for the 
ESR
+syndrome, can not specify the EC field which is not under control by KVM.
+If this virtual SError is taken to EL1 using AArch64, this value will be 
reported
+into ISS filed of ESR_EL1.
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 3256b92..38c8a64 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -77,6 +77,9 @@ int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long 
ext)
case KVM_CAP_ARM_PMU_V3:
r = kvm_arm_support_pmu_v3();
break;
+   case KVM_CAP_ARM_INJECT_SERROR_ESR:
+   r = cpus_have_const_cap(ARM64_HAS_RAS_EXTN);
+   break;
case KVM_CAP_SET_GUEST_DEBUG:
case KVM_CAP_VCPU_ATTRIBUTES:
r = 1;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 8fb90a0..3587b33 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -934,6 +934,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_S390_AIS_MIGRATION 150
 #define KVM_CAP_PPC_GET_CPU_CHAR 151
 #define KVM_CAP_S390_BPB 152
+#define KVM_CAP_ARM_INJECT_SERROR_ESR 153
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
1.9.1



  1   2   3   >