Commit ff6862c2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm-drivers-6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc

Pull ARM driver updates from Arnd Bergmann:
 "The drivers branch for 6.1 is a bit larger than for most releases.

  Most of the changes come from SoC maintainers for the drivers/soc
  subsystem:

   - A new driver for error handling on the NVIDIA Tegra 'control
     backbone' bus.

   - A new driver for Qualcomm LLCC/DDR bandwidth measurement

   - New Rockchip rv1126 and rk3588 power domain drivers

   - DT binding updates for memory controllers, older Rockchip SoCs,
     various Mediatek devices, Qualcomm SCM firmware

   - Minor updates to Hisilicon LPC bus, the Allwinner SRAM driver, the
     Apple rtkit firmware driver, Tegra firmware

   - Minor updates for SoC drivers (Samsung, Mediatek, Renesas, Tegra,
     Qualcomm, Broadcom, NXP, ...)

  There are also some separate subsystem with downstream maintainers
  that merge updates this way:

   - Various updates and new drivers in the memory controller subsystem
     for Mediatek and Broadcom SoCs

   - Small set of changes in preparation to add support for FF-A v1.1
     specification later, in the Arm FF-A firmware subsystem

   - debugfs support in the PSCI firmware subsystem"

* tag 'arm-drivers-6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (149 commits)
  ARM: remove check for CONFIG_DEBUG_LL_SER3
  firmware/psci: Add debugfs support to ease debugging
  firmware/psci: Print a warning if PSCI doesn't accept PC mode
  dt-bindings: memory: snps,dw-umctl2-ddrc: Extend schema with IRQs/resets/clocks props
  dt-bindings: memory: snps,dw-umctl2-ddrc: Replace opencoded numbers with macros
  dt-bindings: memory: snps,dw-umctl2-ddrc: Use more descriptive device name
  dt-bindings: memory: synopsys,ddrc-ecc: Detach Zynq DDRC controller support
  soc: sunxi: sram: Add support for the D1 system control
  soc: sunxi: sram: Export the LDO control register
  soc: sunxi: sram: Save a pointer to the OF match data
  soc: sunxi: sram: Return void from the release function
  soc: apple: rtkit: Add apple_rtkit_poll
  soc: imx: add i.MX93 media blk ctrl driver
  soc: imx: add i.MX93 SRC power domain driver
  soc: imx: imx8m-blk-ctrl: Use genpd_xlate_onecell
  soc: imx: imx8mp-blk-ctrl: handle PCIe PHY resets
  soc: imx: imx8m-blk-ctrl: add i.MX8MP VPU blk ctrl
  soc: imx: add i.MX8MP HDMI blk ctrl HDCP/HRV_MWR
  soc: imx: add icc paths for i.MX8MP hsio/hdmi blk ctrl
  soc: imx: add icc paths for i.MX8MP media blk ctrl
  ...
parents 40285e64 44137949
What: /sys/bus/platform/devices/*/srpd
Date: July 2022
KernelVersion: 5.21
Contact: Florian Fainelli <f.fainelli@gmail.com>
Description:
Self Refresh Power Down (SRPD) inactivity timeout counted in
internal DDR controller clock cycles. Possible values range
from 0 (disable inactivity timeout) to 65535 (0xffff).
What: /sys/bus/platform/devices/*/frequency
Date: July 2022
KernelVersion: 5.21
Contact: Florian Fainelli <f.fainelli@gmail.com>
Description:
DDR PHY frequency in Hz.
...@@ -187,15 +187,8 @@ Required properties: ...@@ -187,15 +187,8 @@ Required properties:
Sequencer DRAM parameters and control registers. Used for Self-Refresh Sequencer DRAM parameters and control registers. Used for Self-Refresh
Power-Down (SRPD), among other things. Power-Down (SRPD), among other things.
Required properties: See Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml for a
- compatible : should contain one of these full list of supported compatible strings and properties.
"brcm,brcmstb-memc-ddr-rev-b.2.1"
"brcm,brcmstb-memc-ddr-rev-b.2.2"
"brcm,brcmstb-memc-ddr-rev-b.2.3"
"brcm,brcmstb-memc-ddr-rev-b.3.0"
"brcm,brcmstb-memc-ddr-rev-b.3.1"
"brcm,brcmstb-memc-ddr"
- reg : the MEMC DDR register range
Example: Example:
......
...@@ -554,8 +554,7 @@ properties: ...@@ -554,8 +554,7 @@ properties:
- engicam,imx6ul-isiot # Engicam Is.IoT MX6UL eMMC/NAND Starter kit - engicam,imx6ul-isiot # Engicam Is.IoT MX6UL eMMC/NAND Starter kit
- fsl,imx6ul-14x14-evk # i.MX6 UltraLite 14x14 EVK Board - fsl,imx6ul-14x14-evk # i.MX6 UltraLite 14x14 EVK Board
- karo,imx6ul-tx6ul # Ka-Ro electronics TXUL-0010 Module - karo,imx6ul-tx6ul # Ka-Ro electronics TXUL-0010 Module
- kontron,imx6ul-n6310-som # Kontron N6310 SOM - kontron,sl-imx6ul # Kontron SL i.MX6UL SoM
- kontron,imx6ul-n6311-som # Kontron N6311 SOM
- prt,prti6g # Protonic PRTI6G Board - prt,prti6g # Protonic PRTI6G Board
- technexion,imx6ul-pico-dwarf # TechNexion i.MX6UL Pico-Dwarf - technexion,imx6ul-pico-dwarf # TechNexion i.MX6UL Pico-Dwarf
- technexion,imx6ul-pico-hobbit # TechNexion i.MX6UL Pico-Hobbit - technexion,imx6ul-pico-hobbit # TechNexion i.MX6UL Pico-Hobbit
...@@ -591,23 +590,17 @@ properties: ...@@ -591,23 +590,17 @@ properties:
- const: phytec,imx6ul-pcl063 # PHYTEC phyCORE-i.MX 6UL - const: phytec,imx6ul-pcl063 # PHYTEC phyCORE-i.MX 6UL
- const: fsl,imx6ul - const: fsl,imx6ul
- description: Kontron N6310 S Board - description: Kontron BL i.MX6UL (N631X S) Board
items: items:
- const: kontron,imx6ul-n6310-s - const: kontron,bl-imx6ul # Kontron BL i.MX6UL Carrier Board
- const: kontron,imx6ul-n6310-som - const: kontron,sl-imx6ul # Kontron SL i.MX6UL SoM
- const: fsl,imx6ul - const: fsl,imx6ul
- description: Kontron N6311 S Board - description: Kontron BL i.MX6UL 43 (N631X S 43) Board
items: items:
- const: kontron,imx6ul-n6311-s - const: kontron,bl-imx6ul-43 # Kontron BL i.MX6UL Carrier Board with 4.3" Display
- const: kontron,imx6ul-n6311-som - const: kontron,bl-imx6ul # Kontron BL i.MX6UL Carrier Board
- const: fsl,imx6ul - const: kontron,sl-imx6ul # Kontron SL i.MX6UL SoM
- description: Kontron N6310 S 43 Board
items:
- const: kontron,imx6ul-n6310-s-43
- const: kontron,imx6ul-n6310-s
- const: kontron,imx6ul-n6310-som
- const: fsl,imx6ul - const: fsl,imx6ul
- description: TQ-Systems TQMa6UL1 SoM on MBa6ULx board - description: TQ-Systems TQMa6UL1 SoM on MBa6ULx board
...@@ -637,7 +630,7 @@ properties: ...@@ -637,7 +630,7 @@ properties:
- enum: - enum:
- fsl,imx6ull-14x14-evk # i.MX6 UltraLiteLite 14x14 EVK Board - fsl,imx6ull-14x14-evk # i.MX6 UltraLiteLite 14x14 EVK Board
- joz,jozacp # JOZ Access Point - joz,jozacp # JOZ Access Point
- kontron,imx6ull-n6411-som # Kontron N6411 SOM - kontron,sl-imx6ull # Kontron SL i.MX6ULL SoM
- myir,imx6ull-mys-6ulx-eval # MYiR Tech iMX6ULL Evaluation Board - myir,imx6ull-mys-6ulx-eval # MYiR Tech iMX6ULL Evaluation Board
- toradex,colibri-imx6ull # Colibri iMX6ULL Modules - toradex,colibri-imx6ull # Colibri iMX6ULL Modules
- toradex,colibri-imx6ull-emmc # Colibri iMX6ULL 1GB (eMMC) Module - toradex,colibri-imx6ull-emmc # Colibri iMX6ULL 1GB (eMMC) Module
...@@ -698,10 +691,10 @@ properties: ...@@ -698,10 +691,10 @@ properties:
- const: toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Module - const: toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Module
- const: fsl,imx6ull - const: fsl,imx6ull
- description: Kontron N6411 S Board - description: Kontron BL i.MX6ULL (N6411 S) Board
items: items:
- const: kontron,imx6ull-n6411-s - const: kontron,bl-imx6ull # Kontron BL i.MX6ULL Carrier Board
- const: kontron,imx6ull-n6411-som - const: kontron,sl-imx6ull # Kontron SL i.MX6ULL SoM
- const: fsl,imx6ull - const: fsl,imx6ull
- description: TQ Systems TQMa6ULLx SoM on MBa6ULx board - description: TQ Systems TQMa6ULLx SoM on MBa6ULx board
...@@ -825,13 +818,15 @@ properties: ...@@ -825,13 +818,15 @@ properties:
- emtrion,emcon-mx8mm-avari # emCON-MX8MM SoM on Avari Base - emtrion,emcon-mx8mm-avari # emCON-MX8MM SoM on Avari Base
- fsl,imx8mm-ddr4-evk # i.MX8MM DDR4 EVK Board - fsl,imx8mm-ddr4-evk # i.MX8MM DDR4 EVK Board
- fsl,imx8mm-evk # i.MX8MM EVK Board - fsl,imx8mm-evk # i.MX8MM EVK Board
- gateworks,imx8mm-gw7904
- gw,imx8mm-gw71xx-0x # i.MX8MM Gateworks Development Kit - gw,imx8mm-gw71xx-0x # i.MX8MM Gateworks Development Kit
- gw,imx8mm-gw72xx-0x # i.MX8MM Gateworks Development Kit - gw,imx8mm-gw72xx-0x # i.MX8MM Gateworks Development Kit
- gw,imx8mm-gw73xx-0x # i.MX8MM Gateworks Development Kit - gw,imx8mm-gw73xx-0x # i.MX8MM Gateworks Development Kit
- gw,imx8mm-gw7901 # i.MX8MM Gateworks Board - gw,imx8mm-gw7901 # i.MX8MM Gateworks Board
- gw,imx8mm-gw7902 # i.MX8MM Gateworks Board - gw,imx8mm-gw7902 # i.MX8MM Gateworks Board
- gw,imx8mm-gw7903 # i.MX8MM Gateworks Board - gw,imx8mm-gw7903 # i.MX8MM Gateworks Board
- kontron,imx8mm-n801x-som # i.MX8MM Kontron SL (N801X) SOM - kontron,imx8mm-sl # i.MX8MM Kontron SL (N801X) SOM
- kontron,imx8mm-osm-s # i.MX8MM Kontron OSM-S (N802X) SOM
- menlo,mx8menlo # i.MX8MM Menlo board with Verdin SoM - menlo,mx8menlo # i.MX8MM Menlo board with Verdin SoM
- toradex,verdin-imx8mm # Verdin iMX8M Mini Modules - toradex,verdin-imx8mm # Verdin iMX8M Mini Modules
- toradex,verdin-imx8mm-nonwifi # Verdin iMX8M Mini Modules without Wi-Fi / BT - toradex,verdin-imx8mm-nonwifi # Verdin iMX8M Mini Modules without Wi-Fi / BT
...@@ -850,8 +845,14 @@ properties: ...@@ -850,8 +845,14 @@ properties:
- description: Kontron BL i.MX8MM (N801X S) Board - description: Kontron BL i.MX8MM (N801X S) Board
items: items:
- const: kontron,imx8mm-n801x-s - const: kontron,imx8mm-bl
- const: kontron,imx8mm-n801x-som - const: kontron,imx8mm-sl
- const: fsl,imx8mm
- description: Kontron BL i.MX8MM OSM-S (N802X S) Board
items:
- const: kontron,imx8mm-bl-osm-s
- const: kontron,imx8mm-osm-s
- const: fsl,imx8mm - const: fsl,imx8mm
- description: Toradex Boards with Verdin iMX8M Mini Modules - description: Toradex Boards with Verdin iMX8M Mini Modules
...@@ -936,6 +937,13 @@ properties: ...@@ -936,6 +937,13 @@ properties:
- toradex,verdin-imx8mp-wifi # Verdin iMX8M Plus Wi-Fi / BT Modules - toradex,verdin-imx8mp-wifi # Verdin iMX8M Plus Wi-Fi / BT Modules
- const: fsl,imx8mp - const: fsl,imx8mp
- description: Avnet (MSC Branded) Boards with SM2S i.MX8M Plus Modules
items:
- const: avnet,sm2s-imx8mp-14N0600E-ep1 # SM2S-IMX8PLUS-14N0600E on SM2-MB-EP1 Carrier Board
- const: avnet,sm2s-imx8mp-14N0600E # 14N0600E variant of SM2S-IMX8PLUS SoM
- const: avnet,sm2s-imx8mp # SM2S-IMX8PLUS SoM
- const: fsl,imx8mp
- description: Engicam i.Core MX8M Plus SoM based boards - description: Engicam i.Core MX8M Plus SoM based boards
items: items:
- enum: - enum:
...@@ -1034,6 +1042,12 @@ properties: ...@@ -1034,6 +1042,12 @@ properties:
- toradex,colibri-imx8x # Colibri iMX8X Modules - toradex,colibri-imx8x # Colibri iMX8X Modules
- const: fsl,imx8qxp - const: fsl,imx8qxp
- description: i.MX8DXL based Boards
items:
- enum:
- fsl,imx8dxl-evk # i.MX8DXL EVK Board
- const: fsl,imx8dxl
- description: i.MX8QXP Boards with Toradex Coilbri iMX8X Modules - description: i.MX8QXP Boards with Toradex Coilbri iMX8X Modules
items: items:
- enum: - enum:
......
...@@ -21,10 +21,12 @@ select: ...@@ -21,10 +21,12 @@ select:
enum: enum:
- rockchip,px30-pmu - rockchip,px30-pmu
- rockchip,rk3066-pmu - rockchip,rk3066-pmu
- rockchip,rk3128-pmu
- rockchip,rk3288-pmu - rockchip,rk3288-pmu
- rockchip,rk3368-pmu - rockchip,rk3368-pmu
- rockchip,rk3399-pmu - rockchip,rk3399-pmu
- rockchip,rk3568-pmu - rockchip,rk3568-pmu
- rockchip,rk3588-pmu
required: required:
- compatible - compatible
...@@ -35,10 +37,12 @@ properties: ...@@ -35,10 +37,12 @@ properties:
- enum: - enum:
- rockchip,px30-pmu - rockchip,px30-pmu
- rockchip,rk3066-pmu - rockchip,rk3066-pmu
- rockchip,rk3128-pmu
- rockchip,rk3288-pmu - rockchip,rk3288-pmu
- rockchip,rk3368-pmu - rockchip,rk3368-pmu
- rockchip,rk3399-pmu - rockchip,rk3399-pmu
- rockchip,rk3568-pmu - rockchip,rk3568-pmu
- rockchip,rk3588-pmu
- const: syscon - const: syscon
- const: simple-mfd - const: simple-mfd
......
QCOM Secure Channel Manager (SCM)
Qualcomm processors include an interface to communicate to the secure firmware.
This interface allows for clients to request different types of actions. These
can include CPU power up/down, HDCP requests, loading of firmware, and other
assorted actions.
Required properties:
- compatible: must contain one of the following:
* "qcom,scm-apq8064"
* "qcom,scm-apq8084"
* "qcom,scm-ipq4019"
* "qcom,scm-ipq806x"
* "qcom,scm-ipq8074"
* "qcom,scm-mdm9607"
* "qcom,scm-msm8226"
* "qcom,scm-msm8660"
* "qcom,scm-msm8916"
* "qcom,scm-msm8953"
* "qcom,scm-msm8960"
* "qcom,scm-msm8974"
* "qcom,scm-msm8976"
* "qcom,scm-msm8994"
* "qcom,scm-msm8996"
* "qcom,scm-msm8998"
* "qcom,scm-qcs404"
* "qcom,scm-sc7180"
* "qcom,scm-sc7280"
* "qcom,scm-sm6125"
* "qcom,scm-sdm845"
* "qcom,scm-sdx55"
* "qcom,scm-sdx65"
* "qcom,scm-sm6350"
* "qcom,scm-sm8150"
* "qcom,scm-sm8250"
* "qcom,scm-sm8350"
* "qcom,scm-sm8450"
and:
* "qcom,scm"
- clocks: Specifies clocks needed by the SCM interface, if any:
* core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660" and
"qcom,scm-msm8960"
* core, iface and bus clocks required for "qcom,scm-apq8084",
"qcom,scm-msm8916", "qcom,scm-msm8953", "qcom,scm-msm8974" and "qcom,scm-msm8976"
- clock-names: Must contain "core" for the core clock, "iface" for the interface
clock and "bus" for the bus clock per the requirements of the compatible.
- qcom,dload-mode: phandle to the TCSR hardware block and offset of the
download mode control register (optional)
- interconnects: Specifies the bandwidth requirements of the SCM interface (optional)
Example for MSM8916:
firmware {
scm {
compatible = "qcom,msm8916", "qcom,scm";
clocks = <&gcc GCC_CRYPTO_CLK> ,
<&gcc GCC_CRYPTO_AXI_CLK>,
<&gcc GCC_CRYPTO_AHB_CLK>;
clock-names = "core", "bus", "iface";
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/firmware/qcom,scm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: QCOM Secure Channel Manager (SCM)
description: |
Qualcomm processors include an interface to communicate to the secure firmware.
This interface allows for clients to request different types of actions.
These can include CPU power up/down, HDCP requests, loading of firmware,
and other assorted actions.
maintainers:
- Bjorn Andersson <bjorn.andersson@linaro.org>
- Robert Marko <robimarko@gmail.com>
- Guru Das Srinagesh <quic_gurus@quicinc.com>
properties:
compatible:
items:
- enum:
- qcom,scm-apq8064
- qcom,scm-apq8084
- qcom,scm-ipq4019
- qcom,scm-ipq6018
- qcom,scm-ipq806x
- qcom,scm-ipq8074
- qcom,scm-mdm9607
- qcom,scm-msm8226
- qcom,scm-msm8660
- qcom,scm-msm8916
- qcom,scm-msm8953
- qcom,scm-msm8960
- qcom,scm-msm8974
- qcom,scm-msm8976
- qcom,scm-msm8994
- qcom,scm-msm8996
- qcom,scm-msm8998
- qcom,scm-sc7180
- qcom,scm-sc7280
- qcom,scm-sc8280xp
- qcom,scm-sdm845
- qcom,scm-sdx55
- qcom,scm-sdx65
- qcom,scm-sm6115
- qcom,scm-sm6125
- qcom,scm-sm6350
- qcom,scm-sm8150
- qcom,scm-sm8250
- qcom,scm-sm8350
- qcom,scm-sm8450
- qcom,scm-qcs404
- const: qcom,scm
clocks:
minItems: 1
maxItems: 3
clock-names:
minItems: 1
maxItems: 3
interconnects:
maxItems: 1
interconnect-names:
maxItems: 1
'#reset-cells':
const: 1
qcom,dload-mode:
$ref: /schemas/types.yaml#/definitions/phandle-array
items:
- items:
- description: phandle to TCSR hardware block
- description: offset of the download mode control register
description: TCSR hardware block
allOf:
- if:
properties:
compatible:
contains:
enum:
- qcom,scm-apq8064
- qcom,scm-msm8660
- qcom,scm-msm8960
then:
properties:
clock-names:
items:
- const: core
clocks:
maxItems: 1
required:
- clocks
- clock-names
- if:
properties:
compatible:
contains:
enum:
- qcom,scm-apq8084
- qcom,scm-mdm9607
- qcom,scm-msm8916
- qcom,scm-msm8953
- qcom,scm-msm8974
- qcom,scm-msm8976
then:
properties:
clock-names:
items:
- const: core
- const: bus
- const: iface
clocks:
minItems: 3
maxItems: 3
required:
- clocks
- clock-names
required:
- compatible
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,gcc-msm8916.h>
firmware {
scm {
compatible = "qcom,scm-msm8916", "qcom,scm";
clocks = <&gcc GCC_CRYPTO_CLK>,
<&gcc GCC_CRYPTO_AXI_CLK>,
<&gcc GCC_CRYPTO_AHB_CLK>;
clock-names = "core", "bus", "iface";
};
};
...@@ -24,9 +24,12 @@ properties: ...@@ -24,9 +24,12 @@ properties:
oneOf: oneOf:
- items: - items:
- enum: - enum:
- qcom,sc7280-bwmon
- qcom,sdm845-bwmon - qcom,sdm845-bwmon
- const: qcom,msm8998-bwmon - const: qcom,msm8998-bwmon
- const: qcom,msm8998-bwmon # BWMON v4 - const: qcom,msm8998-bwmon # BWMON v4
- const: qcom,sc7280-llcc-bwmon # BWMON v5
- const: qcom,sdm845-llcc-bwmon # BWMON v5
interconnects: interconnects:
maxItems: 1 maxItems: 1
......
* Samsung Exynos5 G-Scaler device
G-Scaler is used for scaling and color space conversion on Exynos5 SoCs.
Required properties:
- compatible: should be one of
"samsung,exynos5250-gsc"
"samsung,exynos5420-gsc"
"samsung,exynos5433-gsc"
"samsung,exynos5-gsc" (deprecated)
- reg: should contain G-Scaler physical address location and length.
- interrupts: should contain G-Scaler interrupt number
Optional properties:
- samsung,sysreg: handle to syscon used to control the system registers to
set writeback input and destination
Example:
gsc_0: gsc@13e00000 {
compatible = "samsung,exynos5250-gsc";
reg = <0x13e00000 0x1000>;
interrupts = <0 85 0>;
};
Aliases:
Each G-Scaler node should have a numbered alias in the aliases node,
in the form of gscN, N = 0...3. G-Scaler driver uses these aliases
to retrieve the device IDs using "of_alias_get_id()" call.
Example:
aliases {
gsc0 =&gsc_0;
gsc1 =&gsc_1;
gsc2 =&gsc_2;
gsc3 =&gsc_3;
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/samsung,exynos5250-gsc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Samsung Exynos SoC G-Scaler
maintainers:
- Inki Dae <inki.dae@samsung.com>
- Krzysztof Kozlowski <krzk@kernel.org>
- Seung-Woo Kim <sw0312.kim@samsung.com
description:
G-Scaler is used for scaling and color space conversion on Samsung Exynos
SoCs.
Each G-Scaler node should have a numbered alias in the aliases node, in the
form of gscN, N = 0...3.
properties:
compatible:
oneOf:
- items:
- enum:
- samsung,exynos5250-gsc
- samsung,exynos5420-gsc
- const: samsung,exynos5-gsc
- enum:
- samsung,exynos5433-gsc
- const: samsung,exynos5-gsc
deprecated: True
clocks:
minItems: 1
maxItems: 5
clock-names:
minItems: 1
maxItems: 5
interrupts:
maxItems: 1
iommus:
maxItems: 1
power-domains:
maxItems: 1
reg:
maxItems: 1
samsung,sysreg:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Syscon used to control the system registers to set writeback input and destination.
required:
- compatible
- clocks
- clock-names
- interrupts
- reg
allOf:
- if:
properties:
compatible:
contains:
enum:
- samsung,exynos5-gsc
- samsung,exynos5250-gsc
- samsung,exynos5420-gsc
then:
properties:
clocks:
maxItems: 1
clock-names:
items:
- const: gscl
else:
properties:
clocks:
minItems: 5
clock-names:
items:
- const: pclk
- const: aclk
- const: aclk_xiu
- const: aclk_gsclbend
- const: gsd
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/exynos5250.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
video-scaler@13e00000 {
compatible = "samsung,exynos5250-gsc", "samsung,exynos5-gsc";
reg = <0x13e00000 0x1000>;
interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
power-domains = <&pd_gsc>;
clocks = <&clock CLK_GSCL0>;
clock-names = "gscl";
iommus = <&sysmmu_gsc0>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/memory-controllers/brcm,brcmstb-memc-ddr.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Memory controller (MEMC) for Broadcom STB
maintainers:
- Florian Fainelli <f.fainelli@gmail.com>
properties:
compatible:
items:
- enum:
- brcm,brcmstb-memc-ddr-rev-b.1.x
- brcm,brcmstb-memc-ddr-rev-b.2.0
- brcm,brcmstb-memc-ddr-rev-b.2.1
- brcm,brcmstb-memc-ddr-rev-b.2.2
- brcm,brcmstb-memc-ddr-rev-b.2.3
- brcm,brcmstb-memc-ddr-rev-b.2.5
- brcm,brcmstb-memc-ddr-rev-b.2.6
- brcm,brcmstb-memc-ddr-rev-b.2.7
- brcm,brcmstb-memc-ddr-rev-b.2.8
- brcm,brcmstb-memc-ddr-rev-b.3.0
- brcm,brcmstb-memc-ddr-rev-b.3.1
- brcm,brcmstb-memc-ddr-rev-c.1.0
- brcm,brcmstb-memc-ddr-rev-c.1.1
- brcm,brcmstb-memc-ddr-rev-c.1.2
- brcm,brcmstb-memc-ddr-rev-c.1.3
- brcm,brcmstb-memc-ddr-rev-c.1.4
- const: brcm,brcmstb-memc-ddr
reg:
maxItems: 1
clock-frequency:
description: DDR PHY frequency in Hz
required:
- compatible
- reg
additionalProperties: false
examples:
- |
memory-controller@9902000 {
compatible = "brcm,brcmstb-memc-ddr-rev-c.1.1", "brcm,brcmstb-memc-ddr";
reg = <0x9902000 0x600>;
clock-frequency = <2133000000>;
};
...@@ -16,7 +16,7 @@ description: | ...@@ -16,7 +16,7 @@ description: |
MediaTek SMI have two generations of HW architecture, here is the list MediaTek SMI have two generations of HW architecture, here is the list
which generation the SoCs use: which generation the SoCs use:
generation 1: mt2701 and mt7623. generation 1: mt2701 and mt7623.
generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8192 and mt8195. generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8188, mt8192 and mt8195.
There's slight differences between the two SMI, for generation 2, the There's slight differences between the two SMI, for generation 2, the
register which control the iommu port is at each larb's register base. But register which control the iommu port is at each larb's register base. But
...@@ -37,6 +37,8 @@ properties: ...@@ -37,6 +37,8 @@ properties:
- mediatek,mt8173-smi-common - mediatek,mt8173-smi-common
- mediatek,mt8183-smi-common - mediatek,mt8183-smi-common
- mediatek,mt8186-smi-common - mediatek,mt8186-smi-common
- mediatek,mt8188-smi-common-vdo
- mediatek,mt8188-smi-common-vpp
- mediatek,mt8192-smi-common - mediatek,mt8192-smi-common
- mediatek,mt8195-smi-common-vdo - mediatek,mt8195-smi-common-vdo
- mediatek,mt8195-smi-common-vpp - mediatek,mt8195-smi-common-vpp
...@@ -144,7 +146,16 @@ allOf: ...@@ -144,7 +146,16 @@ allOf:
- const: gals0 - const: gals0
- const: gals1 - const: gals1
else: # for gen2 HW that don't have gals - if: # for gen2 HW that don't have gals
properties:
compatible:
enum:
- mediatek,mt2712-smi-common
- mediatek,mt6795-smi-common
- mediatek,mt8167-smi-common
- mediatek,mt8173-smi-common
then:
properties: properties:
clocks: clocks:
minItems: 2 minItems: 2
......
...@@ -25,6 +25,7 @@ properties: ...@@ -25,6 +25,7 @@ properties:
- mediatek,mt8173-smi-larb - mediatek,mt8173-smi-larb
- mediatek,mt8183-smi-larb - mediatek,mt8183-smi-larb
- mediatek,mt8186-smi-larb - mediatek,mt8186-smi-larb
- mediatek,mt8188-smi-larb
- mediatek,mt8192-smi-larb - mediatek,mt8192-smi-larb
- mediatek,mt8195-smi-larb - mediatek,mt8195-smi-larb
...@@ -78,6 +79,7 @@ allOf: ...@@ -78,6 +79,7 @@ allOf:
enum: enum:
- mediatek,mt8183-smi-larb - mediatek,mt8183-smi-larb
- mediatek,mt8186-smi-larb - mediatek,mt8186-smi-larb
- mediatek,mt8188-smi-larb
- mediatek,mt8195-smi-larb - mediatek,mt8195-smi-larb
then: then:
...@@ -111,6 +113,7 @@ allOf: ...@@ -111,6 +113,7 @@ allOf:
- mediatek,mt2712-smi-larb - mediatek,mt2712-smi-larb
- mediatek,mt6779-smi-larb - mediatek,mt6779-smi-larb
- mediatek,mt8186-smi-larb - mediatek,mt8186-smi-larb
- mediatek,mt8188-smi-larb
- mediatek,mt8192-smi-larb - mediatek,mt8192-smi-larb
- mediatek,mt8195-smi-larb - mediatek,mt8195-smi-larb
......
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/memory-controllers/snps,dw-umctl2-ddrc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Synopsys DesignWare Universal Multi-Protocol Memory Controller
maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
- Manish Narani <manish.narani@xilinx.com>
- Michal Simek <michal.simek@xilinx.com>
description: |
Synopsys DesignWare Enhanced uMCTL2 DDR Memory Controller is capable of
working with the memory devices supporting up to (LP)DDR4 protocol. It can
be equipped with SEC/DEC ECC feature if DRAM data bus width is either
16-bits or 32-bits or 64-bits wide.
For instance the ZynqMP DDR controller is based on the DW uMCTL2 v2.40a
controller. It has an optional SEC/DEC ECC support in 64- and 32-bits
bus width configurations.
properties:
compatible:
oneOf:
- deprecated: true
description: Synopsys DW uMCTL2 DDR controller v3.80a
const: snps,ddrc-3.80a
- description: Synopsys DW uMCTL2 DDR controller
const: snps,dw-umctl2-ddrc
- description: Xilinx ZynqMP DDR controller v2.40a
const: xlnx,zynqmp-ddrc-2.40a
interrupts:
description:
DW uMCTL2 DDRC IP-core provides individual IRQ signal for each event":"
ECC Corrected Error, ECC Uncorrected Error, ECC Address Protection,
Scrubber-Done signal, DFI Parity/CRC Error. Some platforms may have the
signals merged before they reach the IRQ controller or have some of them
absent in case if the corresponding feature is unavailable/disabled.
minItems: 1
maxItems: 5
interrupt-names:
minItems: 1
maxItems: 5
oneOf:
- description: Common ECC CE/UE/Scrubber/DFI Errors IRQ
items:
- const: ecc
- description: Individual ECC CE/UE/Scrubber/DFI Errors IRQs
items:
enum: [ ecc_ce, ecc_ue, ecc_ap, ecc_sbr, dfi_e ]
reg:
maxItems: 1
clocks:
description:
A standard set of the clock sources contains CSRs bus clock, AXI-ports
reference clock, DDRC core clock, Scrubber standalone clock
(synchronous to the DDRC clock).
minItems: 1
maxItems: 4
clock-names:
minItems: 1
maxItems: 4
items:
enum: [ pclk, aclk, core, sbr ]
resets:
description:
Each clock domain can have separate reset signal.
minItems: 1
maxItems: 4
reset-names:
minItems: 1
maxItems: 4
items:
enum: [ prst, arst, core, sbr ]
required:
- compatible
- reg
- interrupts
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
memory-controller@fd070000 {
compatible = "xlnx,zynqmp-ddrc-2.40a";
reg = <0xfd070000 0x30000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "ecc";
};
- |
#include <dt-bindings/interrupt-controller/irq.h>
memory-controller@3d400000 {
compatible = "snps,dw-umctl2-ddrc";
reg = <0x3d400000 0x400000>;
interrupts = <147 IRQ_TYPE_LEVEL_HIGH>, <148 IRQ_TYPE_LEVEL_HIGH>,
<149 IRQ_TYPE_LEVEL_HIGH>, <150 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "ecc_ce", "ecc_ue", "ecc_sbr", "dfi_e";
clocks = <&pclk>, <&aclk>, <&core_clk>, <&sbr_clk>;
clock-names = "pclk", "aclk", "core", "sbr";
};
...
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/memory-controllers/synopsys,ddrc-ecc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Synopsys IntelliDDR Multi Protocol memory controller
maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
- Manish Narani <manish.narani@xilinx.com>
- Michal Simek <michal.simek@xilinx.com>
description: |
The ZynqMP DDR ECC controller has an optional ECC support in 64-bit and
32-bit bus width configurations.
The Zynq DDR ECC controller has an optional ECC support in half-bus width
(16-bit) configuration.
These both ECC controllers correct single bit ECC errors and detect double bit
ECC errors.
properties:
compatible:
enum:
- snps,ddrc-3.80a
- xlnx,zynq-ddrc-a05
- xlnx,zynqmp-ddrc-2.40a
interrupts:
maxItems: 1
reg:
maxItems: 1
required:
- compatible
- reg
allOf:
- if:
properties:
compatible:
contains:
enum:
- snps,ddrc-3.80a
- xlnx,zynqmp-ddrc-2.40a
then:
required:
- interrupts
else:
properties:
interrupts: false
additionalProperties: false
examples:
- |
memory-controller@f8006000 {
compatible = "xlnx,zynq-ddrc-a05";
reg = <0xf8006000 0x1000>;
};
- |
axi {
#address-cells = <2>;
#size-cells = <2>;
memory-controller@fd070000 {
compatible = "xlnx,zynqmp-ddrc-2.40a";
reg = <0x0 0xfd070000 0x0 0x30000>;
interrupt-parent = <&gic>;
interrupts = <0 112 4>;
};
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/memory-controllers/xlnx,zynq-ddrc-a05.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Zynq A05 DDR Memory Controller
maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
- Manish Narani <manish.narani@xilinx.com>
- Michal Simek <michal.simek@xilinx.com>
description:
The Zynq DDR ECC controller has an optional ECC support in half-bus width
(16-bit) configuration. It is cappable of correcting single bit ECC errors
and detecting double bit ECC errors.
properties:
compatible:
const: xlnx,zynq-ddrc-a05
reg:
maxItems: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
memory-controller@f8006000 {
compatible = "xlnx,zynq-ddrc-a05";
reg = <0xf8006000 0x1000>;
};
...
...@@ -40,6 +40,8 @@ properties: ...@@ -40,6 +40,8 @@ properties:
- allwinner,sun50i-a64-system-controller - allwinner,sun50i-a64-system-controller
- brcm,cru-clkset - brcm,cru-clkset
- freecom,fsg-cs2-system-controller - freecom,fsg-cs2-system-controller
- fsl,imx93-aonmix-ns-syscfg
- fsl,imx93-wakeupmix-syscfg
- hisilicon,dsa-subctrl - hisilicon,dsa-subctrl
- hisilicon,hi6220-sramctrl - hisilicon,hi6220-sramctrl
- hisilicon,pcie-sas-subctrl - hisilicon,pcie-sas-subctrl
......
...@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# ...@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek Power Domains Controller title: Mediatek Power Domains Controller
maintainers: maintainers:
- Weiyi Lu <weiyi.lu@mediatek.com> - MandyJH Liu <mandyjh.liu@mediatek.com>
- Matthias Brugger <mbrugger@suse.com> - Matthias Brugger <mbrugger@suse.com>
description: | description: |
...@@ -19,7 +19,7 @@ description: | ...@@ -19,7 +19,7 @@ description: |
properties: properties:
$nodename: $nodename:
const: power-controller pattern: '^power-controller(@[0-9a-f]+)?$'
compatible: compatible:
enum: enum:
...@@ -42,6 +42,23 @@ properties: ...@@ -42,6 +42,23 @@ properties:
patternProperties: patternProperties:
"^power-domain@[0-9a-f]+$": "^power-domain@[0-9a-f]+$":
$ref: "#/$defs/power-domain-node"
patternProperties:
"^power-domain@[0-9a-f]+$":
$ref: "#/$defs/power-domain-node"
patternProperties:
"^power-domain@[0-9a-f]+$":
$ref: "#/$defs/power-domain-node"
patternProperties:
"^power-domain@[0-9a-f]+$":
$ref: "#/$defs/power-domain-node"
unevaluatedProperties: false
unevaluatedProperties: false
unevaluatedProperties: false
unevaluatedProperties: false
$defs:
power-domain-node:
type: object type: object
description: | description: |
Represents the power domains within the power controller node as documented Represents the power domains within the power controller node as documented
...@@ -100,123 +117,9 @@ patternProperties: ...@@ -100,123 +117,9 @@ patternProperties:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the device containing the SMI register range. description: phandle to the device containing the SMI register range.
patternProperties:
"^power-domain@[0-9a-f]+$":
type: object
description: |
Represents a power domain child within a power domain parent node.
properties:
'#power-domain-cells':
description:
Must be 0 for nodes representing a single PM domain and 1 for nodes
providing multiple PM domains.
'#address-cells':
const: 1
'#size-cells':
const: 0
reg:
maxItems: 1
clocks:
description: |
A number of phandles to clocks that need to be enabled during domain
power-up sequencing.
clock-names:
description: |
List of names of clocks, in order to match the power-up sequencing
for each power domain we need to group the clocks by name. BASIC
clocks need to be enabled before enabling the corresponding power
domain, and should not have a '-' in their name (i.e mm, mfg, venc).
SUSBYS clocks need to be enabled before releasing the bus protection,
and should contain a '-' in their name (i.e mm-0, isp-0, cam-0).
In order to follow properly the power-up sequencing, the clocks must
be specified by order, adding first the BASIC clocks followed by the
SUSBSYS clocks.
domain-supply:
description: domain regulator supply.
mediatek,infracfg:
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the device containing the INFRACFG register range.
mediatek,smi:
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the device containing the SMI register range.
patternProperties:
"^power-domain@[0-9a-f]+$":
type: object
description: |
Represents a power domain child within a power domain parent node.
properties:
'#power-domain-cells':
description:
Must be 0 for nodes representing a single PM domain and 1 for nodes
providing multiple PM domains.
'#address-cells':
const: 1
'#size-cells':
const: 0
reg:
maxItems: 1
clocks:
description: |
A number of phandles to clocks that need to be enabled during domain
power-up sequencing.
clock-names:
description: |
List of names of clocks, in order to match the power-up sequencing
for each power domain we need to group the clocks by name. BASIC
clocks need to be enabled before enabling the corresponding power
domain, and should not have a '-' in their name (i.e mm, mfg, venc).
SUSBYS clocks need to be enabled before releasing the bus protection,
and should contain a '-' in their name (i.e mm-0, isp-0, cam-0).
In order to follow properly the power-up sequencing, the clocks must
be specified by order, adding first the BASIC clocks followed by the
SUSBSYS clocks.
domain-supply:
description: domain regulator supply.
mediatek,infracfg:
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the device containing the INFRACFG register range.
mediatek,smi:
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the device containing the SMI register range.
required:
- reg
additionalProperties: false
required:
- reg
additionalProperties: false
required: required:
- reg - reg
additionalProperties: false
required: required:
- compatible - compatible
......
...@@ -40,6 +40,7 @@ properties: ...@@ -40,6 +40,7 @@ properties:
- qcom,sm6115-rpmpd - qcom,sm6115-rpmpd
- qcom,sm6125-rpmpd - qcom,sm6125-rpmpd
- qcom,sm6350-rpmhpd - qcom,sm6350-rpmhpd
- qcom,sm6375-rpmpd
- qcom,sm8150-rpmhpd - qcom,sm8150-rpmhpd
- qcom,sm8250-rpmhpd - qcom,sm8250-rpmhpd
- qcom,sm8350-rpmhpd - qcom,sm8350-rpmhpd
......
...@@ -41,6 +41,8 @@ properties: ...@@ -41,6 +41,8 @@ properties:
- rockchip,rk3368-power-controller - rockchip,rk3368-power-controller
- rockchip,rk3399-power-controller - rockchip,rk3399-power-controller
- rockchip,rk3568-power-controller - rockchip,rk3568-power-controller
- rockchip,rk3588-power-controller
- rockchip,rv1126-power-controller
"#power-domain-cells": "#power-domain-cells":
const: 1 const: 1
...@@ -119,6 +121,8 @@ $defs: ...@@ -119,6 +121,8 @@ $defs:
"include/dt-bindings/power/rk3368-power.h" "include/dt-bindings/power/rk3368-power.h"
"include/dt-bindings/power/rk3399-power.h" "include/dt-bindings/power/rk3399-power.h"
"include/dt-bindings/power/rk3568-power.h" "include/dt-bindings/power/rk3568-power.h"
"include/dt-bindings/power/rk3588-power.h"
"include/dt-bindings/power/rockchip,rv1126-power.h"
clocks: clocks:
minItems: 1 minItems: 1
......
...@@ -58,6 +58,7 @@ properties: ...@@ -58,6 +58,7 @@ properties:
- rockchip,rk3568-pmu-io-voltage-domain - rockchip,rk3568-pmu-io-voltage-domain
- rockchip,rv1108-io-voltage-domain - rockchip,rv1108-io-voltage-domain
- rockchip,rv1108-pmu-io-voltage-domain - rockchip,rv1108-pmu-io-voltage-domain
- rockchip,rv1126-pmu-io-voltage-domain
required: required:
- compatible - compatible
...@@ -78,6 +79,7 @@ allOf: ...@@ -78,6 +79,7 @@ allOf:
- $ref: "#/$defs/rk3568-pmu" - $ref: "#/$defs/rk3568-pmu"
- $ref: "#/$defs/rv1108" - $ref: "#/$defs/rv1108"
- $ref: "#/$defs/rv1108-pmu" - $ref: "#/$defs/rv1108-pmu"
- $ref: "#/$defs/rv1126-pmu"
$defs: $defs:
px30: px30:
...@@ -344,6 +346,34 @@ $defs: ...@@ -344,6 +346,34 @@ $defs:
pmu-supply: pmu-supply:
description: The supply connected to PMUIO_VDD. description: The supply connected to PMUIO_VDD.
rv1126-pmu:
if:
properties:
compatible:
contains:
const: rockchip,rv1126-pmu-io-voltage-domain
then:
properties:
vccio1-supply:
description: The supply connected to VCCIO1.
vccio2-supply:
description: The supply connected to VCCIO2.
vccio3-supply:
description: The supply connected to VCCIO3.
vccio4-supply:
description: The supply connected to VCCIO4.
vccio5-supply:
description: The supply connected to VCCIO5.
vccio6-supply:
description: The supply connected to VCCIO6.
vccio7-supply:
description: The supply connected to VCCIO7.
pmuio0-supply:
description: The supply connected to PMUIO0.
pmuio1-supply:
description: The supply connected to PMUIO1.
examples: examples:
- | - |
io-domains { io-domains {
......
...@@ -27,25 +27,22 @@ properties: ...@@ -27,25 +27,22 @@ properties:
const: 1 const: 1
power-domains: power-domains:
minItems: 4
maxItems: 4 maxItems: 4
power-domain-names: power-domain-names:
items: maxItems: 4
- const: bus
- const: g1
- const: g2
- const: h1
clocks: clocks:
minItems: 3
maxItems: 3 maxItems: 3
clock-names: clock-names:
items: maxItems: 3
- const: g1
- const: g2 interconnects:
- const: h1 maxItems: 3
interconnect-names:
maxItems: 3
required: required:
- compatible - compatible
...@@ -55,6 +52,97 @@ required: ...@@ -55,6 +52,97 @@ required:
- clocks - clocks
- clock-names - clock-names
allOf:
- if:
properties:
compatible:
contains:
const: fsl,imx8mm-vpu-blk-ctrl
then:
properties:
power-domains:
items:
- description: bus power domain
- description: G1 decoder power domain
- description: G2 decoder power domain
- description: H1 encoder power domain
power-domain-names:
items:
- const: bus
- const: g1
- const: g2
- const: h1
clocks:
items:
- description: G1 decoder clk
- description: G2 decoder clk
- description: H1 encoder clk
clock-names:
items:
- const: g1
- const: g2
- const: h1
interconnects:
items:
- description: G1 decoder interconnect
- description: G2 decoder interconnect
- description: H1 encoder power domain
interconnect-names:
items:
- const: g1
- const: g2
- const: h1
- if:
properties:
compatible:
contains:
const: fsl,imx8mp-vpu-blk-ctrl
then:
properties:
power-domains:
items:
- description: bus power domain
- description: G1 decoder power domain
- description: G2 decoder power domain
- description: VC8000E encoder power domain
power-domain-names:
items:
- const: bus
- const: g1
- const: g2
- const: vc8000e
clocks:
items:
- description: G1 decoder clk
- description: G2 decoder clk
- description: VC8000E encoder clk
clock-names:
items:
- const: g1
- const: g2
- const: vc8000e
interconnects:
items:
- description: G1 decoder interconnect
- description: G2 decoder interconnect
- description: VC8000E encoder interconnect
interconnect-names:
items:
- const: g1
- const: g2
- const: vc8000e
additionalProperties: false additionalProperties: false
examples: examples:
......
...@@ -52,6 +52,15 @@ properties: ...@@ -52,6 +52,15 @@ properties:
- const: ref_266m - const: ref_266m
- const: ref_24m - const: ref_24m
interconnects:
maxItems: 3
interconnect-names:
items:
- const: hrv
- const: lcdif-hdmi
- const: hdcp
required: required:
- compatible - compatible
- reg - reg
......
...@@ -48,6 +48,16 @@ properties: ...@@ -48,6 +48,16 @@ properties:
- const: usb - const: usb
- const: pcie - const: pcie
interconnects:
maxItems: 4
interconnect-names:
items:
- const: noc-pcie
- const: usb1
- const: usb2
- const: pcie
required: required:
- compatible - compatible
- reg - reg
......
...@@ -64,6 +64,20 @@ properties: ...@@ -64,6 +64,20 @@ properties:
- const: isp - const: isp
- const: phy - const: phy
interconnects:
maxItems: 8
interconnect-names:
items:
- const: lcdif-rd
- const: lcdif-wr
- const: isi0
- const: isi1
- const: isi2
- const: isp0
- const: isp1
- const: dwe
required: required:
- compatible - compatible
- reg - reg
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/imx/fsl,imx93-media-blk-ctrl.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP i.MX93 Media blk-ctrl
maintainers:
- Peng Fan <peng.fan@nxp.com>
description:
The i.MX93 MEDIAMIX domain contains control and status registers known
as MEDIAMIX Block Control (MEDIAMIX BLK_CTRL). These registers include
clocking, reset, and miscellaneous top-level controls for peripherals
within the MEDIAMIX domain
properties:
compatible:
items:
- const: fsl,imx93-media-blk-ctrl
- const: syscon
reg:
maxItems: 1
'#power-domain-cells':
const: 1
power-domains:
maxItems: 1
clocks:
maxItems: 10
clock-names:
items:
- const: apb
- const: axi
- const: nic
- const: disp
- const: cam
- const: pxp
- const: lcdif
- const: isi
- const: csi
- const: dsi
required:
- compatible
- reg
- power-domains
- clocks
- clock-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/imx93-clock.h>
#include <dt-bindings/power/fsl,imx93-power.h>
media_blk_ctrl: system-controller@4ac10000 {
compatible = "fsl,imx93-media-blk-ctrl", "syscon";
reg = <0x4ac10000 0x10000>;
power-domains = <&mediamix>;
clocks = <&clk IMX93_CLK_MEDIA_APB>,
<&clk IMX93_CLK_MEDIA_AXI>,
<&clk IMX93_CLK_NIC_MEDIA_GATE>,
<&clk IMX93_CLK_MEDIA_DISP_PIX>,
<&clk IMX93_CLK_CAM_PIX>,
<&clk IMX93_CLK_PXP_GATE>,
<&clk IMX93_CLK_LCDIF_GATE>,
<&clk IMX93_CLK_ISI_GATE>,
<&clk IMX93_CLK_MIPI_CSI_GATE>,
<&clk IMX93_CLK_MIPI_DSI_GATE>;
clock-names = "apb", "axi", "nic", "disp", "cam",
"pxp", "lcdif", "isi", "csi", "dsi";
#power-domain-cells = <1>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/soc/imx/fsl,imx93-src.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP i.MX93 System Reset Controller
maintainers:
- Peng Fan <peng.fan@nxp.com>
description: |
The System Reset Controller (SRC) is responsible for the generation of
all the system reset signals and boot argument latching.
Its main functions are as follows,
- Deals with all global system reset sources from other modules,
and generates global system reset.
- Responsible for power gating of MIXs (Slices) and their memory
low power control.
properties:
compatible:
items:
- const: fsl,imx93-src
- const: syscon
reg:
maxItems: 1
ranges: true
'#address-cells':
const: 1
'#size-cells':
const: 1
patternProperties:
"power-domain@[0-9a-f]+$":
type: object
properties:
compatible:
items:
- const: fsl,imx93-src-slice
'#power-domain-cells':
const: 0
reg:
items:
- description: mix slice register region
- description: mem slice register region
clocks:
description: |
A number of phandles to clocks that need to be enabled
during domain power-up sequencing to ensure reset
propagation into devices located inside this power domain.
minItems: 1
maxItems: 5
required:
- compatible
- '#power-domain-cells'
- reg
required:
- compatible
- reg
- ranges
- '#address-cells'
- '#size-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/imx93-clock.h>
system-controller@44460000 {
compatible = "fsl,imx93-src", "syscon";
reg = <0x44460000 0x10000>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
mediamix: power-domain@0 {
compatible = "fsl,imx93-src-slice";
reg = <0x44462400 0x400>, <0x44465800 0x400>;
#power-domain-cells = <0>;
clocks = <&clk IMX93_CLK_MEDIA_AXI>,
<&clk IMX93_CLK_MEDIA_APB>;
};
};
...@@ -26,10 +26,12 @@ properties: ...@@ -26,10 +26,12 @@ properties:
enum: enum:
- mediatek,mt2701-disp-mutex - mediatek,mt2701-disp-mutex
- mediatek,mt2712-disp-mutex - mediatek,mt2712-disp-mutex
- mediatek,mt6795-disp-mutex
- mediatek,mt8167-disp-mutex - mediatek,mt8167-disp-mutex
- mediatek,mt8173-disp-mutex - mediatek,mt8173-disp-mutex
- mediatek,mt8183-disp-mutex - mediatek,mt8183-disp-mutex
- mediatek,mt8186-disp-mutex - mediatek,mt8186-disp-mutex
- mediatek,mt8186-mdp3-mutex
- mediatek,mt8192-disp-mutex - mediatek,mt8192-disp-mutex
- mediatek,mt8195-disp-mutex - mediatek,mt8195-disp-mutex
......
...@@ -28,6 +28,7 @@ Required properties in pwrap device node. ...@@ -28,6 +28,7 @@ Required properties in pwrap device node.
"mediatek,mt8173-pwrap" for MT8173 SoCs "mediatek,mt8173-pwrap" for MT8173 SoCs
"mediatek,mt8183-pwrap" for MT8183 SoCs "mediatek,mt8183-pwrap" for MT8183 SoCs
"mediatek,mt8186-pwrap" for MT8186 SoCs "mediatek,mt8186-pwrap" for MT8186 SoCs
"mediatek,mt8188-pwrap", "mediatek,mt8195-pwrap" for MT8188 SoCs
"mediatek,mt8195-pwrap" for MT8195 SoCs "mediatek,mt8195-pwrap" for MT8195 SoCs
"mediatek,mt8516-pwrap" for MT8516 SoCs "mediatek,mt8516-pwrap" for MT8516 SoCs
- interrupts: IRQ for pwrap in SOC - interrupts: IRQ for pwrap in SOC
......
...@@ -20,6 +20,7 @@ properties: ...@@ -20,6 +20,7 @@ properties:
compatible: compatible:
enum: enum:
- qcom,rpmh-stats - qcom,rpmh-stats
- qcom,sdm845-rpmh-stats
- qcom,rpm-stats - qcom,rpm-stats
# For older RPM firmware versions with fixed offset for the sleep stats # For older RPM firmware versions with fixed offset for the sleep stats
- qcom,apq8084-rpm-stats - qcom,apq8084-rpm-stats
......
...@@ -16,9 +16,12 @@ properties: ...@@ -16,9 +16,12 @@ properties:
- enum: - enum:
- rockchip,rk3288-sgrf - rockchip,rk3288-sgrf
- rockchip,rk3566-pipe-grf - rockchip,rk3566-pipe-grf
- rockchip,rk3568-pcie3-phy-grf
- rockchip,rk3568-pipe-grf - rockchip,rk3568-pipe-grf
- rockchip,rk3568-pipe-phy-grf - rockchip,rk3568-pipe-phy-grf
- rockchip,rk3568-usb2phy-grf - rockchip,rk3568-usb2phy-grf
- rockchip,rk3588-pcie3-phy-grf
- rockchip,rk3588-pcie3-pipe-grf
- rockchip,rv1108-usbgrf - rockchip,rv1108-usbgrf
- const: syscon - const: syscon
- items: - items:
...@@ -28,6 +31,7 @@ properties: ...@@ -28,6 +31,7 @@ properties:
- rockchip,px30-usb2phy-grf - rockchip,px30-usb2phy-grf
- rockchip,rk3036-grf - rockchip,rk3036-grf
- rockchip,rk3066-grf - rockchip,rk3066-grf
- rockchip,rk3128-grf
- rockchip,rk3188-grf - rockchip,rk3188-grf
- rockchip,rk3228-grf - rockchip,rk3228-grf
- rockchip,rk3288-grf - rockchip,rk3288-grf
...@@ -45,6 +49,8 @@ properties: ...@@ -45,6 +49,8 @@ properties:
- rockchip,rk3568-pmugrf - rockchip,rk3568-pmugrf
- rockchip,rv1108-grf - rockchip,rv1108-grf
- rockchip,rv1108-pmugrf - rockchip,rv1108-pmugrf
- rockchip,rv1126-grf
- rockchip,rv1126-pmugrf
- const: syscon - const: syscon
- const: simple-mfd - const: simple-mfd
...@@ -178,6 +184,7 @@ allOf: ...@@ -178,6 +184,7 @@ allOf:
contains: contains:
enum: enum:
- rockchip,px30-usb2phy-grf - rockchip,px30-usb2phy-grf
- rockchip,rk3128-grf
- rockchip,rk3228-grf - rockchip,rk3228-grf
- rockchip,rk3308-usb2phy-grf - rockchip,rk3308-usb2phy-grf
- rockchip,rk3328-usb2phy-grf - rockchip,rk3328-usb2phy-grf
......
...@@ -3125,6 +3125,8 @@ W: http://wiki.xilinx.com ...@@ -3125,6 +3125,8 @@ W: http://wiki.xilinx.com
T: git https://github.com/Xilinx/linux-xlnx.git T: git https://github.com/Xilinx/linux-xlnx.git
F: Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml F: Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
F: Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml F: Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml
F: Documentation/devicetree/bindings/memory-controllers/snps,dw-umctl2-ddrc.yaml
F: Documentation/devicetree/bindings/memory-controllers/xlnx,zynq-ddrc-a05.yaml
F: Documentation/devicetree/bindings/spi/xlnx,zynq-qspi.yaml F: Documentation/devicetree/bindings/spi/xlnx,zynq-qspi.yaml
F: arch/arm/mach-zynq/ F: arch/arm/mach-zynq/
F: drivers/clocksource/timer-cadence-ttc.c F: drivers/clocksource/timer-cadence-ttc.c
...@@ -5407,8 +5409,8 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git ...@@ -5407,8 +5409,8 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
F: drivers/cpuidle/cpuidle-big_little.c F: drivers/cpuidle/cpuidle-big_little.c
CPUIDLE DRIVER - ARM EXYNOS CPUIDLE DRIVER - ARM EXYNOS
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
M: Daniel Lezcano <daniel.lezcano@linaro.org> M: Daniel Lezcano <daniel.lezcano@linaro.org>
R: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
M: Kukjin Kim <kgene@kernel.org> M: Kukjin Kim <kgene@kernel.org>
L: linux-pm@vger.kernel.org L: linux-pm@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org L: linux-samsung-soc@vger.kernel.org
...@@ -12441,7 +12443,6 @@ F: drivers/power/supply/max77976_charger.c ...@@ -12441,7 +12443,6 @@ F: drivers/power/supply/max77976_charger.c
MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-pm@vger.kernel.org L: linux-pm@vger.kernel.org
S: Supported S: Supported
B: mailto:linux-samsung-soc@vger.kernel.org B: mailto:linux-samsung-soc@vger.kernel.org
...@@ -12453,7 +12454,6 @@ F: drivers/power/supply/max77693_charger.c ...@@ -12453,7 +12454,6 @@ F: drivers/power/supply/max77693_charger.c
MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS
M: Chanwoo Choi <cw00.choi@samsung.com> M: Chanwoo Choi <cw00.choi@samsung.com>
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
S: Supported S: Supported
B: mailto:linux-samsung-soc@vger.kernel.org B: mailto:linux-samsung-soc@vger.kernel.org
...@@ -16587,14 +16587,6 @@ T: git git://linuxtv.org/media_tree.git ...@@ -16587,14 +16587,6 @@ T: git git://linuxtv.org/media_tree.git
F: drivers/media/usb/pwc/* F: drivers/media/usb/pwc/*
F: include/trace/events/pwc.h F: include/trace/events/pwc.h
PWM FAN DRIVER
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-hwmon@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/hwmon/pwm-fan.txt
F: Documentation/hwmon/pwm-fan.rst
F: drivers/hwmon/pwm-fan.c
PWM IR Transmitter PWM IR Transmitter
M: Sean Young <sean@mess.org> M: Sean Young <sean@mess.org>
L: linux-media@vger.kernel.org L: linux-media@vger.kernel.org
...@@ -18055,7 +18047,6 @@ F: drivers/platform/x86/samsung-laptop.c ...@@ -18055,7 +18047,6 @@ F: drivers/platform/x86/samsung-laptop.c
SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org L: linux-samsung-soc@vger.kernel.org
S: Supported S: Supported
......
...@@ -67,11 +67,7 @@ ...@@ -67,11 +67,7 @@
#if defined(CONFIG_ARCH_SA1100) #if defined(CONFIG_ARCH_SA1100)
.macro loadsp, rb, tmp1, tmp2 .macro loadsp, rb, tmp1, tmp2
mov \rb, #0x80000000 @ physical base address mov \rb, #0x80000000 @ physical base address
#ifdef CONFIG_DEBUG_LL_SER3
add \rb, \rb, #0x00050000 @ Ser3
#else
add \rb, \rb, #0x00010000 @ Ser1 add \rb, \rb, #0x00010000 @ Ser1
#endif
.endm .endm
#else #else
.macro loadsp, rb, tmp1, tmp2 .macro loadsp, rb, tmp1, tmp2
......
...@@ -85,7 +85,7 @@ static int wait_lpc_idle(void __iomem *mbase, unsigned int waitcnt) ...@@ -85,7 +85,7 @@ static int wait_lpc_idle(void __iomem *mbase, unsigned int waitcnt)
ndelay(LPC_NSEC_PERWAIT); ndelay(LPC_NSEC_PERWAIT);
} while (--waitcnt); } while (--waitcnt);
return -ETIME; return -ETIMEDOUT;
} }
/* /*
...@@ -347,7 +347,7 @@ static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev, ...@@ -347,7 +347,7 @@ static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev,
unsigned long sys_port; unsigned long sys_port;
resource_size_t len = resource_size(res); resource_size_t len = resource_size(res);
sys_port = logic_pio_trans_hwaddr(&host->fwnode, res->start, len); sys_port = logic_pio_trans_hwaddr(acpi_fwnode_handle(host), res->start, len);
if (sys_port == ~0UL) if (sys_port == ~0UL)
return -EFAULT; return -EFAULT;
...@@ -472,9 +472,7 @@ static int hisi_lpc_acpi_clear_enumerated(struct acpi_device *adev, void *not_us ...@@ -472,9 +472,7 @@ static int hisi_lpc_acpi_clear_enumerated(struct acpi_device *adev, void *not_us
struct hisi_lpc_acpi_cell { struct hisi_lpc_acpi_cell {
const char *hid; const char *hid;
const char *name; const struct platform_device_info *pdevinfo;
void *pdata;
size_t pdata_size;
}; };
static void hisi_lpc_acpi_remove(struct device *hostdev) static void hisi_lpc_acpi_remove(struct device *hostdev)
...@@ -505,28 +503,45 @@ static int hisi_lpc_acpi_add_child(struct acpi_device *child, void *data) ...@@ -505,28 +503,45 @@ static int hisi_lpc_acpi_add_child(struct acpi_device *child, void *data)
/* ipmi */ /* ipmi */
{ {
.hid = "IPI0001", .hid = "IPI0001",
.name = "hisi-lpc-ipmi", .pdevinfo = (struct platform_device_info []) {
{
.parent = hostdev,
.fwnode = acpi_fwnode_handle(child),
.name = "hisi-lpc-ipmi",
.id = PLATFORM_DEVID_AUTO,
.res = res,
.num_res = num_res,
},
},
}, },
/* 8250-compatible uart */ /* 8250-compatible uart */
{ {
.hid = "HISI1031", .hid = "HISI1031",
.name = "serial8250", .pdevinfo = (struct platform_device_info []) {
.pdata = (struct plat_serial8250_port []) {
{ {
.iobase = res->start, .parent = hostdev,
.uartclk = 1843200, .fwnode = acpi_fwnode_handle(child),
.iotype = UPIO_PORT, .name = "serial8250",
.flags = UPF_BOOT_AUTOCONF, .id = PLATFORM_DEVID_AUTO,
.res = res,
.num_res = num_res,
.data = (struct plat_serial8250_port []) {
{
.iobase = res->start,
.uartclk = 1843200,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF,
},
{}
},
.size_data = 2 * sizeof(struct plat_serial8250_port),
}, },
{}
}, },
.pdata_size = 2 *
sizeof(struct plat_serial8250_port),
}, },
{} {}
}; };
for (; cell && cell->name; cell++) { for (; cell && cell->hid; cell++) {
if (!strcmp(cell->hid, hid)) { if (!strcmp(cell->hid, hid)) {
found = true; found = true;
break; break;
...@@ -540,31 +555,12 @@ static int hisi_lpc_acpi_add_child(struct acpi_device *child, void *data) ...@@ -540,31 +555,12 @@ static int hisi_lpc_acpi_add_child(struct acpi_device *child, void *data)
return 0; return 0;
} }
pdev = platform_device_alloc(cell->name, PLATFORM_DEVID_AUTO); pdev = platform_device_register_full(cell->pdevinfo);
if (!pdev) if (IS_ERR(pdev))
return -ENOMEM; return PTR_ERR(pdev);
pdev->dev.parent = hostdev;
ACPI_COMPANION_SET(&pdev->dev, child);
ret = platform_device_add_resources(pdev, res, num_res);
if (ret)
goto fail;
ret = platform_device_add_data(pdev, cell->pdata, cell->pdata_size);
if (ret)
goto fail;
ret = platform_device_add(pdev);
if (ret)
goto fail;
acpi_device_set_enumerated(child); acpi_device_set_enumerated(child);
return 0; return 0;
fail:
platform_device_put(pdev);
return ret;
} }
/* /*
...@@ -589,11 +585,6 @@ static int hisi_lpc_acpi_probe(struct device *hostdev) ...@@ -589,11 +585,6 @@ static int hisi_lpc_acpi_probe(struct device *hostdev)
return ret; return ret;
} }
static const struct acpi_device_id hisi_lpc_acpi_match[] = {
{"HISI0191"},
{}
};
#else #else
static int hisi_lpc_acpi_probe(struct device *dev) static int hisi_lpc_acpi_probe(struct device *dev)
{ {
...@@ -615,11 +606,9 @@ static void hisi_lpc_acpi_remove(struct device *hostdev) ...@@ -615,11 +606,9 @@ static void hisi_lpc_acpi_remove(struct device *hostdev)
static int hisi_lpc_probe(struct platform_device *pdev) static int hisi_lpc_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct acpi_device *acpi_device = ACPI_COMPANION(dev);
struct logic_pio_hwaddr *range; struct logic_pio_hwaddr *range;
struct hisi_lpc_dev *lpcdev; struct hisi_lpc_dev *lpcdev;
resource_size_t io_end; resource_size_t io_end;
struct resource *res;
int ret; int ret;
lpcdev = devm_kzalloc(dev, sizeof(*lpcdev), GFP_KERNEL); lpcdev = devm_kzalloc(dev, sizeof(*lpcdev), GFP_KERNEL);
...@@ -628,8 +617,7 @@ static int hisi_lpc_probe(struct platform_device *pdev) ...@@ -628,8 +617,7 @@ static int hisi_lpc_probe(struct platform_device *pdev)
spin_lock_init(&lpcdev->cycle_lock); spin_lock_init(&lpcdev->cycle_lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); lpcdev->membase = devm_platform_ioremap_resource(pdev, 0);
lpcdev->membase = devm_ioremap_resource(dev, res);
if (IS_ERR(lpcdev->membase)) if (IS_ERR(lpcdev->membase))
return PTR_ERR(lpcdev->membase); return PTR_ERR(lpcdev->membase);
...@@ -637,7 +625,7 @@ static int hisi_lpc_probe(struct platform_device *pdev) ...@@ -637,7 +625,7 @@ static int hisi_lpc_probe(struct platform_device *pdev)
if (!range) if (!range)
return -ENOMEM; return -ENOMEM;
range->fwnode = dev->fwnode; range->fwnode = dev_fwnode(dev);
range->flags = LOGIC_PIO_INDIRECT; range->flags = LOGIC_PIO_INDIRECT;
range->size = PIO_INDIRECT_SIZE; range->size = PIO_INDIRECT_SIZE;
range->hostdata = lpcdev; range->hostdata = lpcdev;
...@@ -651,7 +639,7 @@ static int hisi_lpc_probe(struct platform_device *pdev) ...@@ -651,7 +639,7 @@ static int hisi_lpc_probe(struct platform_device *pdev)
} }
/* register the LPC host PIO resources */ /* register the LPC host PIO resources */
if (acpi_device) if (is_acpi_device_node(range->fwnode))
ret = hisi_lpc_acpi_probe(dev); ret = hisi_lpc_acpi_probe(dev);
else else
ret = of_platform_populate(dev->of_node, NULL, NULL, dev); ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
...@@ -672,11 +660,10 @@ static int hisi_lpc_probe(struct platform_device *pdev) ...@@ -672,11 +660,10 @@ static int hisi_lpc_probe(struct platform_device *pdev)
static int hisi_lpc_remove(struct platform_device *pdev) static int hisi_lpc_remove(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct acpi_device *acpi_device = ACPI_COMPANION(dev);
struct hisi_lpc_dev *lpcdev = dev_get_drvdata(dev); struct hisi_lpc_dev *lpcdev = dev_get_drvdata(dev);
struct logic_pio_hwaddr *range = lpcdev->io_host; struct logic_pio_hwaddr *range = lpcdev->io_host;
if (acpi_device) if (is_acpi_device_node(range->fwnode))
hisi_lpc_acpi_remove(dev); hisi_lpc_acpi_remove(dev);
else else
of_platform_depopulate(dev); of_platform_depopulate(dev);
...@@ -692,11 +679,16 @@ static const struct of_device_id hisi_lpc_of_match[] = { ...@@ -692,11 +679,16 @@ static const struct of_device_id hisi_lpc_of_match[] = {
{} {}
}; };
static const struct acpi_device_id hisi_lpc_acpi_match[] = {
{"HISI0191"},
{}
};
static struct platform_driver hisi_lpc_driver = { static struct platform_driver hisi_lpc_driver = {
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
.of_match_table = hisi_lpc_of_match, .of_match_table = hisi_lpc_of_match,
.acpi_match_table = ACPI_PTR(hisi_lpc_acpi_match), .acpi_match_table = hisi_lpc_acpi_match,
}, },
.probe = hisi_lpc_probe, .probe = hisi_lpc_probe,
.remove = hisi_lpc_remove, .remove = hisi_lpc_remove,
......
...@@ -124,10 +124,8 @@ static bool psci_pd_try_set_osi_mode(void) ...@@ -124,10 +124,8 @@ static bool psci_pd_try_set_osi_mode(void)
return false; return false;
ret = psci_set_osi_mode(true); ret = psci_set_osi_mode(true);
if (ret) { if (ret)
pr_warn("failed to enable OSI mode: %d\n", ret);
return false; return false;
}
return true; return true;
} }
......
...@@ -167,7 +167,8 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev) ...@@ -167,7 +167,8 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev)
return valid; return valid;
} }
struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id) struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id,
const struct ffa_ops *ops)
{ {
int ret; int ret;
struct device *dev; struct device *dev;
...@@ -183,6 +184,7 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id) ...@@ -183,6 +184,7 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id)
dev_set_name(&ffa_dev->dev, "arm-ffa-%04x", vm_id); dev_set_name(&ffa_dev->dev, "arm-ffa-%04x", vm_id);
ffa_dev->vm_id = vm_id; ffa_dev->vm_id = vm_id;
ffa_dev->ops = ops;
uuid_copy(&ffa_dev->uuid, uuid); uuid_copy(&ffa_dev->uuid, uuid);
ret = device_register(&ffa_dev->dev); ret = device_register(&ffa_dev->dev);
......
...@@ -163,6 +163,7 @@ struct ffa_drv_info { ...@@ -163,6 +163,7 @@ struct ffa_drv_info {
struct mutex tx_lock; /* lock to protect Tx buffer */ struct mutex tx_lock; /* lock to protect Tx buffer */
void *rx_buffer; void *rx_buffer;
void *tx_buffer; void *tx_buffer;
bool mem_ops_native;
}; };
static struct ffa_drv_info *drv_info; static struct ffa_drv_info *drv_info;
...@@ -263,18 +264,24 @@ static int ffa_rxtx_unmap(u16 vm_id) ...@@ -263,18 +264,24 @@ static int ffa_rxtx_unmap(u16 vm_id)
return 0; return 0;
} }
#define PARTITION_INFO_GET_RETURN_COUNT_ONLY BIT(0)
/* buffer must be sizeof(struct ffa_partition_info) * num_partitions */ /* buffer must be sizeof(struct ffa_partition_info) * num_partitions */
static int static int
__ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3, __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
struct ffa_partition_info *buffer, int num_partitions) struct ffa_partition_info *buffer, int num_partitions)
{ {
int count; int idx, count, flags = 0, sz, buf_sz;
ffa_value_t partition_info; ffa_value_t partition_info;
if (!buffer || !num_partitions) /* Just get the count for now */
flags = PARTITION_INFO_GET_RETURN_COUNT_ONLY;
mutex_lock(&drv_info->rx_lock); mutex_lock(&drv_info->rx_lock);
invoke_ffa_fn((ffa_value_t){ invoke_ffa_fn((ffa_value_t){
.a0 = FFA_PARTITION_INFO_GET, .a0 = FFA_PARTITION_INFO_GET,
.a1 = uuid0, .a2 = uuid1, .a3 = uuid2, .a4 = uuid3, .a1 = uuid0, .a2 = uuid1, .a3 = uuid2, .a4 = uuid3,
.a5 = flags,
}, &partition_info); }, &partition_info);
if (partition_info.a0 == FFA_ERROR) { if (partition_info.a0 == FFA_ERROR) {
...@@ -284,8 +291,19 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3, ...@@ -284,8 +291,19 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
count = partition_info.a2; count = partition_info.a2;
if (drv_info->version > FFA_VERSION_1_0) {
buf_sz = sz = partition_info.a3;
if (sz > sizeof(*buffer))
buf_sz = sizeof(*buffer);
} else {
/* FFA_VERSION_1_0 lacks size in the response */
buf_sz = sz = 8;
}
if (buffer && count <= num_partitions) if (buffer && count <= num_partitions)
memcpy(buffer, drv_info->rx_buffer, sizeof(*buffer) * count); for (idx = 0; idx < count; idx++)
memcpy(buffer + idx, drv_info->rx_buffer + idx * sz,
buf_sz);
ffa_rx_release(); ffa_rx_release();
...@@ -571,6 +589,39 @@ static int ffa_memory_reclaim(u64 g_handle, u32 flags) ...@@ -571,6 +589,39 @@ static int ffa_memory_reclaim(u64 g_handle, u32 flags)
return 0; return 0;
} }
static int ffa_features(u32 func_feat_id, u32 input_props,
u32 *if_props_1, u32 *if_props_2)
{
ffa_value_t id;
if (!ARM_SMCCC_IS_FAST_CALL(func_feat_id) && input_props) {
pr_err("%s: Invalid Parameters: %x, %x", __func__,
func_feat_id, input_props);
return ffa_to_linux_errno(FFA_RET_INVALID_PARAMETERS);
}
invoke_ffa_fn((ffa_value_t){
.a0 = FFA_FEATURES, .a1 = func_feat_id, .a2 = input_props,
}, &id);
if (id.a0 == FFA_ERROR)
return ffa_to_linux_errno((int)id.a2);
if (if_props_1)
*if_props_1 = id.a2;
if (if_props_2)
*if_props_2 = id.a3;
return 0;
}
static void ffa_set_up_mem_ops_native_flag(void)
{
if (!ffa_features(FFA_FN_NATIVE(MEM_LEND), 0, NULL, NULL) ||
!ffa_features(FFA_FN_NATIVE(MEM_SHARE), 0, NULL, NULL))
drv_info->mem_ops_native = true;
}
static u32 ffa_api_version_get(void) static u32 ffa_api_version_get(void)
{ {
return drv_info->version; return drv_info->version;
...@@ -597,11 +648,19 @@ static int ffa_partition_info_get(const char *uuid_str, ...@@ -597,11 +648,19 @@ static int ffa_partition_info_get(const char *uuid_str,
return 0; return 0;
} }
static void ffa_mode_32bit_set(struct ffa_device *dev) static void _ffa_mode_32bit_set(struct ffa_device *dev)
{ {
dev->mode_32bit = true; dev->mode_32bit = true;
} }
static void ffa_mode_32bit_set(struct ffa_device *dev)
{
if (drv_info->version > FFA_VERSION_1_0)
return;
_ffa_mode_32bit_set(dev);
}
static int ffa_sync_send_receive(struct ffa_device *dev, static int ffa_sync_send_receive(struct ffa_device *dev,
struct ffa_send_direct_data *data) struct ffa_send_direct_data *data)
{ {
...@@ -609,17 +668,15 @@ static int ffa_sync_send_receive(struct ffa_device *dev, ...@@ -609,17 +668,15 @@ static int ffa_sync_send_receive(struct ffa_device *dev,
dev->mode_32bit, data); dev->mode_32bit, data);
} }
static int static int ffa_memory_share(struct ffa_mem_ops_args *args)
ffa_memory_share(struct ffa_device *dev, struct ffa_mem_ops_args *args)
{ {
if (dev->mode_32bit) if (drv_info->mem_ops_native)
return ffa_memory_ops(FFA_MEM_SHARE, args); return ffa_memory_ops(FFA_FN_NATIVE(MEM_SHARE), args);
return ffa_memory_ops(FFA_FN_NATIVE(MEM_SHARE), args); return ffa_memory_ops(FFA_MEM_SHARE, args);
} }
static int static int ffa_memory_lend(struct ffa_mem_ops_args *args)
ffa_memory_lend(struct ffa_device *dev, struct ffa_mem_ops_args *args)
{ {
/* Note that upon a successful MEM_LEND request the caller /* Note that upon a successful MEM_LEND request the caller
* must ensure that the memory region specified is not accessed * must ensure that the memory region specified is not accessed
...@@ -628,36 +685,47 @@ ffa_memory_lend(struct ffa_device *dev, struct ffa_mem_ops_args *args) ...@@ -628,36 +685,47 @@ ffa_memory_lend(struct ffa_device *dev, struct ffa_mem_ops_args *args)
* however on systems without a hypervisor the responsibility * however on systems without a hypervisor the responsibility
* falls to the calling kernel driver to prevent access. * falls to the calling kernel driver to prevent access.
*/ */
if (dev->mode_32bit) if (drv_info->mem_ops_native)
return ffa_memory_ops(FFA_MEM_LEND, args); return ffa_memory_ops(FFA_FN_NATIVE(MEM_LEND), args);
return ffa_memory_ops(FFA_FN_NATIVE(MEM_LEND), args); return ffa_memory_ops(FFA_MEM_LEND, args);
} }
static const struct ffa_dev_ops ffa_ops = { static const struct ffa_info_ops ffa_drv_info_ops = {
.api_version_get = ffa_api_version_get, .api_version_get = ffa_api_version_get,
.partition_info_get = ffa_partition_info_get, .partition_info_get = ffa_partition_info_get,
};
static const struct ffa_msg_ops ffa_drv_msg_ops = {
.mode_32bit_set = ffa_mode_32bit_set, .mode_32bit_set = ffa_mode_32bit_set,
.sync_send_receive = ffa_sync_send_receive, .sync_send_receive = ffa_sync_send_receive,
};
static const struct ffa_mem_ops ffa_drv_mem_ops = {
.memory_reclaim = ffa_memory_reclaim, .memory_reclaim = ffa_memory_reclaim,
.memory_share = ffa_memory_share, .memory_share = ffa_memory_share,
.memory_lend = ffa_memory_lend, .memory_lend = ffa_memory_lend,
}; };
const struct ffa_dev_ops *ffa_dev_ops_get(struct ffa_device *dev) static const struct ffa_ops ffa_drv_ops = {
{ .info_ops = &ffa_drv_info_ops,
if (ffa_device_is_valid(dev)) .msg_ops = &ffa_drv_msg_ops,
return &ffa_ops; .mem_ops = &ffa_drv_mem_ops,
};
return NULL;
}
EXPORT_SYMBOL_GPL(ffa_dev_ops_get);
void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid) void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid)
{ {
int count, idx; int count, idx;
struct ffa_partition_info *pbuf, *tpbuf; struct ffa_partition_info *pbuf, *tpbuf;
/*
* FF-A v1.1 provides UUID for each partition as part of the discovery
* API, the discovered UUID must be populated in the device's UUID and
* there is no need to copy the same from the driver table.
*/
if (drv_info->version > FFA_VERSION_1_0)
return;
count = ffa_partition_probe(uuid, &pbuf); count = ffa_partition_probe(uuid, &pbuf);
if (count <= 0) if (count <= 0)
return; return;
...@@ -671,6 +739,7 @@ void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid) ...@@ -671,6 +739,7 @@ void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid)
static void ffa_setup_partitions(void) static void ffa_setup_partitions(void)
{ {
int count, idx; int count, idx;
uuid_t uuid;
struct ffa_device *ffa_dev; struct ffa_device *ffa_dev;
struct ffa_partition_info *pbuf, *tpbuf; struct ffa_partition_info *pbuf, *tpbuf;
...@@ -681,19 +750,24 @@ static void ffa_setup_partitions(void) ...@@ -681,19 +750,24 @@ static void ffa_setup_partitions(void)
} }
for (idx = 0, tpbuf = pbuf; idx < count; idx++, tpbuf++) { for (idx = 0, tpbuf = pbuf; idx < count; idx++, tpbuf++) {
/* Note that the &uuid_null parameter will require import_uuid(&uuid, (u8 *)tpbuf->uuid);
/* Note that if the UUID will be uuid_null, that will require
* ffa_device_match() to find the UUID of this partition id * ffa_device_match() to find the UUID of this partition id
* with help of ffa_device_match_uuid(). Once the FF-A spec * with help of ffa_device_match_uuid(). FF-A v1.1 and above
* is updated to provide correct UUID here for each partition * provides UUID here for each partition as part of the
* as part of the discovery API, we need to pass the * discovery API and the same is passed.
* discovered UUID here instead.
*/ */
ffa_dev = ffa_device_register(&uuid_null, tpbuf->id); ffa_dev = ffa_device_register(&uuid, tpbuf->id, &ffa_drv_ops);
if (!ffa_dev) { if (!ffa_dev) {
pr_err("%s: failed to register partition ID 0x%x\n", pr_err("%s: failed to register partition ID 0x%x\n",
__func__, tpbuf->id); __func__, tpbuf->id);
continue; continue;
} }
if (drv_info->version > FFA_VERSION_1_0 &&
!(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC))
_ffa_mode_32bit_set(ffa_dev);
} }
kfree(pbuf); kfree(pbuf);
} }
...@@ -751,6 +825,8 @@ static int __init ffa_init(void) ...@@ -751,6 +825,8 @@ static int __init ffa_init(void)
ffa_setup_partitions(); ffa_setup_partitions();
ffa_set_up_mem_ops_native_flag();
return 0; return 0;
free_pages: free_pages:
if (drv_info->tx_buffer) if (drv_info->tx_buffer)
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/arm-smccc.h> #include <linux/arm-smccc.h>
#include <linux/cpuidle.h> #include <linux/cpuidle.h>
#include <linux/debugfs.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -163,6 +164,8 @@ int psci_set_osi_mode(bool enable) ...@@ -163,6 +164,8 @@ int psci_set_osi_mode(bool enable)
PSCI_1_0_SUSPEND_MODE_PC; PSCI_1_0_SUSPEND_MODE_PC;
err = invoke_psci_fn(PSCI_1_0_FN_SET_SUSPEND_MODE, suspend_mode, 0, 0); err = invoke_psci_fn(PSCI_1_0_FN_SET_SUSPEND_MODE, suspend_mode, 0, 0);
if (err < 0)
pr_warn("failed to set %s mode: %d\n", enable ? "OSI" : "PC", err);
return psci_to_linux_errno(err); return psci_to_linux_errno(err);
} }
...@@ -324,12 +327,125 @@ static void psci_sys_poweroff(void) ...@@ -324,12 +327,125 @@ static void psci_sys_poweroff(void)
invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0); invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
} }
static int __init psci_features(u32 psci_func_id) static int psci_features(u32 psci_func_id)
{ {
return invoke_psci_fn(PSCI_1_0_FN_PSCI_FEATURES, return invoke_psci_fn(PSCI_1_0_FN_PSCI_FEATURES,
psci_func_id, 0, 0); psci_func_id, 0, 0);
} }
#ifdef CONFIG_DEBUG_FS
#define PSCI_ID(ver, _name) \
{ .fn = PSCI_##ver##_FN_##_name, .name = #_name, }
#define PSCI_ID_NATIVE(ver, _name) \
{ .fn = PSCI_FN_NATIVE(ver, _name), .name = #_name, }
/* A table of all optional functions */
static const struct {
u32 fn;
const char *name;
} psci_fn_ids[] = {
PSCI_ID_NATIVE(0_2, MIGRATE),
PSCI_ID(0_2, MIGRATE_INFO_TYPE),
PSCI_ID_NATIVE(0_2, MIGRATE_INFO_UP_CPU),
PSCI_ID(1_0, CPU_FREEZE),
PSCI_ID_NATIVE(1_0, CPU_DEFAULT_SUSPEND),
PSCI_ID_NATIVE(1_0, NODE_HW_STATE),
PSCI_ID_NATIVE(1_0, SYSTEM_SUSPEND),
PSCI_ID(1_0, SET_SUSPEND_MODE),
PSCI_ID_NATIVE(1_0, STAT_RESIDENCY),
PSCI_ID_NATIVE(1_0, STAT_COUNT),
PSCI_ID_NATIVE(1_1, SYSTEM_RESET2),
PSCI_ID(1_1, MEM_PROTECT),
PSCI_ID_NATIVE(1_1, MEM_PROTECT_CHECK_RANGE),
};
static int psci_debugfs_read(struct seq_file *s, void *data)
{
int feature, type, i;
u32 ver;
ver = psci_ops.get_version();
seq_printf(s, "PSCIv%d.%d\n",
PSCI_VERSION_MAJOR(ver),
PSCI_VERSION_MINOR(ver));
/* PSCI_FEATURES is available only starting from 1.0 */
if (PSCI_VERSION_MAJOR(ver) < 1)
return 0;
feature = psci_features(ARM_SMCCC_VERSION_FUNC_ID);
if (feature != PSCI_RET_NOT_SUPPORTED) {
ver = invoke_psci_fn(ARM_SMCCC_VERSION_FUNC_ID, 0, 0, 0);
seq_printf(s, "SMC Calling Convention v%d.%d\n",
PSCI_VERSION_MAJOR(ver),
PSCI_VERSION_MINOR(ver));
} else {
seq_puts(s, "SMC Calling Convention v1.0 is assumed\n");
}
feature = psci_features(PSCI_FN_NATIVE(0_2, CPU_SUSPEND));
if (feature < 0) {
seq_printf(s, "PSCI_FEATURES(CPU_SUSPEND) error (%d)\n", feature);
} else {
seq_printf(s, "OSI is %ssupported\n",
(feature & BIT(0)) ? "" : "not ");
seq_printf(s, "%s StateID format is used\n",
(feature & BIT(1)) ? "Extended" : "Original");
}
type = psci_ops.migrate_info_type();
if (type == PSCI_0_2_TOS_UP_MIGRATE ||
type == PSCI_0_2_TOS_UP_NO_MIGRATE) {
unsigned long cpuid;
seq_printf(s, "Trusted OS %smigrate capable\n",
type == PSCI_0_2_TOS_UP_NO_MIGRATE ? "not " : "");
cpuid = psci_migrate_info_up_cpu();
seq_printf(s, "Trusted OS resident on physical CPU 0x%lx (#%d)\n",
cpuid, resident_cpu);
} else if (type == PSCI_0_2_TOS_MP) {
seq_puts(s, "Trusted OS migration not required\n");
} else {
if (type != PSCI_RET_NOT_SUPPORTED)
seq_printf(s, "MIGRATE_INFO_TYPE returned unknown type (%d)\n", type);
}
for (i = 0; i < ARRAY_SIZE(psci_fn_ids); i++) {
feature = psci_features(psci_fn_ids[i].fn);
if (feature == PSCI_RET_NOT_SUPPORTED)
continue;
if (feature < 0)
seq_printf(s, "PSCI_FEATURES(%s) error (%d)\n",
psci_fn_ids[i].name, feature);
else
seq_printf(s, "%s is supported\n", psci_fn_ids[i].name);
}
return 0;
}
static int psci_debugfs_open(struct inode *inode, struct file *f)
{
return single_open(f, psci_debugfs_read, NULL);
}
static const struct file_operations psci_debugfs_ops = {
.owner = THIS_MODULE,
.open = psci_debugfs_open,
.release = single_release,
.read = seq_read,
.llseek = seq_lseek
};
static int __init psci_debugfs_init(void)
{
return PTR_ERR_OR_ZERO(debugfs_create_file("psci", 0444, NULL, NULL,
&psci_debugfs_ops));
}
late_initcall(psci_debugfs_init)
#endif
#ifdef CONFIG_CPU_IDLE #ifdef CONFIG_CPU_IDLE
static int psci_suspend_finisher(unsigned long state) static int psci_suspend_finisher(unsigned long state)
{ {
......
...@@ -129,8 +129,6 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, ...@@ -129,8 +129,6 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
#define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03 #define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03
#define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02 #define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02
extern void __qcom_scm_init(void);
/* common error codes */ /* common error codes */
#define QCOM_SCM_V2_EBUSY -12 #define QCOM_SCM_V2_EBUSY -12
#define QCOM_SCM_ENOMEM -5 #define QCOM_SCM_ENOMEM -5
......
...@@ -377,18 +377,11 @@ static ssize_t bpmp_debug_store(struct file *file, const char __user *buf, ...@@ -377,18 +377,11 @@ static ssize_t bpmp_debug_store(struct file *file, const char __user *buf,
if (!filename) if (!filename)
return -ENOENT; return -ENOENT;
databuf = kmalloc(count, GFP_KERNEL); databuf = memdup_user(buf, count);
if (!databuf) if (IS_ERR(databuf))
return -ENOMEM; return PTR_ERR(databuf);
if (copy_from_user(databuf, buf, count)) {
err = -EFAULT;
goto free_ret;
}
err = mrq_debug_write(bpmp, filename, databuf, count); err = mrq_debug_write(bpmp, filename, databuf, count);
free_ret:
kfree(databuf); kfree(databuf);
return err ?: count; return err ?: count;
......
...@@ -488,8 +488,8 @@ config I2C_BCM_KONA ...@@ -488,8 +488,8 @@ config I2C_BCM_KONA
config I2C_BRCMSTB config I2C_BRCMSTB
tristate "BRCM Settop/DSL I2C controller" tristate "BRCM Settop/DSL I2C controller"
depends on ARCH_BCM2835 || ARCH_BCM4908 || ARCH_BCMBCA || \ depends on ARCH_BCM2835 || ARCH_BCMBCA || ARCH_BRCMSTB || \
ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST BMIPS_GENERIC || COMPILE_TEST
default y default y
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
......
...@@ -66,6 +66,15 @@ config BRCMSTB_DPFE ...@@ -66,6 +66,15 @@ config BRCMSTB_DPFE
for the DRAM's temperature. Slower refresh rate means cooler RAM, for the DRAM's temperature. Slower refresh rate means cooler RAM,
higher refresh rate means hotter RAM. higher refresh rate means hotter RAM.
config BRCMSTB_MEMC
tristate "Broadcom STB MEMC driver"
default ARCH_BRCMSTB
depends on ARCH_BRCMSTB || COMPILE_TEST
help
This driver provides a way to configure the Broadcom STB memory
controller and specifically control the Self Refresh Power Down
(SRPD) inactivity timeout.
config BT1_L2_CTL config BT1_L2_CTL
bool "Baikal-T1 CM2 L2-RAM Cache Control Block" bool "Baikal-T1 CM2 L2-RAM Cache Control Block"
depends on MIPS_BAIKAL_T1 || COMPILE_TEST depends on MIPS_BAIKAL_T1 || COMPILE_TEST
......
...@@ -11,6 +11,7 @@ obj-$(CONFIG_ARM_PL172_MPMC) += pl172.o ...@@ -11,6 +11,7 @@ obj-$(CONFIG_ARM_PL172_MPMC) += pl172.o
obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o
obj-$(CONFIG_ATMEL_EBI) += atmel-ebi.o obj-$(CONFIG_ATMEL_EBI) += atmel-ebi.o
obj-$(CONFIG_BRCMSTB_DPFE) += brcmstb_dpfe.o obj-$(CONFIG_BRCMSTB_DPFE) += brcmstb_dpfe.o
obj-$(CONFIG_BRCMSTB_MEMC) += brcmstb_memc.o
obj-$(CONFIG_BT1_L2_CTL) += bt1-l2-ctl.o obj-$(CONFIG_BT1_L2_CTL) += bt1-l2-ctl.o
obj-$(CONFIG_TI_AEMIF) += ti-aemif.o obj-$(CONFIG_TI_AEMIF) += ti-aemif.o
obj-$(CONFIG_TI_EMIF) += emif.o obj-$(CONFIG_TI_EMIF) += emif.o
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* DDR Self-Refresh Power Down (SRPD) support for Broadcom STB SoCs
*
*/
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#define REG_MEMC_CNTRLR_CONFIG 0x00
#define CNTRLR_CONFIG_LPDDR4_SHIFT 5
#define CNTRLR_CONFIG_MASK 0xf
#define REG_MEMC_SRPD_CFG_21 0x20
#define REG_MEMC_SRPD_CFG_20 0x34
#define REG_MEMC_SRPD_CFG_1x 0x3c
#define INACT_COUNT_SHIFT 0
#define INACT_COUNT_MASK 0xffff
#define SRPD_EN_SHIFT 16
struct brcmstb_memc_data {
u32 srpd_offset;
};
struct brcmstb_memc {
struct device *dev;
void __iomem *ddr_ctrl;
unsigned int timeout_cycles;
u32 frequency;
u32 srpd_offset;
};
static int brcmstb_memc_uses_lpddr4(struct brcmstb_memc *memc)
{
void __iomem *config = memc->ddr_ctrl + REG_MEMC_CNTRLR_CONFIG;
u32 reg;
reg = readl_relaxed(config) & CNTRLR_CONFIG_MASK;
return reg == CNTRLR_CONFIG_LPDDR4_SHIFT;
}
static int brcmstb_memc_srpd_config(struct brcmstb_memc *memc,
unsigned int cycles)
{
void __iomem *cfg = memc->ddr_ctrl + memc->srpd_offset;
u32 val;
/* Max timeout supported in HW */
if (cycles > INACT_COUNT_MASK)
return -EINVAL;
memc->timeout_cycles = cycles;
val = (cycles << INACT_COUNT_SHIFT) & INACT_COUNT_MASK;
if (cycles)
val |= BIT(SRPD_EN_SHIFT);
writel_relaxed(val, cfg);
/* Ensure the write is committed to the controller */
(void)readl_relaxed(cfg);
return 0;
}
static ssize_t frequency_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct brcmstb_memc *memc = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", memc->frequency);
}
static ssize_t srpd_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct brcmstb_memc *memc = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", memc->timeout_cycles);
}
static ssize_t srpd_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct brcmstb_memc *memc = dev_get_drvdata(dev);
unsigned int val;
int ret;
/*
* Cannot change the inactivity timeout on LPDDR4 chips because the
* dynamic tuning process will also get affected by the inactivity
* timeout, thus making it non functional.
*/
if (brcmstb_memc_uses_lpddr4(memc))
return -EOPNOTSUPP;
ret = kstrtouint(buf, 10, &val);
if (ret < 0)
return ret;
ret = brcmstb_memc_srpd_config(memc, val);
if (ret)
return ret;
return count;
}
static DEVICE_ATTR_RO(frequency);
static DEVICE_ATTR_RW(srpd);
static struct attribute *dev_attrs[] = {
&dev_attr_frequency.attr,
&dev_attr_srpd.attr,
NULL,
};
static struct attribute_group dev_attr_group = {
.attrs = dev_attrs,
};
static const struct of_device_id brcmstb_memc_of_match[];
static int brcmstb_memc_probe(struct platform_device *pdev)
{
const struct brcmstb_memc_data *memc_data;
const struct of_device_id *of_id;
struct device *dev = &pdev->dev;
struct brcmstb_memc *memc;
int ret;
memc = devm_kzalloc(dev, sizeof(*memc), GFP_KERNEL);
if (!memc)
return -ENOMEM;
dev_set_drvdata(dev, memc);
of_id = of_match_device(brcmstb_memc_of_match, dev);
memc_data = of_id->data;
memc->srpd_offset = memc_data->srpd_offset;
memc->ddr_ctrl = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(memc->ddr_ctrl))
return PTR_ERR(memc->ddr_ctrl);
of_property_read_u32(pdev->dev.of_node, "clock-frequency",
&memc->frequency);
ret = sysfs_create_group(&dev->kobj, &dev_attr_group);
if (ret)
return ret;
return 0;
}
static int brcmstb_memc_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
sysfs_remove_group(&dev->kobj, &dev_attr_group);
return 0;
}
enum brcmstb_memc_hwtype {
BRCMSTB_MEMC_V21,
BRCMSTB_MEMC_V20,
BRCMSTB_MEMC_V1X,
};
static const struct brcmstb_memc_data brcmstb_memc_versions[] = {
{ .srpd_offset = REG_MEMC_SRPD_CFG_21 },
{ .srpd_offset = REG_MEMC_SRPD_CFG_20 },
{ .srpd_offset = REG_MEMC_SRPD_CFG_1x },
};
static const struct of_device_id brcmstb_memc_of_match[] = {
{
.compatible = "brcm,brcmstb-memc-ddr-rev-b.1.x",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V1X]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.0",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V20]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.1",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.2",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.3",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.5",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.6",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.7",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-b.2.8",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-b.3.0",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-b.3.1",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.0",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.1",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.2",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.3",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
{
.compatible = "brcm,brcmstb-memc-ddr-rev-c.1.4",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21]
},
/* default to the original offset */
{
.compatible = "brcm,brcmstb-memc-ddr",
.data = &brcmstb_memc_versions[BRCMSTB_MEMC_V1X]
},
{}
};
static int brcmstb_memc_suspend(struct device *dev)
{
struct brcmstb_memc *memc = dev_get_drvdata(dev);
void __iomem *cfg = memc->ddr_ctrl + memc->srpd_offset;
u32 val;
if (memc->timeout_cycles == 0)
return 0;
/*
* Disable SRPD prior to suspending the system since that can
* cause issues with other memory clients managed by the ARM
* trusted firmware to access memory.
*/
val = readl_relaxed(cfg);
val &= ~BIT(SRPD_EN_SHIFT);
writel_relaxed(val, cfg);
/* Ensure the write is committed to the controller */
(void)readl_relaxed(cfg);
return 0;
}
static int brcmstb_memc_resume(struct device *dev)
{
struct brcmstb_memc *memc = dev_get_drvdata(dev);
if (memc->timeout_cycles == 0)
return 0;
return brcmstb_memc_srpd_config(memc, memc->timeout_cycles);
}
static DEFINE_SIMPLE_DEV_PM_OPS(brcmstb_memc_pm_ops, brcmstb_memc_suspend,
brcmstb_memc_resume);
static struct platform_driver brcmstb_memc_driver = {
.probe = brcmstb_memc_probe,
.remove = brcmstb_memc_remove,
.driver = {
.name = "brcmstb_memc",
.of_match_table = brcmstb_memc_of_match,
.pm = pm_ptr(&brcmstb_memc_pm_ops),
},
};
module_platform_driver(brcmstb_memc_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Broadcom");
MODULE_DESCRIPTION("DDR SRPD driver for Broadcom STB chips");
...@@ -24,11 +24,24 @@ ...@@ -24,11 +24,24 @@
#define EMIF_STAT_CLEAR_BUSY_SFT 16 #define EMIF_STAT_CLEAR_BUSY_SFT 16
#define EMIF_CTRL 0x10 #define EMIF_CTRL 0x10
#define EMIF_CTRL_CLEAR_EN_SFT 0 #define EMIF_CTRL_CLEAR_EN_SFT 0
#define EMIF_CTRL_CLEAR_EN_MSK GENMASK_ULL(3, 0) #define EMIF_CTRL_CLEAR_EN_MSK GENMASK_ULL(7, 0)
#define EMIF_POLL_INVL 10000 /* us */ #define EMIF_POLL_INVL 10000 /* us */
#define EMIF_POLL_TIMEOUT 5000000 /* us */ #define EMIF_POLL_TIMEOUT 5000000 /* us */
/*
* The Capability Register replaces the Control Register (at the same
* offset) for EMIF feature revisions > 0. The bitmask that indicates
* the presence of memory channels exists in both the Capability Register
* and Control Register definitions. These can be thought of as a C union.
* The Capability Register definitions are used to check for the existence
* of a memory channel, and the Control Register definitions are used for
* managing the memory-clear functionality in revision 0.
*/
#define EMIF_CAPABILITY_BASE 0x10
#define EMIF_CAPABILITY_CHN_MSK_V0 GENMASK_ULL(3, 0)
#define EMIF_CAPABILITY_CHN_MSK GENMASK_ULL(7, 0)
struct dfl_emif { struct dfl_emif {
struct device *dev; struct device *dev;
void __iomem *base; void __iomem *base;
...@@ -106,16 +119,30 @@ emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 0); ...@@ -106,16 +119,30 @@ emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 0);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 1); emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 1);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 2); emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 2);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 3); emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 3);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 4);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 5);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 6);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 7);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 0); emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 0);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 1); emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 1);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 2); emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 2);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 3); emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 3);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 4);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 5);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 6);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 7);
emif_clear_attr(0); emif_clear_attr(0);
emif_clear_attr(1); emif_clear_attr(1);
emif_clear_attr(2); emif_clear_attr(2);
emif_clear_attr(3); emif_clear_attr(3);
emif_clear_attr(4);
emif_clear_attr(5);
emif_clear_attr(6);
emif_clear_attr(7);
static struct attribute *dfl_emif_attrs[] = { static struct attribute *dfl_emif_attrs[] = {
&emif_attr_inf0_init_done.attr.attr, &emif_attr_inf0_init_done.attr.attr,
...@@ -134,6 +161,22 @@ static struct attribute *dfl_emif_attrs[] = { ...@@ -134,6 +161,22 @@ static struct attribute *dfl_emif_attrs[] = {
&emif_attr_inf3_cal_fail.attr.attr, &emif_attr_inf3_cal_fail.attr.attr,
&emif_attr_inf3_clear.attr.attr, &emif_attr_inf3_clear.attr.attr,
&emif_attr_inf4_init_done.attr.attr,
&emif_attr_inf4_cal_fail.attr.attr,
&emif_attr_inf4_clear.attr.attr,
&emif_attr_inf5_init_done.attr.attr,
&emif_attr_inf5_cal_fail.attr.attr,
&emif_attr_inf5_clear.attr.attr,
&emif_attr_inf6_init_done.attr.attr,
&emif_attr_inf6_cal_fail.attr.attr,
&emif_attr_inf6_clear.attr.attr,
&emif_attr_inf7_init_done.attr.attr,
&emif_attr_inf7_cal_fail.attr.attr,
&emif_attr_inf7_clear.attr.attr,
NULL, NULL,
}; };
...@@ -143,15 +186,24 @@ static umode_t dfl_emif_visible(struct kobject *kobj, ...@@ -143,15 +186,24 @@ static umode_t dfl_emif_visible(struct kobject *kobj,
struct dfl_emif *de = dev_get_drvdata(kobj_to_dev(kobj)); struct dfl_emif *de = dev_get_drvdata(kobj_to_dev(kobj));
struct emif_attr *eattr = container_of(attr, struct emif_attr, struct emif_attr *eattr = container_of(attr, struct emif_attr,
attr.attr); attr.attr);
struct dfl_device *ddev = to_dfl_dev(de->dev);
u64 val; u64 val;
/* /*
* This device supports upto 4 memory interfaces, but not all * This device supports up to 8 memory interfaces, but not all
* interfaces are used on different platforms. The read out value of * interfaces are used on different platforms. The read out value of
* CLEAN_EN field (which is a bitmap) could tell how many interfaces * CAPABILITY_CHN_MSK field (which is a bitmap) indicates which
* are available. * interfaces are available.
*/ */
val = FIELD_GET(EMIF_CTRL_CLEAR_EN_MSK, readq(de->base + EMIF_CTRL)); if (ddev->revision > 0 && strstr(attr->name, "_clear"))
return 0;
if (ddev->revision == 0)
val = FIELD_GET(EMIF_CAPABILITY_CHN_MSK_V0,
readq(de->base + EMIF_CAPABILITY_BASE));
else
val = FIELD_GET(EMIF_CAPABILITY_CHN_MSK,
readq(de->base + EMIF_CAPABILITY_BASE));
return (val & BIT_ULL(eattr->index)) ? attr->mode : 0; return (val & BIT_ULL(eattr->index)) ? attr->mode : 0;
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* Copyright (c) 2015-2016 MediaTek Inc. * Copyright (c) 2015-2016 MediaTek Inc.
* Author: Yong Wu <yong.wu@mediatek.com> * Author: Yong Wu <yong.wu@mediatek.com>
*/ */
#include <linux/arm-smccc.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/component.h> #include <linux/component.h>
#include <linux/device.h> #include <linux/device.h>
...@@ -14,6 +15,7 @@ ...@@ -14,6 +15,7 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/soc/mediatek/mtk_sip_svc.h>
#include <soc/mediatek/smi.h> #include <soc/mediatek/smi.h>
#include <dt-bindings/memory/mt2701-larb-port.h> #include <dt-bindings/memory/mt2701-larb-port.h>
#include <dt-bindings/memory/mtk-memory-port.h> #include <dt-bindings/memory/mtk-memory-port.h>
...@@ -89,6 +91,7 @@ ...@@ -89,6 +91,7 @@
#define MTK_SMI_FLAG_THRT_UPDATE BIT(0) #define MTK_SMI_FLAG_THRT_UPDATE BIT(0)
#define MTK_SMI_FLAG_SW_FLAG BIT(1) #define MTK_SMI_FLAG_SW_FLAG BIT(1)
#define MTK_SMI_FLAG_SLEEP_CTL BIT(2) #define MTK_SMI_FLAG_SLEEP_CTL BIT(2)
#define MTK_SMI_FLAG_CFG_PORT_SEC_CTL BIT(3)
#define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x))) #define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x)))
struct mtk_smi_reg_pair { struct mtk_smi_reg_pair {
...@@ -127,7 +130,7 @@ struct mtk_smi_common_plat { ...@@ -127,7 +130,7 @@ struct mtk_smi_common_plat {
struct mtk_smi_larb_gen { struct mtk_smi_larb_gen {
int port_in_larb[MTK_LARB_NR_MAX + 1]; int port_in_larb[MTK_LARB_NR_MAX + 1];
void (*config_port)(struct device *dev); int (*config_port)(struct device *dev);
unsigned int larb_direct_to_common_mask; unsigned int larb_direct_to_common_mask;
unsigned int flags_general; unsigned int flags_general;
const u8 (*ostd)[SMI_LARB_PORT_NR_MAX]; const u8 (*ostd)[SMI_LARB_PORT_NR_MAX];
...@@ -185,7 +188,7 @@ static const struct component_ops mtk_smi_larb_component_ops = { ...@@ -185,7 +188,7 @@ static const struct component_ops mtk_smi_larb_component_ops = {
.unbind = mtk_smi_larb_unbind, .unbind = mtk_smi_larb_unbind,
}; };
static void mtk_smi_larb_config_port_gen1(struct device *dev) static int mtk_smi_larb_config_port_gen1(struct device *dev)
{ {
struct mtk_smi_larb *larb = dev_get_drvdata(dev); struct mtk_smi_larb *larb = dev_get_drvdata(dev);
const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen; const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
...@@ -214,31 +217,35 @@ static void mtk_smi_larb_config_port_gen1(struct device *dev) ...@@ -214,31 +217,35 @@ static void mtk_smi_larb_config_port_gen1(struct device *dev)
common->smi_ao_base common->smi_ao_base
+ REG_SMI_SECUR_CON_ADDR(m4u_port_id)); + REG_SMI_SECUR_CON_ADDR(m4u_port_id));
} }
return 0;
} }
static void mtk_smi_larb_config_port_mt8167(struct device *dev) static int mtk_smi_larb_config_port_mt8167(struct device *dev)
{ {
struct mtk_smi_larb *larb = dev_get_drvdata(dev); struct mtk_smi_larb *larb = dev_get_drvdata(dev);
writel(*larb->mmu, larb->base + MT8167_SMI_LARB_MMU_EN); writel(*larb->mmu, larb->base + MT8167_SMI_LARB_MMU_EN);
return 0;
} }
static void mtk_smi_larb_config_port_mt8173(struct device *dev) static int mtk_smi_larb_config_port_mt8173(struct device *dev)
{ {
struct mtk_smi_larb *larb = dev_get_drvdata(dev); struct mtk_smi_larb *larb = dev_get_drvdata(dev);
writel(*larb->mmu, larb->base + MT8173_SMI_LARB_MMU_EN); writel(*larb->mmu, larb->base + MT8173_SMI_LARB_MMU_EN);
return 0;
} }
static void mtk_smi_larb_config_port_gen2_general(struct device *dev) static int mtk_smi_larb_config_port_gen2_general(struct device *dev)
{ {
struct mtk_smi_larb *larb = dev_get_drvdata(dev); struct mtk_smi_larb *larb = dev_get_drvdata(dev);
u32 reg, flags_general = larb->larb_gen->flags_general; u32 reg, flags_general = larb->larb_gen->flags_general;
const u8 *larbostd = larb->larb_gen->ostd ? larb->larb_gen->ostd[larb->larbid] : NULL; const u8 *larbostd = larb->larb_gen->ostd ? larb->larb_gen->ostd[larb->larbid] : NULL;
struct arm_smccc_res res;
int i; int i;
if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask) if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask)
return; return 0;
if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_THRT_UPDATE)) { if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_THRT_UPDATE)) {
reg = readl_relaxed(larb->base + SMI_LARB_CMD_THRT_CON); reg = readl_relaxed(larb->base + SMI_LARB_CMD_THRT_CON);
...@@ -253,14 +260,78 @@ static void mtk_smi_larb_config_port_gen2_general(struct device *dev) ...@@ -253,14 +260,78 @@ static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
for (i = 0; i < SMI_LARB_PORT_NR_MAX && larbostd && !!larbostd[i]; i++) for (i = 0; i < SMI_LARB_PORT_NR_MAX && larbostd && !!larbostd[i]; i++)
writel_relaxed(larbostd[i], larb->base + SMI_LARB_OSTDL_PORTx(i)); writel_relaxed(larbostd[i], larb->base + SMI_LARB_OSTDL_PORTx(i));
/*
* When mmu_en bits are in security world, the bank_sel still is in the
* LARB_NONSEC_CON below. And the mmu_en bits of LARB_NONSEC_CON have no
* effect in this case.
*/
if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_CFG_PORT_SEC_CTL)) {
arm_smccc_smc(MTK_SIP_KERNEL_IOMMU_CONTROL, IOMMU_ATF_CMD_CONFIG_SMI_LARB,
larb->larbid, *larb->mmu, 0, 0, 0, 0, &res);
if (res.a0 != 0) {
dev_err(dev, "Enable iommu fail, ret %ld\n", res.a0);
return -EINVAL;
}
}
for_each_set_bit(i, (unsigned long *)larb->mmu, 32) { for_each_set_bit(i, (unsigned long *)larb->mmu, 32) {
reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i)); reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i));
reg |= F_MMU_EN; reg |= F_MMU_EN;
reg |= BANK_SEL(larb->bank[i]); reg |= BANK_SEL(larb->bank[i]);
writel(reg, larb->base + SMI_LARB_NONSEC_CON(i)); writel(reg, larb->base + SMI_LARB_NONSEC_CON(i));
} }
return 0;
} }
static const u8 mtk_smi_larb_mt8188_ostd[][SMI_LARB_PORT_NR_MAX] = {
[0] = {0x02, 0x18, 0x22, 0x22, 0x01, 0x02, 0x0a,},
[1] = {0x12, 0x02, 0x14, 0x14, 0x01, 0x18, 0x0a,},
[2] = {0x12, 0x12, 0x12, 0x12, 0x0a,},
[3] = {0x12, 0x12, 0x12, 0x12, 0x28, 0x28, 0x0a,},
[4] = {0x06, 0x01, 0x17, 0x06, 0x0a, 0x07, 0x07,},
[5] = {0x02, 0x01, 0x04, 0x02, 0x06, 0x01, 0x06, 0x0a,},
[6] = {0x06, 0x01, 0x06, 0x0a,},
[7] = {0x0c, 0x0c, 0x12,},
[8] = {0x0c, 0x01, 0x0a, 0x05, 0x02, 0x03, 0x01, 0x01, 0x14, 0x14,
0x0a, 0x14, 0x1e, 0x01, 0x0c, 0x0a, 0x05, 0x02, 0x02, 0x05,
0x03, 0x01, 0x1e, 0x01, 0x05,},
[9] = {0x1e, 0x01, 0x0a, 0x0a, 0x01, 0x01, 0x03, 0x1e, 0x1e, 0x10,
0x07, 0x01, 0x0a, 0x06, 0x03, 0x03, 0x0e, 0x01, 0x04, 0x28,},
[10] = {0x03, 0x20, 0x01, 0x20, 0x01, 0x01, 0x14, 0x0a, 0x0a, 0x0c,
0x0a, 0x05, 0x02, 0x03, 0x02, 0x14, 0x0a, 0x0a, 0x14, 0x14,
0x14, 0x01, 0x01, 0x14, 0x1e, 0x01, 0x05, 0x03, 0x02, 0x28,},
[11] = {0x03, 0x20, 0x01, 0x20, 0x01, 0x01, 0x14, 0x0a, 0x0a, 0x0c,
0x0a, 0x05, 0x02, 0x03, 0x02, 0x14, 0x0a, 0x0a, 0x14, 0x14,
0x14, 0x01, 0x01, 0x14, 0x1e, 0x01, 0x05, 0x03, 0x02, 0x28,},
[12] = {0x03, 0x20, 0x01, 0x20, 0x01, 0x01, 0x14, 0x0a, 0x0a, 0x0c,
0x0a, 0x05, 0x02, 0x03, 0x02, 0x14, 0x0a, 0x0a, 0x14, 0x14,
0x14, 0x01, 0x01, 0x14, 0x1e, 0x01, 0x05, 0x03, 0x02, 0x28,},
[13] = {0x07, 0x02, 0x04, 0x02, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x07, 0x02, 0x04, 0x02, 0x05, 0x05,},
[14] = {0x02, 0x02, 0x0c, 0x0c, 0x0c, 0x0c, 0x01, 0x01, 0x02, 0x02,
0x02, 0x02, 0x0c, 0x0c, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x02, 0x01, 0x01,},
[15] = {0x0c, 0x0c, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x0c, 0x0c,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02,
0x0c, 0x01, 0x01,},
[16] = {0x28, 0x28, 0x03, 0x01, 0x01, 0x03, 0x14, 0x14, 0x0a, 0x0d,
0x03, 0x05, 0x0e, 0x01, 0x01, 0x05, 0x06, 0x0d, 0x01,},
[17] = {0x28, 0x02, 0x02, 0x12, 0x02, 0x12, 0x10, 0x02, 0x02, 0x0a,
0x12, 0x02, 0x02, 0x0a, 0x16, 0x02, 0x04,},
[18] = {0x28, 0x02, 0x02, 0x12, 0x02, 0x12, 0x10, 0x02, 0x02, 0x0a,
0x12, 0x02, 0x02, 0x0a, 0x16, 0x02, 0x04,},
[19] = {0x1a, 0x0e, 0x0a, 0x0a, 0x0c, 0x0e, 0x10,},
[20] = {0x1a, 0x0e, 0x0a, 0x0a, 0x0c, 0x0e, 0x10,},
[21] = {0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x01,
0x01, 0x01, 0x04, 0x0a, 0x06, 0x01, 0x01, 0x01, 0x0a, 0x06,
0x01, 0x01, 0x05, 0x03, 0x03, 0x04, 0x01,},
[22] = {0x28, 0x19, 0x0c, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04,
0x01,},
[23] = {0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x18, 0x01, 0x01,},
[24] = {0x12, 0x06, 0x12, 0x06,},
[25] = {0x01},
};
static const u8 mtk_smi_larb_mt8195_ostd[][SMI_LARB_PORT_NR_MAX] = { static const u8 mtk_smi_larb_mt8195_ostd[][SMI_LARB_PORT_NR_MAX] = {
[0] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb0 */ [0] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb0 */
[1] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb1 */ [1] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb1 */
...@@ -347,6 +418,13 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = { ...@@ -347,6 +418,13 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = {
.flags_general = MTK_SMI_FLAG_SLEEP_CTL, .flags_general = MTK_SMI_FLAG_SLEEP_CTL,
}; };
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8188 = {
.config_port = mtk_smi_larb_config_port_gen2_general,
.flags_general = MTK_SMI_FLAG_THRT_UPDATE | MTK_SMI_FLAG_SW_FLAG |
MTK_SMI_FLAG_SLEEP_CTL | MTK_SMI_FLAG_CFG_PORT_SEC_CTL,
.ostd = mtk_smi_larb_mt8188_ostd,
};
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = { static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
.config_port = mtk_smi_larb_config_port_gen2_general, .config_port = mtk_smi_larb_config_port_gen2_general,
}; };
...@@ -367,6 +445,7 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = { ...@@ -367,6 +445,7 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
{.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173}, {.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173},
{.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183}, {.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183},
{.compatible = "mediatek,mt8186-smi-larb", .data = &mtk_smi_larb_mt8186}, {.compatible = "mediatek,mt8186-smi-larb", .data = &mtk_smi_larb_mt8186},
{.compatible = "mediatek,mt8188-smi-larb", .data = &mtk_smi_larb_mt8188},
{.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192}, {.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192},
{.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195}, {.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195},
{} {}
...@@ -511,9 +590,7 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev) ...@@ -511,9 +590,7 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
mtk_smi_larb_sleep_ctrl_disable(larb); mtk_smi_larb_sleep_ctrl_disable(larb);
/* Configure the basic setting for this larb */ /* Configure the basic setting for this larb */
larb_gen->config_port(dev); return larb_gen->config_port(dev);
return 0;
} }
static int __maybe_unused mtk_smi_larb_suspend(struct device *dev) static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
...@@ -597,6 +674,18 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8186 = { ...@@ -597,6 +674,18 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8186 = {
.bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(4) | F_MMU1_LARB(7), .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(4) | F_MMU1_LARB(7),
}; };
static const struct mtk_smi_common_plat mtk_smi_common_mt8188_vdo = {
.type = MTK_SMI_GEN2,
.bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(5) | F_MMU1_LARB(7),
.init = mtk_smi_common_mt8195_init,
};
static const struct mtk_smi_common_plat mtk_smi_common_mt8188_vpp = {
.type = MTK_SMI_GEN2,
.bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(7),
.init = mtk_smi_common_mt8195_init,
};
static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = { static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
.type = MTK_SMI_GEN2, .type = MTK_SMI_GEN2,
.has_gals = true, .has_gals = true,
...@@ -633,6 +722,8 @@ static const struct of_device_id mtk_smi_common_of_ids[] = { ...@@ -633,6 +722,8 @@ static const struct of_device_id mtk_smi_common_of_ids[] = {
{.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2}, {.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2},
{.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183}, {.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183},
{.compatible = "mediatek,mt8186-smi-common", .data = &mtk_smi_common_mt8186}, {.compatible = "mediatek,mt8186-smi-common", .data = &mtk_smi_common_mt8186},
{.compatible = "mediatek,mt8188-smi-common-vdo", .data = &mtk_smi_common_mt8188_vdo},
{.compatible = "mediatek,mt8188-smi-common-vpp", .data = &mtk_smi_common_mt8188_vpp},
{.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192}, {.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192},
{.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo}, {.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo},
{.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp}, {.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp},
......
...@@ -134,6 +134,7 @@ const struct lpddr2_timings *of_get_ddr_timings(struct device_node *np_ddr, ...@@ -134,6 +134,7 @@ const struct lpddr2_timings *of_get_ddr_timings(struct device_node *np_ddr,
for_each_child_of_node(np_ddr, np_tim) { for_each_child_of_node(np_ddr, np_tim) {
if (of_device_is_compatible(np_tim, tim_compat)) { if (of_device_is_compatible(np_tim, tim_compat)) {
if (of_do_get_timings(np_tim, &timings[i])) { if (of_do_get_timings(np_tim, &timings[i])) {
of_node_put(np_tim);
devm_kfree(dev, timings); devm_kfree(dev, timings);
goto default_timings; goto default_timings;
} }
...@@ -284,6 +285,7 @@ const struct lpddr3_timings ...@@ -284,6 +285,7 @@ const struct lpddr3_timings
if (of_device_is_compatible(np_tim, tim_compat)) { if (of_device_is_compatible(np_tim, tim_compat)) {
if (of_lpddr3_do_get_timings(np_tim, &timings[i])) { if (of_lpddr3_do_get_timings(np_tim, &timings[i])) {
devm_kfree(dev, timings); devm_kfree(dev, timings);
of_node_put(np_tim);
goto default_timings; goto default_timings;
} }
i++; i++;
......
...@@ -122,6 +122,7 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -122,6 +122,7 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id)
} }
of_platform_device_create(child, NULL, &adev->dev); of_platform_device_create(child, NULL, &adev->dev);
of_node_put(child);
return 0; return 0;
......
...@@ -69,8 +69,8 @@ config MTD_OF_PARTS ...@@ -69,8 +69,8 @@ config MTD_OF_PARTS
config MTD_OF_PARTS_BCM4908 config MTD_OF_PARTS_BCM4908
bool "BCM4908 partitioning support" bool "BCM4908 partitioning support"
depends on MTD_OF_PARTS && (ARCH_BCM4908 || COMPILE_TEST) depends on MTD_OF_PARTS && (ARCH_BCMBCA || COMPILE_TEST)
default ARCH_BCM4908 default ARCH_BCMBCA
help help
This provides partitions parser for BCM4908 family devices This provides partitions parser for BCM4908 family devices
that can have multiple "firmware" partitions. It takes care of that can have multiple "firmware" partitions. It takes care of
...@@ -78,7 +78,7 @@ config MTD_OF_PARTS_BCM4908 ...@@ -78,7 +78,7 @@ config MTD_OF_PARTS_BCM4908
config MTD_OF_PARTS_LINKSYS_NS config MTD_OF_PARTS_LINKSYS_NS
bool "Linksys Northstar partitioning support" bool "Linksys Northstar partitioning support"
depends on MTD_OF_PARTS && (ARCH_BCM_5301X || ARCH_BCM4908 || COMPILE_TEST) depends on MTD_OF_PARTS && (ARCH_BCM_5301X || ARCH_BCMBCA || COMPILE_TEST)
default ARCH_BCM_5301X default ARCH_BCM_5301X
help help
This provides partitions parser for Linksys devices based on Broadcom This provides partitions parser for Linksys devices based on Broadcom
......
...@@ -53,8 +53,8 @@ config B44_PCI ...@@ -53,8 +53,8 @@ config B44_PCI
config BCM4908_ENET config BCM4908_ENET
tristate "Broadcom BCM4908 internal mac support" tristate "Broadcom BCM4908 internal mac support"
depends on ARCH_BCM4908 || COMPILE_TEST depends on ARCH_BCMBCA || COMPILE_TEST
default y if ARCH_BCM4908 default y if ARCH_BCMBCA
help help
This driver supports Ethernet controller integrated into Broadcom This driver supports Ethernet controller integrated into Broadcom
BCM4908 family SoCs. BCM4908 family SoCs.
......
...@@ -274,7 +274,7 @@ config VMD ...@@ -274,7 +274,7 @@ config VMD
config PCIE_BRCMSTB config PCIE_BRCMSTB
tristate "Broadcom Brcmstb PCIe host controller" tristate "Broadcom Brcmstb PCIe host controller"
depends on ARCH_BRCMSTB || ARCH_BCM2835 || ARCH_BCM4908 || \ depends on ARCH_BRCMSTB || ARCH_BCM2835 || ARCH_BCMBCA || \
BMIPS_GENERIC || COMPILE_TEST BMIPS_GENERIC || COMPILE_TEST
depends on OF depends on OF
depends on PCI_MSI_IRQ_DOMAIN depends on PCI_MSI_IRQ_DOMAIN
......
...@@ -93,11 +93,11 @@ config PHY_BRCM_SATA ...@@ -93,11 +93,11 @@ config PHY_BRCM_SATA
config PHY_BRCM_USB config PHY_BRCM_USB
tristate "Broadcom STB USB PHY driver" tristate "Broadcom STB USB PHY driver"
depends on ARCH_BCM4908 || ARCH_BRCMSTB || COMPILE_TEST depends on ARCH_BCMBCA || ARCH_BRCMSTB || COMPILE_TEST
depends on OF depends on OF
select GENERIC_PHY select GENERIC_PHY
select SOC_BRCMSTB if ARCH_BRCMSTB select SOC_BRCMSTB if ARCH_BRCMSTB
default ARCH_BCM4908 || ARCH_BRCMSTB default ARCH_BCMBCA || ARCH_BRCMSTB
help help
Enable this to support the Broadcom STB USB PHY. Enable this to support the Broadcom STB USB PHY.
This driver is required by the USB XHCI, EHCI and OHCI This driver is required by the USB XHCI, EHCI and OHCI
......
...@@ -31,13 +31,13 @@ config PINCTRL_BCM2835 ...@@ -31,13 +31,13 @@ config PINCTRL_BCM2835
config PINCTRL_BCM4908 config PINCTRL_BCM4908
tristate "Broadcom BCM4908 pinmux driver" tristate "Broadcom BCM4908 pinmux driver"
depends on OF && (ARCH_BCM4908 || COMPILE_TEST) depends on OF && (ARCH_BCMBCA || COMPILE_TEST)
select PINMUX select PINMUX
select PINCONF select PINCONF
select GENERIC_PINCONF select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS select GENERIC_PINMUX_FUNCTIONS
default ARCH_BCM4908 default ARCH_BCMBCA
help help
Driver for BCM4908 family SoCs with integrated pin controller. Driver for BCM4908 family SoCs with integrated pin controller.
......
...@@ -201,7 +201,7 @@ config RESET_SCMI ...@@ -201,7 +201,7 @@ config RESET_SCMI
config RESET_SIMPLE config RESET_SIMPLE
bool "Simple Reset Controller Driver" if COMPILE_TEST || EXPERT bool "Simple Reset Controller Driver" if COMPILE_TEST || EXPERT
default ARCH_ASPEED || ARCH_BCM4908 || ARCH_BITMAIN || ARCH_REALTEK || ARCH_STM32 || (ARCH_INTEL_SOCFPGA && ARM64) || ARCH_SUNXI || ARC default ARCH_ASPEED || ARCH_BCMBCA || ARCH_BITMAIN || ARCH_REALTEK || ARCH_STM32 || (ARCH_INTEL_SOCFPGA && ARM64) || ARCH_SUNXI || ARC
depends on HAS_IOMEM depends on HAS_IOMEM
help help
This enables a simple reset controller driver for reset lines that This enables a simple reset controller driver for reset lines that
......
...@@ -469,6 +469,7 @@ static int meson_ee_pwrc_probe(struct platform_device *pdev) ...@@ -469,6 +469,7 @@ static int meson_ee_pwrc_probe(struct platform_device *pdev)
{ {
const struct meson_ee_pwrc_domain_data *match; const struct meson_ee_pwrc_domain_data *match;
struct regmap *regmap_ao, *regmap_hhi; struct regmap *regmap_ao, *regmap_hhi;
struct device_node *parent_np;
struct meson_ee_pwrc *pwrc; struct meson_ee_pwrc *pwrc;
int i, ret; int i, ret;
...@@ -495,7 +496,9 @@ static int meson_ee_pwrc_probe(struct platform_device *pdev) ...@@ -495,7 +496,9 @@ static int meson_ee_pwrc_probe(struct platform_device *pdev)
pwrc->xlate.num_domains = match->count; pwrc->xlate.num_domains = match->count;
regmap_hhi = syscon_node_to_regmap(of_get_parent(pdev->dev.of_node)); parent_np = of_get_parent(pdev->dev.of_node);
regmap_hhi = syscon_node_to_regmap(parent_np);
of_node_put(parent_np);
if (IS_ERR(regmap_hhi)) { if (IS_ERR(regmap_hhi)) {
dev_err(&pdev->dev, "failed to get HHI regmap\n"); dev_err(&pdev->dev, "failed to get HHI regmap\n");
return PTR_ERR(regmap_hhi); return PTR_ERR(regmap_hhi);
......
...@@ -273,6 +273,7 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev) ...@@ -273,6 +273,7 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev)
const struct meson_gx_pwrc_vpu *vpu_pd_match; const struct meson_gx_pwrc_vpu *vpu_pd_match;
struct regmap *regmap_ao, *regmap_hhi; struct regmap *regmap_ao, *regmap_hhi;
struct meson_gx_pwrc_vpu *vpu_pd; struct meson_gx_pwrc_vpu *vpu_pd;
struct device_node *parent_np;
struct reset_control *rstc; struct reset_control *rstc;
struct clk *vpu_clk; struct clk *vpu_clk;
struct clk *vapb_clk; struct clk *vapb_clk;
...@@ -291,7 +292,9 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev) ...@@ -291,7 +292,9 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev)
memcpy(vpu_pd, vpu_pd_match, sizeof(*vpu_pd)); memcpy(vpu_pd, vpu_pd_match, sizeof(*vpu_pd));
regmap_ao = syscon_node_to_regmap(of_get_parent(pdev->dev.of_node)); parent_np = of_get_parent(pdev->dev.of_node);
regmap_ao = syscon_node_to_regmap(parent_np);
of_node_put(parent_np);
if (IS_ERR(regmap_ao)) { if (IS_ERR(regmap_ao)) {
dev_err(&pdev->dev, "failed to get regmap\n"); dev_err(&pdev->dev, "failed to get regmap\n");
return PTR_ERR(regmap_ao); return PTR_ERR(regmap_ao);
......
...@@ -660,6 +660,12 @@ int apple_rtkit_send_message_wait(struct apple_rtkit *rtk, u8 ep, u64 message, ...@@ -660,6 +660,12 @@ int apple_rtkit_send_message_wait(struct apple_rtkit *rtk, u8 ep, u64 message,
} }
EXPORT_SYMBOL_GPL(apple_rtkit_send_message_wait); EXPORT_SYMBOL_GPL(apple_rtkit_send_message_wait);
int apple_rtkit_poll(struct apple_rtkit *rtk)
{
return mbox_client_peek_data(rtk->mbox_chan);
}
EXPORT_SYMBOL_GPL(apple_rtkit_poll);
int apple_rtkit_start_ep(struct apple_rtkit *rtk, u8 endpoint) int apple_rtkit_start_ep(struct apple_rtkit *rtk, u8 endpoint)
{ {
u64 msg; u64 msg;
......
...@@ -13,8 +13,8 @@ endif # SOC_BCM63XX ...@@ -13,8 +13,8 @@ endif # SOC_BCM63XX
config BCM_PMB config BCM_PMB
bool "Broadcom PMB (Power Management Bus) driver" bool "Broadcom PMB (Power Management Bus) driver"
depends on ARCH_BCM4908 || (COMPILE_TEST && OF) depends on ARCH_BCMBCA || (COMPILE_TEST && OF)
default ARCH_BCM4908 default ARCH_BCMBCA
select PM_GENERIC_DOMAINS if PM select PM_GENERIC_DOMAINS if PM
help help
This enables support for the Broadcom's PMB (Power Management Bus) that This enables support for the Broadcom's PMB (Power Management Bus) that
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/notifier.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/panic_notifier.h> #include <linux/panic_notifier.h>
...@@ -664,7 +663,20 @@ static void __iomem *brcmstb_ioremap_match(const struct of_device_id *matches, ...@@ -664,7 +663,20 @@ static void __iomem *brcmstb_ioremap_match(const struct of_device_id *matches,
return of_io_request_and_map(dn, index, dn->full_name); return of_io_request_and_map(dn, index, dn->full_name);
} }
/*
* The AON is a small domain in the SoC that can retain its state across
* various system wide sleep states and specific reset conditions; the
* AON DATA RAM is a small RAM of a few words (< 1KB) which can store
* persistent information across such events.
*
* The purpose of the below panic notifier is to help with notifying
* the bootloader that a panic occurred and so that it should try its
* best to preserve the DRAM contents holding that buffer for recovery
* by the kernel as opposed to wiping out DRAM clean again.
*
* Reference: comment from Florian Fainelli, at
* https://lore.kernel.org/lkml/781cafb0-8d06-8b56-907a-5175c2da196a@gmail.com
*/
static int brcmstb_pm_panic_notify(struct notifier_block *nb, static int brcmstb_pm_panic_notify(struct notifier_block *nb,
unsigned long action, void *data) unsigned long action, void *data)
{ {
......
...@@ -20,4 +20,12 @@ config SOC_IMX8M ...@@ -20,4 +20,12 @@ config SOC_IMX8M
support, it will provide the SoC info like SoC family, support, it will provide the SoC info like SoC family,
ID and revision etc. ID and revision etc.
config SOC_IMX9
tristate "i.MX9 SoC family support"
depends on ARCH_MXC || COMPILE_TEST
default ARCH_MXC && ARM64
select SOC_BUS
help
If you say yes here, you get support for the NXP i.MX9 family
endmenu endmenu
...@@ -7,3 +7,5 @@ obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o ...@@ -7,3 +7,5 @@ obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o
obj-$(CONFIG_SOC_IMX8M) += imx8mp-blk-ctrl.o obj-$(CONFIG_SOC_IMX8M) += imx8mp-blk-ctrl.o
obj-$(CONFIG_SOC_IMX9) += imx93-src.o imx93-pd.o
obj-$(CONFIG_SOC_IMX9) += imx93-blk-ctrl.o
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
*/ */
#include <linux/device.h> #include <linux/device.h>
#include <linux/interconnect.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -37,6 +38,8 @@ struct imx8m_blk_ctrl_domain_data { ...@@ -37,6 +38,8 @@ struct imx8m_blk_ctrl_domain_data {
const char *name; const char *name;
const char * const *clk_names; const char * const *clk_names;
int num_clks; int num_clks;
const char * const *path_names;
int num_paths;
const char *gpc_name; const char *gpc_name;
u32 rst_mask; u32 rst_mask;
u32 clk_mask; u32 clk_mask;
...@@ -52,13 +55,16 @@ struct imx8m_blk_ctrl_domain_data { ...@@ -52,13 +55,16 @@ struct imx8m_blk_ctrl_domain_data {
}; };
#define DOMAIN_MAX_CLKS 4 #define DOMAIN_MAX_CLKS 4
#define DOMAIN_MAX_PATHS 4
struct imx8m_blk_ctrl_domain { struct imx8m_blk_ctrl_domain {
struct generic_pm_domain genpd; struct generic_pm_domain genpd;
const struct imx8m_blk_ctrl_domain_data *data; const struct imx8m_blk_ctrl_domain_data *data;
struct clk_bulk_data clks[DOMAIN_MAX_CLKS]; struct clk_bulk_data clks[DOMAIN_MAX_CLKS];
struct icc_bulk_data paths[DOMAIN_MAX_PATHS];
struct device *power_dev; struct device *power_dev;
struct imx8m_blk_ctrl *bc; struct imx8m_blk_ctrl *bc;
int num_paths;
}; };
struct imx8m_blk_ctrl_data { struct imx8m_blk_ctrl_data {
...@@ -117,6 +123,10 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd) ...@@ -117,6 +123,10 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
if (data->mipi_phy_rst_mask) if (data->mipi_phy_rst_mask)
regmap_set_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask); regmap_set_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask);
ret = icc_bulk_set_bw(domain->num_paths, domain->paths);
if (ret)
dev_err(bc->dev, "failed to set icc bw\n");
/* disable upstream clocks */ /* disable upstream clocks */
clk_bulk_disable_unprepare(data->num_clks, domain->clks); clk_bulk_disable_unprepare(data->num_clks, domain->clks);
...@@ -152,19 +162,6 @@ static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd) ...@@ -152,19 +162,6 @@ static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd)
return 0; return 0;
} }
static struct generic_pm_domain *
imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data)
{
struct genpd_onecell_data *onecell_data = data;
unsigned int index = args->args[0];
if (args->args_count != 1 ||
index >= onecell_data->num_domains)
return ERR_PTR(-EINVAL);
return onecell_data->domains[index];
}
static struct lock_class_key blk_ctrl_genpd_lock_class; static struct lock_class_key blk_ctrl_genpd_lock_class;
static int imx8m_blk_ctrl_probe(struct platform_device *pdev) static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
...@@ -206,7 +203,6 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev) ...@@ -206,7 +203,6 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
bc->onecell_data.num_domains = bc_data->num_domains; bc->onecell_data.num_domains = bc_data->num_domains;
bc->onecell_data.xlate = imx8m_blk_ctrl_xlate;
bc->onecell_data.domains = bc->onecell_data.domains =
devm_kcalloc(dev, bc_data->num_domains, devm_kcalloc(dev, bc_data->num_domains,
sizeof(struct generic_pm_domain *), GFP_KERNEL); sizeof(struct generic_pm_domain *), GFP_KERNEL);
...@@ -224,10 +220,29 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev) ...@@ -224,10 +220,29 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
int j; int j;
domain->data = data; domain->data = data;
domain->num_paths = data->num_paths;
for (j = 0; j < data->num_clks; j++) for (j = 0; j < data->num_clks; j++)
domain->clks[j].id = data->clk_names[j]; domain->clks[j].id = data->clk_names[j];
for (j = 0; j < data->num_paths; j++) {
domain->paths[j].name = data->path_names[j];
/* Fake value for now, just let ICC could configure NoC mode/priority */
domain->paths[j].avg_bw = 1;
domain->paths[j].peak_bw = 1;
}
ret = devm_of_icc_bulk_get(dev, data->num_paths, domain->paths);
if (ret) {
if (ret != -EPROBE_DEFER) {
dev_warn_once(dev, "Could not get interconnect paths, NoC will stay unconfigured!\n");
domain->num_paths = 0;
} else {
dev_err_probe(dev, ret, "failed to get noc entries\n");
goto cleanup_pds;
}
}
ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks);
if (ret) { if (ret) {
dev_err_probe(dev, ret, "failed to get clock\n"); dev_err_probe(dev, ret, "failed to get clock\n");
...@@ -454,6 +469,46 @@ static const struct imx8m_blk_ctrl_data imx8mm_vpu_blk_ctl_dev_data = { ...@@ -454,6 +469,46 @@ static const struct imx8m_blk_ctrl_data imx8mm_vpu_blk_ctl_dev_data = {
.num_domains = ARRAY_SIZE(imx8mm_vpu_blk_ctl_domain_data), .num_domains = ARRAY_SIZE(imx8mm_vpu_blk_ctl_domain_data),
}; };
static const struct imx8m_blk_ctrl_domain_data imx8mp_vpu_blk_ctl_domain_data[] = {
[IMX8MP_VPUBLK_PD_G1] = {
.name = "vpublk-g1",
.clk_names = (const char *[]){ "g1", },
.num_clks = 1,
.gpc_name = "g1",
.rst_mask = BIT(1),
.clk_mask = BIT(1),
.path_names = (const char *[]){"g1"},
.num_paths = 1,
},
[IMX8MP_VPUBLK_PD_G2] = {
.name = "vpublk-g2",
.clk_names = (const char *[]){ "g2", },
.num_clks = 1,
.gpc_name = "g2",
.rst_mask = BIT(0),
.clk_mask = BIT(0),
.path_names = (const char *[]){"g2"},
.num_paths = 1,
},
[IMX8MP_VPUBLK_PD_VC8000E] = {
.name = "vpublk-vc8000e",
.clk_names = (const char *[]){ "vc8000e", },
.num_clks = 1,
.gpc_name = "vc8000e",
.rst_mask = BIT(2),
.clk_mask = BIT(2),
.path_names = (const char *[]){"vc8000e"},
.num_paths = 1,
},
};
static const struct imx8m_blk_ctrl_data imx8mp_vpu_blk_ctl_dev_data = {
.max_reg = 0x18,
.power_notifier_fn = imx8mm_vpu_power_notifier,
.domains = imx8mp_vpu_blk_ctl_domain_data,
.num_domains = ARRAY_SIZE(imx8mp_vpu_blk_ctl_domain_data),
};
static int imx8mm_disp_power_notifier(struct notifier_block *nb, static int imx8mm_disp_power_notifier(struct notifier_block *nb,
unsigned long action, void *data) unsigned long action, void *data)
{ {
...@@ -649,6 +704,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[ ...@@ -649,6 +704,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
.gpc_name = "lcdif1", .gpc_name = "lcdif1",
.rst_mask = BIT(4) | BIT(5) | BIT(23), .rst_mask = BIT(4) | BIT(5) | BIT(23),
.clk_mask = BIT(4) | BIT(5) | BIT(23), .clk_mask = BIT(4) | BIT(5) | BIT(23),
.path_names = (const char *[]){"lcdif-rd", "lcdif-wr"},
.num_paths = 2,
}, },
[IMX8MP_MEDIABLK_PD_ISI] = { [IMX8MP_MEDIABLK_PD_ISI] = {
.name = "mediablk-isi", .name = "mediablk-isi",
...@@ -657,6 +714,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[ ...@@ -657,6 +714,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
.gpc_name = "isi", .gpc_name = "isi",
.rst_mask = BIT(6) | BIT(7), .rst_mask = BIT(6) | BIT(7),
.clk_mask = BIT(6) | BIT(7), .clk_mask = BIT(6) | BIT(7),
.path_names = (const char *[]){"isi0", "isi1", "isi2"},
.num_paths = 3,
}, },
[IMX8MP_MEDIABLK_PD_MIPI_CSI2_2] = { [IMX8MP_MEDIABLK_PD_MIPI_CSI2_2] = {
.name = "mediablk-mipi-csi2-2", .name = "mediablk-mipi-csi2-2",
...@@ -674,6 +733,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[ ...@@ -674,6 +733,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
.gpc_name = "lcdif2", .gpc_name = "lcdif2",
.rst_mask = BIT(11) | BIT(12) | BIT(24), .rst_mask = BIT(11) | BIT(12) | BIT(24),
.clk_mask = BIT(11) | BIT(12) | BIT(24), .clk_mask = BIT(11) | BIT(12) | BIT(24),
.path_names = (const char *[]){"lcdif-rd", "lcdif-wr"},
.num_paths = 2,
}, },
[IMX8MP_MEDIABLK_PD_ISP] = { [IMX8MP_MEDIABLK_PD_ISP] = {
.name = "mediablk-isp", .name = "mediablk-isp",
...@@ -682,6 +743,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[ ...@@ -682,6 +743,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
.gpc_name = "isp", .gpc_name = "isp",
.rst_mask = BIT(16) | BIT(17) | BIT(18), .rst_mask = BIT(16) | BIT(17) | BIT(18),
.clk_mask = BIT(16) | BIT(17) | BIT(18), .clk_mask = BIT(16) | BIT(17) | BIT(18),
.path_names = (const char *[]){"isp0", "isp1"},
.num_paths = 2,
}, },
[IMX8MP_MEDIABLK_PD_DWE] = { [IMX8MP_MEDIABLK_PD_DWE] = {
.name = "mediablk-dwe", .name = "mediablk-dwe",
...@@ -690,6 +753,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[ ...@@ -690,6 +753,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
.gpc_name = "dwe", .gpc_name = "dwe",
.rst_mask = BIT(19) | BIT(20) | BIT(21), .rst_mask = BIT(19) | BIT(20) | BIT(21),
.clk_mask = BIT(19) | BIT(20) | BIT(21), .clk_mask = BIT(19) | BIT(20) | BIT(21),
.path_names = (const char *[]){"dwe"},
.num_paths = 1,
}, },
[IMX8MP_MEDIABLK_PD_MIPI_DSI_2] = { [IMX8MP_MEDIABLK_PD_MIPI_DSI_2] = {
.name = "mediablk-mipi-dsi-2", .name = "mediablk-mipi-dsi-2",
...@@ -787,6 +852,9 @@ static const struct of_device_id imx8m_blk_ctrl_of_match[] = { ...@@ -787,6 +852,9 @@ static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
}, { }, {
.compatible = "fsl,imx8mq-vpu-blk-ctrl", .compatible = "fsl,imx8mq-vpu-blk-ctrl",
.data = &imx8mq_vpu_blk_ctl_dev_data .data = &imx8mq_vpu_blk_ctl_dev_data
}, {
.compatible = "fsl,imx8mp-vpu-blk-ctrl",
.data = &imx8mp_vpu_blk_ctl_dev_data
}, { }, {
/* Sentinel */ /* Sentinel */
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/interconnect.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -18,6 +19,8 @@ ...@@ -18,6 +19,8 @@
#define GPR_REG0 0x0 #define GPR_REG0 0x0
#define PCIE_CLOCK_MODULE_EN BIT(0) #define PCIE_CLOCK_MODULE_EN BIT(0)
#define USB_CLOCK_MODULE_EN BIT(1) #define USB_CLOCK_MODULE_EN BIT(1)
#define PCIE_PHY_APB_RST BIT(4)
#define PCIE_PHY_INIT_RST BIT(5)
struct imx8mp_blk_ctrl_domain; struct imx8mp_blk_ctrl_domain;
...@@ -36,17 +39,22 @@ struct imx8mp_blk_ctrl_domain_data { ...@@ -36,17 +39,22 @@ struct imx8mp_blk_ctrl_domain_data {
const char *name; const char *name;
const char * const *clk_names; const char * const *clk_names;
int num_clks; int num_clks;
const char * const *path_names;
int num_paths;
const char *gpc_name; const char *gpc_name;
}; };
#define DOMAIN_MAX_CLKS 2 #define DOMAIN_MAX_CLKS 2
#define DOMAIN_MAX_PATHS 3
struct imx8mp_blk_ctrl_domain { struct imx8mp_blk_ctrl_domain {
struct generic_pm_domain genpd; struct generic_pm_domain genpd;
const struct imx8mp_blk_ctrl_domain_data *data; const struct imx8mp_blk_ctrl_domain_data *data;
struct clk_bulk_data clks[DOMAIN_MAX_CLKS]; struct clk_bulk_data clks[DOMAIN_MAX_CLKS];
struct icc_bulk_data paths[DOMAIN_MAX_PATHS];
struct device *power_dev; struct device *power_dev;
struct imx8mp_blk_ctrl *bc; struct imx8mp_blk_ctrl *bc;
int num_paths;
int id; int id;
}; };
...@@ -75,6 +83,10 @@ static void imx8mp_hsio_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, ...@@ -75,6 +83,10 @@ static void imx8mp_hsio_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc,
case IMX8MP_HSIOBLK_PD_PCIE: case IMX8MP_HSIOBLK_PD_PCIE:
regmap_set_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN); regmap_set_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN);
break; break;
case IMX8MP_HSIOBLK_PD_PCIE_PHY:
regmap_set_bits(bc->regmap, GPR_REG0,
PCIE_PHY_APB_RST | PCIE_PHY_INIT_RST);
break;
default: default:
break; break;
} }
...@@ -90,6 +102,10 @@ static void imx8mp_hsio_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, ...@@ -90,6 +102,10 @@ static void imx8mp_hsio_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc,
case IMX8MP_HSIOBLK_PD_PCIE: case IMX8MP_HSIOBLK_PD_PCIE:
regmap_clear_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN); regmap_clear_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN);
break; break;
case IMX8MP_HSIOBLK_PD_PCIE_PHY:
regmap_clear_bits(bc->regmap, GPR_REG0,
PCIE_PHY_APB_RST | PCIE_PHY_INIT_RST);
break;
default: default:
break; break;
} }
...@@ -144,6 +160,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = { ...@@ -144,6 +160,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = {
.clk_names = (const char *[]){ "usb" }, .clk_names = (const char *[]){ "usb" },
.num_clks = 1, .num_clks = 1,
.gpc_name = "usb", .gpc_name = "usb",
.path_names = (const char *[]){"usb1", "usb2"},
.num_paths = 2,
}, },
[IMX8MP_HSIOBLK_PD_USB_PHY1] = { [IMX8MP_HSIOBLK_PD_USB_PHY1] = {
.name = "hsioblk-usb-phy1", .name = "hsioblk-usb-phy1",
...@@ -158,6 +176,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = { ...@@ -158,6 +176,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = {
.clk_names = (const char *[]){ "pcie" }, .clk_names = (const char *[]){ "pcie" },
.num_clks = 1, .num_clks = 1,
.gpc_name = "pcie", .gpc_name = "pcie",
.path_names = (const char *[]){"noc-pcie", "pcie"},
.num_paths = 2,
}, },
[IMX8MP_HSIOBLK_PD_PCIE_PHY] = { [IMX8MP_HSIOBLK_PD_PCIE_PHY] = {
.name = "hsioblk-pcie-phy", .name = "hsioblk-pcie-phy",
...@@ -225,6 +245,13 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, ...@@ -225,6 +245,13 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc,
regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12));
regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3)); regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3));
break; break;
case IMX8MP_HDMIBLK_PD_HDCP:
regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11));
break;
case IMX8MP_HDMIBLK_PD_HRV:
regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5));
regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15));
break;
default: default:
break; break;
} }
...@@ -273,6 +300,13 @@ static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, ...@@ -273,6 +300,13 @@ static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc,
regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12));
regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24)); regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24));
break; break;
case IMX8MP_HDMIBLK_PD_HDCP:
regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11));
break;
case IMX8MP_HDMIBLK_PD_HRV:
regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15));
regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5));
break;
default: default:
break; break;
} }
...@@ -322,6 +356,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = { ...@@ -322,6 +356,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
.clk_names = (const char *[]){ "axi", "apb" }, .clk_names = (const char *[]){ "axi", "apb" },
.num_clks = 2, .num_clks = 2,
.gpc_name = "lcdif", .gpc_name = "lcdif",
.path_names = (const char *[]){"lcdif-hdmi"},
.num_paths = 1,
}, },
[IMX8MP_HDMIBLK_PD_PAI] = { [IMX8MP_HDMIBLK_PD_PAI] = {
.name = "hdmiblk-pai", .name = "hdmiblk-pai",
...@@ -353,6 +389,22 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = { ...@@ -353,6 +389,22 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
.num_clks = 2, .num_clks = 2,
.gpc_name = "hdmi-tx-phy", .gpc_name = "hdmi-tx-phy",
}, },
[IMX8MP_HDMIBLK_PD_HRV] = {
.name = "hdmiblk-hrv",
.clk_names = (const char *[]){ "axi", "apb" },
.num_clks = 2,
.gpc_name = "hrv",
.path_names = (const char *[]){"hrv"},
.num_paths = 1,
},
[IMX8MP_HDMIBLK_PD_HDCP] = {
.name = "hdmiblk-hdcp",
.clk_names = (const char *[]){ "axi", "apb" },
.num_clks = 2,
.gpc_name = "hdcp",
.path_names = (const char *[]){"hdcp"},
.num_paths = 1,
},
}; };
static const struct imx8mp_blk_ctrl_data imx8mp_hdmi_blk_ctl_dev_data = { static const struct imx8mp_blk_ctrl_data imx8mp_hdmi_blk_ctl_dev_data = {
...@@ -395,6 +447,10 @@ static int imx8mp_blk_ctrl_power_on(struct generic_pm_domain *genpd) ...@@ -395,6 +447,10 @@ static int imx8mp_blk_ctrl_power_on(struct generic_pm_domain *genpd)
goto clk_disable; goto clk_disable;
} }
ret = icc_bulk_set_bw(domain->num_paths, domain->paths);
if (ret)
dev_err(bc->dev, "failed to set icc bw\n");
clk_bulk_disable_unprepare(data->num_clks, domain->clks); clk_bulk_disable_unprepare(data->num_clks, domain->clks);
return 0; return 0;
...@@ -434,19 +490,6 @@ static int imx8mp_blk_ctrl_power_off(struct generic_pm_domain *genpd) ...@@ -434,19 +490,6 @@ static int imx8mp_blk_ctrl_power_off(struct generic_pm_domain *genpd)
return 0; return 0;
} }
static struct generic_pm_domain *
imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data)
{
struct genpd_onecell_data *onecell_data = data;
unsigned int index = args->args[0];
if (args->args_count != 1 ||
index >= onecell_data->num_domains)
return ERR_PTR(-EINVAL);
return onecell_data->domains[index];
}
static struct lock_class_key blk_ctrl_genpd_lock_class; static struct lock_class_key blk_ctrl_genpd_lock_class;
static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
...@@ -489,7 +532,6 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) ...@@ -489,7 +532,6 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
bc->onecell_data.num_domains = num_domains; bc->onecell_data.num_domains = num_domains;
bc->onecell_data.xlate = imx8m_blk_ctrl_xlate;
bc->onecell_data.domains = bc->onecell_data.domains =
devm_kcalloc(dev, num_domains, devm_kcalloc(dev, num_domains,
sizeof(struct generic_pm_domain *), GFP_KERNEL); sizeof(struct generic_pm_domain *), GFP_KERNEL);
...@@ -510,10 +552,29 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) ...@@ -510,10 +552,29 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
int j; int j;
domain->data = data; domain->data = data;
domain->num_paths = data->num_paths;
for (j = 0; j < data->num_clks; j++) for (j = 0; j < data->num_clks; j++)
domain->clks[j].id = data->clk_names[j]; domain->clks[j].id = data->clk_names[j];
for (j = 0; j < data->num_paths; j++) {
domain->paths[j].name = data->path_names[j];
/* Fake value for now, just let ICC could configure NoC mode/priority */
domain->paths[j].avg_bw = 1;
domain->paths[j].peak_bw = 1;
}
ret = devm_of_icc_bulk_get(dev, data->num_paths, domain->paths);
if (ret) {
if (ret != -EPROBE_DEFER) {
dev_warn_once(dev, "Could not get interconnect paths, NoC will stay unconfigured!\n");
domain->num_paths = 0;
} else {
dev_err_probe(dev, ret, "failed to get noc entries\n");
goto cleanup_pds;
}
}
ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks);
if (ret) { if (ret) {
dev_err_probe(dev, ret, "failed to get clock\n"); dev_err_probe(dev, ret, "failed to get clock\n");
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2022 NXP
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/of_device.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#define MIX_SLICE_SW_CTRL_OFF 0x20
#define SLICE_SW_CTRL_PSW_CTRL_OFF_MASK BIT(4)
#define SLICE_SW_CTRL_PDN_SOFT_MASK BIT(31)
#define MIX_FUNC_STAT_OFF 0xB4
#define FUNC_STAT_PSW_STAT_MASK BIT(0)
#define FUNC_STAT_RST_STAT_MASK BIT(2)
#define FUNC_STAT_ISO_STAT_MASK BIT(4)
struct imx93_power_domain {
struct generic_pm_domain genpd;
struct device *dev;
void __iomem *addr;
struct clk_bulk_data *clks;
int num_clks;
bool init_off;
};
#define to_imx93_pd(_genpd) container_of(_genpd, struct imx93_power_domain, genpd)
static int imx93_pd_on(struct generic_pm_domain *genpd)
{
struct imx93_power_domain *domain = to_imx93_pd(genpd);
void __iomem *addr = domain->addr;
u32 val;
int ret;
ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
if (ret) {
dev_err(domain->dev, "failed to enable clocks for domain: %s\n", genpd->name);
return ret;
}
val = readl(addr + MIX_SLICE_SW_CTRL_OFF);
val &= ~SLICE_SW_CTRL_PDN_SOFT_MASK;
writel(val, addr + MIX_SLICE_SW_CTRL_OFF);
ret = readl_poll_timeout(addr + MIX_FUNC_STAT_OFF, val,
!(val & FUNC_STAT_ISO_STAT_MASK), 1, 10000);
if (ret) {
dev_err(domain->dev, "pd_on timeout: name: %s, stat: %x\n", genpd->name, val);
return ret;
}
return 0;
}
static int imx93_pd_off(struct generic_pm_domain *genpd)
{
struct imx93_power_domain *domain = to_imx93_pd(genpd);
void __iomem *addr = domain->addr;
int ret;
u32 val;
/* Power off MIX */
val = readl(addr + MIX_SLICE_SW_CTRL_OFF);
val |= SLICE_SW_CTRL_PDN_SOFT_MASK;
writel(val, addr + MIX_SLICE_SW_CTRL_OFF);
ret = readl_poll_timeout(addr + MIX_FUNC_STAT_OFF, val,
val & FUNC_STAT_PSW_STAT_MASK, 1, 1000);
if (ret) {
dev_err(domain->dev, "pd_off timeout: name: %s, stat: %x\n", genpd->name, val);
return ret;
}
clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
return 0;
};
static int imx93_pd_remove(struct platform_device *pdev)
{
struct imx93_power_domain *domain = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
if (!domain->init_off)
clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
of_genpd_del_provider(np);
pm_genpd_remove(&domain->genpd);
return 0;
}
static int imx93_pd_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct imx93_power_domain *domain;
int ret;
domain = devm_kzalloc(dev, sizeof(*domain), GFP_KERNEL);
if (!domain)
return -ENOMEM;
domain->addr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(domain->addr))
return PTR_ERR(domain->addr);
domain->num_clks = devm_clk_bulk_get_all(dev, &domain->clks);
if (domain->num_clks < 0)
return dev_err_probe(dev, domain->num_clks, "Failed to get domain's clocks\n");
domain->genpd.name = dev_name(dev);
domain->genpd.power_off = imx93_pd_off;
domain->genpd.power_on = imx93_pd_on;
domain->dev = dev;
domain->init_off = readl(domain->addr + MIX_FUNC_STAT_OFF) & FUNC_STAT_ISO_STAT_MASK;
/* Just to sync the status of hardware */
if (!domain->init_off) {
ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
if (ret) {
dev_err(domain->dev, "failed to enable clocks for domain: %s\n",
domain->genpd.name);
return ret;
}
}
ret = pm_genpd_init(&domain->genpd, NULL, domain->init_off);
if (ret)
return ret;
platform_set_drvdata(pdev, domain);
return of_genpd_add_provider_simple(np, &domain->genpd);
}
static const struct of_device_id imx93_pd_ids[] = {
{ .compatible = "fsl,imx93-src-slice" },
{ }
};
MODULE_DEVICE_TABLE(of, imx93_pd_ids);
static struct platform_driver imx93_power_domain_driver = {
.driver = {
.name = "imx93_power_domain",
.owner = THIS_MODULE,
.of_match_table = imx93_pd_ids,
},
.probe = imx93_pd_probe,
.remove = imx93_pd_remove,
};
module_platform_driver(imx93_power_domain_driver);
MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
MODULE_DESCRIPTION("NXP i.MX93 power domain driver");
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2022 NXP
*/
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
static int imx93_src_probe(struct platform_device *pdev)
{
return devm_of_platform_populate(&pdev->dev);
}
static const struct of_device_id imx93_src_ids[] = {
{ .compatible = "fsl,imx93-src" },
{ }
};
MODULE_DEVICE_TABLE(of, imx93_src_ids);
static struct platform_driver imx93_src_driver = {
.driver = {
.name = "imx93_src",
.owner = THIS_MODULE,
.of_match_table = imx93_src_ids,
},
.probe = imx93_src_probe,
};
module_platform_driver(imx93_src_driver);
MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
MODULE_DESCRIPTION("NXP i.MX93 src driver");
MODULE_LICENSE("GPL");
...@@ -37,6 +37,7 @@ config MTK_INFRACFG ...@@ -37,6 +37,7 @@ config MTK_INFRACFG
config MTK_PMIC_WRAP config MTK_PMIC_WRAP
tristate "MediaTek PMIC Wrapper Support" tristate "MediaTek PMIC Wrapper Support"
depends on RESET_CONTROLLER depends on RESET_CONTROLLER
depends on OF
select REGMAP select REGMAP
help help
Say yes here to add support for MediaTek PMIC Wrapper found Say yes here to add support for MediaTek PMIC Wrapper found
...@@ -46,6 +47,7 @@ config MTK_PMIC_WRAP ...@@ -46,6 +47,7 @@ config MTK_PMIC_WRAP
config MTK_SCPSYS config MTK_SCPSYS
bool "MediaTek SCPSYS Support" bool "MediaTek SCPSYS Support"
default ARCH_MEDIATEK default ARCH_MEDIATEK
depends on OF
select REGMAP select REGMAP
select MTK_INFRACFG select MTK_INFRACFG
select PM_GENERIC_DOMAINS if PM select PM_GENERIC_DOMAINS if PM
......
...@@ -3,6 +3,12 @@ ...@@ -3,6 +3,12 @@
#ifndef __SOC_MEDIATEK_MT8186_MMSYS_H #ifndef __SOC_MEDIATEK_MT8186_MMSYS_H
#define __SOC_MEDIATEK_MT8186_MMSYS_H #define __SOC_MEDIATEK_MT8186_MMSYS_H
/* Values for DPI configuration in MMSYS address space */
#define MT8186_MMSYS_DPI_OUTPUT_FORMAT 0x400
#define DPI_FORMAT_MASK 0x1
#define DPI_RGB888_DDR_CON BIT(0)
#define DPI_RGB565_SDR_CON BIT(1)
#define MT8186_MMSYS_OVL_CON 0xF04 #define MT8186_MMSYS_OVL_CON 0xF04
#define MT8186_MMSYS_OVL0_CON_MASK 0x3 #define MT8186_MMSYS_OVL0_CON_MASK 0x3
#define MT8186_MMSYS_OVL0_2L_CON_MASK 0xC #define MT8186_MMSYS_OVL0_2L_CON_MASK 0xC
......
...@@ -227,6 +227,26 @@ void mtk_mmsys_ddp_disconnect(struct device *dev, ...@@ -227,6 +227,26 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
} }
EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect); EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask, u32 val)
{
u32 tmp;
tmp = readl_relaxed(mmsys->regs + offset);
tmp = (tmp & ~mask) | val;
writel_relaxed(tmp, mmsys->regs + offset);
}
void mtk_mmsys_ddp_dpi_fmt_config(struct device *dev, u32 val)
{
if (val)
mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8186_MMSYS_DPI_OUTPUT_FORMAT,
DPI_RGB888_DDR_CON, DPI_FORMAT_MASK);
else
mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8186_MMSYS_DPI_OUTPUT_FORMAT,
DPI_RGB565_SDR_CON, DPI_FORMAT_MASK);
}
EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_dpi_fmt_config);
static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id, static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id,
bool assert) bool assert)
{ {
......
...@@ -91,6 +91,15 @@ ...@@ -91,6 +91,15 @@
#define MT8183_MUTEX_MOD_MDP_AAL0 23 #define MT8183_MUTEX_MOD_MDP_AAL0 23
#define MT8183_MUTEX_MOD_MDP_CCORR0 24 #define MT8183_MUTEX_MOD_MDP_CCORR0 24
#define MT8186_MUTEX_MOD_MDP_RDMA0 0
#define MT8186_MUTEX_MOD_MDP_AAL0 2
#define MT8186_MUTEX_MOD_MDP_HDR0 4
#define MT8186_MUTEX_MOD_MDP_RSZ0 5
#define MT8186_MUTEX_MOD_MDP_RSZ1 6
#define MT8186_MUTEX_MOD_MDP_WROT0 7
#define MT8186_MUTEX_MOD_MDP_TDSHP0 9
#define MT8186_MUTEX_MOD_MDP_COLOR0 14
#define MT8173_MUTEX_MOD_DISP_OVL0 11 #define MT8173_MUTEX_MOD_DISP_OVL0 11
#define MT8173_MUTEX_MOD_DISP_OVL1 12 #define MT8173_MUTEX_MOD_DISP_OVL1 12
#define MT8173_MUTEX_MOD_DISP_RDMA0 13 #define MT8173_MUTEX_MOD_DISP_RDMA0 13
...@@ -324,6 +333,17 @@ static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = { ...@@ -324,6 +333,17 @@ static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1, [DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1,
}; };
static const unsigned int mt8186_mdp_mutex_table_mod[MUTEX_MOD_IDX_MAX] = {
[MUTEX_MOD_IDX_MDP_RDMA0] = MT8186_MUTEX_MOD_MDP_RDMA0,
[MUTEX_MOD_IDX_MDP_RSZ0] = MT8186_MUTEX_MOD_MDP_RSZ0,
[MUTEX_MOD_IDX_MDP_RSZ1] = MT8186_MUTEX_MOD_MDP_RSZ1,
[MUTEX_MOD_IDX_MDP_TDSHP0] = MT8186_MUTEX_MOD_MDP_TDSHP0,
[MUTEX_MOD_IDX_MDP_WROT0] = MT8186_MUTEX_MOD_MDP_WROT0,
[MUTEX_MOD_IDX_MDP_HDR0] = MT8186_MUTEX_MOD_MDP_HDR0,
[MUTEX_MOD_IDX_MDP_AAL0] = MT8186_MUTEX_MOD_MDP_AAL0,
[MUTEX_MOD_IDX_MDP_COLOR0] = MT8186_MUTEX_MOD_MDP_COLOR0,
};
static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = { static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0, [DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
[DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0, [DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
...@@ -380,6 +400,13 @@ static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = { ...@@ -380,6 +400,13 @@ static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
[MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3, [MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
}; };
static const unsigned int mt6795_mutex_sof[DDP_MUTEX_SOF_MAX] = {
[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
[MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0,
};
static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = { static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
...@@ -434,6 +461,13 @@ static const struct mtk_mutex_data mt2712_mutex_driver_data = { ...@@ -434,6 +461,13 @@ static const struct mtk_mutex_data mt2712_mutex_driver_data = {
.mutex_sof_reg = MT2701_MUTEX0_SOF0, .mutex_sof_reg = MT2701_MUTEX0_SOF0,
}; };
static const struct mtk_mutex_data mt6795_mutex_driver_data = {
.mutex_mod = mt8173_mutex_mod,
.mutex_sof = mt6795_mutex_sof,
.mutex_mod_reg = MT2701_MUTEX0_MOD0,
.mutex_sof_reg = MT2701_MUTEX0_SOF0,
};
static const struct mtk_mutex_data mt8167_mutex_driver_data = { static const struct mtk_mutex_data mt8167_mutex_driver_data = {
.mutex_mod = mt8167_mutex_mod, .mutex_mod = mt8167_mutex_mod,
.mutex_sof = mt8167_mutex_sof, .mutex_sof = mt8167_mutex_sof,
...@@ -458,6 +492,12 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = { ...@@ -458,6 +492,12 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
.no_clk = true, .no_clk = true,
}; };
static const struct mtk_mutex_data mt8186_mdp_mutex_driver_data = {
.mutex_mod_reg = MT8183_MUTEX0_MOD0,
.mutex_sof_reg = MT8183_MUTEX0_SOF0,
.mutex_table_mod = mt8186_mdp_mutex_table_mod,
};
static const struct mtk_mutex_data mt8186_mutex_driver_data = { static const struct mtk_mutex_data mt8186_mutex_driver_data = {
.mutex_mod = mt8186_mutex_mod, .mutex_mod = mt8186_mutex_mod,
.mutex_sof = mt8186_mutex_sof, .mutex_sof = mt8186_mutex_sof,
...@@ -802,6 +842,8 @@ static const struct of_device_id mutex_driver_dt_match[] = { ...@@ -802,6 +842,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
.data = &mt2701_mutex_driver_data}, .data = &mt2701_mutex_driver_data},
{ .compatible = "mediatek,mt2712-disp-mutex", { .compatible = "mediatek,mt2712-disp-mutex",
.data = &mt2712_mutex_driver_data}, .data = &mt2712_mutex_driver_data},
{ .compatible = "mediatek,mt6795-disp-mutex",
.data = &mt6795_mutex_driver_data},
{ .compatible = "mediatek,mt8167-disp-mutex", { .compatible = "mediatek,mt8167-disp-mutex",
.data = &mt8167_mutex_driver_data}, .data = &mt8167_mutex_driver_data},
{ .compatible = "mediatek,mt8173-disp-mutex", { .compatible = "mediatek,mt8173-disp-mutex",
...@@ -810,6 +852,8 @@ static const struct of_device_id mutex_driver_dt_match[] = { ...@@ -810,6 +852,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
.data = &mt8183_mutex_driver_data}, .data = &mt8183_mutex_driver_data},
{ .compatible = "mediatek,mt8186-disp-mutex", { .compatible = "mediatek,mt8186-disp-mutex",
.data = &mt8186_mutex_driver_data}, .data = &mt8186_mutex_driver_data},
{ .compatible = "mediatek,mt8186-mdp3-mutex",
.data = &mt8186_mdp_mutex_driver_data},
{ .compatible = "mediatek,mt8192-disp-mutex", { .compatible = "mediatek,mt8192-disp-mutex",
.data = &mt8192_mutex_driver_data}, .data = &mt8192_mutex_driver_data},
{ .compatible = "mediatek,mt8195-disp-mutex", { .compatible = "mediatek,mt8195-disp-mutex",
......
...@@ -393,7 +393,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no ...@@ -393,7 +393,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
ret = PTR_ERR(clk); ret = PTR_ERR(clk);
dev_err_probe(scpsys->dev, ret, dev_err_probe(scpsys->dev, ret,
"%pOF: failed to get clk at index %d: %d\n", node, i, ret); "%pOF: failed to get clk at index %d\n", node, i);
goto err_put_clocks; goto err_put_clocks;
} }
...@@ -405,8 +405,8 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no ...@@ -405,8 +405,8 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
ret = PTR_ERR(clk); ret = PTR_ERR(clk);
dev_err_probe(scpsys->dev, ret, dev_err_probe(scpsys->dev, ret,
"%pOF: failed to get clk at index %d: %d\n", node, "%pOF: failed to get clk at index %d\n", node,
i + clk_ind, ret); i + clk_ind);
goto err_put_subsys_clocks; goto err_put_subsys_clocks;
} }
......
...@@ -2316,7 +2316,7 @@ static int pwrap_probe(struct platform_device *pdev) ...@@ -2316,7 +2316,7 @@ static int pwrap_probe(struct platform_device *pdev)
static struct platform_driver pwrap_drv = { static struct platform_driver pwrap_drv = {
.driver = { .driver = {
.name = "mt-pmic-pwrap", .name = "mt-pmic-pwrap",
.of_match_table = of_match_ptr(of_pwrap_match_tbl), .of_match_table = of_pwrap_match_tbl,
}, },
.probe = pwrap_probe, .probe = pwrap_probe,
}; };
......
...@@ -1141,7 +1141,7 @@ static struct platform_driver scpsys_drv = { ...@@ -1141,7 +1141,7 @@ static struct platform_driver scpsys_drv = {
.name = "mtk-scpsys", .name = "mtk-scpsys",
.suppress_bind_attrs = true, .suppress_bind_attrs = true,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = of_match_ptr(of_scpsys_match_tbl), .of_match_table = of_scpsys_match_tbl,
}, },
}; };
builtin_platform_driver(scpsys_drv); builtin_platform_driver(scpsys_drv);
This diff is collapsed.
...@@ -129,7 +129,7 @@ config QCOM_RPMHPD ...@@ -129,7 +129,7 @@ config QCOM_RPMHPD
config QCOM_RPMPD config QCOM_RPMPD
tristate "Qualcomm RPM Power domain driver" tristate "Qualcomm RPM Power domain driver"
depends on PM depends on PM && OF
depends on QCOM_SMD_RPM depends on QCOM_SMD_RPM
select PM_GENERIC_DOMAINS select PM_GENERIC_DOMAINS
select PM_GENERIC_DOMAINS_OF select PM_GENERIC_DOMAINS_OF
......
This diff is collapsed.
...@@ -104,6 +104,7 @@ struct qcom_llcc_config { ...@@ -104,6 +104,7 @@ struct qcom_llcc_config {
int size; int size;
bool need_llcc_cfg; bool need_llcc_cfg;
const u32 *reg_offset; const u32 *reg_offset;
const struct llcc_edac_reg_offset *edac_reg_offset;
}; };
enum llcc_reg_offset { enum llcc_reg_offset {
...@@ -296,12 +297,68 @@ static const struct llcc_slice_config sm8450_data[] = { ...@@ -296,12 +297,68 @@ static const struct llcc_slice_config sm8450_data[] = {
{LLCC_AENPU, 8, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 }, {LLCC_AENPU, 8, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 },
}; };
static const u32 llcc_v1_2_reg_offset[] = { static const struct llcc_edac_reg_offset llcc_v1_edac_reg_offset = {
.trp_ecc_error_status0 = 0x20344,
.trp_ecc_error_status1 = 0x20348,
.trp_ecc_sb_err_syn0 = 0x2304c,
.trp_ecc_db_err_syn0 = 0x20370,
.trp_ecc_error_cntr_clear = 0x20440,
.trp_interrupt_0_status = 0x20480,
.trp_interrupt_0_clear = 0x20484,
.trp_interrupt_0_enable = 0x20488,
/* LLCC Common registers */
.cmn_status0 = 0x3000c,
.cmn_interrupt_0_enable = 0x3001c,
.cmn_interrupt_2_enable = 0x3003c,
/* LLCC DRP registers */
.drp_ecc_error_cfg = 0x40000,
.drp_ecc_error_cntr_clear = 0x40004,
.drp_interrupt_status = 0x41000,
.drp_interrupt_clear = 0x41008,
.drp_interrupt_enable = 0x4100c,
.drp_ecc_error_status0 = 0x42044,
.drp_ecc_error_status1 = 0x42048,
.drp_ecc_sb_err_syn0 = 0x4204c,
.drp_ecc_db_err_syn0 = 0x42070,
};
static const struct llcc_edac_reg_offset llcc_v2_1_edac_reg_offset = {
.trp_ecc_error_status0 = 0x20344,
.trp_ecc_error_status1 = 0x20348,
.trp_ecc_sb_err_syn0 = 0x2034c,
.trp_ecc_db_err_syn0 = 0x20370,
.trp_ecc_error_cntr_clear = 0x20440,
.trp_interrupt_0_status = 0x20480,
.trp_interrupt_0_clear = 0x20484,
.trp_interrupt_0_enable = 0x20488,
/* LLCC Common registers */
.cmn_status0 = 0x3400c,
.cmn_interrupt_0_enable = 0x3401c,
.cmn_interrupt_2_enable = 0x3403c,
/* LLCC DRP registers */
.drp_ecc_error_cfg = 0x50000,
.drp_ecc_error_cntr_clear = 0x50004,
.drp_interrupt_status = 0x50020,
.drp_interrupt_clear = 0x50028,
.drp_interrupt_enable = 0x5002c,
.drp_ecc_error_status0 = 0x520f4,
.drp_ecc_error_status1 = 0x520f8,
.drp_ecc_sb_err_syn0 = 0x520fc,
.drp_ecc_db_err_syn0 = 0x52120,
};
/* LLCC register offset starting from v1.0.0 */
static const u32 llcc_v1_reg_offset[] = {
[LLCC_COMMON_HW_INFO] = 0x00030000, [LLCC_COMMON_HW_INFO] = 0x00030000,
[LLCC_COMMON_STATUS0] = 0x0003000c, [LLCC_COMMON_STATUS0] = 0x0003000c,
}; };
static const u32 llcc_v21_reg_offset[] = { /* LLCC register offset starting from v2.0.1 */
static const u32 llcc_v2_1_reg_offset[] = {
[LLCC_COMMON_HW_INFO] = 0x00034000, [LLCC_COMMON_HW_INFO] = 0x00034000,
[LLCC_COMMON_STATUS0] = 0x0003400c, [LLCC_COMMON_STATUS0] = 0x0003400c,
}; };
...@@ -310,70 +367,80 @@ static const struct qcom_llcc_config sc7180_cfg = { ...@@ -310,70 +367,80 @@ static const struct qcom_llcc_config sc7180_cfg = {
.sct_data = sc7180_data, .sct_data = sc7180_data,
.size = ARRAY_SIZE(sc7180_data), .size = ARRAY_SIZE(sc7180_data),
.need_llcc_cfg = true, .need_llcc_cfg = true,
.reg_offset = llcc_v1_2_reg_offset, .reg_offset = llcc_v1_reg_offset,
.edac_reg_offset = &llcc_v1_edac_reg_offset,
}; };
static const struct qcom_llcc_config sc7280_cfg = { static const struct qcom_llcc_config sc7280_cfg = {
.sct_data = sc7280_data, .sct_data = sc7280_data,
.size = ARRAY_SIZE(sc7280_data), .size = ARRAY_SIZE(sc7280_data),
.need_llcc_cfg = true, .need_llcc_cfg = true,
.reg_offset = llcc_v1_2_reg_offset, .reg_offset = llcc_v1_reg_offset,
.edac_reg_offset = &llcc_v1_edac_reg_offset,
}; };
static const struct qcom_llcc_config sc8180x_cfg = { static const struct qcom_llcc_config sc8180x_cfg = {
.sct_data = sc8180x_data, .sct_data = sc8180x_data,
.size = ARRAY_SIZE(sc8180x_data), .size = ARRAY_SIZE(sc8180x_data),
.need_llcc_cfg = true, .need_llcc_cfg = true,
.reg_offset = llcc_v1_2_reg_offset, .reg_offset = llcc_v1_reg_offset,
.edac_reg_offset = &llcc_v1_edac_reg_offset,
}; };
static const struct qcom_llcc_config sc8280xp_cfg = { static const struct qcom_llcc_config sc8280xp_cfg = {
.sct_data = sc8280xp_data, .sct_data = sc8280xp_data,
.size = ARRAY_SIZE(sc8280xp_data), .size = ARRAY_SIZE(sc8280xp_data),
.need_llcc_cfg = true, .need_llcc_cfg = true,
.reg_offset = llcc_v1_2_reg_offset, .reg_offset = llcc_v1_reg_offset,
.edac_reg_offset = &llcc_v1_edac_reg_offset,
}; };
static const struct qcom_llcc_config sdm845_cfg = { static const struct qcom_llcc_config sdm845_cfg = {
.sct_data = sdm845_data, .sct_data = sdm845_data,
.size = ARRAY_SIZE(sdm845_data), .size = ARRAY_SIZE(sdm845_data),
.need_llcc_cfg = false, .need_llcc_cfg = false,
.reg_offset = llcc_v1_2_reg_offset, .reg_offset = llcc_v1_reg_offset,
.edac_reg_offset = &llcc_v1_edac_reg_offset,
}; };
static const struct qcom_llcc_config sm6350_cfg = { static const struct qcom_llcc_config sm6350_cfg = {
.sct_data = sm6350_data, .sct_data = sm6350_data,
.size = ARRAY_SIZE(sm6350_data), .size = ARRAY_SIZE(sm6350_data),
.need_llcc_cfg = true, .need_llcc_cfg = true,
.reg_offset = llcc_v1_2_reg_offset, .reg_offset = llcc_v1_reg_offset,
.edac_reg_offset = &llcc_v1_edac_reg_offset,
}; };
static const struct qcom_llcc_config sm8150_cfg = { static const struct qcom_llcc_config sm8150_cfg = {
.sct_data = sm8150_data, .sct_data = sm8150_data,
.size = ARRAY_SIZE(sm8150_data), .size = ARRAY_SIZE(sm8150_data),
.need_llcc_cfg = true, .need_llcc_cfg = true,
.reg_offset = llcc_v1_2_reg_offset, .reg_offset = llcc_v1_reg_offset,
.edac_reg_offset = &llcc_v1_edac_reg_offset,
}; };
static const struct qcom_llcc_config sm8250_cfg = { static const struct qcom_llcc_config sm8250_cfg = {
.sct_data = sm8250_data, .sct_data = sm8250_data,
.size = ARRAY_SIZE(sm8250_data), .size = ARRAY_SIZE(sm8250_data),
.need_llcc_cfg = true, .need_llcc_cfg = true,
.reg_offset = llcc_v1_2_reg_offset, .reg_offset = llcc_v1_reg_offset,
.edac_reg_offset = &llcc_v1_edac_reg_offset,
}; };
static const struct qcom_llcc_config sm8350_cfg = { static const struct qcom_llcc_config sm8350_cfg = {
.sct_data = sm8350_data, .sct_data = sm8350_data,
.size = ARRAY_SIZE(sm8350_data), .size = ARRAY_SIZE(sm8350_data),
.need_llcc_cfg = true, .need_llcc_cfg = true,
.reg_offset = llcc_v1_2_reg_offset, .reg_offset = llcc_v1_reg_offset,
.edac_reg_offset = &llcc_v1_edac_reg_offset,
}; };
static const struct qcom_llcc_config sm8450_cfg = { static const struct qcom_llcc_config sm8450_cfg = {
.sct_data = sm8450_data, .sct_data = sm8450_data,
.size = ARRAY_SIZE(sm8450_data), .size = ARRAY_SIZE(sm8450_data),
.need_llcc_cfg = true, .need_llcc_cfg = true,
.reg_offset = llcc_v21_reg_offset, .reg_offset = llcc_v2_1_reg_offset,
.edac_reg_offset = &llcc_v2_1_edac_reg_offset,
}; };
static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER; static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
...@@ -774,6 +841,7 @@ static int qcom_llcc_probe(struct platform_device *pdev) ...@@ -774,6 +841,7 @@ static int qcom_llcc_probe(struct platform_device *pdev)
drv_data->cfg = llcc_cfg; drv_data->cfg = llcc_cfg;
drv_data->cfg_size = sz; drv_data->cfg_size = sz;
drv_data->edac_reg_offset = cfg->edac_reg_offset;
mutex_init(&drv_data->lock); mutex_init(&drv_data->lock);
platform_set_drvdata(pdev, drv_data); platform_set_drvdata(pdev, drv_data);
......
...@@ -246,6 +246,14 @@ static const struct stats_config rpm_data_dba0 = { ...@@ -246,6 +246,14 @@ static const struct stats_config rpm_data_dba0 = {
.subsystem_stats_in_smem = false, .subsystem_stats_in_smem = false,
}; };
static const struct stats_config rpmh_data_sdm845 = {
.stats_offset = 0x48,
.num_records = 2,
.appended_stats_avail = false,
.dynamic_offset = false,
.subsystem_stats_in_smem = true,
};
static const struct stats_config rpmh_data = { static const struct stats_config rpmh_data = {
.stats_offset = 0x48, .stats_offset = 0x48,
.num_records = 3, .num_records = 3,
...@@ -261,6 +269,7 @@ static const struct of_device_id qcom_stats_table[] = { ...@@ -261,6 +269,7 @@ static const struct of_device_id qcom_stats_table[] = {
{ .compatible = "qcom,msm8974-rpm-stats", .data = &rpm_data_dba0 }, { .compatible = "qcom,msm8974-rpm-stats", .data = &rpm_data_dba0 },
{ .compatible = "qcom,rpm-stats", .data = &rpm_data }, { .compatible = "qcom,rpm-stats", .data = &rpm_data },
{ .compatible = "qcom,rpmh-stats", .data = &rpmh_data }, { .compatible = "qcom,rpmh-stats", .data = &rpmh_data },
{ .compatible = "qcom,sdm845-rpmh-stats", .data = &rpmh_data_sdm845 },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, qcom_stats_table); MODULE_DEVICE_TABLE(of, qcom_stats_table);
......
This diff is collapsed.
This diff is collapsed.
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define RPMPD_RWLM 0x6d6c7772 #define RPMPD_RWLM 0x6d6c7772
#define RPMPD_RWSC 0x63737772 #define RPMPD_RWSC 0x63737772
#define RPMPD_RWSM 0x6d737772 #define RPMPD_RWSM 0x6d737772
#define RPMPD_RWGX 0x78677772
/* Operation Keys */ /* Operation Keys */
#define KEY_CORNER 0x6e726f63 /* corn */ #define KEY_CORNER 0x6e726f63 /* corn */
...@@ -433,6 +434,26 @@ static const struct rpmpd_desc sm6125_desc = { ...@@ -433,6 +434,26 @@ static const struct rpmpd_desc sm6125_desc = {
.max_state = RPM_SMD_LEVEL_BINNING, .max_state = RPM_SMD_LEVEL_BINNING,
}; };
DEFINE_RPMPD_PAIR(sm6375, vddgx, vddgx_ao, RWGX, LEVEL, 0);
static struct rpmpd *sm6375_rpmpds[] = {
[SM6375_VDDCX] = &sm6125_vddcx,
[SM6375_VDDCX_AO] = &sm6125_vddcx_ao,
[SM6375_VDDCX_VFL] = &sm6125_vddcx_vfl,
[SM6375_VDDMX] = &sm6125_vddmx,
[SM6375_VDDMX_AO] = &sm6125_vddmx_ao,
[SM6375_VDDMX_VFL] = &sm6125_vddmx_vfl,
[SM6375_VDDGX] = &sm6375_vddgx,
[SM6375_VDDGX_AO] = &sm6375_vddgx_ao,
[SM6375_VDD_LPI_CX] = &sm6115_vdd_lpi_cx,
[SM6375_VDD_LPI_MX] = &sm6115_vdd_lpi_mx,
};
static const struct rpmpd_desc sm6375_desc = {
.rpmpds = sm6375_rpmpds,
.num_pds = ARRAY_SIZE(sm6375_rpmpds),
.max_state = RPM_SMD_LEVEL_TURBO_NO_CPR,
};
static struct rpmpd *qcm2290_rpmpds[] = { static struct rpmpd *qcm2290_rpmpds[] = {
[QCM2290_VDDCX] = &sm6115_vddcx, [QCM2290_VDDCX] = &sm6115_vddcx,
[QCM2290_VDDCX_AO] = &sm6115_vddcx_ao, [QCM2290_VDDCX_AO] = &sm6115_vddcx_ao,
...@@ -466,6 +487,7 @@ static const struct of_device_id rpmpd_match_table[] = { ...@@ -466,6 +487,7 @@ static const struct of_device_id rpmpd_match_table[] = {
{ .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc }, { .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc },
{ .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc }, { .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc },
{ .compatible = "qcom,sm6125-rpmpd", .data = &sm6125_desc }, { .compatible = "qcom,sm6125-rpmpd", .data = &sm6125_desc },
{ .compatible = "qcom,sm6375-rpmpd", .data = &sm6375_desc },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, rpmpd_match_table); MODULE_DEVICE_TABLE(of, rpmpd_match_table);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment