All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] arm: exynos: Add E850-96 board
@ 2023-12-13  3:16 Sam Protsenko
  2023-12-13  3:16 ` [PATCH 01/13] dt-bindings: soc: samsung: Add Exynos USI Sam Protsenko
                   ` (13 more replies)
  0 siblings, 14 replies; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

NOTE: This patch series depends on "pinctrl: exynos: Prepare for other
SoCs support" series [1]. It should be applied first.

Add Exynos850 SoC and WinLink's E850-96 board support. A short overview
of series additions and modifications:
  * USI driver: configures UART block
  * PMU driver: connects AP UART lines to uart1 pins)
  * Exynos850 clock driver: generates UART clocks
  * Exynos850 pinctrl driver: mux UART pins
  * serial_s5p: UART driver
  * Exynos850 SoC: dtsi files and MMU maps
  * E850-96 board: dts files, defconfig, board file and doc

Most of the code was borrowed from mainline Linux kernel (where this
board is already enabled) and adapted for U-Boot. Preliminary
preparation for this series includes next patches / series (already
merged):

  * commit 585a2aaac2ac ("arm: exynos: Include missing CPU header in
                          soc.c")
  * commit c9ab9f30c8e4 ("arm: exynos: Include missing CPU header in
                          gpio.h")
  * commit 11bd2787deff ("watchdog: s5p_wdt: Include missing CPU
                          header")
  * commit 08cfa971a717 ("exynos: Avoid duplicate reset_cpu with
                          SYSRESET enabled")
  * commit f655090901dc ("clk: exynos: Add header guard for clk-pll.h")
  * commit 2227f4c0afed ("serial: s5p: Fix clk_get_by_index() error code
                          check")
  * commit a0615ffc99a5 ("serial: s5p: Remove common.h inclusion")
  * commit 5ad21de6bae0 ("serial: s5p: Use livetree API to get "id"
                          property")
  * commit e79f630dbf67 ("serial: s5p: Use named constants for register
                          values")
  * commit a627f2802a71 ("serial: s5p: Improve coding style")
  * commit 33e7ca5a9b6a ("serial: s5p: Use dev_read_addr_ptr() to get
                          base address")
  * commit 6219b47c4d91 ("board: samsung: Fix SYS_CONFIG_NAME configs in
                          axy17lte Kconfig")
  * commit 470682ace1e0 ("configs: Remove unneeded SYS_CONFIG_NAME from
                          a*y17lte defconfigs")

and series [1] (dependency) is still pending.

For more detailed description please see the board documentation (added
in PATCH #12) and corresponding commit messages.

[1] https://lists.denx.de/pipermail/u-boot/2023-November/539033.html

Sam Protsenko (13):
  dt-bindings: soc: samsung: Add Exynos USI
  dt-bindings: soc: samsung: Add Exynos PMU
  dt-bindings: clock: Add Exynos850 clock controller
  soc: samsung: Add Exynos USI driver
  soc: samsung: Add Exynos PMU driver
  clk: exynos: Move pll code into clk-exynos7420
  clk: exynos: Add Samsung clock framework
  clk: exynos: Add Exynos850 clock driver
  pinctrl: exynos: Add pinctrl support for Exynos850
  serial: s5p: Add Exynos850 compatible
  arm: exynos: Add Exynos850 SoC support
  board: samsung: Add support for E850-96 board
  MAINTAINERS: Add new Samsung subsystems

 MAINTAINERS                                   |   25 +
 arch/arm/dts/Makefile                         |    1 +
 arch/arm/dts/exynos-pinctrl.h                 |   79 +
 arch/arm/dts/exynos850-e850-96-u-boot.dtsi    |   37 +
 arch/arm/dts/exynos850-e850-96.dts            |  273 ++++
 arch/arm/dts/exynos850-pinctrl.dtsi           |  663 +++++++++
 arch/arm/dts/exynos850.dtsi                   |  809 +++++++++++
 arch/arm/mach-exynos/Kconfig                  |   28 +-
 arch/arm/mach-exynos/mmu-arm64.c              |   34 +
 board/samsung/e850-96/Kconfig                 |   16 +
 board/samsung/e850-96/MAINTAINERS             |    9 +
 board/samsung/e850-96/Makefile                |    6 +
 board/samsung/e850-96/e850-96.c               |   22 +
 configs/e850-96_defconfig                     |   21 +
 doc/board/samsung/e850-96.rst                 |   87 ++
 .../img/exynos850-boot-architecture.svg       | 1283 +++++++++++++++++
 doc/board/samsung/index.rst                   |    1 +
 .../clock/samsung,exynos850-clock.yaml        |  307 ++++
 .../soc/samsung/exynos-pmu.yaml               |   85 ++
 .../soc/samsung/exynos-usi.yaml               |  162 +++
 drivers/clk/exynos/Kconfig                    |    7 +
 drivers/clk/exynos/Makefile                   |   11 +-
 drivers/clk/exynos/clk-exynos7420.c           |   25 +-
 drivers/clk/exynos/clk-exynos850.c            |  189 +++
 drivers/clk/exynos/clk-pll.c                  |  167 ++-
 drivers/clk/exynos/clk-pll.h                  |   16 +-
 drivers/clk/exynos/clk.c                      |  121 ++
 drivers/clk/exynos/clk.h                      |  228 +++
 drivers/pinctrl/exynos/Kconfig                |    8 +
 drivers/pinctrl/exynos/Makefile               |    1 +
 drivers/pinctrl/exynos/pinctrl-exynos850.c    |  125 ++
 drivers/serial/serial_s5p.c                   |    1 +
 drivers/soc/Kconfig                           |    1 +
 drivers/soc/Makefile                          |    1 +
 drivers/soc/samsung/Kconfig                   |   33 +
 drivers/soc/samsung/Makefile                  |    4 +
 drivers/soc/samsung/exynos-pmu.c              |  102 ++
 drivers/soc/samsung/exynos-usi.c              |  218 +++
 include/configs/e850-96.h                     |   12 +
 include/dt-bindings/clock/exynos850.h         |  337 +++++
 include/dt-bindings/soc/samsung,exynos-usi.h  |   17 +
 41 files changed, 5548 insertions(+), 24 deletions(-)
 create mode 100644 arch/arm/dts/exynos-pinctrl.h
 create mode 100644 arch/arm/dts/exynos850-e850-96-u-boot.dtsi
 create mode 100644 arch/arm/dts/exynos850-e850-96.dts
 create mode 100644 arch/arm/dts/exynos850-pinctrl.dtsi
 create mode 100644 arch/arm/dts/exynos850.dtsi
 create mode 100644 board/samsung/e850-96/Kconfig
 create mode 100644 board/samsung/e850-96/MAINTAINERS
 create mode 100644 board/samsung/e850-96/Makefile
 create mode 100644 board/samsung/e850-96/e850-96.c
 create mode 100644 configs/e850-96_defconfig
 create mode 100644 doc/board/samsung/e850-96.rst
 create mode 100644 doc/board/samsung/img/exynos850-boot-architecture.svg
 create mode 100644 doc/device-tree-bindings/clock/samsung,exynos850-clock.yaml
 create mode 100644 doc/device-tree-bindings/soc/samsung/exynos-pmu.yaml
 create mode 100644 doc/device-tree-bindings/soc/samsung/exynos-usi.yaml
 create mode 100644 drivers/clk/exynos/clk-exynos850.c
 create mode 100644 drivers/clk/exynos/clk.c
 create mode 100644 drivers/clk/exynos/clk.h
 create mode 100644 drivers/pinctrl/exynos/pinctrl-exynos850.c
 create mode 100644 drivers/soc/samsung/Kconfig
 create mode 100644 drivers/soc/samsung/Makefile
 create mode 100644 drivers/soc/samsung/exynos-pmu.c
 create mode 100644 drivers/soc/samsung/exynos-usi.c
 create mode 100644 include/configs/e850-96.h
 create mode 100644 include/dt-bindings/clock/exynos850.h
 create mode 100644 include/dt-bindings/soc/samsung,exynos-usi.h

-- 
2.39.2


^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 01/13] dt-bindings: soc: samsung: Add Exynos USI
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-13  3:16 ` [PATCH 02/13] dt-bindings: soc: samsung: Add Exynos PMU Sam Protsenko
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

Add USI bindings documentation and header file. Those are taken from
Linux kernel [1,2], but the documentation was reworked a bit to only
describe the compatibles that will be supported in U-Boot soon.

[1] Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
[2] include/dt-bindings/soc/samsung,exynos-usi.h

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 .../soc/samsung/exynos-usi.yaml               | 162 ++++++++++++++++++
 include/dt-bindings/soc/samsung,exynos-usi.h  |  17 ++
 2 files changed, 179 insertions(+)
 create mode 100644 doc/device-tree-bindings/soc/samsung/exynos-usi.yaml
 create mode 100644 include/dt-bindings/soc/samsung,exynos-usi.h

diff --git a/doc/device-tree-bindings/soc/samsung/exynos-usi.yaml b/doc/device-tree-bindings/soc/samsung/exynos-usi.yaml
new file mode 100644
index 000000000000..8e6423f11568
--- /dev/null
+++ b/doc/device-tree-bindings/soc/samsung/exynos-usi.yaml
@@ -0,0 +1,162 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/samsung/exynos-usi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung's Exynos USI (Universal Serial Interface)
+
+maintainers:
+  - Sam Protsenko <semen.protsenko@linaro.org>
+
+description: |
+  USI IP-core provides selectable serial protocol (UART, SPI or High-Speed I2C).
+  USI shares almost all internal circuits within each protocol, so only one
+  protocol can be chosen at a time. USI is modeled as a node with zero or more
+  child nodes, each representing a serial sub-node device. The mode setting
+  selects which particular function will be used.
+
+properties:
+  $nodename:
+    pattern: "^usi@[0-9a-f]+$"
+
+  compatible:
+    enum:
+      - samsung,exynos850-usi
+
+  reg: true
+
+  clocks: true
+
+  clock-names: true
+
+  ranges: true
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  samsung,sysreg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: phandle to System Register syscon node
+          - description: offset of SW_CONF register for this USI controller
+    description:
+      Should be phandle/offset pair. The phandle to System Register syscon node
+      (for the same domain where this USI controller resides) and the offset
+      of SW_CONF register for this USI controller.
+
+  samsung,mode:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Selects USI function (which serial protocol to use). Refer to
+      <include/dt-bindings/soc/samsung,exynos-usi.h> for valid USI mode values.
+
+  samsung,clkreq-on:
+    type: boolean
+    description:
+      Enable this property if underlying protocol requires the clock to be
+      continuously provided without automatic gating. As suggested by SoC
+      manual, it should be set in case of SPI/I2C slave, UART Rx and I2C
+      multi-master mode. Usually this property is needed if USI mode is set
+      to "UART".
+
+      This property is optional.
+
+patternProperties:
+  "^i2c@[0-9a-f]+$":
+    $ref: /schemas/i2c/i2c-exynos5.yaml
+    description: Child node describing underlying I2C
+
+  "^serial@[0-9a-f]+$":
+    $ref: /schemas/serial/samsung_uart.yaml
+    description: Child node describing underlying UART/serial
+
+  "^spi@[0-9a-f]+$":
+    $ref: /schemas/spi/samsung,spi.yaml
+    description: Child node describing underlying SPI
+
+required:
+  - compatible
+  - ranges
+  - "#address-cells"
+  - "#size-cells"
+  - samsung,sysreg
+  - samsung,mode
+
+if:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - samsung,exynos850-usi
+
+then:
+  properties:
+    reg:
+      maxItems: 1
+
+    clocks:
+      items:
+        - description: Bus (APB) clock
+        - description: Operating clock for UART/SPI/I2C protocol
+
+    clock-names:
+      items:
+        - const: pclk
+        - const: ipclk
+
+  required:
+    - reg
+    - clocks
+    - clock-names
+
+else:
+  properties:
+    reg: false
+    clocks: false
+    clock-names: false
+    samsung,clkreq-on: false
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/soc/samsung,exynos-usi.h>
+
+    usi0: usi@138200c0 {
+        compatible = "samsung,exynos850-usi";
+        reg = <0x138200c0 0x20>;
+        samsung,sysreg = <&sysreg_peri 0x1010>;
+        samsung,mode = <USI_V2_UART>;
+        samsung,clkreq-on; /* needed for UART mode */
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+        clocks = <&cmu_peri 32>, <&cmu_peri 31>;
+        clock-names = "pclk", "ipclk";
+
+        serial_0: serial@13820000 {
+            compatible = "samsung,exynos850-uart";
+            reg = <0x13820000 0xc0>;
+            interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cmu_peri 32>, <&cmu_peri 31>;
+            clock-names = "uart", "clk_uart_baud0";
+            status = "disabled";
+        };
+
+        hsi2c_0: i2c@13820000 {
+            compatible = "samsung,exynosautov9-hsi2c";
+            reg = <0x13820000 0xc0>;
+            interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+            clocks = <&cmu_peri 31>, <&cmu_peri 32>;
+            clock-names = "hsi2c", "hsi2c_pclk";
+            status = "disabled";
+        };
+    };
diff --git a/include/dt-bindings/soc/samsung,exynos-usi.h b/include/dt-bindings/soc/samsung,exynos-usi.h
new file mode 100644
index 000000000000..a01af169d249
--- /dev/null
+++ b/include/dt-bindings/soc/samsung,exynos-usi.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021 Linaro Ltd.
+ * Author: Sam Protsenko <semen.protsenko@linaro.org>
+ *
+ * Device Tree bindings for Samsung Exynos USI (Universal Serial Interface).
+ */
+
+#ifndef __DT_BINDINGS_SAMSUNG_EXYNOS_USI_H
+#define __DT_BINDINGS_SAMSUNG_EXYNOS_USI_H
+
+#define USI_V2_NONE		0
+#define USI_V2_UART		1
+#define USI_V2_SPI		2
+#define USI_V2_I2C		3
+
+#endif /* __DT_BINDINGS_SAMSUNG_EXYNOS_USI_H */
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 02/13] dt-bindings: soc: samsung: Add Exynos PMU
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
  2023-12-13  3:16 ` [PATCH 01/13] dt-bindings: soc: samsung: Add Exynos USI Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-13  3:16 ` [PATCH 03/13] dt-bindings: clock: Add Exynos850 clock controller Sam Protsenko
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

Add bindings documentation for Exynos PMU hardware block. It was taken
from Linux kernel [1], but minimized and modified to reflect features
that will be actually supported in U-Boot soon. For example,
the "samsung,uart-debug-1" property is not available in Linux kernel
bindings and only present in U-Boot.

[1] Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 .../soc/samsung/exynos-pmu.yaml               | 85 +++++++++++++++++++
 1 file changed, 85 insertions(+)
 create mode 100644 doc/device-tree-bindings/soc/samsung/exynos-pmu.yaml

diff --git a/doc/device-tree-bindings/soc/samsung/exynos-pmu.yaml b/doc/device-tree-bindings/soc/samsung/exynos-pmu.yaml
new file mode 100644
index 000000000000..c3e95c33b01d
--- /dev/null
+++ b/doc/device-tree-bindings/soc/samsung/exynos-pmu.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/samsung/exynos-pmu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC series Power Management Unit (PMU)
+
+maintainers:
+  - Sam Protsenko <semen.protsenko@linaro.org>
+
+description: |+
+  PMU block controls the power and operation states of Exynos SoC. It contains
+  registers for changing the state of next features::
+
+  - Local power control. Exynos SoCs have various power domains, and it's
+    possible to turn them on and off independently, using corresponding
+    registers in PMU block
+  - System-level power control. That allows putting the system into power-down
+    modes (sleep) by turning off the power for most of the domains
+  - Miscellaneous PMU related features
+
+# Custom select to avoid matching all nodes with 'syscon'
+select:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - samsung,exynos850-pmu
+  required:
+    - compatible
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - samsung,exynos850-pmu
+          - const: syscon
+
+  reg:
+    maxItems: 1
+
+  samsung,uart-debug-1:
+    type: boolean
+    description:
+      Enable this property if AP UART lines (Application Processor UART) must be
+      connected to UART_DEBUG_1 path in PMU block. That's usually needed when
+      the serial console is provided by uart1_pins. If this property is not
+      specified, the default behavior will be used (AP UART lines connected to
+      UART_DEBUG_0 path, which usually means uart0_pins are used for the serial
+      console).
+
+  syscon-poweroff:
+    $ref: /schemas/power/reset/syscon-poweroff.yaml#
+    type: object
+    description:
+      Node for power off method
+
+  syscon-reboot:
+    $ref: /schemas/power/reset/syscon-reboot.yaml#
+    type: object
+    description:
+      Node for reboot method
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    pmu_system_controller: system-controller@11860000 {
+        compatible = "samsung,exynos850-pmu", "syscon";
+        reg = <0x11860000 0x10000>;
+
+        reboot: syscon-reboot {
+            compatible = "syscon-reboot";
+            regmap = <&pmu_system_controller>;
+            offset = <0x3a00>; /* SYSTEM_CONFIGURATION */
+            mask = <0x2>; /* SWRESET_SYSTEM */
+            value = <0x2>; /* reset value */
+        };
+    };
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 03/13] dt-bindings: clock: Add Exynos850 clock controller
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
  2023-12-13  3:16 ` [PATCH 01/13] dt-bindings: soc: samsung: Add Exynos USI Sam Protsenko
  2023-12-13  3:16 ` [PATCH 02/13] dt-bindings: soc: samsung: Add Exynos PMU Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-13  3:16 ` [PATCH 04/13] soc: samsung: Add Exynos USI driver Sam Protsenko
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

Add bindings documentation and the header file for Exynos850 clock
controller. It was taken from Linux kernel [1,2].

[1] Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
[2] include/dt-bindings/clock/exynos850.h

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 .../clock/samsung,exynos850-clock.yaml        | 307 ++++++++++++++++
 include/dt-bindings/clock/exynos850.h         | 337 ++++++++++++++++++
 2 files changed, 644 insertions(+)
 create mode 100644 doc/device-tree-bindings/clock/samsung,exynos850-clock.yaml
 create mode 100644 include/dt-bindings/clock/exynos850.h

diff --git a/doc/device-tree-bindings/clock/samsung,exynos850-clock.yaml b/doc/device-tree-bindings/clock/samsung,exynos850-clock.yaml
new file mode 100644
index 000000000000..a0906efe1223
--- /dev/null
+++ b/doc/device-tree-bindings/clock/samsung,exynos850-clock.yaml
@@ -0,0 +1,307 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos850-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos850 SoC clock controller
+
+maintainers:
+  - Sam Protsenko <semen.protsenko@linaro.org>
+
+description: |
+  Exynos850 clock controller is comprised of several CMU units, generating
+  clocks for different domains. Those CMU units are modeled as separate device
+  tree nodes, and might depend on each other. Root clocks in that clock tree are
+  two external clocks:: OSCCLK (26 MHz) and RTCCLK (32768 Hz). Those external
+  clocks must be defined as fixed-rate clocks in dts.
+
+  CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
+  dividers; all other leaf clocks (other CMUs) are usually derived from CMU_TOP.
+
+  Each clock is assigned an identifier and client nodes can use this identifier
+  to specify the clock which they consume. All clocks available for usage
+  in clock consumer nodes are defined as preprocessor macros in
+  'dt-bindings/clock/exynos850.h' header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos850-cmu-top
+      - samsung,exynos850-cmu-apm
+      - samsung,exynos850-cmu-aud
+      - samsung,exynos850-cmu-cmgp
+      - samsung,exynos850-cmu-core
+      - samsung,exynos850-cmu-dpu
+      - samsung,exynos850-cmu-g3d
+      - samsung,exynos850-cmu-hsi
+      - samsung,exynos850-cmu-is
+      - samsung,exynos850-cmu-mfcmscl
+      - samsung,exynos850-cmu-peri
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-top
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+
+        clock-names:
+          items:
+            - const: oscclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-apm
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_APM bus clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_clkcmu_apm_bus
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-aud
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: AUD clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_aud
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-cmgp
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_CMGP bus clock (from CMU_APM)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: gout_clkcmu_cmgp_bus
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-core
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_CORE bus clock (from CMU_TOP)
+            - description: CCI clock (from CMU_TOP)
+            - description: eMMC clock (from CMU_TOP)
+            - description: SSS clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_core_bus
+            - const: dout_core_cci
+            - const: dout_core_mmc_embd
+            - const: dout_core_sss
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-dpu
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: DPU clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_dpu
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-g3d
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: G3D clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_g3d_switch
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-hsi
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: External RTC clock (32768 Hz)
+            - description: CMU_HSI bus clock (from CMU_TOP)
+            - description: SD card clock (from CMU_TOP)
+            - description: USB 2.0 DRD clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: rtcclk
+            - const: dout_hsi_bus
+            - const: dout_hsi_mmc_card
+            - const: dout_hsi_usb20drd
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-is
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_IS bus clock (from CMU_TOP)
+            - description: Image Texture Processing core clock (from CMU_TOP)
+            - description: Visual Recognition Accelerator clock (from CMU_TOP)
+            - description: Geometric Distortion Correction clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_is_bus
+            - const: dout_is_itp
+            - const: dout_is_vra
+            - const: dout_is_gdc
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-mfcmscl
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: Multi-Format Codec clock (from CMU_TOP)
+            - description: Memory to Memory Scaler clock (from CMU_TOP)
+            - description: Multi-Channel Scaler clock (from CMU_TOP)
+            - description: JPEG codec clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_mfcmscl_mfc
+            - const: dout_mfcmscl_m2m
+            - const: dout_mfcmscl_mcsc
+            - const: dout_mfcmscl_jpeg
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos850-cmu-peri
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (26 MHz)
+            - description: CMU_PERI bus clock (from CMU_TOP)
+            - description: UART clock (from CMU_TOP)
+            - description: Parent clock for HSI2C and SPI (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: dout_peri_bus
+            - const: dout_peri_uart
+            - const: dout_peri_ip
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - reg
+
+additionalProperties: false
+
+examples:
+  # Clock controller node for CMU_PERI
+  - |
+    #include <dt-bindings/clock/exynos850.h>
+
+    cmu_peri: clock-controller@10030000 {
+        compatible = "samsung,exynos850-cmu-peri";
+        reg = <0x10030000 0x8000>;
+        #clock-cells = <1>;
+
+        clocks = <&oscclk>, <&cmu_top CLK_DOUT_PERI_BUS>,
+                 <&cmu_top CLK_DOUT_PERI_UART>,
+                 <&cmu_top CLK_DOUT_PERI_IP>;
+        clock-names = "oscclk", "dout_peri_bus",
+                      "dout_peri_uart", "dout_peri_ip";
+    };
+
+...
diff --git a/include/dt-bindings/clock/exynos850.h b/include/dt-bindings/clock/exynos850.h
new file mode 100644
index 000000000000..3090e09c9a55
--- /dev/null
+++ b/include/dt-bindings/clock/exynos850.h
@@ -0,0 +1,337 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2021 Linaro Ltd.
+ * Author: Sam Protsenko <semen.protsenko@linaro.org>
+ *
+ * Device Tree binding constants for Exynos850 clock controller.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_EXYNOS_850_H
+#define _DT_BINDINGS_CLOCK_EXYNOS_850_H
+
+/* CMU_TOP */
+#define CLK_FOUT_SHARED0_PLL		1
+#define CLK_FOUT_SHARED1_PLL		2
+#define CLK_FOUT_MMC_PLL		3
+#define CLK_MOUT_SHARED0_PLL		4
+#define CLK_MOUT_SHARED1_PLL		5
+#define CLK_MOUT_MMC_PLL		6
+#define CLK_MOUT_CORE_BUS		7
+#define CLK_MOUT_CORE_CCI		8
+#define CLK_MOUT_CORE_MMC_EMBD		9
+#define CLK_MOUT_CORE_SSS		10
+#define CLK_MOUT_DPU			11
+#define CLK_MOUT_HSI_BUS		12
+#define CLK_MOUT_HSI_MMC_CARD		13
+#define CLK_MOUT_HSI_USB20DRD		14
+#define CLK_MOUT_PERI_BUS		15
+#define CLK_MOUT_PERI_UART		16
+#define CLK_MOUT_PERI_IP		17
+#define CLK_DOUT_SHARED0_DIV3		18
+#define CLK_DOUT_SHARED0_DIV2		19
+#define CLK_DOUT_SHARED1_DIV3		20
+#define CLK_DOUT_SHARED1_DIV2		21
+#define CLK_DOUT_SHARED0_DIV4		22
+#define CLK_DOUT_SHARED1_DIV4		23
+#define CLK_DOUT_CORE_BUS		24
+#define CLK_DOUT_CORE_CCI		25
+#define CLK_DOUT_CORE_MMC_EMBD		26
+#define CLK_DOUT_CORE_SSS		27
+#define CLK_DOUT_DPU			28
+#define CLK_DOUT_HSI_BUS		29
+#define CLK_DOUT_HSI_MMC_CARD		30
+#define CLK_DOUT_HSI_USB20DRD		31
+#define CLK_DOUT_PERI_BUS		32
+#define CLK_DOUT_PERI_UART		33
+#define CLK_DOUT_PERI_IP		34
+#define CLK_GOUT_CORE_BUS		35
+#define CLK_GOUT_CORE_CCI		36
+#define CLK_GOUT_CORE_MMC_EMBD		37
+#define CLK_GOUT_CORE_SSS		38
+#define CLK_GOUT_DPU			39
+#define CLK_GOUT_HSI_BUS		40
+#define CLK_GOUT_HSI_MMC_CARD		41
+#define CLK_GOUT_HSI_USB20DRD		42
+#define CLK_GOUT_PERI_BUS		43
+#define CLK_GOUT_PERI_UART		44
+#define CLK_GOUT_PERI_IP		45
+#define CLK_MOUT_CLKCMU_APM_BUS		46
+#define CLK_DOUT_CLKCMU_APM_BUS		47
+#define CLK_GOUT_CLKCMU_APM_BUS		48
+#define CLK_MOUT_AUD			49
+#define CLK_GOUT_AUD			50
+#define CLK_DOUT_AUD			51
+#define CLK_MOUT_IS_BUS			52
+#define CLK_MOUT_IS_ITP			53
+#define CLK_MOUT_IS_VRA			54
+#define CLK_MOUT_IS_GDC			55
+#define CLK_GOUT_IS_BUS			56
+#define CLK_GOUT_IS_ITP			57
+#define CLK_GOUT_IS_VRA			58
+#define CLK_GOUT_IS_GDC			59
+#define CLK_DOUT_IS_BUS			60
+#define CLK_DOUT_IS_ITP			61
+#define CLK_DOUT_IS_VRA			62
+#define CLK_DOUT_IS_GDC			63
+#define CLK_MOUT_MFCMSCL_MFC		64
+#define CLK_MOUT_MFCMSCL_M2M		65
+#define CLK_MOUT_MFCMSCL_MCSC		66
+#define CLK_MOUT_MFCMSCL_JPEG		67
+#define CLK_GOUT_MFCMSCL_MFC		68
+#define CLK_GOUT_MFCMSCL_M2M		69
+#define CLK_GOUT_MFCMSCL_MCSC		70
+#define CLK_GOUT_MFCMSCL_JPEG		71
+#define CLK_DOUT_MFCMSCL_MFC		72
+#define CLK_DOUT_MFCMSCL_M2M		73
+#define CLK_DOUT_MFCMSCL_MCSC		74
+#define CLK_DOUT_MFCMSCL_JPEG		75
+#define CLK_MOUT_G3D_SWITCH		76
+#define CLK_GOUT_G3D_SWITCH		77
+#define CLK_DOUT_G3D_SWITCH		78
+
+/* CMU_APM */
+#define CLK_RCO_I3C_PMIC		1
+#define OSCCLK_RCO_APM			2
+#define CLK_RCO_APM__ALV		3
+#define CLK_DLL_DCO			4
+#define CLK_MOUT_APM_BUS_USER		5
+#define CLK_MOUT_RCO_APM_I3C_USER	6
+#define CLK_MOUT_RCO_APM_USER		7
+#define CLK_MOUT_DLL_USER		8
+#define CLK_MOUT_CLKCMU_CHUB_BUS	9
+#define CLK_MOUT_APM_BUS		10
+#define CLK_MOUT_APM_I3C		11
+#define CLK_DOUT_CLKCMU_CHUB_BUS	12
+#define CLK_DOUT_APM_BUS		13
+#define CLK_DOUT_APM_I3C		14
+#define CLK_GOUT_CLKCMU_CMGP_BUS	15
+#define CLK_GOUT_CLKCMU_CHUB_BUS	16
+#define CLK_GOUT_RTC_PCLK		17
+#define CLK_GOUT_TOP_RTC_PCLK		18
+#define CLK_GOUT_I3C_PCLK		19
+#define CLK_GOUT_I3C_SCLK		20
+#define CLK_GOUT_SPEEDY_PCLK		21
+#define CLK_GOUT_GPIO_ALIVE_PCLK	22
+#define CLK_GOUT_PMU_ALIVE_PCLK		23
+#define CLK_GOUT_SYSREG_APM_PCLK	24
+
+/* CMU_AUD */
+#define CLK_DOUT_AUD_AUDIF		1
+#define CLK_DOUT_AUD_BUSD		2
+#define CLK_DOUT_AUD_BUSP		3
+#define CLK_DOUT_AUD_CNT		4
+#define CLK_DOUT_AUD_CPU		5
+#define CLK_DOUT_AUD_CPU_ACLK		6
+#define CLK_DOUT_AUD_CPU_PCLKDBG	7
+#define CLK_DOUT_AUD_FM			8
+#define CLK_DOUT_AUD_FM_SPDY		9
+#define CLK_DOUT_AUD_MCLK		10
+#define CLK_DOUT_AUD_UAIF0		11
+#define CLK_DOUT_AUD_UAIF1		12
+#define CLK_DOUT_AUD_UAIF2		13
+#define CLK_DOUT_AUD_UAIF3		14
+#define CLK_DOUT_AUD_UAIF4		15
+#define CLK_DOUT_AUD_UAIF5		16
+#define CLK_DOUT_AUD_UAIF6		17
+#define CLK_FOUT_AUD_PLL		18
+#define CLK_GOUT_AUD_ABOX_ACLK		19
+#define CLK_GOUT_AUD_ASB_CCLK		20
+#define CLK_GOUT_AUD_CA32_CCLK		21
+#define CLK_GOUT_AUD_CNT_BCLK		22
+#define CLK_GOUT_AUD_CODEC_MCLK		23
+#define CLK_GOUT_AUD_DAP_CCLK		24
+#define CLK_GOUT_AUD_GPIO_PCLK		25
+#define CLK_GOUT_AUD_PPMU_ACLK		26
+#define CLK_GOUT_AUD_PPMU_PCLK		27
+#define CLK_GOUT_AUD_SPDY_BCLK		28
+#define CLK_GOUT_AUD_SYSMMU_CLK		29
+#define CLK_GOUT_AUD_SYSREG_PCLK	30
+#define CLK_GOUT_AUD_TZPC_PCLK		31
+#define CLK_GOUT_AUD_UAIF0_BCLK		32
+#define CLK_GOUT_AUD_UAIF1_BCLK		33
+#define CLK_GOUT_AUD_UAIF2_BCLK		34
+#define CLK_GOUT_AUD_UAIF3_BCLK		35
+#define CLK_GOUT_AUD_UAIF4_BCLK		36
+#define CLK_GOUT_AUD_UAIF5_BCLK		37
+#define CLK_GOUT_AUD_UAIF6_BCLK		38
+#define CLK_GOUT_AUD_WDT_PCLK		39
+#define CLK_MOUT_AUD_CPU		40
+#define CLK_MOUT_AUD_CPU_HCH		41
+#define CLK_MOUT_AUD_CPU_USER		42
+#define CLK_MOUT_AUD_FM			43
+#define CLK_MOUT_AUD_PLL		44
+#define CLK_MOUT_AUD_TICK_USB_USER	45
+#define CLK_MOUT_AUD_UAIF0		46
+#define CLK_MOUT_AUD_UAIF1		47
+#define CLK_MOUT_AUD_UAIF2		48
+#define CLK_MOUT_AUD_UAIF3		49
+#define CLK_MOUT_AUD_UAIF4		50
+#define CLK_MOUT_AUD_UAIF5		51
+#define CLK_MOUT_AUD_UAIF6		52
+#define IOCLK_AUDIOCDCLK0		53
+#define IOCLK_AUDIOCDCLK1		54
+#define IOCLK_AUDIOCDCLK2		55
+#define IOCLK_AUDIOCDCLK3		56
+#define IOCLK_AUDIOCDCLK4		57
+#define IOCLK_AUDIOCDCLK5		58
+#define IOCLK_AUDIOCDCLK6		59
+#define TICK_USB			60
+#define CLK_GOUT_AUD_CMU_AUD_PCLK	61
+
+/* CMU_CMGP */
+#define CLK_RCO_CMGP			1
+#define CLK_MOUT_CMGP_ADC		2
+#define CLK_MOUT_CMGP_USI0		3
+#define CLK_MOUT_CMGP_USI1		4
+#define CLK_DOUT_CMGP_ADC		5
+#define CLK_DOUT_CMGP_USI0		6
+#define CLK_DOUT_CMGP_USI1		7
+#define CLK_GOUT_CMGP_ADC_S0_PCLK	8
+#define CLK_GOUT_CMGP_ADC_S1_PCLK	9
+#define CLK_GOUT_CMGP_GPIO_PCLK		10
+#define CLK_GOUT_CMGP_USI0_IPCLK	11
+#define CLK_GOUT_CMGP_USI0_PCLK		12
+#define CLK_GOUT_CMGP_USI1_IPCLK	13
+#define CLK_GOUT_CMGP_USI1_PCLK		14
+#define CLK_GOUT_SYSREG_CMGP_PCLK	15
+
+/* CMU_G3D */
+#define CLK_FOUT_G3D_PLL		1
+#define CLK_MOUT_G3D_PLL		2
+#define CLK_MOUT_G3D_SWITCH_USER	3
+#define CLK_MOUT_G3D_BUSD		4
+#define CLK_DOUT_G3D_BUSP		5
+#define CLK_GOUT_G3D_CMU_G3D_PCLK	6
+#define CLK_GOUT_G3D_GPU_CLK		7
+#define CLK_GOUT_G3D_TZPC_PCLK		8
+#define CLK_GOUT_G3D_GRAY2BIN_CLK	9
+#define CLK_GOUT_G3D_BUSD_CLK		10
+#define CLK_GOUT_G3D_BUSP_CLK		11
+#define CLK_GOUT_G3D_SYSREG_PCLK	12
+
+/* CMU_HSI */
+#define CLK_MOUT_HSI_BUS_USER		1
+#define CLK_MOUT_HSI_MMC_CARD_USER	2
+#define CLK_MOUT_HSI_USB20DRD_USER	3
+#define CLK_MOUT_HSI_RTC		4
+#define CLK_GOUT_USB_RTC_CLK		5
+#define CLK_GOUT_USB_REF_CLK		6
+#define CLK_GOUT_USB_PHY_REF_CLK	7
+#define CLK_GOUT_USB_PHY_ACLK		8
+#define CLK_GOUT_USB_BUS_EARLY_CLK	9
+#define CLK_GOUT_GPIO_HSI_PCLK		10
+#define CLK_GOUT_MMC_CARD_ACLK		11
+#define CLK_GOUT_MMC_CARD_SDCLKIN	12
+#define CLK_GOUT_SYSREG_HSI_PCLK	13
+#define CLK_GOUT_HSI_PPMU_ACLK		14
+#define CLK_GOUT_HSI_PPMU_PCLK		15
+#define CLK_GOUT_HSI_CMU_HSI_PCLK	16
+
+/* CMU_IS */
+#define CLK_MOUT_IS_BUS_USER		1
+#define CLK_MOUT_IS_ITP_USER		2
+#define CLK_MOUT_IS_VRA_USER		3
+#define CLK_MOUT_IS_GDC_USER		4
+#define CLK_DOUT_IS_BUSP		5
+#define CLK_GOUT_IS_CMU_IS_PCLK		6
+#define CLK_GOUT_IS_CSIS0_ACLK		7
+#define CLK_GOUT_IS_CSIS1_ACLK		8
+#define CLK_GOUT_IS_CSIS2_ACLK		9
+#define CLK_GOUT_IS_TZPC_PCLK		10
+#define CLK_GOUT_IS_CSIS_DMA_CLK	11
+#define CLK_GOUT_IS_GDC_CLK		12
+#define CLK_GOUT_IS_IPP_CLK		13
+#define CLK_GOUT_IS_ITP_CLK		14
+#define CLK_GOUT_IS_MCSC_CLK		15
+#define CLK_GOUT_IS_VRA_CLK		16
+#define CLK_GOUT_IS_PPMU_IS0_ACLK	17
+#define CLK_GOUT_IS_PPMU_IS0_PCLK	18
+#define CLK_GOUT_IS_PPMU_IS1_ACLK	19
+#define CLK_GOUT_IS_PPMU_IS1_PCLK	20
+#define CLK_GOUT_IS_SYSMMU_IS0_CLK	21
+#define CLK_GOUT_IS_SYSMMU_IS1_CLK	22
+#define CLK_GOUT_IS_SYSREG_PCLK		23
+
+/* CMU_MFCMSCL */
+#define CLK_MOUT_MFCMSCL_MFC_USER		1
+#define CLK_MOUT_MFCMSCL_M2M_USER		2
+#define CLK_MOUT_MFCMSCL_MCSC_USER		3
+#define CLK_MOUT_MFCMSCL_JPEG_USER		4
+#define CLK_DOUT_MFCMSCL_BUSP			5
+#define CLK_GOUT_MFCMSCL_CMU_MFCMSCL_PCLK	6
+#define CLK_GOUT_MFCMSCL_TZPC_PCLK		7
+#define CLK_GOUT_MFCMSCL_JPEG_ACLK		8
+#define CLK_GOUT_MFCMSCL_M2M_ACLK		9
+#define CLK_GOUT_MFCMSCL_MCSC_CLK		10
+#define CLK_GOUT_MFCMSCL_MFC_ACLK		11
+#define CLK_GOUT_MFCMSCL_PPMU_ACLK		12
+#define CLK_GOUT_MFCMSCL_PPMU_PCLK		13
+#define CLK_GOUT_MFCMSCL_SYSMMU_CLK		14
+#define CLK_GOUT_MFCMSCL_SYSREG_PCLK		15
+
+/* CMU_PERI */
+#define CLK_MOUT_PERI_BUS_USER		1
+#define CLK_MOUT_PERI_UART_USER		2
+#define CLK_MOUT_PERI_HSI2C_USER	3
+#define CLK_MOUT_PERI_SPI_USER		4
+#define CLK_DOUT_PERI_HSI2C0		5
+#define CLK_DOUT_PERI_HSI2C1		6
+#define CLK_DOUT_PERI_HSI2C2		7
+#define CLK_DOUT_PERI_SPI0		8
+#define CLK_GOUT_PERI_HSI2C0		9
+#define CLK_GOUT_PERI_HSI2C1		10
+#define CLK_GOUT_PERI_HSI2C2		11
+#define CLK_GOUT_GPIO_PERI_PCLK		12
+#define CLK_GOUT_HSI2C0_IPCLK		13
+#define CLK_GOUT_HSI2C0_PCLK		14
+#define CLK_GOUT_HSI2C1_IPCLK		15
+#define CLK_GOUT_HSI2C1_PCLK		16
+#define CLK_GOUT_HSI2C2_IPCLK		17
+#define CLK_GOUT_HSI2C2_PCLK		18
+#define CLK_GOUT_I2C0_PCLK		19
+#define CLK_GOUT_I2C1_PCLK		20
+#define CLK_GOUT_I2C2_PCLK		21
+#define CLK_GOUT_I2C3_PCLK		22
+#define CLK_GOUT_I2C4_PCLK		23
+#define CLK_GOUT_I2C5_PCLK		24
+#define CLK_GOUT_I2C6_PCLK		25
+#define CLK_GOUT_MCT_PCLK		26
+#define CLK_GOUT_PWM_MOTOR_PCLK		27
+#define CLK_GOUT_SPI0_IPCLK		28
+#define CLK_GOUT_SPI0_PCLK		29
+#define CLK_GOUT_SYSREG_PERI_PCLK	30
+#define CLK_GOUT_UART_IPCLK		31
+#define CLK_GOUT_UART_PCLK		32
+#define CLK_GOUT_WDT0_PCLK		33
+#define CLK_GOUT_WDT1_PCLK		34
+
+/* CMU_CORE */
+#define CLK_MOUT_CORE_BUS_USER		1
+#define CLK_MOUT_CORE_CCI_USER		2
+#define CLK_MOUT_CORE_MMC_EMBD_USER	3
+#define CLK_MOUT_CORE_SSS_USER		4
+#define CLK_MOUT_CORE_GIC		5
+#define CLK_DOUT_CORE_BUSP		6
+#define CLK_GOUT_CCI_ACLK		7
+#define CLK_GOUT_GIC_CLK		8
+#define CLK_GOUT_MMC_EMBD_ACLK		9
+#define CLK_GOUT_MMC_EMBD_SDCLKIN	10
+#define CLK_GOUT_SSS_ACLK		11
+#define CLK_GOUT_SSS_PCLK		12
+#define CLK_GOUT_GPIO_CORE_PCLK		13
+#define CLK_GOUT_SYSREG_CORE_PCLK	14
+
+/* CMU_DPU */
+#define CLK_MOUT_DPU_USER		1
+#define CLK_DOUT_DPU_BUSP		2
+#define CLK_GOUT_DPU_CMU_DPU_PCLK	3
+#define CLK_GOUT_DPU_DECON0_ACLK	4
+#define CLK_GOUT_DPU_DMA_ACLK		5
+#define CLK_GOUT_DPU_DPP_ACLK		6
+#define CLK_GOUT_DPU_PPMU_ACLK		7
+#define CLK_GOUT_DPU_PPMU_PCLK		8
+#define CLK_GOUT_DPU_SMMU_CLK		9
+#define CLK_GOUT_DPU_SYSREG_PCLK	10
+#define DPU_NR_CLK			11
+
+#endif /* _DT_BINDINGS_CLOCK_EXYNOS_850_H */
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 04/13] soc: samsung: Add Exynos USI driver
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
                   ` (2 preceding siblings ...)
  2023-12-13  3:16 ` [PATCH 03/13] dt-bindings: clock: Add Exynos850 clock controller Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-19 11:40   ` Chanho Park
                     ` (2 more replies)
  2023-12-13  3:16 ` [PATCH 05/13] soc: samsung: Add Exynos PMU driver Sam Protsenko
                   ` (9 subsequent siblings)
  13 siblings, 3 replies; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

USIv2 IP-core is found on modern ARM64 Exynos SoCs (like Exynos850) and
provides selectable serial protocol (one of: UART, SPI, I2C). USIv2
registers usually reside in the same register map as a particular
underlying protocol it implements, but have some particular offset. E.g.
on Exynos850 the USI_UART has 0x13820000 base address, where UART
registers have 0x00..0x40 offsets, and USI registers have 0xc0..0xdc
offsets. Desired protocol can be chosen via SW_CONF register from System
Register block of the same domain as USI.

Before starting to use a particular protocol, USIv2 must be configured
properly:
  1. Select protocol to be used via System Register
  2. Clear "reset" flag in USI_CON
  3. Configure HWACG behavior (e.g. for UART Rx the HWACG must be
     disabled, so that the IP clock is not gated automatically); this is
     done using USI_OPTION register
  4. Keep both USI clocks (PCLK and IPCLK) running during USI registers
     modification

This driver implements the above behavior. Of course, USIv2 driver
should be probed before UART/I2C/SPI drivers. It can be achieved by
embedding UART/I2C/SPI nodes inside of the USI node (in Device Tree);
driver then walks underlying nodes and instantiates those. Driver also
handles USI configuration on PM resume, as register contents can be lost
during CPU suspend.

This driver is designed with different USI versions in mind. So it
should be relatively easy to add new USI revisions to it later.

Driver's code was copied over from Linux kernel [1] and adapted
correspondingly for U-Boot API. UCLASS_MISC is used, and although no
misc operations are implemented, it makes it easier to probe the driver
this way (as compared to UCLASS_NOP) and keep the code compact.

[1] drivers/soc/samsung/exynos-usi.c

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/soc/Kconfig              |   1 +
 drivers/soc/Makefile             |   1 +
 drivers/soc/samsung/Kconfig      |  23 ++++
 drivers/soc/samsung/Makefile     |   3 +
 drivers/soc/samsung/exynos-usi.c | 218 +++++++++++++++++++++++++++++++
 5 files changed, 246 insertions(+)
 create mode 100644 drivers/soc/samsung/Kconfig
 create mode 100644 drivers/soc/samsung/Makefile
 create mode 100644 drivers/soc/samsung/exynos-usi.c

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 85dac9de78a4..03433bc0e6d2 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -40,6 +40,7 @@ config SOC_XILINX_VERSAL_NET
 	  This allows other drivers to verify the SoC familiy & revision using
 	  matching SoC attributes.
 
+source "drivers/soc/samsung/Kconfig"
 source "drivers/soc/ti/Kconfig"
 
 endmenu
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 84385650d46d..610bf816d40a 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,6 +2,7 @@
 #
 # Makefile for the U-Boot SOC specific device drivers.
 
+obj-$(CONFIG_SOC_SAMSUNG) += samsung/
 obj-$(CONFIG_SOC_TI) += ti/
 obj-$(CONFIG_SOC_DEVICE) += soc-uclass.o
 obj-$(CONFIG_SOC_DEVICE_TI_K3) += soc_ti_k3.o
diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
new file mode 100644
index 000000000000..ffb87fe79316
--- /dev/null
+++ b/drivers/soc/samsung/Kconfig
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+menuconfig SOC_SAMSUNG
+	bool "Samsung SoC drivers support"
+
+if SOC_SAMSUNG
+
+config EXYNOS_USI
+	bool "Exynos USI (Universal Serial Interface) driver"
+	depends on ARCH_EXYNOS
+	select MISC
+	select REGMAP
+	select SYSCON
+	help
+	  Enable support for USI block. USI (Universal Serial Interface) is an
+	  IP-core found in modern Samsung Exynos SoCs, like Exynos850 and
+	  ExynosAutoV9. USI block can be configured to provide one of the
+	  following serial protocols: UART, SPI or High Speed I2C.
+
+	  This driver allows one to configure USI for desired protocol, which
+	  is usually done in USI node in Device Tree.
+
+endif
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
new file mode 100644
index 000000000000..833ac073fbfa
--- /dev/null
+++ b/drivers/soc/samsung/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-$(CONFIG_EXYNOS_USI)	+= exynos-usi.o
diff --git a/drivers/soc/samsung/exynos-usi.c b/drivers/soc/samsung/exynos-usi.c
new file mode 100644
index 000000000000..23255177e6e3
--- /dev/null
+++ b/drivers/soc/samsung/exynos-usi.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Linaro Ltd.
+ * Author: Sam Protsenko <semen.protsenko@linaro.org>
+ *
+ * Samsung Exynos USI driver (Universal Serial Interface).
+ */
+
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <errno.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+#include <dt-bindings/soc/samsung,exynos-usi.h>
+
+/* USIv2: System Register: SW_CONF register bits */
+#define USI_V2_SW_CONF_NONE	0x0
+#define USI_V2_SW_CONF_UART	BIT(0)
+#define USI_V2_SW_CONF_SPI	BIT(1)
+#define USI_V2_SW_CONF_I2C	BIT(2)
+#define USI_V2_SW_CONF_MASK	(USI_V2_SW_CONF_UART | USI_V2_SW_CONF_SPI | \
+				 USI_V2_SW_CONF_I2C)
+
+/* USIv2: USI register offsets */
+#define USI_CON			0x04
+#define USI_OPTION		0x08
+
+/* USIv2: USI register bits */
+#define USI_CON_RESET		BIT(0)
+#define USI_OPTION_CLKREQ_ON	BIT(1)
+#define USI_OPTION_CLKSTOP_ON	BIT(2)
+
+enum exynos_usi_ver {
+	USI_VER2 = 2,
+};
+
+struct exynos_usi_variant {
+	enum exynos_usi_ver ver;	/* USI IP-core version */
+	unsigned int sw_conf_mask;	/* SW_CONF mask for all protocols */
+	size_t min_mode;		/* first index in exynos_usi_modes[] */
+	size_t max_mode;		/* last index in exynos_usi_modes[] */
+};
+
+struct exynos_usi {
+	struct udevice *dev;
+	void __iomem *regs;		/* USI register map */
+
+	size_t mode;			/* current USI SW_CONF mode index */
+	bool clkreq_on;			/* always provide clock to IP */
+
+	/* System Register */
+	struct regmap *sysreg;		/* System Register map */
+	unsigned int sw_conf;		/* SW_CONF register offset in sysreg */
+
+	const struct exynos_usi_variant *data;
+};
+
+struct exynos_usi_mode {
+	const char *name;		/* mode name */
+	unsigned int val;		/* mode register value */
+};
+
+static const struct exynos_usi_mode exynos_usi_modes[] = {
+	[USI_V2_NONE] =	{ .name = "none", .val = USI_V2_SW_CONF_NONE },
+	[USI_V2_UART] =	{ .name = "uart", .val = USI_V2_SW_CONF_UART },
+	[USI_V2_SPI] =	{ .name = "spi",  .val = USI_V2_SW_CONF_SPI },
+	[USI_V2_I2C] =	{ .name = "i2c",  .val = USI_V2_SW_CONF_I2C },
+};
+
+static const struct exynos_usi_variant exynos850_usi_data = {
+	.ver		= USI_VER2,
+	.sw_conf_mask	= USI_V2_SW_CONF_MASK,
+	.min_mode	= USI_V2_NONE,
+	.max_mode	= USI_V2_I2C,
+};
+
+static const struct udevice_id exynos_usi_ids[] = {
+	{
+		.compatible = "samsung,exynos850-usi",
+		.data = (ulong)&exynos850_usi_data,
+	},
+	{ } /* sentinel */
+};
+
+/**
+ * exynos_usi_set_sw_conf - Set USI block configuration mode
+ * @usi: USI driver object
+ * @mode: Mode index
+ *
+ * Select underlying serial protocol (UART/SPI/I2C) in USI IP-core.
+ *
+ * Return: 0 on success, or negative error code on failure.
+ */
+static int exynos_usi_set_sw_conf(struct exynos_usi *usi, size_t mode)
+{
+	unsigned int val;
+	int ret;
+
+	if (mode < usi->data->min_mode || mode > usi->data->max_mode)
+		return -EINVAL;
+
+	val = exynos_usi_modes[mode].val;
+	ret = regmap_update_bits(usi->sysreg, usi->sw_conf,
+				 usi->data->sw_conf_mask, val);
+	if (ret)
+		return ret;
+
+	usi->mode = mode;
+	dev_dbg(usi->dev, "protocol: %s\n", exynos_usi_modes[usi->mode].name);
+
+	return 0;
+}
+
+/**
+ * exynos_usi_enable - Initialize USI block
+ * @usi: USI driver object
+ *
+ * USI IP-core start state is "reset" (on startup and after CPU resume). This
+ * routine enables the USI block by clearing the reset flag. It also configures
+ * HWACG behavior (needed e.g. for UART Rx). It should be performed before
+ * underlying protocol becomes functional.
+ */
+static void exynos_usi_enable(const struct exynos_usi *usi)
+{
+	u32 val;
+
+	/* Enable USI block */
+	val = readl(usi->regs + USI_CON);
+	val &= ~USI_CON_RESET;
+	writel(val, usi->regs + USI_CON);
+	udelay(1);
+
+	/* Continuously provide the clock to USI IP w/o gating */
+	if (usi->clkreq_on) {
+		val = readl(usi->regs + USI_OPTION);
+		val &= ~USI_OPTION_CLKSTOP_ON;
+		val |= USI_OPTION_CLKREQ_ON;
+		writel(val, usi->regs + USI_OPTION);
+	}
+}
+
+static int exynos_usi_configure(struct exynos_usi *usi)
+{
+	int ret;
+
+	ret = exynos_usi_set_sw_conf(usi, usi->mode);
+	if (ret)
+		return ret;
+
+	if (usi->data->ver == USI_VER2)
+		exynos_usi_enable(usi);
+
+	return 0;
+}
+
+static int exynos_usi_parse_dt(struct exynos_usi *usi)
+{
+	struct udevice *dev = usi->dev;
+	ofnode node;
+	int ret;
+	u32 mode;
+
+	node = dev_ofnode(dev);
+
+	ret = ofnode_read_u32(node, "samsung,mode", &mode);
+	if (ret)
+		return ret;
+	if (mode < usi->data->min_mode || mode > usi->data->max_mode)
+		return -EINVAL;
+	usi->mode = mode;
+
+	usi->sysreg = syscon_regmap_lookup_by_phandle(dev, "samsung,sysreg");
+	if (IS_ERR(usi->sysreg))
+		return PTR_ERR(usi->sysreg);
+
+	ret = ofnode_read_u32_index(node, "samsung,sysreg", 1, &usi->sw_conf);
+	if (ret)
+		return ret;
+
+	usi->clkreq_on = ofnode_read_bool(node, "samsung,clkreq-on");
+
+	return 0;
+}
+
+static int exynos_usi_probe(struct udevice *dev)
+{
+	struct exynos_usi *usi;
+	int ret;
+
+	usi = dev_get_priv(dev);
+	usi->dev = dev;
+	usi->data = (struct exynos_usi_variant *)dev_get_driver_data(dev);
+
+	ret = exynos_usi_parse_dt(usi);
+	if (ret)
+		return ret;
+
+	if (usi->data->ver == USI_VER2) {
+		usi->regs = dev_read_addr_ptr(dev);
+		if (!usi->regs)
+			return -ENODEV;
+	}
+
+	return exynos_usi_configure(usi);
+}
+
+U_BOOT_DRIVER(exynos_usi) = {
+	.name		= "exynos-usi",
+	.id		= UCLASS_MISC,
+	.of_match	= exynos_usi_ids,
+	.probe		= exynos_usi_probe,
+	.priv_auto	= sizeof(struct exynos_usi),
+};
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 05/13] soc: samsung: Add Exynos PMU driver
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
                   ` (3 preceding siblings ...)
  2023-12-13  3:16 ` [PATCH 04/13] soc: samsung: Add Exynos USI driver Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-19 11:39   ` Chanho Park
  2023-12-13  3:16 ` [PATCH 06/13] clk: exynos: Move pll code into clk-exynos7420 Sam Protsenko
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

Add basic Power Management Unit (PMU) driver for Exynos SoCs. For now
it's only capable of changing UART path in PMU, which is needed for
E850-96 board. The driver's structure resembles the exynos-pmu driver
from Linux kernel, and although it's very basic and slim at the moment,
it can be easily extended in future if the need arises.

UCLASS_NOP is used, as there are no benefits in using more elaborate
classes like UCLASS_MISC in this case. The DM_FLAG_PROBE_AFTER_BIND flag
is added in bind function, as the probe function must be always called
for this driver.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/soc/samsung/Kconfig      |  10 +++
 drivers/soc/samsung/Makefile     |   1 +
 drivers/soc/samsung/exynos-pmu.c | 102 +++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+)
 create mode 100644 drivers/soc/samsung/exynos-pmu.c

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index ffb87fe79316..737b7ca8cd19 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -5,6 +5,16 @@ menuconfig SOC_SAMSUNG
 
 if SOC_SAMSUNG
 
+config EXYNOS_PMU
+	bool "Exynos PMU controller driver"
+	depends on ARCH_EXYNOS
+	select REGMAP
+	select SYSCON
+	help
+	  Enable support for system controller configuration driver. It allows
+	  one to configure system controller registers (e.g. some register in
+	  PMU syscon) by providing register's offset, mask and value.
+
 config EXYNOS_USI
 	bool "Exynos USI (Universal Serial Interface) driver"
 	depends on ARCH_EXYNOS
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
index 833ac073fbfa..0eb3ed8353b0 100644
--- a/drivers/soc/samsung/Makefile
+++ b/drivers/soc/samsung/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0+
 
+obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o
 obj-$(CONFIG_EXYNOS_USI)	+= exynos-usi.o
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
new file mode 100644
index 000000000000..233ad4a908f5
--- /dev/null
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Linaro Ltd.
+ * Author: Sam Protsenko <semen.protsenko@linaro.org>
+ *
+ * Exynos PMU (Power Management Unit) driver.
+ */
+
+#include <dm.h>
+#include <errno.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+
+#define EXYNOS850_UART_IO_SHARE_CTRL	0x0760
+#define SEL_RXD_AP_UART_SHIFT		16
+#define SEL_RXD_AP_UART_MASK		GENMASK(17, 16)
+#define SEL_TXD_GPIO_1_SHIFT		20
+#define SEL_TXD_GPIO_1_MASK		GENMASK(21, 20)
+#define RXD_GPIO_1			0x3
+#define TXD_AP_UART			0x0
+
+struct exynos_pmu {
+	struct udevice *dev;
+	const struct exynos_pmu_data *pmu_data;
+	struct regmap *regmap;
+};
+
+struct exynos_pmu_data {
+	int (*pmu_init)(struct exynos_pmu *priv);
+};
+
+static int exynos850_pmu_init(struct exynos_pmu *priv)
+{
+	ofnode node;
+	bool uart_debug_1;
+	unsigned int offset, mask, value;
+
+	node = dev_ofnode(priv->dev);
+	uart_debug_1 = ofnode_read_bool(node, "samsung,uart-debug-1");
+	if (!uart_debug_1)
+		return 0;
+
+	/*
+	 * If uart1_pins are used for serial, AP UART lines have to be muxed
+	 * in PMU block to UART_DEBUG_1 path (GPIO_1). By default (reset value)
+	 * UART_DEBUG_0 path (uart0_pins) is connected to AP UART lines.
+	 */
+	offset = EXYNOS850_UART_IO_SHARE_CTRL;
+	mask = SEL_RXD_AP_UART_MASK | SEL_TXD_GPIO_1_MASK;
+	value = RXD_GPIO_1 << SEL_RXD_AP_UART_SHIFT |
+		TXD_AP_UART << SEL_TXD_GPIO_1_SHIFT;
+	return regmap_update_bits(priv->regmap, offset, mask, value);
+}
+
+static const struct exynos_pmu_data exynos850_pmu_data = {
+	.pmu_init = exynos850_pmu_init,
+};
+
+static int exynos_pmu_bind(struct udevice *dev)
+{
+	dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
+	return 0;
+}
+
+static int exynos_pmu_probe(struct udevice *dev)
+{
+	ofnode node;
+	struct exynos_pmu *priv;
+
+	priv = dev_get_priv(dev);
+	priv->dev = dev;
+
+	node = dev_ofnode(dev);
+	priv->regmap = syscon_node_to_regmap(node);
+	if (IS_ERR(priv->regmap))
+		return PTR_ERR(priv->regmap);
+
+	priv->pmu_data = (struct exynos_pmu_data *)dev_get_driver_data(dev);
+	if (priv->pmu_data && priv->pmu_data->pmu_init)
+		return priv->pmu_data->pmu_init(priv);
+
+	return 0;
+}
+
+static const struct udevice_id exynos_pmu_ids[] = {
+	{
+		.compatible = "samsung,exynos850-pmu",
+		.data = (ulong)&exynos850_pmu_data
+	},
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(exynos_pmu) = {
+	.name		= "exynos-pmu",
+	.id		= UCLASS_NOP,
+	.of_match	= exynos_pmu_ids,
+	.bind		= exynos_pmu_bind,
+	.probe		= exynos_pmu_probe,
+	.priv_auto	= sizeof(struct exynos_pmu),
+};
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 06/13] clk: exynos: Move pll code into clk-exynos7420
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
                   ` (4 preceding siblings ...)
  2023-12-13  3:16 ` [PATCH 05/13] soc: samsung: Add Exynos PMU driver Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-19 11:41   ` Chanho Park
  2023-12-13  3:16 ` [PATCH 07/13] clk: exynos: Add Samsung clock framework Sam Protsenko
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

PLL utilities code is only used by clk-exynos7420 driver at the moment.
Move it into clk-exynos7420 to make clk-pll.c file available for CCF PLL
clocks implementation, which is coming in the next patches.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/clk/exynos/Makefile         |  1 -
 drivers/clk/exynos/clk-exynos7420.c | 25 +++++++++++++++++++++-
 drivers/clk/exynos/clk-pll.c        | 32 -----------------------------
 drivers/clk/exynos/clk-pll.h        | 13 ------------
 4 files changed, 24 insertions(+), 47 deletions(-)
 delete mode 100644 drivers/clk/exynos/clk-pll.c
 delete mode 100644 drivers/clk/exynos/clk-pll.h

diff --git a/drivers/clk/exynos/Makefile b/drivers/clk/exynos/Makefile
index c9f29c873e9b..7faf238571ef 100644
--- a/drivers/clk/exynos/Makefile
+++ b/drivers/clk/exynos/Makefile
@@ -3,5 +3,4 @@
 # Copyright (C) 2016 Samsung Electronics
 # Thomas Abraham <thomas.ab@samsung.com>
 
-obj-y				+= clk-pll.o
 obj-$(CONFIG_CLK_EXYNOS7420)	+= clk-exynos7420.o
diff --git a/drivers/clk/exynos/clk-exynos7420.c b/drivers/clk/exynos/clk-exynos7420.c
index 7d869eb02b8e..9caa932e12fb 100644
--- a/drivers/clk/exynos/clk-exynos7420.c
+++ b/drivers/clk/exynos/clk-exynos7420.c
@@ -10,8 +10,15 @@
 #include <errno.h>
 #include <clk-uclass.h>
 #include <asm/io.h>
+#include <div64.h>
 #include <dt-bindings/clock/exynos7420-clk.h>
-#include "clk-pll.h"
+
+#define PLL145X_MDIV_SHIFT	16
+#define PLL145X_MDIV_MASK	0x3ff
+#define PLL145X_PDIV_SHIFT	8
+#define PLL145X_PDIV_MASK	0x3f
+#define PLL145X_SDIV_SHIFT	0
+#define PLL145X_SDIV_MASK	0x7
 
 #define DIVIDER(reg, shift, mask)	\
 	(((readl(reg) >> shift) & mask) + 1)
@@ -64,6 +71,22 @@ struct exynos7420_clk_top0_priv {
 	unsigned long sclk_uart2;
 };
 
+static unsigned long pll145x_get_rate(unsigned int *con1,
+				      unsigned long fin_freq)
+{
+	unsigned long pll_con1 = readl(con1);
+	unsigned long mdiv, sdiv, pdiv;
+	u64 fvco = fin_freq;
+
+	mdiv = (pll_con1 >> PLL145X_MDIV_SHIFT) & PLL145X_MDIV_MASK;
+	pdiv = (pll_con1 >> PLL145X_PDIV_SHIFT) & PLL145X_PDIV_MASK;
+	sdiv = (pll_con1 >> PLL145X_SDIV_SHIFT) & PLL145X_SDIV_MASK;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+	return (unsigned long)fvco;
+}
+
 static ulong exynos7420_topc_get_rate(struct clk *clk)
 {
 	struct exynos7420_clk_topc_priv *priv = dev_get_priv(clk->dev);
diff --git a/drivers/clk/exynos/clk-pll.c b/drivers/clk/exynos/clk-pll.c
deleted file mode 100644
index 407fc71d415b..000000000000
--- a/drivers/clk/exynos/clk-pll.c
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Exynos PLL helper functions for clock drivers.
- * Copyright (C) 2016 Samsung Electronics
- * Thomas Abraham <thomas.ab@samsung.com>
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <div64.h>
-
-#define PLL145X_MDIV_SHIFT	16
-#define PLL145X_MDIV_MASK	0x3ff
-#define PLL145X_PDIV_SHIFT	8
-#define PLL145X_PDIV_MASK	0x3f
-#define PLL145X_SDIV_SHIFT	0
-#define PLL145X_SDIV_MASK	0x7
-
-unsigned long pll145x_get_rate(unsigned int *con1, unsigned long fin_freq)
-{
-	unsigned long pll_con1 = readl(con1);
-	unsigned long mdiv, sdiv, pdiv;
-	uint64_t fvco = fin_freq;
-
-	mdiv = (pll_con1 >> PLL145X_MDIV_SHIFT) & PLL145X_MDIV_MASK;
-	pdiv = (pll_con1 >> PLL145X_PDIV_SHIFT) & PLL145X_PDIV_MASK;
-	sdiv = (pll_con1 >> PLL145X_SDIV_SHIFT) & PLL145X_SDIV_MASK;
-
-	fvco *= mdiv;
-	do_div(fvco, (pdiv << sdiv));
-	return (unsigned long)fvco;
-}
diff --git a/drivers/clk/exynos/clk-pll.h b/drivers/clk/exynos/clk-pll.h
deleted file mode 100644
index 7b7af5e67612..000000000000
--- a/drivers/clk/exynos/clk-pll.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Exynos PLL helper functions for clock drivers.
- * Copyright (C) 2016 Samsung Electronics
- * Thomas Abraham <thomas.ab@samsung.com>
- */
-
-#ifndef __EXYNOS_CLK_PLL_H
-#define __EXYNOS_CLK_PLL_H
-
-unsigned long pll145x_get_rate(unsigned int *con1, unsigned long fin_freq);
-
-#endif /* __EXYNOS_CLK_PLL_H */
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 07/13] clk: exynos: Add Samsung clock framework
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
                   ` (5 preceding siblings ...)
  2023-12-13  3:16 ` [PATCH 06/13] clk: exynos: Move pll code into clk-exynos7420 Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-19 11:38   ` Chanho Park
  2023-12-27  9:11   ` Minkyu Kang
  2023-12-13  3:16 ` [PATCH 08/13] clk: exynos: Add Exynos850 clock driver Sam Protsenko
                   ` (6 subsequent siblings)
  13 siblings, 2 replies; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

Heavily based on Linux kernel Samsung clock framework, with some changes
to accommodate the differences in U-Boot CCF implementation. It's also
quite minimal as compared to the Linux version.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/clk/exynos/Makefile  |   9 +-
 drivers/clk/exynos/clk-pll.c | 167 +++++++++++++++++++++++++
 drivers/clk/exynos/clk-pll.h |  23 ++++
 drivers/clk/exynos/clk.c     | 121 +++++++++++++++++++
 drivers/clk/exynos/clk.h     | 228 +++++++++++++++++++++++++++++++++++
 5 files changed, 546 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/exynos/clk-pll.c
 create mode 100644 drivers/clk/exynos/clk-pll.h
 create mode 100644 drivers/clk/exynos/clk.c
 create mode 100644 drivers/clk/exynos/clk.h

diff --git a/drivers/clk/exynos/Makefile b/drivers/clk/exynos/Makefile
index 7faf238571ef..04c5b9a39e16 100644
--- a/drivers/clk/exynos/Makefile
+++ b/drivers/clk/exynos/Makefile
@@ -1,6 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0+
 #
 # Copyright (C) 2016 Samsung Electronics
-# Thomas Abraham <thomas.ab@samsung.com>
+# Copyright (C) 2023 Linaro Ltd.
+#
+# Authors:
+#   Thomas Abraham <thomas.ab@samsung.com>
+#   Sam Protsenko <semen.protsenko@linaro.org>
 
-obj-$(CONFIG_CLK_EXYNOS7420)	+= clk-exynos7420.o
+obj-$(CONFIG_$(SPL_TPL_)CLK_CCF)	+= clk.o clk-pll.o
+obj-$(CONFIG_CLK_EXYNOS7420)		+= clk-exynos7420.o
diff --git a/drivers/clk/exynos/clk-pll.c b/drivers/clk/exynos/clk-pll.c
new file mode 100644
index 000000000000..9e496ff83aaf
--- /dev/null
+++ b/drivers/clk/exynos/clk-pll.c
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Samsung Electronics
+ * Copyright (C) 2023 Linaro Ltd.
+ *
+ * Authors:
+ *   Thomas Abraham <thomas.ab@exynos.com>
+ *   Sam Protsenko <semen.protsenko@linaro.org>
+ *
+ * This file contains the utility functions to register the pll clocks.
+ */
+
+#include <asm/io.h>
+#include <div64.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <dm/device.h>
+#include <clk.h>
+#include "clk.h"
+
+#define UBOOT_DM_CLK_SAMSUNG_PLL0822X	"samsung_clk_pll0822x"
+#define UBOOT_DM_CLK_SAMSUNG_PLL0831X	"samsung_clk_pll0831x"
+
+struct samsung_clk_pll {
+	struct clk		clk;
+	void __iomem		*con_reg;
+	enum samsung_pll_type	type;
+};
+
+#define to_clk_pll(_clk) container_of(_clk, struct samsung_clk_pll, clk)
+
+/*
+ * PLL0822x Clock Type
+ */
+
+#define PLL0822X_MDIV_MASK		0x3ff
+#define PLL0822X_PDIV_MASK		0x3f
+#define PLL0822X_SDIV_MASK		0x7
+#define PLL0822X_MDIV_SHIFT		16
+#define PLL0822X_PDIV_SHIFT		8
+#define PLL0822X_SDIV_SHIFT		0
+
+static unsigned long samsung_pll0822x_recalc_rate(struct clk *clk)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(clk);
+	u32 mdiv, pdiv, sdiv, pll_con3;
+	u64 fvco = clk_get_parent_rate(clk);
+
+	pll_con3 = readl_relaxed(pll->con_reg);
+	mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
+	pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
+	sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll0822x_clk_min_ops = {
+	.get_rate = samsung_pll0822x_recalc_rate,
+};
+
+/*
+ * PLL0831x Clock Type
+ */
+
+#define PLL0831X_KDIV_MASK		0xffff
+#define PLL0831X_MDIV_MASK		0x1ff
+#define PLL0831X_PDIV_MASK		0x3f
+#define PLL0831X_SDIV_MASK		0x7
+#define PLL0831X_MDIV_SHIFT		16
+#define PLL0831X_PDIV_SHIFT		8
+#define PLL0831X_SDIV_SHIFT		0
+#define PLL0831X_KDIV_SHIFT		0
+
+static unsigned long samsung_pll0831x_recalc_rate(struct clk *clk)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(clk);
+	u32 mdiv, pdiv, sdiv, pll_con3, pll_con5;
+	s16 kdiv;
+	u64 fvco = clk_get_parent_rate(clk);
+
+	pll_con3 = readl_relaxed(pll->con_reg);
+	pll_con5 = readl_relaxed(pll->con_reg + 8);
+	mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK;
+	pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK;
+	sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK;
+	kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) & PLL0831X_KDIV_MASK);
+
+	fvco *= (mdiv << 16) + kdiv;
+	do_div(fvco, (pdiv << sdiv));
+	fvco >>= 16;
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll0831x_clk_min_ops = {
+	.get_rate = samsung_pll0831x_recalc_rate,
+};
+
+static struct clk *_samsung_clk_register_pll(void __iomem *base,
+					const struct samsung_pll_clock *pll_clk)
+{
+	struct samsung_clk_pll *pll;
+	struct clk *clk;
+	const char *drv_name;
+	int ret;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	pll->con_reg = base + pll_clk->con_offset;
+	pll->type = pll_clk->type;
+	clk = &pll->clk;
+	clk->flags = pll_clk->flags;
+
+	switch (pll_clk->type) {
+	case pll_0822x:
+		drv_name = UBOOT_DM_CLK_SAMSUNG_PLL0822X;
+		break;
+	case pll_0831x:
+		drv_name = UBOOT_DM_CLK_SAMSUNG_PLL0831X;
+		break;
+	default:
+		kfree(pll);
+		return ERR_PTR(-ENODEV);
+	}
+
+	ret = clk_register(clk, drv_name, pll_clk->name, pll_clk->parent_name);
+	if (ret) {
+		kfree(pll);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+
+void samsung_clk_register_pll(void __iomem *base,
+			      const struct samsung_pll_clock *clk_list,
+			      unsigned int nr_clk)
+{
+	unsigned int cnt;
+
+	for (cnt = 0; cnt < nr_clk; cnt++) {
+		struct clk *clk;
+		const struct samsung_pll_clock *pll_clk;
+
+		pll_clk = &clk_list[cnt];
+		clk = _samsung_clk_register_pll(base, pll_clk);
+		clk_dm(pll_clk->id, clk);
+	}
+}
+
+U_BOOT_DRIVER(samsung_pll0822x_clk) = {
+	.name	= UBOOT_DM_CLK_SAMSUNG_PLL0822X,
+	.id	= UCLASS_CLK,
+	.ops	= &samsung_pll0822x_clk_min_ops,
+	.flags	= DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(samsung_pll0831x_clk) = {
+	.name	= UBOOT_DM_CLK_SAMSUNG_PLL0831X,
+	.id	= UCLASS_CLK,
+	.ops	= &samsung_pll0831x_clk_min_ops,
+	.flags	= DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/exynos/clk-pll.h b/drivers/clk/exynos/clk-pll.h
new file mode 100644
index 000000000000..3b477369aeb8
--- /dev/null
+++ b/drivers/clk/exynos/clk-pll.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Samsung Electronics
+ * Copyright (C) 2023 Linaro Ltd.
+ *
+ * Authors:
+ *   Thomas Abraham <thomas.ab@exynos.com>
+ *   Sam Protsenko <semen.protsenko@linaro.org>
+ *
+ * Common Clock Framework support for all PLL's in Samsung platforms.
+ */
+
+#ifndef __EXYNOS_CLK_PLL_H
+#define __EXYNOS_CLK_PLL_H
+
+#include <linux/clk-provider.h>
+
+enum samsung_pll_type {
+	pll_0822x,
+	pll_0831x,
+};
+
+#endif /* __EXYNOS_CLK_PLL_H */
diff --git a/drivers/clk/exynos/clk.c b/drivers/clk/exynos/clk.c
new file mode 100644
index 000000000000..430767f072d8
--- /dev/null
+++ b/drivers/clk/exynos/clk.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023 Linaro Ltd.
+ * Sam Protsenko <semen.protsenko@linaro.org>
+ *
+ * This file includes utility functions to register clocks to common
+ * clock framework for Samsung platforms.
+ */
+
+#include <dm.h>
+#include "clk.h"
+
+void samsung_clk_register_mux(void __iomem *base,
+			      const struct samsung_mux_clock *clk_list,
+			      unsigned int nr_clk)
+{
+	unsigned int cnt;
+
+	for (cnt = 0; cnt < nr_clk; cnt++) {
+		struct clk *clk;
+		const struct samsung_mux_clock *m;
+
+		m = &clk_list[cnt];
+		clk = clk_register_mux(NULL, m->name, m->parent_names,
+			m->num_parents, m->flags, base + m->offset, m->shift,
+			m->width, m->mux_flags);
+		clk_dm(m->id, clk);
+	}
+}
+
+void samsung_clk_register_div(void __iomem *base,
+			      const struct samsung_div_clock *clk_list,
+			      unsigned int nr_clk)
+{
+	unsigned int cnt;
+
+	for (cnt = 0; cnt < nr_clk; cnt++) {
+		struct clk *clk;
+		const struct samsung_div_clock *d;
+
+		d = &clk_list[cnt];
+		clk = clk_register_divider(NULL, d->name, d->parent_name,
+			d->flags, base + d->offset, d->shift,
+			d->width, d->div_flags);
+		clk_dm(d->id, clk);
+	}
+}
+
+void samsung_clk_register_gate(void __iomem *base,
+			       const struct samsung_gate_clock *clk_list,
+			       unsigned int nr_clk)
+{
+	unsigned int cnt;
+
+	for (cnt = 0; cnt < nr_clk; cnt++) {
+		struct clk *clk;
+		const struct samsung_gate_clock *g;
+
+		g = &clk_list[cnt];
+		clk = clk_register_gate(NULL, g->name, g->parent_name,
+			g->flags, base + g->offset, g->bit_idx,
+			g->gate_flags, NULL);
+		clk_dm(g->id, clk);
+	}
+}
+
+typedef void (*samsung_clk_register_fn)(void __iomem *base,
+					const void *clk_list,
+					unsigned int nr_clk);
+
+static const samsung_clk_register_fn samsung_clk_register_fns[] = {
+	[S_CLK_MUX]	= (samsung_clk_register_fn)samsung_clk_register_mux,
+	[S_CLK_DIV]	= (samsung_clk_register_fn)samsung_clk_register_div,
+	[S_CLK_GATE]	= (samsung_clk_register_fn)samsung_clk_register_gate,
+	[S_CLK_PLL]	= (samsung_clk_register_fn)samsung_clk_register_pll,
+};
+
+/**
+ * samsung_cmu_register_clocks() - Register provided clock groups
+ * @base: Base address of CMU registers
+ * @clk_groups: list of clock groups
+ * @nr_groups: count of clock groups in @clk_groups
+ *
+ * Having the array of clock groups @clk_groups makes it possible to keep a
+ * correct clocks registration order.
+ */
+void samsung_cmu_register_clocks(void __iomem *base,
+				 const struct samsung_clk_group *clk_groups,
+				 unsigned int nr_groups)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr_groups; i++) {
+		const struct samsung_clk_group *g = &clk_groups[i];
+
+		samsung_clk_register_fns[g->type](base, g->clk_list, g->nr_clk);
+	}
+}
+
+/**
+ * samsung_cmu_register_one - Register all CMU clocks
+ * @dev: CMU device
+ * @clk_groups: list of CMU clock groups
+ * @nr_groups: count of CMU clock groups in @clk_groups
+ *
+ * Return: 0 on success or negative value on error.
+ */
+int samsung_cmu_register_one(struct udevice *dev,
+			     const struct samsung_clk_group *clk_groups,
+			     unsigned int nr_groups)
+{
+	void __iomem *base;
+
+	base = dev_read_addr_ptr(dev);
+	if (!base)
+		return -EINVAL;
+
+	samsung_cmu_register_clocks(base, clk_groups, nr_groups);
+
+	return 0;
+}
diff --git a/drivers/clk/exynos/clk.h b/drivers/clk/exynos/clk.h
new file mode 100644
index 000000000000..91a51b877a63
--- /dev/null
+++ b/drivers/clk/exynos/clk.h
@@ -0,0 +1,228 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023 Linaro Ltd.
+ * Sam Protsenko <semen.protsenko@linaro.org>
+ *
+ * Common Clock Framework support for all Samsung platforms.
+ */
+
+#ifndef __EXYNOS_CLK_H
+#define __EXYNOS_CLK_H
+
+#include <errno.h>
+#include <linux/clk-provider.h>
+#include "clk-pll.h"
+
+/**
+ * struct samsung_mux_clock - information about mux clock
+ * @id: platform specific id of the clock
+ * @name: name of this mux clock
+ * @parent_names: array of pointer to parent clock names
+ * @num_parents: number of parents listed in @parent_names
+ * @flags: optional flags for basic clock
+ * @offset: offset of the register for configuring the mux
+ * @shift: starting bit location of the mux control bit-field in @reg
+ * @width: width of the mux control bit-field in @reg
+ * @mux_flags: flags for mux-type clock
+ */
+struct samsung_mux_clock {
+	unsigned int		id;
+	const char		*name;
+	const char		* const *parent_names;
+	u8			num_parents;
+	unsigned long		flags;
+	unsigned long		offset;
+	u8			shift;
+	u8			width;
+	u8			mux_flags;
+};
+
+#define PNAME(x) static const char * const x[]
+
+#define __MUX(_id, cname, pnames, o, s, w, f, mf)			\
+	{								\
+		.id		= _id,					\
+		.name		= cname,				\
+		.parent_names	= pnames,				\
+		.num_parents	= ARRAY_SIZE(pnames),			\
+		.flags		= (f) | CLK_SET_RATE_NO_REPARENT,	\
+		.offset		= o,					\
+		.shift		= s,					\
+		.width		= w,					\
+		.mux_flags	= mf,					\
+	}
+
+#define MUX(_id, cname, pnames, o, s, w)				\
+	__MUX(_id, cname, pnames, o, s, w, 0, 0)
+
+#define MUX_F(_id, cname, pnames, o, s, w, f, mf)			\
+	__MUX(_id, cname, pnames, o, s, w, f, mf)
+
+/**
+ * struct samsung_div_clock - information about div clock
+ * @id: platform specific id of the clock
+ * @name: name of this div clock
+ * @parent_name: name of the parent clock
+ * @flags: optional flags for basic clock
+ * @offset: offset of the register for configuring the div
+ * @shift: starting bit location of the div control bit-field in @reg
+ * @width: width of the bitfield
+ * @div_flags: flags for div-type clock
+ */
+struct samsung_div_clock {
+	unsigned int		id;
+	const char		*name;
+	const char		*parent_name;
+	unsigned long		flags;
+	unsigned long		offset;
+	u8			shift;
+	u8			width;
+	u8			div_flags;
+};
+
+#define __DIV(_id, cname, pname, o, s, w, f, df)	\
+	{						\
+		.id		= _id,			\
+		.name		= cname,		\
+		.parent_name	= pname,		\
+		.flags		= f,			\
+		.offset		= o,			\
+		.shift		= s,			\
+		.width		= w,			\
+		.div_flags	= df,			\
+	}
+
+#define DIV(_id, cname, pname, o, s, w)			\
+	__DIV(_id, cname, pname, o, s, w, 0, 0)
+
+#define DIV_F(_id, cname, pname, o, s, w, f, df)	\
+	__DIV(_id, cname, pname, o, s, w, f, df)
+
+/**
+ * struct samsung_gate_clock - information about gate clock
+ * @id: platform specific id of the clock
+ * @name: name of this gate clock
+ * @parent_name: name of the parent clock
+ * @flags: optional flags for basic clock
+ * @offset: offset of the register for configuring the gate
+ * @bit_idx: bit index of the gate control bit-field in @reg
+ * @gate_flags: flags for gate-type clock
+ */
+struct samsung_gate_clock {
+	unsigned int		id;
+	const char		*name;
+	const char		*parent_name;
+	unsigned long		flags;
+	unsigned long		offset;
+	u8			bit_idx;
+	u8			gate_flags;
+};
+
+#define __GATE(_id, cname, pname, o, b, f, gf)			\
+	{							\
+		.id		= _id,				\
+		.name		= cname,			\
+		.parent_name	= pname,			\
+		.flags		= f,				\
+		.offset		= o,				\
+		.bit_idx	= b,				\
+		.gate_flags	= gf,				\
+	}
+
+#define GATE(_id, cname, pname, o, b, f, gf)			\
+	__GATE(_id, cname, pname, o, b, f, gf)
+
+/**
+ * struct samsung_pll_clock - information about pll clock
+ * @id: platform specific id of the clock
+ * @name: name of this pll clock
+ * @parent_name: name of the parent clock
+ * @flags: optional flags for basic clock
+ * @con_offset: offset of the register for configuring the PLL
+ * @type: type of PLL to be registered
+ */
+struct samsung_pll_clock {
+	unsigned int		id;
+	const char		*name;
+	const char		*parent_name;
+	unsigned long		flags;
+	int			con_offset;
+	enum samsung_pll_type	type;
+};
+
+#define PLL(_typ, _id, _name, _pname, _con)		\
+	{						\
+		.id		= _id,			\
+		.name		= _name,		\
+		.parent_name	= _pname,		\
+		.flags		= CLK_GET_RATE_NOCACHE,	\
+		.con_offset	= _con,			\
+		.type		= _typ,			\
+	}
+
+enum samsung_clock_type {
+	S_CLK_MUX,
+	S_CLK_DIV,
+	S_CLK_GATE,
+	S_CLK_PLL,
+};
+
+/**
+ * struct samsung_clock_group - contains a list of clocks of one type
+ * @type: type of clocks this structure contains
+ * @clk_list: list of clocks
+ * @nr_clk: count of clocks in @clk_list
+ */
+struct samsung_clk_group {
+	enum samsung_clock_type type;
+	const void *clk_list;
+	unsigned int nr_clk;
+};
+
+void samsung_clk_register_mux(void __iomem *base,
+			      const struct samsung_mux_clock *clk_list,
+			      unsigned int nr_clk);
+void samsung_clk_register_div(void __iomem *base,
+			      const struct samsung_div_clock *clk_list,
+			      unsigned int nr_clk);
+void samsung_clk_register_gate(void __iomem *base,
+			       const struct samsung_gate_clock *clk_list,
+			       unsigned int nr_clk);
+void samsung_clk_register_pll(void __iomem *base,
+			      const struct samsung_pll_clock *clk_list,
+			      unsigned int nr_clk);
+
+void samsung_cmu_register_clocks(void __iomem *base,
+				 const struct samsung_clk_group *clk_groups,
+				 unsigned int nr_groups);
+int samsung_cmu_register_one(struct udevice *dev,
+			     const struct samsung_clk_group *clk_groups,
+			     unsigned int nr_groups);
+
+/**
+ * samsung_register_cmu - Register CMU clocks ensuring parent CMU is present
+ * @dev: CMU device
+ * @clk_groups: list of CMU clock groups
+ * @parent_drv: name of parent CMU driver
+ *
+ * Register provided CMU clocks, but make sure CMU_TOP driver is instantiated
+ * first.
+ *
+ * Return: 0 on success or negative value on error.
+ */
+#define samsung_register_cmu(dev, clk_groups, parent_drv)		\
+({									\
+	struct udevice *__parent;					\
+	int __ret;							\
+									\
+	__ret = uclass_get_device_by_driver(UCLASS_CLK,			\
+		DM_DRIVER_GET(parent_drv), &__parent);			\
+	if (__ret || !__parent)						\
+		__ret = -ENOENT;					\
+	else								\
+		__ret = samsung_cmu_register_one(dev, clk_groups,	\
+			ARRAY_SIZE(clk_groups));			\
+	__ret;								\
+})
+
+#endif /* __EXYNOS_CLK_H */
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 08/13] clk: exynos: Add Exynos850 clock driver
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
                   ` (6 preceding siblings ...)
  2023-12-13  3:16 ` [PATCH 07/13] clk: exynos: Add Samsung clock framework Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-19 11:33   ` Chanho Park
  2023-12-13  3:16 ` [PATCH 09/13] pinctrl: exynos: Add pinctrl support for Exynos850 Sam Protsenko
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

Heavily influenced by its Linux kernel counterpart. It's implemented on
top of recently added Samsung CCF clock framework API. For now only UART
leaf clocks are implemented, along with all preceding clocks in CMU_TOP
and CMU_PERI. The UART baud clock is required in the serial driver, to
get its rate for the consequent baud rate calculation.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/clk/exynos/Kconfig         |   7 ++
 drivers/clk/exynos/Makefile        |   1 +
 drivers/clk/exynos/clk-exynos850.c | 189 +++++++++++++++++++++++++++++
 3 files changed, 197 insertions(+)
 create mode 100644 drivers/clk/exynos/clk-exynos850.c

diff --git a/drivers/clk/exynos/Kconfig b/drivers/clk/exynos/Kconfig
index eb0efa97d15c..85ce9d6e2418 100644
--- a/drivers/clk/exynos/Kconfig
+++ b/drivers/clk/exynos/Kconfig
@@ -15,4 +15,11 @@ config CLK_EXYNOS7420
 	  This enables common clock driver support for platforms based
 	  on Samsung Exynos7420 SoC.
 
+config CLK_EXYNOS850
+	bool "Clock driver for Samsung's Exynos850 SoC"
+	select CLK_CCF
+	help
+	  This enables common clock driver support for platforms based
+	  on Samsung Exynos850 SoC.
+
 endmenu
diff --git a/drivers/clk/exynos/Makefile b/drivers/clk/exynos/Makefile
index 04c5b9a39e16..734100e2bff3 100644
--- a/drivers/clk/exynos/Makefile
+++ b/drivers/clk/exynos/Makefile
@@ -9,3 +9,4 @@
 
 obj-$(CONFIG_$(SPL_TPL_)CLK_CCF)	+= clk.o clk-pll.o
 obj-$(CONFIG_CLK_EXYNOS7420)		+= clk-exynos7420.o
+obj-$(CONFIG_CLK_EXYNOS850)		+= clk-exynos850.o
diff --git a/drivers/clk/exynos/clk-exynos850.c b/drivers/clk/exynos/clk-exynos850.c
new file mode 100644
index 000000000000..cf94a3e1b646
--- /dev/null
+++ b/drivers/clk/exynos/clk-exynos850.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Samsung Exynos850 clock driver.
+ * Copyright (c) 2023 Linaro Ltd.
+ * Author: Sam Protsenko <semen.protsenko@linaro.org>
+ */
+
+#include <dm.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/exynos850.h>
+#include "clk.h"
+
+/* ---- CMU_TOP ------------------------------------------------------------- */
+
+/* Register Offset definitions for CMU_TOP (0x120e0000) */
+#define PLL_CON0_PLL_MMC			0x0100
+#define PLL_CON3_PLL_MMC			0x010c
+#define PLL_CON0_PLL_SHARED0			0x0140
+#define PLL_CON3_PLL_SHARED0			0x014c
+#define PLL_CON0_PLL_SHARED1			0x0180
+#define PLL_CON3_PLL_SHARED1			0x018c
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS		0x1070
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_IP		0x1074
+#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART	0x1078
+#define CLK_CON_DIV_CLKCMU_PERI_BUS		0x187c
+#define CLK_CON_DIV_CLKCMU_PERI_IP		0x1880
+#define CLK_CON_DIV_CLKCMU_PERI_UART		0x1884
+#define CLK_CON_DIV_PLL_SHARED0_DIV2		0x188c
+#define CLK_CON_DIV_PLL_SHARED0_DIV3		0x1890
+#define CLK_CON_DIV_PLL_SHARED0_DIV4		0x1894
+#define CLK_CON_DIV_PLL_SHARED1_DIV2		0x1898
+#define CLK_CON_DIV_PLL_SHARED1_DIV3		0x189c
+#define CLK_CON_DIV_PLL_SHARED1_DIV4		0x18a0
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS	0x2080
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_IP		0x2084
+#define CLK_CON_GAT_GATE_CLKCMU_PERI_UART	0x2088
+
+static const struct samsung_pll_clock top_pure_pll_clks[] = {
+	PLL(pll_0822x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "clock-oscclk",
+	    PLL_CON3_PLL_SHARED0),
+	PLL(pll_0822x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "clock-oscclk",
+	    PLL_CON3_PLL_SHARED1),
+	PLL(pll_0831x, CLK_FOUT_MMC_PLL, "fout_mmc_pll", "clock-oscclk",
+	    PLL_CON3_PLL_MMC),
+};
+
+/* List of parent clocks for Muxes in CMU_TOP */
+PNAME(mout_shared0_pll_p)	= { "clock-oscclk", "fout_shared0_pll" };
+PNAME(mout_shared1_pll_p)	= { "clock-oscclk", "fout_shared1_pll" };
+PNAME(mout_mmc_pll_p)		= { "clock-oscclk", "fout_mmc_pll" };
+/* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */
+PNAME(mout_peri_bus_p)		= { "dout_shared0_div4", "dout_shared1_div4" };
+PNAME(mout_peri_uart_p)		= { "clock-oscclk", "dout_shared0_div4",
+				    "dout_shared1_div4", "clock-oscclk" };
+PNAME(mout_peri_ip_p)		= { "clock-oscclk", "dout_shared0_div4",
+				    "dout_shared1_div4", "clock-oscclk" };
+
+static const struct samsung_mux_clock top_pure_mux_clks[] = {
+	MUX(CLK_MOUT_SHARED0_PLL, "mout_shared0_pll", mout_shared0_pll_p,
+	    PLL_CON0_PLL_SHARED0, 4, 1),
+	MUX(CLK_MOUT_SHARED1_PLL, "mout_shared1_pll", mout_shared1_pll_p,
+	    PLL_CON0_PLL_SHARED1, 4, 1),
+	MUX(CLK_MOUT_MMC_PLL, "mout_mmc_pll", mout_mmc_pll_p,
+	    PLL_CON0_PLL_MMC, 4, 1),
+};
+
+static const struct samsung_mux_clock top_peri_mux_clks[] = {
+	MUX(CLK_MOUT_PERI_BUS, "mout_peri_bus", mout_peri_bus_p,
+	    CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 0, 1),
+	MUX(CLK_MOUT_PERI_UART, "mout_peri_uart", mout_peri_uart_p,
+	    CLK_CON_MUX_MUX_CLKCMU_PERI_UART, 0, 2),
+	MUX(CLK_MOUT_PERI_IP, "mout_peri_ip", mout_peri_ip_p,
+	    CLK_CON_MUX_MUX_CLKCMU_PERI_IP, 0, 2),
+};
+
+static const struct samsung_div_clock top_pure_div_clks[] = {
+	DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "mout_shared0_pll",
+	    CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
+	DIV(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "mout_shared0_pll",
+	    CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
+	DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "mout_shared1_pll",
+	    CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
+	DIV(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "mout_shared1_pll",
+	    CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
+	DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "dout_shared0_div2",
+	    CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
+	DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2",
+	    CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
+};
+
+static const struct samsung_div_clock top_peri_div_clks[] = {
+	DIV(CLK_DOUT_PERI_BUS, "dout_peri_bus", "gout_peri_bus",
+	    CLK_CON_DIV_CLKCMU_PERI_BUS, 0, 4),
+	DIV(CLK_DOUT_PERI_UART, "dout_peri_uart", "gout_peri_uart",
+	    CLK_CON_DIV_CLKCMU_PERI_UART, 0, 4),
+	DIV(CLK_DOUT_PERI_IP, "dout_peri_ip", "gout_peri_ip",
+	    CLK_CON_DIV_CLKCMU_PERI_IP, 0, 4),
+};
+
+static const struct samsung_gate_clock top_peri_gate_clks[] = {
+	GATE(CLK_GOUT_PERI_BUS, "gout_peri_bus", "mout_peri_bus",
+	     CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 21, 0, 0),
+	GATE(CLK_GOUT_PERI_UART, "gout_peri_uart", "mout_peri_uart",
+	     CLK_CON_GAT_GATE_CLKCMU_PERI_UART, 21, 0, 0),
+	GATE(CLK_GOUT_PERI_IP, "gout_peri_ip", "mout_peri_ip",
+	     CLK_CON_GAT_GATE_CLKCMU_PERI_IP, 21, 0, 0),
+};
+
+static const struct samsung_clk_group top_cmu_clks[] = {
+	/* CMU_TOP_PURECLKCOMP */
+	{ S_CLK_PLL, top_pure_pll_clks, ARRAY_SIZE(top_pure_pll_clks) },
+	{ S_CLK_MUX, top_pure_mux_clks, ARRAY_SIZE(top_pure_mux_clks) },
+	{ S_CLK_DIV, top_pure_div_clks, ARRAY_SIZE(top_pure_div_clks) },
+
+	/* CMU_TOP clocks for CMU_PERI */
+	{ S_CLK_MUX, top_peri_mux_clks, ARRAY_SIZE(top_peri_mux_clks) },
+	{ S_CLK_GATE, top_peri_gate_clks, ARRAY_SIZE(top_peri_gate_clks) },
+	{ S_CLK_DIV, top_peri_div_clks, ARRAY_SIZE(top_peri_div_clks) },
+};
+
+static int exynos850_cmu_top_probe(struct udevice *dev)
+{
+	return samsung_cmu_register_one(dev, top_cmu_clks,
+					ARRAY_SIZE(top_cmu_clks));
+}
+
+static const struct udevice_id exynos850_cmu_top_ids[] = {
+	{ .compatible = "samsung,exynos850-cmu-top" },
+	{ }
+};
+
+U_BOOT_DRIVER(exynos850_cmu_top) = {
+	.name		= "exynos850-cmu-top",
+	.id		= UCLASS_CLK,
+	.of_match	= exynos850_cmu_top_ids,
+	.ops		= &ccf_clk_ops,
+	.probe		= exynos850_cmu_top_probe,
+	.flags		= DM_FLAG_PRE_RELOC,
+};
+
+/* ---- CMU_PERI ------------------------------------------------------------ */
+
+/* Register Offset definitions for CMU_PERI (0x10030000) */
+#define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER	0x0600
+#define PLL_CON0_MUX_CLKCMU_PERI_UART_USER	0x0630
+#define CLK_CON_GAT_GOUT_PERI_UART_IPCLK	0x20a8
+#define CLK_CON_GAT_GOUT_PERI_UART_PCLK		0x20ac
+
+/* List of parent clocks for Muxes in CMU_PERI */
+PNAME(mout_peri_bus_user_p)	= { "clock-oscclk", "dout_peri_bus" };
+PNAME(mout_peri_uart_user_p)	= { "clock-oscclk", "dout_peri_uart" };
+
+static const struct samsung_mux_clock peri_mux_clks[] = {
+	MUX(CLK_MOUT_PERI_BUS_USER, "mout_peri_bus_user", mout_peri_bus_user_p,
+	    PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 4, 1),
+	MUX(CLK_MOUT_PERI_UART_USER, "mout_peri_uart_user",
+	    mout_peri_uart_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 4, 1),
+};
+
+static const struct samsung_gate_clock peri_gate_clks[] = {
+	GATE(CLK_GOUT_UART_IPCLK, "gout_uart_ipclk", "mout_peri_uart_user",
+	     CLK_CON_GAT_GOUT_PERI_UART_IPCLK, 21, 0, 0),
+	GATE(CLK_GOUT_UART_PCLK, "gout_uart_pclk", "mout_peri_bus_user",
+	     CLK_CON_GAT_GOUT_PERI_UART_PCLK, 21, 0, 0),
+};
+
+static const struct samsung_clk_group peri_cmu_clks[] = {
+	{ S_CLK_MUX, peri_mux_clks, ARRAY_SIZE(peri_mux_clks) },
+	{ S_CLK_GATE, peri_gate_clks, ARRAY_SIZE(peri_gate_clks) },
+};
+
+static int exynos850_cmu_peri_probe(struct udevice *dev)
+{
+	return samsung_register_cmu(dev, peri_cmu_clks, exynos850_cmu_top);
+}
+
+static const struct udevice_id exynos850_cmu_peri_ids[] = {
+	{ .compatible = "samsung,exynos850-cmu-peri" },
+	{ }
+};
+
+U_BOOT_DRIVER(exynos850_cmu_peri) = {
+	.name		= "exynos850-cmu-peri",
+	.id		= UCLASS_CLK,
+	.of_match	= exynos850_cmu_peri_ids,
+	.ops		= &ccf_clk_ops,
+	.probe		= exynos850_cmu_peri_probe,
+	.flags		= DM_FLAG_PRE_RELOC,
+};
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 09/13] pinctrl: exynos: Add pinctrl support for Exynos850
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
                   ` (7 preceding siblings ...)
  2023-12-13  3:16 ` [PATCH 08/13] clk: exynos: Add Exynos850 clock driver Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-19 11:32   ` Chanho Park
  2023-12-13  3:16 ` [PATCH 10/13] serial: s5p: Add Exynos850 compatible Sam Protsenko
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

Add pinctrl support for Exynos850 SoC. It was mostly extracted from
corresponding Linux kernel code [1]. Power down modes and external
interrupt data were removed while converting the code for U-Boot, but
everything else was kept almost unchanged.

[1] drivers/pinctrl/samsung/pinctrl-exynos-arm64.c

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/pinctrl/exynos/Kconfig             |   8 ++
 drivers/pinctrl/exynos/Makefile            |   1 +
 drivers/pinctrl/exynos/pinctrl-exynos850.c | 125 +++++++++++++++++++++
 3 files changed, 134 insertions(+)
 create mode 100644 drivers/pinctrl/exynos/pinctrl-exynos850.c

diff --git a/drivers/pinctrl/exynos/Kconfig b/drivers/pinctrl/exynos/Kconfig
index a60f49869b45..1b7fb62bc4ba 100644
--- a/drivers/pinctrl/exynos/Kconfig
+++ b/drivers/pinctrl/exynos/Kconfig
@@ -16,3 +16,11 @@ config PINCTRL_EXYNOS78x0
 	help
 	  Support pin multiplexing and pin configuration control on
 	  Samsung's Exynos78x0 SoC.
+
+config PINCTRL_EXYNOS850
+	bool "Samsung Exynos850 pinctrl driver"
+	depends on ARCH_EXYNOS && PINCTRL_FULL
+	select PINCTRL_EXYNOS
+	help
+	  Support pin multiplexing and pin configuration control on
+	  Samsung's Exynos850 SoC.
diff --git a/drivers/pinctrl/exynos/Makefile b/drivers/pinctrl/exynos/Makefile
index 07db970ca942..3abe1226eb74 100644
--- a/drivers/pinctrl/exynos/Makefile
+++ b/drivers/pinctrl/exynos/Makefile
@@ -6,3 +6,4 @@
 obj-$(CONFIG_PINCTRL_EXYNOS)		+= pinctrl-exynos.o
 obj-$(CONFIG_PINCTRL_EXYNOS7420)	+= pinctrl-exynos7420.o
 obj-$(CONFIG_PINCTRL_EXYNOS78x0)	+= pinctrl-exynos78x0.o
+obj-$(CONFIG_PINCTRL_EXYNOS850)		+= pinctrl-exynos850.o
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos850.c b/drivers/pinctrl/exynos/pinctrl-exynos850.c
new file mode 100644
index 000000000000..2445dd752ea8
--- /dev/null
+++ b/drivers/pinctrl/exynos/pinctrl-exynos850.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Linaro Ltd.
+ * Author: Sam Protsenko <semen.protsenko@linaro.org>
+ *
+ * Samsung Exynos USI driver (Universal Serial Interface).
+ */
+
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include "pinctrl-exynos.h"
+
+#define EXYNOS850_PIN_BANK(pins, reg, id)		\
+	{						\
+		.type		= &exynos850_bank_type,	\
+		.offset		= reg,			\
+		.nr_pins	= pins,			\
+		.name		= id			\
+	}
+
+/* CON, DAT, PUD, DRV */
+static const struct samsung_pin_bank_type exynos850_bank_type = {
+	.fld_width = { 4, 1, 4, 4, },
+	.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
+};
+
+static const struct pinctrl_ops exynos850_pinctrl_ops = {
+	.set_state = exynos_pinctrl_set_state
+};
+
+/* pin banks of exynos850 pin-controller 0 (ALIVE) */
+static const struct samsung_pin_bank_data exynos850_pin_banks0[] = {
+	EXYNOS850_PIN_BANK(8, 0x000, "gpa0"),
+	EXYNOS850_PIN_BANK(8, 0x020, "gpa1"),
+	EXYNOS850_PIN_BANK(8, 0x040, "gpa2"),
+	EXYNOS850_PIN_BANK(8, 0x060, "gpa3"),
+	EXYNOS850_PIN_BANK(4, 0x080, "gpa4"),
+	EXYNOS850_PIN_BANK(3, 0x0a0, "gpq0"),
+};
+
+/* pin banks of exynos850 pin-controller 1 (CMGP) */
+static const struct samsung_pin_bank_data exynos850_pin_banks1[] = {
+	EXYNOS850_PIN_BANK(1, 0x000, "gpm0"),
+	EXYNOS850_PIN_BANK(1, 0x020, "gpm1"),
+	EXYNOS850_PIN_BANK(1, 0x040, "gpm2"),
+	EXYNOS850_PIN_BANK(1, 0x060, "gpm3"),
+	EXYNOS850_PIN_BANK(1, 0x080, "gpm4"),
+	EXYNOS850_PIN_BANK(1, 0x0a0, "gpm5"),
+	EXYNOS850_PIN_BANK(1, 0x0c0, "gpm6"),
+	EXYNOS850_PIN_BANK(1, 0x0e0, "gpm7"),
+};
+
+/* pin banks of exynos850 pin-controller 2 (AUD) */
+static const struct samsung_pin_bank_data exynos850_pin_banks2[] = {
+	EXYNOS850_PIN_BANK(5, 0x000, "gpb0"),
+	EXYNOS850_PIN_BANK(5, 0x020, "gpb1"),
+};
+
+/* pin banks of exynos850 pin-controller 3 (HSI) */
+static const struct samsung_pin_bank_data exynos850_pin_banks3[] = {
+	EXYNOS850_PIN_BANK(6, 0x000, "gpf2"),
+};
+
+/* pin banks of exynos850 pin-controller 4 (CORE) */
+static const struct samsung_pin_bank_data exynos850_pin_banks4[] = {
+	EXYNOS850_PIN_BANK(4, 0x000, "gpf0"),
+	EXYNOS850_PIN_BANK(8, 0x020, "gpf1"),
+};
+
+/* pin banks of exynos850 pin-controller 5 (PERI) */
+static const struct samsung_pin_bank_data exynos850_pin_banks5[] = {
+	EXYNOS850_PIN_BANK(2, 0x000, "gpg0"),
+	EXYNOS850_PIN_BANK(6, 0x020, "gpp0"),
+	EXYNOS850_PIN_BANK(4, 0x040, "gpp1"),
+	EXYNOS850_PIN_BANK(4, 0x060, "gpp2"),
+	EXYNOS850_PIN_BANK(8, 0x080, "gpg1"),
+	EXYNOS850_PIN_BANK(8, 0x0a0, "gpg2"),
+	EXYNOS850_PIN_BANK(1, 0x0c0, "gpg3"),
+	EXYNOS850_PIN_BANK(3, 0x0e0, "gpc0"),
+	EXYNOS850_PIN_BANK(6, 0x100, "gpc1"),
+};
+
+static const struct samsung_pin_ctrl exynos850_pin_ctrl[] = {
+	{
+		/* pin-controller instance 0 ALIVE data */
+		.pin_banks	= exynos850_pin_banks0,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks0),
+	}, {
+		/* pin-controller instance 1 CMGP data */
+		.pin_banks	= exynos850_pin_banks1,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks1),
+	}, {
+		/* pin-controller instance 2 AUD data */
+		.pin_banks	= exynos850_pin_banks2,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks2),
+	}, {
+		/* pin-controller instance 3 HSI data */
+		.pin_banks	= exynos850_pin_banks3,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks3),
+	}, {
+		/* pin-controller instance 4 CORE data */
+		.pin_banks	= exynos850_pin_banks4,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks4),
+	}, {
+		/* pin-controller instance 5 PERI data */
+		.pin_banks	= exynos850_pin_banks5,
+		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks5),
+	},
+	{/* list terminator */}
+};
+
+static const struct udevice_id exynos850_pinctrl_ids[] = {
+	{ .compatible = "samsung,exynos850-pinctrl",
+		.data = (ulong)exynos850_pin_ctrl },
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_exynos850) = {
+	.name		= "pinctrl_exynos850",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= exynos850_pinctrl_ids,
+	.priv_auto	= sizeof(struct exynos_pinctrl_priv),
+	.ops		= &exynos850_pinctrl_ops,
+	.probe		= exynos_pinctrl_probe,
+};
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 10/13] serial: s5p: Add Exynos850 compatible
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
                   ` (8 preceding siblings ...)
  2023-12-13  3:16 ` [PATCH 09/13] pinctrl: exynos: Add pinctrl support for Exynos850 Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-13  3:16 ` [PATCH 11/13] arm: exynos: Add Exynos850 SoC support Sam Protsenko
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

Enable serial support for Exynos850 SoC by adding the corresponding
compatible string. No additional changes needed, the driver works as is
on Exynos850. Related USI and PMU configuration is enabled in separate
drivers. The only other dependencies are clock and pinctrl drivers,
which are already enabled too.

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 drivers/serial/serial_s5p.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index 7d04dcff54fc..801b7645afa4 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -257,6 +257,7 @@ static const struct dm_serial_ops s5p_serial_ops = {
 
 static const struct udevice_id s5p_serial_ids[] = {
 	{ .compatible = "samsung,exynos4210-uart",	.data = PORT_S5P },
+	{ .compatible = "samsung,exynos850-uart",	.data = PORT_S5P },
 	{ .compatible = "apple,s5l-uart",		.data = PORT_S5L },
 	{ }
 };
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 11/13] arm: exynos: Add Exynos850 SoC support
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
                   ` (9 preceding siblings ...)
  2023-12-13  3:16 ` [PATCH 10/13] serial: s5p: Add Exynos850 compatible Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-13  3:16 ` [PATCH 12/13] board: samsung: Add support for E850-96 board Sam Protsenko
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

Samsung Exynos850 is ARMv8-based mobile-oriented SoC. It features
Cortex-A55 CPU (8 cores) and it's built using 8nm process.

Add Exynos850 support by enabling next features:

  * Import Exynos850 SoC dtsi files from Linux kernel
  * Add Exynos850 MMU memory map
  * Introduce ARCH_EXYNOS9 platform config option

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 arch/arm/dts/exynos-pinctrl.h       |  79 +++
 arch/arm/dts/exynos850-pinctrl.dtsi | 663 +++++++++++++++++++++++
 arch/arm/dts/exynos850.dtsi         | 809 ++++++++++++++++++++++++++++
 arch/arm/mach-exynos/Kconfig        |   9 +
 arch/arm/mach-exynos/mmu-arm64.c    |  34 ++
 5 files changed, 1594 insertions(+)
 create mode 100644 arch/arm/dts/exynos-pinctrl.h
 create mode 100644 arch/arm/dts/exynos850-pinctrl.dtsi
 create mode 100644 arch/arm/dts/exynos850.dtsi

diff --git a/arch/arm/dts/exynos-pinctrl.h b/arch/arm/dts/exynos-pinctrl.h
new file mode 100644
index 000000000000..7dd94a9b3652
--- /dev/null
+++ b/arch/arm/dts/exynos-pinctrl.h
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Samsung Exynos DTS pinctrl constants
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2022 Linaro Ltd
+ * Author: Krzysztof Kozlowski <krzk@kernel.org>
+ */
+
+#ifndef __DTS_ARM64_SAMSUNG_EXYNOS_PINCTRL_H__
+#define __DTS_ARM64_SAMSUNG_EXYNOS_PINCTRL_H__
+
+#define EXYNOS_PIN_PULL_NONE		0
+#define EXYNOS_PIN_PULL_DOWN		1
+#define EXYNOS_PIN_PULL_UP		3
+
+/* Pin function in power down mode */
+#define EXYNOS_PIN_PDN_OUT0		0
+#define EXYNOS_PIN_PDN_OUT1		1
+#define EXYNOS_PIN_PDN_INPUT		2
+#define EXYNOS_PIN_PDN_PREV		3
+
+/*
+ * Drive strengths for Exynos5410, Exynos542x, Exynos5800, Exynos7885, Exynos850
+ * (except GPIO_HSI block), ExynosAutov9 (FSI0, PERIC1)
+ */
+#define EXYNOS5420_PIN_DRV_LV1		0
+#define EXYNOS5420_PIN_DRV_LV2		1
+#define EXYNOS5420_PIN_DRV_LV3		2
+#define EXYNOS5420_PIN_DRV_LV4		3
+
+/* Drive strengths for Exynos5433 */
+#define EXYNOS5433_PIN_DRV_FAST_SR1	0
+#define EXYNOS5433_PIN_DRV_FAST_SR2	1
+#define EXYNOS5433_PIN_DRV_FAST_SR3	2
+#define EXYNOS5433_PIN_DRV_FAST_SR4	3
+#define EXYNOS5433_PIN_DRV_FAST_SR5	4
+#define EXYNOS5433_PIN_DRV_FAST_SR6	5
+#define EXYNOS5433_PIN_DRV_SLOW_SR1	8
+#define EXYNOS5433_PIN_DRV_SLOW_SR2	9
+#define EXYNOS5433_PIN_DRV_SLOW_SR3	0xa
+#define EXYNOS5433_PIN_DRV_SLOW_SR4	0xb
+#define EXYNOS5433_PIN_DRV_SLOW_SR5	0xc
+#define EXYNOS5433_PIN_DRV_SLOW_SR6	0xf
+
+/* Drive strengths for Exynos7 (except FSYS1) */
+#define EXYNOS7_PIN_DRV_LV1		0
+#define EXYNOS7_PIN_DRV_LV2		2
+#define EXYNOS7_PIN_DRV_LV3		1
+#define EXYNOS7_PIN_DRV_LV4		3
+
+/* Drive strengths for Exynos7 FSYS1 block */
+#define EXYNOS7_FSYS1_PIN_DRV_LV1	0
+#define EXYNOS7_FSYS1_PIN_DRV_LV2	4
+#define EXYNOS7_FSYS1_PIN_DRV_LV3	2
+#define EXYNOS7_FSYS1_PIN_DRV_LV4	6
+#define EXYNOS7_FSYS1_PIN_DRV_LV5	1
+#define EXYNOS7_FSYS1_PIN_DRV_LV6	5
+
+/* Drive strengths for Exynos850 GPIO_HSI block */
+#define EXYNOS850_HSI_PIN_DRV_LV1	0	/* 1x   */
+#define EXYNOS850_HSI_PIN_DRV_LV1_5	1	/* 1.5x */
+#define EXYNOS850_HSI_PIN_DRV_LV2	2	/* 2x   */
+#define EXYNOS850_HSI_PIN_DRV_LV2_5	3	/* 2.5x */
+#define EXYNOS850_HSI_PIN_DRV_LV3	4	/* 3x   */
+#define EXYNOS850_HSI_PIN_DRV_LV4	5	/* 4x   */
+
+#define EXYNOS_PIN_FUNC_INPUT		0
+#define EXYNOS_PIN_FUNC_OUTPUT		1
+#define EXYNOS_PIN_FUNC_2		2
+#define EXYNOS_PIN_FUNC_3		3
+#define EXYNOS_PIN_FUNC_4		4
+#define EXYNOS_PIN_FUNC_5		5
+#define EXYNOS_PIN_FUNC_6		6
+#define EXYNOS_PIN_FUNC_EINT		0xf
+#define EXYNOS_PIN_FUNC_F		EXYNOS_PIN_FUNC_EINT
+
+#endif /* __DTS_ARM64_SAMSUNG_EXYNOS_PINCTRL_H__ */
diff --git a/arch/arm/dts/exynos850-pinctrl.dtsi b/arch/arm/dts/exynos850-pinctrl.dtsi
new file mode 100644
index 000000000000..424bc80bde68
--- /dev/null
+++ b/arch/arm/dts/exynos850-pinctrl.dtsi
@@ -0,0 +1,663 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos850 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (C) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 Linaro Ltd.
+ *
+ * Samsung's Exynos850 SoC pin-mux and pin-config options are listed as device
+ * tree nodes in this file.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "exynos-pinctrl.h"
+
+&pinctrl_alive {
+	gpa0: gpa0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa1: gpa1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa2: gpa2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa3: gpa3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpa4: gpa4-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpq0: gpq0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	/* I2C5 (also called CAM_PMIC_I2C in TRM) */
+	i2c5_pins: i2c5-pins {
+		samsung,pins = "gpa3-5", "gpa3-6";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	/* I2C6 (also called MOTOR_I2C in TRM) */
+	i2c6_pins: i2c6-pins {
+		samsung,pins = "gpa3-7", "gpa4-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	/* USI: UART_DEBUG_0 pins */
+	uart0_pins: uart0-pins {
+		samsung,pins = "gpq0-0", "gpq0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI: UART_DEBUG_1 pins */
+	uart1_pins: uart1-pins {
+		samsung,pins = "gpa3-7", "gpa4-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+};
+
+&pinctrl_cmgp {
+	gpm0: gpm0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm1: gpm1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm2: gpm2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm3: gpm3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm4: gpm4-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm5: gpm5-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm6: gpm6-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm7: gpm7-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	/* USI_CMGP0: HSI2C function */
+	hsi2c3_pins: hsi2c3-pins {
+		samsung,pins = "gpm0-0", "gpm1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	/* USI_CMGP0: UART function (4 pins, Auto Flow Control) */
+	uart1_single_pins: uart1-single-pins {
+		samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0", "gpm3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP0: UART function (2 pins, Non-Auto Flow Control) */
+	uart1_dual_pins: uart1-dual-pins {
+		samsung,pins = "gpm0-0", "gpm1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP0: SPI function */
+	spi1_pins: spi1-pins {
+		samsung,pins = "gpm0-0", "gpm1-0", "gpm2-0", "gpm3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	/* USI_CMGP1: HSI2C function */
+	hsi2c4_pins: hsi2c4-pins {
+		samsung,pins = "gpm4-0", "gpm5-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	/* USI_CMGP1: UART function (4 pins, Auto Flow Control) */
+	uart2_single_pins: uart2-single-pins {
+		samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0", "gpm7-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP1: UART function (2 pins, Non-Auto Flow Control) */
+	uart2_dual_pins: uart2-dual-pins {
+		samsung,pins = "gpm4-0", "gpm5-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	/* USI_CMGP1: SPI function */
+	spi2_pins: spi2-pins {
+		samsung,pins = "gpm4-0", "gpm5-0", "gpm6-0", "gpm7-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+};
+
+&pinctrl_aud {
+	gpb0: gpb0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb1: gpb1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	aud_codec_mclk_pins: aud-codec-mclk-pins {
+		samsung,pins = "gpb0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_codec_mclk_idle_pins: aud-codec-mclk-idle-pins {
+		samsung,pins = "gpb0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s0_pins: aud-i2s0-pins {
+		samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s0_idle_pins: aud-i2s0-idle-pins {
+		samsung,pins = "gpb0-1", "gpb0-2", "gpb0-3", "gpb0-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s1_pins: aud-i2s1-pins {
+		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_i2s1_idle_pins: aud-i2s1-idle-pins {
+		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_fm_pins: aud-fm-pins {
+		samsung,pins = "gpb1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+
+	aud_fm_idle_pins: aud-fm-idle-pins {
+		samsung,pins = "gpb1-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+};
+
+&pinctrl_hsi {
+	gpf2: gpf2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	sd2_clk_pins: sd2-clk-pins {
+		samsung,pins = "gpf2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS850_HSI_PIN_DRV_LV2>;
+	};
+
+	sd2_cmd_pins: sd2-cmd-pins {
+		samsung,pins = "gpf2-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS850_HSI_PIN_DRV_LV2>;
+	 };
+
+	sd2_bus1_pins: sd2-bus1-pins {
+		samsung,pins = "gpf2-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS850_HSI_PIN_DRV_LV2>;
+	};
+
+	sd2_bus4_pins: sd2-bus4-pins {
+		samsung,pins = "gpf2-3", "gpf2-4", "gpf2-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS850_HSI_PIN_DRV_LV2>;
+	};
+
+	sd2_pdn_pins: sd2-pdn-pins {
+		samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
+			       "gpf2-4", "gpf2-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+	};
+};
+
+&pinctrl_core {
+	gpf0: gpf0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf1: gpf1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	sd0_clk_pins: sd0-clk-pins {
+		samsung,pins = "gpf0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+	};
+
+	sd0_cmd_pins: sd0-cmd-pins {
+		samsung,pins = "gpf0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+	};
+
+	sd0_rdqs_pins: sd0-rdqs-pins {
+		samsung,pins = "gpf0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+	};
+
+	sd0_nreset_pins: sd0-nreset-pins {
+		samsung,pins = "gpf0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+	};
+
+	sd0_bus1_pins: sd0-bus1-pins {
+		samsung,pins = "gpf1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+	};
+
+	sd0_bus4_pins: sd0-bus4-pins {
+		samsung,pins = "gpf1-1", "gpf1-2", "gpf1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+	};
+
+	sd0_bus8_pins: sd0-bus8-pins {
+		samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+	};
+};
+
+&pinctrl_peri {
+	gpc0: gpc0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpc1: gpc1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg0: gpg0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg3: gpg3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp0: gpp0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+	gpp1: gpp1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpp2: gpp2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	sensor_mclk0_in_pins: sensor-mclk0-in-pins {
+		samsung,pins = "gpc0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+	};
+
+	sensor_mclk0_out_pins: sensor-mclk0-out-pins {
+		samsung,pins = "gpc0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+	};
+
+	sensor_mclk0_fn_pins: sensor-mclk0-fn-pins {
+		samsung,pins = "gpc0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+	};
+
+	sensor_mclk1_in_pins: sensor-mclk1-in-pins {
+		samsung,pins = "gpc0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+	};
+
+	sensor_mclk1_out_pins: sensor-mclk1-out-pins {
+		samsung,pins = "gpc0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+	};
+
+	sensor_mclk1_fn_pins: sensor-mclk1-fn-pins {
+		samsung,pins = "gpc0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+	};
+
+	sensor_mclk2_in_pins: sensor-mclk2-in-pins {
+		samsung,pins = "gpc0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+	};
+
+	sensor_mclk2_out_pins: sensor-mclk2-out-pins {
+		samsung,pins = "gpc0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+	};
+
+	sensor_mclk2_fn_pins: sensor-mclk2-fn-pins {
+		samsung,pins = "gpc0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+	};
+
+	/* USI: HSI2C0 */
+	hsi2c0_pins: hsi2c0-pins {
+		samsung,pins = "gpc1-0", "gpc1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	/* USI: HSI2C1 */
+	hsi2c1_pins: hsi2c1-pins {
+		samsung,pins = "gpc1-2", "gpc1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	/* USI: HSI2C2 */
+	hsi2c2_pins: hsi2c2-pins {
+		samsung,pins = "gpc1-4", "gpc1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	/* USI: SPI */
+	spi0_pins: spi0-pins {
+		samsung,pins = "gpp2-0", "gpp2-1", "gpp2-2", "gpp2-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	i2c0_pins: i2c0-pins {
+		samsung,pins = "gpp0-0", "gpp0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	i2c1_pins: i2c1-pins {
+		samsung,pins = "gpp0-2", "gpp0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	i2c2_pins: i2c2-pins {
+		samsung,pins = "gpp0-4", "gpp0-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	i2c3_pins: i2c3-pins {
+		samsung,pins = "gpp1-0", "gpp1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	i2c4_pins: i2c4-pins {
+		samsung,pins = "gpp1-2", "gpp1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	xclkout_pins: xclkout-pins {
+		samsung,pins = "gpq0-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+};
diff --git a/arch/arm/dts/exynos850.dtsi b/arch/arm/dts/exynos850.dtsi
new file mode 100644
index 000000000000..53104e65b9c6
--- /dev/null
+++ b/arch/arm/dts/exynos850.dtsi
@@ -0,0 +1,809 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung Exynos850 SoC device tree source
+ *
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 Linaro Ltd.
+ *
+ * Samsung Exynos850 SoC device nodes are listed in this file.
+ * Exynos850 based board files can include this file and provide
+ * values for board specific bindings.
+ */
+
+#include <dt-bindings/clock/exynos850.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/samsung,exynos-usi.h>
+
+/ {
+	/* Also known under engineering name Exynos3830 */
+	compatible = "samsung,exynos850";
+	#address-cells = <2>;
+	#size-cells = <1>;
+
+	interrupt-parent = <&gic>;
+
+	aliases {
+		pinctrl0 = &pinctrl_alive;
+		pinctrl1 = &pinctrl_cmgp;
+		pinctrl2 = &pinctrl_aud;
+		pinctrl3 = &pinctrl_hsi;
+		pinctrl4 = &pinctrl_core;
+		pinctrl5 = &pinctrl_peri;
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a55-pmu";
+		interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>,
+				     <&cpu4>, <&cpu5>, <&cpu6>, <&cpu7>;
+	};
+
+	/* Main system clock (XTCXO); external, must be 26 MHz */
+	oscclk: clock-oscclk {
+		compatible = "fixed-clock";
+		clock-output-names = "oscclk";
+		#clock-cells = <0>;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+				core1 {
+					cpu = <&cpu1>;
+				};
+				core2 {
+					cpu = <&cpu2>;
+				};
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+				core1 {
+					cpu = <&cpu5>;
+				};
+				core2 {
+					cpu = <&cpu6>;
+				};
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0>;
+			enable-method = "psci";
+		};
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x1>;
+			enable-method = "psci";
+		};
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x2>;
+			enable-method = "psci";
+		};
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x3>;
+			enable-method = "psci";
+		};
+		cpu4: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x100>;
+			enable-method = "psci";
+		};
+		cpu5: cpu@101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x101>;
+			enable-method = "psci";
+		};
+		cpu6: cpu@102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x102>;
+			enable-method = "psci";
+		};
+		cpu7: cpu@103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x103>;
+			enable-method = "psci";
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		/* Hypervisor Virtual Timer interrupt is not wired to GIC */
+		interrupts =
+		     <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+		     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+		     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+		     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	soc: soc@0 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x0 0x0 0x0 0x20000000>;
+
+		chipid@10000000 {
+			compatible = "samsung,exynos850-chipid";
+			reg = <0x10000000 0x100>;
+		};
+
+		timer@10040000 {
+			compatible = "samsung,exynos850-mct",
+				     "samsung,exynos4210-mct";
+			reg = <0x10040000 0x800>;
+			interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&oscclk>, <&cmu_peri CLK_GOUT_MCT_PCLK>;
+			clock-names = "fin_pll", "mct";
+		};
+
+		gic: interrupt-controller@12a01000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			reg = <0x12a01000 0x1000>,
+			      <0x12a02000 0x2000>,
+			      <0x12a04000 0x2000>,
+			      <0x12a06000 0x2000>;
+			interrupt-controller;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) |
+						 IRQ_TYPE_LEVEL_HIGH)>;
+		};
+
+		pmu_system_controller: system-controller@11860000 {
+			compatible = "samsung,exynos850-pmu", "syscon";
+			reg = <0x11860000 0x10000>;
+
+			reboot: syscon-reboot {
+				compatible = "syscon-reboot";
+				regmap = <&pmu_system_controller>;
+				offset = <0x3a00>; /* SYSTEM_CONFIGURATION */
+				mask = <0x2>; /* SWRESET_SYSTEM */
+				value = <0x2>; /* reset value */
+			};
+		};
+
+		watchdog_cl0: watchdog@10050000 {
+			compatible = "samsung,exynos850-wdt";
+			reg = <0x10050000 0x100>;
+			interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_peri CLK_GOUT_WDT0_PCLK>, <&oscclk>;
+			clock-names = "watchdog", "watchdog_src";
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			samsung,cluster-index = <0>;
+			status = "disabled";
+		};
+
+		watchdog_cl1: watchdog@10060000 {
+			compatible = "samsung,exynos850-wdt";
+			reg = <0x10060000 0x100>;
+			interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_peri CLK_GOUT_WDT1_PCLK>, <&oscclk>;
+			clock-names = "watchdog", "watchdog_src";
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			samsung,cluster-index = <1>;
+			status = "disabled";
+		};
+
+		cmu_peri: clock-controller@10030000 {
+			compatible = "samsung,exynos850-cmu-peri";
+			reg = <0x10030000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_PERI_BUS>,
+				 <&cmu_top CLK_DOUT_PERI_UART>,
+				 <&cmu_top CLK_DOUT_PERI_IP>;
+			clock-names = "oscclk", "dout_peri_bus",
+				      "dout_peri_uart", "dout_peri_ip";
+		};
+
+		cmu_g3d: clock-controller@11400000 {
+			compatible = "samsung,exynos850-cmu-g3d";
+			reg = <0x11400000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_G3D_SWITCH>;
+			clock-names = "oscclk", "dout_g3d_switch";
+		};
+
+		cmu_apm: clock-controller@11800000 {
+			compatible = "samsung,exynos850-cmu-apm";
+			reg = <0x11800000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_CLKCMU_APM_BUS>;
+			clock-names = "oscclk", "dout_clkcmu_apm_bus";
+		};
+
+		cmu_cmgp: clock-controller@11c00000 {
+			compatible = "samsung,exynos850-cmu-cmgp";
+			reg = <0x11c00000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_apm CLK_GOUT_CLKCMU_CMGP_BUS>;
+			clock-names = "oscclk", "gout_clkcmu_cmgp_bus";
+		};
+
+		cmu_core: clock-controller@12000000 {
+			compatible = "samsung,exynos850-cmu-core";
+			reg = <0x12000000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_CORE_BUS>,
+				 <&cmu_top CLK_DOUT_CORE_CCI>,
+				 <&cmu_top CLK_DOUT_CORE_MMC_EMBD>,
+				 <&cmu_top CLK_DOUT_CORE_SSS>;
+			clock-names = "oscclk", "dout_core_bus",
+				      "dout_core_cci", "dout_core_mmc_embd",
+				      "dout_core_sss";
+		};
+
+		cmu_top: clock-controller@120e0000 {
+			compatible = "samsung,exynos850-cmu-top";
+			reg = <0x120e0000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>;
+			clock-names = "oscclk";
+		};
+
+		cmu_mfcmscl: clock-controller@12c00000 {
+			compatible = "samsung,exynos850-cmu-mfcmscl";
+			reg = <0x12c00000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>,
+				 <&cmu_top CLK_DOUT_MFCMSCL_MFC>,
+				 <&cmu_top CLK_DOUT_MFCMSCL_M2M>,
+				 <&cmu_top CLK_DOUT_MFCMSCL_MCSC>,
+				 <&cmu_top CLK_DOUT_MFCMSCL_JPEG>;
+			clock-names = "oscclk", "dout_mfcmscl_mfc",
+				      "dout_mfcmscl_m2m", "dout_mfcmscl_mcsc",
+				      "dout_mfcmscl_jpeg";
+		};
+
+		cmu_dpu: clock-controller@13000000 {
+			compatible = "samsung,exynos850-cmu-dpu";
+			reg = <0x13000000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_DPU>;
+			clock-names = "oscclk", "dout_dpu";
+		};
+
+		cmu_hsi: clock-controller@13400000 {
+			compatible = "samsung,exynos850-cmu-hsi";
+			reg = <0x13400000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>,
+				 <&cmu_top CLK_DOUT_HSI_BUS>,
+				 <&cmu_top CLK_DOUT_HSI_MMC_CARD>,
+				 <&cmu_top CLK_DOUT_HSI_USB20DRD>;
+			clock-names = "oscclk", "dout_hsi_bus",
+				      "dout_hsi_mmc_card", "dout_hsi_usb20drd";
+		};
+
+		cmu_is: clock-controller@14500000 {
+			compatible = "samsung,exynos850-cmu-is";
+			reg = <0x14500000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>,
+				 <&cmu_top CLK_DOUT_IS_BUS>,
+				 <&cmu_top CLK_DOUT_IS_ITP>,
+				 <&cmu_top CLK_DOUT_IS_VRA>,
+				 <&cmu_top CLK_DOUT_IS_GDC>;
+			clock-names = "oscclk", "dout_is_bus", "dout_is_itp",
+				      "dout_is_vra", "dout_is_gdc";
+		};
+
+		cmu_aud: clock-controller@14a00000 {
+			compatible = "samsung,exynos850-cmu-aud";
+			reg = <0x14a00000 0x8000>;
+			#clock-cells = <1>;
+
+			clocks = <&oscclk>, <&cmu_top CLK_DOUT_AUD>;
+			clock-names = "oscclk", "dout_aud";
+		};
+
+		pinctrl_alive: pinctrl@11850000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x11850000 0x1000>;
+
+			wakeup-interrupt-controller {
+				compatible = "samsung,exynos850-wakeup-eint";
+			};
+		};
+
+		pinctrl_cmgp: pinctrl@11c30000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x11c30000 0x1000>;
+
+			wakeup-interrupt-controller {
+				compatible = "samsung,exynos850-wakeup-eint";
+			};
+		};
+
+		pinctrl_core: pinctrl@12070000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x12070000 0x1000>;
+			interrupts = <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_hsi: pinctrl@13430000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x13430000 0x1000>;
+			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_peri: pinctrl@139b0000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x139b0000 0x1000>;
+			interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_aud: pinctrl@14a60000 {
+			compatible = "samsung,exynos850-pinctrl";
+			reg = <0x14a60000 0x1000>;
+		};
+
+		rtc: rtc@11a30000 {
+			compatible = "samsung,s3c6410-rtc";
+			reg = <0x11a30000 0x100>;
+			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cmu_apm CLK_GOUT_RTC_PCLK>;
+			clock-names = "rtc";
+			status = "disabled";
+		};
+
+		mmc_0: mmc@12100000 {
+			compatible = "samsung,exynos7-dw-mshc-smu";
+			reg = <0x12100000 0x2000>;
+			interrupts = <GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&cmu_core CLK_GOUT_MMC_EMBD_ACLK>,
+				 <&cmu_core CLK_GOUT_MMC_EMBD_SDCLKIN>;
+			clock-names = "biu", "ciu";
+			fifo-depth = <0x40>;
+			status = "disabled";
+		};
+
+		i2c_0: i2c@13830000 {
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x13830000 0x100>;
+			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c0_pins>;
+			clocks = <&cmu_peri CLK_GOUT_I2C0_PCLK>;
+			clock-names = "i2c";
+			status = "disabled";
+		};
+
+		i2c_1: i2c@13840000 {
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x13840000 0x100>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c1_pins>;
+			clocks = <&cmu_peri CLK_GOUT_I2C1_PCLK>;
+			clock-names = "i2c";
+			status = "disabled";
+		};
+
+		i2c_2: i2c@13850000 {
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x13850000 0x100>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c2_pins>;
+			clocks = <&cmu_peri CLK_GOUT_I2C2_PCLK>;
+			clock-names = "i2c";
+			status = "disabled";
+		};
+
+		i2c_3: i2c@13860000 {
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x13860000 0x100>;
+			interrupts = <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c3_pins>;
+			clocks = <&cmu_peri CLK_GOUT_I2C3_PCLK>;
+			clock-names = "i2c";
+			status = "disabled";
+		};
+
+		i2c_4: i2c@13870000 {
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x13870000 0x100>;
+			interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c4_pins>;
+			clocks = <&cmu_peri CLK_GOUT_I2C4_PCLK>;
+			clock-names = "i2c";
+			status = "disabled";
+		};
+
+		/* I2C_5 (also called CAM_PMIC_I2C in TRM) */
+		i2c_5: i2c@13880000 {
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x13880000 0x100>;
+			interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c5_pins>;
+			clocks = <&cmu_peri CLK_GOUT_I2C5_PCLK>;
+			clock-names = "i2c";
+			status = "disabled";
+		};
+
+		/* I2C_6 (also called MOTOR_I2C in TRM) */
+		i2c_6: i2c@13890000 {
+			compatible = "samsung,s3c2440-i2c";
+			reg = <0x13890000 0x100>;
+			interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&i2c6_pins>;
+			clocks = <&cmu_peri CLK_GOUT_I2C6_PCLK>;
+			clock-names = "i2c";
+			status = "disabled";
+		};
+
+		sysmmu_mfcmscl: sysmmu@12c50000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x12c50000 0x9000>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+			clock-names = "sysmmu";
+			clocks = <&cmu_mfcmscl CLK_GOUT_MFCMSCL_SYSMMU_CLK>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_dpu: sysmmu@130c0000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x130c0000 0x9000>;
+			interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+			clock-names = "sysmmu";
+			clocks = <&cmu_dpu CLK_GOUT_DPU_SMMU_CLK>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_is0: sysmmu@14550000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x14550000 0x9000>;
+			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+			clock-names = "sysmmu";
+			clocks = <&cmu_is CLK_GOUT_IS_SYSMMU_IS0_CLK>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_is1: sysmmu@14570000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x14570000 0x9000>;
+			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
+			clock-names = "sysmmu";
+			clocks = <&cmu_is CLK_GOUT_IS_SYSMMU_IS1_CLK>;
+			#iommu-cells = <0>;
+		};
+
+		sysmmu_aud: sysmmu@14850000 {
+			compatible = "samsung,exynos-sysmmu";
+			reg = <0x14850000 0x9000>;
+			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
+			clock-names = "sysmmu";
+			clocks = <&cmu_aud CLK_GOUT_AUD_SYSMMU_CLK>;
+			#iommu-cells = <0>;
+		};
+
+		sysreg_peri: syscon@10020000 {
+			compatible = "samsung,exynos850-peri-sysreg",
+				     "samsung,exynos850-sysreg", "syscon";
+			reg = <0x10020000 0x10000>;
+			clocks = <&cmu_peri CLK_GOUT_SYSREG_PERI_PCLK>;
+		};
+
+		sysreg_cmgp: syscon@11c20000 {
+			compatible = "samsung,exynos850-cmgp-sysreg",
+				     "samsung,exynos850-sysreg", "syscon";
+			reg = <0x11c20000 0x10000>;
+			clocks = <&cmu_cmgp CLK_GOUT_SYSREG_CMGP_PCLK>;
+		};
+
+		usbdrd: usb@13600000 {
+			compatible = "samsung,exynos850-dwusb3";
+			ranges = <0x0 0x13600000 0x10000>;
+			clocks = <&cmu_hsi CLK_GOUT_USB_BUS_EARLY_CLK>,
+				 <&cmu_hsi CLK_GOUT_USB_REF_CLK>;
+			clock-names = "bus_early", "ref";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			status = "disabled";
+
+			usbdrd_dwc3: usb@0 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x10000>;
+				interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+				phys = <&usbdrd_phy 0>;
+				phy-names = "usb2-phy";
+			};
+		};
+
+		usbdrd_phy: phy@135d0000 {
+			compatible = "samsung,exynos850-usbdrd-phy";
+			reg = <0x135d0000 0x100>;
+			clocks = <&cmu_hsi CLK_GOUT_USB_PHY_ACLK>,
+				 <&cmu_hsi CLK_GOUT_USB_PHY_REF_CLK>;
+			clock-names = "phy", "ref";
+			samsung,pmu-syscon = <&pmu_system_controller>;
+			#phy-cells = <1>;
+			status = "disabled";
+		};
+
+		usi_uart: usi@138200c0 {
+			compatible = "samsung,exynos850-usi";
+			reg = <0x138200c0 0x20>;
+			samsung,sysreg = <&sysreg_peri 0x1010>;
+			samsung,mode = <USI_V2_UART>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			clocks = <&cmu_peri CLK_GOUT_UART_PCLK>,
+				 <&cmu_peri CLK_GOUT_UART_IPCLK>;
+			clock-names = "pclk", "ipclk";
+			status = "disabled";
+
+			serial_0: serial@13820000 {
+				compatible = "samsung,exynos850-uart";
+				reg = <0x13820000 0xc0>;
+				interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&uart0_pins>;
+				clocks = <&cmu_peri CLK_GOUT_UART_PCLK>,
+					 <&cmu_peri CLK_GOUT_UART_IPCLK>;
+				clock-names = "uart", "clk_uart_baud0";
+				status = "disabled";
+			};
+		};
+
+		usi_hsi2c_0: usi@138a00c0 {
+			compatible = "samsung,exynos850-usi";
+			reg = <0x138a00c0 0x20>;
+			samsung,sysreg = <&sysreg_peri 0x1020>;
+			samsung,mode = <USI_V2_I2C>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			clocks = <&cmu_peri CLK_GOUT_HSI2C0_PCLK>,
+				 <&cmu_peri CLK_GOUT_HSI2C0_IPCLK>;
+			clock-names = "pclk", "ipclk";
+			status = "disabled";
+
+			hsi2c_0: i2c@138a0000 {
+				compatible = "samsung,exynosautov9-hsi2c";
+				reg = <0x138a0000 0xc0>;
+				interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&hsi2c0_pins>;
+				clocks = <&cmu_peri CLK_GOUT_HSI2C0_IPCLK>,
+					 <&cmu_peri CLK_GOUT_HSI2C0_PCLK>;
+				clock-names = "hsi2c", "hsi2c_pclk";
+				status = "disabled";
+			};
+		};
+
+		usi_hsi2c_1: usi@138b00c0 {
+			compatible = "samsung,exynos850-usi";
+			reg = <0x138b00c0 0x20>;
+			samsung,sysreg = <&sysreg_peri 0x1030>;
+			samsung,mode = <USI_V2_I2C>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			clocks = <&cmu_peri CLK_GOUT_HSI2C1_PCLK>,
+				 <&cmu_peri CLK_GOUT_HSI2C1_IPCLK>;
+			clock-names = "pclk", "ipclk";
+			status = "disabled";
+
+			hsi2c_1: i2c@138b0000 {
+				compatible = "samsung,exynosautov9-hsi2c";
+				reg = <0x138b0000 0xc0>;
+				interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&hsi2c1_pins>;
+				clocks = <&cmu_peri CLK_GOUT_HSI2C1_IPCLK>,
+					 <&cmu_peri CLK_GOUT_HSI2C1_PCLK>;
+				clock-names = "hsi2c", "hsi2c_pclk";
+				status = "disabled";
+			};
+		};
+
+		usi_hsi2c_2: usi@138c00c0 {
+			compatible = "samsung,exynos850-usi";
+			reg = <0x138c00c0 0x20>;
+			samsung,sysreg = <&sysreg_peri 0x1040>;
+			samsung,mode = <USI_V2_I2C>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			clocks = <&cmu_peri CLK_GOUT_HSI2C2_PCLK>,
+				 <&cmu_peri CLK_GOUT_HSI2C2_IPCLK>;
+			clock-names = "pclk", "ipclk";
+			status = "disabled";
+
+			hsi2c_2: i2c@138c0000 {
+				compatible = "samsung,exynosautov9-hsi2c";
+				reg = <0x138c0000 0xc0>;
+				interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&hsi2c2_pins>;
+				clocks = <&cmu_peri CLK_GOUT_HSI2C2_IPCLK>,
+					 <&cmu_peri CLK_GOUT_HSI2C2_PCLK>;
+				clock-names = "hsi2c", "hsi2c_pclk";
+				status = "disabled";
+			};
+		};
+
+		usi_spi_0: usi@139400c0 {
+			compatible = "samsung,exynos850-usi";
+			reg = <0x139400c0 0x20>;
+			samsung,sysreg = <&sysreg_peri 0x1050>;
+			samsung,mode = <USI_V2_SPI>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			clocks = <&cmu_peri CLK_GOUT_SPI0_PCLK>,
+				 <&cmu_peri CLK_GOUT_SPI0_IPCLK>;
+			clock-names = "pclk", "ipclk";
+			status = "disabled";
+		};
+
+		usi_cmgp0: usi@11d000c0 {
+			compatible = "samsung,exynos850-usi";
+			reg = <0x11d000c0 0x20>;
+			samsung,sysreg = <&sysreg_cmgp 0x2000>;
+			samsung,mode = <USI_V2_I2C>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI0_PCLK>,
+				 <&cmu_cmgp CLK_GOUT_CMGP_USI0_IPCLK>;
+			clock-names = "pclk", "ipclk";
+			status = "disabled";
+
+			hsi2c_3: i2c@11d00000 {
+				compatible = "samsung,exynosautov9-hsi2c";
+				reg = <0x11d00000 0xc0>;
+				interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&hsi2c3_pins>;
+				clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI0_IPCLK>,
+					 <&cmu_cmgp CLK_GOUT_CMGP_USI0_PCLK>;
+				clock-names = "hsi2c", "hsi2c_pclk";
+				status = "disabled";
+			};
+
+			serial_1: serial@11d00000 {
+				compatible = "samsung,exynos850-uart";
+				reg = <0x11d00000 0xc0>;
+				interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&uart1_single_pins>;
+				clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI0_PCLK>,
+					 <&cmu_cmgp CLK_GOUT_CMGP_USI0_IPCLK>;
+				clock-names = "uart", "clk_uart_baud0";
+				status = "disabled";
+			};
+		};
+
+		usi_cmgp1: usi@11d200c0 {
+			compatible = "samsung,exynos850-usi";
+			reg = <0x11d200c0 0x20>;
+			samsung,sysreg = <&sysreg_cmgp 0x2010>;
+			samsung,mode = <USI_V2_I2C>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+			clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI1_PCLK>,
+				 <&cmu_cmgp CLK_GOUT_CMGP_USI1_IPCLK>;
+			clock-names = "pclk", "ipclk";
+			status = "disabled";
+
+			hsi2c_4: i2c@11d20000 {
+				compatible = "samsung,exynosautov9-hsi2c";
+				reg = <0x11d20000 0xc0>;
+				interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&hsi2c4_pins>;
+				clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI1_IPCLK>,
+					 <&cmu_cmgp CLK_GOUT_CMGP_USI1_PCLK>;
+				clock-names = "hsi2c", "hsi2c_pclk";
+				status = "disabled";
+			};
+
+			serial_2: serial@11d20000 {
+				compatible = "samsung,exynos850-uart";
+				reg = <0x11d20000 0xc0>;
+				interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&uart2_single_pins>;
+				clocks = <&cmu_cmgp CLK_GOUT_CMGP_USI1_PCLK>,
+					 <&cmu_cmgp CLK_GOUT_CMGP_USI1_IPCLK>;
+				clock-names = "uart", "clk_uart_baud0";
+				status = "disabled";
+			};
+		};
+	};
+};
+
+#include "exynos850-pinctrl.dtsi"
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 8f3aee052c8a..45fc6bb024b0 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -58,6 +58,15 @@ config ARCH_EXYNOS7
 	  Cortex-A53 CPU (and some in a big.LITTLE configuration). There are
 	  multiple SoCs in this family including Exynos7420.
 
+config ARCH_EXYNOS9
+	bool "Exynos9 SoC family"
+	select ARM64
+	select BLK
+	select DM_MMC
+	help
+	  Samsung Exynos9 SoC family are based on ARMv8 Cortex CPU. There are
+	  multiple SoCs in this family including Exynos850.
+
 endchoice
 
 if ARCH_EXYNOS4
diff --git a/arch/arm/mach-exynos/mmu-arm64.c b/arch/arm/mach-exynos/mmu-arm64.c
index 8d8c64e8f8fa..30e522804fbf 100644
--- a/arch/arm/mach-exynos/mmu-arm64.c
+++ b/arch/arm/mach-exynos/mmu-arm64.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <asm/armv8/mmu.h>
+#include <linux/sizes.h>
 
 #if IS_ENABLED(CONFIG_EXYNOS7420)
 
@@ -95,4 +96,37 @@ static struct mm_region exynos7880_mem_map[] = {
 };
 
 struct mm_region *mem_map = exynos7880_mem_map;
+
+#elif IS_ENABLED(CONFIG_EXYNOS850)
+
+static struct mm_region exynos850_mem_map[] = {
+	{
+		/* Peripheral block */
+		.virt = 0x10000000UL,
+		.phys = 0x10000000UL,
+		.size = SZ_256M,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* DDR, 32-bit area */
+		.virt = 0x80000000UL,
+		.phys = 0x80000000UL,
+		.size = SZ_2G,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		/* DDR, 64-bit area */
+		.virt = 0x880000000UL,
+		.phys = 0x880000000UL,
+		.size = SZ_2G,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		/* List terminator */
+	}
+};
+
+struct mm_region *mem_map = exynos850_mem_map;
+
 #endif
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 12/13] board: samsung: Add support for E850-96 board
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
                   ` (10 preceding siblings ...)
  2023-12-13  3:16 ` [PATCH 11/13] arm: exynos: Add Exynos850 SoC support Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-13  3:16 ` [PATCH 13/13] MAINTAINERS: Add new Samsung subsystems Sam Protsenko
  2023-12-18 15:31 ` [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
  13 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

Add support for WinLink E850-96 board [1]. It's based on Exynos850 SoC
and follows 96boards specification, so it's compatible with 96boards
mezzanine boards [2]. This patch enables next features:

  * Serial console
  * USI
  * PMU (muxing AP UART path)
  * Pinctrl
  * Clocks
  * Timer (ARMv8 architected)
  * Reset control

It's quite a minimal enablement. Features like MMC, USB and Ethernet
will be enabled later.

The rationale for config values is as follows:

  * TEXT_BASE = 0xf8800000

    That's where BL2 loads the U-Boot payload, so TEXT_BASE must be
    exactly this value. Overall the memory map is designed in a way to
    keep the bootloader in the upper 128 MiB area of RAM, which is
    0xf8000000..0xffffffff. That includes bootloader's code, stack,
    data, heap, MMU tables, etc. All the memory below that 128 MiB chunk
    can be used for storing boot images (0x80000000..0xf8000000).

  * CUSTOM_SYS_INIT_SP_ADDR = 0xf8c00000

    Just 4 MiB above the TEXT_BASE address, to leave enough space for
    U-Boot code and stack itself (grows downwards).

  * SYS_LOAD_ADDR = 0x80000000

    The beginning of RAM. That's where Linux kernel image must be
    loaded.

  * SYS_MALLOC_LEN = 0x81f000

    8 MiB for malloc() + ENV_SIZE (128 KiB)

  * SYS_MALLOC_F_LEN = 0x4000

    Increase malloc() pool size available before relocation from 8 KiB
    (default) to 16 KiB. Otherwise "alloc space exhausted" message
    appears in U-Boot log during board_init_f() stage. There are next
    reasons for doing so:

      1. Having "bootph-all" flags in some dts nodes leads to binding
         those during pre-relocation stage, and binding (DM) uses
         dynamic memory allocation
      2. clk-exynos850 driver uses CCF clocks, which in turn use dynamic
         memory allocation

Device tree file was imported from Linux kernel. All nodes and boot
phase flags added in exynos850-e850-96-u-boot.dtsi are only needed to
enable serial console:

  * oscclk -> cmu_top -> cmu_peri: generate UART/USI clocks
  * pinctrl_alive and uart1_pins: needed to mux UART pins
  * pmu_system_controller: configures AP UART path to uart1_pins
  * usi_uart: configures USI block to operate as a UART protocol
  * serial_0: enables serial console (UART)

[1] https://www.96boards.org/product/e850-96b/
[2] https://www.96boards.org/products/mezzanine/

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 arch/arm/dts/Makefile                         |    1 +
 arch/arm/dts/exynos850-e850-96-u-boot.dtsi    |   37 +
 arch/arm/dts/exynos850-e850-96.dts            |  273 ++++
 arch/arm/mach-exynos/Kconfig                  |   19 +-
 board/samsung/e850-96/Kconfig                 |   16 +
 board/samsung/e850-96/MAINTAINERS             |    9 +
 board/samsung/e850-96/Makefile                |    6 +
 board/samsung/e850-96/e850-96.c               |   22 +
 configs/e850-96_defconfig                     |   21 +
 doc/board/samsung/e850-96.rst                 |   87 ++
 .../img/exynos850-boot-architecture.svg       | 1283 +++++++++++++++++
 doc/board/samsung/index.rst                   |    1 +
 include/configs/e850-96.h                     |   12 +
 13 files changed, 1786 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/dts/exynos850-e850-96-u-boot.dtsi
 create mode 100644 arch/arm/dts/exynos850-e850-96.dts
 create mode 100644 board/samsung/e850-96/Kconfig
 create mode 100644 board/samsung/e850-96/MAINTAINERS
 create mode 100644 board/samsung/e850-96/Makefile
 create mode 100644 board/samsung/e850-96/e850-96.c
 create mode 100644 configs/e850-96_defconfig
 create mode 100644 doc/board/samsung/e850-96.rst
 create mode 100644 doc/board/samsung/img/exynos850-boot-architecture.svg
 create mode 100644 include/configs/e850-96.h

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 5fc888680b39..7d949a6798ee 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -31,6 +31,7 @@ dtb-$(CONFIG_EXYNOS7420) += exynos7420-espresso7420.dtb
 dtb-$(CONFIG_TARGET_A5Y17LTE) += exynos78x0-axy17lte.dtb
 dtb-$(CONFIG_TARGET_A3Y17LTE) += exynos78x0-axy17lte.dtb
 dtb-$(CONFIG_TARGET_A7Y17LTE) += exynos78x0-axy17lte.dtb
+dtb-$(CONFIG_TARGET_E850_96) += exynos850-e850-96.dtb
 
 dtb-$(CONFIG_ARCH_APPLE) += \
 	t8103-j274.dtb \
diff --git a/arch/arm/dts/exynos850-e850-96-u-boot.dtsi b/arch/arm/dts/exynos850-e850-96-u-boot.dtsi
new file mode 100644
index 000000000000..7ad11e9faab2
--- /dev/null
+++ b/arch/arm/dts/exynos850-e850-96-u-boot.dtsi
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 Linaro Ltd.
+ */
+
+&cmu_top {
+	bootph-all;
+};
+
+&cmu_peri {
+	bootph-all;
+};
+
+&oscclk {
+	bootph-all;
+};
+
+&pinctrl_alive {
+	bootph-all;
+};
+
+&pmu_system_controller {
+	bootph-all;
+	samsung,uart-debug-1;
+};
+
+&serial_0 {
+	bootph-all;
+};
+
+&uart1_pins {
+	bootph-all;
+};
+
+&usi_uart {
+	bootph-all;
+};
diff --git a/arch/arm/dts/exynos850-e850-96.dts b/arch/arm/dts/exynos850-e850-96.dts
new file mode 100644
index 000000000000..f074df8982b3
--- /dev/null
+++ b/arch/arm/dts/exynos850-e850-96.dts
@@ -0,0 +1,273 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * WinLink E850-96 board device tree source
+ *
+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (C) 2021 Linaro Ltd.
+ *
+ * Device tree source file for WinLink's E850-96 board which is based on
+ * Samsung Exynos850 SoC.
+ */
+
+/dts-v1/;
+
+#include "exynos850.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+	model = "WinLink E850-96 board";
+	compatible = "winlink,e850-96", "samsung,exynos850";
+
+	aliases {
+		mmc0 = &mmc_0;
+		serial0 = &serial_0;
+	};
+
+	chosen {
+		stdout-path = &serial_0;
+	};
+
+	connector {
+		compatible = "gpio-usb-b-connector", "usb-b-connector";
+		label = "micro-USB";
+		type = "micro";
+		vbus-supply = <&reg_usb_host_vbus>;
+		id-gpios = <&gpa0 0 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&micro_usb_det_pins>;
+
+		port {
+			usb_dr_connector: endpoint {
+				remote-endpoint = <&usb1_drd_sw>;
+			};
+		};
+	};
+
+	/*
+	 * RAM: 4 GiB (eMCP):
+	 *   - 2 GiB at 0x80000000
+	 *   - 2 GiB at 0x880000000
+	 *
+	 * 0xbab00000..0xbfffffff: secure memory (85 MiB).
+	 */
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x3ab00000>,
+		      <0x0 0xc0000000 0x40000000>,
+		      <0x8 0x80000000 0x80000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&key_voldown_pins &key_volup_pins>;
+
+		volume-down-key {
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			gpios = <&gpa1 0 GPIO_ACTIVE_LOW>;
+		};
+
+		volume-up-key {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&gpa0 7 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		/* HEART_BEAT_LED */
+		user_led1: led-1 {
+			label = "yellow:user1";
+			gpios = <&gpg2 2 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_YELLOW>;
+			function = LED_FUNCTION_HEARTBEAT;
+			linux,default-trigger = "heartbeat";
+		};
+
+		/* eMMC_LED */
+		user_led2: led-2 {
+			label = "yellow:user2";
+			gpios = <&gpg2 3 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_YELLOW>;
+			linux,default-trigger = "mmc0";
+		};
+
+		/* SD_LED */
+		user_led3: led-3 {
+			label = "white:user3";
+			gpios = <&gpg2 4 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_WHITE>;
+			function = LED_FUNCTION_SD;
+			linux,default-trigger = "mmc2";
+		};
+
+		/* WIFI_LED */
+		wlan_active_led: led-4 {
+			label = "yellow:wlan";
+			gpios = <&gpg2 6 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_YELLOW>;
+			function = LED_FUNCTION_WLAN;
+			linux,default-trigger = "phy0tx";
+			default-state = "off";
+		};
+
+		/* BLUETOOTH_LED */
+		bt_active_led: led-5 {
+			label = "blue:bt";
+			gpios = <&gpg2 7 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_BLUE>;
+			function = LED_FUNCTION_BLUETOOTH;
+			linux,default-trigger = "hci0-power";
+			default-state = "off";
+		};
+	};
+
+	/* TODO: Remove this once PMIC is implemented  */
+	reg_dummy: regulator-0 {
+		compatible = "regulator-fixed";
+		regulator-name = "dummy_reg";
+	};
+
+	reg_usb_host_vbus: regulator-1 {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_host_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpa3 5 GPIO_ACTIVE_LOW>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+
+		ramoops@f0000000 {
+			compatible = "ramoops";
+			reg = <0x0 0xf0000000 0x200000>;
+			record-size = <0x20000>;
+			console-size = <0x20000>;
+			ftrace-size = <0x100000>;
+			pmsg-size = <0x20000>;
+		};
+	};
+
+	/*
+	 * RTC clock (XrtcXTI); external, must be 32.768 kHz.
+	 *
+	 * TODO: Remove this once RTC clock is implemented properly as part of
+	 *       PMIC driver.
+	 */
+	rtcclk: clock-rtcclk {
+		compatible = "fixed-clock";
+		clock-output-names = "rtcclk";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+};
+
+&cmu_hsi {
+	clocks = <&oscclk>, <&rtcclk>,
+		 <&cmu_top CLK_DOUT_HSI_BUS>,
+		 <&cmu_top CLK_DOUT_HSI_MMC_CARD>,
+		 <&cmu_top CLK_DOUT_HSI_USB20DRD>;
+	clock-names = "oscclk", "rtcclk", "dout_hsi_bus",
+		      "dout_hsi_mmc_card", "dout_hsi_usb20drd";
+};
+
+&mmc_0 {
+	status = "okay";
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	cap-mmc-highspeed;
+	non-removable;
+	mmc-hs400-enhanced-strobe;
+	card-detect-delay = <200>;
+	clock-frequency = <800000000>;
+	bus-width = <8>;
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-sdr-timing = <0 4>;
+	samsung,dw-mshc-ddr-timing = <2 4>;
+	samsung,dw-mshc-hs400-timing = <0 2>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd0_clk_pins &sd0_cmd_pins &sd0_rdqs_pins &sd0_nreset_pins
+		     &sd0_bus1_pins &sd0_bus4_pins &sd0_bus8_pins>;
+};
+
+&oscclk {
+	clock-frequency = <26000000>;
+};
+
+&pinctrl_alive {
+	key_voldown_pins: key-voldown-pins {
+		samsung,pins = "gpa1-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	key_volup_pins: key-volup-pins {
+		samsung,pins = "gpa0-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+
+	micro_usb_det_pins: micro-usb-det-pins {
+		samsung,pins = "gpa0-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+};
+
+&rtc {
+	status = "okay";
+	clocks = <&cmu_apm CLK_GOUT_RTC_PCLK>, <&rtcclk>;
+	clock-names = "rtc", "rtc_src";
+};
+
+&serial_0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+};
+
+&usbdrd {
+	status = "okay";
+	vdd10-supply = <&reg_dummy>;
+	vdd33-supply = <&reg_dummy>;
+};
+
+&usbdrd_dwc3 {
+	dr_mode = "otg";
+	usb-role-switch;
+	role-switch-default-mode = "host";
+
+	port {
+		usb1_drd_sw: endpoint {
+			remote-endpoint = <&usb_dr_connector>;
+		};
+	};
+};
+
+&usbdrd_phy {
+	status = "okay";
+};
+
+&usi_uart {
+	samsung,clkreq-on; /* needed for UART mode */
+	status = "okay";
+};
+
+&watchdog_cl0 {
+	status = "okay";
+};
+
+&watchdog_cl1 {
+	status = "okay";
+};
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 45fc6bb024b0..af00ee1db07a 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -2,7 +2,7 @@ if ARCH_EXYNOS
 
 config BOARD_COMMON
 	def_bool y
-	depends on !TARGET_SMDKV310 && !TARGET_ARNDALE
+	depends on !TARGET_SMDKV310 && !TARGET_ARNDALE && !TARGET_E850_96
 
 config SPI_BOOTING
 	bool
@@ -237,6 +237,22 @@ config  TARGET_A3Y17LTE
 endchoice
 endif
 
+if ARCH_EXYNOS9
+
+choice
+	prompt "EXYNOS9 board select"
+
+config TARGET_E850_96
+	bool "WinLink E850-96 board"
+	select ARM64
+	select CLK_EXYNOS
+	select OF_CONTROL
+	select PINCTRL
+	select PINCTRL_EXYNOS850
+
+endchoice
+endif
+
 config SYS_SOC
 	default "exynos"
 
@@ -261,5 +277,6 @@ source "board/samsung/smdk5250/Kconfig"
 source "board/samsung/smdk5420/Kconfig"
 source "board/samsung/espresso7420/Kconfig"
 source "board/samsung/axy17lte/Kconfig"
+source "board/samsung/e850-96/Kconfig"
 
 endif
diff --git a/board/samsung/e850-96/Kconfig b/board/samsung/e850-96/Kconfig
new file mode 100644
index 000000000000..f891a906959b
--- /dev/null
+++ b/board/samsung/e850-96/Kconfig
@@ -0,0 +1,16 @@
+if TARGET_E850_96
+
+config EXYNOS850
+	bool "Exynos850 SoC support"
+	default y
+
+config SYS_BOARD
+	default "e850-96"
+
+config SYS_VENDOR
+	default "samsung"
+
+config SYS_CONFIG_NAME
+	default "e850-96"
+
+endif
diff --git a/board/samsung/e850-96/MAINTAINERS b/board/samsung/e850-96/MAINTAINERS
new file mode 100644
index 000000000000..e8b9365eea85
--- /dev/null
+++ b/board/samsung/e850-96/MAINTAINERS
@@ -0,0 +1,9 @@
+WINLINK E850-96 BOARD
+M:	Sam Protsenko <semen.protsenko@linaro.org>
+S:	Maintained
+F:	arch/arm/dts/exynos850-e850-96-u-boot.dtsi
+F:	arch/arm/dts/exynos850-e850-96.dts
+F:	board/samsung/e850-96/
+F:	configs/e850-96_defconfig
+F:	doc/board/samsung/e850-96.rst
+F:	include/configs/e850-96.h
diff --git a/board/samsung/e850-96/Makefile b/board/samsung/e850-96/Makefile
new file mode 100644
index 000000000000..301c22337119
--- /dev/null
+++ b/board/samsung/e850-96/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020, Linaro Limited
+# Sam Protsenko <semen.protsenko@linaro.org>
+
+obj-y	:= e850-96.o
diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c
new file mode 100644
index 000000000000..a00d81b5d4c3
--- /dev/null
+++ b/board/samsung/e850-96/e850-96.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020, Linaro Limited
+ * Sam Protsenko <semen.protsenko@linaro.org>
+ */
+
+#include <init.h>
+
+int dram_init(void)
+{
+	return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+	return fdtdec_setup_memory_banksize();
+}
+
+int board_init(void)
+{
+	return 0;
+}
diff --git a/configs/e850-96_defconfig b/configs/e850-96_defconfig
new file mode 100644
index 000000000000..bb41635ff784
--- /dev/null
+++ b/configs/e850-96_defconfig
@@ -0,0 +1,21 @@
+CONFIG_ARM=y
+CONFIG_ARCH_CPU_INIT=y
+CONFIG_ARCH_EXYNOS=y
+CONFIG_TEXT_BASE=0xf8800000
+CONFIG_SYS_MALLOC_LEN=0x81f000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_ARCH_EXYNOS9=y
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xf8c00000
+CONFIG_DEFAULT_DEVICE_TREE="exynos850-e850-96"
+CONFIG_SYS_LOAD_ADDR=0x80000000
+# CONFIG_AUTOBOOT is not set
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_NET is not set
+CONFIG_CLK_EXYNOS850=y
+# CONFIG_MMC is not set
+CONFIG_SOC_SAMSUNG=y
+CONFIG_EXYNOS_PMU=y
+CONFIG_EXYNOS_USI=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_SYSCON=y
diff --git a/doc/board/samsung/e850-96.rst b/doc/board/samsung/e850-96.rst
new file mode 100644
index 000000000000..0cb95473e536
--- /dev/null
+++ b/doc/board/samsung/e850-96.rst
@@ -0,0 +1,87 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. sectionauthor:: Sam Protsenko <semen.protsenko@linaro.org>
+
+WinLink E850-96 board
+=====================
+
+Overview
+--------
+
+WinLink's E850-96 board [1]_ is based on Samsung Exynos850 SoC and follows
+96Boards Consumer Edition specification [2]_. That makes it possible to use
+96Boards mezzanine boards [3]_ along with it. It's an open-hardware board and
+the hardware design files [4]_ were published, along with the supported
+software [5]_ and related documentation.
+
+U-Boot can be used on E850-96 instead of the original Samsung LittleKernel based
+bootloader [6]_. Because FWBL1 [7]_ doesn't verify bootloader's signature, there
+is no need to sign a U-Boot binary. That means U-Boot binary can be flashed into
+``bootloader`` partition (instead of LittleKernel bootloader) and it will just
+work.
+
+Because BL2 bootloader already sets up DRAM and runs the final bootloader
+(U-Boot) from DRAM, there is no need in U-Boot SPL. It's enough to have only
+U-Boot proper (``u-boot.bin``).
+
+Boot Flow
+---------
+
+The boot path for Exynos850 is shown on the figure below.
+
+.. image:: img/exynos850-boot-architecture.svg
+  :alt: Exynos850 SoC boot flow
+
+Legend:
+
+* ``BL0``: Boot ROM code
+* ``BL1``: Software part of Boot ROM
+* ``EPBL``: Exynos Primary Boot Loader
+* ``BL2``: Initializes CMU and DRAM and runs the final bootloader
+* ``Bootloader``: Final bootloader (e.g. U-Boot); also called BL33 in terms of
+  ARM boot flow
+* ``EL3_MON``: EL3 monitor (trusted firmware, handles SMC calls); also called
+  BL31 in terms of ARM boot flow
+* ``LDFW``: Loadable Firmware
+
+Build Procedure
+---------------
+
+.. warning::
+  At the moment both eMMC and USB features are not enabled in U-Boot. Flashing
+  U-Boot binary **WILL** effectively brick your board. The ``dltool`` [8]_ can
+  be used then to perform USB boot and flash LittleKernel bootloader binary [7]_
+  to unbrick and revive the board. Flashing U-Boot binary might be helpful for
+  developers or anybody who want to check current state of U-Boot enablement on
+  E850-96 (which is mostly serial console and related blocks).
+
+Build U-Boot binary from source code (using AArch64 baremetal GCC toolchain):
+
+.. prompt:: bash $
+
+  export PATH=<toolchain path>/bin:$PATH
+  export CROSS_COMPILE=<toolchain prefix>
+  make e850-96_defconfig
+  make
+
+Boot E850-96 board into fastboot mode as described in board software doc [9]_,
+and flash U-Boot binary into ``bootloader`` eMMC partition:
+
+.. prompt:: bash $
+
+  fastboot flash bootloader u-boot.bin
+  fastboot reboot
+
+U-Boot will boot up to the shell.
+
+References
+----------
+
+.. [1] https://www.96boards.org/product/e850-96b/
+.. [2] https://www.96boards.org/products/ce/
+.. [3] https://www.96boards.org/products/mezzanine/
+.. [4] https://www.96boards.org/documentation/consumer/e850-96b/hardware-docs/
+.. [5] https://gitlab.com/Linaro/96boards/e850-96/
+.. [6] https://gitlab.com/Linaro/96boards/e850-96/lk
+.. [7] https://gitlab.com/Linaro/96boards/e850-96/images
+.. [8] https://gitlab.com/Linaro/96boards/e850-96/tools/dltool
+.. [9] https://gitlab.com/Linaro/96boards/e850-96/doc
diff --git a/doc/board/samsung/img/exynos850-boot-architecture.svg b/doc/board/samsung/img/exynos850-boot-architecture.svg
new file mode 100644
index 000000000000..c6e850407b4a
--- /dev/null
+++ b/doc/board/samsung/img/exynos850-boot-architecture.svg
@@ -0,0 +1,1283 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Do not edit this file with editors other than draw.io -->
+
+<svg
+   version="1.1"
+   width="611px"
+   height="327px"
+   viewBox="-0.5 -0.5 611 327"
+   content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2023-12-13T00:04:32.824Z&quot; agent=&quot;Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0&quot; etag=&quot;21pvX7xTZUZ4TDUqmo5l&quot; version=&quot;22.1.8&quot; type=&quot;device&quot;&gt;
+  &lt;diagram name=&quot;Page-1&quot; id=&quot;F-97ItDN78I3cBfC3uC2&quot;&gt;
+    &lt;mxGraphModel dx=&quot;987&quot; dy=&quot;663&quot; grid=&quot;1&quot; gridSize=&quot;10&quot; guides=&quot;1&quot; tooltips=&quot;1&quot; connect=&quot;1&quot; arrows=&quot;1&quot; fold=&quot;1&quot; page=&quot;1&quot; pageScale=&quot;1&quot; pageWidth=&quot;850&quot; pageHeight=&quot;1100&quot; math=&quot;0&quot; shadow=&quot;0&quot;&gt;
+      &lt;root&gt;
+        &lt;mxCell id=&quot;0&quot; /&gt;
+        &lt;mxCell id=&quot;1&quot; parent=&quot;0&quot; /&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-47&quot; value=&quot;Secure World&quot; style=&quot;shape=partialRectangle;whiteSpace=wrap;html=1;bottom=0;right=0;fillColor=#f8cecc;fontFamily=Helvetica;fontSize=11;strokeColor=#b85450;verticalAlign=top;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;430&quot; y=&quot;160&quot; width=&quot;140&quot; height=&quot;200&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-48&quot; value=&quot;&quot; style=&quot;shape=partialRectangle;whiteSpace=wrap;html=1;top=0;left=0;fillColor=#f8cecc;fontFamily=Helvetica;fontSize=11;strokeColor=#b85450;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;340&quot; y=&quot;360&quot; width=&quot;230&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-49&quot; value=&quot;&quot; style=&quot;shape=partialRectangle;whiteSpace=wrap;html=1;bottom=0;right=0;fillColor=#f8cecc;fontFamily=Helvetica;fontSize=11;strokeColor=#b85450;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;340&quot; y=&quot;340&quot; width=&quot;160&quot; height=&quot;80&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-50&quot; value=&quot;&quot; style=&quot;shape=partialRectangle;whiteSpace=wrap;html=1;top=0;left=0;fillColor=#f8cecc;fontFamily=Helvetica;fontSize=11;rotation=-90;strokeColor=#b85450;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;465.71&quot; y=&quot;255.7&quot; width=&quot;199.53&quot; height=&quot;9.06&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-43&quot; value=&quot;Non-Secure World&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=11;fillColor=#d5e8d4;strokeColor=#82b366;align=center;verticalAlign=top;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;340&quot; y=&quot;160&quot; width=&quot;80&quot; height=&quot;170&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-42&quot; value=&quot;&amp;lt;span style=&amp;quot;white-space: pre;&amp;quot;&amp;gt;&amp;#x9;&amp;lt;/span&amp;gt;Booting Period&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=11;align=left;verticalAlign=top;fillColor=#dae8fc;strokeColor=#6c8ebf;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;30&quot; y=&quot;270&quot; width=&quot;300&quot; height=&quot;150&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-4&quot; value=&quot;&quot; style=&quot;edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;azJPLbs4vMiacVWs4TNu-1&quot; target=&quot;azJPLbs4vMiacVWs4TNu-2&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-1&quot; value=&quot;BL0&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;40&quot; y=&quot;360&quot; width=&quot;40&quot; height=&quot;40&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-5&quot; value=&quot;&quot; style=&quot;edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;azJPLbs4vMiacVWs4TNu-2&quot; target=&quot;azJPLbs4vMiacVWs4TNu-3&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-2&quot; value=&quot;BL1&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;100&quot; y=&quot;360&quot; width=&quot;40&quot; height=&quot;40&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-9&quot; style=&quot;edgeStyle=elbowEdgeStyle;shape=connector;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;endArrow=classic;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;azJPLbs4vMiacVWs4TNu-3&quot; target=&quot;azJPLbs4vMiacVWs4TNu-6&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;&gt;
+            &lt;Array as=&quot;points&quot;&gt;
+              &lt;mxPoint x=&quot;180&quot; y=&quot;350&quot; /&gt;
+            &lt;/Array&gt;
+          &lt;/mxGeometry&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-26&quot; style=&quot;edgeStyle=elbowEdgeStyle;shape=connector;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;endArrow=classic;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;azJPLbs4vMiacVWs4TNu-3&quot; target=&quot;azJPLbs4vMiacVWs4TNu-13&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-3&quot; value=&quot;EPBL&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;160&quot; y=&quot;360&quot; width=&quot;40&quot; height=&quot;40&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-10&quot; style=&quot;edgeStyle=elbowEdgeStyle;shape=connector;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0;entryDx=0;entryDy=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;endArrow=classic;exitX=0.5;exitY=1;exitDx=0;exitDy=0;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;azJPLbs4vMiacVWs4TNu-6&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;&gt;
+            &lt;mxPoint x=&quot;270&quot; y=&quot;310&quot; as=&quot;sourcePoint&quot; /&gt;
+            &lt;mxPoint x=&quot;200&quot; y=&quot;370&quot; as=&quot;targetPoint&quot; /&gt;
+            &lt;Array as=&quot;points&quot;&gt;
+              &lt;mxPoint x=&quot;220&quot; y=&quot;340&quot; /&gt;
+            &lt;/Array&gt;
+          &lt;/mxGeometry&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-12&quot; style=&quot;edgeStyle=elbowEdgeStyle;shape=connector;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;endArrow=classic;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;azJPLbs4vMiacVWs4TNu-6&quot; target=&quot;azJPLbs4vMiacVWs4TNu-11&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-6&quot; value=&quot;BL2&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;200&quot; y=&quot;280&quot; width=&quot;40&quot; height=&quot;40&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-16&quot; style=&quot;edgeStyle=elbowEdgeStyle;shape=connector;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;endArrow=classic;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;azJPLbs4vMiacVWs4TNu-11&quot; target=&quot;azJPLbs4vMiacVWs4TNu-14&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-27&quot; style=&quot;edgeStyle=elbowEdgeStyle;shape=connector;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0;entryDx=0;entryDy=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;endArrow=classic;&quot; edge=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot;&gt;
+            &lt;mxPoint x=&quot;289.5&quot; y=&quot;320&quot; as=&quot;sourcePoint&quot; /&gt;
+            &lt;mxPoint x=&quot;289.5000000000009&quot; y=&quot;360&quot; as=&quot;targetPoint&quot; /&gt;
+          &lt;/mxGeometry&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-11&quot; value=&quot;Bootloader&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=11;fontColor=default;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;260&quot; y=&quot;280&quot; width=&quot;60&quot; height=&quot;40&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-23&quot; style=&quot;edgeStyle=elbowEdgeStyle;shape=connector;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;endArrow=classic;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;azJPLbs4vMiacVWs4TNu-13&quot; target=&quot;azJPLbs4vMiacVWs4TNu-20&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-24&quot; style=&quot;edgeStyle=elbowEdgeStyle;shape=connector;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;endArrow=classic;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;azJPLbs4vMiacVWs4TNu-13&quot; target=&quot;azJPLbs4vMiacVWs4TNu-21&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-13&quot; value=&quot;EL3_MON&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=11;fontColor=default;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;260&quot; y=&quot;360&quot; width=&quot;300&quot; height=&quot;40&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-17&quot; style=&quot;edgeStyle=elbowEdgeStyle;shape=connector;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;endArrow=classic;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;azJPLbs4vMiacVWs4TNu-14&quot; target=&quot;azJPLbs4vMiacVWs4TNu-15&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-14&quot; value=&quot;Linux&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=11;fontColor=default;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;360&quot; y=&quot;280&quot; width=&quot;40&quot; height=&quot;40&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-15&quot; value=&quot;&amp;lt;div&amp;gt;Android&amp;lt;/div&amp;gt;&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=11;fontColor=default;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;360&quot; y=&quot;200&quot; width=&quot;40&quot; height=&quot;40&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-19&quot; value=&quot;Secure App&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=11;fontColor=default;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;440&quot; y=&quot;200&quot; width=&quot;60&quot; height=&quot;40&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-22&quot; style=&quot;edgeStyle=elbowEdgeStyle;shape=connector;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;endArrow=classic;&quot; edge=&quot;1&quot; parent=&quot;1&quot; source=&quot;azJPLbs4vMiacVWs4TNu-20&quot; target=&quot;azJPLbs4vMiacVWs4TNu-19&quot;&gt;
+          &lt;mxGeometry relative=&quot;1&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-20&quot; value=&quot;Secure OS&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=11;fontColor=default;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;440&quot; y=&quot;280&quot; width=&quot;60&quot; height=&quot;40&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-21&quot; value=&quot;LDFW&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fontFamily=Helvetica;fontSize=11;fontColor=default;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;520&quot; y=&quot;280&quot; width=&quot;40&quot; height=&quot;40&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-32&quot; value=&quot;&amp;lt;div&amp;gt;iROM&amp;lt;/div&amp;gt;&quot; style=&quot;shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;fillColor=none;endSize=3;width=30;startSize=3;strokeWidth=1;targetPerimeterSpacing=0;sourcePerimeterSpacing=0;&quot; edge=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry width=&quot;100&quot; height=&quot;100&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;
+            &lt;mxPoint x=&quot;40&quot; y=&quot;460&quot; as=&quot;sourcePoint&quot; /&gt;
+            &lt;mxPoint x=&quot;80&quot; y=&quot;460&quot; as=&quot;targetPoint&quot; /&gt;
+            &lt;Array as=&quot;points&quot; /&gt;
+          &lt;/mxGeometry&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-33&quot; value=&quot;&amp;lt;div&amp;gt;iRAM&amp;lt;/div&amp;gt;&quot; style=&quot;shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;fillColor=none;endSize=6;width=30;startSize=6;strokeWidth=1;targetPerimeterSpacing=0;sourcePerimeterSpacing=0;&quot; edge=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry width=&quot;100&quot; height=&quot;100&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;
+            &lt;mxPoint x=&quot;100&quot; y=&quot;460&quot; as=&quot;sourcePoint&quot; /&gt;
+            &lt;mxPoint x=&quot;240&quot; y=&quot;460&quot; as=&quot;targetPoint&quot; /&gt;
+            &lt;Array as=&quot;points&quot; /&gt;
+          &lt;/mxGeometry&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-34&quot; value=&quot;&amp;lt;div&amp;gt;DRAM&amp;lt;/div&amp;gt;&quot; style=&quot;shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;fillColor=none;endSize=6;width=30;startSize=6;strokeWidth=1;targetPerimeterSpacing=0;sourcePerimeterSpacing=0;&quot; edge=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry width=&quot;100&quot; height=&quot;100&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;
+            &lt;mxPoint x=&quot;260&quot; y=&quot;460&quot; as=&quot;sourcePoint&quot; /&gt;
+            &lt;mxPoint x=&quot;560&quot; y=&quot;460&quot; as=&quot;targetPoint&quot; /&gt;
+            &lt;Array as=&quot;points&quot; /&gt;
+          &lt;/mxGeometry&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-35&quot; value=&quot;&quot; style=&quot;endArrow=none;dashed=1;html=1;rounded=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;shape=connector;&quot; edge=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;
+            &lt;mxPoint x=&quot;20&quot; y=&quot;260&quot; as=&quot;sourcePoint&quot; /&gt;
+            &lt;mxPoint x=&quot;610&quot; y=&quot;260&quot; as=&quot;targetPoint&quot; /&gt;
+          &lt;/mxGeometry&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-36&quot; value=&quot;&quot; style=&quot;endArrow=none;dashed=1;html=1;rounded=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;shape=connector;&quot; edge=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;
+            &lt;mxPoint x=&quot;20&quot; y=&quot;340&quot; as=&quot;sourcePoint&quot; /&gt;
+            &lt;mxPoint x=&quot;610&quot; y=&quot;340&quot; as=&quot;targetPoint&quot; /&gt;
+          &lt;/mxGeometry&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-38&quot; value=&quot;&quot; style=&quot;endArrow=none;dashed=1;html=1;rounded=0;labelBackgroundColor=default;strokeColor=default;align=center;verticalAlign=middle;fontFamily=Helvetica;fontSize=11;fontColor=default;shape=connector;&quot; edge=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry width=&quot;50&quot; height=&quot;50&quot; relative=&quot;1&quot; as=&quot;geometry&quot;&gt;
+            &lt;mxPoint x=&quot;20&quot; y=&quot;410&quot; as=&quot;sourcePoint&quot; /&gt;
+            &lt;mxPoint x=&quot;610&quot; y=&quot;410&quot; as=&quot;targetPoint&quot; /&gt;
+          &lt;/mxGeometry&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-39&quot; value=&quot;EL0&quot; style=&quot;text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=11;fontFamily=Helvetica;fontColor=default;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;570&quot; y=&quot;205&quot; width=&quot;60&quot; height=&quot;30&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-40&quot; value=&quot;EL1&quot; style=&quot;text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=11;fontFamily=Helvetica;fontColor=default;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;570&quot; y=&quot;285&quot; width=&quot;60&quot; height=&quot;30&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+        &lt;mxCell id=&quot;azJPLbs4vMiacVWs4TNu-41&quot; value=&quot;EL3&quot; style=&quot;text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=11;fontFamily=Helvetica;fontColor=default;&quot; vertex=&quot;1&quot; parent=&quot;1&quot;&gt;
+          &lt;mxGeometry x=&quot;570&quot; y=&quot;365&quot; width=&quot;60&quot; height=&quot;30&quot; as=&quot;geometry&quot; /&gt;
+        &lt;/mxCell&gt;
+      &lt;/root&gt;
+    &lt;/mxGraphModel&gt;
+  &lt;/diagram&gt;
+&lt;/mxfile&gt;
+"
+   id="svg242"
+   sodipodi:docname="Untitled Diagram.drawio(1).svg"
+   inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns:xhtml="http://www.w3.org/1999/xhtml">
+  <sodipodi:namedview
+     id="namedview244"
+     pagecolor="#ffffff"
+     bordercolor="#000000"
+     borderopacity="0.25"
+     inkscape:showpageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     inkscape:deskcolor="#d1d1d1"
+     showgrid="false"
+     inkscape:zoom="1.4211573"
+     inkscape:cx="171.69105"
+     inkscape:cy="123.84273"
+     inkscape:window-width="1916"
+     inkscape:window-height="1053"
+     inkscape:window-x="0"
+     inkscape:window-y="23"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="switch30" />
+  <defs
+     id="defs2" />
+  <g
+     id="g232">
+    <rect
+       x="410"
+       y="0"
+       width="140"
+       height="200"
+       fill="#f8cecc"
+       stroke="none"
+       pointer-events="all"
+       id="rect4" />
+    <path
+       d="M 410 0 L 550 0 M 550 200 M 410 200 L 410 0"
+       fill="none"
+       stroke="#b85450"
+       stroke-linecap="square"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path6" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g12">
+      <switch
+         id="switch10">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 7px; margin-left: 411px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Secure World</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="480"
+           y="18"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text8">Secure World</text>
+      </switch>
+    </g>
+    <rect
+       x="320"
+       y="200"
+       width="230"
+       height="60"
+       fill="#f8cecc"
+       stroke="none"
+       pointer-events="all"
+       id="rect14" />
+    <path
+       d="M 320 200 M 550 200 L 550 260 L 320 260"
+       fill="none"
+       stroke="#b85450"
+       stroke-linecap="square"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path16" />
+    <rect
+       x="320"
+       y="180"
+       width="160"
+       height="80"
+       fill="#f8cecc"
+       stroke="none"
+       pointer-events="all"
+       id="rect18" />
+    <path
+       d="M 320 180 L 480 180 M 480 260 M 320 260 L 320 180"
+       fill="none"
+       stroke="#b85450"
+       stroke-linecap="square"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path20" />
+    <rect
+       x="445.71"
+       y="95.7"
+       width="199.53"
+       height="9.06"
+       fill="#f8cecc"
+       stroke="none"
+       transform="rotate(-90,545.48,100.23)"
+       pointer-events="all"
+       id="rect22" />
+    <path
+       d="M 445.71 95.7 M 645.24 95.7 L 645.24 104.76 L 445.71 104.76"
+       fill="none"
+       stroke="#b85450"
+       stroke-linecap="square"
+       stroke-miterlimit="10"
+       transform="rotate(-90,545.48,100.23)"
+       pointer-events="all"
+       id="path24" />
+    <rect
+       x="320"
+       y="0"
+       width="80"
+       height="170"
+       fill="#d5e8d4"
+       stroke="#82b366"
+       pointer-events="all"
+       id="rect26" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g32">
+      <switch
+         id="switch30">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 7px; margin-left: 321px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Non-Secure World</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="360"
+           y="18"
+           fill="#000000"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text28"><tspan
+             sodipodi:role="line"
+             id="tspan629"
+             x="360"
+             y="18">Non-Secure</tspan><tspan
+             sodipodi:role="line"
+             id="tspan631"
+             x="360"
+             y="31.75">World</tspan></text>
+      </switch>
+    </g>
+    <rect
+       x="10"
+       y="110"
+       width="300"
+       height="150"
+       fill="#dae8fc"
+       stroke="#6c8ebf"
+       pointer-events="all"
+       id="rect34" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g40">
+      <switch
+         id="switch38">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe flex-start; justify-content: unsafe flex-start; width: 298px; height: 1px; padding-top: 117px; margin-left: 12px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: left;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><xhtml:span
+   style="white-space: pre;" />
+Booting Period</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="12"
+           y="128"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           id="text36">	Booting Period</text>
+      </switch>
+    </g>
+    <path
+       d="M 60 220 L 73.63 220"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path42" />
+    <path
+       d="M 78.88 220 L 71.88 223.5 L 73.63 220 L 71.88 216.5 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path44" />
+    <rect
+       x="20"
+       y="200"
+       width="40"
+       height="40"
+       fill="rgb(255, 255, 255)"
+       stroke="rgb(0, 0, 0)"
+       pointer-events="all"
+       id="rect46" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g52">
+      <switch
+         id="switch50">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 220px; margin-left: 21px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">BL0</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="40"
+           y="224"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="12px"
+           text-anchor="middle"
+           id="text48">BL0</text>
+      </switch>
+    </g>
+    <path
+       d="M 120 220 L 133.63 220"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path54" />
+    <path
+       d="M 138.88 220 L 131.88 223.5 L 133.63 220 L 131.88 216.5 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path56" />
+    <rect
+       x="80"
+       y="200"
+       width="40"
+       height="40"
+       fill="rgb(255, 255, 255)"
+       stroke="rgb(0, 0, 0)"
+       pointer-events="all"
+       id="rect58" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g64">
+      <switch
+         id="switch62">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 220px; margin-left: 81px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">BL1</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="100"
+           y="224"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="12px"
+           text-anchor="middle"
+           id="text60">BL1</text>
+      </switch>
+    </g>
+    <path
+       d="M 160 200 L 160 140 L 173.63 140"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path66" />
+    <path
+       d="M 178.88 140 L 171.88 143.5 L 173.63 140 L 171.88 136.5 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path68" />
+    <path
+       d="M 180 220 L 209.67 220 L 233.63 220"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path70" />
+    <path
+       d="M 238.88 220 L 231.88 223.5 L 233.63 220 L 231.88 216.5 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path72" />
+    <rect
+       x="140"
+       y="200"
+       width="40"
+       height="40"
+       fill="rgb(255, 255, 255)"
+       stroke="rgb(0, 0, 0)"
+       pointer-events="all"
+       id="rect74" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g80">
+      <switch
+         id="switch78">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 220px; margin-left: 141px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">EPBL</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="160"
+           y="224"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="12px"
+           text-anchor="middle"
+           id="text76">EPBL</text>
+      </switch>
+    </g>
+    <path
+       d="M 200 160 L 200 210 L 186.37 210"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path82" />
+    <path
+       d="M 181.12 210 L 188.12 206.5 L 186.37 210 L 188.12 213.5 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path84" />
+    <path
+       d="M 220 140 L 229.67 140 L 233.63 140"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path86" />
+    <path
+       d="M 238.88 140 L 231.88 143.5 L 233.63 140 L 231.88 136.5 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path88" />
+    <rect
+       x="180"
+       y="120"
+       width="40"
+       height="40"
+       fill="rgb(255, 255, 255)"
+       stroke="rgb(0, 0, 0)"
+       pointer-events="all"
+       id="rect90" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g96">
+      <switch
+         id="switch94">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 140px; margin-left: 181px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">BL2</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="200"
+           y="144"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="12px"
+           text-anchor="middle"
+           id="text92">BL2</text>
+      </switch>
+    </g>
+    <path
+       d="M 300 140 L 319.67 140 L 333.63 140"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path98" />
+    <path
+       d="M 338.88 140 L 331.88 143.5 L 333.63 140 L 331.88 136.5 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path100" />
+    <path
+       d="M 269.5 160 L 269.64 193.63"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path102" />
+    <path
+       d="M 269.66 198.88 L 266.13 191.9 L 269.64 193.63 L 273.13 191.87 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path104" />
+    <rect
+       x="240"
+       y="120"
+       width="60"
+       height="40"
+       fill="rgb(255, 255, 255)"
+       stroke="rgb(0, 0, 0)"
+       pointer-events="all"
+       id="rect106" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g112">
+      <switch
+         id="switch110">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 140px; margin-left: 241px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Bootloader</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="270"
+           y="143"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text108">Bootloader</text>
+      </switch>
+    </g>
+    <path
+       d="M 449.67 200 L 449.67 166.37"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path114" />
+    <path
+       d="M 449.67 161.12 L 453.17 168.12 L 449.67 166.37 L 446.17 168.12 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path116" />
+    <path
+       d="M 519.67 200 L 519.67 166.37"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path118" />
+    <path
+       d="M 519.67 161.12 L 523.17 168.12 L 519.67 166.37 L 516.17 168.12 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path120" />
+    <rect
+       x="240"
+       y="200"
+       width="300"
+       height="40"
+       fill="rgb(255, 255, 255)"
+       stroke="rgb(0, 0, 0)"
+       pointer-events="all"
+       id="rect122" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g128">
+      <switch
+         id="switch126">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 298px; height: 1px; padding-top: 220px; margin-left: 241px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">EL3_MON</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="390"
+           y="223"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text124">EL3_MON</text>
+      </switch>
+    </g>
+    <path
+       d="M 359.67 120 L 359.67 86.37"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path130" />
+    <path
+       d="M 359.67 81.12 L 363.17 88.12 L 359.67 86.37 L 356.17 88.12 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path132" />
+    <rect
+       x="340"
+       y="120"
+       width="40"
+       height="40"
+       fill="rgb(255, 255, 255)"
+       stroke="rgb(0, 0, 0)"
+       pointer-events="all"
+       id="rect134" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g140">
+      <switch
+         id="switch138">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 140px; margin-left: 341px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Linux</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="360"
+           y="143"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text136">Linux</text>
+      </switch>
+    </g>
+    <rect
+       x="340"
+       y="40"
+       width="40"
+       height="40"
+       fill="rgb(255, 255, 255)"
+       stroke="rgb(0, 0, 0)"
+       pointer-events="all"
+       id="rect142" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g148">
+      <switch
+         id="switch146">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 60px; margin-left: 341px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
+                <xhtml:div>Android</xhtml:div>
+              </xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="360"
+           y="63"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text144">Android</text>
+      </switch>
+    </g>
+    <rect
+       x="420"
+       y="40"
+       width="60"
+       height="40"
+       fill="rgb(255, 255, 255)"
+       stroke="rgb(0, 0, 0)"
+       pointer-events="all"
+       id="rect150" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g156">
+      <switch
+         id="switch154">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 60px; margin-left: 421px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Secure App</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="450"
+           y="63"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text152">Secure App</text>
+      </switch>
+    </g>
+    <path
+       d="M 449.67 120 L 449.67 86.37"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="stroke"
+       id="path158" />
+    <path
+       d="M 449.67 81.12 L 453.17 88.12 L 449.67 86.37 L 446.17 88.12 Z"
+       fill="rgb(0, 0, 0)"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path160" />
+    <rect
+       x="420"
+       y="120"
+       width="60"
+       height="40"
+       fill="rgb(255, 255, 255)"
+       stroke="rgb(0, 0, 0)"
+       pointer-events="all"
+       id="rect162" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g168">
+      <switch
+         id="switch166">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 140px; margin-left: 421px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Secure OS</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="450"
+           y="143"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text164">Secure OS</text>
+      </switch>
+    </g>
+    <rect
+       x="500"
+       y="120"
+       width="40"
+       height="40"
+       fill="rgb(255, 255, 255)"
+       stroke="rgb(0, 0, 0)"
+       pointer-events="all"
+       id="rect170" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g176">
+      <switch
+         id="switch174">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 140px; margin-left: 501px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">LDFW</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="520"
+           y="143"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text172">LDFW</text>
+      </switch>
+    </g>
+    <path
+       d="M 30.5 315 L 30.5 325.5 L 20.5 300 L 30.5 274.5 L 30.5 285 L 49.5 285 L 49.5 274.5 L 59.5 300 L 49.5 325.5 L 49.5 315 Z"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path178" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g184">
+      <switch
+         id="switch182">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 300px; margin-left: 40px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
+                <xhtml:div>iROM</xhtml:div>
+              </xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="40"
+           y="303"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text180">iROM</text>
+      </switch>
+    </g>
+    <path
+       d="M 99.5 315 L 99.5 325.5 L 80.5 300 L 99.5 274.5 L 99.5 285 L 200.5 285 L 200.5 274.5 L 219.5 300 L 200.5 325.5 L 200.5 315 Z"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path186" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g192">
+      <switch
+         id="switch190">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 300px; margin-left: 150px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
+                <xhtml:div>iRAM</xhtml:div>
+              </xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="150"
+           y="303"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text188">iRAM</text>
+      </switch>
+    </g>
+    <path
+       d="M 259.5 315 L 259.5 325.5 L 240.5 300 L 259.5 274.5 L 259.5 285 L 520.5 285 L 520.5 274.5 L 539.5 300 L 520.5 325.5 L 520.5 315 Z"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       pointer-events="all"
+       id="path194" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g200">
+      <switch
+         id="switch198">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 300px; margin-left: 390px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
+                <xhtml:div>DRAM</xhtml:div>
+              </xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="390"
+           y="303"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text196">DRAM</text>
+      </switch>
+    </g>
+    <path
+       d="M 0 100 L 590 100"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       stroke-dasharray="3 3"
+       pointer-events="stroke"
+       id="path202" />
+    <path
+       d="M 0 180 L 590 180"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       stroke-dasharray="3 3"
+       pointer-events="stroke"
+       id="path204" />
+    <path
+       d="M 0 250 L 590 250"
+       fill="none"
+       stroke="rgb(0, 0, 0)"
+       stroke-miterlimit="10"
+       stroke-dasharray="3 3"
+       pointer-events="stroke"
+       id="path206" />
+    <rect
+       x="550"
+       y="45"
+       width="60"
+       height="30"
+       fill="none"
+       stroke="none"
+       pointer-events="all"
+       id="rect208" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g214">
+      <switch
+         id="switch212">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 60px; margin-left: 551px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">EL0</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="580"
+           y="63"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text210">EL0</text>
+      </switch>
+    </g>
+    <rect
+       x="550"
+       y="125"
+       width="60"
+       height="30"
+       fill="none"
+       stroke="none"
+       pointer-events="all"
+       id="rect216" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g222">
+      <switch
+         id="switch220">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 140px; margin-left: 551px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">EL1</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="580"
+           y="143"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text218">EL1</text>
+      </switch>
+    </g>
+    <rect
+       x="550"
+       y="205"
+       width="60"
+       height="30"
+       fill="none"
+       stroke="none"
+       pointer-events="all"
+       id="rect224" />
+    <g
+       transform="translate(-0.5 -0.5)"
+       id="g230">
+      <switch
+         id="switch228">
+        <foreignObject
+           style="overflow: visible; text-align: left;"
+           pointer-events="none"
+           width="100%"
+           height="100%"
+           requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
+          <xhtml:div
+             style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 220px; margin-left: 551px;">
+            <xhtml:div
+               style="box-sizing: border-box; font-size: 0px; text-align: center;"
+               data-drawio-colors="color: rgb(0, 0, 0); ">
+              <xhtml:div
+                 style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">EL3</xhtml:div>
+            </xhtml:div>
+          </xhtml:div>
+        </foreignObject>
+        <text
+           x="580"
+           y="223"
+           fill="rgb(0, 0, 0)"
+           font-family="Helvetica"
+           font-size="11px"
+           text-anchor="middle"
+           id="text226">EL3</text>
+      </switch>
+    </g>
+  </g>
+  <switch
+     id="switch240">
+    <g
+       requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"
+       id="g234" />
+    <a
+       transform="translate(0,-5)"
+       xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems"
+       target="_blank"
+       id="a238">
+      <text
+         text-anchor="middle"
+         font-size="10px"
+         x="50%"
+         y="100%"
+         id="text236">Text is not SVG - cannot display</text>
+    </a>
+  </switch>
+</svg>
diff --git a/doc/board/samsung/index.rst b/doc/board/samsung/index.rst
index 971805e20169..a1c9636b0507 100644
--- a/doc/board/samsung/index.rst
+++ b/doc/board/samsung/index.rst
@@ -7,3 +7,4 @@ Samsung
    :maxdepth: 2
 
    axy17lte
+   e850-96
diff --git a/include/configs/e850-96.h b/include/configs/e850-96.h
new file mode 100644
index 000000000000..4607b3089b21
--- /dev/null
+++ b/include/configs/e850-96.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020, Linaro Limited
+ * Sam Protsenko <semen.protsenko@linaro.org>
+ *
+ * Configuration for E850-96 board.
+ */
+
+#ifndef __E850_96_H
+#define __E850_96_H
+
+#endif /* __E850_96_H */
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 13/13] MAINTAINERS: Add new Samsung subsystems
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
                   ` (11 preceding siblings ...)
  2023-12-13  3:16 ` [PATCH 12/13] board: samsung: Add support for E850-96 board Sam Protsenko
@ 2023-12-13  3:16 ` Sam Protsenko
  2023-12-18 15:31 ` [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
  13 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2023-12-13  3:16 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson
  Cc: Simon Glass, Heinrich Schuchardt, u-boot

Add next Samsung subsystems with Sam Protsenko as a maintainer:

- Samsung CCF Clock Framework
- Exynos850 SoC Support
- Samsung SoC Drivers

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
---
 MAINTAINERS | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9f74c0aacaac..3efb3df99d89 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -560,6 +560,31 @@ F:	arch/arm/mach-exynos/
 F:	arch/arm/mach-s5pc1xx/
 F:	arch/arm/cpu/armv7/s5p-common/
 
+ARM SAMSUNG CLOCK
+M:	Sam Protsenko <semen.protsenko@linaro.org>
+S:	Maintained
+F:	drivers/clk/exynos/clk-pll.c
+F:	drivers/clk/exynos/clk-pll.h
+F:	drivers/clk/exynos/clk.c
+F:	drivers/clk/exynos/clk.h
+
+ARM SAMSUNG EXYNOS850 SOC
+M:	Sam Protsenko <semen.protsenko@linaro.org>
+S:	Maintained
+F:	arch/arm/dts/exynos850-pinctrl.dtsi
+F:	arch/arm/dts/exynos850.dtsi
+F:	doc/device-tree-bindings/clock/samsung,exynos850-clock.yaml
+F:	drivers/clk/exynos/clk-exynos850.c
+F:	drivers/pinctrl/exynos/pinctrl-exynos850.c
+F:	include/dt-bindings/clock/exynos850.h
+
+ARM SAMSUNG SOC DRIVERS
+M:	Sam Protsenko <semen.protsenko@linaro.org>
+S:	Maintained
+F:	doc/device-tree-bindings/soc/samsung/*
+F:	drivers/soc/samsung/*
+F:	include/dt-bindings/soc/samsung,*.h
+
 ARM SANCLOUD
 M:	Paul Barker <paul.barker@sancloud.com>
 R:	Marc Murphy <marc.murphy@sancloud.com>
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH 00/13] arm: exynos: Add E850-96 board
  2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
                   ` (12 preceding siblings ...)
  2023-12-13  3:16 ` [PATCH 13/13] MAINTAINERS: Add new Samsung subsystems Sam Protsenko
@ 2023-12-18 15:31 ` Sam Protsenko
  2023-12-22  7:34   ` Minkyu Kang
  13 siblings, 1 reply; 30+ messages in thread
From: Sam Protsenko @ 2023-12-18 15:31 UTC (permalink / raw)
  To: Minkyu Kang, Tom Rini
  Cc: Simon Glass, Heinrich Schuchardt, u-boot, Lukasz Majewski,
	Sean Anderson

On Tue, Dec 12, 2023 at 9:16 PM Sam Protsenko
<semen.protsenko@linaro.org> wrote:
>
> NOTE: This patch series depends on "pinctrl: exynos: Prepare for other
> SoCs support" series [1]. It should be applied first.
>
> Add Exynos850 SoC and WinLink's E850-96 board support. A short overview
> of series additions and modifications:
>   * USI driver: configures UART block
>   * PMU driver: connects AP UART lines to uart1 pins)
>   * Exynos850 clock driver: generates UART clocks
>   * Exynos850 pinctrl driver: mux UART pins
>   * serial_s5p: UART driver
>   * Exynos850 SoC: dtsi files and MMU maps
>   * E850-96 board: dts files, defconfig, board file and doc
>
> Most of the code was borrowed from mainline Linux kernel (where this
> board is already enabled) and adapted for U-Boot. Preliminary
> preparation for this series includes next patches / series (already
> merged):
>
>   * commit 585a2aaac2ac ("arm: exynos: Include missing CPU header in
>                           soc.c")
>   * commit c9ab9f30c8e4 ("arm: exynos: Include missing CPU header in
>                           gpio.h")
>   * commit 11bd2787deff ("watchdog: s5p_wdt: Include missing CPU
>                           header")
>   * commit 08cfa971a717 ("exynos: Avoid duplicate reset_cpu with
>                           SYSRESET enabled")
>   * commit f655090901dc ("clk: exynos: Add header guard for clk-pll.h")
>   * commit 2227f4c0afed ("serial: s5p: Fix clk_get_by_index() error code
>                           check")
>   * commit a0615ffc99a5 ("serial: s5p: Remove common.h inclusion")
>   * commit 5ad21de6bae0 ("serial: s5p: Use livetree API to get "id"
>                           property")
>   * commit e79f630dbf67 ("serial: s5p: Use named constants for register
>                           values")
>   * commit a627f2802a71 ("serial: s5p: Improve coding style")
>   * commit 33e7ca5a9b6a ("serial: s5p: Use dev_read_addr_ptr() to get
>                           base address")
>   * commit 6219b47c4d91 ("board: samsung: Fix SYS_CONFIG_NAME configs in
>                           axy17lte Kconfig")
>   * commit 470682ace1e0 ("configs: Remove unneeded SYS_CONFIG_NAME from
>                           a*y17lte defconfigs")
>
> and series [1] (dependency) is still pending.
>
> For more detailed description please see the board documentation (added
> in PATCH #12) and corresponding commit messages.
>
> [1] https://lists.denx.de/pipermail/u-boot/2023-November/539033.html
>
> Sam Protsenko (13):
>   dt-bindings: soc: samsung: Add Exynos USI
>   dt-bindings: soc: samsung: Add Exynos PMU
>   dt-bindings: clock: Add Exynos850 clock controller
>   soc: samsung: Add Exynos USI driver
>   soc: samsung: Add Exynos PMU driver
>   clk: exynos: Move pll code into clk-exynos7420
>   clk: exynos: Add Samsung clock framework
>   clk: exynos: Add Exynos850 clock driver
>   pinctrl: exynos: Add pinctrl support for Exynos850
>   serial: s5p: Add Exynos850 compatible
>   arm: exynos: Add Exynos850 SoC support
>   board: samsung: Add support for E850-96 board
>   MAINTAINERS: Add new Samsung subsystems
>
>  MAINTAINERS                                   |   25 +
>  arch/arm/dts/Makefile                         |    1 +
>  arch/arm/dts/exynos-pinctrl.h                 |   79 +
>  arch/arm/dts/exynos850-e850-96-u-boot.dtsi    |   37 +
>  arch/arm/dts/exynos850-e850-96.dts            |  273 ++++
>  arch/arm/dts/exynos850-pinctrl.dtsi           |  663 +++++++++
>  arch/arm/dts/exynos850.dtsi                   |  809 +++++++++++
>  arch/arm/mach-exynos/Kconfig                  |   28 +-
>  arch/arm/mach-exynos/mmu-arm64.c              |   34 +
>  board/samsung/e850-96/Kconfig                 |   16 +
>  board/samsung/e850-96/MAINTAINERS             |    9 +
>  board/samsung/e850-96/Makefile                |    6 +
>  board/samsung/e850-96/e850-96.c               |   22 +
>  configs/e850-96_defconfig                     |   21 +
>  doc/board/samsung/e850-96.rst                 |   87 ++
>  .../img/exynos850-boot-architecture.svg       | 1283 +++++++++++++++++
>  doc/board/samsung/index.rst                   |    1 +
>  .../clock/samsung,exynos850-clock.yaml        |  307 ++++
>  .../soc/samsung/exynos-pmu.yaml               |   85 ++
>  .../soc/samsung/exynos-usi.yaml               |  162 +++
>  drivers/clk/exynos/Kconfig                    |    7 +
>  drivers/clk/exynos/Makefile                   |   11 +-
>  drivers/clk/exynos/clk-exynos7420.c           |   25 +-
>  drivers/clk/exynos/clk-exynos850.c            |  189 +++
>  drivers/clk/exynos/clk-pll.c                  |  167 ++-
>  drivers/clk/exynos/clk-pll.h                  |   16 +-
>  drivers/clk/exynos/clk.c                      |  121 ++
>  drivers/clk/exynos/clk.h                      |  228 +++
>  drivers/pinctrl/exynos/Kconfig                |    8 +
>  drivers/pinctrl/exynos/Makefile               |    1 +
>  drivers/pinctrl/exynos/pinctrl-exynos850.c    |  125 ++
>  drivers/serial/serial_s5p.c                   |    1 +
>  drivers/soc/Kconfig                           |    1 +
>  drivers/soc/Makefile                          |    1 +
>  drivers/soc/samsung/Kconfig                   |   33 +
>  drivers/soc/samsung/Makefile                  |    4 +
>  drivers/soc/samsung/exynos-pmu.c              |  102 ++
>  drivers/soc/samsung/exynos-usi.c              |  218 +++
>  include/configs/e850-96.h                     |   12 +
>  include/dt-bindings/clock/exynos850.h         |  337 +++++
>  include/dt-bindings/soc/samsung,exynos-usi.h  |   17 +
>  41 files changed, 5548 insertions(+), 24 deletions(-)
>  create mode 100644 arch/arm/dts/exynos-pinctrl.h
>  create mode 100644 arch/arm/dts/exynos850-e850-96-u-boot.dtsi
>  create mode 100644 arch/arm/dts/exynos850-e850-96.dts
>  create mode 100644 arch/arm/dts/exynos850-pinctrl.dtsi
>  create mode 100644 arch/arm/dts/exynos850.dtsi
>  create mode 100644 board/samsung/e850-96/Kconfig
>  create mode 100644 board/samsung/e850-96/MAINTAINERS
>  create mode 100644 board/samsung/e850-96/Makefile
>  create mode 100644 board/samsung/e850-96/e850-96.c
>  create mode 100644 configs/e850-96_defconfig
>  create mode 100644 doc/board/samsung/e850-96.rst
>  create mode 100644 doc/board/samsung/img/exynos850-boot-architecture.svg
>  create mode 100644 doc/device-tree-bindings/clock/samsung,exynos850-clock.yaml
>  create mode 100644 doc/device-tree-bindings/soc/samsung/exynos-pmu.yaml
>  create mode 100644 doc/device-tree-bindings/soc/samsung/exynos-usi.yaml
>  create mode 100644 drivers/clk/exynos/clk-exynos850.c
>  create mode 100644 drivers/clk/exynos/clk.c
>  create mode 100644 drivers/clk/exynos/clk.h
>  create mode 100644 drivers/pinctrl/exynos/pinctrl-exynos850.c
>  create mode 100644 drivers/soc/samsung/Kconfig
>  create mode 100644 drivers/soc/samsung/Makefile
>  create mode 100644 drivers/soc/samsung/exynos-pmu.c
>  create mode 100644 drivers/soc/samsung/exynos-usi.c
>  create mode 100644 include/configs/e850-96.h
>  create mode 100644 include/dt-bindings/clock/exynos850.h
>  create mode 100644 include/dt-bindings/soc/samsung,exynos-usi.h
>
> --

Hi Tom, Minkyu,

Would really appreciate a review for this series. It's not only adding
a new board, but also a bunch of stuff that I think can be useful for
other modern Exynos platforms (CCF Samsung clock framework, USI
driver, etc).

Thanks!

> 2.39.2
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [PATCH 09/13] pinctrl: exynos: Add pinctrl support for Exynos850
  2023-12-13  3:16 ` [PATCH 09/13] pinctrl: exynos: Add pinctrl support for Exynos850 Sam Protsenko
@ 2023-12-19 11:32   ` Chanho Park
  2024-01-10 23:48     ` Sam Protsenko
  0 siblings, 1 reply; 30+ messages in thread
From: Chanho Park @ 2023-12-19 11:32 UTC (permalink / raw)
  To: 'Sam Protsenko', 'Minkyu Kang',
	'Tom Rini', 'Lukasz Majewski',
	'Sean Anderson'
  Cc: 'Simon Glass', 'Heinrich Schuchardt', u-boot

> -----Original Message-----
> From: U-Boot <u-boot-bounces@lists.denx.de> On Behalf Of Sam Protsenko
> Sent: Wednesday, December 13, 2023 12:17 PM
> To: Minkyu Kang <mk7.kang@samsung.com>; Tom Rini <trini@konsulko.com>;
> Lukasz Majewski <lukma@denx.de>; Sean Anderson <seanga2@gmail.com>
> Cc: Simon Glass <sjg@chromium.org>; Heinrich Schuchardt
> <xypron.glpk@gmx.de>; u-boot@lists.denx.de
> Subject: [PATCH 09/13] pinctrl: exynos: Add pinctrl support for Exynos850
> 
> Add pinctrl support for Exynos850 SoC. It was mostly extracted from
> corresponding Linux kernel code [1]. Power down modes and external
> interrupt data were removed while converting the code for U-Boot, but
> everything else was kept almost unchanged.
> 
> [1] drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/pinctrl/exynos/Kconfig             |   8 ++
>  drivers/pinctrl/exynos/Makefile            |   1 +
>  drivers/pinctrl/exynos/pinctrl-exynos850.c | 125 +++++++++++++++++++++
>  3 files changed, 134 insertions(+)
>  create mode 100644 drivers/pinctrl/exynos/pinctrl-exynos850.c
> 
> diff --git a/drivers/pinctrl/exynos/Kconfig
> b/drivers/pinctrl/exynos/Kconfig
> index a60f49869b45..1b7fb62bc4ba 100644
> --- a/drivers/pinctrl/exynos/Kconfig
> +++ b/drivers/pinctrl/exynos/Kconfig
> @@ -16,3 +16,11 @@ config PINCTRL_EXYNOS78x0
>  	help
>  	  Support pin multiplexing and pin configuration control on
>  	  Samsung's Exynos78x0 SoC.
> +
> +config PINCTRL_EXYNOS850
> +	bool "Samsung Exynos850 pinctrl driver"
> +	depends on ARCH_EXYNOS && PINCTRL_FULL
> +	select PINCTRL_EXYNOS
> +	help
> +	  Support pin multiplexing and pin configuration control on
> +	  Samsung's Exynos850 SoC.
> diff --git a/drivers/pinctrl/exynos/Makefile
> b/drivers/pinctrl/exynos/Makefile
> index 07db970ca942..3abe1226eb74 100644
> --- a/drivers/pinctrl/exynos/Makefile
> +++ b/drivers/pinctrl/exynos/Makefile
> @@ -6,3 +6,4 @@
>  obj-$(CONFIG_PINCTRL_EXYNOS)		+= pinctrl-exynos.o
>  obj-$(CONFIG_PINCTRL_EXYNOS7420)	+= pinctrl-exynos7420.o
>  obj-$(CONFIG_PINCTRL_EXYNOS78x0)	+= pinctrl-exynos78x0.o
> +obj-$(CONFIG_PINCTRL_EXYNOS850)		+= pinctrl-exynos850.o
> diff --git a/drivers/pinctrl/exynos/pinctrl-exynos850.c
> b/drivers/pinctrl/exynos/pinctrl-exynos850.c
> new file mode 100644
> index 000000000000..2445dd752ea8
> --- /dev/null
> +++ b/drivers/pinctrl/exynos/pinctrl-exynos850.c
> @@ -0,0 +1,125 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023 Linaro Ltd.
> + * Author: Sam Protsenko <semen.protsenko@linaro.org>
> + *
> + * Samsung Exynos USI driver (Universal Serial Interface).

Typo. It should be a subject for the pinctrl driver.

Otherwise,
Reviewed-by: Chanho Park <chanho61.park@samsung.com>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [PATCH 08/13] clk: exynos: Add Exynos850 clock driver
  2023-12-13  3:16 ` [PATCH 08/13] clk: exynos: Add Exynos850 clock driver Sam Protsenko
@ 2023-12-19 11:33   ` Chanho Park
  0 siblings, 0 replies; 30+ messages in thread
From: Chanho Park @ 2023-12-19 11:33 UTC (permalink / raw)
  To: 'Sam Protsenko', 'Minkyu Kang',
	'Tom Rini', 'Lukasz Majewski',
	'Sean Anderson'
  Cc: 'Simon Glass', 'Heinrich Schuchardt', u-boot

> -----Original Message-----
> From: U-Boot <u-boot-bounces@lists.denx.de> On Behalf Of Sam Protsenko
> Sent: Wednesday, December 13, 2023 12:17 PM
> To: Minkyu Kang <mk7.kang@samsung.com>; Tom Rini <trini@konsulko.com>;
> Lukasz Majewski <lukma@denx.de>; Sean Anderson <seanga2@gmail.com>
> Cc: Simon Glass <sjg@chromium.org>; Heinrich Schuchardt
> <xypron.glpk@gmx.de>; u-boot@lists.denx.de
> Subject: [PATCH 08/13] clk: exynos: Add Exynos850 clock driver
> 
> Heavily influenced by its Linux kernel counterpart. It's implemented on
> top of recently added Samsung CCF clock framework API. For now only UART
> leaf clocks are implemented, along with all preceding clocks in CMU_TOP
> and CMU_PERI. The UART baud clock is required in the serial driver, to
> get its rate for the consequent baud rate calculation.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>

Reviewed-by: Chanho Park <chanho61.park@samsung.com>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [PATCH 07/13] clk: exynos: Add Samsung clock framework
  2023-12-13  3:16 ` [PATCH 07/13] clk: exynos: Add Samsung clock framework Sam Protsenko
@ 2023-12-19 11:38   ` Chanho Park
  2024-01-11  2:40     ` Sam Protsenko
  2023-12-27  9:11   ` Minkyu Kang
  1 sibling, 1 reply; 30+ messages in thread
From: Chanho Park @ 2023-12-19 11:38 UTC (permalink / raw)
  To: 'Sam Protsenko', 'Minkyu Kang',
	'Tom Rini', 'Lukasz Majewski',
	'Sean Anderson'
  Cc: 'Simon Glass', 'Heinrich Schuchardt', u-boot

> -----Original Message-----
> From: U-Boot <u-boot-bounces@lists.denx.de> On Behalf Of Sam Protsenko
> Sent: Wednesday, December 13, 2023 12:17 PM
> To: Minkyu Kang <mk7.kang@samsung.com>; Tom Rini <trini@konsulko.com>;
> Lukasz Majewski <lukma@denx.de>; Sean Anderson <seanga2@gmail.com>
> Cc: Simon Glass <sjg@chromium.org>; Heinrich Schuchardt
> <xypron.glpk@gmx.de>; u-boot@lists.denx.de
> Subject: [PATCH 07/13] clk: exynos: Add Samsung clock framework
> 
> Heavily based on Linux kernel Samsung clock framework, with some changes
> to accommodate the differences in U-Boot CCF implementation. It's also
> quite minimal as compared to the Linux version.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/clk/exynos/Makefile  |   9 +-
>  drivers/clk/exynos/clk-pll.c | 167 +++++++++++++++++++++++++
>  drivers/clk/exynos/clk-pll.h |  23 ++++
>  drivers/clk/exynos/clk.c     | 121 +++++++++++++++++++
>  drivers/clk/exynos/clk.h     | 228 +++++++++++++++++++++++++++++++++++
>  5 files changed, 546 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/clk/exynos/clk-pll.c
>  create mode 100644 drivers/clk/exynos/clk-pll.h
>  create mode 100644 drivers/clk/exynos/clk.c
>  create mode 100644 drivers/clk/exynos/clk.h
> 
> diff --git a/drivers/clk/exynos/Makefile b/drivers/clk/exynos/Makefile
> index 7faf238571ef..04c5b9a39e16 100644
> --- a/drivers/clk/exynos/Makefile
> +++ b/drivers/clk/exynos/Makefile
> @@ -1,6 +1,11 @@
>  # SPDX-License-Identifier: GPL-2.0+
>  #
>  # Copyright (C) 2016 Samsung Electronics
> -# Thomas Abraham <thomas.ab@samsung.com>
> +# Copyright (C) 2023 Linaro Ltd.
> +#
> +# Authors:
> +#   Thomas Abraham <thomas.ab@samsung.com>
> +#   Sam Protsenko <semen.protsenko@linaro.org>
> 
> -obj-$(CONFIG_CLK_EXYNOS7420)	+= clk-exynos7420.o
> +obj-$(CONFIG_$(SPL_TPL_)CLK_CCF)	+= clk.o clk-pll.o
> +obj-$(CONFIG_CLK_EXYNOS7420)		+= clk-exynos7420.o
> diff --git a/drivers/clk/exynos/clk-pll.c b/drivers/clk/exynos/clk-pll.c
> new file mode 100644
> index 000000000000..9e496ff83aaf
> --- /dev/null
> +++ b/drivers/clk/exynos/clk-pll.c
> @@ -0,0 +1,167 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2016 Samsung Electronics
> + * Copyright (C) 2023 Linaro Ltd.
> + *
> + * Authors:
> + *   Thomas Abraham <thomas.ab@exynos.com>

Need to correct Thomas's email to samsung.com if you want to keep his
original credit even though his e-mail was already stale since he left the
company.

> + *   Sam Protsenko <semen.protsenko@linaro.org>
> + *
> + * This file contains the utility functions to register the pll clocks.
> + */
> +
> +#include <asm/io.h>
> +#include <div64.h>
> +#include <malloc.h>
> +#include <clk-uclass.h>
> +#include <dm/device.h>
> +#include <clk.h>
> +#include "clk.h"
> +
> +#define UBOOT_DM_CLK_SAMSUNG_PLL0822X	"samsung_clk_pll0822x"
> +#define UBOOT_DM_CLK_SAMSUNG_PLL0831X	"samsung_clk_pll0831x"
> +
> +struct samsung_clk_pll {
> +	struct clk		clk;
> +	void __iomem		*con_reg;
> +	enum samsung_pll_type	type;
> +};
> +
> +#define to_clk_pll(_clk) container_of(_clk, struct samsung_clk_pll, clk)
> +
> +/*
> + * PLL0822x Clock Type
> + */
> +
> +#define PLL0822X_MDIV_MASK		0x3ff
> +#define PLL0822X_PDIV_MASK		0x3f
> +#define PLL0822X_SDIV_MASK		0x7
> +#define PLL0822X_MDIV_SHIFT		16
> +#define PLL0822X_PDIV_SHIFT		8
> +#define PLL0822X_SDIV_SHIFT		0
> +
> +static unsigned long samsung_pll0822x_recalc_rate(struct clk *clk)
> +{
> +	struct samsung_clk_pll *pll = to_clk_pll(clk);
> +	u32 mdiv, pdiv, sdiv, pll_con3;
> +	u64 fvco = clk_get_parent_rate(clk);
> +
> +	pll_con3 = readl_relaxed(pll->con_reg);
> +	mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
> +	pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
> +	sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
> +
> +	fvco *= mdiv;
> +	do_div(fvco, (pdiv << sdiv));
> +	return (unsigned long)fvco;
> +}
> +
> +static const struct clk_ops samsung_pll0822x_clk_min_ops = {
> +	.get_rate = samsung_pll0822x_recalc_rate,
> +};
> +
> +/*
> + * PLL0831x Clock Type
> + */
> +
> +#define PLL0831X_KDIV_MASK		0xffff
> +#define PLL0831X_MDIV_MASK		0x1ff
> +#define PLL0831X_PDIV_MASK		0x3f
> +#define PLL0831X_SDIV_MASK		0x7
> +#define PLL0831X_MDIV_SHIFT		16
> +#define PLL0831X_PDIV_SHIFT		8
> +#define PLL0831X_SDIV_SHIFT		0
> +#define PLL0831X_KDIV_SHIFT		0
> +
> +static unsigned long samsung_pll0831x_recalc_rate(struct clk *clk)
> +{
> +	struct samsung_clk_pll *pll = to_clk_pll(clk);
> +	u32 mdiv, pdiv, sdiv, pll_con3, pll_con5;
> +	s16 kdiv;
> +	u64 fvco = clk_get_parent_rate(clk);
> +
> +	pll_con3 = readl_relaxed(pll->con_reg);
> +	pll_con5 = readl_relaxed(pll->con_reg + 8);
> +	mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK;
> +	pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK;
> +	sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK;
> +	kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) &
> PLL0831X_KDIV_MASK);
> +
> +	fvco *= (mdiv << 16) + kdiv;
> +	do_div(fvco, (pdiv << sdiv));
> +	fvco >>= 16;
> +
> +	return (unsigned long)fvco;
> +}
> +
> +static const struct clk_ops samsung_pll0831x_clk_min_ops = {
> +	.get_rate = samsung_pll0831x_recalc_rate,
> +};
> +
> +static struct clk *_samsung_clk_register_pll(void __iomem *base,
> +					const struct samsung_pll_clock
*pll_clk)
> +{
> +	struct samsung_clk_pll *pll;
> +	struct clk *clk;
> +	const char *drv_name;
> +	int ret;
> +
> +	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> +	if (!pll)
> +		return ERR_PTR(-ENOMEM);
> +
> +	pll->con_reg = base + pll_clk->con_offset;
> +	pll->type = pll_clk->type;
> +	clk = &pll->clk;
> +	clk->flags = pll_clk->flags;
> +
> +	switch (pll_clk->type) {
> +	case pll_0822x:
> +		drv_name = UBOOT_DM_CLK_SAMSUNG_PLL0822X;
> +		break;
> +	case pll_0831x:
> +		drv_name = UBOOT_DM_CLK_SAMSUNG_PLL0831X;
> +		break;
> +	default:
> +		kfree(pll);
> +		return ERR_PTR(-ENODEV);
> +	}
> +
> +	ret = clk_register(clk, drv_name, pll_clk->name, pll_clk-
> >parent_name);
> +	if (ret) {
> +		kfree(pll);
> +		return ERR_PTR(ret);
> +	}
> +
> +	return clk;
> +}
> +
> +void samsung_clk_register_pll(void __iomem *base,
> +			      const struct samsung_pll_clock *clk_list,
> +			      unsigned int nr_clk)
> +{
> +	unsigned int cnt;
> +
> +	for (cnt = 0; cnt < nr_clk; cnt++) {
> +		struct clk *clk;
> +		const struct samsung_pll_clock *pll_clk;
> +
> +		pll_clk = &clk_list[cnt];
> +		clk = _samsung_clk_register_pll(base, pll_clk);
> +		clk_dm(pll_clk->id, clk);
> +	}
> +}
> +
> +U_BOOT_DRIVER(samsung_pll0822x_clk) = {
> +	.name	= UBOOT_DM_CLK_SAMSUNG_PLL0822X,
> +	.id	= UCLASS_CLK,
> +	.ops	= &samsung_pll0822x_clk_min_ops,
> +	.flags	= DM_FLAG_PRE_RELOC,
> +};
> +
> +U_BOOT_DRIVER(samsung_pll0831x_clk) = {
> +	.name	= UBOOT_DM_CLK_SAMSUNG_PLL0831X,
> +	.id	= UCLASS_CLK,
> +	.ops	= &samsung_pll0831x_clk_min_ops,
> +	.flags	= DM_FLAG_PRE_RELOC,
> +};
> diff --git a/drivers/clk/exynos/clk-pll.h b/drivers/clk/exynos/clk-pll.h
> new file mode 100644
> index 000000000000..3b477369aeb8
> --- /dev/null
> +++ b/drivers/clk/exynos/clk-pll.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2016 Samsung Electronics
> + * Copyright (C) 2023 Linaro Ltd.
> + *
> + * Authors:
> + *   Thomas Abraham <thomas.ab@exynos.com>

Ditto.

Othewise,
Reviewed-by: Chanho Park <chanho61.park@samsung.com>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [PATCH 05/13] soc: samsung: Add Exynos PMU driver
  2023-12-13  3:16 ` [PATCH 05/13] soc: samsung: Add Exynos PMU driver Sam Protsenko
@ 2023-12-19 11:39   ` Chanho Park
  0 siblings, 0 replies; 30+ messages in thread
From: Chanho Park @ 2023-12-19 11:39 UTC (permalink / raw)
  To: 'Sam Protsenko', 'Minkyu Kang',
	'Tom Rini', 'Lukasz Majewski',
	'Sean Anderson'
  Cc: 'Simon Glass', 'Heinrich Schuchardt', u-boot

> -----Original Message-----
> From: U-Boot <u-boot-bounces@lists.denx.de> On Behalf Of Sam Protsenko
> Sent: Wednesday, December 13, 2023 12:17 PM
> To: Minkyu Kang <mk7.kang@samsung.com>; Tom Rini <trini@konsulko.com>;
> Lukasz Majewski <lukma@denx.de>; Sean Anderson <seanga2@gmail.com>
> Cc: Simon Glass <sjg@chromium.org>; Heinrich Schuchardt
> <xypron.glpk@gmx.de>; u-boot@lists.denx.de
> Subject: [PATCH 05/13] soc: samsung: Add Exynos PMU driver
> 
> Add basic Power Management Unit (PMU) driver for Exynos SoCs. For now
> it's only capable of changing UART path in PMU, which is needed for
> E850-96 board. The driver's structure resembles the exynos-pmu driver
> from Linux kernel, and although it's very basic and slim at the moment,
> it can be easily extended in future if the need arises.
> 
> UCLASS_NOP is used, as there are no benefits in using more elaborate
> classes like UCLASS_MISC in this case. The DM_FLAG_PROBE_AFTER_BIND flag
> is added in bind function, as the probe function must be always called
> for this driver.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>

Reviewed-by: Chanho Park <chanho61.park@samsung.com>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [PATCH 04/13] soc: samsung: Add Exynos USI driver
  2023-12-13  3:16 ` [PATCH 04/13] soc: samsung: Add Exynos USI driver Sam Protsenko
@ 2023-12-19 11:40   ` Chanho Park
  2023-12-27  9:11   ` Minkyu Kang
  2023-12-27 17:48   ` Simon Glass
  2 siblings, 0 replies; 30+ messages in thread
From: Chanho Park @ 2023-12-19 11:40 UTC (permalink / raw)
  To: 'Sam Protsenko', 'Minkyu Kang',
	'Tom Rini', 'Lukasz Majewski',
	'Sean Anderson'
  Cc: 'Simon Glass', 'Heinrich Schuchardt', u-boot

> -----Original Message-----
> From: U-Boot <u-boot-bounces@lists.denx.de> On Behalf Of Sam Protsenko
> Sent: Wednesday, December 13, 2023 12:17 PM
> To: Minkyu Kang <mk7.kang@samsung.com>; Tom Rini <trini@konsulko.com>;
> Lukasz Majewski <lukma@denx.de>; Sean Anderson <seanga2@gmail.com>
> Cc: Simon Glass <sjg@chromium.org>; Heinrich Schuchardt
> <xypron.glpk@gmx.de>; u-boot@lists.denx.de
> Subject: [PATCH 04/13] soc: samsung: Add Exynos USI driver
> 
> USIv2 IP-core is found on modern ARM64 Exynos SoCs (like Exynos850) and
> provides selectable serial protocol (one of: UART, SPI, I2C). USIv2
> registers usually reside in the same register map as a particular
> underlying protocol it implements, but have some particular offset. E.g.
> on Exynos850 the USI_UART has 0x13820000 base address, where UART
> registers have 0x00..0x40 offsets, and USI registers have 0xc0..0xdc
> offsets. Desired protocol can be chosen via SW_CONF register from System
> Register block of the same domain as USI.
> 
> Before starting to use a particular protocol, USIv2 must be configured
> properly:
>   1. Select protocol to be used via System Register
>   2. Clear "reset" flag in USI_CON
>   3. Configure HWACG behavior (e.g. for UART Rx the HWACG must be
>      disabled, so that the IP clock is not gated automatically); this is
>      done using USI_OPTION register
>   4. Keep both USI clocks (PCLK and IPCLK) running during USI registers
>      modification
> 
> This driver implements the above behavior. Of course, USIv2 driver
> should be probed before UART/I2C/SPI drivers. It can be achieved by
> embedding UART/I2C/SPI nodes inside of the USI node (in Device Tree);
> driver then walks underlying nodes and instantiates those. Driver also
> handles USI configuration on PM resume, as register contents can be lost
> during CPU suspend.
> 
> This driver is designed with different USI versions in mind. So it
> should be relatively easy to add new USI revisions to it later.
> 
> Driver's code was copied over from Linux kernel [1] and adapted
> correspondingly for U-Boot API. UCLASS_MISC is used, and although no
> misc operations are implemented, it makes it easier to probe the driver
> this way (as compared to UCLASS_NOP) and keep the code compact.
> 
> [1] drivers/soc/samsung/exynos-usi.c
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>

Reviewed-by: Chanho Park <chanho61.park@samsung.com>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* RE: [PATCH 06/13] clk: exynos: Move pll code into clk-exynos7420
  2023-12-13  3:16 ` [PATCH 06/13] clk: exynos: Move pll code into clk-exynos7420 Sam Protsenko
@ 2023-12-19 11:41   ` Chanho Park
  0 siblings, 0 replies; 30+ messages in thread
From: Chanho Park @ 2023-12-19 11:41 UTC (permalink / raw)
  To: 'Sam Protsenko', 'Minkyu Kang',
	'Tom Rini', 'Lukasz Majewski',
	'Sean Anderson'
  Cc: 'Simon Glass', 'Heinrich Schuchardt', u-boot

> -----Original Message-----
> From: U-Boot <u-boot-bounces@lists.denx.de> On Behalf Of Sam Protsenko
> Sent: Wednesday, December 13, 2023 12:17 PM
> To: Minkyu Kang <mk7.kang@samsung.com>; Tom Rini <trini@konsulko.com>;
> Lukasz Majewski <lukma@denx.de>; Sean Anderson <seanga2@gmail.com>
> Cc: Simon Glass <sjg@chromium.org>; Heinrich Schuchardt
> <xypron.glpk@gmx.de>; u-boot@lists.denx.de
> Subject: [PATCH 06/13] clk: exynos: Move pll code into clk-exynos7420
> 
> PLL utilities code is only used by clk-exynos7420 driver at the moment.
> Move it into clk-exynos7420 to make clk-pll.c file available for CCF PLL
> clocks implementation, which is coming in the next patches.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>

Reviewed-by: Chanho Park <chanho61.park@samsung.com>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 00/13] arm: exynos: Add E850-96 board
  2023-12-18 15:31 ` [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
@ 2023-12-22  7:34   ` Minkyu Kang
  0 siblings, 0 replies; 30+ messages in thread
From: Minkyu Kang @ 2023-12-22  7:34 UTC (permalink / raw)
  To: Sam Protsenko
  Cc: Heinrich Schuchardt, Lukasz Majewski, Minkyu Kang, Sean Anderson,
	Simon Glass, Tom Rini, u-boot

Hi,


2023년 12월 19일 (화) 07:07, Sam Protsenko <semen.protsenko@linaro.org>님이 작성:

> On Tue, Dec 12, 2023 at 9:16 PM Sam Protsenko
> <semen.protsenko@linaro.org> wrote:
> >
> > NOTE: This patch series depends on "pinctrl: exynos: Prepare for other
> > SoCs support" series [1]. It should be applied first.
> >
> > Add Exynos850 SoC and WinLink's E850-96 board support. A short overview
> > of series additions and modifications:
> >   * USI driver: configures UART block
> >   * PMU driver: connects AP UART lines to uart1 pins)
> >   * Exynos850 clock driver: generates UART clocks
> >   * Exynos850 pinctrl driver: mux UART pins
> >   * serial_s5p: UART driver
> >   * Exynos850 SoC: dtsi files and MMU maps
> >   * E850-96 board: dts files, defconfig, board file and doc
> >
> > Most of the code was borrowed from mainline Linux kernel (where this
> > board is already enabled) and adapted for U-Boot. Preliminary
> > preparation for this series includes next patches / series (already
> > merged):
> >
> >   * commit 585a2aaac2ac ("arm: exynos: Include missing CPU header in
> >                           soc.c")
> >   * commit c9ab9f30c8e4 ("arm: exynos: Include missing CPU header in
> >                           gpio.h")
> >   * commit 11bd2787deff ("watchdog: s5p_wdt: Include missing CPU
> >                           header")
> >   * commit 08cfa971a717 ("exynos: Avoid duplicate reset_cpu with
> >                           SYSRESET enabled")
> >   * commit f655090901dc ("clk: exynos: Add header guard for clk-pll.h")
> >   * commit 2227f4c0afed ("serial: s5p: Fix clk_get_by_index() error code
> >                           check")
> >   * commit a0615ffc99a5 ("serial: s5p: Remove common.h inclusion")
> >   * commit 5ad21de6bae0 ("serial: s5p: Use livetree API to get "id"
> >                           property")
> >   * commit e79f630dbf67 ("serial: s5p: Use named constants for register
> >                           values")
> >   * commit a627f2802a71 ("serial: s5p: Improve coding style")
> >   * commit 33e7ca5a9b6a ("serial: s5p: Use dev_read_addr_ptr() to get
> >                           base address")
> >   * commit 6219b47c4d91 ("board: samsung: Fix SYS_CONFIG_NAME configs in
> >                           axy17lte Kconfig")
> >   * commit 470682ace1e0 ("configs: Remove unneeded SYS_CONFIG_NAME from
> >                           a*y17lte defconfigs")
> >
> > and series [1] (dependency) is still pending.
> >
> > For more detailed description please see the board documentation (added
> > in PATCH #12) and corresponding commit messages.
> >
> > [1] https://lists.denx.de/pipermail/u-boot/2023-November/539033.html
> >
> > Sam Protsenko (13):
> >   dt-bindings: soc: samsung: Add Exynos USI
> >   dt-bindings: soc: samsung: Add Exynos PMU
> >   dt-bindings: clock: Add Exynos850 clock controller
> >   soc: samsung: Add Exynos USI driver
> >   soc: samsung: Add Exynos PMU driver
> >   clk: exynos: Move pll code into clk-exynos7420
> >   clk: exynos: Add Samsung clock framework
> >   clk: exynos: Add Exynos850 clock driver
> >   pinctrl: exynos: Add pinctrl support for Exynos850
> >   serial: s5p: Add Exynos850 compatible
> >   arm: exynos: Add Exynos850 SoC support
> >   board: samsung: Add support for E850-96 board
> >   MAINTAINERS: Add new Samsung subsystems
> >
> >  MAINTAINERS                                   |   25 +
> >  arch/arm/dts/Makefile                         |    1 +
> >  arch/arm/dts/exynos-pinctrl.h                 |   79 +
> >  arch/arm/dts/exynos850-e850-96-u-boot.dtsi    |   37 +
> >  arch/arm/dts/exynos850-e850-96.dts            |  273 ++++
> >  arch/arm/dts/exynos850-pinctrl.dtsi           |  663 +++++++++
> >  arch/arm/dts/exynos850.dtsi                   |  809 +++++++++++
> >  arch/arm/mach-exynos/Kconfig                  |   28 +-
> >  arch/arm/mach-exynos/mmu-arm64.c              |   34 +
> >  board/samsung/e850-96/Kconfig                 |   16 +
> >  board/samsung/e850-96/MAINTAINERS             |    9 +
> >  board/samsung/e850-96/Makefile                |    6 +
> >  board/samsung/e850-96/e850-96.c               |   22 +
> >  configs/e850-96_defconfig                     |   21 +
> >  doc/board/samsung/e850-96.rst                 |   87 ++
> >  .../img/exynos850-boot-architecture.svg       | 1283 +++++++++++++++++
> >  doc/board/samsung/index.rst                   |    1 +
> >  .../clock/samsung,exynos850-clock.yaml        |  307 ++++
> >  .../soc/samsung/exynos-pmu.yaml               |   85 ++
> >  .../soc/samsung/exynos-usi.yaml               |  162 +++
> >  drivers/clk/exynos/Kconfig                    |    7 +
> >  drivers/clk/exynos/Makefile                   |   11 +-
> >  drivers/clk/exynos/clk-exynos7420.c           |   25 +-
> >  drivers/clk/exynos/clk-exynos850.c            |  189 +++
> >  drivers/clk/exynos/clk-pll.c                  |  167 ++-
> >  drivers/clk/exynos/clk-pll.h                  |   16 +-
> >  drivers/clk/exynos/clk.c                      |  121 ++
> >  drivers/clk/exynos/clk.h                      |  228 +++
> >  drivers/pinctrl/exynos/Kconfig                |    8 +
> >  drivers/pinctrl/exynos/Makefile               |    1 +
> >  drivers/pinctrl/exynos/pinctrl-exynos850.c    |  125 ++
> >  drivers/serial/serial_s5p.c                   |    1 +
> >  drivers/soc/Kconfig                           |    1 +
> >  drivers/soc/Makefile                          |    1 +
> >  drivers/soc/samsung/Kconfig                   |   33 +
> >  drivers/soc/samsung/Makefile                  |    4 +
> >  drivers/soc/samsung/exynos-pmu.c              |  102 ++
> >  drivers/soc/samsung/exynos-usi.c              |  218 +++
> >  include/configs/e850-96.h                     |   12 +
> >  include/dt-bindings/clock/exynos850.h         |  337 +++++
> >  include/dt-bindings/soc/samsung,exynos-usi.h  |   17 +
> >  41 files changed, 5548 insertions(+), 24 deletions(-)
> >  create mode 100644 arch/arm/dts/exynos-pinctrl.h
> >  create mode 100644 arch/arm/dts/exynos850-e850-96-u-boot.dtsi
> >  create mode 100644 arch/arm/dts/exynos850-e850-96.dts
> >  create mode 100644 arch/arm/dts/exynos850-pinctrl.dtsi
> >  create mode 100644 arch/arm/dts/exynos850.dtsi
> >  create mode 100644 board/samsung/e850-96/Kconfig
> >  create mode 100644 board/samsung/e850-96/MAINTAINERS
> >  create mode 100644 board/samsung/e850-96/Makefile
> >  create mode 100644 board/samsung/e850-96/e850-96.c
> >  create mode 100644 configs/e850-96_defconfig
> >  create mode 100644 doc/board/samsung/e850-96.rst
> >  create mode 100644 doc/board/samsung/img/exynos850-boot-architecture.svg
> >  create mode 100644
> doc/device-tree-bindings/clock/samsung,exynos850-clock.yaml
> >  create mode 100644 doc/device-tree-bindings/soc/samsung/exynos-pmu.yaml
> >  create mode 100644 doc/device-tree-bindings/soc/samsung/exynos-usi.yaml
> >  create mode 100644 drivers/clk/exynos/clk-exynos850.c
> >  create mode 100644 drivers/clk/exynos/clk.c
> >  create mode 100644 drivers/clk/exynos/clk.h
> >  create mode 100644 drivers/pinctrl/exynos/pinctrl-exynos850.c
> >  create mode 100644 drivers/soc/samsung/Kconfig
> >  create mode 100644 drivers/soc/samsung/Makefile
> >  create mode 100644 drivers/soc/samsung/exynos-pmu.c
> >  create mode 100644 drivers/soc/samsung/exynos-usi.c
> >  create mode 100644 include/configs/e850-96.h
> >  create mode 100644 include/dt-bindings/clock/exynos850.h
> >  create mode 100644 include/dt-bindings/soc/samsung,exynos-usi.h
> >
> > --
>
> Hi Tom, Minkyu,
>
> Would really appreciate a review for this series. It's not only adding
> a new board, but also a bunch of stuff that I think can be useful for
> other modern Exynos platforms (CCF Samsung clock framework, USI
> driver, etc).
>
> Thanks!


I'm in middle of holiday recently, so it is difficult to review actually.
I'll check soon.

Merry christmas.

Thanks.
Minkyu Kang.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 04/13] soc: samsung: Add Exynos USI driver
  2023-12-13  3:16 ` [PATCH 04/13] soc: samsung: Add Exynos USI driver Sam Protsenko
  2023-12-19 11:40   ` Chanho Park
@ 2023-12-27  9:11   ` Minkyu Kang
  2024-01-11  1:25     ` Sam Protsenko
  2023-12-27 17:48   ` Simon Glass
  2 siblings, 1 reply; 30+ messages in thread
From: Minkyu Kang @ 2023-12-27  9:11 UTC (permalink / raw)
  To: Sam Protsenko
  Cc: Heinrich Schuchardt, Lukasz Majewski, Minkyu Kang, Sean Anderson,
	Simon Glass, Tom Rini, u-boot

Hi


2023년 12월 13일 (수) 12:42, Sam Protsenko <semen.protsenko@linaro.org>님이 작성:

> USIv2 IP-core is found on modern ARM64 Exynos SoCs (like Exynos850) and
> provides selectable serial protocol (one of: UART, SPI, I2C). USIv2
> registers usually reside in the same register map as a particular
> underlying protocol it implements, but have some particular offset. E.g.
> on Exynos850 the USI_UART has 0x13820000 base address, where UART
> registers have 0x00..0x40 offsets, and USI registers have 0xc0..0xdc
> offsets. Desired protocol can be chosen via SW_CONF register from System
> Register block of the same domain as USI.
>
> Before starting to use a particular protocol, USIv2 must be configured
> properly:
>   1. Select protocol to be used via System Register
>   2. Clear "reset" flag in USI_CON
>   3. Configure HWACG behavior (e.g. for UART Rx the HWACG must be
>      disabled, so that the IP clock is not gated automatically); this is
>      done using USI_OPTION register
>   4. Keep both USI clocks (PCLK and IPCLK) running during USI registers
>      modification
>
> This driver implements the above behavior. Of course, USIv2 driver
> should be probed before UART/I2C/SPI drivers. It can be achieved by
> embedding UART/I2C/SPI nodes inside of the USI node (in Device Tree);
> driver then walks underlying nodes and instantiates those. Driver also
> handles USI configuration on PM resume, as register contents can be lost
> during CPU suspend.
>
> This driver is designed with different USI versions in mind. So it
> should be relatively easy to add new USI revisions to it later.
>
> Driver's code was copied over from Linux kernel [1] and adapted
> correspondingly for U-Boot API. UCLASS_MISC is used, and although no
> misc operations are implemented, it makes it easier to probe the driver
> this way (as compared to UCLASS_NOP) and keep the code compact.
>
> [1] drivers/soc/samsung/exynos-usi.c
>
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/soc/Kconfig              |   1 +
>  drivers/soc/Makefile             |   1 +
>  drivers/soc/samsung/Kconfig      |  23 ++++
>  drivers/soc/samsung/Makefile     |   3 +
>  drivers/soc/samsung/exynos-usi.c | 218 +++++++++++++++++++++++++++++++
>  5 files changed, 246 insertions(+)
>  create mode 100644 drivers/soc/samsung/Kconfig
>  create mode 100644 drivers/soc/samsung/Makefile
>  create mode 100644 drivers/soc/samsung/exynos-usi.c
>
> diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
> index 85dac9de78a4..03433bc0e6d2 100644
> --- a/drivers/soc/Kconfig
> +++ b/drivers/soc/Kconfig
> @@ -40,6 +40,7 @@ config SOC_XILINX_VERSAL_NET
>           This allows other drivers to verify the SoC familiy & revision
> using
>           matching SoC attributes.
>
> +source "drivers/soc/samsung/Kconfig"
>  source "drivers/soc/ti/Kconfig"
>
>  endmenu
> diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
> index 84385650d46d..610bf816d40a 100644
> --- a/drivers/soc/Makefile
> +++ b/drivers/soc/Makefile
> @@ -2,6 +2,7 @@
>  #
>  # Makefile for the U-Boot SOC specific device drivers.
>
> +obj-$(CONFIG_SOC_SAMSUNG) += samsung/
>  obj-$(CONFIG_SOC_TI) += ti/
>  obj-$(CONFIG_SOC_DEVICE) += soc-uclass.o
>  obj-$(CONFIG_SOC_DEVICE_TI_K3) += soc_ti_k3.o
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> new file mode 100644
> index 000000000000..ffb87fe79316
> --- /dev/null
> +++ b/drivers/soc/samsung/Kconfig
> @@ -0,0 +1,23 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +
> +menuconfig SOC_SAMSUNG
> +       bool "Samsung SoC drivers support"
> +
> +if SOC_SAMSUNG
> +
> +config EXYNOS_USI
> +       bool "Exynos USI (Universal Serial Interface) driver"
> +       depends on ARCH_EXYNOS
> +       select MISC
> +       select REGMAP
> +       select SYSCON
> +       help
> +         Enable support for USI block. USI (Universal Serial Interface)
> is an
> +         IP-core found in modern Samsung Exynos SoCs, like Exynos850 and
> +         ExynosAutoV9. USI block can be configured to provide one of the
> +         following serial protocols: UART, SPI or High Speed I2C.
> +
> +         This driver allows one to configure USI for desired protocol,
> which
> +         is usually done in USI node in Device Tree.
> +
> +endif
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> new file mode 100644
> index 000000000000..833ac073fbfa
> --- /dev/null
> +++ b/drivers/soc/samsung/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +
> +obj-$(CONFIG_EXYNOS_USI)       += exynos-usi.o
> diff --git a/drivers/soc/samsung/exynos-usi.c
> b/drivers/soc/samsung/exynos-usi.c
> new file mode 100644
> index 000000000000..23255177e6e3
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-usi.c
> @@ -0,0 +1,218 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023 Linaro Ltd.
> + * Author: Sam Protsenko <semen.protsenko@linaro.org>
> + *
> + * Samsung Exynos USI driver (Universal Serial Interface).
> + */
> +
> +#include <dm.h>
> +#include <dm/device_compat.h>
> +#include <errno.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +#include <asm/io.h>
> +#include <linux/bitops.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +
> +#include <dt-bindings/soc/samsung,exynos-usi.h>
> +
> +/* USIv2: System Register: SW_CONF register bits */
> +#define USI_V2_SW_CONF_NONE    0x0
> +#define USI_V2_SW_CONF_UART    BIT(0)
> +#define USI_V2_SW_CONF_SPI     BIT(1)
> +#define USI_V2_SW_CONF_I2C     BIT(2)
> +#define USI_V2_SW_CONF_MASK    (USI_V2_SW_CONF_UART | USI_V2_SW_CONF_SPI
> | \
> +                                USI_V2_SW_CONF_I2C)
> +
> +/* USIv2: USI register offsets */
> +#define USI_CON                        0x04
> +#define USI_OPTION             0x08
> +
> +/* USIv2: USI register bits */
> +#define USI_CON_RESET          BIT(0)
> +#define USI_OPTION_CLKREQ_ON   BIT(1)
> +#define USI_OPTION_CLKSTOP_ON  BIT(2)
> +
> +enum exynos_usi_ver {
> +       USI_VER2 = 2,
> +};
> +
> +struct exynos_usi_variant {
> +       enum exynos_usi_ver ver;        /* USI IP-core version */
> +       unsigned int sw_conf_mask;      /* SW_CONF mask for all protocols
> */
> +       size_t min_mode;                /* first index in
> exynos_usi_modes[] */
> +       size_t max_mode;                /* last index in
> exynos_usi_modes[] */
> +};
> +
> +struct exynos_usi {
> +       struct udevice *dev;
> +       void __iomem *regs;             /* USI register map */
> +
> +       size_t mode;                    /* current USI SW_CONF mode index
> */
> +       bool clkreq_on;                 /* always provide clock to IP */
> +
> +       /* System Register */
> +       struct regmap *sysreg;          /* System Register map */
> +       unsigned int sw_conf;           /* SW_CONF register offset in
> sysreg */
> +
> +       const struct exynos_usi_variant *data;
> +};
> +
> +struct exynos_usi_mode {
> +       const char *name;               /* mode name */
> +       unsigned int val;               /* mode register value */
> +};
> +
> +static const struct exynos_usi_mode exynos_usi_modes[] = {
> +       [USI_V2_NONE] = { .name = "none", .val = USI_V2_SW_CONF_NONE },
> +       [USI_V2_UART] = { .name = "uart", .val = USI_V2_SW_CONF_UART },
> +       [USI_V2_SPI] =  { .name = "spi",  .val = USI_V2_SW_CONF_SPI },
> +       [USI_V2_I2C] =  { .name = "i2c",  .val = USI_V2_SW_CONF_I2C },
> +};
> +
> +static const struct exynos_usi_variant exynos850_usi_data = {
> +       .ver            = USI_VER2,
> +       .sw_conf_mask   = USI_V2_SW_CONF_MASK,
> +       .min_mode       = USI_V2_NONE,
> +       .max_mode       = USI_V2_I2C,
> +};
> +
> +static const struct udevice_id exynos_usi_ids[] = {
> +       {
> +               .compatible = "samsung,exynos850-usi",
> +               .data = (ulong)&exynos850_usi_data,
> +       },
> +       { } /* sentinel */
> +};
> +
> +/**
> + * exynos_usi_set_sw_conf - Set USI block configuration mode
> + * @usi: USI driver object
> + * @mode: Mode index
> + *
> + * Select underlying serial protocol (UART/SPI/I2C) in USI IP-core.
> + *
> + * Return: 0 on success, or negative error code on failure.
> + */
> +static int exynos_usi_set_sw_conf(struct exynos_usi *usi, size_t mode)


The value of mode is same as usi->mode, but is there a reason to pass it as
a parameter?


> +{
> +       unsigned int val;
> +       int ret;
> +
> +       if (mode < usi->data->min_mode || mode > usi->data->max_mode)
> +               return -EINVAL;
> +
> +       val = exynos_usi_modes[mode].val;
> +       ret = regmap_update_bits(usi->sysreg, usi->sw_conf,
> +                                usi->data->sw_conf_mask, val);
> +       if (ret)
> +               return ret;
> +
> +       usi->mode = mode;


This will obviously be the same value always.


> +       dev_dbg(usi->dev, "protocol: %s\n",
> exynos_usi_modes[usi->mode].name);
> +
> +       return 0;
> +}
> +
> +/**
> + * exynos_usi_enable - Initialize USI block
> + * @usi: USI driver object
> + *
> + * USI IP-core start state is "reset" (on startup and after CPU resume).
> This
> + * routine enables the USI block by clearing the reset flag. It also
> configures
> + * HWACG behavior (needed e.g. for UART Rx). It should be performed before
> + * underlying protocol becomes functional.
> + */
> +static void exynos_usi_enable(const struct exynos_usi *usi)
> +{
> +       u32 val;
> +
> +       /* Enable USI block */
> +       val = readl(usi->regs + USI_CON);
> +       val &= ~USI_CON_RESET;
> +       writel(val, usi->regs + USI_CON);
> +       udelay(1);
> +
> +       /* Continuously provide the clock to USI IP w/o gating */
> +       if (usi->clkreq_on) {
> +               val = readl(usi->regs + USI_OPTION);
> +               val &= ~USI_OPTION_CLKSTOP_ON;
> +               val |= USI_OPTION_CLKREQ_ON;
> +               writel(val, usi->regs + USI_OPTION);
> +       }
> +}
> +
> +static int exynos_usi_configure(struct exynos_usi *usi)
> +{
> +       int ret;
> +
> +       ret = exynos_usi_set_sw_conf(usi, usi->mode);
> +       if (ret)
> +               return ret;
> +
> +       if (usi->data->ver == USI_VER2)
> +               exynos_usi_enable(usi);
> +
> +       return 0;
> +}
> +
> +static int exynos_usi_parse_dt(struct exynos_usi *usi)
> +{
> +       struct udevice *dev = usi->dev;
> +       ofnode node;
> +       int ret;
> +       u32 mode;
> +
> +       node = dev_ofnode(dev);
> +
> +       ret = ofnode_read_u32(node, "samsung,mode", &mode);
> +       if (ret)
> +               return ret;
> +       if (mode < usi->data->min_mode || mode > usi->data->max_mode)
> +               return -EINVAL;
> +       usi->mode = mode;
> +
> +       usi->sysreg = syscon_regmap_lookup_by_phandle(dev,
> "samsung,sysreg");
> +       if (IS_ERR(usi->sysreg))
> +               return PTR_ERR(usi->sysreg);
> +
> +       ret = ofnode_read_u32_index(node, "samsung,sysreg", 1,
> &usi->sw_conf);
> +       if (ret)
> +               return ret;
> +
> +       usi->clkreq_on = ofnode_read_bool(node, "samsung,clkreq-on");
> +
> +       return 0;
> +}
> +
> +static int exynos_usi_probe(struct udevice *dev)
> +{
> +       struct exynos_usi *usi;
> +       int ret;
> +
> +       usi = dev_get_priv(dev);
> +       usi->dev = dev;
> +       usi->data = (struct exynos_usi_variant *)dev_get_driver_data(dev);
> +
> +       ret = exynos_usi_parse_dt(usi);
> +       if (ret)
> +               return ret;
> +
> +       if (usi->data->ver == USI_VER2) {
> +               usi->regs = dev_read_addr_ptr(dev);
> +               if (!usi->regs)
> +                       return -ENODEV;
> +       }
> +
> +       return exynos_usi_configure(usi);
> +}
> +
> +U_BOOT_DRIVER(exynos_usi) = {
> +       .name           = "exynos-usi",
> +       .id             = UCLASS_MISC,
> +       .of_match       = exynos_usi_ids,
> +       .probe          = exynos_usi_probe,
> +       .priv_auto      = sizeof(struct exynos_usi),
> +};
> --
> 2.39.2
>

Thanks.
Minkyu Kang.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 07/13] clk: exynos: Add Samsung clock framework
  2023-12-13  3:16 ` [PATCH 07/13] clk: exynos: Add Samsung clock framework Sam Protsenko
  2023-12-19 11:38   ` Chanho Park
@ 2023-12-27  9:11   ` Minkyu Kang
  2024-01-11  1:15     ` Sam Protsenko
  1 sibling, 1 reply; 30+ messages in thread
From: Minkyu Kang @ 2023-12-27  9:11 UTC (permalink / raw)
  To: Sam Protsenko
  Cc: Heinrich Schuchardt, Lukasz Majewski, Minkyu Kang, Sean Anderson,
	Simon Glass, Tom Rini, u-boot

Hi,


2023년 12월 13일 (수) 12:27, Sam Protsenko <semen.protsenko@linaro.org>님이 작성:

> Heavily based on Linux kernel Samsung clock framework, with some changes
> to accommodate the differences in U-Boot CCF implementation. It's also
> quite minimal as compared to the Linux version.
>
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/clk/exynos/Makefile  |   9 +-
>  drivers/clk/exynos/clk-pll.c | 167 +++++++++++++++++++++++++
>  drivers/clk/exynos/clk-pll.h |  23 ++++
>  drivers/clk/exynos/clk.c     | 121 +++++++++++++++++++
>  drivers/clk/exynos/clk.h     | 228 +++++++++++++++++++++++++++++++++++
>  5 files changed, 546 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/clk/exynos/clk-pll.c
>  create mode 100644 drivers/clk/exynos/clk-pll.h
>  create mode 100644 drivers/clk/exynos/clk.c
>  create mode 100644 drivers/clk/exynos/clk.h
>
> diff --git a/drivers/clk/exynos/Makefile b/drivers/clk/exynos/Makefile
> index 7faf238571ef..04c5b9a39e16 100644
> --- a/drivers/clk/exynos/Makefile
> +++ b/drivers/clk/exynos/Makefile
> @@ -1,6 +1,11 @@
>  # SPDX-License-Identifier: GPL-2.0+
>  #
>  # Copyright (C) 2016 Samsung Electronics
> -# Thomas Abraham <thomas.ab@samsung.com>
> +# Copyright (C) 2023 Linaro Ltd.
> +#
> +# Authors:
> +#   Thomas Abraham <thomas.ab@samsung.com>
> +#   Sam Protsenko <semen.protsenko@linaro.org>
>
> -obj-$(CONFIG_CLK_EXYNOS7420)   += clk-exynos7420.o
> +obj-$(CONFIG_$(SPL_TPL_)CLK_CCF)       += clk.o clk-pll.o
> +obj-$(CONFIG_CLK_EXYNOS7420)           += clk-exynos7420.o
> diff --git a/drivers/clk/exynos/clk-pll.c b/drivers/clk/exynos/clk-pll.c
> new file mode 100644
> index 000000000000..9e496ff83aaf
> --- /dev/null
> +++ b/drivers/clk/exynos/clk-pll.c
> @@ -0,0 +1,167 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2016 Samsung Electronics
> + * Copyright (C) 2023 Linaro Ltd.
> + *
> + * Authors:
> + *   Thomas Abraham <thomas.ab@exynos.com>
> + *   Sam Protsenko <semen.protsenko@linaro.org>
> + *
> + * This file contains the utility functions to register the pll clocks.
> + */
> +
> +#include <asm/io.h>
> +#include <div64.h>
> +#include <malloc.h>
> +#include <clk-uclass.h>
> +#include <dm/device.h>
> +#include <clk.h>
> +#include "clk.h"
> +
> +#define UBOOT_DM_CLK_SAMSUNG_PLL0822X  "samsung_clk_pll0822x"
> +#define UBOOT_DM_CLK_SAMSUNG_PLL0831X  "samsung_clk_pll0831x"
> +
> +struct samsung_clk_pll {
> +       struct clk              clk;
> +       void __iomem            *con_reg;
> +       enum samsung_pll_type   type;
> +};
> +
> +#define to_clk_pll(_clk) container_of(_clk, struct samsung_clk_pll, clk)
> +
> +/*
> + * PLL0822x Clock Type
> + */
> +
> +#define PLL0822X_MDIV_MASK             0x3ff
> +#define PLL0822X_PDIV_MASK             0x3f
> +#define PLL0822X_SDIV_MASK             0x7
> +#define PLL0822X_MDIV_SHIFT            16
> +#define PLL0822X_PDIV_SHIFT            8
> +#define PLL0822X_SDIV_SHIFT            0
> +
> +static unsigned long samsung_pll0822x_recalc_rate(struct clk *clk)
> +{
> +       struct samsung_clk_pll *pll = to_clk_pll(clk);
> +       u32 mdiv, pdiv, sdiv, pll_con3;
> +       u64 fvco = clk_get_parent_rate(clk);
> +
> +       pll_con3 = readl_relaxed(pll->con_reg);
> +       mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
> +       pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
> +       sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
> +
> +       fvco *= mdiv;
> +       do_div(fvco, (pdiv << sdiv));
> +       return (unsigned long)fvco;
> +}
> +
> +static const struct clk_ops samsung_pll0822x_clk_min_ops = {
> +       .get_rate = samsung_pll0822x_recalc_rate,
> +};
> +
> +/*
> + * PLL0831x Clock Type
> + */
> +
> +#define PLL0831X_KDIV_MASK             0xffff
> +#define PLL0831X_MDIV_MASK             0x1ff
> +#define PLL0831X_PDIV_MASK             0x3f
> +#define PLL0831X_SDIV_MASK             0x7
> +#define PLL0831X_MDIV_SHIFT            16
> +#define PLL0831X_PDIV_SHIFT            8
> +#define PLL0831X_SDIV_SHIFT            0
> +#define PLL0831X_KDIV_SHIFT            0
> +
> +static unsigned long samsung_pll0831x_recalc_rate(struct clk *clk)
> +{
> +       struct samsung_clk_pll *pll = to_clk_pll(clk);
> +       u32 mdiv, pdiv, sdiv, pll_con3, pll_con5;
> +       s16 kdiv;
> +       u64 fvco = clk_get_parent_rate(clk);
> +
> +       pll_con3 = readl_relaxed(pll->con_reg);
> +       pll_con5 = readl_relaxed(pll->con_reg + 8);
> +       mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK;
> +       pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK;
> +       sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK;
> +       kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) &
> PLL0831X_KDIV_MASK);
> +
> +       fvco *= (mdiv << 16) + kdiv;
> +       do_div(fvco, (pdiv << sdiv));
> +       fvco >>= 16;
> +
> +       return (unsigned long)fvco;
> +}
> +
> +static const struct clk_ops samsung_pll0831x_clk_min_ops = {
> +       .get_rate = samsung_pll0831x_recalc_rate,
> +};
> +
> +static struct clk *_samsung_clk_register_pll(void __iomem *base,
> +                                       const struct samsung_pll_clock
> *pll_clk)
> +{
> +       struct samsung_clk_pll *pll;
> +       struct clk *clk;
> +       const char *drv_name;
> +       int ret;
> +
> +       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> +       if (!pll)
> +               return ERR_PTR(-ENOMEM);
> +
> +       pll->con_reg = base + pll_clk->con_offset;
> +       pll->type = pll_clk->type;
> +       clk = &pll->clk;
> +       clk->flags = pll_clk->flags;
> +
> +       switch (pll_clk->type) {
> +       case pll_0822x:
> +               drv_name = UBOOT_DM_CLK_SAMSUNG_PLL0822X;
> +               break;
> +       case pll_0831x:
> +               drv_name = UBOOT_DM_CLK_SAMSUNG_PLL0831X;
> +               break;
> +       default:
> +               kfree(pll);
> +               return ERR_PTR(-ENODEV);
> +       }
> +
> +       ret = clk_register(clk, drv_name, pll_clk->name,
> pll_clk->parent_name);
> +       if (ret) {
> +               kfree(pll);
> +               return ERR_PTR(ret);
> +       }
> +
> +       return clk;
> +}
> +
> +void samsung_clk_register_pll(void __iomem *base,
> +                             const struct samsung_pll_clock *clk_list,
> +                             unsigned int nr_clk)
> +{
> +       unsigned int cnt;
> +
> +       for (cnt = 0; cnt < nr_clk; cnt++) {
> +               struct clk *clk;
> +               const struct samsung_pll_clock *pll_clk;
> +
> +               pll_clk = &clk_list[cnt];
> +               clk = _samsung_clk_register_pll(base, pll_clk);
> +               clk_dm(pll_clk->id, clk);
> +       }
> +}
> +
> +U_BOOT_DRIVER(samsung_pll0822x_clk) = {
> +       .name   = UBOOT_DM_CLK_SAMSUNG_PLL0822X,
> +       .id     = UCLASS_CLK,
> +       .ops    = &samsung_pll0822x_clk_min_ops,
> +       .flags  = DM_FLAG_PRE_RELOC,
> +};
> +
> +U_BOOT_DRIVER(samsung_pll0831x_clk) = {
> +       .name   = UBOOT_DM_CLK_SAMSUNG_PLL0831X,
> +       .id     = UCLASS_CLK,
> +       .ops    = &samsung_pll0831x_clk_min_ops,
> +       .flags  = DM_FLAG_PRE_RELOC,
> +};
> diff --git a/drivers/clk/exynos/clk-pll.h b/drivers/clk/exynos/clk-pll.h
> new file mode 100644
> index 000000000000..3b477369aeb8
> --- /dev/null
> +++ b/drivers/clk/exynos/clk-pll.h
> @@ -0,0 +1,23 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2016 Samsung Electronics
> + * Copyright (C) 2023 Linaro Ltd.
> + *
> + * Authors:
> + *   Thomas Abraham <thomas.ab@exynos.com>
> + *   Sam Protsenko <semen.protsenko@linaro.org>
> + *
> + * Common Clock Framework support for all PLL's in Samsung platforms.
> + */
> +
> +#ifndef __EXYNOS_CLK_PLL_H
> +#define __EXYNOS_CLK_PLL_H
> +
> +#include <linux/clk-provider.h>
> +
> +enum samsung_pll_type {
> +       pll_0822x,
> +       pll_0831x,


why don't you modify to uppercase?


> +};
> +
> +#endif /* __EXYNOS_CLK_PLL_H */
> diff --git a/drivers/clk/exynos/clk.c b/drivers/clk/exynos/clk.c
> new file mode 100644
> index 000000000000..430767f072d8
> --- /dev/null
> +++ b/drivers/clk/exynos/clk.c
> @@ -0,0 +1,121 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2023 Linaro Ltd.
> + * Sam Protsenko <semen.protsenko@linaro.org>
> + *
> + * This file includes utility functions to register clocks to common
> + * clock framework for Samsung platforms.
> + */
> +
> +#include <dm.h>
> +#include "clk.h"
> +
> +void samsung_clk_register_mux(void __iomem *base,
> +                             const struct samsung_mux_clock *clk_list,
> +                             unsigned int nr_clk)
> +{
> +       unsigned int cnt;
> +
> +       for (cnt = 0; cnt < nr_clk; cnt++) {
> +               struct clk *clk;
> +               const struct samsung_mux_clock *m;


wouldn't it be better if use a more meaningful name like mux?


> +
> +               m = &clk_list[cnt];


Is there any possibility that the value is null or wrong (e.g. overflow)


> +               clk = clk_register_mux(NULL, m->name, m->parent_names,
> +                       m->num_parents, m->flags, base + m->offset,
> m->shift,
> +                       m->width, m->mux_flags);
> +               clk_dm(m->id, clk);
> +       }
> +}
> +
> +void samsung_clk_register_div(void __iomem *base,
> +                             const struct samsung_div_clock *clk_list,
> +                             unsigned int nr_clk)
> +{
> +       unsigned int cnt;
> +
> +       for (cnt = 0; cnt < nr_clk; cnt++) {
> +               struct clk *clk;
> +               const struct samsung_div_clock *d;
> +
> +               d = &clk_list[cnt];
> +               clk = clk_register_divider(NULL, d->name, d->parent_name,
> +                       d->flags, base + d->offset, d->shift,
> +                       d->width, d->div_flags);
> +               clk_dm(d->id, clk);
> +       }
> +}
> +
> +void samsung_clk_register_gate(void __iomem *base,
> +                              const struct samsung_gate_clock *clk_list,
> +                              unsigned int nr_clk)
> +{
> +       unsigned int cnt;
> +
> +       for (cnt = 0; cnt < nr_clk; cnt++) {
> +               struct clk *clk;
> +               const struct samsung_gate_clock *g;
> +
> +               g = &clk_list[cnt];
> +               clk = clk_register_gate(NULL, g->name, g->parent_name,
> +                       g->flags, base + g->offset, g->bit_idx,
> +                       g->gate_flags, NULL);
> +               clk_dm(g->id, clk);
> +       }
> +}
> +
> +typedef void (*samsung_clk_register_fn)(void __iomem *base,
> +                                       const void *clk_list,
> +                                       unsigned int nr_clk);
> +
> +static const samsung_clk_register_fn samsung_clk_register_fns[] = {
> +       [S_CLK_MUX]     =
> (samsung_clk_register_fn)samsung_clk_register_mux,
> +       [S_CLK_DIV]     =
> (samsung_clk_register_fn)samsung_clk_register_div,
> +       [S_CLK_GATE]    =
> (samsung_clk_register_fn)samsung_clk_register_gate,
> +       [S_CLK_PLL]     =
> (samsung_clk_register_fn)samsung_clk_register_pll,
> +};
> +
> +/**
> + * samsung_cmu_register_clocks() - Register provided clock groups
> + * @base: Base address of CMU registers
> + * @clk_groups: list of clock groups
> + * @nr_groups: count of clock groups in @clk_groups
> + *
> + * Having the array of clock groups @clk_groups makes it possible to keep
> a
> + * correct clocks registration order.
> + */
> +void samsung_cmu_register_clocks(void __iomem *base,
> +                                const struct samsung_clk_group
> *clk_groups,
> +                                unsigned int nr_groups)
> +{
> +       unsigned int i;
> +
> +       for (i = 0; i < nr_groups; i++) {
> +               const struct samsung_clk_group *g = &clk_groups[i];
> +
> +               samsung_clk_register_fns[g->type](base, g->clk_list,
> g->nr_clk);
> +       }
> +}
> +
> +/**
> + * samsung_cmu_register_one - Register all CMU clocks
> + * @dev: CMU device
> + * @clk_groups: list of CMU clock groups
> + * @nr_groups: count of CMU clock groups in @clk_groups
> + *
> + * Return: 0 on success or negative value on error.
> + */
> +int samsung_cmu_register_one(struct udevice *dev,
> +                            const struct samsung_clk_group *clk_groups,
> +                            unsigned int nr_groups)
> +{
> +       void __iomem *base;
> +
> +       base = dev_read_addr_ptr(dev);
> +       if (!base)
> +               return -EINVAL;
> +
> +       samsung_cmu_register_clocks(base, clk_groups, nr_groups);
> +
> +       return 0;
> +}
> diff --git a/drivers/clk/exynos/clk.h b/drivers/clk/exynos/clk.h
> new file mode 100644
> index 000000000000..91a51b877a63
> --- /dev/null
> +++ b/drivers/clk/exynos/clk.h
> @@ -0,0 +1,228 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2023 Linaro Ltd.
> + * Sam Protsenko <semen.protsenko@linaro.org>
> + *
> + * Common Clock Framework support for all Samsung platforms.
> + */
> +
> +#ifndef __EXYNOS_CLK_H
> +#define __EXYNOS_CLK_H
> +
> +#include <errno.h>
> +#include <linux/clk-provider.h>
> +#include "clk-pll.h"
> +
> +/**
> + * struct samsung_mux_clock - information about mux clock
> + * @id: platform specific id of the clock
> + * @name: name of this mux clock
> + * @parent_names: array of pointer to parent clock names
> + * @num_parents: number of parents listed in @parent_names
> + * @flags: optional flags for basic clock
> + * @offset: offset of the register for configuring the mux
> + * @shift: starting bit location of the mux control bit-field in @reg
> + * @width: width of the mux control bit-field in @reg
> + * @mux_flags: flags for mux-type clock
> + */
> +struct samsung_mux_clock {
> +       unsigned int            id;
> +       const char              *name;
> +       const char              * const *parent_names;
> +       u8                      num_parents;
> +       unsigned long           flags;
> +       unsigned long           offset;
> +       u8                      shift;
> +       u8                      width;
> +       u8                      mux_flags;
> +};
> +
> +#define PNAME(x) static const char * const x[]
> +
> +#define __MUX(_id, cname, pnames, o, s, w, f, mf)                      \
> +       {                                                               \
> +               .id             = _id,                                  \
> +               .name           = cname,                                \
> +               .parent_names   = pnames,                               \
> +               .num_parents    = ARRAY_SIZE(pnames),                   \
> +               .flags          = (f) | CLK_SET_RATE_NO_REPARENT,       \
> +               .offset         = o,                                    \
> +               .shift          = s,                                    \
> +               .width          = w,                                    \
> +               .mux_flags      = mf,                                   \
> +       }
> +
> +#define MUX(_id, cname, pnames, o, s, w)                               \
> +       __MUX(_id, cname, pnames, o, s, w, 0, 0)
> +
> +#define MUX_F(_id, cname, pnames, o, s, w, f, mf)                      \
> +       __MUX(_id, cname, pnames, o, s, w, f, mf)
> +
> +/**
> + * struct samsung_div_clock - information about div clock
> + * @id: platform specific id of the clock
> + * @name: name of this div clock
> + * @parent_name: name of the parent clock
> + * @flags: optional flags for basic clock
> + * @offset: offset of the register for configuring the div
> + * @shift: starting bit location of the div control bit-field in @reg
> + * @width: width of the bitfield
> + * @div_flags: flags for div-type clock
> + */
> +struct samsung_div_clock {
> +       unsigned int            id;
> +       const char              *name;
> +       const char              *parent_name;
> +       unsigned long           flags;
> +       unsigned long           offset;
> +       u8                      shift;
> +       u8                      width;
> +       u8                      div_flags;
> +};
> +
> +#define __DIV(_id, cname, pname, o, s, w, f, df)       \
> +       {                                               \
> +               .id             = _id,                  \
> +               .name           = cname,                \
> +               .parent_name    = pname,                \
> +               .flags          = f,                    \
> +               .offset         = o,                    \
> +               .shift          = s,                    \
> +               .width          = w,                    \
> +               .div_flags      = df,                   \
> +       }
> +
> +#define DIV(_id, cname, pname, o, s, w)                        \
> +       __DIV(_id, cname, pname, o, s, w, 0, 0)
> +
> +#define DIV_F(_id, cname, pname, o, s, w, f, df)       \
> +       __DIV(_id, cname, pname, o, s, w, f, df)
> +
> +/**
> + * struct samsung_gate_clock - information about gate clock
> + * @id: platform specific id of the clock
> + * @name: name of this gate clock
> + * @parent_name: name of the parent clock
> + * @flags: optional flags for basic clock
> + * @offset: offset of the register for configuring the gate
> + * @bit_idx: bit index of the gate control bit-field in @reg
> + * @gate_flags: flags for gate-type clock
> + */
> +struct samsung_gate_clock {
> +       unsigned int            id;
> +       const char              *name;
> +       const char              *parent_name;
> +       unsigned long           flags;
> +       unsigned long           offset;
> +       u8                      bit_idx;
> +       u8                      gate_flags;
> +};
> +
> +#define __GATE(_id, cname, pname, o, b, f, gf)                 \
> +       {                                                       \
> +               .id             = _id,                          \
> +               .name           = cname,                        \
> +               .parent_name    = pname,                        \
> +               .flags          = f,                            \
> +               .offset         = o,                            \
> +               .bit_idx        = b,                            \
> +               .gate_flags     = gf,                           \
> +       }
> +
> +#define GATE(_id, cname, pname, o, b, f, gf)                   \
> +       __GATE(_id, cname, pname, o, b, f, gf)
> +
> +/**
> + * struct samsung_pll_clock - information about pll clock
> + * @id: platform specific id of the clock
> + * @name: name of this pll clock
> + * @parent_name: name of the parent clock
> + * @flags: optional flags for basic clock
> + * @con_offset: offset of the register for configuring the PLL
> + * @type: type of PLL to be registered
> + */
> +struct samsung_pll_clock {
> +       unsigned int            id;
> +       const char              *name;
> +       const char              *parent_name;
> +       unsigned long           flags;
> +       int                     con_offset;
> +       enum samsung_pll_type   type;
> +};
> +
> +#define PLL(_typ, _id, _name, _pname, _con)            \
> +       {                                               \
> +               .id             = _id,                  \
> +               .name           = _name,                \
> +               .parent_name    = _pname,               \
> +               .flags          = CLK_GET_RATE_NOCACHE, \
> +               .con_offset     = _con,                 \
> +               .type           = _typ,                 \
> +       }
> +
> +enum samsung_clock_type {
> +       S_CLK_MUX,
> +       S_CLK_DIV,
> +       S_CLK_GATE,
> +       S_CLK_PLL,
> +};
> +
> +/**
> + * struct samsung_clock_group - contains a list of clocks of one type
> + * @type: type of clocks this structure contains
> + * @clk_list: list of clocks
> + * @nr_clk: count of clocks in @clk_list
> + */
> +struct samsung_clk_group {
> +       enum samsung_clock_type type;
> +       const void *clk_list;
> +       unsigned int nr_clk;
> +};
> +
> +void samsung_clk_register_mux(void __iomem *base,
> +                             const struct samsung_mux_clock *clk_list,
> +                             unsigned int nr_clk);
> +void samsung_clk_register_div(void __iomem *base,
> +                             const struct samsung_div_clock *clk_list,
> +                             unsigned int nr_clk);
> +void samsung_clk_register_gate(void __iomem *base,
> +                              const struct samsung_gate_clock *clk_list,
> +                              unsigned int nr_clk);
> +void samsung_clk_register_pll(void __iomem *base,
> +                             const struct samsung_pll_clock *clk_list,
> +                             unsigned int nr_clk);
> +
> +void samsung_cmu_register_clocks(void __iomem *base,
> +                                const struct samsung_clk_group
> *clk_groups,
> +                                unsigned int nr_groups);
> +int samsung_cmu_register_one(struct udevice *dev,
> +                            const struct samsung_clk_group *clk_groups,
> +                            unsigned int nr_groups);
> +
> +/**
> + * samsung_register_cmu - Register CMU clocks ensuring parent CMU is
> present
> + * @dev: CMU device
> + * @clk_groups: list of CMU clock groups
> + * @parent_drv: name of parent CMU driver
> + *
> + * Register provided CMU clocks, but make sure CMU_TOP driver is
> instantiated
> + * first.
> + *
> + * Return: 0 on success or negative value on error.
> + */
> +#define samsung_register_cmu(dev, clk_groups, parent_drv)              \
> +({                                                                     \
> +       struct udevice *__parent;                                       \
> +       int __ret;                                                      \
> +                                                                       \
> +       __ret = uclass_get_device_by_driver(UCLASS_CLK,                 \
> +               DM_DRIVER_GET(parent_drv), &__parent);                  \
> +       if (__ret || !__parent)                                         \
> +               __ret = -ENOENT;                                        \
> +       else                                                            \
> +               __ret = samsung_cmu_register_one(dev, clk_groups,       \
> +                       ARRAY_SIZE(clk_groups));                        \
> +       __ret;                                                          \
> +})
> +
> +#endif /* __EXYNOS_CLK_H */
> --
> 2.39.2
>

Thanks.
Minkyu Kang.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 04/13] soc: samsung: Add Exynos USI driver
  2023-12-13  3:16 ` [PATCH 04/13] soc: samsung: Add Exynos USI driver Sam Protsenko
  2023-12-19 11:40   ` Chanho Park
  2023-12-27  9:11   ` Minkyu Kang
@ 2023-12-27 17:48   ` Simon Glass
  2024-01-11  2:20     ` Sam Protsenko
  2 siblings, 1 reply; 30+ messages in thread
From: Simon Glass @ 2023-12-27 17:48 UTC (permalink / raw)
  To: Sam Protsenko
  Cc: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson,
	Heinrich Schuchardt, u-boot

Hi Sam,

On Wed, Dec 13, 2023 at 3:16 AM Sam Protsenko
<semen.protsenko@linaro.org> wrote:
>
> USIv2 IP-core is found on modern ARM64 Exynos SoCs (like Exynos850) and
> provides selectable serial protocol (one of: UART, SPI, I2C). USIv2
> registers usually reside in the same register map as a particular
> underlying protocol it implements, but have some particular offset. E.g.
> on Exynos850 the USI_UART has 0x13820000 base address, where UART
> registers have 0x00..0x40 offsets, and USI registers have 0xc0..0xdc
> offsets. Desired protocol can be chosen via SW_CONF register from System
> Register block of the same domain as USI.
>
> Before starting to use a particular protocol, USIv2 must be configured
> properly:
>   1. Select protocol to be used via System Register
>   2. Clear "reset" flag in USI_CON
>   3. Configure HWACG behavior (e.g. for UART Rx the HWACG must be
>      disabled, so that the IP clock is not gated automatically); this is
>      done using USI_OPTION register
>   4. Keep both USI clocks (PCLK and IPCLK) running during USI registers
>      modification
>
> This driver implements the above behavior. Of course, USIv2 driver
> should be probed before UART/I2C/SPI drivers. It can be achieved by
> embedding UART/I2C/SPI nodes inside of the USI node (in Device Tree);
> driver then walks underlying nodes and instantiates those. Driver also
> handles USI configuration on PM resume, as register contents can be lost
> during CPU suspend.
>
> This driver is designed with different USI versions in mind. So it
> should be relatively easy to add new USI revisions to it later.
>
> Driver's code was copied over from Linux kernel [1] and adapted
> correspondingly for U-Boot API. UCLASS_MISC is used, and although no
> misc operations are implemented, it makes it easier to probe the driver
> this way (as compared to UCLASS_NOP) and keep the code compact.
>
> [1] drivers/soc/samsung/exynos-usi.c
>
> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> ---
>  drivers/soc/Kconfig              |   1 +
>  drivers/soc/Makefile             |   1 +
>  drivers/soc/samsung/Kconfig      |  23 ++++
>  drivers/soc/samsung/Makefile     |   3 +
>  drivers/soc/samsung/exynos-usi.c | 218 +++++++++++++++++++++++++++++++
>  5 files changed, 246 insertions(+)
>  create mode 100644 drivers/soc/samsung/Kconfig
>  create mode 100644 drivers/soc/samsung/Makefile
>  create mode 100644 drivers/soc/samsung/exynos-usi.c
>

Just a few nits here

Reviewed-by: Simon Glass <sjg@chromium.org>

> diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
> index 85dac9de78a4..03433bc0e6d2 100644
> --- a/drivers/soc/Kconfig
> +++ b/drivers/soc/Kconfig
> @@ -40,6 +40,7 @@ config SOC_XILINX_VERSAL_NET
>           This allows other drivers to verify the SoC familiy & revision using
>           matching SoC attributes.
>
> +source "drivers/soc/samsung/Kconfig"
>  source "drivers/soc/ti/Kconfig"
>
>  endmenu
> diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
> index 84385650d46d..610bf816d40a 100644
> --- a/drivers/soc/Makefile
> +++ b/drivers/soc/Makefile
> @@ -2,6 +2,7 @@
>  #
>  # Makefile for the U-Boot SOC specific device drivers.
>
> +obj-$(CONFIG_SOC_SAMSUNG) += samsung/
>  obj-$(CONFIG_SOC_TI) += ti/
>  obj-$(CONFIG_SOC_DEVICE) += soc-uclass.o
>  obj-$(CONFIG_SOC_DEVICE_TI_K3) += soc_ti_k3.o
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> new file mode 100644
> index 000000000000..ffb87fe79316
> --- /dev/null
> +++ b/drivers/soc/samsung/Kconfig
> @@ -0,0 +1,23 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +
> +menuconfig SOC_SAMSUNG
> +       bool "Samsung SoC drivers support"
> +
> +if SOC_SAMSUNG
> +
> +config EXYNOS_USI
> +       bool "Exynos USI (Universal Serial Interface) driver"
> +       depends on ARCH_EXYNOS
> +       select MISC
> +       select REGMAP
> +       select SYSCON
> +       help
> +         Enable support for USI block. USI (Universal Serial Interface) is an
> +         IP-core found in modern Samsung Exynos SoCs, like Exynos850 and
> +         ExynosAutoV9. USI block can be configured to provide one of the
> +         following serial protocols: UART, SPI or High Speed I2C.
> +
> +         This driver allows one to configure USI for desired protocol, which
> +         is usually done in USI node in Device Tree.
> +
> +endif
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> new file mode 100644
> index 000000000000..833ac073fbfa
> --- /dev/null
> +++ b/drivers/soc/samsung/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +
> +obj-$(CONFIG_EXYNOS_USI)       += exynos-usi.o
> diff --git a/drivers/soc/samsung/exynos-usi.c b/drivers/soc/samsung/exynos-usi.c
> new file mode 100644
> index 000000000000..23255177e6e3
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-usi.c
> @@ -0,0 +1,218 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2023 Linaro Ltd.
> + * Author: Sam Protsenko <semen.protsenko@linaro.org>
> + *
> + * Samsung Exynos USI driver (Universal Serial Interface).
> + */
> +
> +#include <dm.h>
> +#include <dm/device_compat.h>
> +#include <errno.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +#include <asm/io.h>
> +#include <linux/bitops.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +
> +#include <dt-bindings/soc/samsung,exynos-usi.h>
> +
> +/* USIv2: System Register: SW_CONF register bits */
> +#define USI_V2_SW_CONF_NONE    0x0
> +#define USI_V2_SW_CONF_UART    BIT(0)
> +#define USI_V2_SW_CONF_SPI     BIT(1)
> +#define USI_V2_SW_CONF_I2C     BIT(2)
> +#define USI_V2_SW_CONF_MASK    (USI_V2_SW_CONF_UART | USI_V2_SW_CONF_SPI | \
> +                                USI_V2_SW_CONF_I2C)
> +
> +/* USIv2: USI register offsets */
> +#define USI_CON                        0x04
> +#define USI_OPTION             0x08
> +
> +/* USIv2: USI register bits */
> +#define USI_CON_RESET          BIT(0)
> +#define USI_OPTION_CLKREQ_ON   BIT(1)
> +#define USI_OPTION_CLKSTOP_ON  BIT(2)
> +
> +enum exynos_usi_ver {
> +       USI_VER2 = 2,
> +};
> +
> +struct exynos_usi_variant {
> +       enum exynos_usi_ver ver;        /* USI IP-core version */
> +       unsigned int sw_conf_mask;      /* SW_CONF mask for all protocols */
> +       size_t min_mode;                /* first index in exynos_usi_modes[] */
> +       size_t max_mode;                /* last index in exynos_usi_modes[] */
> +};
> +
> +struct exynos_usi {
> +       struct udevice *dev;

Can we drop this? It doesn't seem very useful and we try to avoid
having bidirectional pointers. since it is possible to get the 'priv'
pointer from the device.

> +       void __iomem *regs;             /* USI register map */
> +
> +       size_t mode;                    /* current USI SW_CONF mode index */
> +       bool clkreq_on;                 /* always provide clock to IP */
> +
> +       /* System Register */
> +       struct regmap *sysreg;          /* System Register map */
> +       unsigned int sw_conf;           /* SW_CONF register offset in sysreg */
> +
> +       const struct exynos_usi_variant *data;
> +};
> +
> +struct exynos_usi_mode {
> +       const char *name;               /* mode name */
> +       unsigned int val;               /* mode register value */
> +};
> +
> +static const struct exynos_usi_mode exynos_usi_modes[] = {
> +       [USI_V2_NONE] = { .name = "none", .val = USI_V2_SW_CONF_NONE },
> +       [USI_V2_UART] = { .name = "uart", .val = USI_V2_SW_CONF_UART },
> +       [USI_V2_SPI] =  { .name = "spi",  .val = USI_V2_SW_CONF_SPI },
> +       [USI_V2_I2C] =  { .name = "i2c",  .val = USI_V2_SW_CONF_I2C },
> +};
> +
> +static const struct exynos_usi_variant exynos850_usi_data = {
> +       .ver            = USI_VER2,
> +       .sw_conf_mask   = USI_V2_SW_CONF_MASK,
> +       .min_mode       = USI_V2_NONE,
> +       .max_mode       = USI_V2_I2C,
> +};
> +
> +static const struct udevice_id exynos_usi_ids[] = {
> +       {
> +               .compatible = "samsung,exynos850-usi",
> +               .data = (ulong)&exynos850_usi_data,
> +       },
> +       { } /* sentinel */
> +};
> +
> +/**
> + * exynos_usi_set_sw_conf - Set USI block configuration mode
> + * @usi: USI driver object
> + * @mode: Mode index
> + *
> + * Select underlying serial protocol (UART/SPI/I2C) in USI IP-core.
> + *
> + * Return: 0 on success, or negative error code on failure.
> + */
> +static int exynos_usi_set_sw_conf(struct exynos_usi *usi, size_t mode)
> +{
> +       unsigned int val;
> +       int ret;
> +
> +       if (mode < usi->data->min_mode || mode > usi->data->max_mode)
> +               return -EINVAL;
> +
> +       val = exynos_usi_modes[mode].val;
> +       ret = regmap_update_bits(usi->sysreg, usi->sw_conf,
> +                                usi->data->sw_conf_mask, val);
> +       if (ret)
> +               return ret;
> +
> +       usi->mode = mode;
> +       dev_dbg(usi->dev, "protocol: %s\n", exynos_usi_modes[usi->mode].name);
> +
> +       return 0;
> +}
> +
> +/**
> + * exynos_usi_enable - Initialize USI block
> + * @usi: USI driver object
> + *
> + * USI IP-core start state is "reset" (on startup and after CPU resume). This
> + * routine enables the USI block by clearing the reset flag. It also configures
> + * HWACG behavior (needed e.g. for UART Rx). It should be performed before
> + * underlying protocol becomes functional.
> + */
> +static void exynos_usi_enable(const struct exynos_usi *usi)
> +{
> +       u32 val;
> +
> +       /* Enable USI block */
> +       val = readl(usi->regs + USI_CON);
> +       val &= ~USI_CON_RESET;
> +       writel(val, usi->regs + USI_CON);
> +       udelay(1);
> +
> +       /* Continuously provide the clock to USI IP w/o gating */
> +       if (usi->clkreq_on) {
> +               val = readl(usi->regs + USI_OPTION);
> +               val &= ~USI_OPTION_CLKSTOP_ON;
> +               val |= USI_OPTION_CLKREQ_ON;
> +               writel(val, usi->regs + USI_OPTION);
> +       }
> +}
> +
> +static int exynos_usi_configure(struct exynos_usi *usi)
> +{
> +       int ret;
> +
> +       ret = exynos_usi_set_sw_conf(usi, usi->mode);
> +       if (ret)
> +               return ret;
> +
> +       if (usi->data->ver == USI_VER2)
> +               exynos_usi_enable(usi);
> +
> +       return 0;
> +}
> +
> +static int exynos_usi_parse_dt(struct exynos_usi *usi)

Use of_to_plat() method?

> +{
> +       struct udevice *dev = usi->dev;
> +       ofnode node;
> +       int ret;
> +       u32 mode;
> +
> +       node = dev_ofnode(dev);
> +
> +       ret = ofnode_read_u32(node, "samsung,mode", &mode);
> +       if (ret)
> +               return ret;
> +       if (mode < usi->data->min_mode || mode > usi->data->max_mode)
> +               return -EINVAL;
> +       usi->mode = mode;
> +
> +       usi->sysreg = syscon_regmap_lookup_by_phandle(dev, "samsung,sysreg");
> +       if (IS_ERR(usi->sysreg))
> +               return PTR_ERR(usi->sysreg);
> +
> +       ret = ofnode_read_u32_index(node, "samsung,sysreg", 1, &usi->sw_conf);
> +       if (ret)
> +               return ret;
> +
> +       usi->clkreq_on = ofnode_read_bool(node, "samsung,clkreq-on");
> +
> +       return 0;
> +}
> +
> +static int exynos_usi_probe(struct udevice *dev)
> +{
> +       struct exynos_usi *usi;
> +       int ret;
> +
> +       usi = dev_get_priv(dev);
> +       usi->dev = dev;

Hoping you can drop that

> +       usi->data = (struct exynos_usi_variant *)dev_get_driver_data(dev);
> +
> +       ret = exynos_usi_parse_dt(usi);
> +       if (ret)
> +               return ret;
> +
> +       if (usi->data->ver == USI_VER2) {
> +               usi->regs = dev_read_addr_ptr(dev);
> +               if (!usi->regs)
> +                       return -ENODEV;
> +       }
> +
> +       return exynos_usi_configure(usi);
> +}
> +
> +U_BOOT_DRIVER(exynos_usi) = {
> +       .name           = "exynos-usi",
> +       .id             = UCLASS_MISC,
> +       .of_match       = exynos_usi_ids,
> +       .probe          = exynos_usi_probe,
> +       .priv_auto      = sizeof(struct exynos_usi),
> +};
> --
> 2.39.2
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 09/13] pinctrl: exynos: Add pinctrl support for Exynos850
  2023-12-19 11:32   ` Chanho Park
@ 2024-01-10 23:48     ` Sam Protsenko
  0 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2024-01-10 23:48 UTC (permalink / raw)
  To: Chanho Park
  Cc: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson,
	Simon Glass, Heinrich Schuchardt, u-boot

On Tue, Dec 19, 2023 at 5:32 AM Chanho Park <chanho61.park@samsung.com> wrote:
>
> > -----Original Message-----
> > From: U-Boot <u-boot-bounces@lists.denx.de> On Behalf Of Sam Protsenko
> > Sent: Wednesday, December 13, 2023 12:17 PM
> > To: Minkyu Kang <mk7.kang@samsung.com>; Tom Rini <trini@konsulko.com>;
> > Lukasz Majewski <lukma@denx.de>; Sean Anderson <seanga2@gmail.com>
> > Cc: Simon Glass <sjg@chromium.org>; Heinrich Schuchardt
> > <xypron.glpk@gmx.de>; u-boot@lists.denx.de
> > Subject: [PATCH 09/13] pinctrl: exynos: Add pinctrl support for Exynos850
> >
> > Add pinctrl support for Exynos850 SoC. It was mostly extracted from
> > corresponding Linux kernel code [1]. Power down modes and external
> > interrupt data were removed while converting the code for U-Boot, but
> > everything else was kept almost unchanged.
> >
> > [1] drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
> > ---
> >  drivers/pinctrl/exynos/Kconfig             |   8 ++
> >  drivers/pinctrl/exynos/Makefile            |   1 +
> >  drivers/pinctrl/exynos/pinctrl-exynos850.c | 125 +++++++++++++++++++++
> >  3 files changed, 134 insertions(+)
> >  create mode 100644 drivers/pinctrl/exynos/pinctrl-exynos850.c
> >
> > diff --git a/drivers/pinctrl/exynos/Kconfig
> > b/drivers/pinctrl/exynos/Kconfig
> > index a60f49869b45..1b7fb62bc4ba 100644
> > --- a/drivers/pinctrl/exynos/Kconfig
> > +++ b/drivers/pinctrl/exynos/Kconfig
> > @@ -16,3 +16,11 @@ config PINCTRL_EXYNOS78x0
> >       help
> >         Support pin multiplexing and pin configuration control on
> >         Samsung's Exynos78x0 SoC.
> > +
> > +config PINCTRL_EXYNOS850
> > +     bool "Samsung Exynos850 pinctrl driver"
> > +     depends on ARCH_EXYNOS && PINCTRL_FULL
> > +     select PINCTRL_EXYNOS
> > +     help
> > +       Support pin multiplexing and pin configuration control on
> > +       Samsung's Exynos850 SoC.
> > diff --git a/drivers/pinctrl/exynos/Makefile
> > b/drivers/pinctrl/exynos/Makefile
> > index 07db970ca942..3abe1226eb74 100644
> > --- a/drivers/pinctrl/exynos/Makefile
> > +++ b/drivers/pinctrl/exynos/Makefile
> > @@ -6,3 +6,4 @@
> >  obj-$(CONFIG_PINCTRL_EXYNOS)         += pinctrl-exynos.o
> >  obj-$(CONFIG_PINCTRL_EXYNOS7420)     += pinctrl-exynos7420.o
> >  obj-$(CONFIG_PINCTRL_EXYNOS78x0)     += pinctrl-exynos78x0.o
> > +obj-$(CONFIG_PINCTRL_EXYNOS850)              += pinctrl-exynos850.o
> > diff --git a/drivers/pinctrl/exynos/pinctrl-exynos850.c
> > b/drivers/pinctrl/exynos/pinctrl-exynos850.c
> > new file mode 100644
> > index 000000000000..2445dd752ea8
> > --- /dev/null
> > +++ b/drivers/pinctrl/exynos/pinctrl-exynos850.c
> > @@ -0,0 +1,125 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2023 Linaro Ltd.
> > + * Author: Sam Protsenko <semen.protsenko@linaro.org>
> > + *
> > + * Samsung Exynos USI driver (Universal Serial Interface).
>
> Typo. It should be a subject for the pinctrl driver.
>

Nice catch! Will be fixed in v2.

> Otherwise,
> Reviewed-by: Chanho Park <chanho61.park@samsung.com>

Thanks for the review!

>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 07/13] clk: exynos: Add Samsung clock framework
  2023-12-27  9:11   ` Minkyu Kang
@ 2024-01-11  1:15     ` Sam Protsenko
  0 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2024-01-11  1:15 UTC (permalink / raw)
  To: Minkyu Kang
  Cc: Heinrich Schuchardt, Lukasz Majewski, Minkyu Kang, Sean Anderson,
	Simon Glass, Tom Rini, u-boot

On Wed, Dec 27, 2023 at 3:12 AM Minkyu Kang <promsoft@gmail.com> wrote:
>
> Hi,
>
>
> 2023년 12월 13일 (수) 12:27, Sam Protsenko <semen.protsenko@linaro.org>님이 작성:
>>
>> Heavily based on Linux kernel Samsung clock framework, with some changes
>> to accommodate the differences in U-Boot CCF implementation. It's also
>> quite minimal as compared to the Linux version.
>>
>> Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
>> ---

[snip]

>> diff --git a/drivers/clk/exynos/clk-pll.h b/drivers/clk/exynos/clk-pll.h
>> new file mode 100644
>> index 000000000000..3b477369aeb8
>> --- /dev/null
>> +++ b/drivers/clk/exynos/clk-pll.h
>> @@ -0,0 +1,23 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ */
>> +/*
>> + * Copyright (C) 2016 Samsung Electronics
>> + * Copyright (C) 2023 Linaro Ltd.
>> + *
>> + * Authors:
>> + *   Thomas Abraham <thomas.ab@exynos.com>
>> + *   Sam Protsenko <semen.protsenko@linaro.org>
>> + *
>> + * Common Clock Framework support for all PLL's in Samsung platforms.
>> + */
>> +
>> +#ifndef __EXYNOS_CLK_PLL_H
>> +#define __EXYNOS_CLK_PLL_H
>> +
>> +#include <linux/clk-provider.h>
>> +
>> +enum samsung_pll_type {
>> +       pll_0822x,
>> +       pll_0831x,
>
>
> why don't you modify to uppercase?
>

That code was basically copied over from Linux kernel (from
drivers/clk/samsung/clk-pll.h file). I'm trying to keep it as close to
the original as possible, to ease any possible backporting in future.
Although kernel coding style indeed tends to stick to uppercase in
enums, in my opinion the backporting/compatibility concern outweighs
the style one. Hope it's ok with you if I keep it as is in v2?

>>
>> +};
>> +
>> +#endif /* __EXYNOS_CLK_PLL_H */
>> diff --git a/drivers/clk/exynos/clk.c b/drivers/clk/exynos/clk.c
>> new file mode 100644
>> index 000000000000..430767f072d8
>> --- /dev/null
>> +++ b/drivers/clk/exynos/clk.c
>> @@ -0,0 +1,121 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (C) 2023 Linaro Ltd.
>> + * Sam Protsenko <semen.protsenko@linaro.org>
>> + *
>> + * This file includes utility functions to register clocks to common
>> + * clock framework for Samsung platforms.
>> + */
>> +
>> +#include <dm.h>
>> +#include "clk.h"
>> +
>> +void samsung_clk_register_mux(void __iomem *base,
>> +                             const struct samsung_mux_clock *clk_list,
>> +                             unsigned int nr_clk)
>> +{
>> +       unsigned int cnt;
>> +
>> +       for (cnt = 0; cnt < nr_clk; cnt++) {
>> +               struct clk *clk;
>> +               const struct samsung_mux_clock *m;
>
>
> wouldn't it be better if use a more meaningful name like mux?
>

My reasoning for choosing the name that short in this case was because
of super-short scope (3 lines of code), and OTOH this variable is
massively used during that scope, like this:

        clk = clk_register_mux(NULL, m->name, m->parent_names,
                m->num_parents, m->flags, base + m->offset, m->shift,
                m->width, m->mux_flags);

Hope it makes sense. If you still prefer 'mux', please let me know and
I'll use it in v2.

>>
>> +
>> +               m = &clk_list[cnt];
>
>
> Is there any possibility that the value is null or wrong (e.g. overflow)
>

I decided to keep it with no error handling because I didn't feel like
it would bring much value. Because this code is supposed to be used
via samsung_cmu_register_one(), and the CMU structure passed to that
function is usually going to be defined in this idiomatic way (as can
be seen in clk-exynos850.c driver):

        static const struct samsung_clk_group top_cmu_clks[] = {
                { S_CLK_PLL, top_pure_pll_clks, ARRAY_SIZE(top_pure_pll_clks) },
                { S_CLK_MUX, top_pure_mux_clks, ARRAY_SIZE(top_pure_mux_clks) },
                 ...

and the corresponding clocks structures are also defined like this:

        static const struct samsung_mux_clock top_pure_mux_clks[] = {
                MUX(CLK_MOUT_SHARED0_PLL, "mout_shared0_pll",
mout_shared0_pll_p,
                    PLL_CON0_PLL_SHARED0, 4, 1),
                MUX(CLK_MOUT_SHARED1_PLL, "mout_shared1_pll",
mout_shared1_pll_p,
                    PLL_CON0_PLL_SHARED1, 4, 1),
                ...

I'd say the odds for messing this up are next to none, because of
using ARRAY_SIZE() and clock macros like MUX(). Especially because the
example is already set in clk-exynos850 driver and I assume everybody
would just use it as a template, which usually happens. So after
exploring the alternative approach (with added error handling) I felt
it was unjustifiable cluttered comparing to the more concise version
present in this series, at least in this particular code. Also, that
code resembles its kernel counterpart, where the clock pointer isn't
checked as well.

I'm not even sure how to handle possible errors here, as it's the
critical platform code. So maybe letting it just crash is not a bad
decision too. But if you have a strong opinion on this one, please let
me know how you would like me to handle that.

>> +               clk = clk_register_mux(NULL, m->name, m->parent_names,
>> +                       m->num_parents, m->flags, base + m->offset, m->shift,
>> +                       m->width, m->mux_flags);
>> +               clk_dm(m->id, clk);
>> +       }
>>> +}

[snip]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 04/13] soc: samsung: Add Exynos USI driver
  2023-12-27  9:11   ` Minkyu Kang
@ 2024-01-11  1:25     ` Sam Protsenko
  0 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2024-01-11  1:25 UTC (permalink / raw)
  To: Minkyu Kang
  Cc: Heinrich Schuchardt, Lukasz Majewski, Minkyu Kang, Sean Anderson,
	Simon Glass, Tom Rini, u-boot

On Wed, Dec 27, 2023 at 3:11 AM Minkyu Kang <promsoft@gmail.com> wrote:
>
> Hi
>
>
> 2023년 12월 13일 (수) 12:42, Sam Protsenko <semen.protsenko@linaro.org>님이 작성:
>>

[snip]

>> +
>> +/**
>> + * exynos_usi_set_sw_conf - Set USI block configuration mode
>> + * @usi: USI driver object
>> + * @mode: Mode index
>> + *
>> + * Select underlying serial protocol (UART/SPI/I2C) in USI IP-core.
>> + *
>> + * Return: 0 on success, or negative error code on failure.
>> + */
>> +static int exynos_usi_set_sw_conf(struct exynos_usi *usi, size_t mode)
>
>
> The value of mode is same as usi->mode, but is there a reason to pass it as a parameter?
>
>>
>> +{
>> +       unsigned int val;
>> +       int ret;
>> +
>> +       if (mode < usi->data->min_mode || mode > usi->data->max_mode)
>> +               return -EINVAL;
>> +
>> +       val = exynos_usi_modes[mode].val;
>> +       ret = regmap_update_bits(usi->sysreg, usi->sw_conf,
>> +                                usi->data->sw_conf_mask, val);
>> +       if (ret)
>> +               return ret;
>> +
>> +       usi->mode = mode;
>
>
> This will obviously be the same value always.
>

Thanks for the review! Yes, you are right. This code was copy-pasted
from Linux kernel. So at the time I thought it was better to leave it
as is, for backporting reasons. But now that I look at it, this won't
be too helpful. So I'll get rid of it in v2.

[snip]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 04/13] soc: samsung: Add Exynos USI driver
  2023-12-27 17:48   ` Simon Glass
@ 2024-01-11  2:20     ` Sam Protsenko
  0 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2024-01-11  2:20 UTC (permalink / raw)
  To: Simon Glass
  Cc: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson,
	Heinrich Schuchardt, u-boot

On Wed, Dec 27, 2023 at 11:49 AM Simon Glass <sjg@chromium.org> wrote:
>
> Hi Sam,
>

[snip]

>
> Just a few nits here
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>

[snip]

> > +
> > +struct exynos_usi {
> > +       struct udevice *dev;
>
> Can we drop this? It doesn't seem very useful and we try to avoid
> having bidirectional pointers. since it is possible to get the 'priv'
> pointer from the device.
>

Sure. I tried to keep the driver as close as possible to Linux
kernel's version, where I borrowed it from. But if it's the current
preference in U-Boot, I'll fix this in v2.

[snip]

> > +static int exynos_usi_parse_dt(struct exynos_usi *usi)
>
> Use of_to_plat() method?
>

Will do in v2. Thanks for the review!

[snip]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 07/13] clk: exynos: Add Samsung clock framework
  2023-12-19 11:38   ` Chanho Park
@ 2024-01-11  2:40     ` Sam Protsenko
  0 siblings, 0 replies; 30+ messages in thread
From: Sam Protsenko @ 2024-01-11  2:40 UTC (permalink / raw)
  To: Chanho Park
  Cc: Minkyu Kang, Tom Rini, Lukasz Majewski, Sean Anderson,
	Simon Glass, Heinrich Schuchardt, u-boot

On Tue, Dec 19, 2023 at 5:38 AM Chanho Park <chanho61.park@samsung.com> wrote:
>

[snip]

> > diff --git a/drivers/clk/exynos/clk-pll.c b/drivers/clk/exynos/clk-pll.c
> > new file mode 100644
> > index 000000000000..9e496ff83aaf
> > --- /dev/null
> > +++ b/drivers/clk/exynos/clk-pll.c
> > @@ -0,0 +1,167 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2016 Samsung Electronics
> > + * Copyright (C) 2023 Linaro Ltd.
> > + *
> > + * Authors:
> > + *   Thomas Abraham <thomas.ab@exynos.com>
>
> Need to correct Thomas's email to samsung.com if you want to keep his
> original credit even though his e-mail was already stale since he left the
> company.
>

Thanks for the review, will do in v2!

[snip]

> > + *
> > + * Authors:
> > + *   Thomas Abraham <thomas.ab@exynos.com>
>
> Ditto.
>
> Othewise,
> Reviewed-by: Chanho Park <chanho61.park@samsung.com>
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2024-01-11  2:41 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-13  3:16 [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
2023-12-13  3:16 ` [PATCH 01/13] dt-bindings: soc: samsung: Add Exynos USI Sam Protsenko
2023-12-13  3:16 ` [PATCH 02/13] dt-bindings: soc: samsung: Add Exynos PMU Sam Protsenko
2023-12-13  3:16 ` [PATCH 03/13] dt-bindings: clock: Add Exynos850 clock controller Sam Protsenko
2023-12-13  3:16 ` [PATCH 04/13] soc: samsung: Add Exynos USI driver Sam Protsenko
2023-12-19 11:40   ` Chanho Park
2023-12-27  9:11   ` Minkyu Kang
2024-01-11  1:25     ` Sam Protsenko
2023-12-27 17:48   ` Simon Glass
2024-01-11  2:20     ` Sam Protsenko
2023-12-13  3:16 ` [PATCH 05/13] soc: samsung: Add Exynos PMU driver Sam Protsenko
2023-12-19 11:39   ` Chanho Park
2023-12-13  3:16 ` [PATCH 06/13] clk: exynos: Move pll code into clk-exynos7420 Sam Protsenko
2023-12-19 11:41   ` Chanho Park
2023-12-13  3:16 ` [PATCH 07/13] clk: exynos: Add Samsung clock framework Sam Protsenko
2023-12-19 11:38   ` Chanho Park
2024-01-11  2:40     ` Sam Protsenko
2023-12-27  9:11   ` Minkyu Kang
2024-01-11  1:15     ` Sam Protsenko
2023-12-13  3:16 ` [PATCH 08/13] clk: exynos: Add Exynos850 clock driver Sam Protsenko
2023-12-19 11:33   ` Chanho Park
2023-12-13  3:16 ` [PATCH 09/13] pinctrl: exynos: Add pinctrl support for Exynos850 Sam Protsenko
2023-12-19 11:32   ` Chanho Park
2024-01-10 23:48     ` Sam Protsenko
2023-12-13  3:16 ` [PATCH 10/13] serial: s5p: Add Exynos850 compatible Sam Protsenko
2023-12-13  3:16 ` [PATCH 11/13] arm: exynos: Add Exynos850 SoC support Sam Protsenko
2023-12-13  3:16 ` [PATCH 12/13] board: samsung: Add support for E850-96 board Sam Protsenko
2023-12-13  3:16 ` [PATCH 13/13] MAINTAINERS: Add new Samsung subsystems Sam Protsenko
2023-12-18 15:31 ` [PATCH 00/13] arm: exynos: Add E850-96 board Sam Protsenko
2023-12-22  7:34   ` Minkyu Kang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.