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:
Sequencer DRAM parameters and control registers. Used for Self-Refresh
Power-Down (SRPD), among other things.
Required properties:
- compatible : should contain one of these
"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
See Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml for a
full list of supported compatible strings and properties.
Example:
......
......@@ -554,8 +554,7 @@ properties:
- engicam,imx6ul-isiot # Engicam Is.IoT MX6UL eMMC/NAND Starter kit
- fsl,imx6ul-14x14-evk # i.MX6 UltraLite 14x14 EVK Board
- karo,imx6ul-tx6ul # Ka-Ro electronics TXUL-0010 Module
- kontron,imx6ul-n6310-som # Kontron N6310 SOM
- kontron,imx6ul-n6311-som # Kontron N6311 SOM
- kontron,sl-imx6ul # Kontron SL i.MX6UL SoM
- prt,prti6g # Protonic PRTI6G Board
- technexion,imx6ul-pico-dwarf # TechNexion i.MX6UL Pico-Dwarf
- technexion,imx6ul-pico-hobbit # TechNexion i.MX6UL Pico-Hobbit
......@@ -591,23 +590,17 @@ properties:
- const: phytec,imx6ul-pcl063 # PHYTEC phyCORE-i.MX 6UL
- const: fsl,imx6ul
- description: Kontron N6310 S Board
- description: Kontron BL i.MX6UL (N631X S) Board
items:
- const: kontron,imx6ul-n6310-s
- const: kontron,imx6ul-n6310-som
- const: kontron,bl-imx6ul # Kontron BL i.MX6UL Carrier Board
- const: kontron,sl-imx6ul # Kontron SL i.MX6UL SoM
- const: fsl,imx6ul
- description: Kontron N6311 S Board
- description: Kontron BL i.MX6UL 43 (N631X S 43) Board
items:
- const: kontron,imx6ul-n6311-s
- const: kontron,imx6ul-n6311-som
- const: fsl,imx6ul
- description: Kontron N6310 S 43 Board
items:
- const: kontron,imx6ul-n6310-s-43
- const: kontron,imx6ul-n6310-s
- const: kontron,imx6ul-n6310-som
- const: kontron,bl-imx6ul-43 # Kontron BL i.MX6UL Carrier Board with 4.3" Display
- const: kontron,bl-imx6ul # Kontron BL i.MX6UL Carrier Board
- const: kontron,sl-imx6ul # Kontron SL i.MX6UL SoM
- const: fsl,imx6ul
- description: TQ-Systems TQMa6UL1 SoM on MBa6ULx board
......@@ -637,7 +630,7 @@ properties:
- enum:
- fsl,imx6ull-14x14-evk # i.MX6 UltraLiteLite 14x14 EVK Board
- 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
- toradex,colibri-imx6ull # Colibri iMX6ULL Modules
- toradex,colibri-imx6ull-emmc # Colibri iMX6ULL 1GB (eMMC) Module
......@@ -698,10 +691,10 @@ properties:
- const: toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Module
- const: fsl,imx6ull
- description: Kontron N6411 S Board
- description: Kontron BL i.MX6ULL (N6411 S) Board
items:
- const: kontron,imx6ull-n6411-s
- const: kontron,imx6ull-n6411-som
- const: kontron,bl-imx6ull # Kontron BL i.MX6ULL Carrier Board
- const: kontron,sl-imx6ull # Kontron SL i.MX6ULL SoM
- const: fsl,imx6ull
- description: TQ Systems TQMa6ULLx SoM on MBa6ULx board
......@@ -825,13 +818,15 @@ properties:
- emtrion,emcon-mx8mm-avari # emCON-MX8MM SoM on Avari Base
- fsl,imx8mm-ddr4-evk # i.MX8MM DDR4 EVK Board
- fsl,imx8mm-evk # i.MX8MM EVK Board
- gateworks,imx8mm-gw7904
- gw,imx8mm-gw71xx-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-gw7901 # i.MX8MM Gateworks Board
- gw,imx8mm-gw7902 # 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
- toradex,verdin-imx8mm # Verdin iMX8M Mini Modules
- toradex,verdin-imx8mm-nonwifi # Verdin iMX8M Mini Modules without Wi-Fi / BT
......@@ -850,8 +845,14 @@ properties:
- description: Kontron BL i.MX8MM (N801X S) Board
items:
- const: kontron,imx8mm-n801x-s
- const: kontron,imx8mm-n801x-som
- const: kontron,imx8mm-bl
- 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
- description: Toradex Boards with Verdin iMX8M Mini Modules
......@@ -936,6 +937,13 @@ properties:
- toradex,verdin-imx8mp-wifi # Verdin iMX8M Plus Wi-Fi / BT Modules
- 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
items:
- enum:
......@@ -1034,6 +1042,12 @@ properties:
- toradex,colibri-imx8x # Colibri iMX8X Modules
- 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
items:
- enum:
......
......@@ -21,10 +21,12 @@ select:
enum:
- rockchip,px30-pmu
- rockchip,rk3066-pmu
- rockchip,rk3128-pmu
- rockchip,rk3288-pmu
- rockchip,rk3368-pmu
- rockchip,rk3399-pmu
- rockchip,rk3568-pmu
- rockchip,rk3588-pmu
required:
- compatible
......@@ -35,10 +37,12 @@ properties:
- enum:
- rockchip,px30-pmu
- rockchip,rk3066-pmu
- rockchip,rk3128-pmu
- rockchip,rk3288-pmu
- rockchip,rk3368-pmu
- rockchip,rk3399-pmu
- rockchip,rk3568-pmu
- rockchip,rk3588-pmu
- const: syscon
- 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:
oneOf:
- items:
- enum:
- qcom,sc7280-bwmon
- qcom,sdm845-bwmon
- const: qcom,msm8998-bwmon
- const: qcom,msm8998-bwmon # BWMON v4
- const: qcom,sc7280-llcc-bwmon # BWMON v5
- const: qcom,sdm845-llcc-bwmon # BWMON v5
interconnects:
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: |
MediaTek SMI have two generations of HW architecture, here is the list
which generation the SoCs use:
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
register which control the iommu port is at each larb's register base. But
......@@ -37,6 +37,8 @@ properties:
- mediatek,mt8173-smi-common
- mediatek,mt8183-smi-common
- mediatek,mt8186-smi-common
- mediatek,mt8188-smi-common-vdo
- mediatek,mt8188-smi-common-vpp
- mediatek,mt8192-smi-common
- mediatek,mt8195-smi-common-vdo
- mediatek,mt8195-smi-common-vpp
......@@ -144,7 +146,16 @@ allOf:
- const: gals0
- 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:
clocks:
minItems: 2
......
......@@ -25,6 +25,7 @@ properties:
- mediatek,mt8173-smi-larb
- mediatek,mt8183-smi-larb
- mediatek,mt8186-smi-larb
- mediatek,mt8188-smi-larb
- mediatek,mt8192-smi-larb
- mediatek,mt8195-smi-larb
......@@ -78,6 +79,7 @@ allOf:
enum:
- mediatek,mt8183-smi-larb
- mediatek,mt8186-smi-larb
- mediatek,mt8188-smi-larb
- mediatek,mt8195-smi-larb
then:
......@@ -111,6 +113,7 @@ allOf:
- mediatek,mt2712-smi-larb
- mediatek,mt6779-smi-larb
- mediatek,mt8186-smi-larb
- mediatek,mt8188-smi-larb
- mediatek,mt8192-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:
- allwinner,sun50i-a64-system-controller
- brcm,cru-clkset
- freecom,fsg-cs2-system-controller
- fsl,imx93-aonmix-ns-syscfg
- fsl,imx93-wakeupmix-syscfg
- hisilicon,dsa-subctrl
- hisilicon,hi6220-sramctrl
- hisilicon,pcie-sas-subctrl
......
......@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek Power Domains Controller
maintainers:
- Weiyi Lu <weiyi.lu@mediatek.com>
- MandyJH Liu <mandyjh.liu@mediatek.com>
- Matthias Brugger <mbrugger@suse.com>
description: |
......@@ -19,7 +19,7 @@ description: |
properties:
$nodename:
const: power-controller
pattern: '^power-controller(@[0-9a-f]+)?$'
compatible:
enum:
......@@ -42,6 +42,23 @@ properties:
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"
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
description: |
Represents the power domains within the power controller node as documented
......@@ -100,123 +117,9 @@ patternProperties:
$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.
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:
- reg
additionalProperties: false
required:
- compatible
......
......@@ -40,6 +40,7 @@ properties:
- qcom,sm6115-rpmpd
- qcom,sm6125-rpmpd
- qcom,sm6350-rpmhpd
- qcom,sm6375-rpmpd
- qcom,sm8150-rpmhpd
- qcom,sm8250-rpmhpd
- qcom,sm8350-rpmhpd
......
......@@ -41,6 +41,8 @@ properties:
- rockchip,rk3368-power-controller
- rockchip,rk3399-power-controller
- rockchip,rk3568-power-controller
- rockchip,rk3588-power-controller
- rockchip,rv1126-power-controller
"#power-domain-cells":
const: 1
......@@ -119,6 +121,8 @@ $defs:
"include/dt-bindings/power/rk3368-power.h"
"include/dt-bindings/power/rk3399-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:
minItems: 1
......
......@@ -58,6 +58,7 @@ properties:
- rockchip,rk3568-pmu-io-voltage-domain
- rockchip,rv1108-io-voltage-domain
- rockchip,rv1108-pmu-io-voltage-domain
- rockchip,rv1126-pmu-io-voltage-domain
required:
- compatible
......@@ -78,6 +79,7 @@ allOf:
- $ref: "#/$defs/rk3568-pmu"
- $ref: "#/$defs/rv1108"
- $ref: "#/$defs/rv1108-pmu"
- $ref: "#/$defs/rv1126-pmu"
$defs:
px30:
......@@ -344,6 +346,34 @@ $defs:
pmu-supply:
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:
- |
io-domains {
......
......@@ -27,25 +27,22 @@ properties:
const: 1
power-domains:
minItems: 4
maxItems: 4
power-domain-names:
items:
- const: bus
- const: g1
- const: g2
- const: h1
maxItems: 4
clocks:
minItems: 3
maxItems: 3
clock-names:
items:
- const: g1
- const: g2
- const: h1
maxItems: 3
interconnects:
maxItems: 3
interconnect-names:
maxItems: 3
required:
- compatible
......@@ -55,6 +52,97 @@ required:
- clocks
- 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
examples:
......
......@@ -52,6 +52,15 @@ properties:
- const: ref_266m
- const: ref_24m
interconnects:
maxItems: 3
interconnect-names:
items:
- const: hrv
- const: lcdif-hdmi
- const: hdcp
required:
- compatible
- reg
......
......@@ -48,6 +48,16 @@ properties:
- const: usb
- const: pcie
interconnects:
maxItems: 4
interconnect-names:
items:
- const: noc-pcie
- const: usb1
- const: usb2
- const: pcie
required:
- compatible
- reg
......
......@@ -64,6 +64,20 @@ properties:
- const: isp
- 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:
- compatible
- 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:
enum:
- mediatek,mt2701-disp-mutex
- mediatek,mt2712-disp-mutex
- mediatek,mt6795-disp-mutex
- mediatek,mt8167-disp-mutex
- mediatek,mt8173-disp-mutex
- mediatek,mt8183-disp-mutex
- mediatek,mt8186-disp-mutex
- mediatek,mt8186-mdp3-mutex
- mediatek,mt8192-disp-mutex
- mediatek,mt8195-disp-mutex
......
......@@ -28,6 +28,7 @@ Required properties in pwrap device node.
"mediatek,mt8173-pwrap" for MT8173 SoCs
"mediatek,mt8183-pwrap" for MT8183 SoCs
"mediatek,mt8186-pwrap" for MT8186 SoCs
"mediatek,mt8188-pwrap", "mediatek,mt8195-pwrap" for MT8188 SoCs
"mediatek,mt8195-pwrap" for MT8195 SoCs
"mediatek,mt8516-pwrap" for MT8516 SoCs
- interrupts: IRQ for pwrap in SOC
......
......@@ -20,6 +20,7 @@ properties:
compatible:
enum:
- qcom,rpmh-stats
- qcom,sdm845-rpmh-stats
- qcom,rpm-stats
# For older RPM firmware versions with fixed offset for the sleep stats
- qcom,apq8084-rpm-stats
......
......@@ -16,9 +16,12 @@ properties:
- enum:
- rockchip,rk3288-sgrf
- rockchip,rk3566-pipe-grf
- rockchip,rk3568-pcie3-phy-grf
- rockchip,rk3568-pipe-grf
- rockchip,rk3568-pipe-phy-grf
- rockchip,rk3568-usb2phy-grf
- rockchip,rk3588-pcie3-phy-grf
- rockchip,rk3588-pcie3-pipe-grf
- rockchip,rv1108-usbgrf
- const: syscon
- items:
......@@ -28,6 +31,7 @@ properties:
- rockchip,px30-usb2phy-grf
- rockchip,rk3036-grf
- rockchip,rk3066-grf
- rockchip,rk3128-grf
- rockchip,rk3188-grf
- rockchip,rk3228-grf
- rockchip,rk3288-grf
......@@ -45,6 +49,8 @@ properties:
- rockchip,rk3568-pmugrf
- rockchip,rv1108-grf
- rockchip,rv1108-pmugrf
- rockchip,rv1126-grf
- rockchip,rv1126-pmugrf
- const: syscon
- const: simple-mfd
......@@ -178,6 +184,7 @@ allOf:
contains:
enum:
- rockchip,px30-usb2phy-grf
- rockchip,rk3128-grf
- rockchip,rk3228-grf
- rockchip,rk3308-usb2phy-grf
- rockchip,rk3328-usb2phy-grf
......
......@@ -3125,6 +3125,8 @@ W: http://wiki.xilinx.com
T: git https://github.com/Xilinx/linux-xlnx.git
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/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: arch/arm/mach-zynq/
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
F: drivers/cpuidle/cpuidle-big_little.c
CPUIDLE DRIVER - ARM EXYNOS
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
M: Daniel Lezcano <daniel.lezcano@linaro.org>
R: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
M: Kukjin Kim <kgene@kernel.org>
L: linux-pm@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org
......@@ -12441,7 +12443,6 @@ F: drivers/power/supply/max77976_charger.c
MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-pm@vger.kernel.org
S: Supported
B: mailto:linux-samsung-soc@vger.kernel.org
......@@ -12453,7 +12454,6 @@ F: drivers/power/supply/max77693_charger.c
MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS
M: Chanwoo Choi <cw00.choi@samsung.com>
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-kernel@vger.kernel.org
S: Supported
B: mailto:linux-samsung-soc@vger.kernel.org
......@@ -16587,14 +16587,6 @@ T: git git://linuxtv.org/media_tree.git
F: drivers/media/usb/pwc/*
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
M: Sean Young <sean@mess.org>
L: linux-media@vger.kernel.org
......@@ -18055,7 +18047,6 @@ F: drivers/platform/x86/samsung-laptop.c
SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-kernel@vger.kernel.org
L: linux-samsung-soc@vger.kernel.org
S: Supported
......
......@@ -67,11 +67,7 @@
#if defined(CONFIG_ARCH_SA1100)
.macro loadsp, rb, tmp1, tmp2
mov \rb, #0x80000000 @ physical base address
#ifdef CONFIG_DEBUG_LL_SER3
add \rb, \rb, #0x00050000 @ Ser3
#else
add \rb, \rb, #0x00010000 @ Ser1
#endif
.endm
#else
.macro loadsp, rb, tmp1, tmp2
......
......@@ -85,7 +85,7 @@ static int wait_lpc_idle(void __iomem *mbase, unsigned int waitcnt)
ndelay(LPC_NSEC_PERWAIT);
} while (--waitcnt);
return -ETIME;
return -ETIMEDOUT;
}
/*
......@@ -347,7 +347,7 @@ static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev,
unsigned long sys_port;
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)
return -EFAULT;
......@@ -472,9 +472,7 @@ static int hisi_lpc_acpi_clear_enumerated(struct acpi_device *adev, void *not_us
struct hisi_lpc_acpi_cell {
const char *hid;
const char *name;
void *pdata;
size_t pdata_size;
const struct platform_device_info *pdevinfo;
};
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)
/* ipmi */
{
.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 */
{
.hid = "HISI1031",
.name = "serial8250",
.pdata = (struct plat_serial8250_port []) {
.pdevinfo = (struct platform_device_info []) {
{
.iobase = res->start,
.uartclk = 1843200,
.iotype = UPIO_PORT,
.flags = UPF_BOOT_AUTOCONF,
.parent = hostdev,
.fwnode = acpi_fwnode_handle(child),
.name = "serial8250",
.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)) {
found = true;
break;
......@@ -540,31 +555,12 @@ static int hisi_lpc_acpi_add_child(struct acpi_device *child, void *data)
return 0;
}
pdev = platform_device_alloc(cell->name, PLATFORM_DEVID_AUTO);
if (!pdev)
return -ENOMEM;
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;
pdev = platform_device_register_full(cell->pdevinfo);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
acpi_device_set_enumerated(child);
return 0;
fail:
platform_device_put(pdev);
return ret;
}
/*
......@@ -589,11 +585,6 @@ static int hisi_lpc_acpi_probe(struct device *hostdev)
return ret;
}
static const struct acpi_device_id hisi_lpc_acpi_match[] = {
{"HISI0191"},
{}
};
#else
static int hisi_lpc_acpi_probe(struct device *dev)
{
......@@ -615,11 +606,9 @@ static void hisi_lpc_acpi_remove(struct device *hostdev)
static int hisi_lpc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct acpi_device *acpi_device = ACPI_COMPANION(dev);
struct logic_pio_hwaddr *range;
struct hisi_lpc_dev *lpcdev;
resource_size_t io_end;
struct resource *res;
int ret;
lpcdev = devm_kzalloc(dev, sizeof(*lpcdev), GFP_KERNEL);
......@@ -628,8 +617,7 @@ static int hisi_lpc_probe(struct platform_device *pdev)
spin_lock_init(&lpcdev->cycle_lock);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
lpcdev->membase = devm_ioremap_resource(dev, res);
lpcdev->membase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(lpcdev->membase))
return PTR_ERR(lpcdev->membase);
......@@ -637,7 +625,7 @@ static int hisi_lpc_probe(struct platform_device *pdev)
if (!range)
return -ENOMEM;
range->fwnode = dev->fwnode;
range->fwnode = dev_fwnode(dev);
range->flags = LOGIC_PIO_INDIRECT;
range->size = PIO_INDIRECT_SIZE;
range->hostdata = lpcdev;
......@@ -651,7 +639,7 @@ static int hisi_lpc_probe(struct platform_device *pdev)
}
/* register the LPC host PIO resources */
if (acpi_device)
if (is_acpi_device_node(range->fwnode))
ret = hisi_lpc_acpi_probe(dev);
else
ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
......@@ -672,11 +660,10 @@ static int hisi_lpc_probe(struct platform_device *pdev)
static int hisi_lpc_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct acpi_device *acpi_device = ACPI_COMPANION(dev);
struct hisi_lpc_dev *lpcdev = dev_get_drvdata(dev);
struct logic_pio_hwaddr *range = lpcdev->io_host;
if (acpi_device)
if (is_acpi_device_node(range->fwnode))
hisi_lpc_acpi_remove(dev);
else
of_platform_depopulate(dev);
......@@ -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 = {
.driver = {
.name = DRV_NAME,
.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,
.remove = hisi_lpc_remove,
......
......@@ -124,10 +124,8 @@ static bool psci_pd_try_set_osi_mode(void)
return false;
ret = psci_set_osi_mode(true);
if (ret) {
pr_warn("failed to enable OSI mode: %d\n", ret);
if (ret)
return false;
}
return true;
}
......
......@@ -167,7 +167,8 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev)
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;
struct device *dev;
......@@ -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);
ffa_dev->vm_id = vm_id;
ffa_dev->ops = ops;
uuid_copy(&ffa_dev->uuid, uuid);
ret = device_register(&ffa_dev->dev);
......
......@@ -163,6 +163,7 @@ struct ffa_drv_info {
struct mutex tx_lock; /* lock to protect Tx buffer */
void *rx_buffer;
void *tx_buffer;
bool mem_ops_native;
};
static struct ffa_drv_info *drv_info;
......@@ -263,18 +264,24 @@ static int ffa_rxtx_unmap(u16 vm_id)
return 0;
}
#define PARTITION_INFO_GET_RETURN_COUNT_ONLY BIT(0)
/* buffer must be sizeof(struct ffa_partition_info) * num_partitions */
static int
__ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
struct ffa_partition_info *buffer, int num_partitions)
{
int count;
int idx, count, flags = 0, sz, buf_sz;
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);
invoke_ffa_fn((ffa_value_t){
.a0 = FFA_PARTITION_INFO_GET,
.a1 = uuid0, .a2 = uuid1, .a3 = uuid2, .a4 = uuid3,
.a5 = flags,
}, &partition_info);
if (partition_info.a0 == FFA_ERROR) {
......@@ -284,8 +291,19 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
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)
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();
......@@ -571,6 +589,39 @@ static int ffa_memory_reclaim(u64 g_handle, u32 flags)
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)
{
return drv_info->version;
......@@ -597,11 +648,19 @@ static int ffa_partition_info_get(const char *uuid_str,
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;
}
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,
struct ffa_send_direct_data *data)
{
......@@ -609,17 +668,15 @@ static int ffa_sync_send_receive(struct ffa_device *dev,
dev->mode_32bit, data);
}
static int
ffa_memory_share(struct ffa_device *dev, struct ffa_mem_ops_args *args)
static int ffa_memory_share(struct ffa_mem_ops_args *args)
{
if (dev->mode_32bit)
return ffa_memory_ops(FFA_MEM_SHARE, args);
if (drv_info->mem_ops_native)
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
ffa_memory_lend(struct ffa_device *dev, struct ffa_mem_ops_args *args)
static int ffa_memory_lend(struct ffa_mem_ops_args *args)
{
/* Note that upon a successful MEM_LEND request the caller
* 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)
* however on systems without a hypervisor the responsibility
* falls to the calling kernel driver to prevent access.
*/
if (dev->mode_32bit)
return ffa_memory_ops(FFA_MEM_LEND, args);
if (drv_info->mem_ops_native)
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,
.partition_info_get = ffa_partition_info_get,
};
static const struct ffa_msg_ops ffa_drv_msg_ops = {
.mode_32bit_set = ffa_mode_32bit_set,
.sync_send_receive = ffa_sync_send_receive,
};
static const struct ffa_mem_ops ffa_drv_mem_ops = {
.memory_reclaim = ffa_memory_reclaim,
.memory_share = ffa_memory_share,
.memory_lend = ffa_memory_lend,
};
const struct ffa_dev_ops *ffa_dev_ops_get(struct ffa_device *dev)
{
if (ffa_device_is_valid(dev))
return &ffa_ops;
return NULL;
}
EXPORT_SYMBOL_GPL(ffa_dev_ops_get);
static const struct ffa_ops ffa_drv_ops = {
.info_ops = &ffa_drv_info_ops,
.msg_ops = &ffa_drv_msg_ops,
.mem_ops = &ffa_drv_mem_ops,
};
void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid)
{
int count, idx;
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);
if (count <= 0)
return;
......@@ -671,6 +739,7 @@ void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid)
static void ffa_setup_partitions(void)
{
int count, idx;
uuid_t uuid;
struct ffa_device *ffa_dev;
struct ffa_partition_info *pbuf, *tpbuf;
......@@ -681,19 +750,24 @@ static void ffa_setup_partitions(void)
}
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
* with help of ffa_device_match_uuid(). Once the FF-A spec
* is updated to provide correct UUID here for each partition
* as part of the discovery API, we need to pass the
* discovered UUID here instead.
* with help of ffa_device_match_uuid(). FF-A v1.1 and above
* provides UUID here for each partition as part of the
* discovery API and the same is passed.
*/
ffa_dev = ffa_device_register(&uuid_null, tpbuf->id);
ffa_dev = ffa_device_register(&uuid, tpbuf->id, &ffa_drv_ops);
if (!ffa_dev) {
pr_err("%s: failed to register partition ID 0x%x\n",
__func__, tpbuf->id);
continue;
}
if (drv_info->version > FFA_VERSION_1_0 &&
!(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC))
_ffa_mode_32bit_set(ffa_dev);
}
kfree(pbuf);
}
......@@ -751,6 +825,8 @@ static int __init ffa_init(void)
ffa_setup_partitions();
ffa_set_up_mem_ops_native_flag();
return 0;
free_pages:
if (drv_info->tx_buffer)
......
......@@ -9,6 +9,7 @@
#include <linux/acpi.h>
#include <linux/arm-smccc.h>
#include <linux/cpuidle.h>
#include <linux/debugfs.h>
#include <linux/errno.h>
#include <linux/linkage.h>
#include <linux/of.h>
......@@ -163,6 +164,8 @@ int psci_set_osi_mode(bool enable)
PSCI_1_0_SUSPEND_MODE_PC;
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);
}
......@@ -324,12 +327,125 @@ static void psci_sys_poweroff(void)
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,
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
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,
#define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03
#define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02
extern void __qcom_scm_init(void);
/* common error codes */
#define QCOM_SCM_V2_EBUSY -12
#define QCOM_SCM_ENOMEM -5
......
......@@ -377,18 +377,11 @@ static ssize_t bpmp_debug_store(struct file *file, const char __user *buf,
if (!filename)
return -ENOENT;
databuf = kmalloc(count, GFP_KERNEL);
if (!databuf)
return -ENOMEM;
if (copy_from_user(databuf, buf, count)) {
err = -EFAULT;
goto free_ret;
}
databuf = memdup_user(buf, count);
if (IS_ERR(databuf))
return PTR_ERR(databuf);
err = mrq_debug_write(bpmp, filename, databuf, count);
free_ret:
kfree(databuf);
return err ?: count;
......
......@@ -488,8 +488,8 @@ config I2C_BCM_KONA
config I2C_BRCMSTB
tristate "BRCM Settop/DSL I2C controller"
depends on ARCH_BCM2835 || ARCH_BCM4908 || ARCH_BCMBCA || \
ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST
depends on ARCH_BCM2835 || ARCH_BCMBCA || ARCH_BRCMSTB || \
BMIPS_GENERIC || COMPILE_TEST
default y
help
If you say yes to this option, support will be included for the
......
......@@ -66,6 +66,15 @@ config BRCMSTB_DPFE
for the DRAM's temperature. Slower refresh rate means cooler 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
bool "Baikal-T1 CM2 L2-RAM Cache Control Block"
depends on MIPS_BAIKAL_T1 || COMPILE_TEST
......
......@@ -11,6 +11,7 @@ obj-$(CONFIG_ARM_PL172_MPMC) += pl172.o
obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o
obj-$(CONFIG_ATMEL_EBI) += atmel-ebi.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_TI_AEMIF) += ti-aemif.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 @@
#define EMIF_STAT_CLEAR_BUSY_SFT 16
#define EMIF_CTRL 0x10
#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_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 device *dev;
void __iomem *base;
......@@ -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, 2);
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, 1);
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, 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(1);
emif_clear_attr(2);
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[] = {
&emif_attr_inf0_init_done.attr.attr,
......@@ -134,6 +161,22 @@ static struct attribute *dfl_emif_attrs[] = {
&emif_attr_inf3_cal_fail.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,
};
......@@ -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 emif_attr *eattr = container_of(attr, struct emif_attr,
attr.attr);
struct dfl_device *ddev = to_dfl_dev(de->dev);
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
* CLEAN_EN field (which is a bitmap) could tell how many interfaces
* are available.
* CAPABILITY_CHN_MSK field (which is a bitmap) indicates which
* 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;
}
......
......@@ -3,6 +3,7 @@
* Copyright (c) 2015-2016 MediaTek Inc.
* Author: Yong Wu <yong.wu@mediatek.com>
*/
#include <linux/arm-smccc.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/device.h>
......@@ -14,6 +15,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/soc/mediatek/mtk_sip_svc.h>
#include <soc/mediatek/smi.h>
#include <dt-bindings/memory/mt2701-larb-port.h>
#include <dt-bindings/memory/mtk-memory-port.h>
......@@ -89,6 +91,7 @@
#define MTK_SMI_FLAG_THRT_UPDATE BIT(0)
#define MTK_SMI_FLAG_SW_FLAG BIT(1)
#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)))
struct mtk_smi_reg_pair {
......@@ -127,7 +130,7 @@ struct mtk_smi_common_plat {
struct mtk_smi_larb_gen {
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 flags_general;
const u8 (*ostd)[SMI_LARB_PORT_NR_MAX];
......@@ -185,7 +188,7 @@ static const struct component_ops mtk_smi_larb_component_ops = {
.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);
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)
common->smi_ao_base
+ 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);
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);
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);
u32 reg, flags_general = larb->larb_gen->flags_general;
const u8 *larbostd = larb->larb_gen->ostd ? larb->larb_gen->ostd[larb->larbid] : NULL;
struct arm_smccc_res res;
int i;
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)) {
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)
for (i = 0; i < SMI_LARB_PORT_NR_MAX && larbostd && !!larbostd[i]; 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) {
reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i));
reg |= F_MMU_EN;
reg |= BANK_SEL(larb->bank[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] = {
[0] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb0 */
[1] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb1 */
......@@ -347,6 +418,13 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = {
.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 = {
.config_port = mtk_smi_larb_config_port_gen2_general,
};
......@@ -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,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183},
{.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,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195},
{}
......@@ -511,9 +590,7 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
mtk_smi_larb_sleep_ctrl_disable(larb);
/* Configure the basic setting for this larb */
larb_gen->config_port(dev);
return 0;
return larb_gen->config_port(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 = {
.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 = {
.type = MTK_SMI_GEN2,
.has_gals = true,
......@@ -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,mt8183-smi-common", .data = &mtk_smi_common_mt8183},
{.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,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo},
{.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,
for_each_child_of_node(np_ddr, np_tim) {
if (of_device_is_compatible(np_tim, tim_compat)) {
if (of_do_get_timings(np_tim, &timings[i])) {
of_node_put(np_tim);
devm_kfree(dev, timings);
goto default_timings;
}
......@@ -284,6 +285,7 @@ const struct lpddr3_timings
if (of_device_is_compatible(np_tim, tim_compat)) {
if (of_lpddr3_do_get_timings(np_tim, &timings[i])) {
devm_kfree(dev, timings);
of_node_put(np_tim);
goto default_timings;
}
i++;
......
......@@ -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_node_put(child);
return 0;
......
......@@ -69,8 +69,8 @@ config MTD_OF_PARTS
config MTD_OF_PARTS_BCM4908
bool "BCM4908 partitioning support"
depends on MTD_OF_PARTS && (ARCH_BCM4908 || COMPILE_TEST)
default ARCH_BCM4908
depends on MTD_OF_PARTS && (ARCH_BCMBCA || COMPILE_TEST)
default ARCH_BCMBCA
help
This provides partitions parser for BCM4908 family devices
that can have multiple "firmware" partitions. It takes care of
......@@ -78,7 +78,7 @@ config MTD_OF_PARTS_BCM4908
config MTD_OF_PARTS_LINKSYS_NS
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
help
This provides partitions parser for Linksys devices based on Broadcom
......
......@@ -53,8 +53,8 @@ config B44_PCI
config BCM4908_ENET
tristate "Broadcom BCM4908 internal mac support"
depends on ARCH_BCM4908 || COMPILE_TEST
default y if ARCH_BCM4908
depends on ARCH_BCMBCA || COMPILE_TEST
default y if ARCH_BCMBCA
help
This driver supports Ethernet controller integrated into Broadcom
BCM4908 family SoCs.
......
......@@ -274,7 +274,7 @@ config VMD
config PCIE_BRCMSTB
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
depends on OF
depends on PCI_MSI_IRQ_DOMAIN
......
......@@ -93,11 +93,11 @@ config PHY_BRCM_SATA
config PHY_BRCM_USB
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
select GENERIC_PHY
select SOC_BRCMSTB if ARCH_BRCMSTB
default ARCH_BCM4908 || ARCH_BRCMSTB
default ARCH_BCMBCA || ARCH_BRCMSTB
help
Enable this to support the Broadcom STB USB PHY.
This driver is required by the USB XHCI, EHCI and OHCI
......
......@@ -31,13 +31,13 @@ config PINCTRL_BCM2835
config PINCTRL_BCM4908
tristate "Broadcom BCM4908 pinmux driver"
depends on OF && (ARCH_BCM4908 || COMPILE_TEST)
depends on OF && (ARCH_BCMBCA || COMPILE_TEST)
select PINMUX
select PINCONF
select GENERIC_PINCONF
select GENERIC_PINCTRL_GROUPS
select GENERIC_PINMUX_FUNCTIONS
default ARCH_BCM4908
default ARCH_BCMBCA
help
Driver for BCM4908 family SoCs with integrated pin controller.
......
......@@ -201,7 +201,7 @@ config RESET_SCMI
config RESET_SIMPLE
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
help
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)
{
const struct meson_ee_pwrc_domain_data *match;
struct regmap *regmap_ao, *regmap_hhi;
struct device_node *parent_np;
struct meson_ee_pwrc *pwrc;
int i, ret;
......@@ -495,7 +496,9 @@ static int meson_ee_pwrc_probe(struct platform_device *pdev)
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)) {
dev_err(&pdev->dev, "failed to get HHI regmap\n");
return PTR_ERR(regmap_hhi);
......
......@@ -273,6 +273,7 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev)
const struct meson_gx_pwrc_vpu *vpu_pd_match;
struct regmap *regmap_ao, *regmap_hhi;
struct meson_gx_pwrc_vpu *vpu_pd;
struct device_node *parent_np;
struct reset_control *rstc;
struct clk *vpu_clk;
struct clk *vapb_clk;
......@@ -291,7 +292,9 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev)
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)) {
dev_err(&pdev->dev, "failed to get regmap\n");
return PTR_ERR(regmap_ao);
......
......@@ -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);
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)
{
u64 msg;
......
......@@ -13,8 +13,8 @@ endif # SOC_BCM63XX
config BCM_PMB
bool "Broadcom PMB (Power Management Bus) driver"
depends on ARCH_BCM4908 || (COMPILE_TEST && OF)
default ARCH_BCM4908
depends on ARCH_BCMBCA || (COMPILE_TEST && OF)
default ARCH_BCMBCA
select PM_GENERIC_DOMAINS if PM
help
This enables support for the Broadcom's PMB (Power Management Bus) that
......
......@@ -25,7 +25,6 @@
#include <linux/kernel.h>
#include <linux/memblock.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/panic_notifier.h>
......@@ -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);
}
/*
* 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,
unsigned long action, void *data)
{
......
......@@ -20,4 +20,12 @@ config SOC_IMX8M
support, it will provide the SoC info like SoC family,
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
......@@ -7,3 +7,5 @@ obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
obj-$(CONFIG_SOC_IMX8M) += imx8m-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 @@
*/
#include <linux/device.h>
#include <linux/interconnect.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
......@@ -37,6 +38,8 @@ struct imx8m_blk_ctrl_domain_data {
const char *name;
const char * const *clk_names;
int num_clks;
const char * const *path_names;
int num_paths;
const char *gpc_name;
u32 rst_mask;
u32 clk_mask;
......@@ -52,13 +55,16 @@ struct imx8m_blk_ctrl_domain_data {
};
#define DOMAIN_MAX_CLKS 4
#define DOMAIN_MAX_PATHS 4
struct imx8m_blk_ctrl_domain {
struct generic_pm_domain genpd;
const struct imx8m_blk_ctrl_domain_data *data;
struct clk_bulk_data clks[DOMAIN_MAX_CLKS];
struct icc_bulk_data paths[DOMAIN_MAX_PATHS];
struct device *power_dev;
struct imx8m_blk_ctrl *bc;
int num_paths;
};
struct imx8m_blk_ctrl_data {
......@@ -117,6 +123,10 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
if (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 */
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)
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 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;
bc->onecell_data.num_domains = bc_data->num_domains;
bc->onecell_data.xlate = imx8m_blk_ctrl_xlate;
bc->onecell_data.domains =
devm_kcalloc(dev, bc_data->num_domains,
sizeof(struct generic_pm_domain *), GFP_KERNEL);
......@@ -224,10 +220,29 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
int j;
domain->data = data;
domain->num_paths = data->num_paths;
for (j = 0; j < data->num_clks; 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);
if (ret) {
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 = {
.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,
unsigned long action, void *data)
{
......@@ -649,6 +704,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
.gpc_name = "lcdif1",
.rst_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] = {
.name = "mediablk-isi",
......@@ -657,6 +714,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
.gpc_name = "isi",
.rst_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] = {
.name = "mediablk-mipi-csi2-2",
......@@ -674,6 +733,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
.gpc_name = "lcdif2",
.rst_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] = {
.name = "mediablk-isp",
......@@ -682,6 +743,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
.gpc_name = "isp",
.rst_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] = {
.name = "mediablk-dwe",
......@@ -690,6 +753,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[
.gpc_name = "dwe",
.rst_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] = {
.name = "mediablk-mipi-dsi-2",
......@@ -787,6 +852,9 @@ static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
}, {
.compatible = "fsl,imx8mq-vpu-blk-ctrl",
.data = &imx8mq_vpu_blk_ctl_dev_data
}, {
.compatible = "fsl,imx8mp-vpu-blk-ctrl",
.data = &imx8mp_vpu_blk_ctl_dev_data
}, {
/* Sentinel */
}
......
......@@ -6,6 +6,7 @@
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/interconnect.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
......@@ -18,6 +19,8 @@
#define GPR_REG0 0x0
#define PCIE_CLOCK_MODULE_EN BIT(0)
#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;
......@@ -36,17 +39,22 @@ struct imx8mp_blk_ctrl_domain_data {
const char *name;
const char * const *clk_names;
int num_clks;
const char * const *path_names;
int num_paths;
const char *gpc_name;
};
#define DOMAIN_MAX_CLKS 2
#define DOMAIN_MAX_PATHS 3
struct imx8mp_blk_ctrl_domain {
struct generic_pm_domain genpd;
const struct imx8mp_blk_ctrl_domain_data *data;
struct clk_bulk_data clks[DOMAIN_MAX_CLKS];
struct icc_bulk_data paths[DOMAIN_MAX_PATHS];
struct device *power_dev;
struct imx8mp_blk_ctrl *bc;
int num_paths;
int id;
};
......@@ -75,6 +83,10 @@ static void imx8mp_hsio_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc,
case IMX8MP_HSIOBLK_PD_PCIE:
regmap_set_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN);
break;
case IMX8MP_HSIOBLK_PD_PCIE_PHY:
regmap_set_bits(bc->regmap, GPR_REG0,
PCIE_PHY_APB_RST | PCIE_PHY_INIT_RST);
break;
default:
break;
}
......@@ -90,6 +102,10 @@ static void imx8mp_hsio_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc,
case IMX8MP_HSIOBLK_PD_PCIE:
regmap_clear_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN);
break;
case IMX8MP_HSIOBLK_PD_PCIE_PHY:
regmap_clear_bits(bc->regmap, GPR_REG0,
PCIE_PHY_APB_RST | PCIE_PHY_INIT_RST);
break;
default:
break;
}
......@@ -144,6 +160,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = {
.clk_names = (const char *[]){ "usb" },
.num_clks = 1,
.gpc_name = "usb",
.path_names = (const char *[]){"usb1", "usb2"},
.num_paths = 2,
},
[IMX8MP_HSIOBLK_PD_USB_PHY1] = {
.name = "hsioblk-usb-phy1",
......@@ -158,6 +176,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = {
.clk_names = (const char *[]){ "pcie" },
.num_clks = 1,
.gpc_name = "pcie",
.path_names = (const char *[]){"noc-pcie", "pcie"},
.num_paths = 2,
},
[IMX8MP_HSIOBLK_PD_PCIE_PHY] = {
.name = "hsioblk-pcie-phy",
......@@ -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_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3));
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:
break;
}
......@@ -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_CLK_CTL1, BIT(22) | BIT(24));
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:
break;
}
......@@ -322,6 +356,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
.clk_names = (const char *[]){ "axi", "apb" },
.num_clks = 2,
.gpc_name = "lcdif",
.path_names = (const char *[]){"lcdif-hdmi"},
.num_paths = 1,
},
[IMX8MP_HDMIBLK_PD_PAI] = {
.name = "hdmiblk-pai",
......@@ -353,6 +389,22 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = {
.num_clks = 2,
.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 = {
......@@ -395,6 +447,10 @@ static int imx8mp_blk_ctrl_power_on(struct generic_pm_domain *genpd)
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);
return 0;
......@@ -434,19 +490,6 @@ static int imx8mp_blk_ctrl_power_off(struct generic_pm_domain *genpd)
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 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;
bc->onecell_data.num_domains = num_domains;
bc->onecell_data.xlate = imx8m_blk_ctrl_xlate;
bc->onecell_data.domains =
devm_kcalloc(dev, num_domains,
sizeof(struct generic_pm_domain *), GFP_KERNEL);
......@@ -510,10 +552,29 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev)
int j;
domain->data = data;
domain->num_paths = data->num_paths;
for (j = 0; j < data->num_clks; 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);
if (ret) {
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
config MTK_PMIC_WRAP
tristate "MediaTek PMIC Wrapper Support"
depends on RESET_CONTROLLER
depends on OF
select REGMAP
help
Say yes here to add support for MediaTek PMIC Wrapper found
......@@ -46,6 +47,7 @@ config MTK_PMIC_WRAP
config MTK_SCPSYS
bool "MediaTek SCPSYS Support"
default ARCH_MEDIATEK
depends on OF
select REGMAP
select MTK_INFRACFG
select PM_GENERIC_DOMAINS if PM
......
......@@ -3,6 +3,12 @@
#ifndef __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_OVL0_CON_MASK 0x3
#define MT8186_MMSYS_OVL0_2L_CON_MASK 0xC
......
......@@ -227,6 +227,26 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
}
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,
bool assert)
{
......
......@@ -91,6 +91,15 @@
#define MT8183_MUTEX_MOD_MDP_AAL0 23
#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_OVL1 12
#define MT8173_MUTEX_MOD_DISP_RDMA0 13
......@@ -324,6 +333,17 @@ static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[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] = {
[DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
[DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
......@@ -380,6 +400,13 @@ static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
[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] = {
[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
......@@ -434,6 +461,13 @@ static const struct mtk_mutex_data mt2712_mutex_driver_data = {
.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 = {
.mutex_mod = mt8167_mutex_mod,
.mutex_sof = mt8167_mutex_sof,
......@@ -458,6 +492,12 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
.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 = {
.mutex_mod = mt8186_mutex_mod,
.mutex_sof = mt8186_mutex_sof,
......@@ -802,6 +842,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
.data = &mt2701_mutex_driver_data},
{ .compatible = "mediatek,mt2712-disp-mutex",
.data = &mt2712_mutex_driver_data},
{ .compatible = "mediatek,mt6795-disp-mutex",
.data = &mt6795_mutex_driver_data},
{ .compatible = "mediatek,mt8167-disp-mutex",
.data = &mt8167_mutex_driver_data},
{ .compatible = "mediatek,mt8173-disp-mutex",
......@@ -810,6 +852,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
.data = &mt8183_mutex_driver_data},
{ .compatible = "mediatek,mt8186-disp-mutex",
.data = &mt8186_mutex_driver_data},
{ .compatible = "mediatek,mt8186-mdp3-mutex",
.data = &mt8186_mdp_mutex_driver_data},
{ .compatible = "mediatek,mt8192-disp-mutex",
.data = &mt8192_mutex_driver_data},
{ .compatible = "mediatek,mt8195-disp-mutex",
......
......@@ -393,7 +393,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
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;
}
......@@ -405,8 +405,8 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
dev_err_probe(scpsys->dev, ret,
"%pOF: failed to get clk at index %d: %d\n", node,
i + clk_ind, ret);
"%pOF: failed to get clk at index %d\n", node,
i + clk_ind);
goto err_put_subsys_clocks;
}
......
......@@ -2316,7 +2316,7 @@ static int pwrap_probe(struct platform_device *pdev)
static struct platform_driver pwrap_drv = {
.driver = {
.name = "mt-pmic-pwrap",
.of_match_table = of_match_ptr(of_pwrap_match_tbl),
.of_match_table = of_pwrap_match_tbl,
},
.probe = pwrap_probe,
};
......
......@@ -1141,7 +1141,7 @@ static struct platform_driver scpsys_drv = {
.name = "mtk-scpsys",
.suppress_bind_attrs = true,
.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);
This diff is collapsed.
......@@ -129,7 +129,7 @@ config QCOM_RPMHPD
config QCOM_RPMPD
tristate "Qualcomm RPM Power domain driver"
depends on PM
depends on PM && OF
depends on QCOM_SMD_RPM
select PM_GENERIC_DOMAINS
select PM_GENERIC_DOMAINS_OF
......
This diff is collapsed.
......@@ -104,6 +104,7 @@ struct qcom_llcc_config {
int size;
bool need_llcc_cfg;
const u32 *reg_offset;
const struct llcc_edac_reg_offset *edac_reg_offset;
};
enum llcc_reg_offset {
......@@ -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 },
};
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_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_STATUS0] = 0x0003400c,
};
......@@ -310,70 +367,80 @@ static const struct qcom_llcc_config sc7180_cfg = {
.sct_data = sc7180_data,
.size = ARRAY_SIZE(sc7180_data),
.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 = {
.sct_data = sc7280_data,
.size = ARRAY_SIZE(sc7280_data),
.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 = {
.sct_data = sc8180x_data,
.size = ARRAY_SIZE(sc8180x_data),
.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 = {
.sct_data = sc8280xp_data,
.size = ARRAY_SIZE(sc8280xp_data),
.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 = {
.sct_data = sdm845_data,
.size = ARRAY_SIZE(sdm845_data),
.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 = {
.sct_data = sm6350_data,
.size = ARRAY_SIZE(sm6350_data),
.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 = {
.sct_data = sm8150_data,
.size = ARRAY_SIZE(sm8150_data),
.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 = {
.sct_data = sm8250_data,
.size = ARRAY_SIZE(sm8250_data),
.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 = {
.sct_data = sm8350_data,
.size = ARRAY_SIZE(sm8350_data),
.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 = {
.sct_data = sm8450_data,
.size = ARRAY_SIZE(sm8450_data),
.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;
......@@ -774,6 +841,7 @@ static int qcom_llcc_probe(struct platform_device *pdev)
drv_data->cfg = llcc_cfg;
drv_data->cfg_size = sz;
drv_data->edac_reg_offset = cfg->edac_reg_offset;
mutex_init(&drv_data->lock);
platform_set_drvdata(pdev, drv_data);
......
......@@ -246,6 +246,14 @@ static const struct stats_config rpm_data_dba0 = {
.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 = {
.stats_offset = 0x48,
.num_records = 3,
......@@ -261,6 +269,7 @@ static const struct of_device_id qcom_stats_table[] = {
{ .compatible = "qcom,msm8974-rpm-stats", .data = &rpm_data_dba0 },
{ .compatible = "qcom,rpm-stats", .data = &rpm_data },
{ .compatible = "qcom,rpmh-stats", .data = &rpmh_data },
{ .compatible = "qcom,sdm845-rpmh-stats", .data = &rpmh_data_sdm845 },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_stats_table);
......
This diff is collapsed.
This diff is collapsed.
......@@ -29,6 +29,7 @@
#define RPMPD_RWLM 0x6d6c7772
#define RPMPD_RWSC 0x63737772
#define RPMPD_RWSM 0x6d737772
#define RPMPD_RWGX 0x78677772
/* Operation Keys */
#define KEY_CORNER 0x6e726f63 /* corn */
......@@ -433,6 +434,26 @@ static const struct rpmpd_desc sm6125_desc = {
.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[] = {
[QCM2290_VDDCX] = &sm6115_vddcx,
[QCM2290_VDDCX_AO] = &sm6115_vddcx_ao,
......@@ -466,6 +487,7 @@ static const struct of_device_id rpmpd_match_table[] = {
{ .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc },
{ .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc },
{ .compatible = "qcom,sm6125-rpmpd", .data = &sm6125_desc },
{ .compatible = "qcom,sm6375-rpmpd", .data = &sm6375_desc },
{ }
};
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