Skip to contentSkip to conversation

*** Support ASPEED AST2600 I2C ***

PATCH In review Jamin Lin 4 participants 14 messages Jun 17, 2021 – Jun 24, 2021

Subsystems (3)
lore
Share & tools
lore

Jamin Lin

author
#0 lore raw

cover *** Support ASPEED AST2600 I2C ***

Support I2C controller of ASPEED AST2600 and
enable the new register set

Jamin Lin (3):
dts: aspeed: Add node for AST2600 I2C and I2CS
dt-bindings: i2c-new: Add bindings for AST2600 I2C i2c:support new register set for ast2600

 .../bindings/i2c/aspeed,new-i2c.yaml          |  107 +
 arch/arm/boot/dts/aspeed-g6.dtsi              |  150 +-
 drivers/i2c/busses/Kconfig                    |   11 +
 drivers/i2c/busses/Makefile                   |    1 +
 drivers/i2c/busses/ast2600-i2c-global.c       |  205 ++
 drivers/i2c/busses/ast2600-i2c-global.h       |   25 +
 drivers/i2c/busses/i2c-new-aspeed.c           | 1796 +++++++++++++++++
 7 files changed, 2263 insertions(+), 32 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i2c/aspeed,new-i2c.yaml
 create mode 100644 drivers/i2c/busses/ast2600-i2c-global.c
 create mode 100644 drivers/i2c/busses/ast2600-i2c-global.h
 create mode 100644 drivers/i2c/busses/i2c-new-aspeed.c
Signature · 1 line
2.17.1
author
#1 lore raw

PATCH 1/3 dts: aspeed: Add node for AST2600 I2C and I2CS

Support byte-mode, dma-mode and buffer-mode for
data transfer of I2C. Add i2c-global-regs node
to support the new register set Add node to
support I2CS.

---
 arch/arm/boot/dts/aspeed-g6.dtsi | 150 ++++++++++++++++++++++++-------
 1 file changed, 118 insertions(+), 32 deletions(-)
arch/arm/boot/dts/aspeed-g6.dtsi +118 -32
index f96607b7b4e2..e83df01123fe 100644
@@ -667,6 +667,13 @@
 				clocks = <&syscon ASPEED_CLK_GATE_FSICLK>;
 				status = "disabled";
 			};
+
+			i2csec: bus at 1e7a8000 {
+				compatible = "simple-bus";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x1e7a8000 0x1000>;
+			};
 		};
 	};
 };
@@ -674,12 +681,20 @@
 #include "aspeed-g6-pinctrl.dtsi"
 
 &i2c {
+
+	i2c_gr: i2c-global-regs at 0 {
+		compatible = "aspeed,ast2600-i2c-global", "syscon";
+		reg = <0x0 0x20>;
+		clocks = <&syscon ASPEED_CLK_APB2>;
+		resets = <&syscon ASPEED_RESET_I2C>;
+	};
+
 	i2c0: i2c-bus at 80 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x80 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x80 0x80>, <0xC00 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
@@ -690,11 +705,11 @@
 	};
 
 	i2c1: i2c-bus at 100 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x100 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x100 0x80>, <0xC20 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
@@ -705,11 +720,11 @@
 	};
 
 	i2c2: i2c-bus at 180 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x180 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x180 0x80>, <0xC40 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
@@ -720,11 +735,11 @@
 	};
 
 	i2c3: i2c-bus at 200 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x200 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x200 0x80>, <0xC60 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
@@ -735,11 +750,11 @@
 	};
 
 	i2c4: i2c-bus at 280 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x280 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x280 0x80>, <0xC80 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
@@ -750,11 +765,11 @@
 	};
 
 	i2c5: i2c-bus at 300 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x300 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x300 0x80>, <0xCA0 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
@@ -765,11 +780,11 @@
 	};
 
 	i2c6: i2c-bus at 380 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x380 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x380 0x80>, <0xCC0 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
@@ -780,11 +795,11 @@
 	};
 
 	i2c7: i2c-bus at 400 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x400 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x400 0x80>, <0xCE0 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
@@ -795,11 +810,11 @@
 	};
 
 	i2c8: i2c-bus at 480 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x480 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x480 0x80>, <0xD00 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
@@ -810,11 +825,11 @@
 	};
 
 	i2c9: i2c-bus at 500 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x500 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x500 0x80>, <0xD20 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
@@ -825,11 +840,11 @@
 	};
 
 	i2c10: i2c-bus at 580 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x580 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x580 0x80>, <0xD40 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
@@ -840,11 +855,11 @@
 	};
 
 	i2c11: i2c-bus at 600 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x600 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x600 0x80>, <0xD60 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
@@ -855,11 +870,11 @@
 	};
 
 	i2c12: i2c-bus at 680 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x680 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x680 0x80>, <0xD80 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
@@ -870,11 +885,11 @@
 	};
 
 	i2c13: i2c-bus at 700 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x700 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x700 0x80>, <0xDA0 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
@@ -885,11 +900,11 @@
 	};
 
 	i2c14: i2c-bus at 780 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x780 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x780 0x80>, <0xDC0 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
@@ -900,11 +915,11 @@
 	};
 
 	i2c15: i2c-bus at 800 {
+		compatible = "aspeed,ast2600-i2c-bus";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interrupt-cells = <1>;
-		reg = <0x800 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
+		reg = <0x800 0x80>, <0xDE0 0x20>;
 		clocks = <&syscon ASPEED_CLK_APB2>;
 		resets = <&syscon ASPEED_RESET_I2C>;
 		interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
@@ -914,3 +929,74 @@
 		status = "disabled";
 	};
 };
+
+&i2csec {
+
+	i2c_gr0: i2c-global-regs at 0 {
+		compatible = "aspeed,ast2600-i2c-global", "syscon";
+		reg = <0x0 0x20>;
+		clocks = <&syscon ASPEED_CLK_APB2>;
+		status = "disabled";
+	};
+
+	i2c16: i2c-bus at 80 {
+		compatible = "aspeed,ast2600-i2c-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#interrupt-cells = <1>;
+		reg = <0x80 0x80>, <0xC00 0x20>;
+		clocks = <&syscon ASPEED_CLK_APB2>;
+		interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+		bus-frequency = <100000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2c1_default>;
+		buff-mode;
+		status = "disabled";
+	};
+
+	i2c17: i2c-bus at 100 {
+		compatible = "aspeed,ast2600-i2c-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#interrupt-cells = <1>;
+		reg = <0x100 0x80>, <0xC20 0x20>;
+		clocks = <&syscon ASPEED_CLK_APB2>;
+		interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+		bus-frequency = <100000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2c2_default>;
+		buff-mode;
+		status = "disabled";
+	};
+
+	i2c18: i2c-bus at 180 {
+		compatible = "aspeed,ast2600-i2c-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#interrupt-cells = <1>;
+		reg = <0x180 0x80>, <0xC40 0x20>;
+		clocks = <&syscon ASPEED_CLK_APB2>;
+		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+		bus-frequency = <100000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2c3_default>;
+		buff-mode;
+		status = "disabled";
+	};
+
+	i2c19: i2c-bus at 200 {
+		compatible = "aspeed,ast2600-i2c-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#interrupt-cells = <1>;
+		reg = <0x200 0x80>, <0xC60 0x20>;
+		clocks = <&syscon ASPEED_CLK_APB2>;
+		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+		bus-frequency = <100000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2c4_default>;
+		buff-mode;
+		status = "disabled";
+	};
+
+};
Signature · 1 line
2.17.1
author
#2 lore raw

PATCH 2/3 dt-bindings: i2c-new: Add bindings for AST2600 I2C

In reply to Jamin Lin

AST2600 support the new register set of I2C controller Add bindings document to support the new driver of I2C

---
 .../bindings/i2c/aspeed,new-i2c.yaml          | 107 ++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/aspeed,new-i2c.yaml
Documentation/devicetree/bindings/i2c/aspeed,new-i2c.yaml new file +107 -0
new file mode 100644
index 000000000000..2c264596b138
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/aspeed,new-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED I2C on the AST26XX SoCs Device Tree Bindings
+
+description: |
+  ASPEED I2C controller support the new register set since AST26XX
+  The i2c-global-regs device is used to enable new register set
+
+maintainers:
+  - Ryan Chen <[email protected]>
+
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - aspeed,ast2600-i2c-bus
+      - items:
+          - enum:
+              - aspeed,ast2600-i2c-global
+          - const: syscon
+
+  reg:
+    minItems: 1
+    maxItems: 2
+    items:
+      - description: address offset and range of bus
+      - description: address offset and range of bus buffer
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description:
+      root clock of bus, should reference the APB
+      clock in the second cell
+
+  resets:
+    maxItems: 1
+
+  bus-frequency:
+    minimum: 100
+    maximum: 5000000
+    default: 100000
+    description: frequency of the bus clock in Hz defaults to 100 kHz when not
+      specified
+
+  multi-master:
+    type: boolean
+    description:
+      states that there is another master active on this bus
+
+  buff-mode:
+    type: boolean
+    description:
+      buffer mode data transfer
+
+  byte-mode:
+    type: boolean
+    description:
+      byte mode tata transfer
+
+  smbus-alert:
+    type: boolean
+    description:
+      smbus alert protocol
+
+required:
+  - reg
+  - compatible
+  - clocks
+  - resets
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/aspeed-scu-ic.h>
+    #include <dt-bindings/clock/ast2600-clock.h>
+
+    i2c_gr: i2c-global-regs at 0 {
+      compatible = "aspeed,ast2600-i2c-global", "syscon";
+      reg = <0x0 0x20>;
+      clocks = <&syscon ASPEED_CLK_APB2>;
+      resets = <&syscon ASPEED_RESET_I2C>;
+    };
+
+    i2c0: i2c-bus at 80 {
+      compatible = "aspeed,ast2600-i2c-bus";
+      #address-cells = <1>;
+      #size-cells = <0>;
+      #interrupt-cells = <1>;
+      reg = <0x80 0x80>, <0xC00 0x20>;
+      clocks = <&syscon ASPEED_CLK_APB2>;
+      resets = <&syscon ASPEED_RESET_I2C>;
+      interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+      bus-frequency = <100000>;
+    };
Signature · 1 line
2.17.1
maintainer
#3 lore raw

Re: [PATCH 2/3] dt-bindings: i2c-new: Add bindings for AST2600 I2C

Quoted 32 lines · Jamin Lin

AST2600 support the new register set of I2C controller Add bindings document to support the new driver of I2C

---
 .../bindings/i2c/aspeed,new-i2c.yaml          | 107 ++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/aspeed,new-i2c.yaml
Documentation/devicetree/bindings/i2c/aspeed,new-i2c.yaml new file +17 -0
new file mode 100644
index 000000000000..2c264596b138
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/aspeed,new-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED I2C on the AST26XX SoCs Device Tree Bindings
+
+description: |
+  ASPEED I2C controller support the new register set since AST26XX
+  The i2c-global-regs device is used to enable new register set
+
+maintainers:
+  - Ryan Chen <[email protected]>
+
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#

Documentation/devicetree/bindings/i2c/aspeed,new-i2c.yaml line 27

Quoted 10 lines
Documentation/devicetree/bindings/i2c/aspeed,new-i2c.yaml new file +10 -0
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - aspeed,ast2600-i2c-bus
+      - items:
+          - enum:
+              - aspeed,ast2600-i2c-global

This is not an i2c controller and a separate block, so it belongs in its own binding doc.

Documentation/devicetree/bindings/i2c/aspeed,new-i2c.yaml line 32

Quoted 5 lines
Documentation/devicetree/bindings/i2c/aspeed,new-i2c.yaml new file +5 -0
+          - const: syscon
+
+  reg:
+    minItems: 1
+    maxItems: 2

Drop maxItems. 2 is implied by items length.

Quoted 79 lines
Documentation/devicetree/bindings/i2c/aspeed,new-i2c.yaml new file +75 -0
+    items:
+      - description: address offset and range of bus
+      - description: address offset and range of bus buffer
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description:
+      root clock of bus, should reference the APB
+      clock in the second cell
+
+  resets:
+    maxItems: 1
+
+  bus-frequency:
+    minimum: 100
+    maximum: 5000000
+    default: 100000
+    description: frequency of the bus clock in Hz defaults to 100 kHz when not
+      specified
+
+  multi-master:
+    type: boolean
+    description:
+      states that there is another master active on this bus
+
+  buff-mode:
+    type: boolean
+    description:
+      buffer mode data transfer
+
+  byte-mode:
+    type: boolean
+    description:
+      byte mode tata transfer
+
+  smbus-alert:
+    type: boolean
+    description:
+      smbus alert protocol
+
+required:
+  - reg
+  - compatible
+  - clocks
+  - resets
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/aspeed-scu-ic.h>
+    #include <dt-bindings/clock/ast2600-clock.h>
+
+    i2c_gr: i2c-global-regs at 0 {
+      compatible = "aspeed,ast2600-i2c-global", "syscon";
+      reg = <0x0 0x20>;
+      clocks = <&syscon ASPEED_CLK_APB2>;
+      resets = <&syscon ASPEED_RESET_I2C>;
+    };
+
+    i2c0: i2c-bus at 80 {
+      compatible = "aspeed,ast2600-i2c-bus";
+      #address-cells = <1>;
+      #size-cells = <0>;
+      #interrupt-cells = <1>;
+      reg = <0x80 0x80>, <0xC00 0x20>;
+      clocks = <&syscon ASPEED_CLK_APB2>;
+      resets = <&syscon ASPEED_RESET_I2C>;
+      interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+      bus-frequency = <100000>;
+    };
Signature · 1 line
2.17.1
author
#4 lore raw

PATCH 3/3 i2c:support new register set for ast2600

In reply to Jamin Lin

Add i2c new driver to support new register set for AST2600. AST2600 support three modes for data transfer which are byte mode, buffer mode and dma mode, respectively. The global driver of i2c is used to set the new register mode and define the base clock frequency
of baseclk_1~baseclk_4.

---
 drivers/i2c/busses/Kconfig              |   11 +
 drivers/i2c/busses/Makefile             |    1 +
 drivers/i2c/busses/ast2600-i2c-global.c |  205 +++
 drivers/i2c/busses/ast2600-i2c-global.h |   25 +
 drivers/i2c/busses/i2c-new-aspeed.c     | 1796 +++++++++++++++++++++++
 5 files changed, 2038 insertions(+)
 create mode 100644 drivers/i2c/busses/ast2600-i2c-global.c
 create mode 100644 drivers/i2c/busses/ast2600-i2c-global.h
 create mode 100644 drivers/i2c/busses/i2c-new-aspeed.c
drivers/i2c/busses/Kconfig +11 -0
index 10acece9d7b9..d348e3848746 100644
@@ -378,6 +378,17 @@ config I2C_ALTERA
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-altera.
 
+config I2C_NEW_ASPEED
+	bool "Aspeed New I2C Controller"
+	depends on ARCH_ASPEED || MACH_ASPEED_G6
+	select I2C_SMBUS
+	help
+	  If you say yes to this option, support will be included for the
+	  Aspeed I2C controller with new register set.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-new-aspeed.
+
 config I2C_ASPEED
 	tristate "Aspeed I2C Controller"
 	depends on ARCH_ASPEED || COMPILE_TEST
drivers/i2c/busses/Makefile +1 -0
index 69e9963615f6..0179bf275f78 100644
@@ -35,6 +35,7 @@ obj-$(CONFIG_I2C_POWERMAC)	+= i2c-powermac.o
 obj-$(CONFIG_I2C_ALTERA)	+= i2c-altera.o
 obj-$(CONFIG_I2C_AMD_MP2)	+= i2c-amd-mp2-pci.o i2c-amd-mp2-plat.o
 obj-$(CONFIG_I2C_ASPEED)	+= i2c-aspeed.o
+obj-$(CONFIG_I2C_NEW_ASPEED)	+= i2c-new-aspeed.o ast2600-i2c-global.o
 obj-$(CONFIG_I2C_AT91)		+= i2c-at91.o
 i2c-at91-objs			:= i2c-at91-core.o i2c-at91-master.o
 ifeq ($(CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL),y)
drivers/i2c/busses/ast2600-i2c-global.c new file +205 -0

205 lines not on this page · raw message

drivers/i2c/busses/ast2600-i2c-global.h new file +25 -0
new file mode 100644
index 000000000000..70807c37dd46
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ *	Copyright (C) ASPEED Technology Inc.
+ *	Ryan Chen <[email protected]>
+ */
+
+#ifndef AST2600_I2C_GLOBAL_H
+#define AST2600_I2C_GLOBAL_H 1
+
+#define ASPEED_I2CG_ISR				0x00
+#define ASPEED_I2CG_SLAVE_ISR		0x04	/* ast2600 */
+#define ASPEED_I2CG_OWNER			0x08
+#define ASPEED_I2CG_CTRL			0x0C
+#define ASPEED_I2CG_CLK_DIV_CTRL	0x10	/* ast2600 */
+
+/* 0x0C : I2CG SRAM Buffer Enable  */
+#define ASPEED_I2CG_SRAM_BUFFER_ENABLE		BIT(0)
+
+/* ast2600 */
+#define ASPEED_I2CG_SLAVE_PKT_NAK		BIT(4)
+#define ASPEED_I2CG_M_S_SEPARATE_INTR	BIT(3)
+#define ASPEED_I2CG_CTRL_NEW_REG		BIT(2)
+#define ASPEED_I2CG_CTRL_NEW_CLK_DIV	BIT(1)
+
+#endif /* AST2600_I2C_GLOBAL_H */
drivers/i2c/busses/i2c-new-aspeed.c new file +1796 -0

1,796 lines not on this page · raw message

Signature · 1 line
2.17.1
#5 lore raw

Re: [PATCH 3/3] i2c:support new register set for ast2600

Quoted 3 lines · Jamin Lin

Add i2c new driver to support new register set for AST2600. AST2600 support three modes for data transfer which are byte mode, buffer mode and dma mode, respectively.

DMA

Quoted 3 lines

The global driver of i2c is used to set the new register mode and define the base clock frequency
of baseclk_1~baseclk_4.

...

drivers/i2c/busses/Kconfig config I2C_ALTERA · line 382

Quoted 2 lines
drivers/i2c/busses/Kconfig +2 -0
+config I2C_NEW_ASPEED
+	bool "Aspeed New I2C Controller"

Why can't be module?

drivers/i2c/busses/Kconfig config I2C_ALTERA · line 383

Quoted 1 line
drivers/i2c/busses/Kconfig +1 -0
+	depends on ARCH_ASPEED || MACH_ASPEED_G6

COMPILE_TEST?

Quoted 1 line
drivers/i2c/busses/Kconfig +1 -0
+	select I2C_SMBUS

...

drivers/i2c/busses/ast2600-i2c-global.c line 10

Quoted 11 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +10 -0
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  Aspeed I2C Interrupt Controller.
+ *
+ *	Copyright (C) ASPEED Technology Inc.
+ *	Ryan Chen <[email protected]>
 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.

SPDX covers this.

Quoted 1 line

+ */

...

Quoted 10 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +10 -0
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>

drivers/i2c/busses/ast2600-i2c-global.c line 39

Quoted 10 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +8 -0
+#include <linux/io.h>
+#include <linux/reset.h>
+#include <linux/delay.h>
+#include <linux/clk-provider.h>
+#include "ast2600-i2c-global.h"
 
+static const struct of_device_id aspeed_i2c_ic_of_match[] = {
+	{ .compatible = "aspeed,ast2600-i2c-global", .data = (void *)0},
 
+	{ },

No need to have comma for terminator line.

Quoted 1 line

+};

No MODULE_DEVICE_TABLE()?

...

drivers/i2c/busses/ast2600-i2c-global.c line 61

Quoted 7 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +7 -0
+static const struct aspeed_i2c_base_clk i2c_base_clk[BASE_CLK_COUNT] = {
+	/* name	target_freq */
+	{  "base_clk0",	1000000 },	/* 1M */
+	{  "base_clk1",	4000000 },	/* 4M */
+	{  "base_clk2",	10000000 },	/* 10M */
+	{  "base_clk3",	40000000 },	/* 40M */
+};

Why it's not provided as the clock provider(s)?

...

drivers/i2c/busses/ast2600-i2c-global.c line 70

Quoted 8 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +8 -0
+static u32 aspeed_i2c_ic_get_new_clk_divider(unsigned long	base_clk, struct device_node *node)
+{
+	struct clk_hw_onecell_data *onecell;
+	struct clk_hw *hw;
+	int err;
+	u32 clk_divider = 0;
+	int i, j;
+	unsigned long base_freq;

Use reversed xmas tree order for all these blocks.

The rule of thumb, btw, that any comment applies to all similar places by default (independently on which line it was given against).

drivers/i2c/busses/ast2600-i2c-global.c line 73

Quoted 2 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +2 -0
+	onecell = kzalloc(sizeof(*onecell) +
+			  (BASE_CLK_COUNT * sizeof(struct clk_hw *)),

Check overflow.h for useful macros.

drivers/i2c/busses/ast2600-i2c-global.c line 75

Quoted 3 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +2 -0
+			  GFP_KERNEL);
 
+

Redundant blank line.

drivers/i2c/busses/ast2600-i2c-global.c line 77

Quoted 3 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +2 -0
+	if (!onecell) {
 
+		pr_err("allocate clk_hw\n");

Drop all these noisy useless messages.

drivers/i2c/busses/ast2600-i2c-global.c line 83

Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +6 -0
+		return 0;
+	}
+
+	onecell->num = BASE_CLK_COUNT;
+
+	pr_debug("base_clk %ld\n", base_clk);

This...

drivers/i2c/busses/ast2600-i2c-global.c line 85

Quoted 2 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +2 -0
+	for (j = 0; j < BASE_CLK_COUNT; j++) {
+		pr_debug("target clk : %ld\n", i2c_base_clk[j].base_freq);

...and this and so on...

Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +6 -0
+		for (i = 0; i < 0xff; i++) {
+			/*
+			 * i maps to div:
+			 * 0x00: div 1
+			 * 0x01: div 1.5
+			 * 0x02: div 2

drivers/i2c/busses/ast2600-i2c-global.c line 101

Quoted 10 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +10 -0
+			 * 0x03: div 2.5
+			 * 0x04: div 3
+			 * ...
+			 * 0xFE: div 128
+			 * 0xFF: div 128.5
+			 */
+			base_freq = base_clk * 2 / (2 + i);
+			if (base_freq <= i2c_base_clk[j].base_freq)
+				break;
+		}

oAre yuo sure you can't eliminate the entire for-loop? Think about it a bit, please.

drivers/i2c/busses/ast2600-i2c-global.c line 109

Quoted 9 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +8 -0
+		pr_info("i2cg - %s : %ld\n", i2c_base_clk[j].name, base_freq);
+		hw = clk_hw_register_fixed_rate(NULL, i2c_base_clk[j].name, NULL, 0, base_freq);
+		if (IS_ERR(hw)) {
+			pr_err("failed to register input clock: %ld\n", PTR_ERR(hw));
+			break;
+		}
+		onecell->hws[j] = hw;
 
+		clk_divider |= (i << (8 * j));

See above.

Quoted 8 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +8 -0
+	}
+
+	err = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, onecell);
+	if (err)
+		pr_err("failed to add i2c base clk provider: %d\n", err);
+
+	return clk_divider;
+}

...

drivers/i2c/busses/ast2600-i2c-global.c line 131

Quoted 13 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +12 -0
+static int aspeed_i2c_global_probe(struct platform_device *pdev)
+{
+	struct aspeed_i2c_ic *i2c_ic;
+	struct device_node *node = pdev->dev.of_node;
+	const struct of_device_id *match;
+	struct clk *parent_clk;
+	unsigned long	parent_clk_frequency;
+	u32 clk_divider;
+	int ret = 0;
 
+	match = of_match_node(aspeed_i2c_ic_of_match, node);
+	if (!match)
+		return -ENOMEM;

device_get_match_data()

drivers/i2c/busses/ast2600-i2c-global.c line 133

Quoted 1 line
drivers/i2c/busses/ast2600-i2c-global.c new file +1 -0
+	i2c_ic = kzalloc(sizeof(*i2c_ic), GFP_KERNEL);

devm_kzalloc()

drivers/i2c/busses/ast2600-i2c-global.c line 137

Quoted 4 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +4 -0
+	if (!i2c_ic)
+		return -ENOMEM;
+
+	i2c_ic->base = of_iomap(node, 0);

platform_get_resource

drivers/i2c/busses/ast2600-i2c-global.c line 143

Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +5 -0
+	if (!i2c_ic->base) {
+		ret = -ENOMEM;
+		goto err_free_ic;
+	}
 
+	i2c_ic->bus_num = (int)match->data;

Why not auto?

drivers/i2c/busses/ast2600-i2c-global.c line 146

Quoted 2 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +2 -0
+	if (i2c_ic->bus_num) {
+		i2c_ic->parent_irq = irq_of_parse_and_map(node, 0);

platform_get_irq()

drivers/i2c/busses/ast2600-i2c-global.c line 154

Quoted 9 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +7 -0
+		if (i2c_ic->parent_irq < 0) {
+			ret = i2c_ic->parent_irq;
+			goto err_iounmap;
+		}
+	}
 
+	i2c_ic->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 
+

Redundant.

drivers/i2c/busses/ast2600-i2c-global.c line 157

Quoted 4 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +3 -0
+	if (IS_ERR(i2c_ic->rst)) {
 
+		dev_dbg(&pdev->dev,
+			"missing or invalid reset controller device tree entry");

Make it optional.

Quoted 30 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +30 -0
+	} else {
+		/* SCU I2C Reset */
+		reset_control_assert(i2c_ic->rst);
+		udelay(3);
+		reset_control_deassert(i2c_ic->rst);
+	}
+
+	/* ast2600 init */
+	writel(ASPEED_I2CG_SLAVE_PKT_NAK |
+	       ASPEED_I2CG_CTRL_NEW_REG |
+	       ASPEED_I2CG_CTRL_NEW_CLK_DIV,
+	       i2c_ic->base + ASPEED_I2CG_CTRL);
+	parent_clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(parent_clk))
+		return PTR_ERR(parent_clk);
+	parent_clk_frequency = clk_get_rate(parent_clk);
+	pr_debug("parent_clk_frequency %ld\n", parent_clk_frequency);
+	clk_divider = aspeed_i2c_ic_get_new_clk_divider(parent_clk_frequency, node);
+	writel(clk_divider, i2c_ic->base + ASPEED_I2CG_CLK_DIV_CTRL);
+
+	pr_info("i2c global registered\n");
+
+	return 0;
+
+err_iounmap:
+	iounmap(i2c_ic->base);
+err_free_ic:
+	kfree(i2c_ic);
+	return ret;
+}

...

drivers/i2c/busses/ast2600-i2c-global.h line 8

Quoted 2 lines
drivers/i2c/busses/ast2600-i2c-global.h new file +2 -0
+#ifndef AST2600_I2C_GLOBAL_H
+#define AST2600_I2C_GLOBAL_H 1

Missed bits.h

Quoted 1 line

+#endif /* AST2600_I2C_GLOBAL_H */

...

Quoted 2 lines

+/*
+ * i2c-new-aspeed.c - I2C driver for the Aspeed SoC

It's a bad idea to put file name inside the file.

Quoted 5 lines

+ *
+ * Copyright (C) ASPEED Technology Inc.
+ * Ryan Chen <[email protected]>
+ *
+ */

...

Quoted 1 line

+#define AST_I2CC_TX_DIR_MASK (0x7 << 29)

GENMASK()

...

drivers/i2c/busses/i2c-new-aspeed.c line 75

Quoted 4 lines
drivers/i2c/busses/i2c-new-aspeed.c new file +4 -0
+#define AST_I2CC_GET_RX_BUF_LEN(x)		(((x) >> 24) & 0x3f)
+#define AST_I2CC_SET_RX_BUF_LEN(x)		((((x) - 1) & 0x1f) << 16)
+#define AST_I2CC_SET_TX_BUF_LEN(x)		((((x) - 1) & 0x1f) << 8)
+#define AST_I2CC_GET_TX_BUF_LEN(x)		((((x) >> 8) & 0x1f) + 1)

Ditto.

...

Quoted 1 line

+static struct ast_i2c_timing_table aspeed_old_i2c_timing_table[] = {

What the ... is this for?!

Quoted 141 lines
drivers/i2c/busses/i2c-new-aspeed.c new file +141 -0
+	/* Divisor : Base Clock : tCKHighMin : tCK High : tCK Low  */
+	/* Divisor :	  [3:0] : [23: 20]   :   [19:16]:   [15:12] */
+	{ 6, 0x00000300 | (0x0) | (0x2 << 20) | (0x2 << 16) | (0x2 << 12) },
+	{ 7, 0x00000300 | (0x0) | (0x3 << 20) | (0x3 << 16) | (0x2 << 12) },
+	{ 8, 0x00000300 | (0x0) | (0x3 << 20) | (0x3 << 16) | (0x3 << 12) },
+	{ 9, 0x00000300 | (0x0) | (0x4 << 20) | (0x4 << 16) | (0x3 << 12) },
+	{ 10, 0x00000300 | (0x0) | (0x4 << 20) | (0x4 << 16) | (0x4 << 12) },
+	{ 11, 0x00000300 | (0x0) | (0x5 << 20) | (0x5 << 16) | (0x4 << 12) },
+	{ 12, 0x00000300 | (0x0) | (0x5 << 20) | (0x5 << 16) | (0x5 << 12) },
+	{ 13, 0x00000300 | (0x0) | (0x6 << 20) | (0x6 << 16) | (0x5 << 12) },
+	{ 14, 0x00000300 | (0x0) | (0x6 << 20) | (0x6 << 16) | (0x6 << 12) },
+	{ 15, 0x00000300 | (0x0) | (0x7 << 20) | (0x7 << 16) | (0x6 << 12) },
+	{ 16, 0x00000300 | (0x0) | (0x7 << 20) | (0x7 << 16) | (0x7 << 12) },
+	{ 17, 0x00000300 | (0x0) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 18, 0x00000300 | (0x0) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 19, 0x00000300 | (0x0) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 20, 0x00000300 | (0x0) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 21, 0x00000300 | (0x0) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 22, 0x00000300 | (0x0) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 23, 0x00000300 | (0x0) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 24, 0x00000300 | (0x0) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 25, 0x00000300 | (0x0) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 26, 0x00000300 | (0x0) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 27, 0x00000300 | (0x0) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 28, 0x00000300 | (0x0) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 29, 0x00000300 | (0x0) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 30, 0x00000300 | (0x0) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 31, 0x00000300 | (0x0) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 32, 0x00000300 | (0x0) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 34, 0x00000300 | (0x1) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 36, 0x00000300 | (0x1) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 38, 0x00000300 | (0x1) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 40, 0x00000300 | (0x1) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 42, 0x00000300 | (0x1) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 44, 0x00000300 | (0x1) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 46, 0x00000300 | (0x1) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 48, 0x00000300 | (0x1) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 50, 0x00000300 | (0x1) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 52, 0x00000300 | (0x1) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 54, 0x00000300 | (0x1) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 56, 0x00000300 | (0x1) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 58, 0x00000300 | (0x1) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 60, 0x00000300 | (0x1) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 62, 0x00000300 | (0x1) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 64, 0x00000300 | (0x1) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 68, 0x00000300 | (0x2) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 72, 0x00000300 | (0x2) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 76, 0x00000300 | (0x2) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 80, 0x00000300 | (0x2) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 84, 0x00000300 | (0x2) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 88, 0x00000300 | (0x2) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 92, 0x00000300 | (0x2) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 96, 0x00000300 | (0x2) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 100, 0x00000300 | (0x2) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 104, 0x00000300 | (0x2) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 108, 0x00000300 | (0x2) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 112, 0x00000300 | (0x2) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 116, 0x00000300 | (0x2) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 120, 0x00000300 | (0x2) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 124, 0x00000300 | (0x2) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 128, 0x00000300 | (0x2) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 136, 0x00000300 | (0x3) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 144, 0x00000300 | (0x3) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 152, 0x00000300 | (0x3) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 160, 0x00000300 | (0x3) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 168, 0x00000300 | (0x3) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 176, 0x00000300 | (0x3) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 184, 0x00000300 | (0x3) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 192, 0x00000300 | (0x3) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 200, 0x00000300 | (0x3) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 208, 0x00000300 | (0x3) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 216, 0x00000300 | (0x3) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 224, 0x00000300 | (0x3) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 232, 0x00000300 | (0x3) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 240, 0x00000300 | (0x3) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 248, 0x00000300 | (0x3) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 256, 0x00000300 | (0x3) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 272, 0x00000300 | (0x4) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 288, 0x00000300 | (0x4) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 304, 0x00000300 | (0x4) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 320, 0x00000300 | (0x4) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 336, 0x00000300 | (0x4) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 352, 0x00000300 | (0x4) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 368, 0x00000300 | (0x4) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 384, 0x00000300 | (0x4) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 400, 0x00000300 | (0x4) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 416, 0x00000300 | (0x4) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 432, 0x00000300 | (0x4) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 448, 0x00000300 | (0x4) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 464, 0x00000300 | (0x4) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 480, 0x00000300 | (0x4) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 496, 0x00000300 | (0x4) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 512, 0x00000300 | (0x4) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 544, 0x00000300 | (0x5) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 576, 0x00000300 | (0x5) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 608, 0x00000300 | (0x5) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 640, 0x00000300 | (0x5) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 672, 0x00000300 | (0x5) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 704, 0x00000300 | (0x5) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 736, 0x00000300 | (0x5) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 768, 0x00000300 | (0x5) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 800, 0x00000300 | (0x5) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 832, 0x00000300 | (0x5) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 864, 0x00000300 | (0x5) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 896, 0x00000300 | (0x5) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 928, 0x00000300 | (0x5) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 960, 0x00000300 | (0x5) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 992, 0x00000300 | (0x5) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 1024, 0x00000300 | (0x5) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 1088, 0x00000300 | (0x6) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 1152, 0x00000300 | (0x6) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 1216, 0x00000300 | (0x6) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 1280, 0x00000300 | (0x6) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 1344, 0x00000300 | (0x6) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 1408, 0x00000300 | (0x6) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 1472, 0x00000300 | (0x6) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 1536, 0x00000300 | (0x6) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 1600, 0x00000300 | (0x6) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 1664, 0x00000300 | (0x6) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 1728, 0x00000300 | (0x6) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 1792, 0x00000300 | (0x6) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 1856, 0x00000300 | (0x6) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 1920, 0x00000300 | (0x6) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 1984, 0x00000300 | (0x6) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 2048, 0x00000300 | (0x6) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 2176, 0x00000300 | (0x7) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 2304, 0x00000300 | (0x7) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 2432, 0x00000300 | (0x7) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 2560, 0x00000300 | (0x7) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 2688, 0x00000300 | (0x7) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 2816, 0x00000300 | (0x7) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 2944, 0x00000300 | (0x7) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 3072, 0x00000300 | (0x7) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+};

...

drivers/i2c/busses/i2c-new-aspeed.c line 373

Quoted 6 lines
drivers/i2c/busses/i2c-new-aspeed.c new file +5 -0
+enum xfer_mode {
+	BYTE_MODE = 0,
+	BUFF_MODE,
+	DMA_MODE,
 
+

Redundant blank line.

Quoted 1 line

+};

Signature · 2 lines
With Best Regards,
Andy Shevchenko
author
#6 lore raw

Re: [PATCH 3/3] i2c:support new register set for ast2600

Quoted 6 lines · Andy Shevchenko
Quoted 3 lines · Jamin Lin

Add i2c new driver to support new register set for AST2600. AST2600 support three modes for data transfer which are byte mode, buffer mode and dma mode, respectively.

DMA

Will update

Quoted 5 lines
Quoted 4 lines

The global driver of i2c is used to set the new register mode and define the base clock frequency
of baseclk_1~baseclk_4.

Quoted 7 lines

...

drivers/i2c/busses/Kconfig config I2C_ALTERA · line 382

Quoted 2 lines
drivers/i2c/busses/Kconfig +2 -0
+config I2C_NEW_ASPEED
+	bool "Aspeed New I2C Controller"

Why can't be module?

Will update tristate

Quoted 4 lines

drivers/i2c/busses/Kconfig config I2C_ALTERA · line 383

Quoted 1 line
drivers/i2c/busses/Kconfig +1 -0
+	depends on ARCH_ASPEED || MACH_ASPEED_G6

COMPILE_TEST?

Will add ARCH_ASPEED || MACH_ASPEED_G6 || COMPILE_TEST

Quoted 11 lines
Quoted 1 line
drivers/i2c/busses/Kconfig +1 -0
+	select I2C_SMBUS

...

Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +6 -0
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  Aspeed I2C Interrupt Controller.
+ *
+ *	Copyright (C) ASPEED Technology Inc.
+ *	Ryan Chen <[email protected]>
Quoted 7 lines
Quoted 4 lines

+ *

+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.

SPDX covers this.

Will change as following what do you think?
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Aspeed I2C Interrupt Controller.
* Copyright (C) ASPEED Technology Inc.
* Ryan Chen <[email protected]>
*/

Quoted 19 lines

...

Quoted 15 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +15 -0
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+#include <linux/reset.h>
+#include <linux/delay.h>
+#include <linux/clk-provider.h>
+#include "ast2600-i2c-global.h"
Quoted 7 lines

drivers/i2c/busses/ast2600-i2c-global.c line 39

Quoted 4 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +3 -0
+static const struct of_device_id aspeed_i2c_ic_of_match[] = {
+	{ .compatible = "aspeed,ast2600-i2c-global", .data = (void *)0},
 
+	{ },

No need to have comma for terminator line.

Will update

Quoted 16 lines
Quoted 1 line

+};

No MODULE_DEVICE_TABLE()?

...

drivers/i2c/busses/ast2600-i2c-global.c line 61

Quoted 7 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +7 -0
+static const struct aspeed_i2c_base_clk i2c_base_clk[BASE_CLK_COUNT] = {
+	/* name	target_freq */
+	{  "base_clk0",	1000000 },	/* 1M */
+	{  "base_clk1",	4000000 },	/* 4M */
+	{  "base_clk2",	10000000 },	/* 10M */
+	{  "base_clk3",	40000000 },	/* 40M */
+};

Why it's not provided as the clock provider(s)?

Quoted 1 line

...

According to the design of ASPEED AST2600 SOC, the I2C bus is connected to PHB bus. The clock driver provides PHB clock and its default frequency is 100MHZ. AST2600 support the bus frequency of I2C from 0.1kbps to 5Mbps if PHB clock is 50MHZ. To meet the different bus frequency of I2C, we use this programmer to calculate the divider to change the base clock.
For example,
It calculates divider to change base_clock 1 to 1M to support I2C bus frequency 100KHZ It calculates divider to change base_clock 2 to 4M to support I2C bus frequency 400KHZ

Quoted 12 lines

drivers/i2c/busses/ast2600-i2c-global.c line 70

Quoted 9 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +8 -0
+static u32 aspeed_i2c_ic_get_new_clk_divider(unsigned long	base_clk, struct device_node *node)
+{
+	struct clk_hw_onecell_data *onecell;
+	struct clk_hw *hw;
+	int err;
+	u32 clk_divider = 0;
+	int i, j;
+	unsigned long base_freq;

Use reversed xmas tree order for all these blocks.

Quoted 3 lines

The rule of thumb, btw, that any comment applies to all similar places by default (independently on which line it was given against).

Do you mena change as following?
struct clk_hw_onecell_data *onecell;
unsigned long base_freq;
u32 clk_divider = 0;
struct clk_hw *hw;
int err;
int i;
int j;

Quoted 5 lines

drivers/i2c/busses/ast2600-i2c-global.c line 73

Quoted 2 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +2 -0
+	onecell = kzalloc(sizeof(*onecell) +
+			  (BASE_CLK_COUNT * sizeof(struct clk_hw *)),

Check overflow.h for useful macros.

Will check

Quoted 6 lines

drivers/i2c/busses/ast2600-i2c-global.c line 75

Quoted 3 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +2 -0
+			  GFP_KERNEL);
 
+

Redundant blank line.

Will update

Quoted 6 lines

drivers/i2c/busses/ast2600-i2c-global.c line 77

Quoted 3 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +2 -0
+	if (!onecell) {
 
+		pr_err("allocate clk_hw\n");

Drop all these noisy useless messages.

Will update

Quoted 9 lines

drivers/i2c/busses/ast2600-i2c-global.c line 83

Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +6 -0
+		return 0;
+	}
+
+	onecell->num = BASE_CLK_COUNT;
+
+	pr_debug("base_clk %ld\n", base_clk);

This...

Will update

Quoted 5 lines

drivers/i2c/busses/ast2600-i2c-global.c line 85

Quoted 2 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +2 -0
+	for (j = 0; j < BASE_CLK_COUNT; j++) {
+		pr_debug("target clk : %ld\n", i2c_base_clk[j].base_freq);

...and this and so on...

Will update

Quoted 11 lines
Quoted 11 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +11 -0
+		for (i = 0; i < 0xff; i++) {
+			/*
+			 * i maps to div:
+			 * 0x00: div 1
+			 * 0x01: div 1.5
+			 * 0x02: div 2
+			 * 0x03: div 2.5
+			 * 0x04: div 3
+			 * ...
+			 * 0xFE: div 128
+			 * 0xFF: div 128.5
Quoted 9 lines

drivers/i2c/busses/ast2600-i2c-global.c line 101

Quoted 5 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +5 -0
+			 */
+			base_freq = base_clk * 2 / (2 + i);
+			if (base_freq <= i2c_base_clk[j].base_freq)
+				break;
+		}

oAre yuo sure you can't eliminate the entire for-loop? Think about it a bit, please.

What do you think if we use "lookup table" instaed of above for loop?

Quoted 11 lines

drivers/i2c/busses/ast2600-i2c-global.c line 109

Quoted 9 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +8 -0
+		pr_info("i2cg - %s : %ld\n", i2c_base_clk[j].name, base_freq);
+		hw = clk_hw_register_fixed_rate(NULL, i2c_base_clk[j].name, NULL, 0, base_freq);
+		if (IS_ERR(hw)) {
+			pr_err("failed to register input clock: %ld\n", PTR_ERR(hw));
+			break;
+		}
+		onecell->hws[j] = hw;
 
+		clk_divider |= (i << (8 * j));

See above.

Will think a solution

Quoted 21 lines
Quoted 8 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +8 -0
+	}
+
+	err = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, onecell);
+	if (err)
+		pr_err("failed to add i2c base clk provider: %d\n", err);
+
+	return clk_divider;
+}

...

Quoted 9 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +9 -0
+static int aspeed_i2c_global_probe(struct platform_device *pdev)
+{
+	struct aspeed_i2c_ic *i2c_ic;
+	struct device_node *node = pdev->dev.of_node;
+	const struct of_device_id *match;
+	struct clk *parent_clk;
+	unsigned long	parent_clk_frequency;
+	u32 clk_divider;
+	int ret = 0;
Quoted 5 lines

drivers/i2c/busses/ast2600-i2c-global.c line 131

Quoted 3 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +3 -0
+	match = of_match_node(aspeed_i2c_ic_of_match, node);
+	if (!match)
+		return -ENOMEM;

device_get_match_data()

will update

Quoted 3 lines

drivers/i2c/busses/ast2600-i2c-global.c line 133

Quoted 1 line
drivers/i2c/busses/ast2600-i2c-global.c new file +1 -0
+	i2c_ic = kzalloc(sizeof(*i2c_ic), GFP_KERNEL);

devm_kzalloc()

will update

Quoted 6 lines

drivers/i2c/busses/ast2600-i2c-global.c line 137

Quoted 4 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +4 -0
+	if (!i2c_ic)
+		return -ENOMEM;
+
+	i2c_ic->base = of_iomap(node, 0);

platform_get_resource

will update

Quoted 8 lines

drivers/i2c/busses/ast2600-i2c-global.c line 143

Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +5 -0
+	if (!i2c_ic->base) {
+		ret = -ENOMEM;
+		goto err_free_ic;
+	}
 
+	i2c_ic->bus_num = (int)match->data;

Why not auto?

Will try it

Quoted 4 lines

drivers/i2c/busses/ast2600-i2c-global.c line 146

Quoted 2 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +2 -0
+	if (i2c_ic->bus_num) {
+		i2c_ic->parent_irq = irq_of_parse_and_map(node, 0);

platform_get_irq()

Will update

Quoted 11 lines

drivers/i2c/busses/ast2600-i2c-global.c line 154

Quoted 9 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +7 -0
+		if (i2c_ic->parent_irq < 0) {
+			ret = i2c_ic->parent_irq;
+			goto err_iounmap;
+		}
+	}
 
+	i2c_ic->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 
+

Redundant.

Will update

Quoted 6 lines

drivers/i2c/busses/ast2600-i2c-global.c line 157

Quoted 4 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +3 -0
+	if (IS_ERR(i2c_ic->rst)) {
 
+		dev_dbg(&pdev->dev,
+			"missing or invalid reset controller device tree entry");

Make it optional.

Can I change to use "dev_err"?

Quoted 33 lines
Quoted 30 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +30 -0
+	} else {
+		/* SCU I2C Reset */
+		reset_control_assert(i2c_ic->rst);
+		udelay(3);
+		reset_control_deassert(i2c_ic->rst);
+	}
+
+	/* ast2600 init */
+	writel(ASPEED_I2CG_SLAVE_PKT_NAK |
+	       ASPEED_I2CG_CTRL_NEW_REG |
+	       ASPEED_I2CG_CTRL_NEW_CLK_DIV,
+	       i2c_ic->base + ASPEED_I2CG_CTRL);
+	parent_clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(parent_clk))
+		return PTR_ERR(parent_clk);
+	parent_clk_frequency = clk_get_rate(parent_clk);
+	pr_debug("parent_clk_frequency %ld\n", parent_clk_frequency);
+	clk_divider = aspeed_i2c_ic_get_new_clk_divider(parent_clk_frequency, node);
+	writel(clk_divider, i2c_ic->base + ASPEED_I2CG_CLK_DIV_CTRL);
+
+	pr_info("i2c global registered\n");
+
+	return 0;
+
+err_iounmap:
+	iounmap(i2c_ic->base);
+err_free_ic:
+	kfree(i2c_ic);
+	return ret;
+}

...

Quoted 5 lines

drivers/i2c/busses/ast2600-i2c-global.h line 8

Quoted 2 lines
drivers/i2c/busses/ast2600-i2c-global.h new file +2 -0
+#ifndef AST2600_I2C_GLOBAL_H
+#define AST2600_I2C_GLOBAL_H 1

Missed bits.h

Will update as following
#ifndef AST2600_I2C_GLOBAL_H
#define AST2600_I2C_GLOBAL_H
#include <linux/bits.h>

Quoted 9 lines
Quoted 1 line

+#endif /* AST2600_I2C_GLOBAL_H */

...

Quoted 2 lines

+/*
+ * i2c-new-aspeed.c - I2C driver for the Aspeed SoC

It's a bad idea to put file name inside the file.

Thanks for suggestion
Will update to "I2C driver for the Aspeed SoC"

Quoted 12 lines
Quoted 5 lines

+ *
+ * Copyright (C) ASPEED Technology Inc.
+ * Ryan Chen <[email protected]>
+ *
+ */

...

Quoted 1 line

+#define AST_I2CC_TX_DIR_MASK (0x7 << 29)

GENMASK()

Quoted 9 lines

...

drivers/i2c/busses/i2c-new-aspeed.c line 75

Quoted 4 lines
drivers/i2c/busses/i2c-new-aspeed.c new file +4 -0
+#define AST_I2CC_GET_RX_BUF_LEN(x)		(((x) >> 24) & 0x3f)
+#define AST_I2CC_SET_RX_BUF_LEN(x)		((((x) - 1) & 0x1f) << 16)
+#define AST_I2CC_SET_TX_BUF_LEN(x)		((((x) - 1) & 0x1f) << 8)
+#define AST_I2CC_GET_TX_BUF_LEN(x)		((((x) >> 8) & 0x1f) + 1)

Ditto.

Will update and try to use GENMASK

Quoted 5 lines

...

Quoted 1 line

+static struct ast_i2c_timing_table aspeed_old_i2c_timing_table[] = {

What the ... is this for?!

AST2600 support old/new register set for I2C controller.
This lookup table is used to find the divisor for the specific I2C bus frequency for AST2600 I2C controller with old register set.
For example
If I2C bus frequency is 100KHZ and PHB clock is 100MHZ, it will find this table because 100000000/1024 < 100000
"{ 1024, 0x00000300 | (0x5) | (0xf << 20) | (0xf << 16) | (0xf << 12) }"

Quoted 145 lines
Quoted 142 lines
drivers/i2c/busses/i2c-new-aspeed.c new file +141 -0
+	/* Divisor : Base Clock : tCKHighMin : tCK High : tCK Low  */
+	/* Divisor :	  [3:0] : [23: 20]   :   [19:16]:   [15:12] */
+	{ 6, 0x00000300 | (0x0) | (0x2 << 20) | (0x2 << 16) | (0x2 << 12) },
+	{ 7, 0x00000300 | (0x0) | (0x3 << 20) | (0x3 << 16) | (0x2 << 12) },
+	{ 8, 0x00000300 | (0x0) | (0x3 << 20) | (0x3 << 16) | (0x3 << 12) },
+	{ 9, 0x00000300 | (0x0) | (0x4 << 20) | (0x4 << 16) | (0x3 << 12) },
+	{ 10, 0x00000300 | (0x0) | (0x4 << 20) | (0x4 << 16) | (0x4 << 12) },
+	{ 11, 0x00000300 | (0x0) | (0x5 << 20) | (0x5 << 16) | (0x4 << 12) },
+	{ 12, 0x00000300 | (0x0) | (0x5 << 20) | (0x5 << 16) | (0x5 << 12) },
+	{ 13, 0x00000300 | (0x0) | (0x6 << 20) | (0x6 << 16) | (0x5 << 12) },
+	{ 14, 0x00000300 | (0x0) | (0x6 << 20) | (0x6 << 16) | (0x6 << 12) },
+	{ 15, 0x00000300 | (0x0) | (0x7 << 20) | (0x7 << 16) | (0x6 << 12) },
+	{ 16, 0x00000300 | (0x0) | (0x7 << 20) | (0x7 << 16) | (0x7 << 12) },
+	{ 17, 0x00000300 | (0x0) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 18, 0x00000300 | (0x0) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 19, 0x00000300 | (0x0) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 20, 0x00000300 | (0x0) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 21, 0x00000300 | (0x0) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 22, 0x00000300 | (0x0) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 23, 0x00000300 | (0x0) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 24, 0x00000300 | (0x0) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 25, 0x00000300 | (0x0) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 26, 0x00000300 | (0x0) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 27, 0x00000300 | (0x0) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 28, 0x00000300 | (0x0) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 29, 0x00000300 | (0x0) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 30, 0x00000300 | (0x0) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 31, 0x00000300 | (0x0) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 32, 0x00000300 | (0x0) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 34, 0x00000300 | (0x1) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 36, 0x00000300 | (0x1) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 38, 0x00000300 | (0x1) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 40, 0x00000300 | (0x1) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 42, 0x00000300 | (0x1) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 44, 0x00000300 | (0x1) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 46, 0x00000300 | (0x1) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 48, 0x00000300 | (0x1) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 50, 0x00000300 | (0x1) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 52, 0x00000300 | (0x1) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 54, 0x00000300 | (0x1) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 56, 0x00000300 | (0x1) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 58, 0x00000300 | (0x1) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 60, 0x00000300 | (0x1) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 62, 0x00000300 | (0x1) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 64, 0x00000300 | (0x1) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 68, 0x00000300 | (0x2) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 72, 0x00000300 | (0x2) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 76, 0x00000300 | (0x2) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 80, 0x00000300 | (0x2) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 84, 0x00000300 | (0x2) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 88, 0x00000300 | (0x2) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 92, 0x00000300 | (0x2) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 96, 0x00000300 | (0x2) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 100, 0x00000300 | (0x2) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 104, 0x00000300 | (0x2) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 108, 0x00000300 | (0x2) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 112, 0x00000300 | (0x2) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 116, 0x00000300 | (0x2) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 120, 0x00000300 | (0x2) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 124, 0x00000300 | (0x2) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 128, 0x00000300 | (0x2) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 136, 0x00000300 | (0x3) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 144, 0x00000300 | (0x3) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 152, 0x00000300 | (0x3) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 160, 0x00000300 | (0x3) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 168, 0x00000300 | (0x3) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 176, 0x00000300 | (0x3) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 184, 0x00000300 | (0x3) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 192, 0x00000300 | (0x3) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 200, 0x00000300 | (0x3) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 208, 0x00000300 | (0x3) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 216, 0x00000300 | (0x3) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 224, 0x00000300 | (0x3) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 232, 0x00000300 | (0x3) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 240, 0x00000300 | (0x3) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 248, 0x00000300 | (0x3) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 256, 0x00000300 | (0x3) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 272, 0x00000300 | (0x4) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 288, 0x00000300 | (0x4) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 304, 0x00000300 | (0x4) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 320, 0x00000300 | (0x4) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 336, 0x00000300 | (0x4) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 352, 0x00000300 | (0x4) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 368, 0x00000300 | (0x4) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 384, 0x00000300 | (0x4) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 400, 0x00000300 | (0x4) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 416, 0x00000300 | (0x4) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 432, 0x00000300 | (0x4) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 448, 0x00000300 | (0x4) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 464, 0x00000300 | (0x4) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 480, 0x00000300 | (0x4) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 496, 0x00000300 | (0x4) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 512, 0x00000300 | (0x4) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 544, 0x00000300 | (0x5) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 576, 0x00000300 | (0x5) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 608, 0x00000300 | (0x5) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 640, 0x00000300 | (0x5) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 672, 0x00000300 | (0x5) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 704, 0x00000300 | (0x5) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 736, 0x00000300 | (0x5) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 768, 0x00000300 | (0x5) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 800, 0x00000300 | (0x5) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 832, 0x00000300 | (0x5) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 864, 0x00000300 | (0x5) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 896, 0x00000300 | (0x5) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 928, 0x00000300 | (0x5) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 960, 0x00000300 | (0x5) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 992, 0x00000300 | (0x5) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 1024, 0x00000300 | (0x5) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 1088, 0x00000300 | (0x6) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 1152, 0x00000300 | (0x6) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 1216, 0x00000300 | (0x6) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 1280, 0x00000300 | (0x6) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 1344, 0x00000300 | (0x6) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 1408, 0x00000300 | (0x6) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 1472, 0x00000300 | (0x6) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 1536, 0x00000300 | (0x6) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+	{ 1600, 0x00000300 | (0x6) | (0xc << 20) | (0xc << 16) | (0xb << 12) },
+	{ 1664, 0x00000300 | (0x6) | (0xc << 20) | (0xc << 16) | (0xc << 12) },
+	{ 1728, 0x00000300 | (0x6) | (0xd << 20) | (0xd << 16) | (0xc << 12) },
+	{ 1792, 0x00000300 | (0x6) | (0xd << 20) | (0xd << 16) | (0xd << 12) },
+	{ 1856, 0x00000300 | (0x6) | (0xe << 20) | (0xe << 16) | (0xd << 12) },
+	{ 1920, 0x00000300 | (0x6) | (0xe << 20) | (0xe << 16) | (0xe << 12) },
+	{ 1984, 0x00000300 | (0x6) | (0xf << 20) | (0xf << 16) | (0xe << 12) },
+	{ 2048, 0x00000300 | (0x6) | (0xf << 20) | (0xf << 16) | (0xf << 12) },
+
+	{ 2176, 0x00000300 | (0x7) | (0x8 << 20) | (0x8 << 16) | (0x7 << 12) },
+	{ 2304, 0x00000300 | (0x7) | (0x8 << 20) | (0x8 << 16) | (0x8 << 12) },
+	{ 2432, 0x00000300 | (0x7) | (0x9 << 20) | (0x9 << 16) | (0x8 << 12) },
+	{ 2560, 0x00000300 | (0x7) | (0x9 << 20) | (0x9 << 16) | (0x9 << 12) },
+	{ 2688, 0x00000300 | (0x7) | (0xa << 20) | (0xa << 16) | (0x9 << 12) },
+	{ 2816, 0x00000300 | (0x7) | (0xa << 20) | (0xa << 16) | (0xa << 12) },
+	{ 2944, 0x00000300 | (0x7) | (0xb << 20) | (0xb << 16) | (0xa << 12) },
+	{ 3072, 0x00000300 | (0x7) | (0xb << 20) | (0xb << 16) | (0xb << 12) },
+};

...

Quoted 9 lines

drivers/i2c/busses/i2c-new-aspeed.c line 373

Quoted 6 lines
drivers/i2c/busses/i2c-new-aspeed.c new file +5 -0
+enum xfer_mode {
+	BYTE_MODE = 0,
+	BUFF_MODE,
+	DMA_MODE,
 
+

Redundant blank line.

Will update

Quoted 7 lines
Quoted 1 line

+};

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#7 lore raw

Re: [PATCH 3/3] i2c:support new register set for ast2600

Quoted 2 lines · Jamin Lin
Quoted 1 line · Andy Shevchenko

On Thu, Jun 17, 2021 at 05:43:40PM +0800, Jamin Lin wrote:

...

Quoted 7 lines
Quoted 7 lines
Quoted 4 lines

+ *

+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.

SPDX covers this.

Quoted 7 lines

Will change as following what do you think?
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Aspeed I2C Interrupt Controller.
* Copyright (C) ASPEED Technology Inc.
* Ryan Chen <[email protected]>
*/

Yes, something like this.

...

Quoted 10 lines
Quoted 9 lines

drivers/i2c/busses/ast2600-i2c-global.c line 61

Quoted 7 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +7 -0
+static const struct aspeed_i2c_base_clk i2c_base_clk[BASE_CLK_COUNT] = {
+	/* name	target_freq */
+	{  "base_clk0",	1000000 },	/* 1M */
+	{  "base_clk1",	4000000 },	/* 4M */
+	{  "base_clk2",	10000000 },	/* 10M */
+	{  "base_clk3",	40000000 },	/* 40M */
+};

Why it's not provided as the clock provider(s)?

Quoted 8 lines

According to the design of ASPEED AST2600 SOC, the I2C bus is connected to PHB bus. The clock driver provides PHB clock and its default frequency is 100MHZ. AST2600 support the bus frequency of I2C from 0.1kbps to 5Mbps if PHB clock is 50MHZ. To meet the different bus frequency of I2C, we use this programmer to calculate the divider to change the base clock.
For example,
It calculates divider to change base_clock 1 to 1M to support I2C bus frequency 100KHZ It calculates divider to change base_clock 2 to 4M to support I2C bus frequency 400KHZ

My question is, why don't you provide a clock provider (under drivers/clk) for this platform and use it instead?

...

Quoted 12 lines
Quoted 9 lines

drivers/i2c/busses/ast2600-i2c-global.c line 70

Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +6 -0
+	struct clk_hw_onecell_data *onecell;
+	struct clk_hw *hw;
+	int err;
+	u32 clk_divider = 0;
+	int i, j;
+	unsigned long base_freq;

Use reversed xmas tree order for all these blocks.

Quoted 3 lines

The rule of thumb, btw, that any comment applies to all similar places by default (independently on which line it was given against).

Quoted 8 lines

Do you mena change as following?
struct clk_hw_onecell_data *onecell;
unsigned long base_freq;
u32 clk_divider = 0;
struct clk_hw *hw;
int err;
int i;
int j;

Yes.

...

Quoted 20 lines
Quoted 11 lines
Quoted 11 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +11 -0
+		for (i = 0; i < 0xff; i++) {
+			/*
+			 * i maps to div:
+			 * 0x00: div 1
+			 * 0x01: div 1.5
+			 * 0x02: div 2
+			 * 0x03: div 2.5
+			 * 0x04: div 3
+			 * ...
+			 * 0xFE: div 128
+			 * 0xFF: div 128.5
Quoted 9 lines

drivers/i2c/busses/ast2600-i2c-global.c line 101

Quoted 5 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +5 -0
+			 */
+			base_freq = base_clk * 2 / (2 + i);
+			if (base_freq <= i2c_base_clk[j].base_freq)
+				break;
+		}

oAre yuo sure you can't eliminate the entire for-loop? Think about it a bit, please.

Quoted 1 line

What do you think if we use "lookup table" instaed of above for loop?

Besides that it should be a part of clock provider, no, you may use a formula (bit operations and so on).

...

Quoted 9 lines
Quoted 8 lines

drivers/i2c/busses/ast2600-i2c-global.c line 157

Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +4 -0
+	i2c_ic->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 
+	if (IS_ERR(i2c_ic->rst)) {
 
+		dev_dbg(&pdev->dev,
+			"missing or invalid reset controller device tree entry");

Make it optional.

Can I change to use "dev_err"?

What I meant here is to make the reset optional (there is even specific API for that) and return an error in that case.

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +6 -0
+	} else {
+		/* SCU I2C Reset */
+		reset_control_assert(i2c_ic->rst);
+		udelay(3);
+		reset_control_deassert(i2c_ic->rst);
+	}

...

Quoted 10 lines
Quoted 3 lines
Quoted 1 line

+static struct ast_i2c_timing_table aspeed_old_i2c_timing_table[] = {

What the ... is this for?!

AST2600 support old/new register set for I2C controller.
This lookup table is used to find the divisor for the specific I2C bus frequency for AST2600 I2C controller with old register set.
For example
If I2C bus frequency is 100KHZ and PHB clock is 100MHZ, it will find this table because 100000000/1024 < 100000
"{ 1024, 0x00000300 | (0x5) | (0xf << 20) | (0xf << 16) | (0xf << 12) }"

Can't you derive it by formula(s)?

Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
drivers/i2c/busses/i2c-new-aspeed.c new file +3 -0
+	/* Divisor : Base Clock : tCKHighMin : tCK High : tCK Low  */
+	/* Divisor :	  [3:0] : [23: 20]   :   [19:16]:   [15:12] */
 
+};
Signature · 2 lines
With Best Regards,
Andy Shevchenko
author
#8 lore raw

Re: [PATCH 3/3] i2c:support new register set for ast2600

Quoted 21 lines · Andy Shevchenko
Quoted 2 lines · Jamin Lin
Quoted 1 line · Andy Shevchenko

On Thu, Jun 17, 2021 at 05:43:40PM +0800, Jamin Lin wrote:

...

Quoted 7 lines
Quoted 7 lines
Quoted 4 lines

+ *

+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.

SPDX covers this.

Quoted 7 lines

Will change as following what do you think?
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Aspeed I2C Interrupt Controller.
* Copyright (C) ASPEED Technology Inc.
* Ryan Chen <[email protected]>
*/

Quoted 14 lines

Yes, something like this.

...

Quoted 9 lines
Quoted 9 lines

drivers/i2c/busses/ast2600-i2c-global.c line 61

Quoted 7 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +7 -0
+static const struct aspeed_i2c_base_clk i2c_base_clk[BASE_CLK_COUNT] = {
+	/* name	target_freq */
+	{  "base_clk0",	1000000 },	/* 1M */
+	{  "base_clk1",	4000000 },	/* 4M */
+	{  "base_clk2",	10000000 },	/* 10M */
+	{  "base_clk3",	40000000 },	/* 40M */
+};

Why it's not provided as the clock provider(s)?

Will try it

Quoted 11 lines
Quoted 8 lines

According to the design of ASPEED AST2600 SOC, the I2C bus is connected to PHB bus. The clock driver provides PHB clock and its default frequency is 100MHZ. AST2600 support the bus frequency of I2C from 0.1kbps to 5Mbps if PHB clock is 50MHZ. To meet the different bus frequency of I2C, we use this programmer to calculate the divider to change the base clock.
For example,
It calculates divider to change base_clock 1 to 1M to support I2C bus frequency 100KHZ It calculates divider to change base_clock 2 to 4M to support I2C bus frequency 400KHZ

My question is, why don't you provide a clock provider (under drivers/clk) for this platform and use it instead?

Will try it

Quoted 48 lines

...

Quoted 12 lines
Quoted 9 lines

drivers/i2c/busses/ast2600-i2c-global.c line 70

Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +6 -0
+	struct clk_hw_onecell_data *onecell;
+	struct clk_hw *hw;
+	int err;
+	u32 clk_divider = 0;
+	int i, j;
+	unsigned long base_freq;

Use reversed xmas tree order for all these blocks.

Quoted 3 lines

The rule of thumb, btw, that any comment applies to all similar places by default (independently on which line it was given against).

Quoted 8 lines

Do you mena change as following?
struct clk_hw_onecell_data *onecell;
unsigned long base_freq;
u32 clk_divider = 0;
struct clk_hw *hw;
int err;
int i;
int j;

Yes.

...

Quoted 20 lines
Quoted 20 lines
Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +6 -0
+		for (i = 0; i < 0xff; i++) {
+			/*
+			 * i maps to div:
+			 * 0x00: div 1
+			 * 0x01: div 1.5
+			 * 0x02: div 2

drivers/i2c/busses/ast2600-i2c-global.c line 101

Quoted 10 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +10 -0
+			 * 0x03: div 2.5
+			 * 0x04: div 3
+			 * ...
+			 * 0xFE: div 128
+			 * 0xFF: div 128.5
+			 */
+			base_freq = base_clk * 2 / (2 + i);
+			if (base_freq <= i2c_base_clk[j].base_freq)
+				break;
+		}

oAre yuo sure you can't eliminate the entire for-loop? Think about it a bit, please.

Quoted 5 lines
Quoted 1 line

What do you think if we use "lookup table" instaed of above for loop?

Besides that it should be a part of clock provider, no, you may use a formula (bit operations and so on).

Will provide a formula

Quoted 35 lines

...

Quoted 9 lines
Quoted 8 lines

drivers/i2c/busses/ast2600-i2c-global.c line 157

Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +4 -0
+	i2c_ic->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 
+	if (IS_ERR(i2c_ic->rst)) {
 
+		dev_dbg(&pdev->dev,
+			"missing or invalid reset controller device tree entry");

Make it optional.

Can I change to use "dev_err"?

What I meant here is to make the reset optional (there is even specific API for that) and return an error in that case.

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/i2c/busses/ast2600-i2c-global.c new file +6 -0
+	} else {
+		/* SCU I2C Reset */
+		reset_control_assert(i2c_ic->rst);
+		udelay(3);
+		reset_control_deassert(i2c_ic->rst);
+	}

...

Quoted 10 lines
Quoted 3 lines
Quoted 1 line

+static struct ast_i2c_timing_table aspeed_old_i2c_timing_table[] = {

What the ... is this for?!

AST2600 support old/new register set for I2C controller.
This lookup table is used to find the divisor for the specific I2C bus frequency for AST2600 I2C controller with old register set.
For example
If I2C bus frequency is 100KHZ and PHB clock is 100MHZ, it will find this table because 100000000/1024 < 100000
"{ 1024, 0x00000300 | (0x5) | (0xf << 20) | (0xf << 16) | (0xf << 12) }"

Quoted 2 lines

Can't you derive it by formula(s)?

Will provide formula(s)

Quoted 10 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
drivers/i2c/busses/i2c-new-aspeed.c new file +3 -0
+	/* Divisor : Base Clock : tCKHighMin : tCK High : tCK Low  */
+	/* Divisor :	  [3:0] : [23: 20]   :   [19:16]:   [15:12] */
 
+};
Signature · 2 lines
With Best Regards,
Andy Shevchenko
#9 lore raw

Re: [PATCH 3/3] i2c:support new register set for ast2600

In reply to Jamin Lin
Quoted 7 lines · Jamin Lin

Add i2c new driver to support new register set for AST2600. AST2600 support three modes for data transfer which are byte mode, buffer mode and dma mode, respectively. The global driver of i2c is used to set the new register mode and define the base clock frequency
of baseclk_1~baseclk_4.

Quoted 7 lines
---
 drivers/i2c/busses/Kconfig              |   11 +
 drivers/i2c/busses/Makefile             |    1 +
 drivers/i2c/busses/ast2600-i2c-global.c |  205 +++
 drivers/i2c/busses/ast2600-i2c-global.h |   25 +
 drivers/i2c/busses/i2c-new-aspeed.c     | 1796 +++++++++++++++++++++++

I commented _something_ (but read comments carefully, they will cover much more). The overall it seems you have to:
- shrink the code base by at least ~15% (it's possible), i.e. -200 LOCs
- rethink how you do calculations and bit operations
- better code style

Signature · 2 lines
With Best Regards,
Andy Shevchenko
author
#10 lore raw

Re: [PATCH 3/3] i2c:support new register set for ast2600

Quoted 16 lines · Andy Shevchenko
Quoted 7 lines · Jamin Lin

Add i2c new driver to support new register set for AST2600. AST2600 support three modes for data transfer which are byte mode, buffer mode and dma mode, respectively. The global driver of i2c is used to set the new register mode and define the base clock frequency
of baseclk_1~baseclk_4.

Quoted 7 lines
---
 drivers/i2c/busses/Kconfig              |   11 +
 drivers/i2c/busses/Makefile             |    1 +
 drivers/i2c/busses/ast2600-i2c-global.c |  205 +++
 drivers/i2c/busses/ast2600-i2c-global.h |   25 +
 drivers/i2c/busses/i2c-new-aspeed.c     | 1796 +++++++++++++++++++++++
Quoted 3 lines

I commented _something_ (but read comments carefully, they will cover much more). The overall it seems you have to:
- shrink the code base by at least ~15% (it's possible), i.e. -200 LOCs

Can you describe it more detail?
Do you mean I should separate the patch file to fix size limitation?

Quoted 3 lines

- rethink how you do calculations and bit operations
- better code style

Thanks for your review and very good suggestion
I will update them and sent patch again.
By the way, I received test failed email from Robot due to compiling warning. I will fix them, too.

Quoted 5 lines
Signature · 2 lines
With Best Regards,
Andy Shevchenko
#11 lore raw

Re: [PATCH 3/3] i2c:support new register set for ast2600

Quoted 9 lines · Jamin Lin
Quoted 7 lines · Andy Shevchenko
Quoted 6 lines · Jamin Lin

Add i2c new driver to support new register set for AST2600. AST2600 support three modes for data transfer which are byte mode, buffer mode and dma mode, respectively. The global driver of i2c is used to set the new register mode and define the base clock frequency
of baseclk_1~baseclk_4.

Quoted 3 lines
Quoted 1 line

- shrink the code base by at least ~15% (it's possible), i.e. -200 LOCs

Can you describe it more detail?
Do you mean I should separate the patch file to fix size limitation?

No. Based on my brief review you introduce to many redundant LOCs (lines of code). Remove them, refactor the code, make it small and neat and easy to read and understand. It is possible to achieve!

Quoted 7 lines
Quoted 3 lines

- rethink how you do calculations and bit operations
- better code style

Thanks for your review and very good suggestion
I will update them and sent patch again.
By the way, I received test failed email from Robot due to compiling warning. I will fix them, too.

Signature · 2 lines
With Best Regards,
Andy Shevchenko
author
#12 lore raw

Re: [PATCH 3/3] i2c:support new register set for ast2600

Quoted 10 lines · Andy Shevchenko
Quoted 8 lines · Jamin Lin
Quoted 7 lines · Andy Shevchenko
Quoted 6 lines · Jamin Lin

Add i2c new driver to support new register set for AST2600. AST2600 support three modes for data transfer which are byte mode, buffer mode and dma mode, respectively. The global driver of i2c is used to set the new register mode and define the base clock frequency
of baseclk_1~baseclk_4.

Quoted 8 lines
Quoted 3 lines
Quoted 1 line

- shrink the code base by at least ~15% (it's possible), i.e. -200 LOCs

Can you describe it more detail?
Do you mean I should separate the patch file to fix size limitation?

No. Based on my brief review you introduce to many redundant LOCs (lines of code). Remove them, refactor the code, make it small and neat and easy to read and understand. It is possible to achieve!

Will fix
Thanks

Quoted 13 lines
Quoted 7 lines
Quoted 3 lines

- rethink how you do calculations and bit operations
- better code style

Thanks for your review and very good suggestion
I will update them and sent patch again.
By the way, I received test failed email from Robot due to compiling warning. I will fix them, too.

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#13 lore raw

Re: [PATCH 3/3] i2c:support new register set for ast2600

In reply to Jamin Lin
Thank you for the patch! Perhaps something to improve:

Hi Jamin,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on wsa/i2c/for-next]
[also build test WARNING on robh/for-next joel-aspeed/for-next v5.13-rc6 next-20210617] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Jamin-Lin/Support-ASPEED-AST2600-I2C/20210617-174709
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
config: arm-allyesconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/8d16cf8cbc5d3dccd05c23dd7c4744a0890e356f
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Jamin-Lin/Support-ASPEED-AST2600-I2C/20210617-174709 git checkout 8d16cf8cbc5d3dccd05c23dd7c4744a0890e356f
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm

If you fix the issue, kindly add following tag as appropriate

All warnings (new ones prefixed by >>):

>> drivers/i2c/busses/i2c-new-aspeed.c:542:6: warning: no previous prototype for 'aspeed_i2c_slave_packet_irq' [-Wmissing-prototypes]
     542 | void aspeed_i2c_slave_packet_irq(struct aspeed_new_i2c_bus *i2c_bus, u32 sts)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/i2c/busses/i2c-new-aspeed.c:827:6: warning: no previous prototype for 'aspeed_i2c_slave_byte_irq' [-Wmissing-prototypes]
     827 | void aspeed_i2c_slave_byte_irq(struct aspeed_new_i2c_bus *i2c_bus, u32 sts)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/i2c/busses/i2c-new-aspeed.c:883:5: warning: no previous prototype for 'aspeed_new_i2c_slave_irq' [-Wmissing-prototypes]
     883 | int aspeed_new_i2c_slave_irq(struct aspeed_new_i2c_bus *i2c_bus)
         |     ^~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/i2c/busses/i2c-new-aspeed.c:1091:6: warning: no previous prototype for 'aspeed_i2c_master_package_irq' [-Wmissing-prototypes]
    1091 | void aspeed_i2c_master_package_irq(struct aspeed_new_i2c_bus *i2c_bus, u32 sts)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/i2c/busses/i2c-new-aspeed.c:1347:5: warning: no previous prototype for 'aspeed_new_i2c_master_irq' [-Wmissing-prototypes]
    1347 | int aspeed_new_i2c_master_irq(struct aspeed_new_i2c_bus *i2c_bus)
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~

vim +/aspeed_i2c_slave_packet_irq +542 drivers/i2c/busses/i2c-new-aspeed.c

540
541 #ifdef CONFIG_I2C_SLAVE

 > 542	void aspeed_i2c_slave_packet_irq(struct aspeed_new_i2c_bus *i2c_bus, u32 sts)
   543	{
   544		u32 cmd = 0;
   545		u8 value;
   546		u8 byte_data;
   547		int i = 0;
   548		int slave_rx_len;
   549	
   550		sts &= ~(AST_I2CS_PKT_DONE | AST_I2CS_PKT_ERROR);
   551		writel(AST_I2CS_PKT_DONE, i2c_bus->reg_base + AST_I2CS_ISR);
   552		switch (sts) {
   553		case 0:
   554			cmd = SLAVE_TRIGGER_CMD;
   555			if (i2c_bus->mode == DMA_MODE)
   556				cmd |= AST_I2CS_RX_DMA_EN;
   557			else if (i2c_bus->mode == BUFF_MODE)
   558				cmd |= AST_I2CS_RX_BUFF_EN;
   559			else
   560				cmd &= ~AST_I2CS_PKT_MODE_EN;
   561			writel(cmd, i2c_bus->reg_base + AST_I2CS_CMD_STS);
   562			break;
   563		case AST_I2CS_SLAVE_MATCH:
   564		dev_dbg(i2c_bus->dev, "S : Sw\n");
   565		i2c_slave_event(i2c_bus->slave,
   566				I2C_SLAVE_WRITE_REQUESTED, &value);
   567			break;
   568	
   569		case AST_I2CS_SLAVE_MATCH | AST_I2CS_STOP:
   570			dev_dbg(i2c_bus->dev, "S : Sw|P\n");
   571			i2c_slave_event(i2c_bus->slave, I2C_SLAVE_STOP, &value);
   572			cmd = SLAVE_TRIGGER_CMD;
   573			if (i2c_bus->mode == DMA_MODE) {
   574				cmd |= AST_I2CS_RX_DMA_EN;
   575				writel(AST_I2CS_SET_RX_DMA_LEN(I2C_SLAVE_MSG_BUF_SIZE),
   576				       i2c_bus->reg_base + AST_I2CS_DMA_LEN);
   577			} else if (i2c_bus->mode == BUFF_MODE) {
   578				cmd |= AST_I2CS_RX_BUFF_EN;
   579				writel(AST_I2CC_SET_RX_BUF_LEN(i2c_bus->buf_size),
   580				       i2c_bus->reg_base + AST_I2CC_BUFF_CTRL);
   581			} else {
   582				cmd &= ~AST_I2CS_PKT_MODE_EN;
   583			}
   584			writel(cmd, i2c_bus->reg_base + AST_I2CS_CMD_STS);
   585			break;
   586	
   587		case AST_I2CS_SLAVE_MATCH | AST_I2CS_RX_DONE |
   588			AST_I2CS_Wait_RX_DMA | AST_I2CS_STOP:
   589		case AST_I2CS_RX_DONE | AST_I2CS_Wait_RX_DMA | AST_I2CS_STOP:
   590		case AST_I2CS_RX_DONE | AST_I2CS_STOP:
   591		case AST_I2CS_SLAVE_MATCH | AST_I2CS_RX_DONE | AST_I2CS_Wait_RX_DMA:
   592		case AST_I2CS_SLAVE_MATCH | AST_I2CS_RX_DONE | AST_I2CS_STOP:

593 cmd = SLAVE_TRIGGER_CMD;
594 if (sts & AST_I2CS_STOP) {
595 if (sts & AST_I2CS_SLAVE_MATCH)
596 dev_dbg(i2c_bus->dev, "S : Sw|D|P\n");
597 else
598 dev_dbg(i2c_bus->dev, "S : D|P\n");
599 } else {
600 dev_dbg(i2c_bus->dev, "S : Sw|D\n");
601 }
602
603 if (sts & AST_I2CS_SLAVE_MATCH)
604 i2c_slave_event(i2c_bus->slave,
605 I2C_SLAVE_WRITE_REQUESTED,
606 &value);
607
608 if (i2c_bus->mode == DMA_MODE) {
609 cmd |= AST_I2CS_RX_DMA_EN;
610 slave_rx_len =
611 AST_I2C_GET_RX_DMA_LEN(readl(i2c_bus->reg_base +
612 AST_I2CS_DMA_LEN_STS));
613 dev_dbg(i2c_bus->dev, "rx len %d\n", slave_rx_len);
614 for (i = 0; i < slave_rx_len; i++) {
615 i2c_slave_event(i2c_bus->slave,
616 I2C_SLAVE_WRITE_RECEIVED,
617 &i2c_bus->slave_dma_buf[i]);
618 }
619 writel(AST_I2CS_SET_RX_DMA_LEN(I2C_SLAVE_MSG_BUF_SIZE),
620 i2c_bus->reg_base + AST_I2CS_DMA_LEN);
621 } else if (i2c_bus->mode == BUFF_MODE) {
622 cmd |= AST_I2CS_RX_BUFF_EN;
623 slave_rx_len =
624 AST_I2CC_GET_RX_BUF_LEN(readl(i2c_bus->reg_base +
625 AST_I2CC_BUFF_CTRL));
626 for (i = 0; i < slave_rx_len; i++) {
627 value = readb(i2c_bus->buf_base + i);
628 dev_dbg(i2c_bus->dev, "[%02x]", value);
629 i2c_slave_event(i2c_bus->slave,
630 I2C_SLAVE_WRITE_RECEIVED,
631 &value);
632 }
633 writel(AST_I2CC_SET_RX_BUF_LEN(i2c_bus->buf_size),
634 i2c_bus->reg_base + AST_I2CC_BUFF_CTRL);
635 } else {
636 cmd &= ~AST_I2CS_PKT_MODE_EN;
637 byte_data = AST_I2CC_GET_RX_BUFF(readl(i2c_bus->reg_base +
638 AST_I2CC_STS_AND_BUFF));
639 dev_dbg(i2c_bus->dev, "[%02x]", byte_data);
640 i2c_slave_event(i2c_bus->slave,
641 I2C_SLAVE_WRITE_RECEIVED,
642 &byte_data);
643 }
644 if (sts & AST_I2CS_STOP)
645 i2c_slave_event(i2c_bus->slave, I2C_SLAVE_STOP,
646 &value);
647 writel(cmd, i2c_bus->reg_base + AST_I2CS_CMD_STS);
648 break;
649
650 /* it is Mw data Mr coming -> it need send tx */
651 case AST_I2CS_RX_DONE | AST_I2CS_Wait_TX_DMA:
652 case AST_I2CS_SLAVE_MATCH | AST_I2CS_RX_DONE | AST_I2CS_Wait_TX_DMA:
653 /* it should be repeat start read */
654 if (sts & AST_I2CS_SLAVE_MATCH)
655 dev_dbg(i2c_bus->dev,
656 "S: AST_I2CS_Wait_TX_DMA | AST_I2CS_SLAVE_MATCH | AST_I2CS_RX_DONE\n");
657 else
658 dev_dbg(i2c_bus->dev,
659 "S: AST_I2CS_Wait_TX_DMA | AST_I2CS_RX_DONE\n");
660
661 if (sts & AST_I2CS_SLAVE_MATCH)
662 i2c_slave_event(i2c_bus->slave,
663 I2C_SLAVE_WRITE_REQUESTED,
664 &value);
665
666 cmd = SLAVE_TRIGGER_CMD;
667 if (i2c_bus->mode == DMA_MODE) {
668 cmd |= AST_I2CS_TX_DMA_EN;
669 slave_rx_len =
670 AST_I2C_GET_RX_DMA_LEN(readl(i2c_bus->reg_base +
671 AST_I2CS_DMA_LEN_STS));
672 for (i = 0; i < slave_rx_len; i++) {
673 dev_dbg(i2c_bus->dev, "rx [%02x]",
674 i2c_bus->slave_dma_buf[i]);
675 i2c_slave_event(i2c_bus->slave,
676 I2C_SLAVE_WRITE_RECEIVED,
677 &i2c_bus->slave_dma_buf[i]);
678 }
679 i2c_slave_event(i2c_bus->slave,
680 I2C_SLAVE_READ_REQUESTED,
681 &i2c_bus->slave_dma_buf[0]);
682 dev_dbg(i2c_bus->dev, "tx : [%02x]",
683 i2c_bus->slave_dma_buf[0]);
684 writel(0, i2c_bus->reg_base + AST_I2CS_DMA_LEN_STS);
685 writel(AST_I2CS_SET_TX_DMA_LEN(1),
686 i2c_bus->reg_base + AST_I2CS_DMA_LEN);
687 } else if (i2c_bus->mode == BUFF_MODE) {
688 cmd |= AST_I2CS_TX_BUFF_EN;
689 slave_rx_len =
690 AST_I2CC_GET_RX_BUF_LEN(readl(i2c_bus->reg_base +
691 AST_I2CC_BUFF_CTRL));
692 for (i = 0; i < slave_rx_len; i++) {
693 value = readb(i2c_bus->buf_base + i);
694 dev_dbg(i2c_bus->dev, "rx : [%02x]",
695 value);
696 i2c_slave_event(i2c_bus->slave,
697 I2C_SLAVE_WRITE_RECEIVED,
698 &value);
699 }
700 i2c_slave_event(i2c_bus->slave,
701 I2C_SLAVE_READ_REQUESTED,
702 &value);
703 dev_dbg(i2c_bus->dev, "tx : [%02x]", value);
704 writeb(value, i2c_bus->buf_base);
705 writel(AST_I2CC_SET_TX_BUF_LEN(1),
706 i2c_bus->reg_base + AST_I2CC_BUFF_CTRL);
707 } else {
708 cmd &= ~AST_I2CS_PKT_MODE_EN;
709 cmd |= AST_I2CS_TX_CMD;
710 byte_data = AST_I2CC_GET_RX_BUFF(readl(i2c_bus->reg_base +
711 AST_I2CC_STS_AND_BUFF));
712 dev_dbg(i2c_bus->dev, "rx : [%02x]", byte_data);
713 i2c_slave_event(i2c_bus->slave,
714 I2C_SLAVE_WRITE_RECEIVED,
715 &byte_data);
716 i2c_slave_event(i2c_bus->slave,
717 I2C_SLAVE_READ_REQUESTED,
718 &byte_data);
719 dev_dbg(i2c_bus->dev, "tx : [%02x]", byte_data);
720 writel(byte_data, i2c_bus->reg_base +
721 AST_I2CC_STS_AND_BUFF);
722 }
723 writel(cmd, i2c_bus->reg_base + AST_I2CS_CMD_STS);
724 break;
725
726 case AST_I2CS_SLAVE_MATCH | AST_I2CS_Wait_TX_DMA:
727 /* First Start read */
728 dev_dbg(i2c_bus->dev,
729 "S: AST_I2CS_SLAVE_MATCH | AST_I2CS_Wait_TX_DMA\n");
730 cmd = SLAVE_TRIGGER_CMD;
731 if (i2c_bus->mode == DMA_MODE) {
732 cmd |= AST_I2CS_TX_DMA_EN;
733 i2c_slave_event(i2c_bus->slave,
734 I2C_SLAVE_READ_REQUESTED,
735 &i2c_bus->slave_dma_buf[0]);
736 dev_dbg(i2c_bus->dev, "tx: [%x]\n",
737 i2c_bus->slave_dma_buf[0]);
738 writel(AST_I2CS_SET_TX_DMA_LEN(1),
739 i2c_bus->reg_base + AST_I2CS_DMA_LEN);
740 } else if (i2c_bus->mode == BUFF_MODE) {
741 cmd |= AST_I2CS_TX_BUFF_EN;
742 i2c_slave_event(i2c_bus->slave,
743 I2C_SLAVE_READ_REQUESTED,
744 &byte_data);
745 dev_dbg(i2c_bus->dev, "tx : [%02x]", byte_data);
746 writeb(byte_data, i2c_bus->buf_base);
747 writel(AST_I2CC_SET_TX_BUF_LEN(1),
748 i2c_bus->reg_base + AST_I2CC_BUFF_CTRL);
749 } else {
750 cmd &= ~AST_I2CS_PKT_MODE_EN;
751 cmd |= AST_I2CS_TX_CMD;
752 i2c_slave_event(i2c_bus->slave,
753 I2C_SLAVE_READ_REQUESTED,
754 &byte_data);
755 writel(byte_data, i2c_bus->reg_base +
756 AST_I2CC_STS_AND_BUFF);
757 }
758 writel(cmd, i2c_bus->reg_base + AST_I2CS_CMD_STS);
759 break;
760
761 case AST_I2CS_Wait_TX_DMA:
762 /* it should be next start read */
763 dev_dbg(i2c_bus->dev, "S: AST_I2CS_Wait_TX_DMA\n");
764 cmd = SLAVE_TRIGGER_CMD;
765 if (i2c_bus->mode == DMA_MODE) {
766 cmd |= AST_I2CS_TX_DMA_EN;
767 i2c_slave_event(i2c_bus->slave,
768 I2C_SLAVE_READ_PROCESSED,
769 &i2c_bus->slave_dma_buf[0]);
770 dev_dbg(i2c_bus->dev, "tx : [%02x]",
771 i2c_bus->slave_dma_buf[0]);
772 writel(0, i2c_bus->reg_base + AST_I2CS_DMA_LEN_STS);
773 writel(AST_I2CS_SET_TX_DMA_LEN(1),
774 i2c_bus->reg_base + AST_I2CS_DMA_LEN);
775 } else if (i2c_bus->mode == BUFF_MODE) {
776 cmd |= AST_I2CS_TX_BUFF_EN;
777 i2c_slave_event(i2c_bus->slave,
778 I2C_SLAVE_READ_PROCESSED,
779 &value);
780 dev_dbg(i2c_bus->dev, "tx: [%02x]\n", value);
781 writeb(value, i2c_bus->buf_base);
782 writel(AST_I2CC_SET_TX_BUF_LEN(1),
783 i2c_bus->reg_base + AST_I2CC_BUFF_CTRL);
784 } else {
785 cmd &= ~AST_I2CS_PKT_MODE_EN;
786 cmd |= AST_I2CS_TX_CMD;
787 i2c_slave_event(i2c_bus->slave,
788 I2C_SLAVE_READ_PROCESSED,
789 &byte_data);
790 dev_dbg(i2c_bus->dev, "tx: [%02x]\n",
791 byte_data);
792 writel(byte_data, i2c_bus->reg_base +
793 AST_I2CC_STS_AND_BUFF);
794 }
795 writel(cmd, i2c_bus->reg_base + AST_I2CS_CMD_STS);
796 break;
797
798 case AST_I2CS_TX_NAK | AST_I2CS_STOP:
799 /* it just tx complete */
800 dev_dbg(i2c_bus->dev,
801 "S: AST_I2CS_TX_NAK | AST_I2CS_STOP\n");
802 cmd = SLAVE_TRIGGER_CMD;
803 i2c_slave_event(i2c_bus->slave, I2C_SLAVE_STOP, &value);
804 if (i2c_bus->mode == DMA_MODE) {
805 cmd |= AST_I2CS_RX_DMA_EN;
806 writel(0, i2c_bus->reg_base + AST_I2CS_DMA_LEN_STS);
807 writel(AST_I2CS_SET_RX_DMA_LEN(I2C_SLAVE_MSG_BUF_SIZE),
808 i2c_bus->reg_base + AST_I2CS_DMA_LEN);
809 } else if (i2c_bus->mode == BUFF_MODE) {
810 cmd |= AST_I2CS_RX_BUFF_EN;
811 writel(AST_I2CC_SET_RX_BUF_LEN(i2c_bus->buf_size),
812 i2c_bus->reg_base + AST_I2CC_BUFF_CTRL);
813 } else {
814 cmd &= ~AST_I2CS_PKT_MODE_EN;
815 }
816 writel(cmd, i2c_bus->reg_base + AST_I2CS_CMD_STS);
817 break;
818
819 default:
820 dev_dbg(i2c_bus->dev,
821 "todo slave sts case %x, now %x\n", sts,
822 readl(i2c_bus->reg_base + AST_I2CS_ISR));
823 break;
824 }
825 }
826

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org