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 ...
Unified · Split
| @@ -0,0 +1,15 @@ | |||
| 1 | What: /sys/bus/platform/devices/*/srpd | ||
| 2 | Date: July 2022 | ||
| 3 | KernelVersion: 5.21 | ||
| 4 | Contact: Florian Fainelli <f.fainelli@gmail.com> | ||
| 5 | Description: | ||
| 6 | Self Refresh Power Down (SRPD) inactivity timeout counted in | ||
| 7 | internal DDR controller clock cycles. Possible values range | ||
| 8 | from 0 (disable inactivity timeout) to 65535 (0xffff). | ||
| 9 | |||
| 10 | What: /sys/bus/platform/devices/*/frequency | ||
| 11 | Date: July 2022 | ||
| 12 | KernelVersion: 5.21 | ||
| 13 | Contact: Florian Fainelli <f.fainelli@gmail.com> | ||
| 14 | Description: | ||
| 15 | DDR PHY frequency in Hz. | ||
| @@ -187,15 +187,8 @@ Required properties: · 186 unmodified lines | |||
| 187 | Sequencer DRAM parameters and control registers. Used for Self-Refresh | 187 | Sequencer DRAM parameters and control registers. Used for Self-Refresh |
| 188 | Power-Down (SRPD), among other things. | 188 | Power-Down (SRPD), among other things. |
| 189 | 189 | ||
| 190 | Required properties: | 190 | See Documentation/devicetree/bindings/memory-controllers/brcm,brcmstb-memc-ddr.yaml for a |
| 191 | - compatible : should contain one of these | 191 | full list of supported compatible strings and properties. |
| 192 | "brcm,brcmstb-memc-ddr-rev-b.2.1" | ||
| 193 | "brcm,brcmstb-memc-ddr-rev-b.2.2" | ||
| 194 | "brcm,brcmstb-memc-ddr-rev-b.2.3" | ||
| 195 | "brcm,brcmstb-memc-ddr-rev-b.3.0" | ||
| 196 | "brcm,brcmstb-memc-ddr-rev-b.3.1" | ||
| 197 | "brcm,brcmstb-memc-ddr" | ||
| 198 | - reg : the MEMC DDR register range | ||
| 199 | 192 | ||
| 200 | Example: | 193 | Example: |
| 201 | 194 | ||
| @@ -554,8 +554,7 @@ properties: · 553 unmodified lines | |||
| 554 | - engicam,imx6ul-isiot # Engicam Is.IoT MX6UL eMMC/NAND Starter kit | 554 | - engicam,imx6ul-isiot # Engicam Is.IoT MX6UL eMMC/NAND Starter kit |
| 555 | - fsl,imx6ul-14x14-evk # i.MX6 UltraLite 14x14 EVK Board | 555 | - fsl,imx6ul-14x14-evk # i.MX6 UltraLite 14x14 EVK Board |
| 556 | - karo,imx6ul-tx6ul # Ka-Ro electronics TXUL-0010 Module | 556 | - karo,imx6ul-tx6ul # Ka-Ro electronics TXUL-0010 Module |
| 557 | - kontron,imx6ul-n6310-som # Kontron N6310 SOM | 557 | - kontron,sl-imx6ul # Kontron SL i.MX6UL SoM |
| 558 | - kontron,imx6ul-n6311-som # Kontron N6311 SOM | ||
| 559 | - prt,prti6g # Protonic PRTI6G Board | 558 | - prt,prti6g # Protonic PRTI6G Board |
| 560 | - technexion,imx6ul-pico-dwarf # TechNexion i.MX6UL Pico-Dwarf | 559 | - technexion,imx6ul-pico-dwarf # TechNexion i.MX6UL Pico-Dwarf |
| 561 | - technexion,imx6ul-pico-hobbit # TechNexion i.MX6UL Pico-Hobbit | 560 | - technexion,imx6ul-pico-hobbit # TechNexion i.MX6UL Pico-Hobbit |
| @@ -591,23 +590,17 @@ properties: · 29 unmodified lines | |||
| 591 | - const: phytec,imx6ul-pcl063 # PHYTEC phyCORE-i.MX 6UL | 590 | - const: phytec,imx6ul-pcl063 # PHYTEC phyCORE-i.MX 6UL |
| 592 | - const: fsl,imx6ul | 591 | - const: fsl,imx6ul |
| 593 | 592 | ||
| 594 | - description: Kontron N6310 S Board | 593 | - description: Kontron BL i.MX6UL (N631X S) Board |
| 595 | items: | 594 | items: |
| 596 | - const: kontron,imx6ul-n6310-s | 595 | - const: kontron,bl-imx6ul # Kontron BL i.MX6UL Carrier Board |
| 597 | - const: kontron,imx6ul-n6310-som | 596 | - const: kontron,sl-imx6ul # Kontron SL i.MX6UL SoM |
| 598 | - const: fsl,imx6ul | 597 | - const: fsl,imx6ul |
| 599 | 598 | ||
| 600 | - description: Kontron N6311 S Board | 599 | - description: Kontron BL i.MX6UL 43 (N631X S 43) Board |
| 601 | items: | 600 | items: |
| 602 | - const: kontron,imx6ul-n6311-s | 601 | - const: kontron,bl-imx6ul-43 # Kontron BL i.MX6UL Carrier Board with 4.3" Display |
| 603 | - const: kontron,imx6ul-n6311-som | 602 | - const: kontron,bl-imx6ul # Kontron BL i.MX6UL Carrier Board |
| 604 | - const: fsl,imx6ul | 603 | - const: kontron,sl-imx6ul # Kontron SL i.MX6UL SoM |
| 605 | |||
| 606 | - description: Kontron N6310 S 43 Board | ||
| 607 | items: | ||
| 608 | - const: kontron,imx6ul-n6310-s-43 | ||
| 609 | - const: kontron,imx6ul-n6310-s | ||
| 610 | - const: kontron,imx6ul-n6310-som | ||
| 611 | - const: fsl,imx6ul | 604 | - const: fsl,imx6ul |
| 612 | 605 | ||
| 613 | - description: TQ-Systems TQMa6UL1 SoM on MBa6ULx board | 606 | - description: TQ-Systems TQMa6UL1 SoM on MBa6ULx board |
| @@ -637,7 +630,7 @@ properties: · 23 unmodified lines | |||
| 637 | - enum: | 630 | - enum: |
| 638 | - fsl,imx6ull-14x14-evk # i.MX6 UltraLiteLite 14x14 EVK Board | 631 | - fsl,imx6ull-14x14-evk # i.MX6 UltraLiteLite 14x14 EVK Board |
| 639 | - joz,jozacp # JOZ Access Point | 632 | - joz,jozacp # JOZ Access Point |
| 640 | - kontron,imx6ull-n6411-som # Kontron N6411 SOM | 633 | - kontron,sl-imx6ull # Kontron SL i.MX6ULL SoM |
| 641 | - myir,imx6ull-mys-6ulx-eval # MYiR Tech iMX6ULL Evaluation Board | 634 | - myir,imx6ull-mys-6ulx-eval # MYiR Tech iMX6ULL Evaluation Board |
| 642 | - toradex,colibri-imx6ull # Colibri iMX6ULL Modules | 635 | - toradex,colibri-imx6ull # Colibri iMX6ULL Modules |
| 643 | - toradex,colibri-imx6ull-emmc # Colibri iMX6ULL 1GB (eMMC) Module | 636 | - toradex,colibri-imx6ull-emmc # Colibri iMX6ULL 1GB (eMMC) Module |
| @@ -698,10 +691,10 @@ properties: · 54 unmodified lines | |||
| 698 | - const: toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Module | 691 | - const: toradex,colibri-imx6ull-wifi # Colibri iMX6ULL Wi-Fi / BT Module |
| 699 | - const: fsl,imx6ull | 692 | - const: fsl,imx6ull |
| 700 | 693 | ||
| 701 | - description: Kontron N6411 S Board | 694 | - description: Kontron BL i.MX6ULL (N6411 S) Board |
| 702 | items: | 695 | items: |
| 703 | - const: kontron,imx6ull-n6411-s | 696 | - const: kontron,bl-imx6ull # Kontron BL i.MX6ULL Carrier Board |
| 704 | - const: kontron,imx6ull-n6411-som | 697 | - const: kontron,sl-imx6ull # Kontron SL i.MX6ULL SoM |
| 705 | - const: fsl,imx6ull | 698 | - const: fsl,imx6ull |
| 706 | 699 | ||
| 707 | - description: TQ Systems TQMa6ULLx SoM on MBa6ULx board | 700 | - description: TQ Systems TQMa6ULLx SoM on MBa6ULx board |
| @@ -825,13 +818,15 @@ properties: · 117 unmodified lines | |||
| 825 | - emtrion,emcon-mx8mm-avari # emCON-MX8MM SoM on Avari Base | 818 | - emtrion,emcon-mx8mm-avari # emCON-MX8MM SoM on Avari Base |
| 826 | - fsl,imx8mm-ddr4-evk # i.MX8MM DDR4 EVK Board | 819 | - fsl,imx8mm-ddr4-evk # i.MX8MM DDR4 EVK Board |
| 827 | - fsl,imx8mm-evk # i.MX8MM EVK Board | 820 | - fsl,imx8mm-evk # i.MX8MM EVK Board |
| 821 | - gateworks,imx8mm-gw7904 | ||
| 828 | - gw,imx8mm-gw71xx-0x # i.MX8MM Gateworks Development Kit | 822 | - gw,imx8mm-gw71xx-0x # i.MX8MM Gateworks Development Kit |
| 829 | - gw,imx8mm-gw72xx-0x # i.MX8MM Gateworks Development Kit | 823 | - gw,imx8mm-gw72xx-0x # i.MX8MM Gateworks Development Kit |
| 830 | - gw,imx8mm-gw73xx-0x # i.MX8MM Gateworks Development Kit | 824 | - gw,imx8mm-gw73xx-0x # i.MX8MM Gateworks Development Kit |
| 831 | - gw,imx8mm-gw7901 # i.MX8MM Gateworks Board | 825 | - gw,imx8mm-gw7901 # i.MX8MM Gateworks Board |
| 832 | - gw,imx8mm-gw7902 # i.MX8MM Gateworks Board | 826 | - gw,imx8mm-gw7902 # i.MX8MM Gateworks Board |
| 833 | - gw,imx8mm-gw7903 # i.MX8MM Gateworks Board | 827 | - gw,imx8mm-gw7903 # i.MX8MM Gateworks Board |
| 834 | - kontron,imx8mm-n801x-som # i.MX8MM Kontron SL (N801X) SOM | 828 | - kontron,imx8mm-sl # i.MX8MM Kontron SL (N801X) SOM |
| 829 | - kontron,imx8mm-osm-s # i.MX8MM Kontron OSM-S (N802X) SOM | ||
| 835 | - menlo,mx8menlo # i.MX8MM Menlo board with Verdin SoM | 830 | - menlo,mx8menlo # i.MX8MM Menlo board with Verdin SoM |
| 836 | - toradex,verdin-imx8mm # Verdin iMX8M Mini Modules | 831 | - toradex,verdin-imx8mm # Verdin iMX8M Mini Modules |
| 837 | - toradex,verdin-imx8mm-nonwifi # Verdin iMX8M Mini Modules without Wi-Fi / BT | 832 | - toradex,verdin-imx8mm-nonwifi # Verdin iMX8M Mini Modules without Wi-Fi / BT |
| @@ -850,8 +845,14 @@ properties: · 12 unmodified lines | |||
| 850 | 845 | ||
| 851 | - description: Kontron BL i.MX8MM (N801X S) Board | 846 | - description: Kontron BL i.MX8MM (N801X S) Board |
| 852 | items: | 847 | items: |
| 853 | - const: kontron,imx8mm-n801x-s | 848 | - const: kontron,imx8mm-bl |
| 854 | - const: kontron,imx8mm-n801x-som | 849 | - const: kontron,imx8mm-sl |
| 850 | - const: fsl,imx8mm | ||
| 851 | |||
| 852 | - description: Kontron BL i.MX8MM OSM-S (N802X S) Board | ||
| 853 | items: | ||
| 854 | - const: kontron,imx8mm-bl-osm-s | ||
| 855 | - const: kontron,imx8mm-osm-s | ||
| 855 | - const: fsl,imx8mm | 856 | - const: fsl,imx8mm |
| 856 | 857 | ||
| 857 | - description: Toradex Boards with Verdin iMX8M Mini Modules | 858 | - description: Toradex Boards with Verdin iMX8M Mini Modules |
| @@ -936,6 +937,13 @@ properties: · 78 unmodified lines | |||
| 936 | - toradex,verdin-imx8mp-wifi # Verdin iMX8M Plus Wi-Fi / BT Modules | 937 | - toradex,verdin-imx8mp-wifi # Verdin iMX8M Plus Wi-Fi / BT Modules |
| 937 | - const: fsl,imx8mp | 938 | - const: fsl,imx8mp |
| 938 | 939 | ||
| 940 | - description: Avnet (MSC Branded) Boards with SM2S i.MX8M Plus Modules | ||
| 941 | items: | ||
| 942 | - const: avnet,sm2s-imx8mp-14N0600E-ep1 # SM2S-IMX8PLUS-14N0600E on SM2-MB-EP1 Carrier Board | ||
| 943 | - const: avnet,sm2s-imx8mp-14N0600E # 14N0600E variant of SM2S-IMX8PLUS SoM | ||
| 944 | - const: avnet,sm2s-imx8mp # SM2S-IMX8PLUS SoM | ||
| 945 | - const: fsl,imx8mp | ||
| 946 | |||
| 939 | - description: Engicam i.Core MX8M Plus SoM based boards | 947 | - description: Engicam i.Core MX8M Plus SoM based boards |
| 940 | items: | 948 | items: |
| 941 | - enum: | 949 | - enum: |
| @@ -1034,6 +1042,12 @@ properties: · 92 unmodified lines | |||
| 1034 | - toradex,colibri-imx8x # Colibri iMX8X Modules | 1042 | - toradex,colibri-imx8x # Colibri iMX8X Modules |
| 1035 | - const: fsl,imx8qxp | 1043 | - const: fsl,imx8qxp |
| 1036 | 1044 | ||
| 1045 | - description: i.MX8DXL based Boards | ||
| 1046 | items: | ||
| 1047 | - enum: | ||
| 1048 | - fsl,imx8dxl-evk # i.MX8DXL EVK Board | ||
| 1049 | - const: fsl,imx8dxl | ||
| 1050 | |||
| 1037 | - description: i.MX8QXP Boards with Toradex Coilbri iMX8X Modules | 1051 | - description: i.MX8QXP Boards with Toradex Coilbri iMX8X Modules |
| 1038 | items: | 1052 | items: |
| 1039 | - enum: | 1053 | - enum: |
| @@ -21,10 +21,12 @@ select: · 20 unmodified lines | |||
| 21 | enum: | 21 | enum: |
| 22 | - rockchip,px30-pmu | 22 | - rockchip,px30-pmu |
| 23 | - rockchip,rk3066-pmu | 23 | - rockchip,rk3066-pmu |
| 24 | - rockchip,rk3128-pmu | ||
| 24 | - rockchip,rk3288-pmu | 25 | - rockchip,rk3288-pmu |
| 25 | - rockchip,rk3368-pmu | 26 | - rockchip,rk3368-pmu |
| 26 | - rockchip,rk3399-pmu | 27 | - rockchip,rk3399-pmu |
| 27 | - rockchip,rk3568-pmu | 28 | - rockchip,rk3568-pmu |
| 29 | - rockchip,rk3588-pmu | ||
| 28 | 30 | ||
| 29 | required: | 31 | required: |
| 30 | - compatible | 32 | - compatible |
| @@ -35,10 +37,12 @@ properties: · 4 unmodified lines | |||
| 35 | - enum: | 37 | - enum: |
| 36 | - rockchip,px30-pmu | 38 | - rockchip,px30-pmu |
| 37 | - rockchip,rk3066-pmu | 39 | - rockchip,rk3066-pmu |
| 40 | - rockchip,rk3128-pmu | ||
| 38 | - rockchip,rk3288-pmu | 41 | - rockchip,rk3288-pmu |
| 39 | - rockchip,rk3368-pmu | 42 | - rockchip,rk3368-pmu |
| 40 | - rockchip,rk3399-pmu | 43 | - rockchip,rk3399-pmu |
| 41 | - rockchip,rk3568-pmu | 44 | - rockchip,rk3568-pmu |
| 45 | - rockchip,rk3588-pmu | ||
| 42 | - const: syscon | 46 | - const: syscon |
| 43 | - const: simple-mfd | 47 | - const: simple-mfd |
| 44 | 48 | ||
| @@ -1,61 +0,0 @@ | |||
| 1 | QCOM Secure Channel Manager (SCM) | ||
| 2 | |||
| 3 | Qualcomm processors include an interface to communicate to the secure firmware. | ||
| 4 | This interface allows for clients to request different types of actions. These | ||
| 5 | can include CPU power up/down, HDCP requests, loading of firmware, and other | ||
| 6 | assorted actions. | ||
| 7 | |||
| 8 | Required properties: | ||
| 9 | - compatible: must contain one of the following: | ||
| 10 | * "qcom,scm-apq8064" | ||
| 11 | * "qcom,scm-apq8084" | ||
| 12 | * "qcom,scm-ipq4019" | ||
| 13 | * "qcom,scm-ipq806x" | ||
| 14 | * "qcom,scm-ipq8074" | ||
| 15 | * "qcom,scm-mdm9607" | ||
| 16 | * "qcom,scm-msm8226" | ||
| 17 | * "qcom,scm-msm8660" | ||
| 18 | * "qcom,scm-msm8916" | ||
| 19 | * "qcom,scm-msm8953" | ||
| 20 | * "qcom,scm-msm8960" | ||
| 21 | * "qcom,scm-msm8974" | ||
| 22 | * "qcom,scm-msm8976" | ||
| 23 | * "qcom,scm-msm8994" | ||
| 24 | * "qcom,scm-msm8996" | ||
| 25 | * "qcom,scm-msm8998" | ||
| 26 | * "qcom,scm-qcs404" | ||
| 27 | * "qcom,scm-sc7180" | ||
| 28 | * "qcom,scm-sc7280" | ||
| 29 | * "qcom,scm-sm6125" | ||
| 30 | * "qcom,scm-sdm845" | ||
| 31 | * "qcom,scm-sdx55" | ||
| 32 | * "qcom,scm-sdx65" | ||
| 33 | * "qcom,scm-sm6350" | ||
| 34 | * "qcom,scm-sm8150" | ||
| 35 | * "qcom,scm-sm8250" | ||
| 36 | * "qcom,scm-sm8350" | ||
| 37 | * "qcom,scm-sm8450" | ||
| 38 | and: | ||
| 39 | * "qcom,scm" | ||
| 40 | - clocks: Specifies clocks needed by the SCM interface, if any: | ||
| 41 | * core clock required for "qcom,scm-apq8064", "qcom,scm-msm8660" and | ||
| 42 | "qcom,scm-msm8960" | ||
| 43 | * core, iface and bus clocks required for "qcom,scm-apq8084", | ||
| 44 | "qcom,scm-msm8916", "qcom,scm-msm8953", "qcom,scm-msm8974" and "qcom,scm-msm8976" | ||
| 45 | - clock-names: Must contain "core" for the core clock, "iface" for the interface | ||
| 46 | clock and "bus" for the bus clock per the requirements of the compatible. | ||
| 47 | - qcom,dload-mode: phandle to the TCSR hardware block and offset of the | ||
| 48 | download mode control register (optional) | ||
| 49 | - interconnects: Specifies the bandwidth requirements of the SCM interface (optional) | ||
| 50 | |||
| 51 | Example for MSM8916: | ||
| 52 | |||
| 53 | firmware { | ||
| 54 | scm { | ||
| 55 | compatible = "qcom,msm8916", "qcom,scm"; | ||
| 56 | clocks = <&gcc GCC_CRYPTO_CLK> , | ||
| 57 | <&gcc GCC_CRYPTO_AXI_CLK>, | ||
| 58 | <&gcc GCC_CRYPTO_AHB_CLK>; | ||
| 59 | clock-names = "core", "bus", "iface"; | ||
| 60 | }; | ||
| 61 | }; | ||
| @@ -0,0 +1,148 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/firmware/qcom,scm.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: QCOM Secure Channel Manager (SCM) | ||
| 8 | |||
| 9 | description: | | ||
| 10 | Qualcomm processors include an interface to communicate to the secure firmware. | ||
| 11 | This interface allows for clients to request different types of actions. | ||
| 12 | These can include CPU power up/down, HDCP requests, loading of firmware, | ||
| 13 | and other assorted actions. | ||
| 14 | |||
| 15 | maintainers: | ||
| 16 | - Bjorn Andersson <bjorn.andersson@linaro.org> | ||
| 17 | - Robert Marko <robimarko@gmail.com> | ||
| 18 | - Guru Das Srinagesh <quic_gurus@quicinc.com> | ||
| 19 | |||
| 20 | properties: | ||
| 21 | compatible: | ||
| 22 | items: | ||
| 23 | - enum: | ||
| 24 | - qcom,scm-apq8064 | ||
| 25 | - qcom,scm-apq8084 | ||
| 26 | - qcom,scm-ipq4019 | ||
| 27 | - qcom,scm-ipq6018 | ||
| 28 | - qcom,scm-ipq806x | ||
| 29 | - qcom,scm-ipq8074 | ||
| 30 | - qcom,scm-mdm9607 | ||
| 31 | - qcom,scm-msm8226 | ||
| 32 | - qcom,scm-msm8660 | ||
| 33 | - qcom,scm-msm8916 | ||
| 34 | - qcom,scm-msm8953 | ||
| 35 | - qcom,scm-msm8960 | ||
| 36 | - qcom,scm-msm8974 | ||
| 37 | - qcom,scm-msm8976 | ||
| 38 | - qcom,scm-msm8994 | ||
| 39 | - qcom,scm-msm8996 | ||
| 40 | - qcom,scm-msm8998 | ||
| 41 | - qcom,scm-sc7180 | ||
| 42 | - qcom,scm-sc7280 | ||
| 43 | - qcom,scm-sc8280xp | ||
| 44 | - qcom,scm-sdm845 | ||
| 45 | - qcom,scm-sdx55 | ||
| 46 | - qcom,scm-sdx65 | ||
| 47 | - qcom,scm-sm6115 | ||
| 48 | - qcom,scm-sm6125 | ||
| 49 | - qcom,scm-sm6350 | ||
| 50 | - qcom,scm-sm8150 | ||
| 51 | - qcom,scm-sm8250 | ||
| 52 | - qcom,scm-sm8350 | ||
| 53 | - qcom,scm-sm8450 | ||
| 54 | - qcom,scm-qcs404 | ||
| 55 | - const: qcom,scm | ||
| 56 | |||
| 57 | clocks: | ||
| 58 | minItems: 1 | ||
| 59 | maxItems: 3 | ||
| 60 | |||
| 61 | clock-names: | ||
| 62 | minItems: 1 | ||
| 63 | maxItems: 3 | ||
| 64 | |||
| 65 | interconnects: | ||
| 66 | maxItems: 1 | ||
| 67 | |||
| 68 | interconnect-names: | ||
| 69 | maxItems: 1 | ||
| 70 | |||
| 71 | '#reset-cells': | ||
| 72 | const: 1 | ||
| 73 | |||
| 74 | qcom,dload-mode: | ||
| 75 | $ref: /schemas/types.yaml#/definitions/phandle-array | ||
| 76 | items: | ||
| 77 | - items: | ||
| 78 | - description: phandle to TCSR hardware block | ||
| 79 | - description: offset of the download mode control register | ||
| 80 | description: TCSR hardware block | ||
| 81 | |||
| 82 | allOf: | ||
| 83 | - if: | ||
| 84 | properties: | ||
| 85 | compatible: | ||
| 86 | contains: | ||
| 87 | enum: | ||
| 88 | - qcom,scm-apq8064 | ||
| 89 | - qcom,scm-msm8660 | ||
| 90 | - qcom,scm-msm8960 | ||
| 91 | then: | ||
| 92 | properties: | ||
| 93 | clock-names: | ||
| 94 | items: | ||
| 95 | - const: core | ||
| 96 | |||
| 97 | clocks: | ||
| 98 | maxItems: 1 | ||
| 99 | |||
| 100 | required: | ||
| 101 | - clocks | ||
| 102 | - clock-names | ||
| 103 | |||
| 104 | - if: | ||
| 105 | properties: | ||
| 106 | compatible: | ||
| 107 | contains: | ||
| 108 | enum: | ||
| 109 | - qcom,scm-apq8084 | ||
| 110 | - qcom,scm-mdm9607 | ||
| 111 | - qcom,scm-msm8916 | ||
| 112 | - qcom,scm-msm8953 | ||
| 113 | - qcom,scm-msm8974 | ||
| 114 | - qcom,scm-msm8976 | ||
| 115 | then: | ||
| 116 | properties: | ||
| 117 | clock-names: | ||
| 118 | items: | ||
| 119 | - const: core | ||
| 120 | - const: bus | ||
| 121 | - const: iface | ||
| 122 | |||
| 123 | clocks: | ||
| 124 | minItems: 3 | ||
| 125 | maxItems: 3 | ||
| 126 | |||
| 127 | required: | ||
| 128 | - clocks | ||
| 129 | - clock-names | ||
| 130 | |||
| 131 | required: | ||
| 132 | - compatible | ||
| 133 | |||
| 134 | additionalProperties: false | ||
| 135 | |||
| 136 | examples: | ||
| 137 | - | | ||
| 138 | #include <dt-bindings/clock/qcom,gcc-msm8916.h> | ||
| 139 | |||
| 140 | firmware { | ||
| 141 | scm { | ||
| 142 | compatible = "qcom,scm-msm8916", "qcom,scm"; | ||
| 143 | clocks = <&gcc GCC_CRYPTO_CLK>, | ||
| 144 | <&gcc GCC_CRYPTO_AXI_CLK>, | ||
| 145 | <&gcc GCC_CRYPTO_AHB_CLK>; | ||
| 146 | clock-names = "core", "bus", "iface"; | ||
| 147 | }; | ||
| 148 | }; | ||
| @@ -24,9 +24,12 @@ properties: · 23 unmodified lines | |||
| 24 | oneOf: | 24 | oneOf: |
| 25 | - items: | 25 | - items: |
| 26 | - enum: | 26 | - enum: |
| 27 | - qcom,sc7280-bwmon | ||
| 27 | - qcom,sdm845-bwmon | 28 | - qcom,sdm845-bwmon |
| 28 | - const: qcom,msm8998-bwmon | 29 | - const: qcom,msm8998-bwmon |
| 29 | - const: qcom,msm8998-bwmon # BWMON v4 | 30 | - const: qcom,msm8998-bwmon # BWMON v4 |
| 31 | - const: qcom,sc7280-llcc-bwmon # BWMON v5 | ||
| 32 | - const: qcom,sdm845-llcc-bwmon # BWMON v5 | ||
| 30 | 33 | ||
| 31 | interconnects: | 34 | interconnects: |
| 32 | maxItems: 1 | 35 | maxItems: 1 |
| @@ -1,38 +0,0 @@ | |||
| 1 | * Samsung Exynos5 G-Scaler device | ||
| 2 | |||
| 3 | G-Scaler is used for scaling and color space conversion on Exynos5 SoCs. | ||
| 4 | |||
| 5 | Required properties: | ||
| 6 | - compatible: should be one of | ||
| 7 | "samsung,exynos5250-gsc" | ||
| 8 | "samsung,exynos5420-gsc" | ||
| 9 | "samsung,exynos5433-gsc" | ||
| 10 | "samsung,exynos5-gsc" (deprecated) | ||
| 11 | - reg: should contain G-Scaler physical address location and length. | ||
| 12 | - interrupts: should contain G-Scaler interrupt number | ||
| 13 | |||
| 14 | Optional properties: | ||
| 15 | - samsung,sysreg: handle to syscon used to control the system registers to | ||
| 16 | set writeback input and destination | ||
| 17 | |||
| 18 | Example: | ||
| 19 | |||
| 20 | gsc_0: gsc@13e00000 { | ||
| 21 | compatible = "samsung,exynos5250-gsc"; | ||
| 22 | reg = <0x13e00000 0x1000>; | ||
| 23 | interrupts = <0 85 0>; | ||
| 24 | }; | ||
| 25 | |||
| 26 | Aliases: | ||
| 27 | Each G-Scaler node should have a numbered alias in the aliases node, | ||
| 28 | in the form of gscN, N = 0...3. G-Scaler driver uses these aliases | ||
| 29 | to retrieve the device IDs using "of_alias_get_id()" call. | ||
| 30 | |||
| 31 | Example: | ||
| 32 | |||
| 33 | aliases { | ||
| 34 | gsc0 =&gsc_0; | ||
| 35 | gsc1 =&gsc_1; | ||
| 36 | gsc2 =&gsc_2; | ||
| 37 | gsc3 =&gsc_3; | ||
| 38 | }; | ||
| @@ -0,0 +1,109 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/media/samsung,exynos5250-gsc.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Samsung Exynos SoC G-Scaler | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Inki Dae <inki.dae@samsung.com> | ||
| 11 | - Krzysztof Kozlowski <krzk@kernel.org> | ||
| 12 | - Seung-Woo Kim <sw0312.kim@samsung.com | ||
| 13 | |||
| 14 | description: | ||
| 15 | G-Scaler is used for scaling and color space conversion on Samsung Exynos | ||
| 16 | SoCs. | ||
| 17 | |||
| 18 | Each G-Scaler node should have a numbered alias in the aliases node, in the | ||
| 19 | form of gscN, N = 0...3. | ||
| 20 | |||
| 21 | properties: | ||
| 22 | compatible: | ||
| 23 | oneOf: | ||
| 24 | - items: | ||
| 25 | - enum: | ||
| 26 | - samsung,exynos5250-gsc | ||
| 27 | - samsung,exynos5420-gsc | ||
| 28 | - const: samsung,exynos5-gsc | ||
| 29 | - enum: | ||
| 30 | - samsung,exynos5433-gsc | ||
| 31 | - const: samsung,exynos5-gsc | ||
| 32 | deprecated: True | ||
| 33 | |||
| 34 | clocks: | ||
| 35 | minItems: 1 | ||
| 36 | maxItems: 5 | ||
| 37 | |||
| 38 | clock-names: | ||
| 39 | minItems: 1 | ||
| 40 | maxItems: 5 | ||
| 41 | |||
| 42 | interrupts: | ||
| 43 | maxItems: 1 | ||
| 44 | |||
| 45 | iommus: | ||
| 46 | maxItems: 1 | ||
| 47 | |||
| 48 | power-domains: | ||
| 49 | maxItems: 1 | ||
| 50 | |||
| 51 | reg: | ||
| 52 | maxItems: 1 | ||
| 53 | |||
| 54 | samsung,sysreg: | ||
| 55 | $ref: /schemas/types.yaml#/definitions/phandle | ||
| 56 | description: | ||
| 57 | Syscon used to control the system registers to set writeback input and destination. | ||
| 58 | |||
| 59 | required: | ||
| 60 | - compatible | ||
| 61 | - clocks | ||
| 62 | - clock-names | ||
| 63 | - interrupts | ||
| 64 | - reg | ||
| 65 | |||
| 66 | allOf: | ||
| 67 | - if: | ||
| 68 | properties: | ||
| 69 | compatible: | ||
| 70 | contains: | ||
| 71 | enum: | ||
| 72 | - samsung,exynos5-gsc | ||
| 73 | - samsung,exynos5250-gsc | ||
| 74 | - samsung,exynos5420-gsc | ||
| 75 | then: | ||
| 76 | properties: | ||
| 77 | clocks: | ||
| 78 | maxItems: 1 | ||
| 79 | clock-names: | ||
| 80 | items: | ||
| 81 | - const: gscl | ||
| 82 | else: | ||
| 83 | properties: | ||
| 84 | clocks: | ||
| 85 | minItems: 5 | ||
| 86 | clock-names: | ||
| 87 | items: | ||
| 88 | - const: pclk | ||
| 89 | - const: aclk | ||
| 90 | - const: aclk_xiu | ||
| 91 | - const: aclk_gsclbend | ||
| 92 | - const: gsd | ||
| 93 | |||
| 94 | additionalProperties: false | ||
| 95 | |||
| 96 | examples: | ||
| 97 | - | | ||
| 98 | #include <dt-bindings/clock/exynos5250.h> | ||
| 99 | #include <dt-bindings/interrupt-controller/arm-gic.h> | ||
| 100 | |||
| 101 | video-scaler@13e00000 { | ||
| 102 | compatible = "samsung,exynos5250-gsc", "samsung,exynos5-gsc"; | ||
| 103 | reg = <0x13e00000 0x1000>; | ||
| 104 | interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; | ||
| 105 | power-domains = <&pd_gsc>; | ||
| 106 | clocks = <&clock CLK_GSCL0>; | ||
| 107 | clock-names = "gscl"; | ||
| 108 | iommus = <&sysmmu_gsc0>; | ||
| 109 | }; | ||
| @@ -0,0 +1,52 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/memory-controllers/brcm,brcmstb-memc-ddr.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Memory controller (MEMC) for Broadcom STB | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Florian Fainelli <f.fainelli@gmail.com> | ||
| 11 | |||
| 12 | properties: | ||
| 13 | compatible: | ||
| 14 | items: | ||
| 15 | - enum: | ||
| 16 | - brcm,brcmstb-memc-ddr-rev-b.1.x | ||
| 17 | - brcm,brcmstb-memc-ddr-rev-b.2.0 | ||
| 18 | - brcm,brcmstb-memc-ddr-rev-b.2.1 | ||
| 19 | - brcm,brcmstb-memc-ddr-rev-b.2.2 | ||
| 20 | - brcm,brcmstb-memc-ddr-rev-b.2.3 | ||
| 21 | - brcm,brcmstb-memc-ddr-rev-b.2.5 | ||
| 22 | - brcm,brcmstb-memc-ddr-rev-b.2.6 | ||
| 23 | - brcm,brcmstb-memc-ddr-rev-b.2.7 | ||
| 24 | - brcm,brcmstb-memc-ddr-rev-b.2.8 | ||
| 25 | - brcm,brcmstb-memc-ddr-rev-b.3.0 | ||
| 26 | - brcm,brcmstb-memc-ddr-rev-b.3.1 | ||
| 27 | - brcm,brcmstb-memc-ddr-rev-c.1.0 | ||
| 28 | - brcm,brcmstb-memc-ddr-rev-c.1.1 | ||
| 29 | - brcm,brcmstb-memc-ddr-rev-c.1.2 | ||
| 30 | - brcm,brcmstb-memc-ddr-rev-c.1.3 | ||
| 31 | - brcm,brcmstb-memc-ddr-rev-c.1.4 | ||
| 32 | - const: brcm,brcmstb-memc-ddr | ||
| 33 | |||
| 34 | reg: | ||
| 35 | maxItems: 1 | ||
| 36 | |||
| 37 | clock-frequency: | ||
| 38 | description: DDR PHY frequency in Hz | ||
| 39 | |||
| 40 | required: | ||
| 41 | - compatible | ||
| 42 | - reg | ||
| 43 | |||
| 44 | additionalProperties: false | ||
| 45 | |||
| 46 | examples: | ||
| 47 | - | | ||
| 48 | memory-controller@9902000 { | ||
| 49 | compatible = "brcm,brcmstb-memc-ddr-rev-c.1.1", "brcm,brcmstb-memc-ddr"; | ||
| 50 | reg = <0x9902000 0x600>; | ||
| 51 | clock-frequency = <2133000000>; | ||
| 52 | }; | ||
| @@ -16,7 +16,7 @@ description: | · 15 unmodified lines | |||
| 16 | MediaTek SMI have two generations of HW architecture, here is the list | 16 | MediaTek SMI have two generations of HW architecture, here is the list |
| 17 | which generation the SoCs use: | 17 | which generation the SoCs use: |
| 18 | generation 1: mt2701 and mt7623. | 18 | generation 1: mt2701 and mt7623. |
| 19 | generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8192 and mt8195. | 19 | generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8188, mt8192 and mt8195. |
| 20 | 20 | ||
| 21 | There's slight differences between the two SMI, for generation 2, the | 21 | There's slight differences between the two SMI, for generation 2, the |
| 22 | register which control the iommu port is at each larb's register base. But | 22 | register which control the iommu port is at each larb's register base. But |
| @@ -37,6 +37,8 @@ properties: · 14 unmodified lines | |||
| 37 | - mediatek,mt8173-smi-common | 37 | - mediatek,mt8173-smi-common |
| 38 | - mediatek,mt8183-smi-common | 38 | - mediatek,mt8183-smi-common |
| 39 | - mediatek,mt8186-smi-common | 39 | - mediatek,mt8186-smi-common |
| 40 | - mediatek,mt8188-smi-common-vdo | ||
| 41 | - mediatek,mt8188-smi-common-vpp | ||
| 40 | - mediatek,mt8192-smi-common | 42 | - mediatek,mt8192-smi-common |
| 41 | - mediatek,mt8195-smi-common-vdo | 43 | - mediatek,mt8195-smi-common-vdo |
| 42 | - mediatek,mt8195-smi-common-vpp | 44 | - mediatek,mt8195-smi-common-vpp |
| @@ -144,7 +146,16 @@ allOf: · 101 unmodified lines | |||
| 144 | - const: gals0 | 146 | - const: gals0 |
| 145 | - const: gals1 | 147 | - const: gals1 |
| 146 | 148 | ||
| 147 | else: # for gen2 HW that don't have gals | 149 | - if: # for gen2 HW that don't have gals |
| 150 | properties: | ||
| 151 | compatible: | ||
| 152 | enum: | ||
| 153 | - mediatek,mt2712-smi-common | ||
| 154 | - mediatek,mt6795-smi-common | ||
| 155 | - mediatek,mt8167-smi-common | ||
| 156 | - mediatek,mt8173-smi-common | ||
| 157 | |||
| 158 | then: | ||
| 148 | properties: | 159 | properties: |
| 149 | clocks: | 160 | clocks: |
| 150 | minItems: 2 | 161 | minItems: 2 |
| @@ -25,6 +25,7 @@ properties: · 24 unmodified lines | |||
| 25 | - mediatek,mt8173-smi-larb | 25 | - mediatek,mt8173-smi-larb |
| 26 | - mediatek,mt8183-smi-larb | 26 | - mediatek,mt8183-smi-larb |
| 27 | - mediatek,mt8186-smi-larb | 27 | - mediatek,mt8186-smi-larb |
| 28 | - mediatek,mt8188-smi-larb | ||
| 28 | - mediatek,mt8192-smi-larb | 29 | - mediatek,mt8192-smi-larb |
| 29 | - mediatek,mt8195-smi-larb | 30 | - mediatek,mt8195-smi-larb |
| 30 | 31 | ||
| @@ -78,6 +79,7 @@ allOf: · 47 unmodified lines | |||
| 78 | enum: | 79 | enum: |
| 79 | - mediatek,mt8183-smi-larb | 80 | - mediatek,mt8183-smi-larb |
| 80 | - mediatek,mt8186-smi-larb | 81 | - mediatek,mt8186-smi-larb |
| 82 | - mediatek,mt8188-smi-larb | ||
| 81 | - mediatek,mt8195-smi-larb | 83 | - mediatek,mt8195-smi-larb |
| 82 | 84 | ||
| 83 | then: | 85 | then: |
| @@ -111,6 +113,7 @@ allOf: · 27 unmodified lines | |||
| 111 | - mediatek,mt2712-smi-larb | 113 | - mediatek,mt2712-smi-larb |
| 112 | - mediatek,mt6779-smi-larb | 114 | - mediatek,mt6779-smi-larb |
| 113 | - mediatek,mt8186-smi-larb | 115 | - mediatek,mt8186-smi-larb |
| 116 | - mediatek,mt8188-smi-larb | ||
| 114 | - mediatek,mt8192-smi-larb | 117 | - mediatek,mt8192-smi-larb |
| 115 | - mediatek,mt8195-smi-larb | 118 | - mediatek,mt8195-smi-larb |
| 116 | 119 | ||
| @@ -0,0 +1,118 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/memory-controllers/snps,dw-umctl2-ddrc.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Synopsys DesignWare Universal Multi-Protocol Memory Controller | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Krzysztof Kozlowski <krzk@kernel.org> | ||
| 11 | - Manish Narani <manish.narani@xilinx.com> | ||
| 12 | - Michal Simek <michal.simek@xilinx.com> | ||
| 13 | |||
| 14 | description: | | ||
| 15 | Synopsys DesignWare Enhanced uMCTL2 DDR Memory Controller is capable of | ||
| 16 | working with the memory devices supporting up to (LP)DDR4 protocol. It can | ||
| 17 | be equipped with SEC/DEC ECC feature if DRAM data bus width is either | ||
| 18 | 16-bits or 32-bits or 64-bits wide. | ||
| 19 | |||
| 20 | For instance the ZynqMP DDR controller is based on the DW uMCTL2 v2.40a | ||
| 21 | controller. It has an optional SEC/DEC ECC support in 64- and 32-bits | ||
| 22 | bus width configurations. | ||
| 23 | |||
| 24 | properties: | ||
| 25 | compatible: | ||
| 26 | oneOf: | ||
| 27 | - deprecated: true | ||
| 28 | description: Synopsys DW uMCTL2 DDR controller v3.80a | ||
| 29 | const: snps,ddrc-3.80a | ||
| 30 | - description: Synopsys DW uMCTL2 DDR controller | ||
| 31 | const: snps,dw-umctl2-ddrc | ||
| 32 | - description: Xilinx ZynqMP DDR controller v2.40a | ||
| 33 | const: xlnx,zynqmp-ddrc-2.40a | ||
| 34 | |||
| 35 | interrupts: | ||
| 36 | description: | ||
| 37 | DW uMCTL2 DDRC IP-core provides individual IRQ signal for each event":" | ||
| 38 | ECC Corrected Error, ECC Uncorrected Error, ECC Address Protection, | ||
| 39 | Scrubber-Done signal, DFI Parity/CRC Error. Some platforms may have the | ||
| 40 | signals merged before they reach the IRQ controller or have some of them | ||
| 41 | absent in case if the corresponding feature is unavailable/disabled. | ||
| 42 | minItems: 1 | ||
| 43 | maxItems: 5 | ||
| 44 | |||
| 45 | interrupt-names: | ||
| 46 | minItems: 1 | ||
| 47 | maxItems: 5 | ||
| 48 | oneOf: | ||
| 49 | - description: Common ECC CE/UE/Scrubber/DFI Errors IRQ | ||
| 50 | items: | ||
| 51 | - const: ecc | ||
| 52 | - description: Individual ECC CE/UE/Scrubber/DFI Errors IRQs | ||
| 53 | items: | ||
| 54 | enum: [ ecc_ce, ecc_ue, ecc_ap, ecc_sbr, dfi_e ] | ||
| 55 | |||
| 56 | reg: | ||
| 57 | maxItems: 1 | ||
| 58 | |||
| 59 | clocks: | ||
| 60 | description: | ||
| 61 | A standard set of the clock sources contains CSRs bus clock, AXI-ports | ||
| 62 | reference clock, DDRC core clock, Scrubber standalone clock | ||
| 63 | (synchronous to the DDRC clock). | ||
| 64 | minItems: 1 | ||
| 65 | maxItems: 4 | ||
| 66 | |||
| 67 | clock-names: | ||
| 68 | minItems: 1 | ||
| 69 | maxItems: 4 | ||
| 70 | items: | ||
| 71 | enum: [ pclk, aclk, core, sbr ] | ||
| 72 | |||
| 73 | resets: | ||
| 74 | description: | ||
| 75 | Each clock domain can have separate reset signal. | ||
| 76 | minItems: 1 | ||
| 77 | maxItems: 4 | ||
| 78 | |||
| 79 | reset-names: | ||
| 80 | minItems: 1 | ||
| 81 | maxItems: 4 | ||
| 82 | items: | ||
| 83 | enum: [ prst, arst, core, sbr ] | ||
| 84 | |||
| 85 | required: | ||
| 86 | - compatible | ||
| 87 | - reg | ||
| 88 | - interrupts | ||
| 89 | |||
| 90 | additionalProperties: false | ||
| 91 | |||
| 92 | examples: | ||
| 93 | - | | ||
| 94 | #include <dt-bindings/interrupt-controller/arm-gic.h> | ||
| 95 | |||
| 96 | memory-controller@fd070000 { | ||
| 97 | compatible = "xlnx,zynqmp-ddrc-2.40a"; | ||
| 98 | reg = <0xfd070000 0x30000>; | ||
| 99 | |||
| 100 | interrupt-parent = <&gic>; | ||
| 101 | interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; | ||
| 102 | interrupt-names = "ecc"; | ||
| 103 | }; | ||
| 104 | - | | ||
| 105 | #include <dt-bindings/interrupt-controller/irq.h> | ||
| 106 | |||
| 107 | memory-controller@3d400000 { | ||
| 108 | compatible = "snps,dw-umctl2-ddrc"; | ||
| 109 | reg = <0x3d400000 0x400000>; | ||
| 110 | |||
| 111 | interrupts = <147 IRQ_TYPE_LEVEL_HIGH>, <148 IRQ_TYPE_LEVEL_HIGH>, | ||
| 112 | <149 IRQ_TYPE_LEVEL_HIGH>, <150 IRQ_TYPE_LEVEL_HIGH>; | ||
| 113 | interrupt-names = "ecc_ce", "ecc_ue", "ecc_sbr", "dfi_e"; | ||
| 114 | |||
| 115 | clocks = <&pclk>, <&aclk>, <&core_clk>, <&sbr_clk>; | ||
| 116 | clock-names = "pclk", "aclk", "core", "sbr"; | ||
| 117 | }; | ||
| 118 | ... | ||
| @@ -1,76 +0,0 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/memory-controllers/synopsys,ddrc-ecc.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Synopsys IntelliDDR Multi Protocol memory controller | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Krzysztof Kozlowski <krzk@kernel.org> | ||
| 11 | - Manish Narani <manish.narani@xilinx.com> | ||
| 12 | - Michal Simek <michal.simek@xilinx.com> | ||
| 13 | |||
| 14 | description: | | ||
| 15 | The ZynqMP DDR ECC controller has an optional ECC support in 64-bit and | ||
| 16 | 32-bit bus width configurations. | ||
| 17 | |||
| 18 | The Zynq DDR ECC controller has an optional ECC support in half-bus width | ||
| 19 | (16-bit) configuration. | ||
| 20 | |||
| 21 | These both ECC controllers correct single bit ECC errors and detect double bit | ||
| 22 | ECC errors. | ||
| 23 | |||
| 24 | properties: | ||
| 25 | compatible: | ||
| 26 | enum: | ||
| 27 | - snps,ddrc-3.80a | ||
| 28 | - xlnx,zynq-ddrc-a05 | ||
| 29 | - xlnx,zynqmp-ddrc-2.40a | ||
| 30 | |||
| 31 | interrupts: | ||
| 32 | maxItems: 1 | ||
| 33 | |||
| 34 | reg: | ||
| 35 | maxItems: 1 | ||
| 36 | |||
| 37 | required: | ||
| 38 | - compatible | ||
| 39 | - reg | ||
| 40 | |||
| 41 | allOf: | ||
| 42 | - if: | ||
| 43 | properties: | ||
| 44 | compatible: | ||
| 45 | contains: | ||
| 46 | enum: | ||
| 47 | - snps,ddrc-3.80a | ||
| 48 | - xlnx,zynqmp-ddrc-2.40a | ||
| 49 | then: | ||
| 50 | required: | ||
| 51 | - interrupts | ||
| 52 | else: | ||
| 53 | properties: | ||
| 54 | interrupts: false | ||
| 55 | |||
| 56 | additionalProperties: false | ||
| 57 | |||
| 58 | examples: | ||
| 59 | - | | ||
| 60 | memory-controller@f8006000 { | ||
| 61 | compatible = "xlnx,zynq-ddrc-a05"; | ||
| 62 | reg = <0xf8006000 0x1000>; | ||
| 63 | }; | ||
| 64 | |||
| 65 | - | | ||
| 66 | axi { | ||
| 67 | #address-cells = <2>; | ||
| 68 | #size-cells = <2>; | ||
| 69 | |||
| 70 | memory-controller@fd070000 { | ||
| 71 | compatible = "xlnx,zynqmp-ddrc-2.40a"; | ||
| 72 | reg = <0x0 0xfd070000 0x0 0x30000>; | ||
| 73 | interrupt-parent = <&gic>; | ||
| 74 | interrupts = <0 112 4>; | ||
| 75 | }; | ||
| 76 | }; | ||
| @@ -0,0 +1,38 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/memory-controllers/xlnx,zynq-ddrc-a05.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Zynq A05 DDR Memory Controller | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Krzysztof Kozlowski <krzk@kernel.org> | ||
| 11 | - Manish Narani <manish.narani@xilinx.com> | ||
| 12 | - Michal Simek <michal.simek@xilinx.com> | ||
| 13 | |||
| 14 | description: | ||
| 15 | The Zynq DDR ECC controller has an optional ECC support in half-bus width | ||
| 16 | (16-bit) configuration. It is cappable of correcting single bit ECC errors | ||
| 17 | and detecting double bit ECC errors. | ||
| 18 | |||
| 19 | properties: | ||
| 20 | compatible: | ||
| 21 | const: xlnx,zynq-ddrc-a05 | ||
| 22 | |||
| 23 | reg: | ||
| 24 | maxItems: 1 | ||
| 25 | |||
| 26 | required: | ||
| 27 | - compatible | ||
| 28 | - reg | ||
| 29 | |||
| 30 | additionalProperties: false | ||
| 31 | |||
| 32 | examples: | ||
| 33 | - | | ||
| 34 | memory-controller@f8006000 { | ||
| 35 | compatible = "xlnx,zynq-ddrc-a05"; | ||
| 36 | reg = <0xf8006000 0x1000>; | ||
| 37 | }; | ||
| 38 | ... | ||
| @@ -40,6 +40,8 @@ properties: · 39 unmodified lines | |||
| 40 | - allwinner,sun50i-a64-system-controller | 40 | - allwinner,sun50i-a64-system-controller |
| 41 | - brcm,cru-clkset | 41 | - brcm,cru-clkset |
| 42 | - freecom,fsg-cs2-system-controller | 42 | - freecom,fsg-cs2-system-controller |
| 43 | - fsl,imx93-aonmix-ns-syscfg | ||
| 44 | - fsl,imx93-wakeupmix-syscfg | ||
| 43 | - hisilicon,dsa-subctrl | 45 | - hisilicon,dsa-subctrl |
| 44 | - hisilicon,hi6220-sramctrl | 46 | - hisilicon,hi6220-sramctrl |
| 45 | - hisilicon,pcie-sas-subctrl | 47 | - hisilicon,pcie-sas-subctrl |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | |||
| 7 | title: Mediatek Power Domains Controller | 7 | title: Mediatek Power Domains Controller |
| 8 | 8 | ||
| 9 | maintainers: | 9 | maintainers: |
| 10 | - Weiyi Lu <weiyi.lu@mediatek.com> | 10 | - MandyJH Liu <mandyjh.liu@mediatek.com> |
| 11 | - Matthias Brugger <mbrugger@suse.com> | 11 | - Matthias Brugger <mbrugger@suse.com> |
| 12 | 12 | ||
| 13 | description: | | 13 | description: | |
| @@ -19,7 +19,7 @@ description: | · 5 unmodified lines | |||
| 19 | 19 | ||
| 20 | properties: | 20 | properties: |
| 21 | $nodename: | 21 | $nodename: |
| 22 | const: power-controller | 22 | pattern: '^power-controller(@[0-9a-f]+)?$' |
| 23 | 23 | ||
| 24 | compatible: | 24 | compatible: |
| 25 | enum: | 25 | enum: |
| @@ -42,6 +42,23 @@ properties: · 16 unmodified lines | |||
| 42 | 42 | ||
| 43 | patternProperties: | 43 | patternProperties: |
| 44 | "^power-domain@[0-9a-f]+$": | 44 | "^power-domain@[0-9a-f]+$": |
| 45 | $ref: "#/$defs/power-domain-node" | ||
| 46 | patternProperties: | ||
| 47 | "^power-domain@[0-9a-f]+$": | ||
| 48 | $ref: "#/$defs/power-domain-node" | ||
| 49 | patternProperties: | ||
| 50 | "^power-domain@[0-9a-f]+$": | ||
| 51 | $ref: "#/$defs/power-domain-node" | ||
| 52 | patternProperties: | ||
| 53 | "^power-domain@[0-9a-f]+$": | ||
| 54 | $ref: "#/$defs/power-domain-node" | ||
| 55 | unevaluatedProperties: false | ||
| 56 | unevaluatedProperties: false | ||
| 57 | unevaluatedProperties: false | ||
| 58 | unevaluatedProperties: false | ||
| 59 | |||
| 60 | $defs: | ||
| 61 | power-domain-node: | ||
| 45 | type: object | 62 | type: object |
| 46 | description: | | 63 | description: | |
| 47 | Represents the power domains within the power controller node as documented | 64 | Represents the power domains within the power controller node as documented |
| @@ -100,123 +117,9 @@ patternProperties: · 52 unmodified lines | |||
| 100 | $ref: /schemas/types.yaml#/definitions/phandle | 117 | $ref: /schemas/types.yaml#/definitions/phandle |
| 101 | description: phandle to the device containing the SMI register range. | 118 | description: phandle to the device containing the SMI register range. |
| 102 | 119 | ||
| 103 | patternProperties: | ||
| 104 | "^power-domain@[0-9a-f]+$": | ||
| 105 | type: object | ||
| 106 | description: | | ||
| 107 | Represents a power domain child within a power domain parent node. | ||
| 108 | |||
| 109 | properties: | ||
| 110 | |||
| 111 | '#power-domain-cells': | ||
| 112 | description: | ||
| 113 | Must be 0 for nodes representing a single PM domain and 1 for nodes | ||
| 114 | providing multiple PM domains. | ||
| 115 | |||
| 116 | '#address-cells': | ||
| 117 | const: 1 | ||
| 118 | |||
| 119 | '#size-cells': | ||
| 120 | const: 0 | ||
| 121 | |||
| 122 | reg: | ||
| 123 | maxItems: 1 | ||
| 124 | |||
| 125 | clocks: | ||
| 126 | description: | | ||
| 127 | A number of phandles to clocks that need to be enabled during domain | ||
| 128 | power-up sequencing. | ||
| 129 | |||
| 130 | clock-names: | ||
| 131 | description: | | ||
| 132 | List of names of clocks, in order to match the power-up sequencing | ||
| 133 | for each power domain we need to group the clocks by name. BASIC | ||
| 134 | clocks need to be enabled before enabling the corresponding power | ||
| 135 | domain, and should not have a '-' in their name (i.e mm, mfg, venc). | ||
| 136 | SUSBYS clocks need to be enabled before releasing the bus protection, | ||
| 137 | and should contain a '-' in their name (i.e mm-0, isp-0, cam-0). | ||
| 138 | |||
| 139 | In order to follow properly the power-up sequencing, the clocks must | ||
| 140 | be specified by order, adding first the BASIC clocks followed by the | ||
| 141 | SUSBSYS clocks. | ||
| 142 | |||
| 143 | domain-supply: | ||
| 144 | description: domain regulator supply. | ||
| 145 | |||
| 146 | mediatek,infracfg: | ||
| 147 | $ref: /schemas/types.yaml#/definitions/phandle | ||
| 148 | description: phandle to the device containing the INFRACFG register range. | ||
| 149 | |||
| 150 | mediatek,smi: | ||
| 151 | $ref: /schemas/types.yaml#/definitions/phandle | ||
| 152 | description: phandle to the device containing the SMI register range. | ||
| 153 | |||
| 154 | patternProperties: | ||
| 155 | "^power-domain@[0-9a-f]+$": | ||
| 156 | type: object | ||
| 157 | description: | | ||
| 158 | Represents a power domain child within a power domain parent node. | ||
| 159 | |||
| 160 | properties: | ||
| 161 | |||
| 162 | '#power-domain-cells': | ||
| 163 | description: | ||
| 164 | Must be 0 for nodes representing a single PM domain and 1 for nodes | ||
| 165 | providing multiple PM domains. | ||
| 166 | |||
| 167 | '#address-cells': | ||
| 168 | const: 1 | ||
| 169 | |||
| 170 | '#size-cells': | ||
| 171 | const: 0 | ||
| 172 | |||
| 173 | reg: | ||
| 174 | maxItems: 1 | ||
| 175 | |||
| 176 | clocks: | ||
| 177 | description: | | ||
| 178 | A number of phandles to clocks that need to be enabled during domain | ||
| 179 | power-up sequencing. | ||
| 180 | |||
| 181 | clock-names: | ||
| 182 | description: | | ||
| 183 | List of names of clocks, in order to match the power-up sequencing | ||
| 184 | for each power domain we need to group the clocks by name. BASIC | ||
| 185 | clocks need to be enabled before enabling the corresponding power | ||
| 186 | domain, and should not have a '-' in their name (i.e mm, mfg, venc). | ||
| 187 | SUSBYS clocks need to be enabled before releasing the bus protection, | ||
| 188 | and should contain a '-' in their name (i.e mm-0, isp-0, cam-0). | ||
| 189 | |||
| 190 | In order to follow properly the power-up sequencing, the clocks must | ||
| 191 | be specified by order, adding first the BASIC clocks followed by the | ||
| 192 | SUSBSYS clocks. | ||
| 193 | |||
| 194 | domain-supply: | ||
| 195 | description: domain regulator supply. | ||
| 196 | |||
| 197 | mediatek,infracfg: | ||
| 198 | $ref: /schemas/types.yaml#/definitions/phandle | ||
| 199 | description: phandle to the device containing the INFRACFG register range. | ||
| 200 | |||
| 201 | mediatek,smi: | ||
| 202 | $ref: /schemas/types.yaml#/definitions/phandle | ||
| 203 | description: phandle to the device containing the SMI register range. | ||
| 204 | |||
| 205 | required: | ||
| 206 | - reg | ||
| 207 | |||
| 208 | additionalProperties: false | ||
| 209 | |||
| 210 | required: | ||
| 211 | - reg | ||
| 212 | |||
| 213 | additionalProperties: false | ||
| 214 | |||
| 215 | required: | 120 | required: |
| 216 | - reg | 121 | - reg |
| 217 | 122 | ||
| 218 | additionalProperties: false | ||
| 219 | |||
| 220 | required: | 123 | required: |
| 221 | - compatible | 124 | - compatible |
| 222 | 125 | ||
| @@ -40,6 +40,7 @@ properties: · 39 unmodified lines | |||
| 40 | - qcom,sm6115-rpmpd | 40 | - qcom,sm6115-rpmpd |
| 41 | - qcom,sm6125-rpmpd | 41 | - qcom,sm6125-rpmpd |
| 42 | - qcom,sm6350-rpmhpd | 42 | - qcom,sm6350-rpmhpd |
| 43 | - qcom,sm6375-rpmpd | ||
| 43 | - qcom,sm8150-rpmhpd | 44 | - qcom,sm8150-rpmhpd |
| 44 | - qcom,sm8250-rpmhpd | 45 | - qcom,sm8250-rpmhpd |
| 45 | - qcom,sm8350-rpmhpd | 46 | - qcom,sm8350-rpmhpd |
| @@ -41,6 +41,8 @@ properties: · 40 unmodified lines | |||
| 41 | - rockchip,rk3368-power-controller | 41 | - rockchip,rk3368-power-controller |
| 42 | - rockchip,rk3399-power-controller | 42 | - rockchip,rk3399-power-controller |
| 43 | - rockchip,rk3568-power-controller | 43 | - rockchip,rk3568-power-controller |
| 44 | - rockchip,rk3588-power-controller | ||
| 45 | - rockchip,rv1126-power-controller | ||
| 44 | 46 | ||
| 45 | "#power-domain-cells": | 47 | "#power-domain-cells": |
| 46 | const: 1 | 48 | const: 1 |
| @@ -119,6 +121,8 @@ $defs: · 72 unmodified lines | |||
| 119 | "include/dt-bindings/power/rk3368-power.h" | 121 | "include/dt-bindings/power/rk3368-power.h" |
| 120 | "include/dt-bindings/power/rk3399-power.h" | 122 | "include/dt-bindings/power/rk3399-power.h" |
| 121 | "include/dt-bindings/power/rk3568-power.h" | 123 | "include/dt-bindings/power/rk3568-power.h" |
| 124 | "include/dt-bindings/power/rk3588-power.h" | ||
| 125 | "include/dt-bindings/power/rockchip,rv1126-power.h" | ||
| 122 | 126 | ||
| 123 | clocks: | 127 | clocks: |
| 124 | minItems: 1 | 128 | minItems: 1 |
| @@ -58,6 +58,7 @@ properties: · 57 unmodified lines | |||
| 58 | - rockchip,rk3568-pmu-io-voltage-domain | 58 | - rockchip,rk3568-pmu-io-voltage-domain |
| 59 | - rockchip,rv1108-io-voltage-domain | 59 | - rockchip,rv1108-io-voltage-domain |
| 60 | - rockchip,rv1108-pmu-io-voltage-domain | 60 | - rockchip,rv1108-pmu-io-voltage-domain |
| 61 | - rockchip,rv1126-pmu-io-voltage-domain | ||
| 61 | 62 | ||
| 62 | required: | 63 | required: |
| 63 | - compatible | 64 | - compatible |
| @@ -78,6 +79,7 @@ allOf: · 14 unmodified lines | |||
| 78 | - $ref: "#/$defs/rk3568-pmu" | 79 | - $ref: "#/$defs/rk3568-pmu" |
| 79 | - $ref: "#/$defs/rv1108" | 80 | - $ref: "#/$defs/rv1108" |
| 80 | - $ref: "#/$defs/rv1108-pmu" | 81 | - $ref: "#/$defs/rv1108-pmu" |
| 82 | - $ref: "#/$defs/rv1126-pmu" | ||
| 81 | 83 | ||
| 82 | $defs: | 84 | $defs: |
| 83 | px30: | 85 | px30: |
| @@ -344,6 +346,34 @@ $defs: · 260 unmodified lines | |||
| 344 | pmu-supply: | 346 | pmu-supply: |
| 345 | description: The supply connected to PMUIO_VDD. | 347 | description: The supply connected to PMUIO_VDD. |
| 346 | 348 | ||
| 349 | rv1126-pmu: | ||
| 350 | if: | ||
| 351 | properties: | ||
| 352 | compatible: | ||
| 353 | contains: | ||
| 354 | const: rockchip,rv1126-pmu-io-voltage-domain | ||
| 355 | |||
| 356 | then: | ||
| 357 | properties: | ||
| 358 | vccio1-supply: | ||
| 359 | description: The supply connected to VCCIO1. | ||
| 360 | vccio2-supply: | ||
| 361 | description: The supply connected to VCCIO2. | ||
| 362 | vccio3-supply: | ||
| 363 | description: The supply connected to VCCIO3. | ||
| 364 | vccio4-supply: | ||
| 365 | description: The supply connected to VCCIO4. | ||
| 366 | vccio5-supply: | ||
| 367 | description: The supply connected to VCCIO5. | ||
| 368 | vccio6-supply: | ||
| 369 | description: The supply connected to VCCIO6. | ||
| 370 | vccio7-supply: | ||
| 371 | description: The supply connected to VCCIO7. | ||
| 372 | pmuio0-supply: | ||
| 373 | description: The supply connected to PMUIO0. | ||
| 374 | pmuio1-supply: | ||
| 375 | description: The supply connected to PMUIO1. | ||
| 376 | |||
| 347 | examples: | 377 | examples: |
| 348 | - | | 378 | - | |
| 349 | io-domains { | 379 | io-domains { |
| @@ -27,25 +27,22 @@ properties: · 26 unmodified lines | |||
| 27 | const: 1 | 27 | const: 1 |
| 28 | 28 | ||
| 29 | power-domains: | 29 | power-domains: |
| 30 | minItems: 4 | ||
| 31 | maxItems: 4 | 30 | maxItems: 4 |
| 32 | 31 | ||
| 33 | power-domain-names: | 32 | power-domain-names: |
| 34 | items: | 33 | maxItems: 4 |
| 35 | - const: bus | ||
| 36 | - const: g1 | ||
| 37 | - const: g2 | ||
| 38 | - const: h1 | ||
| 39 | 34 | ||
| 40 | clocks: | 35 | clocks: |
| 41 | minItems: 3 | ||
| 42 | maxItems: 3 | 36 | maxItems: 3 |
| 43 | 37 | ||
| 44 | clock-names: | 38 | clock-names: |
| 45 | items: | 39 | maxItems: 3 |
| 46 | - const: g1 | 40 | |
| 47 | - const: g2 | 41 | interconnects: |
| 48 | - const: h1 | 42 | maxItems: 3 |
| 43 | |||
| 44 | interconnect-names: | ||
| 45 | maxItems: 3 | ||
| 49 | 46 | ||
| 50 | required: | 47 | required: |
| 51 | - compatible | 48 | - compatible |
| @@ -55,6 +52,97 @@ required: · 3 unmodified lines | |||
| 55 | - clocks | 52 | - clocks |
| 56 | - clock-names | 53 | - clock-names |
| 57 | 54 | ||
| 55 | allOf: | ||
| 56 | - if: | ||
| 57 | properties: | ||
| 58 | compatible: | ||
| 59 | contains: | ||
| 60 | const: fsl,imx8mm-vpu-blk-ctrl | ||
| 61 | then: | ||
| 62 | properties: | ||
| 63 | power-domains: | ||
| 64 | items: | ||
| 65 | - description: bus power domain | ||
| 66 | - description: G1 decoder power domain | ||
| 67 | - description: G2 decoder power domain | ||
| 68 | - description: H1 encoder power domain | ||
| 69 | |||
| 70 | power-domain-names: | ||
| 71 | items: | ||
| 72 | - const: bus | ||
| 73 | - const: g1 | ||
| 74 | - const: g2 | ||
| 75 | - const: h1 | ||
| 76 | |||
| 77 | clocks: | ||
| 78 | items: | ||
| 79 | - description: G1 decoder clk | ||
| 80 | - description: G2 decoder clk | ||
| 81 | - description: H1 encoder clk | ||
| 82 | |||
| 83 | clock-names: | ||
| 84 | items: | ||
| 85 | - const: g1 | ||
| 86 | - const: g2 | ||
| 87 | - const: h1 | ||
| 88 | |||
| 89 | interconnects: | ||
| 90 | items: | ||
| 91 | - description: G1 decoder interconnect | ||
| 92 | - description: G2 decoder interconnect | ||
| 93 | - description: H1 encoder power domain | ||
| 94 | |||
| 95 | interconnect-names: | ||
| 96 | items: | ||
| 97 | - const: g1 | ||
| 98 | - const: g2 | ||
| 99 | - const: h1 | ||
| 100 | |||
| 101 | - if: | ||
| 102 | properties: | ||
| 103 | compatible: | ||
| 104 | contains: | ||
| 105 | const: fsl,imx8mp-vpu-blk-ctrl | ||
| 106 | then: | ||
| 107 | properties: | ||
| 108 | power-domains: | ||
| 109 | items: | ||
| 110 | - description: bus power domain | ||
| 111 | - description: G1 decoder power domain | ||
| 112 | - description: G2 decoder power domain | ||
| 113 | - description: VC8000E encoder power domain | ||
| 114 | |||
| 115 | power-domain-names: | ||
| 116 | items: | ||
| 117 | - const: bus | ||
| 118 | - const: g1 | ||
| 119 | - const: g2 | ||
| 120 | - const: vc8000e | ||
| 121 | |||
| 122 | clocks: | ||
| 123 | items: | ||
| 124 | - description: G1 decoder clk | ||
| 125 | - description: G2 decoder clk | ||
| 126 | - description: VC8000E encoder clk | ||
| 127 | |||
| 128 | clock-names: | ||
| 129 | items: | ||
| 130 | - const: g1 | ||
| 131 | - const: g2 | ||
| 132 | - const: vc8000e | ||
| 133 | |||
| 134 | interconnects: | ||
| 135 | items: | ||
| 136 | - description: G1 decoder interconnect | ||
| 137 | - description: G2 decoder interconnect | ||
| 138 | - description: VC8000E encoder interconnect | ||
| 139 | |||
| 140 | interconnect-names: | ||
| 141 | items: | ||
| 142 | - const: g1 | ||
| 143 | - const: g2 | ||
| 144 | - const: vc8000e | ||
| 145 | |||
| 58 | additionalProperties: false | 146 | additionalProperties: false |
| 59 | 147 | ||
| 60 | examples: | 148 | examples: |
| @@ -52,6 +52,15 @@ properties: · 51 unmodified lines | |||
| 52 | - const: ref_266m | 52 | - const: ref_266m |
| 53 | - const: ref_24m | 53 | - const: ref_24m |
| 54 | 54 | ||
| 55 | interconnects: | ||
| 56 | maxItems: 3 | ||
| 57 | |||
| 58 | interconnect-names: | ||
| 59 | items: | ||
| 60 | - const: hrv | ||
| 61 | - const: lcdif-hdmi | ||
| 62 | - const: hdcp | ||
| 63 | |||
| 55 | required: | 64 | required: |
| 56 | - compatible | 65 | - compatible |
| 57 | - reg | 66 | - reg |
| @@ -48,6 +48,16 @@ properties: · 47 unmodified lines | |||
| 48 | - const: usb | 48 | - const: usb |
| 49 | - const: pcie | 49 | - const: pcie |
| 50 | 50 | ||
| 51 | interconnects: | ||
| 52 | maxItems: 4 | ||
| 53 | |||
| 54 | interconnect-names: | ||
| 55 | items: | ||
| 56 | - const: noc-pcie | ||
| 57 | - const: usb1 | ||
| 58 | - const: usb2 | ||
| 59 | - const: pcie | ||
| 60 | |||
| 51 | required: | 61 | required: |
| 52 | - compatible | 62 | - compatible |
| 53 | - reg | 63 | - reg |
| @@ -64,6 +64,20 @@ properties: · 63 unmodified lines | |||
| 64 | - const: isp | 64 | - const: isp |
| 65 | - const: phy | 65 | - const: phy |
| 66 | 66 | ||
| 67 | interconnects: | ||
| 68 | maxItems: 8 | ||
| 69 | |||
| 70 | interconnect-names: | ||
| 71 | items: | ||
| 72 | - const: lcdif-rd | ||
| 73 | - const: lcdif-wr | ||
| 74 | - const: isi0 | ||
| 75 | - const: isi1 | ||
| 76 | - const: isi2 | ||
| 77 | - const: isp0 | ||
| 78 | - const: isp1 | ||
| 79 | - const: dwe | ||
| 80 | |||
| 67 | required: | 81 | required: |
| 68 | - compatible | 82 | - compatible |
| 69 | - reg | 83 | - reg |
| @@ -0,0 +1,80 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/soc/imx/fsl,imx93-media-blk-ctrl.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: NXP i.MX93 Media blk-ctrl | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Peng Fan <peng.fan@nxp.com> | ||
| 11 | |||
| 12 | description: | ||
| 13 | The i.MX93 MEDIAMIX domain contains control and status registers known | ||
| 14 | as MEDIAMIX Block Control (MEDIAMIX BLK_CTRL). These registers include | ||
| 15 | clocking, reset, and miscellaneous top-level controls for peripherals | ||
| 16 | within the MEDIAMIX domain | ||
| 17 | |||
| 18 | properties: | ||
| 19 | compatible: | ||
| 20 | items: | ||
| 21 | - const: fsl,imx93-media-blk-ctrl | ||
| 22 | - const: syscon | ||
| 23 | |||
| 24 | reg: | ||
| 25 | maxItems: 1 | ||
| 26 | |||
| 27 | '#power-domain-cells': | ||
| 28 | const: 1 | ||
| 29 | |||
| 30 | power-domains: | ||
| 31 | maxItems: 1 | ||
| 32 | |||
| 33 | clocks: | ||
| 34 | maxItems: 10 | ||
| 35 | |||
| 36 | clock-names: | ||
| 37 | items: | ||
| 38 | - const: apb | ||
| 39 | - const: axi | ||
| 40 | - const: nic | ||
| 41 | - const: disp | ||
| 42 | - const: cam | ||
| 43 | - const: pxp | ||
| 44 | - const: lcdif | ||
| 45 | - const: isi | ||
| 46 | - const: csi | ||
| 47 | - const: dsi | ||
| 48 | |||
| 49 | required: | ||
| 50 | - compatible | ||
| 51 | - reg | ||
| 52 | - power-domains | ||
| 53 | - clocks | ||
| 54 | - clock-names | ||
| 55 | |||
| 56 | additionalProperties: false | ||
| 57 | |||
| 58 | examples: | ||
| 59 | - | | ||
| 60 | #include <dt-bindings/clock/imx93-clock.h> | ||
| 61 | #include <dt-bindings/power/fsl,imx93-power.h> | ||
| 62 | |||
| 63 | media_blk_ctrl: system-controller@4ac10000 { | ||
| 64 | compatible = "fsl,imx93-media-blk-ctrl", "syscon"; | ||
| 65 | reg = <0x4ac10000 0x10000>; | ||
| 66 | power-domains = <&mediamix>; | ||
| 67 | clocks = <&clk IMX93_CLK_MEDIA_APB>, | ||
| 68 | <&clk IMX93_CLK_MEDIA_AXI>, | ||
| 69 | <&clk IMX93_CLK_NIC_MEDIA_GATE>, | ||
| 70 | <&clk IMX93_CLK_MEDIA_DISP_PIX>, | ||
| 71 | <&clk IMX93_CLK_CAM_PIX>, | ||
| 72 | <&clk IMX93_CLK_PXP_GATE>, | ||
| 73 | <&clk IMX93_CLK_LCDIF_GATE>, | ||
| 74 | <&clk IMX93_CLK_ISI_GATE>, | ||
| 75 | <&clk IMX93_CLK_MIPI_CSI_GATE>, | ||
| 76 | <&clk IMX93_CLK_MIPI_DSI_GATE>; | ||
| 77 | clock-names = "apb", "axi", "nic", "disp", "cam", | ||
| 78 | "pxp", "lcdif", "isi", "csi", "dsi"; | ||
| 79 | #power-domain-cells = <1>; | ||
| 80 | }; | ||
| @@ -0,0 +1,96 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/soc/imx/fsl,imx93-src.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: NXP i.MX93 System Reset Controller | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Peng Fan <peng.fan@nxp.com> | ||
| 11 | |||
| 12 | description: | | ||
| 13 | The System Reset Controller (SRC) is responsible for the generation of | ||
| 14 | all the system reset signals and boot argument latching. | ||
| 15 | |||
| 16 | Its main functions are as follows, | ||
| 17 | - Deals with all global system reset sources from other modules, | ||
| 18 | and generates global system reset. | ||
| 19 | - Responsible for power gating of MIXs (Slices) and their memory | ||
| 20 | low power control. | ||
| 21 | |||
| 22 | properties: | ||
| 23 | compatible: | ||
| 24 | items: | ||
| 25 | - const: fsl,imx93-src | ||
| 26 | - const: syscon | ||
| 27 | |||
| 28 | reg: | ||
| 29 | maxItems: 1 | ||
| 30 | |||
| 31 | ranges: true | ||
| 32 | |||
| 33 | '#address-cells': | ||
| 34 | const: 1 | ||
| 35 | |||
| 36 | '#size-cells': | ||
| 37 | const: 1 | ||
| 38 | |||
| 39 | patternProperties: | ||
| 40 | "power-domain@[0-9a-f]+$": | ||
| 41 | |||
| 42 | type: object | ||
| 43 | properties: | ||
| 44 | compatible: | ||
| 45 | items: | ||
| 46 | - const: fsl,imx93-src-slice | ||
| 47 | |||
| 48 | '#power-domain-cells': | ||
| 49 | const: 0 | ||
| 50 | |||
| 51 | reg: | ||
| 52 | items: | ||
| 53 | - description: mix slice register region | ||
| 54 | - description: mem slice register region | ||
| 55 | |||
| 56 | clocks: | ||
| 57 | description: | | ||
| 58 | A number of phandles to clocks that need to be enabled | ||
| 59 | during domain power-up sequencing to ensure reset | ||
| 60 | propagation into devices located inside this power domain. | ||
| 61 | minItems: 1 | ||
| 62 | maxItems: 5 | ||
| 63 | |||
| 64 | required: | ||
| 65 | - compatible | ||
| 66 | - '#power-domain-cells' | ||
| 67 | - reg | ||
| 68 | |||
| 69 | required: | ||
| 70 | - compatible | ||
| 71 | - reg | ||
| 72 | - ranges | ||
| 73 | - '#address-cells' | ||
| 74 | - '#size-cells' | ||
| 75 | |||
| 76 | additionalProperties: false | ||
| 77 | |||
| 78 | examples: | ||
| 79 | - | | ||
| 80 | #include <dt-bindings/clock/imx93-clock.h> | ||
| 81 | |||
| 82 | system-controller@44460000 { | ||
| 83 | compatible = "fsl,imx93-src", "syscon"; | ||
| 84 | reg = <0x44460000 0x10000>; | ||
| 85 | #address-cells = <1>; | ||
| 86 | #size-cells = <1>; | ||
| 87 | ranges; | ||
| 88 | |||
| 89 | mediamix: power-domain@0 { | ||
| 90 | compatible = "fsl,imx93-src-slice"; | ||
| 91 | reg = <0x44462400 0x400>, <0x44465800 0x400>; | ||
| 92 | #power-domain-cells = <0>; | ||
| 93 | clocks = <&clk IMX93_CLK_MEDIA_AXI>, | ||
| 94 | <&clk IMX93_CLK_MEDIA_APB>; | ||
| 95 | }; | ||
| 96 | }; | ||
| @@ -26,10 +26,12 @@ properties: · 25 unmodified lines | |||
| 26 | enum: | 26 | enum: |
| 27 | - mediatek,mt2701-disp-mutex | 27 | - mediatek,mt2701-disp-mutex |
| 28 | - mediatek,mt2712-disp-mutex | 28 | - mediatek,mt2712-disp-mutex |
| 29 | - mediatek,mt6795-disp-mutex | ||
| 29 | - mediatek,mt8167-disp-mutex | 30 | - mediatek,mt8167-disp-mutex |
| 30 | - mediatek,mt8173-disp-mutex | 31 | - mediatek,mt8173-disp-mutex |
| 31 | - mediatek,mt8183-disp-mutex | 32 | - mediatek,mt8183-disp-mutex |
| 32 | - mediatek,mt8186-disp-mutex | 33 | - mediatek,mt8186-disp-mutex |
| 34 | - mediatek,mt8186-mdp3-mutex | ||
| 33 | - mediatek,mt8192-disp-mutex | 35 | - mediatek,mt8192-disp-mutex |
| 34 | - mediatek,mt8195-disp-mutex | 36 | - mediatek,mt8195-disp-mutex |
| 35 | 37 | ||
| @@ -28,6 +28,7 @@ Required properties in pwrap device node. · 27 unmodified lines | |||
| 28 | "mediatek,mt8173-pwrap" for MT8173 SoCs | 28 | "mediatek,mt8173-pwrap" for MT8173 SoCs |
| 29 | "mediatek,mt8183-pwrap" for MT8183 SoCs | 29 | "mediatek,mt8183-pwrap" for MT8183 SoCs |
| 30 | "mediatek,mt8186-pwrap" for MT8186 SoCs | 30 | "mediatek,mt8186-pwrap" for MT8186 SoCs |
| 31 | "mediatek,mt8188-pwrap", "mediatek,mt8195-pwrap" for MT8188 SoCs | ||
| 31 | "mediatek,mt8195-pwrap" for MT8195 SoCs | 32 | "mediatek,mt8195-pwrap" for MT8195 SoCs |
| 32 | "mediatek,mt8516-pwrap" for MT8516 SoCs | 33 | "mediatek,mt8516-pwrap" for MT8516 SoCs |
| 33 | - interrupts: IRQ for pwrap in SOC | 34 | - interrupts: IRQ for pwrap in SOC |
| @@ -20,6 +20,7 @@ properties: · 19 unmodified lines | |||
| 20 | compatible: | 20 | compatible: |
| 21 | enum: | 21 | enum: |
| 22 | - qcom,rpmh-stats | 22 | - qcom,rpmh-stats |
| 23 | - qcom,sdm845-rpmh-stats | ||
| 23 | - qcom,rpm-stats | 24 | - qcom,rpm-stats |
| 24 | # For older RPM firmware versions with fixed offset for the sleep stats | 25 | # For older RPM firmware versions with fixed offset for the sleep stats |
| 25 | - qcom,apq8084-rpm-stats | 26 | - qcom,apq8084-rpm-stats |
| @@ -16,9 +16,12 @@ properties: · 15 unmodified lines | |||
| 16 | - enum: | 16 | - enum: |
| 17 | - rockchip,rk3288-sgrf | 17 | - rockchip,rk3288-sgrf |
| 18 | - rockchip,rk3566-pipe-grf | 18 | - rockchip,rk3566-pipe-grf |
| 19 | - rockchip,rk3568-pcie3-phy-grf | ||
| 19 | - rockchip,rk3568-pipe-grf | 20 | - rockchip,rk3568-pipe-grf |
| 20 | - rockchip,rk3568-pipe-phy-grf | 21 | - rockchip,rk3568-pipe-phy-grf |
| 21 | - rockchip,rk3568-usb2phy-grf | 22 | - rockchip,rk3568-usb2phy-grf |
| 23 | - rockchip,rk3588-pcie3-phy-grf | ||
| 24 | - rockchip,rk3588-pcie3-pipe-grf | ||
| 22 | - rockchip,rv1108-usbgrf | 25 | - rockchip,rv1108-usbgrf |
| 23 | - const: syscon | 26 | - const: syscon |
| 24 | - items: | 27 | - items: |
| @@ -28,6 +31,7 @@ properties: · 3 unmodified lines | |||
| 28 | - rockchip,px30-usb2phy-grf | 31 | - rockchip,px30-usb2phy-grf |
| 29 | - rockchip,rk3036-grf | 32 | - rockchip,rk3036-grf |
| 30 | - rockchip,rk3066-grf | 33 | - rockchip,rk3066-grf |
| 34 | - rockchip,rk3128-grf | ||
| 31 | - rockchip,rk3188-grf | 35 | - rockchip,rk3188-grf |
| 32 | - rockchip,rk3228-grf | 36 | - rockchip,rk3228-grf |
| 33 | - rockchip,rk3288-grf | 37 | - rockchip,rk3288-grf |
| @@ -45,6 +49,8 @@ properties: · 11 unmodified lines | |||
| 45 | - rockchip,rk3568-pmugrf | 49 | - rockchip,rk3568-pmugrf |
| 46 | - rockchip,rv1108-grf | 50 | - rockchip,rv1108-grf |
| 47 | - rockchip,rv1108-pmugrf | 51 | - rockchip,rv1108-pmugrf |
| 52 | - rockchip,rv1126-grf | ||
| 53 | - rockchip,rv1126-pmugrf | ||
| 48 | - const: syscon | 54 | - const: syscon |
| 49 | - const: simple-mfd | 55 | - const: simple-mfd |
| 50 | 56 | ||
| @@ -178,6 +184,7 @@ allOf: · 127 unmodified lines | |||
| 178 | contains: | 184 | contains: |
| 179 | enum: | 185 | enum: |
| 180 | - rockchip,px30-usb2phy-grf | 186 | - rockchip,px30-usb2phy-grf |
| 187 | - rockchip,rk3128-grf | ||
| 181 | - rockchip,rk3228-grf | 188 | - rockchip,rk3228-grf |
| 182 | - rockchip,rk3308-usb2phy-grf | 189 | - rockchip,rk3308-usb2phy-grf |
| 183 | - rockchip,rk3328-usb2phy-grf | 190 | - rockchip,rk3328-usb2phy-grf |
| @@ -3125,6 +3125,8 @@ W: http://wiki.xilinx.com · 3124 unmodified lines | |||
| 3125 | T: git https://github.com/Xilinx/linux-xlnx.git | 3125 | T: git https://github.com/Xilinx/linux-xlnx.git |
| 3126 | F: Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml | 3126 | F: Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml |
| 3127 | F: Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml | 3127 | F: Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml |
| 3128 | F: Documentation/devicetree/bindings/memory-controllers/snps,dw-umctl2-ddrc.yaml | ||
| 3129 | F: Documentation/devicetree/bindings/memory-controllers/xlnx,zynq-ddrc-a05.yaml | ||
| 3128 | F: Documentation/devicetree/bindings/spi/xlnx,zynq-qspi.yaml | 3130 | F: Documentation/devicetree/bindings/spi/xlnx,zynq-qspi.yaml |
| 3129 | F: arch/arm/mach-zynq/ | 3131 | F: arch/arm/mach-zynq/ |
| 3130 | F: drivers/clocksource/timer-cadence-ttc.c | 3132 | 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 · 2276 unmodified lines | |||
| 5407 | F: drivers/cpuidle/cpuidle-big_little.c | 5409 | F: drivers/cpuidle/cpuidle-big_little.c |
| 5408 | 5410 | ||
| 5409 | CPUIDLE DRIVER - ARM EXYNOS | 5411 | CPUIDLE DRIVER - ARM EXYNOS |
| 5410 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> | ||
| 5411 | M: Daniel Lezcano <daniel.lezcano@linaro.org> | 5412 | M: Daniel Lezcano <daniel.lezcano@linaro.org> |
| 5413 | R: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | ||
| 5412 | M: Kukjin Kim <kgene@kernel.org> | 5414 | M: Kukjin Kim <kgene@kernel.org> |
| 5413 | L: linux-pm@vger.kernel.org | 5415 | L: linux-pm@vger.kernel.org |
| 5414 | L: linux-samsung-soc@vger.kernel.org | 5416 | L: linux-samsung-soc@vger.kernel.org |
| @@ -12441,7 +12443,6 @@ F: drivers/power/supply/max77976_charger.c · 7026 unmodified lines | |||
| 12441 | 12443 | ||
| 12442 | MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS | 12444 | MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS |
| 12443 | M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | 12445 | M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> |
| 12444 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> | ||
| 12445 | L: linux-pm@vger.kernel.org | 12446 | L: linux-pm@vger.kernel.org |
| 12446 | S: Supported | 12447 | S: Supported |
| 12447 | B: mailto:linux-samsung-soc@vger.kernel.org | 12448 | B: mailto:linux-samsung-soc@vger.kernel.org |
| @@ -12453,7 +12454,6 @@ F: drivers/power/supply/max77693_charger.c · 5 unmodified lines | |||
| 12453 | MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS | 12454 | MAXIM PMIC AND MUIC DRIVERS FOR EXYNOS BASED BOARDS |
| 12454 | M: Chanwoo Choi <cw00.choi@samsung.com> | 12455 | M: Chanwoo Choi <cw00.choi@samsung.com> |
| 12455 | M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | 12456 | M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> |
| 12456 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> | ||
| 12457 | L: linux-kernel@vger.kernel.org | 12457 | L: linux-kernel@vger.kernel.org |
| 12458 | S: Supported | 12458 | S: Supported |
| 12459 | B: mailto:linux-samsung-soc@vger.kernel.org | 12459 | B: mailto:linux-samsung-soc@vger.kernel.org |
| @@ -16587,14 +16587,6 @@ T: git git://linuxtv.org/media_tree.git · 4127 unmodified lines | |||
| 16587 | F: drivers/media/usb/pwc/* | 16587 | F: drivers/media/usb/pwc/* |
| 16588 | F: include/trace/events/pwc.h | 16588 | F: include/trace/events/pwc.h |
| 16589 | 16589 | ||
| 16590 | PWM FAN DRIVER | ||
| 16591 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> | ||
| 16592 | L: linux-hwmon@vger.kernel.org | ||
| 16593 | S: Supported | ||
| 16594 | F: Documentation/devicetree/bindings/hwmon/pwm-fan.txt | ||
| 16595 | F: Documentation/hwmon/pwm-fan.rst | ||
| 16596 | F: drivers/hwmon/pwm-fan.c | ||
| 16597 | |||
| 16598 | PWM IR Transmitter | 16590 | PWM IR Transmitter |
| 16599 | M: Sean Young <sean@mess.org> | 16591 | M: Sean Young <sean@mess.org> |
| 16600 | L: linux-media@vger.kernel.org | 16592 | L: linux-media@vger.kernel.org |
| @@ -18055,7 +18047,6 @@ F: drivers/platform/x86/samsung-laptop.c · 1454 unmodified lines | |||
| 18055 | 18047 | ||
| 18056 | SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS | 18048 | SAMSUNG MULTIFUNCTION PMIC DEVICE DRIVERS |
| 18057 | M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | 18049 | M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> |
| 18058 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> | ||
| 18059 | L: linux-kernel@vger.kernel.org | 18050 | L: linux-kernel@vger.kernel.org |
| 18060 | L: linux-samsung-soc@vger.kernel.org | 18051 | L: linux-samsung-soc@vger.kernel.org |
| 18061 | S: Supported | 18052 | S: Supported |
| @@ -67,11 +67,7 @@ · 66 unmodified lines | |||
| 67 | #if defined(CONFIG_ARCH_SA1100) | 67 | #if defined(CONFIG_ARCH_SA1100) |
| 68 | .macro loadsp, rb, tmp1, tmp2 | 68 | .macro loadsp, rb, tmp1, tmp2 |
| 69 | mov \rb, #0x80000000 @ physical base address | 69 | mov \rb, #0x80000000 @ physical base address |
| 70 | #ifdef CONFIG_DEBUG_LL_SER3 | ||
| 71 | add \rb, \rb, #0x00050000 @ Ser3 | ||
| 72 | #else | ||
| 73 | add \rb, \rb, #0x00010000 @ Ser1 | 70 | add \rb, \rb, #0x00010000 @ Ser1 |
| 74 | #endif | ||
| 75 | .endm | 71 | .endm |
| 76 | #else | 72 | #else |
| 77 | .macro loadsp, rb, tmp1, tmp2 | 73 | .macro loadsp, rb, tmp1, tmp2 |
| @@ -85,7 +85,7 @@ static int wait_lpc_idle(void __iomem *mbase, unsigned int waitcnt) · 84 unmodified lines | |||
| 85 | ndelay(LPC_NSEC_PERWAIT); | 85 | ndelay(LPC_NSEC_PERWAIT); |
| 86 | } while (--waitcnt); | 86 | } while (--waitcnt); |
| 87 | 87 | ||
| 88 | return -ETIME; | 88 | return -ETIMEDOUT; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | /* | 91 | /* |
| @@ -347,7 +347,7 @@ static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev, · 255 unmodified lines | |||
| 347 | unsigned long sys_port; | 347 | unsigned long sys_port; |
| 348 | resource_size_t len = resource_size(res); | 348 | resource_size_t len = resource_size(res); |
| 349 | 349 | ||
| 350 | sys_port = logic_pio_trans_hwaddr(&host->fwnode, res->start, len); | 350 | sys_port = logic_pio_trans_hwaddr(acpi_fwnode_handle(host), res->start, len); |
| 351 | if (sys_port == ~0UL) | 351 | if (sys_port == ~0UL) |
| 352 | return -EFAULT; | 352 | return -EFAULT; |
| 353 | 353 | ||
| @@ -472,9 +472,7 @@ static int hisi_lpc_acpi_clear_enumerated(struct acpi_device *adev, void *not_us · 118 unmodified lines | |||
| 472 | 472 | ||
| 473 | struct hisi_lpc_acpi_cell { | 473 | struct hisi_lpc_acpi_cell { |
| 474 | const char *hid; | 474 | const char *hid; |
| 475 | const char *name; | 475 | const struct platform_device_info *pdevinfo; |
| 476 | void *pdata; | ||
| 477 | size_t pdata_size; | ||
| 478 | }; | 476 | }; |
| 479 | 477 | ||
| 480 | static void hisi_lpc_acpi_remove(struct device *hostdev) | 478 | 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) · 24 unmodified lines | |||
| 505 | /* ipmi */ | 503 | /* ipmi */ |
| 506 | { | 504 | { |
| 507 | .hid = "IPI0001", | 505 | .hid = "IPI0001", |
| 508 | .name = "hisi-lpc-ipmi", | 506 | .pdevinfo = (struct platform_device_info []) { |
| 507 | { | ||
| 508 | .parent = hostdev, | ||
| 509 | .fwnode = acpi_fwnode_handle(child), | ||
| 510 | .name = "hisi-lpc-ipmi", | ||
| 511 | .id = PLATFORM_DEVID_AUTO, | ||
| 512 | .res = res, | ||
| 513 | .num_res = num_res, | ||
| 514 | }, | ||
| 515 | }, | ||
| 509 | }, | 516 | }, |
| 510 | /* 8250-compatible uart */ | 517 | /* 8250-compatible uart */ |
| 511 | { | 518 | { |
| 512 | .hid = "HISI1031", | 519 | .hid = "HISI1031", |
| 513 | .name = "serial8250", | 520 | .pdevinfo = (struct platform_device_info []) { |
| 514 | .pdata = (struct plat_serial8250_port []) { | ||
| 515 | { | 521 | { |
| 516 | .iobase = res->start, | 522 | .parent = hostdev, |
| 517 | .uartclk = 1843200, | 523 | .fwnode = acpi_fwnode_handle(child), |
| 518 | .iotype = UPIO_PORT, | 524 | .name = "serial8250", |
| 519 | .flags = UPF_BOOT_AUTOCONF, | 525 | .id = PLATFORM_DEVID_AUTO, |
| 526 | .res = res, | ||
| 527 | .num_res = num_res, | ||
| 528 | .data = (struct plat_serial8250_port []) { | ||
| 529 | { | ||
| 530 | .iobase = res->start, | ||
| 531 | .uartclk = 1843200, | ||
| 532 | .iotype = UPIO_PORT, | ||
| 533 | .flags = UPF_BOOT_AUTOCONF, | ||
| 534 | }, | ||
| 535 | {} | ||
| 536 | }, | ||
| 537 | .size_data = 2 * sizeof(struct plat_serial8250_port), | ||
| 520 | }, | 538 | }, |
| 521 | {} | ||
| 522 | }, | 539 | }, |
| 523 | .pdata_size = 2 * | ||
| 524 | sizeof(struct plat_serial8250_port), | ||
| 525 | }, | 540 | }, |
| 526 | {} | 541 | {} |
| 527 | }; | 542 | }; |
| 528 | 543 | ||
| 529 | for (; cell && cell->name; cell++) { | 544 | for (; cell && cell->hid; cell++) { |
| 530 | if (!strcmp(cell->hid, hid)) { | 545 | if (!strcmp(cell->hid, hid)) { |
| 531 | found = true; | 546 | found = true; |
| 532 | break; | 547 | break; |
| @@ -540,31 +555,12 @@ static int hisi_lpc_acpi_add_child(struct acpi_device *child, void *data) · 7 unmodified lines | |||
| 540 | return 0; | 555 | return 0; |
| 541 | } | 556 | } |
| 542 | 557 | ||
| 543 | pdev = platform_device_alloc(cell->name, PLATFORM_DEVID_AUTO); | 558 | pdev = platform_device_register_full(cell->pdevinfo); |
| 544 | if (!pdev) | 559 | if (IS_ERR(pdev)) |
| 545 | return -ENOMEM; | 560 | return PTR_ERR(pdev); |
| 546 | |||
| 547 | pdev->dev.parent = hostdev; | ||
| 548 | ACPI_COMPANION_SET(&pdev->dev, child); | ||
| 549 | |||
| 550 | ret = platform_device_add_resources(pdev, res, num_res); | ||
| 551 | if (ret) | ||
| 552 | goto fail; | ||
| 553 | |||
| 554 | ret = platform_device_add_data(pdev, cell->pdata, cell->pdata_size); | ||
| 555 | if (ret) | ||
| 556 | goto fail; | ||
| 557 | |||
| 558 | ret = platform_device_add(pdev); | ||
| 559 | if (ret) | ||
| 560 | goto fail; | ||
| 561 | 561 | ||
| 562 | acpi_device_set_enumerated(child); | 562 | acpi_device_set_enumerated(child); |
| 563 | return 0; | 563 | return 0; |
| 564 | |||
| 565 | fail: | ||
| 566 | platform_device_put(pdev); | ||
| 567 | return ret; | ||
| 568 | } | 564 | } |
| 569 | 565 | ||
| 570 | /* | 566 | /* |
| @@ -589,11 +585,6 @@ static int hisi_lpc_acpi_probe(struct device *hostdev) · 18 unmodified lines | |||
| 589 | 585 | ||
| 590 | return ret; | 586 | return ret; |
| 591 | } | 587 | } |
| 592 | |||
| 593 | static const struct acpi_device_id hisi_lpc_acpi_match[] = { | ||
| 594 | {"HISI0191"}, | ||
| 595 | {} | ||
| 596 | }; | ||
| 597 | #else | 588 | #else |
| 598 | static int hisi_lpc_acpi_probe(struct device *dev) | 589 | static int hisi_lpc_acpi_probe(struct device *dev) |
| 599 | { | 590 | { |
| @@ -615,11 +606,9 @@ static void hisi_lpc_acpi_remove(struct device *hostdev) · 15 unmodified lines | |||
| 615 | static int hisi_lpc_probe(struct platform_device *pdev) | 606 | static int hisi_lpc_probe(struct platform_device *pdev) |
| 616 | { | 607 | { |
| 617 | struct device *dev = &pdev->dev; | 608 | struct device *dev = &pdev->dev; |
| 618 | struct acpi_device *acpi_device = ACPI_COMPANION(dev); | ||
| 619 | struct logic_pio_hwaddr *range; | 609 | struct logic_pio_hwaddr *range; |
| 620 | struct hisi_lpc_dev *lpcdev; | 610 | struct hisi_lpc_dev *lpcdev; |
| 621 | resource_size_t io_end; | 611 | resource_size_t io_end; |
| 622 | struct resource *res; | ||
| 623 | int ret; | 612 | int ret; |
| 624 | 613 | ||
| 625 | lpcdev = devm_kzalloc(dev, sizeof(*lpcdev), GFP_KERNEL); | 614 | lpcdev = devm_kzalloc(dev, sizeof(*lpcdev), GFP_KERNEL); |
| @@ -628,8 +617,7 @@ static int hisi_lpc_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 628 | 617 | ||
| 629 | spin_lock_init(&lpcdev->cycle_lock); | 618 | spin_lock_init(&lpcdev->cycle_lock); |
| 630 | 619 | ||
| 631 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 620 | lpcdev->membase = devm_platform_ioremap_resource(pdev, 0); |
| 632 | lpcdev->membase = devm_ioremap_resource(dev, res); | ||
| 633 | if (IS_ERR(lpcdev->membase)) | 621 | if (IS_ERR(lpcdev->membase)) |
| 634 | return PTR_ERR(lpcdev->membase); | 622 | return PTR_ERR(lpcdev->membase); |
| 635 | 623 | ||
| @@ -637,7 +625,7 @@ static int hisi_lpc_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 637 | if (!range) | 625 | if (!range) |
| 638 | return -ENOMEM; | 626 | return -ENOMEM; |
| 639 | 627 | ||
| 640 | range->fwnode = dev->fwnode; | 628 | range->fwnode = dev_fwnode(dev); |
| 641 | range->flags = LOGIC_PIO_INDIRECT; | 629 | range->flags = LOGIC_PIO_INDIRECT; |
| 642 | range->size = PIO_INDIRECT_SIZE; | 630 | range->size = PIO_INDIRECT_SIZE; |
| 643 | range->hostdata = lpcdev; | 631 | range->hostdata = lpcdev; |
| @@ -651,7 +639,7 @@ static int hisi_lpc_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 651 | } | 639 | } |
| 652 | 640 | ||
| 653 | /* register the LPC host PIO resources */ | 641 | /* register the LPC host PIO resources */ |
| 654 | if (acpi_device) | 642 | if (is_acpi_device_node(range->fwnode)) |
| 655 | ret = hisi_lpc_acpi_probe(dev); | 643 | ret = hisi_lpc_acpi_probe(dev); |
| 656 | else | 644 | else |
| 657 | ret = of_platform_populate(dev->of_node, NULL, NULL, dev); | 645 | ret = of_platform_populate(dev->of_node, NULL, NULL, dev); |
| @@ -672,11 +660,10 @@ static int hisi_lpc_probe(struct platform_device *pdev) · 14 unmodified lines | |||
| 672 | static int hisi_lpc_remove(struct platform_device *pdev) | 660 | static int hisi_lpc_remove(struct platform_device *pdev) |
| 673 | { | 661 | { |
| 674 | struct device *dev = &pdev->dev; | 662 | struct device *dev = &pdev->dev; |
| 675 | struct acpi_device *acpi_device = ACPI_COMPANION(dev); | ||
| 676 | struct hisi_lpc_dev *lpcdev = dev_get_drvdata(dev); | 663 | struct hisi_lpc_dev *lpcdev = dev_get_drvdata(dev); |
| 677 | struct logic_pio_hwaddr *range = lpcdev->io_host; | 664 | struct logic_pio_hwaddr *range = lpcdev->io_host; |
| 678 | 665 | ||
| 679 | if (acpi_device) | 666 | if (is_acpi_device_node(range->fwnode)) |
| 680 | hisi_lpc_acpi_remove(dev); | 667 | hisi_lpc_acpi_remove(dev); |
| 681 | else | 668 | else |
| 682 | of_platform_depopulate(dev); | 669 | of_platform_depopulate(dev); |
| @@ -692,11 +679,16 @@ static const struct of_device_id hisi_lpc_of_match[] = { · 9 unmodified lines | |||
| 692 | {} | 679 | {} |
| 693 | }; | 680 | }; |
| 694 | 681 | ||
| 682 | static const struct acpi_device_id hisi_lpc_acpi_match[] = { | ||
| 683 | {"HISI0191"}, | ||
| 684 | {} | ||
| 685 | }; | ||
| 686 | |||
| 695 | static struct platform_driver hisi_lpc_driver = { | 687 | static struct platform_driver hisi_lpc_driver = { |
| 696 | .driver = { | 688 | .driver = { |
| 697 | .name = DRV_NAME, | 689 | .name = DRV_NAME, |
| 698 | .of_match_table = hisi_lpc_of_match, | 690 | .of_match_table = hisi_lpc_of_match, |
| 699 | .acpi_match_table = ACPI_PTR(hisi_lpc_acpi_match), | 691 | .acpi_match_table = hisi_lpc_acpi_match, |
| 700 | }, | 692 | }, |
| 701 | .probe = hisi_lpc_probe, | 693 | .probe = hisi_lpc_probe, |
| 702 | .remove = hisi_lpc_remove, | 694 | .remove = hisi_lpc_remove, |
| @@ -124,10 +124,8 @@ static bool psci_pd_try_set_osi_mode(void) · 123 unmodified lines | |||
| 124 | return false; | 124 | return false; |
| 125 | 125 | ||
| 126 | ret = psci_set_osi_mode(true); | 126 | ret = psci_set_osi_mode(true); |
| 127 | if (ret) { | 127 | if (ret) |
| 128 | pr_warn("failed to enable OSI mode: %d\n", ret); | ||
| 129 | return false; | 128 | return false; |
| 130 | } | ||
| 131 | 129 | ||
| 132 | return true; | 130 | return true; |
| 133 | } | 131 | } |
| @@ -167,7 +167,8 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev) · 166 unmodified lines | |||
| 167 | return valid; | 167 | return valid; |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id) | 170 | struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id, |
| 171 | const struct ffa_ops *ops) | ||
| 171 | { | 172 | { |
| 172 | int ret; | 173 | int ret; |
| 173 | struct device *dev; | 174 | struct device *dev; |
| @@ -183,6 +184,7 @@ struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id) · 9 unmodified lines | |||
| 183 | dev_set_name(&ffa_dev->dev, "arm-ffa-%04x", vm_id); | 184 | dev_set_name(&ffa_dev->dev, "arm-ffa-%04x", vm_id); |
| 184 | 185 | ||
| 185 | ffa_dev->vm_id = vm_id; | 186 | ffa_dev->vm_id = vm_id; |
| 187 | ffa_dev->ops = ops; | ||
| 186 | uuid_copy(&ffa_dev->uuid, uuid); | 188 | uuid_copy(&ffa_dev->uuid, uuid); |
| 187 | 189 | ||
| 188 | ret = device_register(&ffa_dev->dev); | 190 | ret = device_register(&ffa_dev->dev); |
| @@ -163,6 +163,7 @@ struct ffa_drv_info { · 162 unmodified lines | |||
| 163 | struct mutex tx_lock; /* lock to protect Tx buffer */ | 163 | struct mutex tx_lock; /* lock to protect Tx buffer */ |
| 164 | void *rx_buffer; | 164 | void *rx_buffer; |
| 165 | void *tx_buffer; | 165 | void *tx_buffer; |
| 166 | bool mem_ops_native; | ||
| 166 | }; | 167 | }; |
| 167 | 168 | ||
| 168 | static struct ffa_drv_info *drv_info; | 169 | static struct ffa_drv_info *drv_info; |
| @@ -263,18 +264,24 @@ static int ffa_rxtx_unmap(u16 vm_id) · 94 unmodified lines | |||
| 263 | return 0; | 264 | return 0; |
| 264 | } | 265 | } |
| 265 | 266 | ||
| 267 | #define PARTITION_INFO_GET_RETURN_COUNT_ONLY BIT(0) | ||
| 268 | |||
| 266 | /* buffer must be sizeof(struct ffa_partition_info) * num_partitions */ | 269 | /* buffer must be sizeof(struct ffa_partition_info) * num_partitions */ |
| 267 | static int | 270 | static int |
| 268 | __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3, | 271 | __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3, |
| 269 | struct ffa_partition_info *buffer, int num_partitions) | 272 | struct ffa_partition_info *buffer, int num_partitions) |
| 270 | { | 273 | { |
| 271 | int count; | 274 | int idx, count, flags = 0, sz, buf_sz; |
| 272 | ffa_value_t partition_info; | 275 | ffa_value_t partition_info; |
| 273 | 276 | ||
| 277 | if (!buffer || !num_partitions) /* Just get the count for now */ | ||
| 278 | flags = PARTITION_INFO_GET_RETURN_COUNT_ONLY; | ||
| 279 | |||
| 274 | mutex_lock(&drv_info->rx_lock); | 280 | mutex_lock(&drv_info->rx_lock); |
| 275 | invoke_ffa_fn((ffa_value_t){ | 281 | invoke_ffa_fn((ffa_value_t){ |
| 276 | .a0 = FFA_PARTITION_INFO_GET, | 282 | .a0 = FFA_PARTITION_INFO_GET, |
| 277 | .a1 = uuid0, .a2 = uuid1, .a3 = uuid2, .a4 = uuid3, | 283 | .a1 = uuid0, .a2 = uuid1, .a3 = uuid2, .a4 = uuid3, |
| 284 | .a5 = flags, | ||
| 278 | }, &partition_info); | 285 | }, &partition_info); |
| 279 | 286 | ||
| 280 | if (partition_info.a0 == FFA_ERROR) { | 287 | if (partition_info.a0 == FFA_ERROR) { |
| @@ -284,8 +291,19 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3, · 3 unmodified lines | |||
| 284 | 291 | ||
| 285 | count = partition_info.a2; | 292 | count = partition_info.a2; |
| 286 | 293 | ||
| 294 | if (drv_info->version > FFA_VERSION_1_0) { | ||
| 295 | buf_sz = sz = partition_info.a3; | ||
| 296 | if (sz > sizeof(*buffer)) | ||
| 297 | buf_sz = sizeof(*buffer); | ||
| 298 | } else { | ||
| 299 | /* FFA_VERSION_1_0 lacks size in the response */ | ||
| 300 | buf_sz = sz = 8; | ||
| 301 | } | ||
| 302 | |||
| 287 | if (buffer && count <= num_partitions) | 303 | if (buffer && count <= num_partitions) |
| 288 | memcpy(buffer, drv_info->rx_buffer, sizeof(*buffer) * count); | 304 | for (idx = 0; idx < count; idx++) |
| 305 | memcpy(buffer + idx, drv_info->rx_buffer + idx * sz, | ||
| 306 | buf_sz); | ||
| 289 | 307 | ||
| 290 | ffa_rx_release(); | 308 | ffa_rx_release(); |
| 291 | 309 | ||
| @@ -571,6 +589,39 @@ static int ffa_memory_reclaim(u64 g_handle, u32 flags) · 279 unmodified lines | |||
| 571 | return 0; | 589 | return 0; |
| 572 | } | 590 | } |
| 573 | 591 | ||
| 592 | static int ffa_features(u32 func_feat_id, u32 input_props, | ||
| 593 | u32 *if_props_1, u32 *if_props_2) | ||
| 594 | { | ||
| 595 | ffa_value_t id; | ||
| 596 | |||
| 597 | if (!ARM_SMCCC_IS_FAST_CALL(func_feat_id) && input_props) { | ||
| 598 | pr_err("%s: Invalid Parameters: %x, %x", __func__, | ||
| 599 | func_feat_id, input_props); | ||
| 600 | return ffa_to_linux_errno(FFA_RET_INVALID_PARAMETERS); | ||
| 601 | } | ||
| 602 | |||
| 603 | invoke_ffa_fn((ffa_value_t){ | ||
| 604 | .a0 = FFA_FEATURES, .a1 = func_feat_id, .a2 = input_props, | ||
| 605 | }, &id); | ||
| 606 | |||
| 607 | if (id.a0 == FFA_ERROR) | ||
| 608 | return ffa_to_linux_errno((int)id.a2); | ||
| 609 | |||
| 610 | if (if_props_1) | ||
| 611 | *if_props_1 = id.a2; | ||
| 612 | if (if_props_2) | ||
| 613 | *if_props_2 = id.a3; | ||
| 614 | |||
| 615 | return 0; | ||
| 616 | } | ||
| 617 | |||
| 618 | static void ffa_set_up_mem_ops_native_flag(void) | ||
| 619 | { | ||
| 620 | if (!ffa_features(FFA_FN_NATIVE(MEM_LEND), 0, NULL, NULL) || | ||
| 621 | !ffa_features(FFA_FN_NATIVE(MEM_SHARE), 0, NULL, NULL)) | ||
| 622 | drv_info->mem_ops_native = true; | ||
| 623 | } | ||
| 624 | |||
| 574 | static u32 ffa_api_version_get(void) | 625 | static u32 ffa_api_version_get(void) |
| 575 | { | 626 | { |
| 576 | return drv_info->version; | 627 | return drv_info->version; |
| @@ -597,11 +648,19 @@ static int ffa_partition_info_get(const char *uuid_str, · 20 unmodified lines | |||
| 597 | return 0; | 648 | return 0; |
| 598 | } | 649 | } |
| 599 | 650 | ||
| 600 | static void ffa_mode_32bit_set(struct ffa_device *dev) | 651 | static void _ffa_mode_32bit_set(struct ffa_device *dev) |
| 601 | { | 652 | { |
| 602 | dev->mode_32bit = true; | 653 | dev->mode_32bit = true; |
| 603 | } | 654 | } |
| 604 | 655 | ||
| 656 | static void ffa_mode_32bit_set(struct ffa_device *dev) | ||
| 657 | { | ||
| 658 | if (drv_info->version > FFA_VERSION_1_0) | ||
| 659 | return; | ||
| 660 | |||
| 661 | _ffa_mode_32bit_set(dev); | ||
| 662 | } | ||
| 663 | |||
| 605 | static int ffa_sync_send_receive(struct ffa_device *dev, | 664 | static int ffa_sync_send_receive(struct ffa_device *dev, |
| 606 | struct ffa_send_direct_data *data) | 665 | struct ffa_send_direct_data *data) |
| 607 | { | 666 | { |
| @@ -609,17 +668,15 @@ static int ffa_sync_send_receive(struct ffa_device *dev, · 1 unmodified line | |||
| 609 | dev->mode_32bit, data); | 668 | dev->mode_32bit, data); |
| 610 | } | 669 | } |
| 611 | 670 | ||
| 612 | static int | 671 | static int ffa_memory_share(struct ffa_mem_ops_args *args) |
| 613 | ffa_memory_share(struct ffa_device *dev, struct ffa_mem_ops_args *args) | ||
| 614 | { | 672 | { |
| 615 | if (dev->mode_32bit) | 673 | if (drv_info->mem_ops_native) |
| 616 | return ffa_memory_ops(FFA_MEM_SHARE, args); | 674 | return ffa_memory_ops(FFA_FN_NATIVE(MEM_SHARE), args); |
| 617 | 675 | ||
| 618 | return ffa_memory_ops(FFA_FN_NATIVE(MEM_SHARE), args); | 676 | return ffa_memory_ops(FFA_MEM_SHARE, args); |
| 619 | } | 677 | } |
| 620 | 678 | ||
| 621 | static int | 679 | static int ffa_memory_lend(struct ffa_mem_ops_args *args) |
| 622 | ffa_memory_lend(struct ffa_device *dev, struct ffa_mem_ops_args *args) | ||
| 623 | { | 680 | { |
| 624 | /* Note that upon a successful MEM_LEND request the caller | 681 | /* Note that upon a successful MEM_LEND request the caller |
| 625 | * must ensure that the memory region specified is not accessed | 682 | * 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) · 2 unmodified lines | |||
| 628 | * however on systems without a hypervisor the responsibility | 685 | * however on systems without a hypervisor the responsibility |
| 629 | * falls to the calling kernel driver to prevent access. | 686 | * falls to the calling kernel driver to prevent access. |
| 630 | */ | 687 | */ |
| 631 | if (dev->mode_32bit) | 688 | if (drv_info->mem_ops_native) |
| 632 | return ffa_memory_ops(FFA_MEM_LEND, args); | 689 | return ffa_memory_ops(FFA_FN_NATIVE(MEM_LEND), args); |
| 633 | 690 | ||
| 634 | return ffa_memory_ops(FFA_FN_NATIVE(MEM_LEND), args); | 691 | return ffa_memory_ops(FFA_MEM_LEND, args); |
| 635 | } | 692 | } |
| 636 | 693 | ||
| 637 | static const struct ffa_dev_ops ffa_ops = { | 694 | static const struct ffa_info_ops ffa_drv_info_ops = { |
| 638 | .api_version_get = ffa_api_version_get, | 695 | .api_version_get = ffa_api_version_get, |
| 639 | .partition_info_get = ffa_partition_info_get, | 696 | .partition_info_get = ffa_partition_info_get, |
| 697 | }; | ||
| 698 | |||
| 699 | static const struct ffa_msg_ops ffa_drv_msg_ops = { | ||
| 640 | .mode_32bit_set = ffa_mode_32bit_set, | 700 | .mode_32bit_set = ffa_mode_32bit_set, |
| 641 | .sync_send_receive = ffa_sync_send_receive, | 701 | .sync_send_receive = ffa_sync_send_receive, |
| 702 | }; | ||
| 703 | |||
| 704 | static const struct ffa_mem_ops ffa_drv_mem_ops = { | ||
| 642 | .memory_reclaim = ffa_memory_reclaim, | 705 | .memory_reclaim = ffa_memory_reclaim, |
| 643 | .memory_share = ffa_memory_share, | 706 | .memory_share = ffa_memory_share, |
| 644 | .memory_lend = ffa_memory_lend, | 707 | .memory_lend = ffa_memory_lend, |
| 645 | }; | 708 | }; |
| 646 | 709 | ||
| 647 | const struct ffa_dev_ops *ffa_dev_ops_get(struct ffa_device *dev) | 710 | static const struct ffa_ops ffa_drv_ops = { |
| 648 | { | 711 | .info_ops = &ffa_drv_info_ops, |
| 649 | if (ffa_device_is_valid(dev)) | 712 | .msg_ops = &ffa_drv_msg_ops, |
| 650 | return &ffa_ops; | 713 | .mem_ops = &ffa_drv_mem_ops, |
| 651 | 714 | }; | |
| 652 | return NULL; | ||
| 653 | } | ||
| 654 | EXPORT_SYMBOL_GPL(ffa_dev_ops_get); | ||
| 655 | 715 | ||
| 656 | void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid) | 716 | void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid) |
| 657 | { | 717 | { |
| 658 | int count, idx; | 718 | int count, idx; |
| 659 | struct ffa_partition_info *pbuf, *tpbuf; | 719 | struct ffa_partition_info *pbuf, *tpbuf; |
| 660 | 720 | ||
| 721 | /* | ||
| 722 | * FF-A v1.1 provides UUID for each partition as part of the discovery | ||
| 723 | * API, the discovered UUID must be populated in the device's UUID and | ||
| 724 | * there is no need to copy the same from the driver table. | ||
| 725 | */ | ||
| 726 | if (drv_info->version > FFA_VERSION_1_0) | ||
| 727 | return; | ||
| 728 | |||
| 661 | count = ffa_partition_probe(uuid, &pbuf); | 729 | count = ffa_partition_probe(uuid, &pbuf); |
| 662 | if (count <= 0) | 730 | if (count <= 0) |
| 663 | return; | 731 | return; |
| @@ -671,6 +739,7 @@ void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid) · 7 unmodified lines | |||
| 671 | static void ffa_setup_partitions(void) | 739 | static void ffa_setup_partitions(void) |
| 672 | { | 740 | { |
| 673 | int count, idx; | 741 | int count, idx; |
| 742 | uuid_t uuid; | ||
| 674 | struct ffa_device *ffa_dev; | 743 | struct ffa_device *ffa_dev; |
| 675 | struct ffa_partition_info *pbuf, *tpbuf; | 744 | struct ffa_partition_info *pbuf, *tpbuf; |
| 676 | 745 | ||
| @@ -681,19 +750,24 @@ static void ffa_setup_partitions(void) · 4 unmodified lines | |||
| 681 | } | 750 | } |
| 682 | 751 | ||
| 683 | for (idx = 0, tpbuf = pbuf; idx < count; idx++, tpbuf++) { | 752 | for (idx = 0, tpbuf = pbuf; idx < count; idx++, tpbuf++) { |
| 684 | /* Note that the &uuid_null parameter will require | 753 | import_uuid(&uuid, (u8 *)tpbuf->uuid); |
| 754 | |||
| 755 | /* Note that if the UUID will be uuid_null, that will require | ||
| 685 | * ffa_device_match() to find the UUID of this partition id | 756 | * ffa_device_match() to find the UUID of this partition id |
| 686 | * with help of ffa_device_match_uuid(). Once the FF-A spec | 757 | * with help of ffa_device_match_uuid(). FF-A v1.1 and above |
| 687 | * is updated to provide correct UUID here for each partition | 758 | * provides UUID here for each partition as part of the |
| 688 | * as part of the discovery API, we need to pass the | 759 | * discovery API and the same is passed. |
| 689 | * discovered UUID here instead. | ||
| 690 | */ | 760 | */ |
| 691 | ffa_dev = ffa_device_register(&uuid_null, tpbuf->id); | 761 | ffa_dev = ffa_device_register(&uuid, tpbuf->id, &ffa_drv_ops); |
| 692 | if (!ffa_dev) { | 762 | if (!ffa_dev) { |
| 693 | pr_err("%s: failed to register partition ID 0x%x\n", | 763 | pr_err("%s: failed to register partition ID 0x%x\n", |
| 694 | __func__, tpbuf->id); | 764 | __func__, tpbuf->id); |
| 695 | continue; | 765 | continue; |
| 696 | } | 766 | } |
| 767 | |||
| 768 | if (drv_info->version > FFA_VERSION_1_0 && | ||
| 769 | !(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC)) | ||
| 770 | _ffa_mode_32bit_set(ffa_dev); | ||
| 697 | } | 771 | } |
| 698 | kfree(pbuf); | 772 | kfree(pbuf); |
| 699 | } | 773 | } |
| @@ -751,6 +825,8 @@ static int __init ffa_init(void) · 51 unmodified lines | |||
| 751 | 825 | ||
| 752 | ffa_setup_partitions(); | 826 | ffa_setup_partitions(); |
| 753 | 827 | ||
| 828 | ffa_set_up_mem_ops_native_flag(); | ||
| 829 | |||
| 754 | return 0; | 830 | return 0; |
| 755 | free_pages: | 831 | free_pages: |
| 756 | if (drv_info->tx_buffer) | 832 | if (drv_info->tx_buffer) |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | #include <linux/acpi.h> | 9 | #include <linux/acpi.h> |
| 10 | #include <linux/arm-smccc.h> | 10 | #include <linux/arm-smccc.h> |
| 11 | #include <linux/cpuidle.h> | 11 | #include <linux/cpuidle.h> |
| 12 | #include <linux/debugfs.h> | ||
| 12 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
| 13 | #include <linux/linkage.h> | 14 | #include <linux/linkage.h> |
| 14 | #include <linux/of.h> | 15 | #include <linux/of.h> |
| @@ -163,6 +164,8 @@ int psci_set_osi_mode(bool enable) · 148 unmodified lines | |||
| 163 | PSCI_1_0_SUSPEND_MODE_PC; | 164 | PSCI_1_0_SUSPEND_MODE_PC; |
| 164 | 165 | ||
| 165 | err = invoke_psci_fn(PSCI_1_0_FN_SET_SUSPEND_MODE, suspend_mode, 0, 0); | 166 | err = invoke_psci_fn(PSCI_1_0_FN_SET_SUSPEND_MODE, suspend_mode, 0, 0); |
| 167 | if (err < 0) | ||
| 168 | pr_warn("failed to set %s mode: %d\n", enable ? "OSI" : "PC", err); | ||
| 166 | return psci_to_linux_errno(err); | 169 | return psci_to_linux_errno(err); |
| 167 | } | 170 | } |
| 168 | 171 | ||
| @@ -324,12 +327,125 @@ static void psci_sys_poweroff(void) · 155 unmodified lines | |||
| 324 | invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0); | 327 | invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0); |
| 325 | } | 328 | } |
| 326 | 329 | ||
| 327 | static int __init psci_features(u32 psci_func_id) | 330 | static int psci_features(u32 psci_func_id) |
| 328 | { | 331 | { |
| 329 | return invoke_psci_fn(PSCI_1_0_FN_PSCI_FEATURES, | 332 | return invoke_psci_fn(PSCI_1_0_FN_PSCI_FEATURES, |
| 330 | psci_func_id, 0, 0); | 333 | psci_func_id, 0, 0); |
| 331 | } | 334 | } |
| 332 | 335 | ||
| 336 | #ifdef CONFIG_DEBUG_FS | ||
| 337 | |||
| 338 | #define PSCI_ID(ver, _name) \ | ||
| 339 | { .fn = PSCI_##ver##_FN_##_name, .name = #_name, } | ||
| 340 | #define PSCI_ID_NATIVE(ver, _name) \ | ||
| 341 | { .fn = PSCI_FN_NATIVE(ver, _name), .name = #_name, } | ||
| 342 | |||
| 343 | /* A table of all optional functions */ | ||
| 344 | static const struct { | ||
| 345 | u32 fn; | ||
| 346 | const char *name; | ||
| 347 | } psci_fn_ids[] = { | ||
| 348 | PSCI_ID_NATIVE(0_2, MIGRATE), | ||
| 349 | PSCI_ID(0_2, MIGRATE_INFO_TYPE), | ||
| 350 | PSCI_ID_NATIVE(0_2, MIGRATE_INFO_UP_CPU), | ||
| 351 | PSCI_ID(1_0, CPU_FREEZE), | ||
| 352 | PSCI_ID_NATIVE(1_0, CPU_DEFAULT_SUSPEND), | ||
| 353 | PSCI_ID_NATIVE(1_0, NODE_HW_STATE), | ||
| 354 | PSCI_ID_NATIVE(1_0, SYSTEM_SUSPEND), | ||
| 355 | PSCI_ID(1_0, SET_SUSPEND_MODE), | ||
| 356 | PSCI_ID_NATIVE(1_0, STAT_RESIDENCY), | ||
| 357 | PSCI_ID_NATIVE(1_0, STAT_COUNT), | ||
| 358 | PSCI_ID_NATIVE(1_1, SYSTEM_RESET2), | ||
| 359 | PSCI_ID(1_1, MEM_PROTECT), | ||
| 360 | PSCI_ID_NATIVE(1_1, MEM_PROTECT_CHECK_RANGE), | ||
| 361 | }; | ||
| 362 | |||
| 363 | static int psci_debugfs_read(struct seq_file *s, void *data) | ||
| 364 | { | ||
| 365 | int feature, type, i; | ||
| 366 | u32 ver; | ||
| 367 | |||
| 368 | ver = psci_ops.get_version(); | ||
| 369 | seq_printf(s, "PSCIv%d.%d\n", | ||
| 370 | PSCI_VERSION_MAJOR(ver), | ||
| 371 | PSCI_VERSION_MINOR(ver)); | ||
| 372 | |||
| 373 | /* PSCI_FEATURES is available only starting from 1.0 */ | ||
| 374 | if (PSCI_VERSION_MAJOR(ver) < 1) | ||
| 375 | return 0; | ||
| 376 | |||
| 377 | feature = psci_features(ARM_SMCCC_VERSION_FUNC_ID); | ||
| 378 | if (feature != PSCI_RET_NOT_SUPPORTED) { | ||
| 379 | ver = invoke_psci_fn(ARM_SMCCC_VERSION_FUNC_ID, 0, 0, 0); | ||
| 380 | seq_printf(s, "SMC Calling Convention v%d.%d\n", | ||
| 381 | PSCI_VERSION_MAJOR(ver), | ||
| 382 | PSCI_VERSION_MINOR(ver)); | ||
| 383 | } else { | ||
| 384 | seq_puts(s, "SMC Calling Convention v1.0 is assumed\n"); | ||
| 385 | } | ||
| 386 | |||
| 387 | feature = psci_features(PSCI_FN_NATIVE(0_2, CPU_SUSPEND)); | ||
| 388 | if (feature < 0) { | ||
| 389 | seq_printf(s, "PSCI_FEATURES(CPU_SUSPEND) error (%d)\n", feature); | ||
| 390 | } else { | ||
| 391 | seq_printf(s, "OSI is %ssupported\n", | ||
| 392 | (feature & BIT(0)) ? "" : "not "); | ||
| 393 | seq_printf(s, "%s StateID format is used\n", | ||
| 394 | (feature & BIT(1)) ? "Extended" : "Original"); | ||
| 395 | } | ||
| 396 | |||
| 397 | type = psci_ops.migrate_info_type(); | ||
| 398 | if (type == PSCI_0_2_TOS_UP_MIGRATE || | ||
| 399 | type == PSCI_0_2_TOS_UP_NO_MIGRATE) { | ||
| 400 | unsigned long cpuid; | ||
| 401 | |||
| 402 | seq_printf(s, "Trusted OS %smigrate capable\n", | ||
| 403 | type == PSCI_0_2_TOS_UP_NO_MIGRATE ? "not " : ""); | ||
| 404 | cpuid = psci_migrate_info_up_cpu(); | ||
| 405 | seq_printf(s, "Trusted OS resident on physical CPU 0x%lx (#%d)\n", | ||
| 406 | cpuid, resident_cpu); | ||
| 407 | } else if (type == PSCI_0_2_TOS_MP) { | ||
| 408 | seq_puts(s, "Trusted OS migration not required\n"); | ||
| 409 | } else { | ||
| 410 | if (type != PSCI_RET_NOT_SUPPORTED) | ||
| 411 | seq_printf(s, "MIGRATE_INFO_TYPE returned unknown type (%d)\n", type); | ||
| 412 | } | ||
| 413 | |||
| 414 | for (i = 0; i < ARRAY_SIZE(psci_fn_ids); i++) { | ||
| 415 | feature = psci_features(psci_fn_ids[i].fn); | ||
| 416 | if (feature == PSCI_RET_NOT_SUPPORTED) | ||
| 417 | continue; | ||
| 418 | if (feature < 0) | ||
| 419 | seq_printf(s, "PSCI_FEATURES(%s) error (%d)\n", | ||
| 420 | psci_fn_ids[i].name, feature); | ||
| 421 | else | ||
| 422 | seq_printf(s, "%s is supported\n", psci_fn_ids[i].name); | ||
| 423 | } | ||
| 424 | |||
| 425 | return 0; | ||
| 426 | } | ||
| 427 | |||
| 428 | static int psci_debugfs_open(struct inode *inode, struct file *f) | ||
| 429 | { | ||
| 430 | return single_open(f, psci_debugfs_read, NULL); | ||
| 431 | } | ||
| 432 | |||
| 433 | static const struct file_operations psci_debugfs_ops = { | ||
| 434 | .owner = THIS_MODULE, | ||
| 435 | .open = psci_debugfs_open, | ||
| 436 | .release = single_release, | ||
| 437 | .read = seq_read, | ||
| 438 | .llseek = seq_lseek | ||
| 439 | }; | ||
| 440 | |||
| 441 | static int __init psci_debugfs_init(void) | ||
| 442 | { | ||
| 443 | return PTR_ERR_OR_ZERO(debugfs_create_file("psci", 0444, NULL, NULL, | ||
| 444 | &psci_debugfs_ops)); | ||
| 445 | } | ||
| 446 | late_initcall(psci_debugfs_init) | ||
| 447 | #endif | ||
| 448 | |||
| 333 | #ifdef CONFIG_CPU_IDLE | 449 | #ifdef CONFIG_CPU_IDLE |
| 334 | static int psci_suspend_finisher(unsigned long state) | 450 | static int psci_suspend_finisher(unsigned long state) |
| 335 | { | 451 | { |
| @@ -129,8 +129,6 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, · 128 unmodified lines | |||
| 129 | #define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03 | 129 | #define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03 |
| 130 | #define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02 | 130 | #define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02 |
| 131 | 131 | ||
| 132 | extern void __qcom_scm_init(void); | ||
| 133 | |||
| 134 | /* common error codes */ | 132 | /* common error codes */ |
| 135 | #define QCOM_SCM_V2_EBUSY -12 | 133 | #define QCOM_SCM_V2_EBUSY -12 |
| 136 | #define QCOM_SCM_ENOMEM -5 | 134 | #define QCOM_SCM_ENOMEM -5 |
| @@ -377,18 +377,11 @@ static ssize_t bpmp_debug_store(struct file *file, const char __user *buf, · 376 unmodified lines | |||
| 377 | if (!filename) | 377 | if (!filename) |
| 378 | return -ENOENT; | 378 | return -ENOENT; |
| 379 | 379 | ||
| 380 | databuf = kmalloc(count, GFP_KERNEL); | 380 | databuf = memdup_user(buf, count); |
| 381 | if (!databuf) | 381 | if (IS_ERR(databuf)) |
| 382 | return -ENOMEM; | 382 | return PTR_ERR(databuf); |
| 383 | |||
| 384 | if (copy_from_user(databuf, buf, count)) { | ||
| 385 | err = -EFAULT; | ||
| 386 | goto free_ret; | ||
| 387 | } | ||
| 388 | 383 | ||
| 389 | err = mrq_debug_write(bpmp, filename, databuf, count); | 384 | err = mrq_debug_write(bpmp, filename, databuf, count); |
| 390 | |||
| 391 | free_ret: | ||
| 392 | kfree(databuf); | 385 | kfree(databuf); |
| 393 | 386 | ||
| 394 | return err ?: count; | 387 | return err ?: count; |
| @@ -488,8 +488,8 @@ config I2C_BCM_KONA · 487 unmodified lines | |||
| 488 | 488 | ||
| 489 | config I2C_BRCMSTB | 489 | config I2C_BRCMSTB |
| 490 | tristate "BRCM Settop/DSL I2C controller" | 490 | tristate "BRCM Settop/DSL I2C controller" |
| 491 | depends on ARCH_BCM2835 || ARCH_BCM4908 || ARCH_BCMBCA || \ | 491 | depends on ARCH_BCM2835 || ARCH_BCMBCA || ARCH_BRCMSTB || \ |
| 492 | ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST | 492 | BMIPS_GENERIC || COMPILE_TEST |
| 493 | default y | 493 | default y |
| 494 | help | 494 | help |
| 495 | If you say yes to this option, support will be included for the | 495 | If you say yes to this option, support will be included for the |
| @@ -66,6 +66,15 @@ config BRCMSTB_DPFE · 65 unmodified lines | |||
| 66 | for the DRAM's temperature. Slower refresh rate means cooler RAM, | 66 | for the DRAM's temperature. Slower refresh rate means cooler RAM, |
| 67 | higher refresh rate means hotter RAM. | 67 | higher refresh rate means hotter RAM. |
| 68 | 68 | ||
| 69 | config BRCMSTB_MEMC | ||
| 70 | tristate "Broadcom STB MEMC driver" | ||
| 71 | default ARCH_BRCMSTB | ||
| 72 | depends on ARCH_BRCMSTB || COMPILE_TEST | ||
| 73 | help | ||
| 74 | This driver provides a way to configure the Broadcom STB memory | ||
| 75 | controller and specifically control the Self Refresh Power Down | ||
| 76 | (SRPD) inactivity timeout. | ||
| 77 | |||
| 69 | config BT1_L2_CTL | 78 | config BT1_L2_CTL |
| 70 | bool "Baikal-T1 CM2 L2-RAM Cache Control Block" | 79 | bool "Baikal-T1 CM2 L2-RAM Cache Control Block" |
| 71 | depends on MIPS_BAIKAL_T1 || COMPILE_TEST | 80 | depends on MIPS_BAIKAL_T1 || COMPILE_TEST |
| @@ -11,6 +11,7 @@ obj-$(CONFIG_ARM_PL172_MPMC) += pl172.o · 10 unmodified lines | |||
| 11 | obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o | 11 | obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o |
| 12 | obj-$(CONFIG_ATMEL_EBI) += atmel-ebi.o | 12 | obj-$(CONFIG_ATMEL_EBI) += atmel-ebi.o |
| 13 | obj-$(CONFIG_BRCMSTB_DPFE) += brcmstb_dpfe.o | 13 | obj-$(CONFIG_BRCMSTB_DPFE) += brcmstb_dpfe.o |
| 14 | obj-$(CONFIG_BRCMSTB_MEMC) += brcmstb_memc.o | ||
| 14 | obj-$(CONFIG_BT1_L2_CTL) += bt1-l2-ctl.o | 15 | obj-$(CONFIG_BT1_L2_CTL) += bt1-l2-ctl.o |
| 15 | obj-$(CONFIG_TI_AEMIF) += ti-aemif.o | 16 | obj-$(CONFIG_TI_AEMIF) += ti-aemif.o |
| 16 | obj-$(CONFIG_TI_EMIF) += emif.o | 17 | obj-$(CONFIG_TI_EMIF) += emif.o |
| @@ -0,0 +1,301 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * DDR Self-Refresh Power Down (SRPD) support for Broadcom STB SoCs | ||
| 4 | * | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/init.h> | ||
| 8 | #include <linux/io.h> | ||
| 9 | #include <linux/kernel.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/of_device.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | |||
| 14 | #define REG_MEMC_CNTRLR_CONFIG 0x00 | ||
| 15 | #define CNTRLR_CONFIG_LPDDR4_SHIFT 5 | ||
| 16 | #define CNTRLR_CONFIG_MASK 0xf | ||
| 17 | #define REG_MEMC_SRPD_CFG_21 0x20 | ||
| 18 | #define REG_MEMC_SRPD_CFG_20 0x34 | ||
| 19 | #define REG_MEMC_SRPD_CFG_1x 0x3c | ||
| 20 | #define INACT_COUNT_SHIFT 0 | ||
| 21 | #define INACT_COUNT_MASK 0xffff | ||
| 22 | #define SRPD_EN_SHIFT 16 | ||
| 23 | |||
| 24 | struct brcmstb_memc_data { | ||
| 25 | u32 srpd_offset; | ||
| 26 | }; | ||
| 27 | |||
| 28 | struct brcmstb_memc { | ||
| 29 | struct device *dev; | ||
| 30 | void __iomem *ddr_ctrl; | ||
| 31 | unsigned int timeout_cycles; | ||
| 32 | u32 frequency; | ||
| 33 | u32 srpd_offset; | ||
| 34 | }; | ||
| 35 | |||
| 36 | static int brcmstb_memc_uses_lpddr4(struct brcmstb_memc *memc) | ||
| 37 | { | ||
| 38 | void __iomem *config = memc->ddr_ctrl + REG_MEMC_CNTRLR_CONFIG; | ||
| 39 | u32 reg; | ||
| 40 | |||
| 41 | reg = readl_relaxed(config) & CNTRLR_CONFIG_MASK; | ||
| 42 | |||
| 43 | return reg == CNTRLR_CONFIG_LPDDR4_SHIFT; | ||
| 44 | } | ||
| 45 | |||
| 46 | static int brcmstb_memc_srpd_config(struct brcmstb_memc *memc, | ||
| 47 | unsigned int cycles) | ||
| 48 | { | ||
| 49 | void __iomem *cfg = memc->ddr_ctrl + memc->srpd_offset; | ||
| 50 | u32 val; | ||
| 51 | |||
| 52 | /* Max timeout supported in HW */ | ||
| 53 | if (cycles > INACT_COUNT_MASK) | ||
| 54 | return -EINVAL; | ||
| 55 | |||
| 56 | memc->timeout_cycles = cycles; | ||
| 57 | |||
| 58 | val = (cycles << INACT_COUNT_SHIFT) & INACT_COUNT_MASK; | ||
| 59 | if (cycles) | ||
| 60 | val |= BIT(SRPD_EN_SHIFT); | ||
| 61 | |||
| 62 | writel_relaxed(val, cfg); | ||
| 63 | /* Ensure the write is committed to the controller */ | ||
| 64 | (void)readl_relaxed(cfg); | ||
| 65 | |||
| 66 | return 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | static ssize_t frequency_show(struct device *dev, | ||
| 70 | struct device_attribute *attr, char *buf) | ||
| 71 | { | ||
| 72 | struct brcmstb_memc *memc = dev_get_drvdata(dev); | ||
| 73 | |||
| 74 | return sprintf(buf, "%d\n", memc->frequency); | ||
| 75 | } | ||
| 76 | |||
| 77 | static ssize_t srpd_show(struct device *dev, | ||
| 78 | struct device_attribute *attr, char *buf) | ||
| 79 | { | ||
| 80 | struct brcmstb_memc *memc = dev_get_drvdata(dev); | ||
| 81 | |||
| 82 | return sprintf(buf, "%d\n", memc->timeout_cycles); | ||
| 83 | } | ||
| 84 | |||
| 85 | static ssize_t srpd_store(struct device *dev, struct device_attribute *attr, | ||
| 86 | const char *buf, size_t count) | ||
| 87 | { | ||
| 88 | struct brcmstb_memc *memc = dev_get_drvdata(dev); | ||
| 89 | unsigned int val; | ||
| 90 | int ret; | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Cannot change the inactivity timeout on LPDDR4 chips because the | ||
| 94 | * dynamic tuning process will also get affected by the inactivity | ||
| 95 | * timeout, thus making it non functional. | ||
| 96 | */ | ||
| 97 | if (brcmstb_memc_uses_lpddr4(memc)) | ||
| 98 | return -EOPNOTSUPP; | ||
| 99 | |||
| 100 | ret = kstrtouint(buf, 10, &val); | ||
| 101 | if (ret < 0) | ||
| 102 | return ret; | ||
| 103 | |||
| 104 | ret = brcmstb_memc_srpd_config(memc, val); | ||
| 105 | if (ret) | ||
| 106 | return ret; | ||
| 107 | |||
| 108 | return count; | ||
| 109 | } | ||
| 110 | |||
| 111 | static DEVICE_ATTR_RO(frequency); | ||
| 112 | static DEVICE_ATTR_RW(srpd); | ||
| 113 | |||
| 114 | static struct attribute *dev_attrs[] = { | ||
| 115 | &dev_attr_frequency.attr, | ||
| 116 | &dev_attr_srpd.attr, | ||
| 117 | NULL, | ||
| 118 | }; | ||
| 119 | |||
| 120 | static struct attribute_group dev_attr_group = { | ||
| 121 | .attrs = dev_attrs, | ||
| 122 | }; | ||
| 123 | |||
| 124 | static const struct of_device_id brcmstb_memc_of_match[]; | ||
| 125 | |||
| 126 | static int brcmstb_memc_probe(struct platform_device *pdev) | ||
| 127 | { | ||
| 128 | const struct brcmstb_memc_data *memc_data; | ||
| 129 | const struct of_device_id *of_id; | ||
| 130 | struct device *dev = &pdev->dev; | ||
| 131 | struct brcmstb_memc *memc; | ||
| 132 | int ret; | ||
| 133 | |||
| 134 | memc = devm_kzalloc(dev, sizeof(*memc), GFP_KERNEL); | ||
| 135 | if (!memc) | ||
| 136 | return -ENOMEM; | ||
| 137 | |||
| 138 | dev_set_drvdata(dev, memc); | ||
| 139 | |||
| 140 | of_id = of_match_device(brcmstb_memc_of_match, dev); | ||
| 141 | memc_data = of_id->data; | ||
| 142 | memc->srpd_offset = memc_data->srpd_offset; | ||
| 143 | |||
| 144 | memc->ddr_ctrl = devm_platform_ioremap_resource(pdev, 0); | ||
| 145 | if (IS_ERR(memc->ddr_ctrl)) | ||
| 146 | return PTR_ERR(memc->ddr_ctrl); | ||
| 147 | |||
| 148 | of_property_read_u32(pdev->dev.of_node, "clock-frequency", | ||
| 149 | &memc->frequency); | ||
| 150 | |||
| 151 | ret = sysfs_create_group(&dev->kobj, &dev_attr_group); | ||
| 152 | if (ret) | ||
| 153 | return ret; | ||
| 154 | |||
| 155 | return 0; | ||
| 156 | } | ||
| 157 | |||
| 158 | static int brcmstb_memc_remove(struct platform_device *pdev) | ||
| 159 | { | ||
| 160 | struct device *dev = &pdev->dev; | ||
| 161 | |||
| 162 | sysfs_remove_group(&dev->kobj, &dev_attr_group); | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | enum brcmstb_memc_hwtype { | ||
| 168 | BRCMSTB_MEMC_V21, | ||
| 169 | BRCMSTB_MEMC_V20, | ||
| 170 | BRCMSTB_MEMC_V1X, | ||
| 171 | }; | ||
| 172 | |||
| 173 | static const struct brcmstb_memc_data brcmstb_memc_versions[] = { | ||
| 174 | { .srpd_offset = REG_MEMC_SRPD_CFG_21 }, | ||
| 175 | { .srpd_offset = REG_MEMC_SRPD_CFG_20 }, | ||
| 176 | { .srpd_offset = REG_MEMC_SRPD_CFG_1x }, | ||
| 177 | }; | ||
| 178 | |||
| 179 | static const struct of_device_id brcmstb_memc_of_match[] = { | ||
| 180 | { | ||
| 181 | .compatible = "brcm,brcmstb-memc-ddr-rev-b.1.x", | ||
| 182 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V1X] | ||
| 183 | }, | ||
| 184 | { | ||
| 185 | .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.0", | ||
| 186 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V20] | ||
| 187 | }, | ||
| 188 | { | ||
| 189 | .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.1", | ||
| 190 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 191 | }, | ||
| 192 | { | ||
| 193 | .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.2", | ||
| 194 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 195 | }, | ||
| 196 | { | ||
| 197 | .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.3", | ||
| 198 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 199 | }, | ||
| 200 | { | ||
| 201 | .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.5", | ||
| 202 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 203 | }, | ||
| 204 | { | ||
| 205 | .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.6", | ||
| 206 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 207 | }, | ||
| 208 | { | ||
| 209 | .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.7", | ||
| 210 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 211 | }, | ||
| 212 | { | ||
| 213 | .compatible = "brcm,brcmstb-memc-ddr-rev-b.2.8", | ||
| 214 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 215 | }, | ||
| 216 | { | ||
| 217 | .compatible = "brcm,brcmstb-memc-ddr-rev-b.3.0", | ||
| 218 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 219 | }, | ||
| 220 | { | ||
| 221 | .compatible = "brcm,brcmstb-memc-ddr-rev-b.3.1", | ||
| 222 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 223 | }, | ||
| 224 | { | ||
| 225 | .compatible = "brcm,brcmstb-memc-ddr-rev-c.1.0", | ||
| 226 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 227 | }, | ||
| 228 | { | ||
| 229 | .compatible = "brcm,brcmstb-memc-ddr-rev-c.1.1", | ||
| 230 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 231 | }, | ||
| 232 | { | ||
| 233 | .compatible = "brcm,brcmstb-memc-ddr-rev-c.1.2", | ||
| 234 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 235 | }, | ||
| 236 | { | ||
| 237 | .compatible = "brcm,brcmstb-memc-ddr-rev-c.1.3", | ||
| 238 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 239 | }, | ||
| 240 | { | ||
| 241 | .compatible = "brcm,brcmstb-memc-ddr-rev-c.1.4", | ||
| 242 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V21] | ||
| 243 | }, | ||
| 244 | /* default to the original offset */ | ||
| 245 | { | ||
| 246 | .compatible = "brcm,brcmstb-memc-ddr", | ||
| 247 | .data = &brcmstb_memc_versions[BRCMSTB_MEMC_V1X] | ||
| 248 | }, | ||
| 249 | {} | ||
| 250 | }; | ||
| 251 | |||
| 252 | static int brcmstb_memc_suspend(struct device *dev) | ||
| 253 | { | ||
| 254 | struct brcmstb_memc *memc = dev_get_drvdata(dev); | ||
| 255 | void __iomem *cfg = memc->ddr_ctrl + memc->srpd_offset; | ||
| 256 | u32 val; | ||
| 257 | |||
| 258 | if (memc->timeout_cycles == 0) | ||
| 259 | return 0; | ||
| 260 | |||
| 261 | /* | ||
| 262 | * Disable SRPD prior to suspending the system since that can | ||
| 263 | * cause issues with other memory clients managed by the ARM | ||
| 264 | * trusted firmware to access memory. | ||
| 265 | */ | ||
| 266 | val = readl_relaxed(cfg); | ||
| 267 | val &= ~BIT(SRPD_EN_SHIFT); | ||
| 268 | writel_relaxed(val, cfg); | ||
| 269 | /* Ensure the write is committed to the controller */ | ||
| 270 | (void)readl_relaxed(cfg); | ||
| 271 | |||
| 272 | return 0; | ||
| 273 | } | ||
| 274 | |||
| 275 | static int brcmstb_memc_resume(struct device *dev) | ||
| 276 | { | ||
| 277 | struct brcmstb_memc *memc = dev_get_drvdata(dev); | ||
| 278 | |||
| 279 | if (memc->timeout_cycles == 0) | ||
| 280 | return 0; | ||
| 281 | |||
| 282 | return brcmstb_memc_srpd_config(memc, memc->timeout_cycles); | ||
| 283 | } | ||
| 284 | |||
| 285 | static DEFINE_SIMPLE_DEV_PM_OPS(brcmstb_memc_pm_ops, brcmstb_memc_suspend, | ||
| 286 | brcmstb_memc_resume); | ||
| 287 | |||
| 288 | static struct platform_driver brcmstb_memc_driver = { | ||
| 289 | .probe = brcmstb_memc_probe, | ||
| 290 | .remove = brcmstb_memc_remove, | ||
| 291 | .driver = { | ||
| 292 | .name = "brcmstb_memc", | ||
| 293 | .of_match_table = brcmstb_memc_of_match, | ||
| 294 | .pm = pm_ptr(&brcmstb_memc_pm_ops), | ||
| 295 | }, | ||
| 296 | }; | ||
| 297 | module_platform_driver(brcmstb_memc_driver); | ||
| 298 | |||
| 299 | MODULE_LICENSE("GPL"); | ||
| 300 | MODULE_AUTHOR("Broadcom"); | ||
| 301 | MODULE_DESCRIPTION("DDR SRPD driver for Broadcom STB chips"); | ||
| @@ -24,11 +24,24 @@ · 23 unmodified lines | |||
| 24 | #define EMIF_STAT_CLEAR_BUSY_SFT 16 | 24 | #define EMIF_STAT_CLEAR_BUSY_SFT 16 |
| 25 | #define EMIF_CTRL 0x10 | 25 | #define EMIF_CTRL 0x10 |
| 26 | #define EMIF_CTRL_CLEAR_EN_SFT 0 | 26 | #define EMIF_CTRL_CLEAR_EN_SFT 0 |
| 27 | #define EMIF_CTRL_CLEAR_EN_MSK GENMASK_ULL(3, 0) | 27 | #define EMIF_CTRL_CLEAR_EN_MSK GENMASK_ULL(7, 0) |
| 28 | 28 | ||
| 29 | #define EMIF_POLL_INVL 10000 /* us */ | 29 | #define EMIF_POLL_INVL 10000 /* us */ |
| 30 | #define EMIF_POLL_TIMEOUT 5000000 /* us */ | 30 | #define EMIF_POLL_TIMEOUT 5000000 /* us */ |
| 31 | 31 | ||
| 32 | /* | ||
| 33 | * The Capability Register replaces the Control Register (at the same | ||
| 34 | * offset) for EMIF feature revisions > 0. The bitmask that indicates | ||
| 35 | * the presence of memory channels exists in both the Capability Register | ||
| 36 | * and Control Register definitions. These can be thought of as a C union. | ||
| 37 | * The Capability Register definitions are used to check for the existence | ||
| 38 | * of a memory channel, and the Control Register definitions are used for | ||
| 39 | * managing the memory-clear functionality in revision 0. | ||
| 40 | */ | ||
| 41 | #define EMIF_CAPABILITY_BASE 0x10 | ||
| 42 | #define EMIF_CAPABILITY_CHN_MSK_V0 GENMASK_ULL(3, 0) | ||
| 43 | #define EMIF_CAPABILITY_CHN_MSK GENMASK_ULL(7, 0) | ||
| 44 | |||
| 32 | struct dfl_emif { | 45 | struct dfl_emif { |
| 33 | struct device *dev; | 46 | struct device *dev; |
| 34 | void __iomem *base; | 47 | void __iomem *base; |
| @@ -106,16 +119,30 @@ emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 0); · 71 unmodified lines | |||
| 106 | emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 1); | 119 | emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 1); |
| 107 | emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 2); | 120 | emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 2); |
| 108 | emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 3); | 121 | emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 3); |
| 122 | emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 4); | ||
| 123 | emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 5); | ||
| 124 | emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 6); | ||
| 125 | emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 7); | ||
| 109 | 126 | ||
| 110 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 0); | 127 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 0); |
| 111 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 1); | 128 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 1); |
| 112 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 2); | 129 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 2); |
| 113 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 3); | 130 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 3); |
| 131 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 4); | ||
| 132 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 5); | ||
| 133 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 6); | ||
| 134 | emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 7); | ||
| 135 | |||
| 114 | 136 | ||
| 115 | emif_clear_attr(0); | 137 | emif_clear_attr(0); |
| 116 | emif_clear_attr(1); | 138 | emif_clear_attr(1); |
| 117 | emif_clear_attr(2); | 139 | emif_clear_attr(2); |
| 118 | emif_clear_attr(3); | 140 | emif_clear_attr(3); |
| 141 | emif_clear_attr(4); | ||
| 142 | emif_clear_attr(5); | ||
| 143 | emif_clear_attr(6); | ||
| 144 | emif_clear_attr(7); | ||
| 145 | |||
| 119 | 146 | ||
| 120 | static struct attribute *dfl_emif_attrs[] = { | 147 | static struct attribute *dfl_emif_attrs[] = { |
| 121 | &emif_attr_inf0_init_done.attr.attr, | 148 | &emif_attr_inf0_init_done.attr.attr, |
| @@ -134,6 +161,22 @@ static struct attribute *dfl_emif_attrs[] = { · 12 unmodified lines | |||
| 134 | &emif_attr_inf3_cal_fail.attr.attr, | 161 | &emif_attr_inf3_cal_fail.attr.attr, |
| 135 | &emif_attr_inf3_clear.attr.attr, | 162 | &emif_attr_inf3_clear.attr.attr, |
| 136 | 163 | ||
| 164 | &emif_attr_inf4_init_done.attr.attr, | ||
| 165 | &emif_attr_inf4_cal_fail.attr.attr, | ||
| 166 | &emif_attr_inf4_clear.attr.attr, | ||
| 167 | |||
| 168 | &emif_attr_inf5_init_done.attr.attr, | ||
| 169 | &emif_attr_inf5_cal_fail.attr.attr, | ||
| 170 | &emif_attr_inf5_clear.attr.attr, | ||
| 171 | |||
| 172 | &emif_attr_inf6_init_done.attr.attr, | ||
| 173 | &emif_attr_inf6_cal_fail.attr.attr, | ||
| 174 | &emif_attr_inf6_clear.attr.attr, | ||
| 175 | |||
| 176 | &emif_attr_inf7_init_done.attr.attr, | ||
| 177 | &emif_attr_inf7_cal_fail.attr.attr, | ||
| 178 | &emif_attr_inf7_clear.attr.attr, | ||
| 179 | |||
| 137 | NULL, | 180 | NULL, |
| 138 | }; | 181 | }; |
| 139 | 182 | ||
| @@ -143,15 +186,24 @@ static umode_t dfl_emif_visible(struct kobject *kobj, · 3 unmodified lines | |||
| 143 | struct dfl_emif *de = dev_get_drvdata(kobj_to_dev(kobj)); | 186 | struct dfl_emif *de = dev_get_drvdata(kobj_to_dev(kobj)); |
| 144 | struct emif_attr *eattr = container_of(attr, struct emif_attr, | 187 | struct emif_attr *eattr = container_of(attr, struct emif_attr, |
| 145 | attr.attr); | 188 | attr.attr); |
| 189 | struct dfl_device *ddev = to_dfl_dev(de->dev); | ||
| 146 | u64 val; | 190 | u64 val; |
| 147 | 191 | ||
| 148 | /* | 192 | /* |
| 149 | * This device supports upto 4 memory interfaces, but not all | 193 | * This device supports up to 8 memory interfaces, but not all |
| 150 | * interfaces are used on different platforms. The read out value of | 194 | * interfaces are used on different platforms. The read out value of |
| 151 | * CLEAN_EN field (which is a bitmap) could tell how many interfaces | 195 | * CAPABILITY_CHN_MSK field (which is a bitmap) indicates which |
| 152 | * are available. | 196 | * interfaces are available. |
| 153 | */ | 197 | */ |
| 154 | val = FIELD_GET(EMIF_CTRL_CLEAR_EN_MSK, readq(de->base + EMIF_CTRL)); | 198 | if (ddev->revision > 0 && strstr(attr->name, "_clear")) |
| 199 | return 0; | ||
| 200 | |||
| 201 | if (ddev->revision == 0) | ||
| 202 | val = FIELD_GET(EMIF_CAPABILITY_CHN_MSK_V0, | ||
| 203 | readq(de->base + EMIF_CAPABILITY_BASE)); | ||
| 204 | else | ||
| 205 | val = FIELD_GET(EMIF_CAPABILITY_CHN_MSK, | ||
| 206 | readq(de->base + EMIF_CAPABILITY_BASE)); | ||
| 155 | 207 | ||
| 156 | return (val & BIT_ULL(eattr->index)) ? attr->mode : 0; | 208 | return (val & BIT_ULL(eattr->index)) ? attr->mode : 0; |
| 157 | } | 209 | } |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 3 | * Copyright (c) 2015-2016 MediaTek Inc. | 3 | * Copyright (c) 2015-2016 MediaTek Inc. |
| 4 | * Author: Yong Wu <yong.wu@mediatek.com> | 4 | * Author: Yong Wu <yong.wu@mediatek.com> |
| 5 | */ | 5 | */ |
| 6 | #include <linux/arm-smccc.h> | ||
| 6 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
| 7 | #include <linux/component.h> | 8 | #include <linux/component.h> |
| 8 | #include <linux/device.h> | 9 | #include <linux/device.h> |
| @@ -14,6 +15,7 @@ · 5 unmodified lines | |||
| 14 | #include <linux/of_platform.h> | 15 | #include <linux/of_platform.h> |
| 15 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 16 | #include <linux/pm_runtime.h> | 17 | #include <linux/pm_runtime.h> |
| 18 | #include <linux/soc/mediatek/mtk_sip_svc.h> | ||
| 17 | #include <soc/mediatek/smi.h> | 19 | #include <soc/mediatek/smi.h> |
| 18 | #include <dt-bindings/memory/mt2701-larb-port.h> | 20 | #include <dt-bindings/memory/mt2701-larb-port.h> |
| 19 | #include <dt-bindings/memory/mtk-memory-port.h> | 21 | #include <dt-bindings/memory/mtk-memory-port.h> |
| @@ -89,6 +91,7 @@ · 69 unmodified lines | |||
| 89 | #define MTK_SMI_FLAG_THRT_UPDATE BIT(0) | 91 | #define MTK_SMI_FLAG_THRT_UPDATE BIT(0) |
| 90 | #define MTK_SMI_FLAG_SW_FLAG BIT(1) | 92 | #define MTK_SMI_FLAG_SW_FLAG BIT(1) |
| 91 | #define MTK_SMI_FLAG_SLEEP_CTL BIT(2) | 93 | #define MTK_SMI_FLAG_SLEEP_CTL BIT(2) |
| 94 | #define MTK_SMI_FLAG_CFG_PORT_SEC_CTL BIT(3) | ||
| 92 | #define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x))) | 95 | #define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x))) |
| 93 | 96 | ||
| 94 | struct mtk_smi_reg_pair { | 97 | struct mtk_smi_reg_pair { |
| @@ -127,7 +130,7 @@ struct mtk_smi_common_plat { · 32 unmodified lines | |||
| 127 | 130 | ||
| 128 | struct mtk_smi_larb_gen { | 131 | struct mtk_smi_larb_gen { |
| 129 | int port_in_larb[MTK_LARB_NR_MAX + 1]; | 132 | int port_in_larb[MTK_LARB_NR_MAX + 1]; |
| 130 | void (*config_port)(struct device *dev); | 133 | int (*config_port)(struct device *dev); |
| 131 | unsigned int larb_direct_to_common_mask; | 134 | unsigned int larb_direct_to_common_mask; |
| 132 | unsigned int flags_general; | 135 | unsigned int flags_general; |
| 133 | const u8 (*ostd)[SMI_LARB_PORT_NR_MAX]; | 136 | const u8 (*ostd)[SMI_LARB_PORT_NR_MAX]; |
| @@ -185,7 +188,7 @@ static const struct component_ops mtk_smi_larb_component_ops = { · 51 unmodified lines | |||
| 185 | .unbind = mtk_smi_larb_unbind, | 188 | .unbind = mtk_smi_larb_unbind, |
| 186 | }; | 189 | }; |
| 187 | 190 | ||
| 188 | static void mtk_smi_larb_config_port_gen1(struct device *dev) | 191 | static int mtk_smi_larb_config_port_gen1(struct device *dev) |
| 189 | { | 192 | { |
| 190 | struct mtk_smi_larb *larb = dev_get_drvdata(dev); | 193 | struct mtk_smi_larb *larb = dev_get_drvdata(dev); |
| 191 | const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen; | 194 | 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) · 22 unmodified lines | |||
| 214 | common->smi_ao_base | 217 | common->smi_ao_base |
| 215 | + REG_SMI_SECUR_CON_ADDR(m4u_port_id)); | 218 | + REG_SMI_SECUR_CON_ADDR(m4u_port_id)); |
| 216 | } | 219 | } |
| 220 | return 0; | ||
| 217 | } | 221 | } |
| 218 | 222 | ||
| 219 | static void mtk_smi_larb_config_port_mt8167(struct device *dev) | 223 | static int mtk_smi_larb_config_port_mt8167(struct device *dev) |
| 220 | { | 224 | { |
| 221 | struct mtk_smi_larb *larb = dev_get_drvdata(dev); | 225 | struct mtk_smi_larb *larb = dev_get_drvdata(dev); |
| 222 | 226 | ||
| 223 | writel(*larb->mmu, larb->base + MT8167_SMI_LARB_MMU_EN); | 227 | writel(*larb->mmu, larb->base + MT8167_SMI_LARB_MMU_EN); |
| 228 | return 0; | ||
| 224 | } | 229 | } |
| 225 | 230 | ||
| 226 | static void mtk_smi_larb_config_port_mt8173(struct device *dev) | 231 | static int mtk_smi_larb_config_port_mt8173(struct device *dev) |
| 227 | { | 232 | { |
| 228 | struct mtk_smi_larb *larb = dev_get_drvdata(dev); | 233 | struct mtk_smi_larb *larb = dev_get_drvdata(dev); |
| 229 | 234 | ||
| 230 | writel(*larb->mmu, larb->base + MT8173_SMI_LARB_MMU_EN); | 235 | writel(*larb->mmu, larb->base + MT8173_SMI_LARB_MMU_EN); |
| 236 | return 0; | ||
| 231 | } | 237 | } |
| 232 | 238 | ||
| 233 | static void mtk_smi_larb_config_port_gen2_general(struct device *dev) | 239 | static int mtk_smi_larb_config_port_gen2_general(struct device *dev) |
| 234 | { | 240 | { |
| 235 | struct mtk_smi_larb *larb = dev_get_drvdata(dev); | 241 | struct mtk_smi_larb *larb = dev_get_drvdata(dev); |
| 236 | u32 reg, flags_general = larb->larb_gen->flags_general; | 242 | u32 reg, flags_general = larb->larb_gen->flags_general; |
| 237 | const u8 *larbostd = larb->larb_gen->ostd ? larb->larb_gen->ostd[larb->larbid] : NULL; | 243 | const u8 *larbostd = larb->larb_gen->ostd ? larb->larb_gen->ostd[larb->larbid] : NULL; |
| 244 | struct arm_smccc_res res; | ||
| 238 | int i; | 245 | int i; |
| 239 | 246 | ||
| 240 | if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask) | 247 | if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask) |
| 241 | return; | 248 | return 0; |
| 242 | 249 | ||
| 243 | if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_THRT_UPDATE)) { | 250 | if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_THRT_UPDATE)) { |
| 244 | reg = readl_relaxed(larb->base + SMI_LARB_CMD_THRT_CON); | 251 | 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) · 8 unmodified lines | |||
| 253 | for (i = 0; i < SMI_LARB_PORT_NR_MAX && larbostd && !!larbostd[i]; i++) | 260 | for (i = 0; i < SMI_LARB_PORT_NR_MAX && larbostd && !!larbostd[i]; i++) |
| 254 | writel_relaxed(larbostd[i], larb->base + SMI_LARB_OSTDL_PORTx(i)); | 261 | writel_relaxed(larbostd[i], larb->base + SMI_LARB_OSTDL_PORTx(i)); |
| 255 | 262 | ||
| 263 | /* | ||
| 264 | * When mmu_en bits are in security world, the bank_sel still is in the | ||
| 265 | * LARB_NONSEC_CON below. And the mmu_en bits of LARB_NONSEC_CON have no | ||
| 266 | * effect in this case. | ||
| 267 | */ | ||
| 268 | if (MTK_SMI_CAPS(flags_general, MTK_SMI_FLAG_CFG_PORT_SEC_CTL)) { | ||
| 269 | arm_smccc_smc(MTK_SIP_KERNEL_IOMMU_CONTROL, IOMMU_ATF_CMD_CONFIG_SMI_LARB, | ||
| 270 | larb->larbid, *larb->mmu, 0, 0, 0, 0, &res); | ||
| 271 | if (res.a0 != 0) { | ||
| 272 | dev_err(dev, "Enable iommu fail, ret %ld\n", res.a0); | ||
| 273 | return -EINVAL; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 256 | for_each_set_bit(i, (unsigned long *)larb->mmu, 32) { | 277 | for_each_set_bit(i, (unsigned long *)larb->mmu, 32) { |
| 257 | reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i)); | 278 | reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i)); |
| 258 | reg |= F_MMU_EN; | 279 | reg |= F_MMU_EN; |
| 259 | reg |= BANK_SEL(larb->bank[i]); | 280 | reg |= BANK_SEL(larb->bank[i]); |
| 260 | writel(reg, larb->base + SMI_LARB_NONSEC_CON(i)); | 281 | writel(reg, larb->base + SMI_LARB_NONSEC_CON(i)); |
| 261 | } | 282 | } |
| 283 | return 0; | ||
| 262 | } | 284 | } |
| 263 | 285 | ||
| 286 | static const u8 mtk_smi_larb_mt8188_ostd[][SMI_LARB_PORT_NR_MAX] = { | ||
| 287 | [0] = {0x02, 0x18, 0x22, 0x22, 0x01, 0x02, 0x0a,}, | ||
| 288 | [1] = {0x12, 0x02, 0x14, 0x14, 0x01, 0x18, 0x0a,}, | ||
| 289 | [2] = {0x12, 0x12, 0x12, 0x12, 0x0a,}, | ||
| 290 | [3] = {0x12, 0x12, 0x12, 0x12, 0x28, 0x28, 0x0a,}, | ||
| 291 | [4] = {0x06, 0x01, 0x17, 0x06, 0x0a, 0x07, 0x07,}, | ||
| 292 | [5] = {0x02, 0x01, 0x04, 0x02, 0x06, 0x01, 0x06, 0x0a,}, | ||
| 293 | [6] = {0x06, 0x01, 0x06, 0x0a,}, | ||
| 294 | [7] = {0x0c, 0x0c, 0x12,}, | ||
| 295 | [8] = {0x0c, 0x01, 0x0a, 0x05, 0x02, 0x03, 0x01, 0x01, 0x14, 0x14, | ||
| 296 | 0x0a, 0x14, 0x1e, 0x01, 0x0c, 0x0a, 0x05, 0x02, 0x02, 0x05, | ||
| 297 | 0x03, 0x01, 0x1e, 0x01, 0x05,}, | ||
| 298 | [9] = {0x1e, 0x01, 0x0a, 0x0a, 0x01, 0x01, 0x03, 0x1e, 0x1e, 0x10, | ||
| 299 | 0x07, 0x01, 0x0a, 0x06, 0x03, 0x03, 0x0e, 0x01, 0x04, 0x28,}, | ||
| 300 | [10] = {0x03, 0x20, 0x01, 0x20, 0x01, 0x01, 0x14, 0x0a, 0x0a, 0x0c, | ||
| 301 | 0x0a, 0x05, 0x02, 0x03, 0x02, 0x14, 0x0a, 0x0a, 0x14, 0x14, | ||
| 302 | 0x14, 0x01, 0x01, 0x14, 0x1e, 0x01, 0x05, 0x03, 0x02, 0x28,}, | ||
| 303 | [11] = {0x03, 0x20, 0x01, 0x20, 0x01, 0x01, 0x14, 0x0a, 0x0a, 0x0c, | ||
| 304 | 0x0a, 0x05, 0x02, 0x03, 0x02, 0x14, 0x0a, 0x0a, 0x14, 0x14, | ||
| 305 | 0x14, 0x01, 0x01, 0x14, 0x1e, 0x01, 0x05, 0x03, 0x02, 0x28,}, | ||
| 306 | [12] = {0x03, 0x20, 0x01, 0x20, 0x01, 0x01, 0x14, 0x0a, 0x0a, 0x0c, | ||
| 307 | 0x0a, 0x05, 0x02, 0x03, 0x02, 0x14, 0x0a, 0x0a, 0x14, 0x14, | ||
| 308 | 0x14, 0x01, 0x01, 0x14, 0x1e, 0x01, 0x05, 0x03, 0x02, 0x28,}, | ||
| 309 | [13] = {0x07, 0x02, 0x04, 0x02, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, | ||
| 310 | 0x07, 0x02, 0x04, 0x02, 0x05, 0x05,}, | ||
| 311 | [14] = {0x02, 0x02, 0x0c, 0x0c, 0x0c, 0x0c, 0x01, 0x01, 0x02, 0x02, | ||
| 312 | 0x02, 0x02, 0x0c, 0x0c, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, | ||
| 313 | 0x02, 0x02, 0x01, 0x01,}, | ||
| 314 | [15] = {0x0c, 0x0c, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x0c, 0x0c, | ||
| 315 | 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, | ||
| 316 | 0x0c, 0x01, 0x01,}, | ||
| 317 | [16] = {0x28, 0x28, 0x03, 0x01, 0x01, 0x03, 0x14, 0x14, 0x0a, 0x0d, | ||
| 318 | 0x03, 0x05, 0x0e, 0x01, 0x01, 0x05, 0x06, 0x0d, 0x01,}, | ||
| 319 | [17] = {0x28, 0x02, 0x02, 0x12, 0x02, 0x12, 0x10, 0x02, 0x02, 0x0a, | ||
| 320 | 0x12, 0x02, 0x02, 0x0a, 0x16, 0x02, 0x04,}, | ||
| 321 | [18] = {0x28, 0x02, 0x02, 0x12, 0x02, 0x12, 0x10, 0x02, 0x02, 0x0a, | ||
| 322 | 0x12, 0x02, 0x02, 0x0a, 0x16, 0x02, 0x04,}, | ||
| 323 | [19] = {0x1a, 0x0e, 0x0a, 0x0a, 0x0c, 0x0e, 0x10,}, | ||
| 324 | [20] = {0x1a, 0x0e, 0x0a, 0x0a, 0x0c, 0x0e, 0x10,}, | ||
| 325 | [21] = {0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x01, | ||
| 326 | 0x01, 0x01, 0x04, 0x0a, 0x06, 0x01, 0x01, 0x01, 0x0a, 0x06, | ||
| 327 | 0x01, 0x01, 0x05, 0x03, 0x03, 0x04, 0x01,}, | ||
| 328 | [22] = {0x28, 0x19, 0x0c, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, | ||
| 329 | 0x01,}, | ||
| 330 | [23] = {0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x18, 0x01, 0x01,}, | ||
| 331 | [24] = {0x12, 0x06, 0x12, 0x06,}, | ||
| 332 | [25] = {0x01}, | ||
| 333 | }; | ||
| 334 | |||
| 264 | static const u8 mtk_smi_larb_mt8195_ostd[][SMI_LARB_PORT_NR_MAX] = { | 335 | static const u8 mtk_smi_larb_mt8195_ostd[][SMI_LARB_PORT_NR_MAX] = { |
| 265 | [0] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb0 */ | 336 | [0] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb0 */ |
| 266 | [1] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb1 */ | 337 | [1] = {0x0a, 0xc, 0x22, 0x22, 0x01, 0x0a,}, /* larb1 */ |
| @@ -347,6 +418,13 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = { · 80 unmodified lines | |||
| 347 | .flags_general = MTK_SMI_FLAG_SLEEP_CTL, | 418 | .flags_general = MTK_SMI_FLAG_SLEEP_CTL, |
| 348 | }; | 419 | }; |
| 349 | 420 | ||
| 421 | static const struct mtk_smi_larb_gen mtk_smi_larb_mt8188 = { | ||
| 422 | .config_port = mtk_smi_larb_config_port_gen2_general, | ||
| 423 | .flags_general = MTK_SMI_FLAG_THRT_UPDATE | MTK_SMI_FLAG_SW_FLAG | | ||
| 424 | MTK_SMI_FLAG_SLEEP_CTL | MTK_SMI_FLAG_CFG_PORT_SEC_CTL, | ||
| 425 | .ostd = mtk_smi_larb_mt8188_ostd, | ||
| 426 | }; | ||
| 427 | |||
| 350 | static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = { | 428 | static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = { |
| 351 | .config_port = mtk_smi_larb_config_port_gen2_general, | 429 | .config_port = mtk_smi_larb_config_port_gen2_general, |
| 352 | }; | 430 | }; |
| @@ -367,6 +445,7 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = { · 14 unmodified lines | |||
| 367 | {.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173}, | 445 | {.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173}, |
| 368 | {.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183}, | 446 | {.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183}, |
| 369 | {.compatible = "mediatek,mt8186-smi-larb", .data = &mtk_smi_larb_mt8186}, | 447 | {.compatible = "mediatek,mt8186-smi-larb", .data = &mtk_smi_larb_mt8186}, |
| 448 | {.compatible = "mediatek,mt8188-smi-larb", .data = &mtk_smi_larb_mt8188}, | ||
| 370 | {.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192}, | 449 | {.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192}, |
| 371 | {.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195}, | 450 | {.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195}, |
| 372 | {} | 451 | {} |
| @@ -511,9 +590,7 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev) · 138 unmodified lines | |||
| 511 | mtk_smi_larb_sleep_ctrl_disable(larb); | 590 | mtk_smi_larb_sleep_ctrl_disable(larb); |
| 512 | 591 | ||
| 513 | /* Configure the basic setting for this larb */ | 592 | /* Configure the basic setting for this larb */ |
| 514 | larb_gen->config_port(dev); | 593 | return larb_gen->config_port(dev); |
| 515 | |||
| 516 | return 0; | ||
| 517 | } | 594 | } |
| 518 | 595 | ||
| 519 | static int __maybe_unused mtk_smi_larb_suspend(struct device *dev) | 596 | 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 = { · 77 unmodified lines | |||
| 597 | .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(4) | F_MMU1_LARB(7), | 674 | .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(4) | F_MMU1_LARB(7), |
| 598 | }; | 675 | }; |
| 599 | 676 | ||
| 677 | static const struct mtk_smi_common_plat mtk_smi_common_mt8188_vdo = { | ||
| 678 | .type = MTK_SMI_GEN2, | ||
| 679 | .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(5) | F_MMU1_LARB(7), | ||
| 680 | .init = mtk_smi_common_mt8195_init, | ||
| 681 | }; | ||
| 682 | |||
| 683 | static const struct mtk_smi_common_plat mtk_smi_common_mt8188_vpp = { | ||
| 684 | .type = MTK_SMI_GEN2, | ||
| 685 | .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(7), | ||
| 686 | .init = mtk_smi_common_mt8195_init, | ||
| 687 | }; | ||
| 688 | |||
| 600 | static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = { | 689 | static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = { |
| 601 | .type = MTK_SMI_GEN2, | 690 | .type = MTK_SMI_GEN2, |
| 602 | .has_gals = true, | 691 | .has_gals = true, |
| @@ -633,6 +722,8 @@ static const struct of_device_id mtk_smi_common_of_ids[] = { · 30 unmodified lines | |||
| 633 | {.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2}, | 722 | {.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2}, |
| 634 | {.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183}, | 723 | {.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183}, |
| 635 | {.compatible = "mediatek,mt8186-smi-common", .data = &mtk_smi_common_mt8186}, | 724 | {.compatible = "mediatek,mt8186-smi-common", .data = &mtk_smi_common_mt8186}, |
| 725 | {.compatible = "mediatek,mt8188-smi-common-vdo", .data = &mtk_smi_common_mt8188_vdo}, | ||
| 726 | {.compatible = "mediatek,mt8188-smi-common-vpp", .data = &mtk_smi_common_mt8188_vpp}, | ||
| 636 | {.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192}, | 727 | {.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192}, |
| 637 | {.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo}, | 728 | {.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo}, |
| 638 | {.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp}, | 729 | {.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, · 133 unmodified lines | |||
| 134 | for_each_child_of_node(np_ddr, np_tim) { | 134 | for_each_child_of_node(np_ddr, np_tim) { |
| 135 | if (of_device_is_compatible(np_tim, tim_compat)) { | 135 | if (of_device_is_compatible(np_tim, tim_compat)) { |
| 136 | if (of_do_get_timings(np_tim, &timings[i])) { | 136 | if (of_do_get_timings(np_tim, &timings[i])) { |
| 137 | of_node_put(np_tim); | ||
| 137 | devm_kfree(dev, timings); | 138 | devm_kfree(dev, timings); |
| 138 | goto default_timings; | 139 | goto default_timings; |
| 139 | } | 140 | } |
| @@ -284,6 +285,7 @@ const struct lpddr3_timings · 144 unmodified lines | |||
| 284 | if (of_device_is_compatible(np_tim, tim_compat)) { | 285 | if (of_device_is_compatible(np_tim, tim_compat)) { |
| 285 | if (of_lpddr3_do_get_timings(np_tim, &timings[i])) { | 286 | if (of_lpddr3_do_get_timings(np_tim, &timings[i])) { |
| 286 | devm_kfree(dev, timings); | 287 | devm_kfree(dev, timings); |
| 288 | of_node_put(np_tim); | ||
| 287 | goto default_timings; | 289 | goto default_timings; |
| 288 | } | 290 | } |
| 289 | i++; | 291 | i++; |
| @@ -122,6 +122,7 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id) · 121 unmodified lines | |||
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | of_platform_device_create(child, NULL, &adev->dev); | 124 | of_platform_device_create(child, NULL, &adev->dev); |
| 125 | of_node_put(child); | ||
| 125 | 126 | ||
| 126 | return 0; | 127 | return 0; |
| 127 | 128 | ||
| @@ -69,8 +69,8 @@ config MTD_OF_PARTS · 68 unmodified lines | |||
| 69 | 69 | ||
| 70 | config MTD_OF_PARTS_BCM4908 | 70 | config MTD_OF_PARTS_BCM4908 |
| 71 | bool "BCM4908 partitioning support" | 71 | bool "BCM4908 partitioning support" |
| 72 | depends on MTD_OF_PARTS && (ARCH_BCM4908 || COMPILE_TEST) | 72 | depends on MTD_OF_PARTS && (ARCH_BCMBCA || COMPILE_TEST) |
| 73 | default ARCH_BCM4908 | 73 | default ARCH_BCMBCA |
| 74 | help | 74 | help |
| 75 | This provides partitions parser for BCM4908 family devices | 75 | This provides partitions parser for BCM4908 family devices |
| 76 | that can have multiple "firmware" partitions. It takes care of | 76 | that can have multiple "firmware" partitions. It takes care of |
| @@ -78,7 +78,7 @@ config MTD_OF_PARTS_BCM4908 · 1 unmodified line | |||
| 78 | 78 | ||
| 79 | config MTD_OF_PARTS_LINKSYS_NS | 79 | config MTD_OF_PARTS_LINKSYS_NS |
| 80 | bool "Linksys Northstar partitioning support" | 80 | bool "Linksys Northstar partitioning support" |
| 81 | depends on MTD_OF_PARTS && (ARCH_BCM_5301X || ARCH_BCM4908 || COMPILE_TEST) | 81 | depends on MTD_OF_PARTS && (ARCH_BCM_5301X || ARCH_BCMBCA || COMPILE_TEST) |
| 82 | default ARCH_BCM_5301X | 82 | default ARCH_BCM_5301X |
| 83 | help | 83 | help |
| 84 | This provides partitions parser for Linksys devices based on Broadcom | 84 | This provides partitions parser for Linksys devices based on Broadcom |
| @@ -53,8 +53,8 @@ config B44_PCI · 52 unmodified lines | |||
| 53 | 53 | ||
| 54 | config BCM4908_ENET | 54 | config BCM4908_ENET |
| 55 | tristate "Broadcom BCM4908 internal mac support" | 55 | tristate "Broadcom BCM4908 internal mac support" |
| 56 | depends on ARCH_BCM4908 || COMPILE_TEST | 56 | depends on ARCH_BCMBCA || COMPILE_TEST |
| 57 | default y if ARCH_BCM4908 | 57 | default y if ARCH_BCMBCA |
| 58 | help | 58 | help |
| 59 | This driver supports Ethernet controller integrated into Broadcom | 59 | This driver supports Ethernet controller integrated into Broadcom |
| 60 | BCM4908 family SoCs. | 60 | BCM4908 family SoCs. |
| @@ -274,7 +274,7 @@ config VMD · 273 unmodified lines | |||
| 274 | 274 | ||
| 275 | config PCIE_BRCMSTB | 275 | config PCIE_BRCMSTB |
| 276 | tristate "Broadcom Brcmstb PCIe host controller" | 276 | tristate "Broadcom Brcmstb PCIe host controller" |
| 277 | depends on ARCH_BRCMSTB || ARCH_BCM2835 || ARCH_BCM4908 || \ | 277 | depends on ARCH_BRCMSTB || ARCH_BCM2835 || ARCH_BCMBCA || \ |
| 278 | BMIPS_GENERIC || COMPILE_TEST | 278 | BMIPS_GENERIC || COMPILE_TEST |
| 279 | depends on OF | 279 | depends on OF |
| 280 | depends on PCI_MSI_IRQ_DOMAIN | 280 | depends on PCI_MSI_IRQ_DOMAIN |
| @@ -93,11 +93,11 @@ config PHY_BRCM_SATA · 92 unmodified lines | |||
| 93 | 93 | ||
| 94 | config PHY_BRCM_USB | 94 | config PHY_BRCM_USB |
| 95 | tristate "Broadcom STB USB PHY driver" | 95 | tristate "Broadcom STB USB PHY driver" |
| 96 | depends on ARCH_BCM4908 || ARCH_BRCMSTB || COMPILE_TEST | 96 | depends on ARCH_BCMBCA || ARCH_BRCMSTB || COMPILE_TEST |
| 97 | depends on OF | 97 | depends on OF |
| 98 | select GENERIC_PHY | 98 | select GENERIC_PHY |
| 99 | select SOC_BRCMSTB if ARCH_BRCMSTB | 99 | select SOC_BRCMSTB if ARCH_BRCMSTB |
| 100 | default ARCH_BCM4908 || ARCH_BRCMSTB | 100 | default ARCH_BCMBCA || ARCH_BRCMSTB |
| 101 | help | 101 | help |
| 102 | Enable this to support the Broadcom STB USB PHY. | 102 | Enable this to support the Broadcom STB USB PHY. |
| 103 | This driver is required by the USB XHCI, EHCI and OHCI | 103 | This driver is required by the USB XHCI, EHCI and OHCI |
| @@ -31,13 +31,13 @@ config PINCTRL_BCM2835 · 30 unmodified lines | |||
| 31 | 31 | ||
| 32 | config PINCTRL_BCM4908 | 32 | config PINCTRL_BCM4908 |
| 33 | tristate "Broadcom BCM4908 pinmux driver" | 33 | tristate "Broadcom BCM4908 pinmux driver" |
| 34 | depends on OF && (ARCH_BCM4908 || COMPILE_TEST) | 34 | depends on OF && (ARCH_BCMBCA || COMPILE_TEST) |
| 35 | select PINMUX | 35 | select PINMUX |
| 36 | select PINCONF | 36 | select PINCONF |
| 37 | select GENERIC_PINCONF | 37 | select GENERIC_PINCONF |
| 38 | select GENERIC_PINCTRL_GROUPS | 38 | select GENERIC_PINCTRL_GROUPS |
| 39 | select GENERIC_PINMUX_FUNCTIONS | 39 | select GENERIC_PINMUX_FUNCTIONS |
| 40 | default ARCH_BCM4908 | 40 | default ARCH_BCMBCA |
| 41 | help | 41 | help |
| 42 | Driver for BCM4908 family SoCs with integrated pin controller. | 42 | Driver for BCM4908 family SoCs with integrated pin controller. |
| 43 | 43 | ||
| @@ -201,7 +201,7 @@ config RESET_SCMI · 200 unmodified lines | |||
| 201 | 201 | ||
| 202 | config RESET_SIMPLE | 202 | config RESET_SIMPLE |
| 203 | bool "Simple Reset Controller Driver" if COMPILE_TEST || EXPERT | 203 | bool "Simple Reset Controller Driver" if COMPILE_TEST || EXPERT |
| 204 | default ARCH_ASPEED || ARCH_BCM4908 || ARCH_BITMAIN || ARCH_REALTEK || ARCH_STM32 || (ARCH_INTEL_SOCFPGA && ARM64) || ARCH_SUNXI || ARC | 204 | default ARCH_ASPEED || ARCH_BCMBCA || ARCH_BITMAIN || ARCH_REALTEK || ARCH_STM32 || (ARCH_INTEL_SOCFPGA && ARM64) || ARCH_SUNXI || ARC |
| 205 | depends on HAS_IOMEM | 205 | depends on HAS_IOMEM |
| 206 | help | 206 | help |
| 207 | This enables a simple reset controller driver for reset lines that | 207 | 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) · 468 unmodified lines | |||
| 469 | { | 469 | { |
| 470 | const struct meson_ee_pwrc_domain_data *match; | 470 | const struct meson_ee_pwrc_domain_data *match; |
| 471 | struct regmap *regmap_ao, *regmap_hhi; | 471 | struct regmap *regmap_ao, *regmap_hhi; |
| 472 | struct device_node *parent_np; | ||
| 472 | struct meson_ee_pwrc *pwrc; | 473 | struct meson_ee_pwrc *pwrc; |
| 473 | int i, ret; | 474 | int i, ret; |
| 474 | 475 | ||
| @@ -495,7 +496,9 @@ static int meson_ee_pwrc_probe(struct platform_device *pdev) · 20 unmodified lines | |||
| 495 | 496 | ||
| 496 | pwrc->xlate.num_domains = match->count; | 497 | pwrc->xlate.num_domains = match->count; |
| 497 | 498 | ||
| 498 | regmap_hhi = syscon_node_to_regmap(of_get_parent(pdev->dev.of_node)); | 499 | parent_np = of_get_parent(pdev->dev.of_node); |
| 500 | regmap_hhi = syscon_node_to_regmap(parent_np); | ||
| 501 | of_node_put(parent_np); | ||
| 499 | if (IS_ERR(regmap_hhi)) { | 502 | if (IS_ERR(regmap_hhi)) { |
| 500 | dev_err(&pdev->dev, "failed to get HHI regmap\n"); | 503 | dev_err(&pdev->dev, "failed to get HHI regmap\n"); |
| 501 | return PTR_ERR(regmap_hhi); | 504 | return PTR_ERR(regmap_hhi); |
| @@ -273,6 +273,7 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev) · 272 unmodified lines | |||
| 273 | const struct meson_gx_pwrc_vpu *vpu_pd_match; | 273 | const struct meson_gx_pwrc_vpu *vpu_pd_match; |
| 274 | struct regmap *regmap_ao, *regmap_hhi; | 274 | struct regmap *regmap_ao, *regmap_hhi; |
| 275 | struct meson_gx_pwrc_vpu *vpu_pd; | 275 | struct meson_gx_pwrc_vpu *vpu_pd; |
| 276 | struct device_node *parent_np; | ||
| 276 | struct reset_control *rstc; | 277 | struct reset_control *rstc; |
| 277 | struct clk *vpu_clk; | 278 | struct clk *vpu_clk; |
| 278 | struct clk *vapb_clk; | 279 | struct clk *vapb_clk; |
| @@ -291,7 +292,9 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev) · 12 unmodified lines | |||
| 291 | 292 | ||
| 292 | memcpy(vpu_pd, vpu_pd_match, sizeof(*vpu_pd)); | 293 | memcpy(vpu_pd, vpu_pd_match, sizeof(*vpu_pd)); |
| 293 | 294 | ||
| 294 | regmap_ao = syscon_node_to_regmap(of_get_parent(pdev->dev.of_node)); | 295 | parent_np = of_get_parent(pdev->dev.of_node); |
| 296 | regmap_ao = syscon_node_to_regmap(parent_np); | ||
| 297 | of_node_put(parent_np); | ||
| 295 | if (IS_ERR(regmap_ao)) { | 298 | if (IS_ERR(regmap_ao)) { |
| 296 | dev_err(&pdev->dev, "failed to get regmap\n"); | 299 | dev_err(&pdev->dev, "failed to get regmap\n"); |
| 297 | return PTR_ERR(regmap_ao); | 300 | return PTR_ERR(regmap_ao); |
| @@ -660,6 +660,12 @@ int apple_rtkit_send_message_wait(struct apple_rtkit *rtk, u8 ep, u64 message, · 659 unmodified lines | |||
| 660 | } | 660 | } |
| 661 | EXPORT_SYMBOL_GPL(apple_rtkit_send_message_wait); | 661 | EXPORT_SYMBOL_GPL(apple_rtkit_send_message_wait); |
| 662 | 662 | ||
| 663 | int apple_rtkit_poll(struct apple_rtkit *rtk) | ||
| 664 | { | ||
| 665 | return mbox_client_peek_data(rtk->mbox_chan); | ||
| 666 | } | ||
| 667 | EXPORT_SYMBOL_GPL(apple_rtkit_poll); | ||
| 668 | |||
| 663 | int apple_rtkit_start_ep(struct apple_rtkit *rtk, u8 endpoint) | 669 | int apple_rtkit_start_ep(struct apple_rtkit *rtk, u8 endpoint) |
| 664 | { | 670 | { |
| 665 | u64 msg; | 671 | u64 msg; |
| @@ -13,8 +13,8 @@ endif # SOC_BCM63XX · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | config BCM_PMB | 14 | config BCM_PMB |
| 15 | bool "Broadcom PMB (Power Management Bus) driver" | 15 | bool "Broadcom PMB (Power Management Bus) driver" |
| 16 | depends on ARCH_BCM4908 || (COMPILE_TEST && OF) | 16 | depends on ARCH_BCMBCA || (COMPILE_TEST && OF) |
| 17 | default ARCH_BCM4908 | 17 | default ARCH_BCMBCA |
| 18 | select PM_GENERIC_DOMAINS if PM | 18 | select PM_GENERIC_DOMAINS if PM |
| 19 | help | 19 | help |
| 20 | This enables support for the Broadcom's PMB (Power Management Bus) that | 20 | This enables support for the Broadcom's PMB (Power Management Bus) that |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | |||
| 25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
| 26 | #include <linux/memblock.h> | 26 | #include <linux/memblock.h> |
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/notifier.h> | ||
| 29 | #include <linux/of.h> | 28 | #include <linux/of.h> |
| 30 | #include <linux/of_address.h> | 29 | #include <linux/of_address.h> |
| 31 | #include <linux/panic_notifier.h> | 30 | #include <linux/panic_notifier.h> |
| @@ -664,7 +663,20 @@ static void __iomem *brcmstb_ioremap_match(const struct of_device_id *matches, · 632 unmodified lines | |||
| 664 | 663 | ||
| 665 | return of_io_request_and_map(dn, index, dn->full_name); | 664 | return of_io_request_and_map(dn, index, dn->full_name); |
| 666 | } | 665 | } |
| 667 | 666 | /* | |
| 667 | * The AON is a small domain in the SoC that can retain its state across | ||
| 668 | * various system wide sleep states and specific reset conditions; the | ||
| 669 | * AON DATA RAM is a small RAM of a few words (< 1KB) which can store | ||
| 670 | * persistent information across such events. | ||
| 671 | * | ||
| 672 | * The purpose of the below panic notifier is to help with notifying | ||
| 673 | * the bootloader that a panic occurred and so that it should try its | ||
| 674 | * best to preserve the DRAM contents holding that buffer for recovery | ||
| 675 | * by the kernel as opposed to wiping out DRAM clean again. | ||
| 676 | * | ||
| 677 | * Reference: comment from Florian Fainelli, at | ||
| 678 | * https://lore.kernel.org/lkml/781cafb0-8d06-8b56-907a-5175c2da196a@gmail.com | ||
| 679 | */ | ||
| 668 | static int brcmstb_pm_panic_notify(struct notifier_block *nb, | 680 | static int brcmstb_pm_panic_notify(struct notifier_block *nb, |
| 669 | unsigned long action, void *data) | 681 | unsigned long action, void *data) |
| 670 | { | 682 | { |
| @@ -20,4 +20,12 @@ config SOC_IMX8M · 19 unmodified lines | |||
| 20 | support, it will provide the SoC info like SoC family, | 20 | support, it will provide the SoC info like SoC family, |
| 21 | ID and revision etc. | 21 | ID and revision etc. |
| 22 | 22 | ||
| 23 | config SOC_IMX9 | ||
| 24 | tristate "i.MX9 SoC family support" | ||
| 25 | depends on ARCH_MXC || COMPILE_TEST | ||
| 26 | default ARCH_MXC && ARM64 | ||
| 27 | select SOC_BUS | ||
| 28 | help | ||
| 29 | If you say yes here, you get support for the NXP i.MX9 family | ||
| 30 | |||
| 23 | endmenu | 31 | endmenu |
| @@ -7,3 +7,5 @@ obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o · 6 unmodified lines | |||
| 7 | obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o | 7 | obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o |
| 8 | obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o | 8 | obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o |
| 9 | obj-$(CONFIG_SOC_IMX8M) += imx8mp-blk-ctrl.o | 9 | obj-$(CONFIG_SOC_IMX8M) += imx8mp-blk-ctrl.o |
| 10 | obj-$(CONFIG_SOC_IMX9) += imx93-src.o imx93-pd.o | ||
| 11 | obj-$(CONFIG_SOC_IMX9) += imx93-blk-ctrl.o | ||
| @@ -5,6 +5,7 @@ · 4 unmodified lines | |||
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <linux/device.h> | 7 | #include <linux/device.h> |
| 8 | #include <linux/interconnect.h> | ||
| 8 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 9 | #include <linux/of_device.h> | 10 | #include <linux/of_device.h> |
| 10 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
| @@ -37,6 +38,8 @@ struct imx8m_blk_ctrl_domain_data { · 26 unmodified lines | |||
| 37 | const char *name; | 38 | const char *name; |
| 38 | const char * const *clk_names; | 39 | const char * const *clk_names; |
| 39 | int num_clks; | 40 | int num_clks; |
| 41 | const char * const *path_names; | ||
| 42 | int num_paths; | ||
| 40 | const char *gpc_name; | 43 | const char *gpc_name; |
| 41 | u32 rst_mask; | 44 | u32 rst_mask; |
| 42 | u32 clk_mask; | 45 | u32 clk_mask; |
| @@ -52,13 +55,16 @@ struct imx8m_blk_ctrl_domain_data { · 9 unmodified lines | |||
| 52 | }; | 55 | }; |
| 53 | 56 | ||
| 54 | #define DOMAIN_MAX_CLKS 4 | 57 | #define DOMAIN_MAX_CLKS 4 |
| 58 | #define DOMAIN_MAX_PATHS 4 | ||
| 55 | 59 | ||
| 56 | struct imx8m_blk_ctrl_domain { | 60 | struct imx8m_blk_ctrl_domain { |
| 57 | struct generic_pm_domain genpd; | 61 | struct generic_pm_domain genpd; |
| 58 | const struct imx8m_blk_ctrl_domain_data *data; | 62 | const struct imx8m_blk_ctrl_domain_data *data; |
| 59 | struct clk_bulk_data clks[DOMAIN_MAX_CLKS]; | 63 | struct clk_bulk_data clks[DOMAIN_MAX_CLKS]; |
| 64 | struct icc_bulk_data paths[DOMAIN_MAX_PATHS]; | ||
| 60 | struct device *power_dev; | 65 | struct device *power_dev; |
| 61 | struct imx8m_blk_ctrl *bc; | 66 | struct imx8m_blk_ctrl *bc; |
| 67 | int num_paths; | ||
| 62 | }; | 68 | }; |
| 63 | 69 | ||
| 64 | struct imx8m_blk_ctrl_data { | 70 | struct imx8m_blk_ctrl_data { |
| @@ -117,6 +123,10 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd) · 52 unmodified lines | |||
| 117 | if (data->mipi_phy_rst_mask) | 123 | if (data->mipi_phy_rst_mask) |
| 118 | regmap_set_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask); | 124 | regmap_set_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask); |
| 119 | 125 | ||
| 126 | ret = icc_bulk_set_bw(domain->num_paths, domain->paths); | ||
| 127 | if (ret) | ||
| 128 | dev_err(bc->dev, "failed to set icc bw\n"); | ||
| 129 | |||
| 120 | /* disable upstream clocks */ | 130 | /* disable upstream clocks */ |
| 121 | clk_bulk_disable_unprepare(data->num_clks, domain->clks); | 131 | clk_bulk_disable_unprepare(data->num_clks, domain->clks); |
| 122 | 132 | ||
| @@ -152,19 +162,6 @@ static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd) · 29 unmodified lines | |||
| 152 | return 0; | 162 | return 0; |
| 153 | } | 163 | } |
| 154 | 164 | ||
| 155 | static struct generic_pm_domain * | ||
| 156 | imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data) | ||
| 157 | { | ||
| 158 | struct genpd_onecell_data *onecell_data = data; | ||
| 159 | unsigned int index = args->args[0]; | ||
| 160 | |||
| 161 | if (args->args_count != 1 || | ||
| 162 | index >= onecell_data->num_domains) | ||
| 163 | return ERR_PTR(-EINVAL); | ||
| 164 | |||
| 165 | return onecell_data->domains[index]; | ||
| 166 | } | ||
| 167 | |||
| 168 | static struct lock_class_key blk_ctrl_genpd_lock_class; | 165 | static struct lock_class_key blk_ctrl_genpd_lock_class; |
| 169 | 166 | ||
| 170 | static int imx8m_blk_ctrl_probe(struct platform_device *pdev) | 167 | static int imx8m_blk_ctrl_probe(struct platform_device *pdev) |
| @@ -206,7 +203,6 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev) · 35 unmodified lines | |||
| 206 | return -ENOMEM; | 203 | return -ENOMEM; |
| 207 | 204 | ||
| 208 | bc->onecell_data.num_domains = bc_data->num_domains; | 205 | bc->onecell_data.num_domains = bc_data->num_domains; |
| 209 | bc->onecell_data.xlate = imx8m_blk_ctrl_xlate; | ||
| 210 | bc->onecell_data.domains = | 206 | bc->onecell_data.domains = |
| 211 | devm_kcalloc(dev, bc_data->num_domains, | 207 | devm_kcalloc(dev, bc_data->num_domains, |
| 212 | sizeof(struct generic_pm_domain *), GFP_KERNEL); | 208 | sizeof(struct generic_pm_domain *), GFP_KERNEL); |
| @@ -224,10 +220,29 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev) · 11 unmodified lines | |||
| 224 | int j; | 220 | int j; |
| 225 | 221 | ||
| 226 | domain->data = data; | 222 | domain->data = data; |
| 223 | domain->num_paths = data->num_paths; | ||
| 227 | 224 | ||
| 228 | for (j = 0; j < data->num_clks; j++) | 225 | for (j = 0; j < data->num_clks; j++) |
| 229 | domain->clks[j].id = data->clk_names[j]; | 226 | domain->clks[j].id = data->clk_names[j]; |
| 230 | 227 | ||
| 228 | for (j = 0; j < data->num_paths; j++) { | ||
| 229 | domain->paths[j].name = data->path_names[j]; | ||
| 230 | /* Fake value for now, just let ICC could configure NoC mode/priority */ | ||
| 231 | domain->paths[j].avg_bw = 1; | ||
| 232 | domain->paths[j].peak_bw = 1; | ||
| 233 | } | ||
| 234 | |||
| 235 | ret = devm_of_icc_bulk_get(dev, data->num_paths, domain->paths); | ||
| 236 | if (ret) { | ||
| 237 | if (ret != -EPROBE_DEFER) { | ||
| 238 | dev_warn_once(dev, "Could not get interconnect paths, NoC will stay unconfigured!\n"); | ||
| 239 | domain->num_paths = 0; | ||
| 240 | } else { | ||
| 241 | dev_err_probe(dev, ret, "failed to get noc entries\n"); | ||
| 242 | goto cleanup_pds; | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 231 | ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); | 246 | ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); |
| 232 | if (ret) { | 247 | if (ret) { |
| 233 | dev_err_probe(dev, ret, "failed to get clock\n"); | 248 | 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 = { · 220 unmodified lines | |||
| 454 | .num_domains = ARRAY_SIZE(imx8mm_vpu_blk_ctl_domain_data), | 469 | .num_domains = ARRAY_SIZE(imx8mm_vpu_blk_ctl_domain_data), |
| 455 | }; | 470 | }; |
| 456 | 471 | ||
| 472 | static const struct imx8m_blk_ctrl_domain_data imx8mp_vpu_blk_ctl_domain_data[] = { | ||
| 473 | [IMX8MP_VPUBLK_PD_G1] = { | ||
| 474 | .name = "vpublk-g1", | ||
| 475 | .clk_names = (const char *[]){ "g1", }, | ||
| 476 | .num_clks = 1, | ||
| 477 | .gpc_name = "g1", | ||
| 478 | .rst_mask = BIT(1), | ||
| 479 | .clk_mask = BIT(1), | ||
| 480 | .path_names = (const char *[]){"g1"}, | ||
| 481 | .num_paths = 1, | ||
| 482 | }, | ||
| 483 | [IMX8MP_VPUBLK_PD_G2] = { | ||
| 484 | .name = "vpublk-g2", | ||
| 485 | .clk_names = (const char *[]){ "g2", }, | ||
| 486 | .num_clks = 1, | ||
| 487 | .gpc_name = "g2", | ||
| 488 | .rst_mask = BIT(0), | ||
| 489 | .clk_mask = BIT(0), | ||
| 490 | .path_names = (const char *[]){"g2"}, | ||
| 491 | .num_paths = 1, | ||
| 492 | }, | ||
| 493 | [IMX8MP_VPUBLK_PD_VC8000E] = { | ||
| 494 | .name = "vpublk-vc8000e", | ||
| 495 | .clk_names = (const char *[]){ "vc8000e", }, | ||
| 496 | .num_clks = 1, | ||
| 497 | .gpc_name = "vc8000e", | ||
| 498 | .rst_mask = BIT(2), | ||
| 499 | .clk_mask = BIT(2), | ||
| 500 | .path_names = (const char *[]){"vc8000e"}, | ||
| 501 | .num_paths = 1, | ||
| 502 | }, | ||
| 503 | }; | ||
| 504 | |||
| 505 | static const struct imx8m_blk_ctrl_data imx8mp_vpu_blk_ctl_dev_data = { | ||
| 506 | .max_reg = 0x18, | ||
| 507 | .power_notifier_fn = imx8mm_vpu_power_notifier, | ||
| 508 | .domains = imx8mp_vpu_blk_ctl_domain_data, | ||
| 509 | .num_domains = ARRAY_SIZE(imx8mp_vpu_blk_ctl_domain_data), | ||
| 510 | }; | ||
| 511 | |||
| 457 | static int imx8mm_disp_power_notifier(struct notifier_block *nb, | 512 | static int imx8mm_disp_power_notifier(struct notifier_block *nb, |
| 458 | unsigned long action, void *data) | 513 | unsigned long action, void *data) |
| 459 | { | 514 | { |
| @@ -649,6 +704,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[ · 189 unmodified lines | |||
| 649 | .gpc_name = "lcdif1", | 704 | .gpc_name = "lcdif1", |
| 650 | .rst_mask = BIT(4) | BIT(5) | BIT(23), | 705 | .rst_mask = BIT(4) | BIT(5) | BIT(23), |
| 651 | .clk_mask = BIT(4) | BIT(5) | BIT(23), | 706 | .clk_mask = BIT(4) | BIT(5) | BIT(23), |
| 707 | .path_names = (const char *[]){"lcdif-rd", "lcdif-wr"}, | ||
| 708 | .num_paths = 2, | ||
| 652 | }, | 709 | }, |
| 653 | [IMX8MP_MEDIABLK_PD_ISI] = { | 710 | [IMX8MP_MEDIABLK_PD_ISI] = { |
| 654 | .name = "mediablk-isi", | 711 | .name = "mediablk-isi", |
| @@ -657,6 +714,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[ · 2 unmodified lines | |||
| 657 | .gpc_name = "isi", | 714 | .gpc_name = "isi", |
| 658 | .rst_mask = BIT(6) | BIT(7), | 715 | .rst_mask = BIT(6) | BIT(7), |
| 659 | .clk_mask = BIT(6) | BIT(7), | 716 | .clk_mask = BIT(6) | BIT(7), |
| 717 | .path_names = (const char *[]){"isi0", "isi1", "isi2"}, | ||
| 718 | .num_paths = 3, | ||
| 660 | }, | 719 | }, |
| 661 | [IMX8MP_MEDIABLK_PD_MIPI_CSI2_2] = { | 720 | [IMX8MP_MEDIABLK_PD_MIPI_CSI2_2] = { |
| 662 | .name = "mediablk-mipi-csi2-2", | 721 | .name = "mediablk-mipi-csi2-2", |
| @@ -674,6 +733,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[ · 11 unmodified lines | |||
| 674 | .gpc_name = "lcdif2", | 733 | .gpc_name = "lcdif2", |
| 675 | .rst_mask = BIT(11) | BIT(12) | BIT(24), | 734 | .rst_mask = BIT(11) | BIT(12) | BIT(24), |
| 676 | .clk_mask = BIT(11) | BIT(12) | BIT(24), | 735 | .clk_mask = BIT(11) | BIT(12) | BIT(24), |
| 736 | .path_names = (const char *[]){"lcdif-rd", "lcdif-wr"}, | ||
| 737 | .num_paths = 2, | ||
| 677 | }, | 738 | }, |
| 678 | [IMX8MP_MEDIABLK_PD_ISP] = { | 739 | [IMX8MP_MEDIABLK_PD_ISP] = { |
| 679 | .name = "mediablk-isp", | 740 | .name = "mediablk-isp", |
| @@ -682,6 +743,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[ · 2 unmodified lines | |||
| 682 | .gpc_name = "isp", | 743 | .gpc_name = "isp", |
| 683 | .rst_mask = BIT(16) | BIT(17) | BIT(18), | 744 | .rst_mask = BIT(16) | BIT(17) | BIT(18), |
| 684 | .clk_mask = BIT(16) | BIT(17) | BIT(18), | 745 | .clk_mask = BIT(16) | BIT(17) | BIT(18), |
| 746 | .path_names = (const char *[]){"isp0", "isp1"}, | ||
| 747 | .num_paths = 2, | ||
| 685 | }, | 748 | }, |
| 686 | [IMX8MP_MEDIABLK_PD_DWE] = { | 749 | [IMX8MP_MEDIABLK_PD_DWE] = { |
| 687 | .name = "mediablk-dwe", | 750 | .name = "mediablk-dwe", |
| @@ -690,6 +753,8 @@ static const struct imx8m_blk_ctrl_domain_data imx8mp_media_blk_ctl_domain_data[ · 2 unmodified lines | |||
| 690 | .gpc_name = "dwe", | 753 | .gpc_name = "dwe", |
| 691 | .rst_mask = BIT(19) | BIT(20) | BIT(21), | 754 | .rst_mask = BIT(19) | BIT(20) | BIT(21), |
| 692 | .clk_mask = BIT(19) | BIT(20) | BIT(21), | 755 | .clk_mask = BIT(19) | BIT(20) | BIT(21), |
| 756 | .path_names = (const char *[]){"dwe"}, | ||
| 757 | .num_paths = 1, | ||
| 693 | }, | 758 | }, |
| 694 | [IMX8MP_MEDIABLK_PD_MIPI_DSI_2] = { | 759 | [IMX8MP_MEDIABLK_PD_MIPI_DSI_2] = { |
| 695 | .name = "mediablk-mipi-dsi-2", | 760 | .name = "mediablk-mipi-dsi-2", |
| @@ -787,6 +852,9 @@ static const struct of_device_id imx8m_blk_ctrl_of_match[] = { · 91 unmodified lines | |||
| 787 | }, { | 852 | }, { |
| 788 | .compatible = "fsl,imx8mq-vpu-blk-ctrl", | 853 | .compatible = "fsl,imx8mq-vpu-blk-ctrl", |
| 789 | .data = &imx8mq_vpu_blk_ctl_dev_data | 854 | .data = &imx8mq_vpu_blk_ctl_dev_data |
| 855 | }, { | ||
| 856 | .compatible = "fsl,imx8mp-vpu-blk-ctrl", | ||
| 857 | .data = &imx8mp_vpu_blk_ctl_dev_data | ||
| 790 | }, { | 858 | }, { |
| 791 | /* Sentinel */ | 859 | /* Sentinel */ |
| 792 | } | 860 | } |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | #include <linux/clk.h> | 7 | #include <linux/clk.h> |
| 8 | #include <linux/device.h> | 8 | #include <linux/device.h> |
| 9 | #include <linux/interconnect.h> | ||
| 9 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 10 | #include <linux/of_device.h> | 11 | #include <linux/of_device.h> |
| 11 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
| @@ -18,6 +19,8 @@ · 6 unmodified lines | |||
| 18 | #define GPR_REG0 0x0 | 19 | #define GPR_REG0 0x0 |
| 19 | #define PCIE_CLOCK_MODULE_EN BIT(0) | 20 | #define PCIE_CLOCK_MODULE_EN BIT(0) |
| 20 | #define USB_CLOCK_MODULE_EN BIT(1) | 21 | #define USB_CLOCK_MODULE_EN BIT(1) |
| 22 | #define PCIE_PHY_APB_RST BIT(4) | ||
| 23 | #define PCIE_PHY_INIT_RST BIT(5) | ||
| 21 | 24 | ||
| 22 | struct imx8mp_blk_ctrl_domain; | 25 | struct imx8mp_blk_ctrl_domain; |
| 23 | 26 | ||
| @@ -36,17 +39,22 @@ struct imx8mp_blk_ctrl_domain_data { · 12 unmodified lines | |||
| 36 | const char *name; | 39 | const char *name; |
| 37 | const char * const *clk_names; | 40 | const char * const *clk_names; |
| 38 | int num_clks; | 41 | int num_clks; |
| 42 | const char * const *path_names; | ||
| 43 | int num_paths; | ||
| 39 | const char *gpc_name; | 44 | const char *gpc_name; |
| 40 | }; | 45 | }; |
| 41 | 46 | ||
| 42 | #define DOMAIN_MAX_CLKS 2 | 47 | #define DOMAIN_MAX_CLKS 2 |
| 48 | #define DOMAIN_MAX_PATHS 3 | ||
| 43 | 49 | ||
| 44 | struct imx8mp_blk_ctrl_domain { | 50 | struct imx8mp_blk_ctrl_domain { |
| 45 | struct generic_pm_domain genpd; | 51 | struct generic_pm_domain genpd; |
| 46 | const struct imx8mp_blk_ctrl_domain_data *data; | 52 | const struct imx8mp_blk_ctrl_domain_data *data; |
| 47 | struct clk_bulk_data clks[DOMAIN_MAX_CLKS]; | 53 | struct clk_bulk_data clks[DOMAIN_MAX_CLKS]; |
| 54 | struct icc_bulk_data paths[DOMAIN_MAX_PATHS]; | ||
| 48 | struct device *power_dev; | 55 | struct device *power_dev; |
| 49 | struct imx8mp_blk_ctrl *bc; | 56 | struct imx8mp_blk_ctrl *bc; |
| 57 | int num_paths; | ||
| 50 | int id; | 58 | int id; |
| 51 | }; | 59 | }; |
| 52 | 60 | ||
| @@ -75,6 +83,10 @@ static void imx8mp_hsio_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, · 22 unmodified lines | |||
| 75 | case IMX8MP_HSIOBLK_PD_PCIE: | 83 | case IMX8MP_HSIOBLK_PD_PCIE: |
| 76 | regmap_set_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN); | 84 | regmap_set_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN); |
| 77 | break; | 85 | break; |
| 86 | case IMX8MP_HSIOBLK_PD_PCIE_PHY: | ||
| 87 | regmap_set_bits(bc->regmap, GPR_REG0, | ||
| 88 | PCIE_PHY_APB_RST | PCIE_PHY_INIT_RST); | ||
| 89 | break; | ||
| 78 | default: | 90 | default: |
| 79 | break; | 91 | break; |
| 80 | } | 92 | } |
| @@ -90,6 +102,10 @@ static void imx8mp_hsio_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, · 9 unmodified lines | |||
| 90 | case IMX8MP_HSIOBLK_PD_PCIE: | 102 | case IMX8MP_HSIOBLK_PD_PCIE: |
| 91 | regmap_clear_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN); | 103 | regmap_clear_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN); |
| 92 | break; | 104 | break; |
| 105 | case IMX8MP_HSIOBLK_PD_PCIE_PHY: | ||
| 106 | regmap_clear_bits(bc->regmap, GPR_REG0, | ||
| 107 | PCIE_PHY_APB_RST | PCIE_PHY_INIT_RST); | ||
| 108 | break; | ||
| 93 | default: | 109 | default: |
| 94 | break; | 110 | break; |
| 95 | } | 111 | } |
| @@ -144,6 +160,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = { · 48 unmodified lines | |||
| 144 | .clk_names = (const char *[]){ "usb" }, | 160 | .clk_names = (const char *[]){ "usb" }, |
| 145 | .num_clks = 1, | 161 | .num_clks = 1, |
| 146 | .gpc_name = "usb", | 162 | .gpc_name = "usb", |
| 163 | .path_names = (const char *[]){"usb1", "usb2"}, | ||
| 164 | .num_paths = 2, | ||
| 147 | }, | 165 | }, |
| 148 | [IMX8MP_HSIOBLK_PD_USB_PHY1] = { | 166 | [IMX8MP_HSIOBLK_PD_USB_PHY1] = { |
| 149 | .name = "hsioblk-usb-phy1", | 167 | .name = "hsioblk-usb-phy1", |
| @@ -158,6 +176,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = { · 8 unmodified lines | |||
| 158 | .clk_names = (const char *[]){ "pcie" }, | 176 | .clk_names = (const char *[]){ "pcie" }, |
| 159 | .num_clks = 1, | 177 | .num_clks = 1, |
| 160 | .gpc_name = "pcie", | 178 | .gpc_name = "pcie", |
| 179 | .path_names = (const char *[]){"noc-pcie", "pcie"}, | ||
| 180 | .num_paths = 2, | ||
| 161 | }, | 181 | }, |
| 162 | [IMX8MP_HSIOBLK_PD_PCIE_PHY] = { | 182 | [IMX8MP_HSIOBLK_PD_PCIE_PHY] = { |
| 163 | .name = "hsioblk-pcie-phy", | 183 | .name = "hsioblk-pcie-phy", |
| @@ -225,6 +245,13 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, · 61 unmodified lines | |||
| 225 | regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); | 245 | regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); |
| 226 | regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3)); | 246 | regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3)); |
| 227 | break; | 247 | break; |
| 248 | case IMX8MP_HDMIBLK_PD_HDCP: | ||
| 249 | regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11)); | ||
| 250 | break; | ||
| 251 | case IMX8MP_HDMIBLK_PD_HRV: | ||
| 252 | regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5)); | ||
| 253 | regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15)); | ||
| 254 | break; | ||
| 228 | default: | 255 | default: |
| 229 | break; | 256 | break; |
| 230 | } | 257 | } |
| @@ -273,6 +300,13 @@ static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, · 42 unmodified lines | |||
| 273 | regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); | 300 | regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); |
| 274 | regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24)); | 301 | regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24)); |
| 275 | break; | 302 | break; |
| 303 | case IMX8MP_HDMIBLK_PD_HDCP: | ||
| 304 | regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(11)); | ||
| 305 | break; | ||
| 306 | case IMX8MP_HDMIBLK_PD_HRV: | ||
| 307 | regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(15)); | ||
| 308 | regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(3) | BIT(4) | BIT(5)); | ||
| 309 | break; | ||
| 276 | default: | 310 | default: |
| 277 | break; | 311 | break; |
| 278 | } | 312 | } |
| @@ -322,6 +356,8 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = { · 43 unmodified lines | |||
| 322 | .clk_names = (const char *[]){ "axi", "apb" }, | 356 | .clk_names = (const char *[]){ "axi", "apb" }, |
| 323 | .num_clks = 2, | 357 | .num_clks = 2, |
| 324 | .gpc_name = "lcdif", | 358 | .gpc_name = "lcdif", |
| 359 | .path_names = (const char *[]){"lcdif-hdmi"}, | ||
| 360 | .num_paths = 1, | ||
| 325 | }, | 361 | }, |
| 326 | [IMX8MP_HDMIBLK_PD_PAI] = { | 362 | [IMX8MP_HDMIBLK_PD_PAI] = { |
| 327 | .name = "hdmiblk-pai", | 363 | .name = "hdmiblk-pai", |
| @@ -353,6 +389,22 @@ static const struct imx8mp_blk_ctrl_domain_data imx8mp_hdmi_domain_data[] = { · 25 unmodified lines | |||
| 353 | .num_clks = 2, | 389 | .num_clks = 2, |
| 354 | .gpc_name = "hdmi-tx-phy", | 390 | .gpc_name = "hdmi-tx-phy", |
| 355 | }, | 391 | }, |
| 392 | [IMX8MP_HDMIBLK_PD_HRV] = { | ||
| 393 | .name = "hdmiblk-hrv", | ||
| 394 | .clk_names = (const char *[]){ "axi", "apb" }, | ||
| 395 | .num_clks = 2, | ||
| 396 | .gpc_name = "hrv", | ||
| 397 | .path_names = (const char *[]){"hrv"}, | ||
| 398 | .num_paths = 1, | ||
| 399 | }, | ||
| 400 | [IMX8MP_HDMIBLK_PD_HDCP] = { | ||
| 401 | .name = "hdmiblk-hdcp", | ||
| 402 | .clk_names = (const char *[]){ "axi", "apb" }, | ||
| 403 | .num_clks = 2, | ||
| 404 | .gpc_name = "hdcp", | ||
| 405 | .path_names = (const char *[]){"hdcp"}, | ||
| 406 | .num_paths = 1, | ||
| 407 | }, | ||
| 356 | }; | 408 | }; |
| 357 | 409 | ||
| 358 | static const struct imx8mp_blk_ctrl_data imx8mp_hdmi_blk_ctl_dev_data = { | 410 | 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) · 36 unmodified lines | |||
| 395 | goto clk_disable; | 447 | goto clk_disable; |
| 396 | } | 448 | } |
| 397 | 449 | ||
| 450 | ret = icc_bulk_set_bw(domain->num_paths, domain->paths); | ||
| 451 | if (ret) | ||
| 452 | dev_err(bc->dev, "failed to set icc bw\n"); | ||
| 453 | |||
| 398 | clk_bulk_disable_unprepare(data->num_clks, domain->clks); | 454 | clk_bulk_disable_unprepare(data->num_clks, domain->clks); |
| 399 | 455 | ||
| 400 | return 0; | 456 | return 0; |
| @@ -434,19 +490,6 @@ static int imx8mp_blk_ctrl_power_off(struct generic_pm_domain *genpd) · 33 unmodified lines | |||
| 434 | return 0; | 490 | return 0; |
| 435 | } | 491 | } |
| 436 | 492 | ||
| 437 | static struct generic_pm_domain * | ||
| 438 | imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data) | ||
| 439 | { | ||
| 440 | struct genpd_onecell_data *onecell_data = data; | ||
| 441 | unsigned int index = args->args[0]; | ||
| 442 | |||
| 443 | if (args->args_count != 1 || | ||
| 444 | index >= onecell_data->num_domains) | ||
| 445 | return ERR_PTR(-EINVAL); | ||
| 446 | |||
| 447 | return onecell_data->domains[index]; | ||
| 448 | } | ||
| 449 | |||
| 450 | static struct lock_class_key blk_ctrl_genpd_lock_class; | 493 | static struct lock_class_key blk_ctrl_genpd_lock_class; |
| 451 | 494 | ||
| 452 | static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) | 495 | static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) |
| @@ -489,7 +532,6 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) · 36 unmodified lines | |||
| 489 | return -ENOMEM; | 532 | return -ENOMEM; |
| 490 | 533 | ||
| 491 | bc->onecell_data.num_domains = num_domains; | 534 | bc->onecell_data.num_domains = num_domains; |
| 492 | bc->onecell_data.xlate = imx8m_blk_ctrl_xlate; | ||
| 493 | bc->onecell_data.domains = | 535 | bc->onecell_data.domains = |
| 494 | devm_kcalloc(dev, num_domains, | 536 | devm_kcalloc(dev, num_domains, |
| 495 | sizeof(struct generic_pm_domain *), GFP_KERNEL); | 537 | sizeof(struct generic_pm_domain *), GFP_KERNEL); |
| @@ -510,10 +552,29 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) · 14 unmodified lines | |||
| 510 | int j; | 552 | int j; |
| 511 | 553 | ||
| 512 | domain->data = data; | 554 | domain->data = data; |
| 555 | domain->num_paths = data->num_paths; | ||
| 513 | 556 | ||
| 514 | for (j = 0; j < data->num_clks; j++) | 557 | for (j = 0; j < data->num_clks; j++) |
| 515 | domain->clks[j].id = data->clk_names[j]; | 558 | domain->clks[j].id = data->clk_names[j]; |
| 516 | 559 | ||
| 560 | for (j = 0; j < data->num_paths; j++) { | ||
| 561 | domain->paths[j].name = data->path_names[j]; | ||
| 562 | /* Fake value for now, just let ICC could configure NoC mode/priority */ | ||
| 563 | domain->paths[j].avg_bw = 1; | ||
| 564 | domain->paths[j].peak_bw = 1; | ||
| 565 | } | ||
| 566 | |||
| 567 | ret = devm_of_icc_bulk_get(dev, data->num_paths, domain->paths); | ||
| 568 | if (ret) { | ||
| 569 | if (ret != -EPROBE_DEFER) { | ||
| 570 | dev_warn_once(dev, "Could not get interconnect paths, NoC will stay unconfigured!\n"); | ||
| 571 | domain->num_paths = 0; | ||
| 572 | } else { | ||
| 573 | dev_err_probe(dev, ret, "failed to get noc entries\n"); | ||
| 574 | goto cleanup_pds; | ||
| 575 | } | ||
| 576 | } | ||
| 577 | |||
| 517 | ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); | 578 | ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); |
| 518 | if (ret) { | 579 | if (ret) { |
| 519 | dev_err_probe(dev, ret, "failed to get clock\n"); | 580 | dev_err_probe(dev, ret, "failed to get clock\n"); |
| @@ -0,0 +1,436 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Copyright 2022 NXP, Peng Fan <peng.fan@nxp.com> | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/clk.h> | ||
| 7 | #include <linux/device.h> | ||
| 8 | #include <linux/module.h> | ||
| 9 | #include <linux/of_device.h> | ||
| 10 | #include <linux/platform_device.h> | ||
| 11 | #include <linux/pm_domain.h> | ||
| 12 | #include <linux/pm_runtime.h> | ||
| 13 | #include <linux/regmap.h> | ||
| 14 | #include <linux/sizes.h> | ||
| 15 | |||
| 16 | #include <dt-bindings/power/fsl,imx93-power.h> | ||
| 17 | |||
| 18 | #define BLK_SFT_RSTN 0x0 | ||
| 19 | #define BLK_CLK_EN 0x4 | ||
| 20 | #define BLK_MAX_CLKS 4 | ||
| 21 | |||
| 22 | #define DOMAIN_MAX_CLKS 4 | ||
| 23 | |||
| 24 | #define LCDIF_QOS_REG 0xC | ||
| 25 | #define LCDIF_DEFAULT_QOS_OFF 12 | ||
| 26 | #define LCDIF_CFG_QOS_OFF 8 | ||
| 27 | |||
| 28 | #define PXP_QOS_REG 0x10 | ||
| 29 | #define PXP_R_DEFAULT_QOS_OFF 28 | ||
| 30 | #define PXP_R_CFG_QOS_OFF 24 | ||
| 31 | #define PXP_W_DEFAULT_QOS_OFF 20 | ||
| 32 | #define PXP_W_CFG_QOS_OFF 16 | ||
| 33 | |||
| 34 | #define ISI_CACHE_REG 0x14 | ||
| 35 | |||
| 36 | #define ISI_QOS_REG 0x1C | ||
| 37 | #define ISI_V_DEFAULT_QOS_OFF 28 | ||
| 38 | #define ISI_V_CFG_QOS_OFF 24 | ||
| 39 | #define ISI_U_DEFAULT_QOS_OFF 20 | ||
| 40 | #define ISI_U_CFG_QOS_OFF 16 | ||
| 41 | #define ISI_Y_R_DEFAULT_QOS_OFF 12 | ||
| 42 | #define ISI_Y_R_CFG_QOS_OFF 8 | ||
| 43 | #define ISI_Y_W_DEFAULT_QOS_OFF 4 | ||
| 44 | #define ISI_Y_W_CFG_QOS_OFF 0 | ||
| 45 | |||
| 46 | #define PRIO_MASK 0xF | ||
| 47 | |||
| 48 | #define PRIO(X) (X) | ||
| 49 | |||
| 50 | struct imx93_blk_ctrl_domain; | ||
| 51 | |||
| 52 | struct imx93_blk_ctrl { | ||
| 53 | struct device *dev; | ||
| 54 | struct regmap *regmap; | ||
| 55 | int num_clks; | ||
| 56 | struct clk_bulk_data clks[BLK_MAX_CLKS]; | ||
| 57 | struct imx93_blk_ctrl_domain *domains; | ||
| 58 | struct genpd_onecell_data onecell_data; | ||
| 59 | }; | ||
| 60 | |||
| 61 | #define DOMAIN_MAX_QOS 4 | ||
| 62 | |||
| 63 | struct imx93_blk_ctrl_qos { | ||
| 64 | u32 reg; | ||
| 65 | u32 cfg_off; | ||
| 66 | u32 default_prio; | ||
| 67 | u32 cfg_prio; | ||
| 68 | }; | ||
| 69 | |||
| 70 | struct imx93_blk_ctrl_domain_data { | ||
| 71 | const char *name; | ||
| 72 | const char * const *clk_names; | ||
| 73 | int num_clks; | ||
| 74 | u32 rst_mask; | ||
| 75 | u32 clk_mask; | ||
| 76 | int num_qos; | ||
| 77 | struct imx93_blk_ctrl_qos qos[DOMAIN_MAX_QOS]; | ||
| 78 | }; | ||
| 79 | |||
| 80 | struct imx93_blk_ctrl_domain { | ||
| 81 | struct generic_pm_domain genpd; | ||
| 82 | const struct imx93_blk_ctrl_domain_data *data; | ||
| 83 | struct clk_bulk_data clks[DOMAIN_MAX_CLKS]; | ||
| 84 | struct imx93_blk_ctrl *bc; | ||
| 85 | }; | ||
| 86 | |||
| 87 | struct imx93_blk_ctrl_data { | ||
| 88 | const struct imx93_blk_ctrl_domain_data *domains; | ||
| 89 | int num_domains; | ||
| 90 | const char * const *clk_names; | ||
| 91 | int num_clks; | ||
| 92 | const struct regmap_access_table *reg_access_table; | ||
| 93 | }; | ||
| 94 | |||
| 95 | static inline struct imx93_blk_ctrl_domain * | ||
| 96 | to_imx93_blk_ctrl_domain(struct generic_pm_domain *genpd) | ||
| 97 | { | ||
| 98 | return container_of(genpd, struct imx93_blk_ctrl_domain, genpd); | ||
| 99 | } | ||
| 100 | |||
| 101 | static int imx93_blk_ctrl_set_qos(struct imx93_blk_ctrl_domain *domain) | ||
| 102 | { | ||
| 103 | const struct imx93_blk_ctrl_domain_data *data = domain->data; | ||
| 104 | struct imx93_blk_ctrl *bc = domain->bc; | ||
| 105 | const struct imx93_blk_ctrl_qos *qos; | ||
| 106 | u32 val, mask; | ||
| 107 | int i; | ||
| 108 | |||
| 109 | for (i = 0; i < data->num_qos; i++) { | ||
| 110 | qos = &data->qos[i]; | ||
| 111 | |||
| 112 | mask = PRIO_MASK << qos->cfg_off; | ||
| 113 | mask |= PRIO_MASK << (qos->cfg_off + 4); | ||
| 114 | val = qos->cfg_prio << qos->cfg_off; | ||
| 115 | val |= qos->default_prio << (qos->cfg_off + 4); | ||
| 116 | |||
| 117 | regmap_write_bits(bc->regmap, qos->reg, mask, val); | ||
| 118 | |||
| 119 | dev_dbg(bc->dev, "data->qos[i].reg 0x%x 0x%x\n", qos->reg, val); | ||
| 120 | } | ||
| 121 | |||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | static int imx93_blk_ctrl_power_on(struct generic_pm_domain *genpd) | ||
| 126 | { | ||
| 127 | struct imx93_blk_ctrl_domain *domain = to_imx93_blk_ctrl_domain(genpd); | ||
| 128 | const struct imx93_blk_ctrl_domain_data *data = domain->data; | ||
| 129 | struct imx93_blk_ctrl *bc = domain->bc; | ||
| 130 | int ret; | ||
| 131 | |||
| 132 | ret = clk_bulk_prepare_enable(bc->num_clks, bc->clks); | ||
| 133 | if (ret) { | ||
| 134 | dev_err(bc->dev, "failed to enable bus clocks\n"); | ||
| 135 | return ret; | ||
| 136 | } | ||
| 137 | |||
| 138 | ret = clk_bulk_prepare_enable(data->num_clks, domain->clks); | ||
| 139 | if (ret) { | ||
| 140 | clk_bulk_disable_unprepare(bc->num_clks, bc->clks); | ||
| 141 | dev_err(bc->dev, "failed to enable clocks\n"); | ||
| 142 | return ret; | ||
| 143 | } | ||
| 144 | |||
| 145 | ret = pm_runtime_get_sync(bc->dev); | ||
| 146 | if (ret < 0) { | ||
| 147 | pm_runtime_put_noidle(bc->dev); | ||
| 148 | dev_err(bc->dev, "failed to power up domain\n"); | ||
| 149 | goto disable_clk; | ||
| 150 | } | ||
| 151 | |||
| 152 | /* ungate clk */ | ||
| 153 | regmap_clear_bits(bc->regmap, BLK_CLK_EN, data->clk_mask); | ||
| 154 | |||
| 155 | /* release reset */ | ||
| 156 | regmap_set_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask); | ||
| 157 | |||
| 158 | dev_dbg(bc->dev, "pd_on: name: %s\n", genpd->name); | ||
| 159 | |||
| 160 | return imx93_blk_ctrl_set_qos(domain); | ||
| 161 | |||
| 162 | disable_clk: | ||
| 163 | clk_bulk_disable_unprepare(data->num_clks, domain->clks); | ||
| 164 | |||
| 165 | clk_bulk_disable_unprepare(bc->num_clks, bc->clks); | ||
| 166 | |||
| 167 | return ret; | ||
| 168 | } | ||
| 169 | |||
| 170 | static int imx93_blk_ctrl_power_off(struct generic_pm_domain *genpd) | ||
| 171 | { | ||
| 172 | struct imx93_blk_ctrl_domain *domain = to_imx93_blk_ctrl_domain(genpd); | ||
| 173 | const struct imx93_blk_ctrl_domain_data *data = domain->data; | ||
| 174 | struct imx93_blk_ctrl *bc = domain->bc; | ||
| 175 | |||
| 176 | dev_dbg(bc->dev, "pd_off: name: %s\n", genpd->name); | ||
| 177 | |||
| 178 | regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask); | ||
| 179 | regmap_set_bits(bc->regmap, BLK_CLK_EN, data->clk_mask); | ||
| 180 | |||
| 181 | pm_runtime_put(bc->dev); | ||
| 182 | |||
| 183 | clk_bulk_disable_unprepare(data->num_clks, domain->clks); | ||
| 184 | |||
| 185 | clk_bulk_disable_unprepare(bc->num_clks, bc->clks); | ||
| 186 | |||
| 187 | return 0; | ||
| 188 | } | ||
| 189 | |||
| 190 | static int imx93_blk_ctrl_probe(struct platform_device *pdev) | ||
| 191 | { | ||
| 192 | struct device *dev = &pdev->dev; | ||
| 193 | const struct imx93_blk_ctrl_data *bc_data = of_device_get_match_data(dev); | ||
| 194 | struct imx93_blk_ctrl *bc; | ||
| 195 | void __iomem *base; | ||
| 196 | int i, ret; | ||
| 197 | |||
| 198 | struct regmap_config regmap_config = { | ||
| 199 | .reg_bits = 32, | ||
| 200 | .val_bits = 32, | ||
| 201 | .reg_stride = 4, | ||
| 202 | .rd_table = bc_data->reg_access_table, | ||
| 203 | .wr_table = bc_data->reg_access_table, | ||
| 204 | .max_register = SZ_4K, | ||
| 205 | }; | ||
| 206 | |||
| 207 | bc = devm_kzalloc(dev, sizeof(*bc), GFP_KERNEL); | ||
| 208 | if (!bc) | ||
| 209 | return -ENOMEM; | ||
| 210 | |||
| 211 | bc->dev = dev; | ||
| 212 | |||
| 213 | base = devm_platform_ioremap_resource(pdev, 0); | ||
| 214 | if (IS_ERR(base)) | ||
| 215 | return PTR_ERR(base); | ||
| 216 | |||
| 217 | bc->regmap = devm_regmap_init_mmio(dev, base, ®map_config); | ||
| 218 | if (IS_ERR(bc->regmap)) | ||
| 219 | return dev_err_probe(dev, PTR_ERR(bc->regmap), | ||
| 220 | "failed to init regmap\n"); | ||
| 221 | |||
| 222 | bc->domains = devm_kcalloc(dev, bc_data->num_domains, | ||
| 223 | sizeof(struct imx93_blk_ctrl_domain), | ||
| 224 | GFP_KERNEL); | ||
| 225 | if (!bc->domains) | ||
| 226 | return -ENOMEM; | ||
| 227 | |||
| 228 | bc->onecell_data.num_domains = bc_data->num_domains; | ||
| 229 | bc->onecell_data.domains = | ||
| 230 | devm_kcalloc(dev, bc_data->num_domains, | ||
| 231 | sizeof(struct generic_pm_domain *), GFP_KERNEL); | ||
| 232 | if (!bc->onecell_data.domains) | ||
| 233 | return -ENOMEM; | ||
| 234 | |||
| 235 | for (i = 0; i < bc_data->num_clks; i++) | ||
| 236 | bc->clks[i].id = bc_data->clk_names[i]; | ||
| 237 | bc->num_clks = bc_data->num_clks; | ||
| 238 | |||
| 239 | ret = devm_clk_bulk_get(dev, bc->num_clks, bc->clks); | ||
| 240 | if (ret) { | ||
| 241 | dev_err_probe(dev, ret, "failed to get bus clock\n"); | ||
| 242 | return ret; | ||
| 243 | } | ||
| 244 | |||
| 245 | for (i = 0; i < bc_data->num_domains; i++) { | ||
| 246 | const struct imx93_blk_ctrl_domain_data *data = &bc_data->domains[i]; | ||
| 247 | struct imx93_blk_ctrl_domain *domain = &bc->domains[i]; | ||
| 248 | int j; | ||
| 249 | |||
| 250 | domain->data = data; | ||
| 251 | |||
| 252 | for (j = 0; j < data->num_clks; j++) | ||
| 253 | domain->clks[j].id = data->clk_names[j]; | ||
| 254 | |||
| 255 | ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); | ||
| 256 | if (ret) { | ||
| 257 | dev_err_probe(dev, ret, "failed to get clock\n"); | ||
| 258 | goto cleanup_pds; | ||
| 259 | } | ||
| 260 | |||
| 261 | domain->genpd.name = data->name; | ||
| 262 | domain->genpd.power_on = imx93_blk_ctrl_power_on; | ||
| 263 | domain->genpd.power_off = imx93_blk_ctrl_power_off; | ||
| 264 | domain->bc = bc; | ||
| 265 | |||
| 266 | ret = pm_genpd_init(&domain->genpd, NULL, true); | ||
| 267 | if (ret) { | ||
| 268 | dev_err_probe(dev, ret, "failed to init power domain\n"); | ||
| 269 | goto cleanup_pds; | ||
| 270 | } | ||
| 271 | |||
| 272 | bc->onecell_data.domains[i] = &domain->genpd; | ||
| 273 | } | ||
| 274 | |||
| 275 | pm_runtime_enable(dev); | ||
| 276 | |||
| 277 | ret = of_genpd_add_provider_onecell(dev->of_node, &bc->onecell_data); | ||
| 278 | if (ret) { | ||
| 279 | dev_err_probe(dev, ret, "failed to add power domain provider\n"); | ||
| 280 | goto cleanup_pds; | ||
| 281 | } | ||
| 282 | |||
| 283 | dev_set_drvdata(dev, bc); | ||
| 284 | |||
| 285 | return 0; | ||
| 286 | |||
| 287 | cleanup_pds: | ||
| 288 | for (i--; i >= 0; i--) | ||
| 289 | pm_genpd_remove(&bc->domains[i].genpd); | ||
| 290 | |||
| 291 | return ret; | ||
| 292 | } | ||
| 293 | |||
| 294 | static int imx93_blk_ctrl_remove(struct platform_device *pdev) | ||
| 295 | { | ||
| 296 | struct imx93_blk_ctrl *bc = dev_get_drvdata(&pdev->dev); | ||
| 297 | int i; | ||
| 298 | |||
| 299 | of_genpd_del_provider(pdev->dev.of_node); | ||
| 300 | |||
| 301 | for (i = 0; bc->onecell_data.num_domains; i++) { | ||
| 302 | struct imx93_blk_ctrl_domain *domain = &bc->domains[i]; | ||
| 303 | |||
| 304 | pm_genpd_remove(&domain->genpd); | ||
| 305 | } | ||
| 306 | |||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 310 | static const struct imx93_blk_ctrl_domain_data imx93_media_blk_ctl_domain_data[] = { | ||
| 311 | [IMX93_MEDIABLK_PD_MIPI_DSI] = { | ||
| 312 | .name = "mediablk-mipi-dsi", | ||
| 313 | .clk_names = (const char *[]){ "dsi" }, | ||
| 314 | .num_clks = 1, | ||
| 315 | .rst_mask = BIT(11) | BIT(12), | ||
| 316 | .clk_mask = BIT(11) | BIT(12), | ||
| 317 | }, | ||
| 318 | [IMX93_MEDIABLK_PD_MIPI_CSI] = { | ||
| 319 | .name = "mediablk-mipi-csi", | ||
| 320 | .clk_names = (const char *[]){ "cam", "csi" }, | ||
| 321 | .num_clks = 2, | ||
| 322 | .rst_mask = BIT(9) | BIT(10), | ||
| 323 | .clk_mask = BIT(9) | BIT(10), | ||
| 324 | }, | ||
| 325 | [IMX93_MEDIABLK_PD_PXP] = { | ||
| 326 | .name = "mediablk-pxp", | ||
| 327 | .clk_names = (const char *[]){ "pxp" }, | ||
| 328 | .num_clks = 1, | ||
| 329 | .rst_mask = BIT(7) | BIT(8), | ||
| 330 | .clk_mask = BIT(7) | BIT(8), | ||
| 331 | .num_qos = 2, | ||
| 332 | .qos = { | ||
| 333 | { | ||
| 334 | .reg = PXP_QOS_REG, | ||
| 335 | .cfg_off = PXP_R_CFG_QOS_OFF, | ||
| 336 | .default_prio = PRIO(3), | ||
| 337 | .cfg_prio = PRIO(6), | ||
| 338 | }, { | ||
| 339 | .reg = PXP_QOS_REG, | ||
| 340 | .cfg_off = PXP_W_CFG_QOS_OFF, | ||
| 341 | .default_prio = PRIO(3), | ||
| 342 | .cfg_prio = PRIO(6), | ||
| 343 | } | ||
| 344 | } | ||
| 345 | }, | ||
| 346 | [IMX93_MEDIABLK_PD_LCDIF] = { | ||
| 347 | .name = "mediablk-lcdif", | ||
| 348 | .clk_names = (const char *[]){ "disp", "lcdif" }, | ||
| 349 | .num_clks = 2, | ||
| 350 | .rst_mask = BIT(4) | BIT(5) | BIT(6), | ||
| 351 | .clk_mask = BIT(4) | BIT(5) | BIT(6), | ||
| 352 | .num_qos = 1, | ||
| 353 | .qos = { | ||
| 354 | { | ||
| 355 | .reg = LCDIF_QOS_REG, | ||
| 356 | .cfg_off = LCDIF_CFG_QOS_OFF, | ||
| 357 | .default_prio = PRIO(3), | ||
| 358 | .cfg_prio = PRIO(7), | ||
| 359 | } | ||
| 360 | } | ||
| 361 | }, | ||
| 362 | [IMX93_MEDIABLK_PD_ISI] = { | ||
| 363 | .name = "mediablk-isi", | ||
| 364 | .clk_names = (const char *[]){ "isi" }, | ||
| 365 | .num_clks = 1, | ||
| 366 | .rst_mask = BIT(2) | BIT(3), | ||
| 367 | .clk_mask = BIT(2) | BIT(3), | ||
| 368 | .num_qos = 4, | ||
| 369 | .qos = { | ||
| 370 | { | ||
| 371 | .reg = ISI_QOS_REG, | ||
| 372 | .cfg_off = ISI_Y_W_CFG_QOS_OFF, | ||
| 373 | .default_prio = PRIO(3), | ||
| 374 | .cfg_prio = PRIO(7), | ||
| 375 | }, { | ||
| 376 | .reg = ISI_QOS_REG, | ||
| 377 | .cfg_off = ISI_Y_R_CFG_QOS_OFF, | ||
| 378 | .default_prio = PRIO(3), | ||
| 379 | .cfg_prio = PRIO(7), | ||
| 380 | }, { | ||
| 381 | .reg = ISI_QOS_REG, | ||
| 382 | .cfg_off = ISI_U_CFG_QOS_OFF, | ||
| 383 | .default_prio = PRIO(3), | ||
| 384 | .cfg_prio = PRIO(7), | ||
| 385 | }, { | ||
| 386 | .reg = ISI_QOS_REG, | ||
| 387 | .cfg_off = ISI_V_CFG_QOS_OFF, | ||
| 388 | .default_prio = PRIO(3), | ||
| 389 | .cfg_prio = PRIO(7), | ||
| 390 | } | ||
| 391 | } | ||
| 392 | }, | ||
| 393 | }; | ||
| 394 | |||
| 395 | static const struct regmap_range imx93_media_blk_ctl_yes_ranges[] = { | ||
| 396 | regmap_reg_range(BLK_SFT_RSTN, BLK_CLK_EN), | ||
| 397 | regmap_reg_range(LCDIF_QOS_REG, ISI_CACHE_REG), | ||
| 398 | regmap_reg_range(ISI_QOS_REG, ISI_QOS_REG), | ||
| 399 | }; | ||
| 400 | |||
| 401 | static const struct regmap_access_table imx93_media_blk_ctl_access_table = { | ||
| 402 | .yes_ranges = imx93_media_blk_ctl_yes_ranges, | ||
| 403 | .n_yes_ranges = ARRAY_SIZE(imx93_media_blk_ctl_yes_ranges), | ||
| 404 | }; | ||
| 405 | |||
| 406 | static const struct imx93_blk_ctrl_data imx93_media_blk_ctl_dev_data = { | ||
| 407 | .domains = imx93_media_blk_ctl_domain_data, | ||
| 408 | .num_domains = ARRAY_SIZE(imx93_media_blk_ctl_domain_data), | ||
| 409 | .clk_names = (const char *[]){ "axi", "apb", "nic", }, | ||
| 410 | .num_clks = 3, | ||
| 411 | .reg_access_table = &imx93_media_blk_ctl_access_table, | ||
| 412 | }; | ||
| 413 | |||
| 414 | static const struct of_device_id imx93_blk_ctrl_of_match[] = { | ||
| 415 | { | ||
| 416 | .compatible = "fsl,imx93-media-blk-ctrl", | ||
| 417 | .data = &imx93_media_blk_ctl_dev_data | ||
| 418 | }, { | ||
| 419 | /* Sentinel */ | ||
| 420 | } | ||
| 421 | }; | ||
| 422 | MODULE_DEVICE_TABLE(of, imx93_blk_ctrl_of_match); | ||
| 423 | |||
| 424 | static struct platform_driver imx93_blk_ctrl_driver = { | ||
| 425 | .probe = imx93_blk_ctrl_probe, | ||
| 426 | .remove = imx93_blk_ctrl_remove, | ||
| 427 | .driver = { | ||
| 428 | .name = "imx93-blk-ctrl", | ||
| 429 | .of_match_table = imx93_blk_ctrl_of_match, | ||
| 430 | }, | ||
| 431 | }; | ||
| 432 | module_platform_driver(imx93_blk_ctrl_driver); | ||
| 433 | |||
| 434 | MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>"); | ||
| 435 | MODULE_DESCRIPTION("i.MX93 BLK CTRL driver"); | ||
| 436 | MODULE_LICENSE("GPL"); | ||
| @@ -0,0 +1,164 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Copyright 2022 NXP | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/clk.h> | ||
| 7 | #include <linux/delay.h> | ||
| 8 | #include <linux/of_device.h> | ||
| 9 | #include <linux/iopoll.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/platform_device.h> | ||
| 12 | #include <linux/pm_domain.h> | ||
| 13 | |||
| 14 | #define MIX_SLICE_SW_CTRL_OFF 0x20 | ||
| 15 | #define SLICE_SW_CTRL_PSW_CTRL_OFF_MASK BIT(4) | ||
| 16 | #define SLICE_SW_CTRL_PDN_SOFT_MASK BIT(31) | ||
| 17 | |||
| 18 | #define MIX_FUNC_STAT_OFF 0xB4 | ||
| 19 | |||
| 20 | #define FUNC_STAT_PSW_STAT_MASK BIT(0) | ||
| 21 | #define FUNC_STAT_RST_STAT_MASK BIT(2) | ||
| 22 | #define FUNC_STAT_ISO_STAT_MASK BIT(4) | ||
| 23 | |||
| 24 | struct imx93_power_domain { | ||
| 25 | struct generic_pm_domain genpd; | ||
| 26 | struct device *dev; | ||
| 27 | void __iomem *addr; | ||
| 28 | struct clk_bulk_data *clks; | ||
| 29 | int num_clks; | ||
| 30 | bool init_off; | ||
| 31 | }; | ||
| 32 | |||
| 33 | #define to_imx93_pd(_genpd) container_of(_genpd, struct imx93_power_domain, genpd) | ||
| 34 | |||
| 35 | static int imx93_pd_on(struct generic_pm_domain *genpd) | ||
| 36 | { | ||
| 37 | struct imx93_power_domain *domain = to_imx93_pd(genpd); | ||
| 38 | void __iomem *addr = domain->addr; | ||
| 39 | u32 val; | ||
| 40 | int ret; | ||
| 41 | |||
| 42 | ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks); | ||
| 43 | if (ret) { | ||
| 44 | dev_err(domain->dev, "failed to enable clocks for domain: %s\n", genpd->name); | ||
| 45 | return ret; | ||
| 46 | } | ||
| 47 | |||
| 48 | val = readl(addr + MIX_SLICE_SW_CTRL_OFF); | ||
| 49 | val &= ~SLICE_SW_CTRL_PDN_SOFT_MASK; | ||
| 50 | writel(val, addr + MIX_SLICE_SW_CTRL_OFF); | ||
| 51 | |||
| 52 | ret = readl_poll_timeout(addr + MIX_FUNC_STAT_OFF, val, | ||
| 53 | !(val & FUNC_STAT_ISO_STAT_MASK), 1, 10000); | ||
| 54 | if (ret) { | ||
| 55 | dev_err(domain->dev, "pd_on timeout: name: %s, stat: %x\n", genpd->name, val); | ||
| 56 | return ret; | ||
| 57 | } | ||
| 58 | |||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | |||
| 62 | static int imx93_pd_off(struct generic_pm_domain *genpd) | ||
| 63 | { | ||
| 64 | struct imx93_power_domain *domain = to_imx93_pd(genpd); | ||
| 65 | void __iomem *addr = domain->addr; | ||
| 66 | int ret; | ||
| 67 | u32 val; | ||
| 68 | |||
| 69 | /* Power off MIX */ | ||
| 70 | val = readl(addr + MIX_SLICE_SW_CTRL_OFF); | ||
| 71 | val |= SLICE_SW_CTRL_PDN_SOFT_MASK; | ||
| 72 | writel(val, addr + MIX_SLICE_SW_CTRL_OFF); | ||
| 73 | |||
| 74 | ret = readl_poll_timeout(addr + MIX_FUNC_STAT_OFF, val, | ||
| 75 | val & FUNC_STAT_PSW_STAT_MASK, 1, 1000); | ||
| 76 | if (ret) { | ||
| 77 | dev_err(domain->dev, "pd_off timeout: name: %s, stat: %x\n", genpd->name, val); | ||
| 78 | return ret; | ||
| 79 | } | ||
| 80 | |||
| 81 | clk_bulk_disable_unprepare(domain->num_clks, domain->clks); | ||
| 82 | |||
| 83 | return 0; | ||
| 84 | }; | ||
| 85 | |||
| 86 | static int imx93_pd_remove(struct platform_device *pdev) | ||
| 87 | { | ||
| 88 | struct imx93_power_domain *domain = platform_get_drvdata(pdev); | ||
| 89 | struct device *dev = &pdev->dev; | ||
| 90 | struct device_node *np = dev->of_node; | ||
| 91 | |||
| 92 | if (!domain->init_off) | ||
| 93 | clk_bulk_disable_unprepare(domain->num_clks, domain->clks); | ||
| 94 | |||
| 95 | of_genpd_del_provider(np); | ||
| 96 | pm_genpd_remove(&domain->genpd); | ||
| 97 | |||
| 98 | return 0; | ||
| 99 | } | ||
| 100 | |||
| 101 | static int imx93_pd_probe(struct platform_device *pdev) | ||
| 102 | { | ||
| 103 | struct device *dev = &pdev->dev; | ||
| 104 | struct device_node *np = dev->of_node; | ||
| 105 | struct imx93_power_domain *domain; | ||
| 106 | int ret; | ||
| 107 | |||
| 108 | domain = devm_kzalloc(dev, sizeof(*domain), GFP_KERNEL); | ||
| 109 | if (!domain) | ||
| 110 | return -ENOMEM; | ||
| 111 | |||
| 112 | domain->addr = devm_platform_ioremap_resource(pdev, 0); | ||
| 113 | if (IS_ERR(domain->addr)) | ||
| 114 | return PTR_ERR(domain->addr); | ||
| 115 | |||
| 116 | domain->num_clks = devm_clk_bulk_get_all(dev, &domain->clks); | ||
| 117 | if (domain->num_clks < 0) | ||
| 118 | return dev_err_probe(dev, domain->num_clks, "Failed to get domain's clocks\n"); | ||
| 119 | |||
| 120 | domain->genpd.name = dev_name(dev); | ||
| 121 | domain->genpd.power_off = imx93_pd_off; | ||
| 122 | domain->genpd.power_on = imx93_pd_on; | ||
| 123 | domain->dev = dev; | ||
| 124 | |||
| 125 | domain->init_off = readl(domain->addr + MIX_FUNC_STAT_OFF) & FUNC_STAT_ISO_STAT_MASK; | ||
| 126 | /* Just to sync the status of hardware */ | ||
| 127 | if (!domain->init_off) { | ||
| 128 | ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks); | ||
| 129 | if (ret) { | ||
| 130 | dev_err(domain->dev, "failed to enable clocks for domain: %s\n", | ||
| 131 | domain->genpd.name); | ||
| 132 | return ret; | ||
| 133 | } | ||
| 134 | } | ||
| 135 | |||
| 136 | ret = pm_genpd_init(&domain->genpd, NULL, domain->init_off); | ||
| 137 | if (ret) | ||
| 138 | return ret; | ||
| 139 | |||
| 140 | platform_set_drvdata(pdev, domain); | ||
| 141 | |||
| 142 | return of_genpd_add_provider_simple(np, &domain->genpd); | ||
| 143 | } | ||
| 144 | |||
| 145 | static const struct of_device_id imx93_pd_ids[] = { | ||
| 146 | { .compatible = "fsl,imx93-src-slice" }, | ||
| 147 | { } | ||
| 148 | }; | ||
| 149 | MODULE_DEVICE_TABLE(of, imx93_pd_ids); | ||
| 150 | |||
| 151 | static struct platform_driver imx93_power_domain_driver = { | ||
| 152 | .driver = { | ||
| 153 | .name = "imx93_power_domain", | ||
| 154 | .owner = THIS_MODULE, | ||
| 155 | .of_match_table = imx93_pd_ids, | ||
| 156 | }, | ||
| 157 | .probe = imx93_pd_probe, | ||
| 158 | .remove = imx93_pd_remove, | ||
| 159 | }; | ||
| 160 | module_platform_driver(imx93_power_domain_driver); | ||
| 161 | |||
| 162 | MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>"); | ||
| 163 | MODULE_DESCRIPTION("NXP i.MX93 power domain driver"); | ||
| 164 | MODULE_LICENSE("GPL"); | ||
| @@ -0,0 +1,33 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Copyright 2022 NXP | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/module.h> | ||
| 7 | #include <linux/of_platform.h> | ||
| 8 | #include <linux/platform_device.h> | ||
| 9 | |||
| 10 | static int imx93_src_probe(struct platform_device *pdev) | ||
| 11 | { | ||
| 12 | return devm_of_platform_populate(&pdev->dev); | ||
| 13 | } | ||
| 14 | |||
| 15 | static const struct of_device_id imx93_src_ids[] = { | ||
| 16 | { .compatible = "fsl,imx93-src" }, | ||
| 17 | { } | ||
| 18 | }; | ||
| 19 | MODULE_DEVICE_TABLE(of, imx93_src_ids); | ||
| 20 | |||
| 21 | static struct platform_driver imx93_src_driver = { | ||
| 22 | .driver = { | ||
| 23 | .name = "imx93_src", | ||
| 24 | .owner = THIS_MODULE, | ||
| 25 | .of_match_table = imx93_src_ids, | ||
| 26 | }, | ||
| 27 | .probe = imx93_src_probe, | ||
| 28 | }; | ||
| 29 | module_platform_driver(imx93_src_driver); | ||
| 30 | |||
| 31 | MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>"); | ||
| 32 | MODULE_DESCRIPTION("NXP i.MX93 src driver"); | ||
| 33 | MODULE_LICENSE("GPL"); | ||
| @@ -37,6 +37,7 @@ config MTK_INFRACFG · 36 unmodified lines | |||
| 37 | config MTK_PMIC_WRAP | 37 | config MTK_PMIC_WRAP |
| 38 | tristate "MediaTek PMIC Wrapper Support" | 38 | tristate "MediaTek PMIC Wrapper Support" |
| 39 | depends on RESET_CONTROLLER | 39 | depends on RESET_CONTROLLER |
| 40 | depends on OF | ||
| 40 | select REGMAP | 41 | select REGMAP |
| 41 | help | 42 | help |
| 42 | Say yes here to add support for MediaTek PMIC Wrapper found | 43 | Say yes here to add support for MediaTek PMIC Wrapper found |
| @@ -46,6 +47,7 @@ config MTK_PMIC_WRAP · 3 unmodified lines | |||
| 46 | config MTK_SCPSYS | 47 | config MTK_SCPSYS |
| 47 | bool "MediaTek SCPSYS Support" | 48 | bool "MediaTek SCPSYS Support" |
| 48 | default ARCH_MEDIATEK | 49 | default ARCH_MEDIATEK |
| 50 | depends on OF | ||
| 49 | select REGMAP | 51 | select REGMAP |
| 50 | select MTK_INFRACFG | 52 | select MTK_INFRACFG |
| 51 | select PM_GENERIC_DOMAINS if PM | 53 | select PM_GENERIC_DOMAINS if PM |
| @@ -3,6 +3,12 @@ · 2 unmodified lines | |||
| 3 | #ifndef __SOC_MEDIATEK_MT8186_MMSYS_H | 3 | #ifndef __SOC_MEDIATEK_MT8186_MMSYS_H |
| 4 | #define __SOC_MEDIATEK_MT8186_MMSYS_H | 4 | #define __SOC_MEDIATEK_MT8186_MMSYS_H |
| 5 | 5 | ||
| 6 | /* Values for DPI configuration in MMSYS address space */ | ||
| 7 | #define MT8186_MMSYS_DPI_OUTPUT_FORMAT 0x400 | ||
| 8 | #define DPI_FORMAT_MASK 0x1 | ||
| 9 | #define DPI_RGB888_DDR_CON BIT(0) | ||
| 10 | #define DPI_RGB565_SDR_CON BIT(1) | ||
| 11 | |||
| 6 | #define MT8186_MMSYS_OVL_CON 0xF04 | 12 | #define MT8186_MMSYS_OVL_CON 0xF04 |
| 7 | #define MT8186_MMSYS_OVL0_CON_MASK 0x3 | 13 | #define MT8186_MMSYS_OVL0_CON_MASK 0x3 |
| 8 | #define MT8186_MMSYS_OVL0_2L_CON_MASK 0xC | 14 | #define MT8186_MMSYS_OVL0_2L_CON_MASK 0xC |
| @@ -227,6 +227,26 @@ void mtk_mmsys_ddp_disconnect(struct device *dev, · 226 unmodified lines | |||
| 227 | } | 227 | } |
| 228 | EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect); | 228 | EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect); |
| 229 | 229 | ||
| 230 | static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask, u32 val) | ||
| 231 | { | ||
| 232 | u32 tmp; | ||
| 233 | |||
| 234 | tmp = readl_relaxed(mmsys->regs + offset); | ||
| 235 | tmp = (tmp & ~mask) | val; | ||
| 236 | writel_relaxed(tmp, mmsys->regs + offset); | ||
| 237 | } | ||
| 238 | |||
| 239 | void mtk_mmsys_ddp_dpi_fmt_config(struct device *dev, u32 val) | ||
| 240 | { | ||
| 241 | if (val) | ||
| 242 | mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8186_MMSYS_DPI_OUTPUT_FORMAT, | ||
| 243 | DPI_RGB888_DDR_CON, DPI_FORMAT_MASK); | ||
| 244 | else | ||
| 245 | mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8186_MMSYS_DPI_OUTPUT_FORMAT, | ||
| 246 | DPI_RGB565_SDR_CON, DPI_FORMAT_MASK); | ||
| 247 | } | ||
| 248 | EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_dpi_fmt_config); | ||
| 249 | |||
| 230 | static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id, | 250 | static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id, |
| 231 | bool assert) | 251 | bool assert) |
| 232 | { | 252 | { |
| @@ -91,6 +91,15 @@ · 90 unmodified lines | |||
| 91 | #define MT8183_MUTEX_MOD_MDP_AAL0 23 | 91 | #define MT8183_MUTEX_MOD_MDP_AAL0 23 |
| 92 | #define MT8183_MUTEX_MOD_MDP_CCORR0 24 | 92 | #define MT8183_MUTEX_MOD_MDP_CCORR0 24 |
| 93 | 93 | ||
| 94 | #define MT8186_MUTEX_MOD_MDP_RDMA0 0 | ||
| 95 | #define MT8186_MUTEX_MOD_MDP_AAL0 2 | ||
| 96 | #define MT8186_MUTEX_MOD_MDP_HDR0 4 | ||
| 97 | #define MT8186_MUTEX_MOD_MDP_RSZ0 5 | ||
| 98 | #define MT8186_MUTEX_MOD_MDP_RSZ1 6 | ||
| 99 | #define MT8186_MUTEX_MOD_MDP_WROT0 7 | ||
| 100 | #define MT8186_MUTEX_MOD_MDP_TDSHP0 9 | ||
| 101 | #define MT8186_MUTEX_MOD_MDP_COLOR0 14 | ||
| 102 | |||
| 94 | #define MT8173_MUTEX_MOD_DISP_OVL0 11 | 103 | #define MT8173_MUTEX_MOD_DISP_OVL0 11 |
| 95 | #define MT8173_MUTEX_MOD_DISP_OVL1 12 | 104 | #define MT8173_MUTEX_MOD_DISP_OVL1 12 |
| 96 | #define MT8173_MUTEX_MOD_DISP_RDMA0 13 | 105 | #define MT8173_MUTEX_MOD_DISP_RDMA0 13 |
| @@ -324,6 +333,17 @@ static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = { · 227 unmodified lines | |||
| 324 | [DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1, | 333 | [DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1, |
| 325 | }; | 334 | }; |
| 326 | 335 | ||
| 336 | static const unsigned int mt8186_mdp_mutex_table_mod[MUTEX_MOD_IDX_MAX] = { | ||
| 337 | [MUTEX_MOD_IDX_MDP_RDMA0] = MT8186_MUTEX_MOD_MDP_RDMA0, | ||
| 338 | [MUTEX_MOD_IDX_MDP_RSZ0] = MT8186_MUTEX_MOD_MDP_RSZ0, | ||
| 339 | [MUTEX_MOD_IDX_MDP_RSZ1] = MT8186_MUTEX_MOD_MDP_RSZ1, | ||
| 340 | [MUTEX_MOD_IDX_MDP_TDSHP0] = MT8186_MUTEX_MOD_MDP_TDSHP0, | ||
| 341 | [MUTEX_MOD_IDX_MDP_WROT0] = MT8186_MUTEX_MOD_MDP_WROT0, | ||
| 342 | [MUTEX_MOD_IDX_MDP_HDR0] = MT8186_MUTEX_MOD_MDP_HDR0, | ||
| 343 | [MUTEX_MOD_IDX_MDP_AAL0] = MT8186_MUTEX_MOD_MDP_AAL0, | ||
| 344 | [MUTEX_MOD_IDX_MDP_COLOR0] = MT8186_MUTEX_MOD_MDP_COLOR0, | ||
| 345 | }; | ||
| 346 | |||
| 327 | static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = { | 347 | static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = { |
| 328 | [DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0, | 348 | [DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0, |
| 329 | [DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0, | 349 | [DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0, |
| @@ -380,6 +400,13 @@ static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = { · 50 unmodified lines | |||
| 380 | [MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3, | 400 | [MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3, |
| 381 | }; | 401 | }; |
| 382 | 402 | ||
| 403 | static const unsigned int mt6795_mutex_sof[DDP_MUTEX_SOF_MAX] = { | ||
| 404 | [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, | ||
| 405 | [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, | ||
| 406 | [MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1, | ||
| 407 | [MUTEX_SOF_DPI0] = MUTEX_SOF_DPI0, | ||
| 408 | }; | ||
| 409 | |||
| 383 | static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = { | 410 | static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = { |
| 384 | [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, | 411 | [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE, |
| 385 | [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, | 412 | [MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0, |
| @@ -434,6 +461,13 @@ static const struct mtk_mutex_data mt2712_mutex_driver_data = { · 48 unmodified lines | |||
| 434 | .mutex_sof_reg = MT2701_MUTEX0_SOF0, | 461 | .mutex_sof_reg = MT2701_MUTEX0_SOF0, |
| 435 | }; | 462 | }; |
| 436 | 463 | ||
| 464 | static const struct mtk_mutex_data mt6795_mutex_driver_data = { | ||
| 465 | .mutex_mod = mt8173_mutex_mod, | ||
| 466 | .mutex_sof = mt6795_mutex_sof, | ||
| 467 | .mutex_mod_reg = MT2701_MUTEX0_MOD0, | ||
| 468 | .mutex_sof_reg = MT2701_MUTEX0_SOF0, | ||
| 469 | }; | ||
| 470 | |||
| 437 | static const struct mtk_mutex_data mt8167_mutex_driver_data = { | 471 | static const struct mtk_mutex_data mt8167_mutex_driver_data = { |
| 438 | .mutex_mod = mt8167_mutex_mod, | 472 | .mutex_mod = mt8167_mutex_mod, |
| 439 | .mutex_sof = mt8167_mutex_sof, | 473 | .mutex_sof = mt8167_mutex_sof, |
| @@ -458,6 +492,12 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = { · 18 unmodified lines | |||
| 458 | .no_clk = true, | 492 | .no_clk = true, |
| 459 | }; | 493 | }; |
| 460 | 494 | ||
| 495 | static const struct mtk_mutex_data mt8186_mdp_mutex_driver_data = { | ||
| 496 | .mutex_mod_reg = MT8183_MUTEX0_MOD0, | ||
| 497 | .mutex_sof_reg = MT8183_MUTEX0_SOF0, | ||
| 498 | .mutex_table_mod = mt8186_mdp_mutex_table_mod, | ||
| 499 | }; | ||
| 500 | |||
| 461 | static const struct mtk_mutex_data mt8186_mutex_driver_data = { | 501 | static const struct mtk_mutex_data mt8186_mutex_driver_data = { |
| 462 | .mutex_mod = mt8186_mutex_mod, | 502 | .mutex_mod = mt8186_mutex_mod, |
| 463 | .mutex_sof = mt8186_mutex_sof, | 503 | .mutex_sof = mt8186_mutex_sof, |
| @@ -802,6 +842,8 @@ static const struct of_device_id mutex_driver_dt_match[] = { · 338 unmodified lines | |||
| 802 | .data = &mt2701_mutex_driver_data}, | 842 | .data = &mt2701_mutex_driver_data}, |
| 803 | { .compatible = "mediatek,mt2712-disp-mutex", | 843 | { .compatible = "mediatek,mt2712-disp-mutex", |
| 804 | .data = &mt2712_mutex_driver_data}, | 844 | .data = &mt2712_mutex_driver_data}, |
| 845 | { .compatible = "mediatek,mt6795-disp-mutex", | ||
| 846 | .data = &mt6795_mutex_driver_data}, | ||
| 805 | { .compatible = "mediatek,mt8167-disp-mutex", | 847 | { .compatible = "mediatek,mt8167-disp-mutex", |
| 806 | .data = &mt8167_mutex_driver_data}, | 848 | .data = &mt8167_mutex_driver_data}, |
| 807 | { .compatible = "mediatek,mt8173-disp-mutex", | 849 | { .compatible = "mediatek,mt8173-disp-mutex", |
| @@ -810,6 +852,8 @@ static const struct of_device_id mutex_driver_dt_match[] = { · 2 unmodified lines | |||
| 810 | .data = &mt8183_mutex_driver_data}, | 852 | .data = &mt8183_mutex_driver_data}, |
| 811 | { .compatible = "mediatek,mt8186-disp-mutex", | 853 | { .compatible = "mediatek,mt8186-disp-mutex", |
| 812 | .data = &mt8186_mutex_driver_data}, | 854 | .data = &mt8186_mutex_driver_data}, |
| 855 | { .compatible = "mediatek,mt8186-mdp3-mutex", | ||
| 856 | .data = &mt8186_mdp_mutex_driver_data}, | ||
| 813 | { .compatible = "mediatek,mt8192-disp-mutex", | 857 | { .compatible = "mediatek,mt8192-disp-mutex", |
| 814 | .data = &mt8192_mutex_driver_data}, | 858 | .data = &mt8192_mutex_driver_data}, |
| 815 | { .compatible = "mediatek,mt8195-disp-mutex", | 859 | { .compatible = "mediatek,mt8195-disp-mutex", |
| @@ -393,7 +393,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no · 392 unmodified lines | |||
| 393 | if (IS_ERR(clk)) { | 393 | if (IS_ERR(clk)) { |
| 394 | ret = PTR_ERR(clk); | 394 | ret = PTR_ERR(clk); |
| 395 | dev_err_probe(scpsys->dev, ret, | 395 | dev_err_probe(scpsys->dev, ret, |
| 396 | "%pOF: failed to get clk at index %d: %d\n", node, i, ret); | 396 | "%pOF: failed to get clk at index %d\n", node, i); |
| 397 | goto err_put_clocks; | 397 | goto err_put_clocks; |
| 398 | } | 398 | } |
| 399 | 399 | ||
| @@ -405,8 +405,8 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no · 5 unmodified lines | |||
| 405 | if (IS_ERR(clk)) { | 405 | if (IS_ERR(clk)) { |
| 406 | ret = PTR_ERR(clk); | 406 | ret = PTR_ERR(clk); |
| 407 | dev_err_probe(scpsys->dev, ret, | 407 | dev_err_probe(scpsys->dev, ret, |
| 408 | "%pOF: failed to get clk at index %d: %d\n", node, | 408 | "%pOF: failed to get clk at index %d\n", node, |
| 409 | i + clk_ind, ret); | 409 | i + clk_ind); |
| 410 | goto err_put_subsys_clocks; | 410 | goto err_put_subsys_clocks; |
| 411 | } | 411 | } |
| 412 | 412 | ||
| @@ -2316,7 +2316,7 @@ err_out1: · 2315 unmodified lines | |||
| 2316 | static struct platform_driver pwrap_drv = { | 2316 | static struct platform_driver pwrap_drv = { |
| 2317 | .driver = { | 2317 | .driver = { |
| 2318 | .name = "mt-pmic-pwrap", | 2318 | .name = "mt-pmic-pwrap", |
| 2319 | .of_match_table = of_match_ptr(of_pwrap_match_tbl), | 2319 | .of_match_table = of_pwrap_match_tbl, |
| 2320 | }, | 2320 | }, |
| 2321 | .probe = pwrap_probe, | 2321 | .probe = pwrap_probe, |
| 2322 | }; | 2322 | }; |
| @@ -1141,7 +1141,7 @@ static struct platform_driver scpsys_drv = { · 1140 unmodified lines | |||
| 1141 | .name = "mtk-scpsys", | 1141 | .name = "mtk-scpsys", |
| 1142 | .suppress_bind_attrs = true, | 1142 | .suppress_bind_attrs = true, |
| 1143 | .owner = THIS_MODULE, | 1143 | .owner = THIS_MODULE, |
| 1144 | .of_match_table = of_match_ptr(of_scpsys_match_tbl), | 1144 | .of_match_table = of_scpsys_match_tbl, |
| 1145 | }, | 1145 | }, |
| 1146 | }; | 1146 | }; |
| 1147 | builtin_platform_driver(scpsys_drv); | 1147 | builtin_platform_driver(scpsys_drv); |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 3 | * Copyright (C) 2022 MediaTek Inc. | 3 | * Copyright (C) 2022 MediaTek Inc. |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <linux/bitfield.h> | ||
| 6 | #include <linux/bits.h> | 7 | #include <linux/bits.h> |
| 7 | #include <linux/clk.h> | 8 | #include <linux/clk.h> |
| 8 | #include <linux/completion.h> | 9 | #include <linux/completion.h> |
| @@ -53,22 +54,79 @@ · 44 unmodified lines | |||
| 53 | #define SVSB_MON_VOLT_IGNORE BIT(16) | 54 | #define SVSB_MON_VOLT_IGNORE BIT(16) |
| 54 | #define SVSB_REMOVE_DVTFIXED_VOLT BIT(24) | 55 | #define SVSB_REMOVE_DVTFIXED_VOLT BIT(24) |
| 55 | 56 | ||
| 56 | /* svs bank register common configuration */ | 57 | /* svs bank register fields and common configuration */ |
| 57 | #define SVSB_DET_MAX 0xffff | 58 | #define SVSB_PTPCONFIG_DETMAX GENMASK(15, 0) |
| 59 | #define SVSB_DET_MAX FIELD_PREP(SVSB_PTPCONFIG_DETMAX, 0xffff) | ||
| 58 | #define SVSB_DET_WINDOW 0xa28 | 60 | #define SVSB_DET_WINDOW 0xa28 |
| 59 | #define SVSB_DTHI 0x1 | 61 | |
| 60 | #define SVSB_DTLO 0xfe | 62 | /* DESCHAR */ |
| 61 | #define SVSB_EN_INIT01 0x1 | 63 | #define SVSB_DESCHAR_FLD_MDES GENMASK(7, 0) |
| 62 | #define SVSB_EN_INIT02 0x5 | 64 | #define SVSB_DESCHAR_FLD_BDES GENMASK(15, 8) |
| 63 | #define SVSB_EN_MON 0x2 | 65 | |
| 64 | #define SVSB_EN_OFF 0x0 | 66 | /* TEMPCHAR */ |
| 65 | #define SVSB_INTEN_INIT0x 0x00005f01 | 67 | #define SVSB_TEMPCHAR_FLD_DVT_FIXED GENMASK(7, 0) |
| 66 | #define SVSB_INTEN_MONVOPEN 0x00ff0000 | 68 | #define SVSB_TEMPCHAR_FLD_MTDES GENMASK(15, 8) |
| 67 | #define SVSB_INTSTS_CLEAN 0x00ffffff | 69 | #define SVSB_TEMPCHAR_FLD_VCO GENMASK(23, 16) |
| 68 | #define SVSB_INTSTS_COMPLETE 0x1 | 70 | |
| 69 | #define SVSB_INTSTS_MONVOP 0x00ff0000 | 71 | /* DETCHAR */ |
| 72 | #define SVSB_DETCHAR_FLD_DCMDET GENMASK(7, 0) | ||
| 73 | #define SVSB_DETCHAR_FLD_DCBDET GENMASK(15, 8) | ||
| 74 | |||
| 75 | /* SVSEN (PTPEN) */ | ||
| 76 | #define SVSB_PTPEN_INIT01 BIT(0) | ||
| 77 | #define SVSB_PTPEN_MON BIT(1) | ||
| 78 | #define SVSB_PTPEN_INIT02 (SVSB_PTPEN_INIT01 | BIT(2)) | ||
| 79 | #define SVSB_PTPEN_OFF 0x0 | ||
| 80 | |||
| 81 | /* FREQPCTS */ | ||
| 82 | #define SVSB_FREQPCTS_FLD_PCT0_4 GENMASK(7, 0) | ||
| 83 | #define SVSB_FREQPCTS_FLD_PCT1_5 GENMASK(15, 8) | ||
| 84 | #define SVSB_FREQPCTS_FLD_PCT2_6 GENMASK(23, 16) | ||
| 85 | #define SVSB_FREQPCTS_FLD_PCT3_7 GENMASK(31, 24) | ||
| 86 | |||
| 87 | /* INTSTS */ | ||
| 88 | #define SVSB_INTSTS_VAL_CLEAN 0x00ffffff | ||
| 89 | #define SVSB_INTSTS_F0_COMPLETE BIT(0) | ||
| 90 | #define SVSB_INTSTS_FLD_MONVOP GENMASK(23, 16) | ||
| 70 | #define SVSB_RUNCONFIG_DEFAULT 0x80000000 | 91 | #define SVSB_RUNCONFIG_DEFAULT 0x80000000 |
| 71 | 92 | ||
| 93 | /* LIMITVALS */ | ||
| 94 | #define SVSB_LIMITVALS_FLD_DTLO GENMASK(7, 0) | ||
| 95 | #define SVSB_LIMITVALS_FLD_DTHI GENMASK(15, 8) | ||
| 96 | #define SVSB_LIMITVALS_FLD_VMIN GENMASK(23, 16) | ||
| 97 | #define SVSB_LIMITVALS_FLD_VMAX GENMASK(31, 24) | ||
| 98 | #define SVSB_VAL_DTHI 0x1 | ||
| 99 | #define SVSB_VAL_DTLO 0xfe | ||
| 100 | |||
| 101 | /* INTEN */ | ||
| 102 | #define SVSB_INTEN_F0EN BIT(0) | ||
| 103 | #define SVSB_INTEN_DACK0UPEN BIT(8) | ||
| 104 | #define SVSB_INTEN_DC0EN BIT(9) | ||
| 105 | #define SVSB_INTEN_DC1EN BIT(10) | ||
| 106 | #define SVSB_INTEN_DACK0LOEN BIT(11) | ||
| 107 | #define SVSB_INTEN_INITPROD_OVF_EN BIT(12) | ||
| 108 | #define SVSB_INTEN_INITSUM_OVF_EN BIT(14) | ||
| 109 | #define SVSB_INTEN_MONVOPEN GENMASK(23, 16) | ||
| 110 | #define SVSB_INTEN_INIT0x (SVSB_INTEN_F0EN | SVSB_INTEN_DACK0UPEN | \ | ||
| 111 | SVSB_INTEN_DC0EN | SVSB_INTEN_DC1EN | \ | ||
| 112 | SVSB_INTEN_DACK0LOEN | \ | ||
| 113 | SVSB_INTEN_INITPROD_OVF_EN | \ | ||
| 114 | SVSB_INTEN_INITSUM_OVF_EN) | ||
| 115 | |||
| 116 | /* TSCALCS */ | ||
| 117 | #define SVSB_TSCALCS_FLD_MTS GENMASK(11, 0) | ||
| 118 | #define SVSB_TSCALCS_FLD_BTS GENMASK(23, 12) | ||
| 119 | |||
| 120 | /* INIT2VALS */ | ||
| 121 | #define SVSB_INIT2VALS_FLD_DCVOFFSETIN GENMASK(15, 0) | ||
| 122 | #define SVSB_INIT2VALS_FLD_AGEVOFFSETIN GENMASK(31, 16) | ||
| 123 | |||
| 124 | /* VOPS */ | ||
| 125 | #define SVSB_VOPS_FLD_VOP0_4 GENMASK(7, 0) | ||
| 126 | #define SVSB_VOPS_FLD_VOP1_5 GENMASK(15, 8) | ||
| 127 | #define SVSB_VOPS_FLD_VOP2_6 GENMASK(23, 16) | ||
| 128 | #define SVSB_VOPS_FLD_VOP3_7 GENMASK(31, 24) | ||
| 129 | |||
| 72 | /* svs bank related setting */ | 130 | /* svs bank related setting */ |
| 73 | #define BITS8 8 | 131 | #define BITS8 8 |
| 74 | #define MAX_OPP_ENTRIES 16 | 132 | #define MAX_OPP_ENTRIES 16 |
| @@ -262,7 +320,6 @@ static const u32 svs_regs_v2[] = { · 187 unmodified lines | |||
| 262 | * @rst: svs platform reset control | 320 | * @rst: svs platform reset control |
| 263 | * @efuse_parsing: svs platform efuse parsing function pointer | 321 | * @efuse_parsing: svs platform efuse parsing function pointer |
| 264 | * @probe: svs platform probe function pointer | 322 | * @probe: svs platform probe function pointer |
| 265 | * @irqflags: svs platform irq settings flags | ||
| 266 | * @efuse_max: total number of svs efuse | 323 | * @efuse_max: total number of svs efuse |
| 267 | * @tefuse_max: total number of thermal efuse | 324 | * @tefuse_max: total number of thermal efuse |
| 268 | * @regs: svs platform registers map | 325 | * @regs: svs platform registers map |
| @@ -280,7 +337,6 @@ struct svs_platform { · 11 unmodified lines | |||
| 280 | struct reset_control *rst; | 337 | struct reset_control *rst; |
| 281 | bool (*efuse_parsing)(struct svs_platform *svsp); | 338 | bool (*efuse_parsing)(struct svs_platform *svsp); |
| 282 | int (*probe)(struct svs_platform *svsp); | 339 | int (*probe)(struct svs_platform *svsp); |
| 283 | unsigned long irqflags; | ||
| 284 | size_t efuse_max; | 340 | size_t efuse_max; |
| 285 | size_t tefuse_max; | 341 | size_t tefuse_max; |
| 286 | const u32 *regs; | 342 | const u32 *regs; |
| @@ -294,7 +350,6 @@ struct svs_platform_data { · 7 unmodified lines | |||
| 294 | struct svs_bank *banks; | 350 | struct svs_bank *banks; |
| 295 | bool (*efuse_parsing)(struct svs_platform *svsp); | 351 | bool (*efuse_parsing)(struct svs_platform *svsp); |
| 296 | int (*probe)(struct svs_platform *svsp); | 352 | int (*probe)(struct svs_platform *svsp); |
| 297 | unsigned long irqflags; | ||
| 298 | const u32 *regs; | 353 | const u32 *regs; |
| 299 | u32 bank_max; | 354 | u32 bank_max; |
| 300 | }; | 355 | }; |
| @@ -668,8 +723,8 @@ static ssize_t svs_enable_debug_write(struct file *filp, · 367 unmodified lines | |||
| 668 | svsp->pbank = svsb; | 723 | svsp->pbank = svsb; |
| 669 | svsb->mode_support = SVSB_MODE_ALL_DISABLE; | 724 | svsb->mode_support = SVSB_MODE_ALL_DISABLE; |
| 670 | svs_switch_bank(svsp); | 725 | svs_switch_bank(svsp); |
| 671 | svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN); | 726 | svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN); |
| 672 | svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS); | 727 | svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS); |
| 673 | spin_unlock_irqrestore(&svs_lock, flags); | 728 | spin_unlock_irqrestore(&svs_lock, flags); |
| 674 | 729 | ||
| 675 | svsb->phase = SVSB_PHASE_ERROR; | 730 | svsb->phase = SVSB_PHASE_ERROR; |
| @@ -830,7 +885,7 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp) · 154 unmodified lines | |||
| 830 | } else if (svsb->type == SVSB_LOW) { | 885 | } else if (svsb->type == SVSB_LOW) { |
| 831 | /* volt[turn_pt] + volt[j] ~ volt[opp_count - 1] */ | 886 | /* volt[turn_pt] + volt[j] ~ volt[opp_count - 1] */ |
| 832 | j = svsb->opp_count - 7; | 887 | j = svsb->opp_count - 7; |
| 833 | svsb->volt[turn_pt] = vop30 & GENMASK(7, 0); | 888 | svsb->volt[turn_pt] = FIELD_GET(SVSB_VOPS_FLD_VOP0_4, vop30); |
| 834 | shift_byte++; | 889 | shift_byte++; |
| 835 | for (i = j; i < svsb->opp_count; i++) { | 890 | for (i = j; i < svsb->opp_count; i++) { |
| 836 | b_sft = BITS8 * (shift_byte % REG_BYTES); | 891 | b_sft = BITS8 * (shift_byte % REG_BYTES); |
| @@ -852,7 +907,7 @@ static void svs_get_bank_volts_v3(struct svs_platform *svsp) · 15 unmodified lines | |||
| 852 | if (svsb->type == SVSB_HIGH) { | 907 | if (svsb->type == SVSB_HIGH) { |
| 853 | /* volt[0] + volt[j] ~ volt[turn_pt - 1] */ | 908 | /* volt[0] + volt[j] ~ volt[turn_pt - 1] */ |
| 854 | j = turn_pt - 7; | 909 | j = turn_pt - 7; |
| 855 | svsb->volt[0] = vop30 & GENMASK(7, 0); | 910 | svsb->volt[0] = FIELD_GET(SVSB_VOPS_FLD_VOP0_4, vop30); |
| 856 | shift_byte++; | 911 | shift_byte++; |
| 857 | for (i = j; i < turn_pt; i++) { | 912 | for (i = j; i < turn_pt; i++) { |
| 858 | b_sft = BITS8 * (shift_byte % REG_BYTES); | 913 | b_sft = BITS8 * (shift_byte % REG_BYTES); |
| @@ -983,16 +1038,16 @@ static void svs_get_bank_volts_v2(struct svs_platform *svsp) · 124 unmodified lines | |||
| 983 | u32 temp, i; | 1038 | u32 temp, i; |
| 984 | 1039 | ||
| 985 | temp = svs_readl_relaxed(svsp, VOP74); | 1040 | temp = svs_readl_relaxed(svsp, VOP74); |
| 986 | svsb->volt[14] = (temp >> 24) & GENMASK(7, 0); | 1041 | svsb->volt[14] = FIELD_GET(SVSB_VOPS_FLD_VOP3_7, temp); |
| 987 | svsb->volt[12] = (temp >> 16) & GENMASK(7, 0); | 1042 | svsb->volt[12] = FIELD_GET(SVSB_VOPS_FLD_VOP2_6, temp); |
| 988 | svsb->volt[10] = (temp >> 8) & GENMASK(7, 0); | 1043 | svsb->volt[10] = FIELD_GET(SVSB_VOPS_FLD_VOP1_5, temp); |
| 989 | svsb->volt[8] = (temp & GENMASK(7, 0)); | 1044 | svsb->volt[8] = FIELD_GET(SVSB_VOPS_FLD_VOP0_4, temp); |
| 990 | 1045 | ||
| 991 | temp = svs_readl_relaxed(svsp, VOP30); | 1046 | temp = svs_readl_relaxed(svsp, VOP30); |
| 992 | svsb->volt[6] = (temp >> 24) & GENMASK(7, 0); | 1047 | svsb->volt[6] = FIELD_GET(SVSB_VOPS_FLD_VOP3_7, temp); |
| 993 | svsb->volt[4] = (temp >> 16) & GENMASK(7, 0); | 1048 | svsb->volt[4] = FIELD_GET(SVSB_VOPS_FLD_VOP2_6, temp); |
| 994 | svsb->volt[2] = (temp >> 8) & GENMASK(7, 0); | 1049 | svsb->volt[2] = FIELD_GET(SVSB_VOPS_FLD_VOP1_5, temp); |
| 995 | svsb->volt[0] = (temp & GENMASK(7, 0)); | 1050 | svsb->volt[0] = FIELD_GET(SVSB_VOPS_FLD_VOP0_4, temp); |
| 996 | 1051 | ||
| 997 | for (i = 0; i <= 12; i += 2) | 1052 | for (i = 0; i <= 12; i += 2) |
| 998 | svsb->volt[i + 1] = interpolate(svsb->freq_pct[i], | 1053 | svsb->volt[i + 1] = interpolate(svsb->freq_pct[i], |
| @@ -1014,20 +1069,20 @@ static void svs_get_bank_volts_v2(struct svs_platform *svsp) · 15 unmodified lines | |||
| 1014 | static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp) | 1069 | static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp) |
| 1015 | { | 1070 | { |
| 1016 | struct svs_bank *svsb = svsp->pbank; | 1071 | struct svs_bank *svsb = svsp->pbank; |
| 1072 | u32 freqpct74_val, freqpct30_val; | ||
| 1073 | |||
| 1074 | freqpct74_val = FIELD_PREP(SVSB_FREQPCTS_FLD_PCT0_4, svsb->freq_pct[8]) | | ||
| 1075 | FIELD_PREP(SVSB_FREQPCTS_FLD_PCT1_5, svsb->freq_pct[10]) | | ||
| 1076 | FIELD_PREP(SVSB_FREQPCTS_FLD_PCT2_6, svsb->freq_pct[12]) | | ||
| 1077 | FIELD_PREP(SVSB_FREQPCTS_FLD_PCT3_7, svsb->freq_pct[14]); | ||
| 1017 | 1078 | ||
| 1018 | svs_writel_relaxed(svsp, | 1079 | freqpct30_val = FIELD_PREP(SVSB_FREQPCTS_FLD_PCT0_4, svsb->freq_pct[0]) | |
| 1019 | (svsb->freq_pct[14] << 24) | | 1080 | FIELD_PREP(SVSB_FREQPCTS_FLD_PCT1_5, svsb->freq_pct[2]) | |
| 1020 | (svsb->freq_pct[12] << 16) | | 1081 | FIELD_PREP(SVSB_FREQPCTS_FLD_PCT2_6, svsb->freq_pct[4]) | |
| 1021 | (svsb->freq_pct[10] << 8) | | 1082 | FIELD_PREP(SVSB_FREQPCTS_FLD_PCT3_7, svsb->freq_pct[6]); |
| 1022 | svsb->freq_pct[8], | 1083 | |
| 1023 | FREQPCT74); | 1084 | svs_writel_relaxed(svsp, freqpct74_val, FREQPCT74); |
| 1024 | 1085 | svs_writel_relaxed(svsp, freqpct30_val, FREQPCT30); | |
| 1025 | svs_writel_relaxed(svsp, | ||
| 1026 | (svsb->freq_pct[6] << 24) | | ||
| 1027 | (svsb->freq_pct[4] << 16) | | ||
| 1028 | (svsb->freq_pct[2] << 8) | | ||
| 1029 | svsb->freq_pct[0], | ||
| 1030 | FREQPCT30); | ||
| 1031 | } | 1086 | } |
| 1032 | 1087 | ||
| 1033 | static void svs_set_bank_phase(struct svs_platform *svsp, | 1088 | static void svs_set_bank_phase(struct svs_platform *svsp, |
| @@ -1038,13 +1093,17 @@ static void svs_set_bank_phase(struct svs_platform *svsp, · 4 unmodified lines | |||
| 1038 | 1093 | ||
| 1039 | svs_switch_bank(svsp); | 1094 | svs_switch_bank(svsp); |
| 1040 | 1095 | ||
| 1041 | des_char = (svsb->bdes << 8) | svsb->mdes; | 1096 | des_char = FIELD_PREP(SVSB_DESCHAR_FLD_BDES, svsb->bdes) | |
| 1097 | FIELD_PREP(SVSB_DESCHAR_FLD_MDES, svsb->mdes); | ||
| 1042 | svs_writel_relaxed(svsp, des_char, DESCHAR); | 1098 | svs_writel_relaxed(svsp, des_char, DESCHAR); |
| 1043 | 1099 | ||
| 1044 | temp_char = (svsb->vco << 16) | (svsb->mtdes << 8) | svsb->dvt_fixed; | 1100 | temp_char = FIELD_PREP(SVSB_TEMPCHAR_FLD_VCO, svsb->vco) | |
| 1101 | FIELD_PREP(SVSB_TEMPCHAR_FLD_MTDES, svsb->mtdes) | | ||
| 1102 | FIELD_PREP(SVSB_TEMPCHAR_FLD_DVT_FIXED, svsb->dvt_fixed); | ||
| 1045 | svs_writel_relaxed(svsp, temp_char, TEMPCHAR); | 1103 | svs_writel_relaxed(svsp, temp_char, TEMPCHAR); |
| 1046 | 1104 | ||
| 1047 | det_char = (svsb->dcbdet << 8) | svsb->dcmdet; | 1105 | det_char = FIELD_PREP(SVSB_DETCHAR_FLD_DCBDET, svsb->dcbdet) | |
| 1106 | FIELD_PREP(SVSB_DETCHAR_FLD_DCMDET, svsb->dcmdet); | ||
| 1048 | svs_writel_relaxed(svsp, det_char, DETCHAR); | 1107 | svs_writel_relaxed(svsp, det_char, DETCHAR); |
| 1049 | 1108 | ||
| 1050 | svs_writel_relaxed(svsp, svsb->dc_config, DCCONFIG); | 1109 | svs_writel_relaxed(svsp, svsb->dc_config, DCCONFIG); |
| @@ -1053,33 +1112,37 @@ static void svs_set_bank_phase(struct svs_platform *svsp, · 2 unmodified lines | |||
| 1053 | 1112 | ||
| 1054 | svsb->set_freq_pct(svsp); | 1113 | svsb->set_freq_pct(svsp); |
| 1055 | 1114 | ||
| 1056 | limit_vals = (svsb->vmax << 24) | (svsb->vmin << 16) | | 1115 | limit_vals = FIELD_PREP(SVSB_LIMITVALS_FLD_DTLO, SVSB_VAL_DTLO) | |
| 1057 | (SVSB_DTHI << 8) | SVSB_DTLO; | 1116 | FIELD_PREP(SVSB_LIMITVALS_FLD_DTHI, SVSB_VAL_DTHI) | |
| 1117 | FIELD_PREP(SVSB_LIMITVALS_FLD_VMIN, svsb->vmin) | | ||
| 1118 | FIELD_PREP(SVSB_LIMITVALS_FLD_VMAX, svsb->vmax); | ||
| 1058 | svs_writel_relaxed(svsp, limit_vals, LIMITVALS); | 1119 | svs_writel_relaxed(svsp, limit_vals, LIMITVALS); |
| 1059 | 1120 | ||
| 1060 | svs_writel_relaxed(svsp, SVSB_DET_WINDOW, DETWINDOW); | 1121 | svs_writel_relaxed(svsp, SVSB_DET_WINDOW, DETWINDOW); |
| 1061 | svs_writel_relaxed(svsp, SVSB_DET_MAX, CONFIG); | 1122 | svs_writel_relaxed(svsp, SVSB_DET_MAX, CONFIG); |
| 1062 | svs_writel_relaxed(svsp, svsb->chk_shift, CHKSHIFT); | 1123 | svs_writel_relaxed(svsp, svsb->chk_shift, CHKSHIFT); |
| 1063 | svs_writel_relaxed(svsp, svsb->ctl0, CTL0); | 1124 | svs_writel_relaxed(svsp, svsb->ctl0, CTL0); |
| 1064 | svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS); | 1125 | svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS); |
| 1065 | 1126 | ||
| 1066 | switch (target_phase) { | 1127 | switch (target_phase) { |
| 1067 | case SVSB_PHASE_INIT01: | 1128 | case SVSB_PHASE_INIT01: |
| 1068 | svs_writel_relaxed(svsp, svsb->vboot, VBOOT); | 1129 | svs_writel_relaxed(svsp, svsb->vboot, VBOOT); |
| 1069 | svs_writel_relaxed(svsp, SVSB_INTEN_INIT0x, INTEN); | 1130 | svs_writel_relaxed(svsp, SVSB_INTEN_INIT0x, INTEN); |
| 1070 | svs_writel_relaxed(svsp, SVSB_EN_INIT01, SVSEN); | 1131 | svs_writel_relaxed(svsp, SVSB_PTPEN_INIT01, SVSEN); |
| 1071 | break; | 1132 | break; |
| 1072 | case SVSB_PHASE_INIT02: | 1133 | case SVSB_PHASE_INIT02: |
| 1134 | init2vals = FIELD_PREP(SVSB_INIT2VALS_FLD_AGEVOFFSETIN, svsb->age_voffset_in) | | ||
| 1135 | FIELD_PREP(SVSB_INIT2VALS_FLD_DCVOFFSETIN, svsb->dc_voffset_in); | ||
| 1073 | svs_writel_relaxed(svsp, SVSB_INTEN_INIT0x, INTEN); | 1136 | svs_writel_relaxed(svsp, SVSB_INTEN_INIT0x, INTEN); |
| 1074 | init2vals = (svsb->age_voffset_in << 16) | svsb->dc_voffset_in; | ||
| 1075 | svs_writel_relaxed(svsp, init2vals, INIT2VALS); | 1137 | svs_writel_relaxed(svsp, init2vals, INIT2VALS); |
| 1076 | svs_writel_relaxed(svsp, SVSB_EN_INIT02, SVSEN); | 1138 | svs_writel_relaxed(svsp, SVSB_PTPEN_INIT02, SVSEN); |
| 1077 | break; | 1139 | break; |
| 1078 | case SVSB_PHASE_MON: | 1140 | case SVSB_PHASE_MON: |
| 1079 | ts_calcs = (svsb->bts << 12) | svsb->mts; | 1141 | ts_calcs = FIELD_PREP(SVSB_TSCALCS_FLD_BTS, svsb->bts) | |
| 1142 | FIELD_PREP(SVSB_TSCALCS_FLD_MTS, svsb->mts); | ||
| 1080 | svs_writel_relaxed(svsp, ts_calcs, TSCALCS); | 1143 | svs_writel_relaxed(svsp, ts_calcs, TSCALCS); |
| 1081 | svs_writel_relaxed(svsp, SVSB_INTEN_MONVOPEN, INTEN); | 1144 | svs_writel_relaxed(svsp, SVSB_INTEN_MONVOPEN, INTEN); |
| 1082 | svs_writel_relaxed(svsp, SVSB_EN_MON, SVSEN); | 1145 | svs_writel_relaxed(svsp, SVSB_PTPEN_MON, SVSEN); |
| 1083 | break; | 1146 | break; |
| 1084 | default: | 1147 | default: |
| 1085 | dev_err(svsb->dev, "requested unknown target phase: %u\n", | 1148 | dev_err(svsb->dev, "requested unknown target phase: %u\n", |
| @@ -1115,8 +1178,8 @@ static inline void svs_error_isr_handler(struct svs_platform *svsp) · 29 unmodified lines | |||
| 1115 | svs_save_bank_register_data(svsp, SVSB_PHASE_ERROR); | 1178 | svs_save_bank_register_data(svsp, SVSB_PHASE_ERROR); |
| 1116 | 1179 | ||
| 1117 | svsb->phase = SVSB_PHASE_ERROR; | 1180 | svsb->phase = SVSB_PHASE_ERROR; |
| 1118 | svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN); | 1181 | svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN); |
| 1119 | svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS); | 1182 | svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS); |
| 1120 | } | 1183 | } |
| 1121 | 1184 | ||
| 1122 | static inline void svs_init01_isr_handler(struct svs_platform *svsp) | 1185 | static inline void svs_init01_isr_handler(struct svs_platform *svsp) |
| @@ -1141,8 +1204,8 @@ static inline void svs_init01_isr_handler(struct svs_platform *svsp) · 18 unmodified lines | |||
| 1141 | svsb->age_voffset_in = svs_readl_relaxed(svsp, AGEVALUES) & | 1204 | svsb->age_voffset_in = svs_readl_relaxed(svsp, AGEVALUES) & |
| 1142 | GENMASK(15, 0); | 1205 | GENMASK(15, 0); |
| 1143 | 1206 | ||
| 1144 | svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN); | 1207 | svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN); |
| 1145 | svs_writel_relaxed(svsp, SVSB_INTSTS_COMPLETE, INTSTS); | 1208 | svs_writel_relaxed(svsp, SVSB_INTSTS_F0_COMPLETE, INTSTS); |
| 1146 | svsb->core_sel &= ~SVSB_DET_CLK_EN; | 1209 | svsb->core_sel &= ~SVSB_DET_CLK_EN; |
| 1147 | } | 1210 | } |
| 1148 | 1211 | ||
| @@ -1160,8 +1223,8 @@ static inline void svs_init02_isr_handler(struct svs_platform *svsp) · 11 unmodified lines | |||
| 1160 | svsb->phase = SVSB_PHASE_INIT02; | 1223 | svsb->phase = SVSB_PHASE_INIT02; |
| 1161 | svsb->get_volts(svsp); | 1224 | svsb->get_volts(svsp); |
| 1162 | 1225 | ||
| 1163 | svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN); | 1226 | svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN); |
| 1164 | svs_writel_relaxed(svsp, SVSB_INTSTS_COMPLETE, INTSTS); | 1227 | svs_writel_relaxed(svsp, SVSB_INTSTS_F0_COMPLETE, INTSTS); |
| 1165 | } | 1228 | } |
| 1166 | 1229 | ||
| 1167 | static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp) | 1230 | static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp) |
| @@ -1174,7 +1237,7 @@ static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp) · 6 unmodified lines | |||
| 1174 | svsb->get_volts(svsp); | 1237 | svsb->get_volts(svsp); |
| 1175 | 1238 | ||
| 1176 | svsb->temp = svs_readl_relaxed(svsp, TEMP) & GENMASK(7, 0); | 1239 | svsb->temp = svs_readl_relaxed(svsp, TEMP) & GENMASK(7, 0); |
| 1177 | svs_writel_relaxed(svsp, SVSB_INTSTS_MONVOP, INTSTS); | 1240 | svs_writel_relaxed(svsp, SVSB_INTSTS_FLD_MONVOP, INTSTS); |
| 1178 | } | 1241 | } |
| 1179 | 1242 | ||
| 1180 | static irqreturn_t svs_isr(int irq, void *data) | 1243 | static irqreturn_t svs_isr(int irq, void *data) |
| @@ -1201,13 +1264,13 @@ static irqreturn_t svs_isr(int irq, void *data) · 20 unmodified lines | |||
| 1201 | int_sts = svs_readl_relaxed(svsp, INTSTS); | 1264 | int_sts = svs_readl_relaxed(svsp, INTSTS); |
| 1202 | svs_en = svs_readl_relaxed(svsp, SVSEN); | 1265 | svs_en = svs_readl_relaxed(svsp, SVSEN); |
| 1203 | 1266 | ||
| 1204 | if (int_sts == SVSB_INTSTS_COMPLETE && | 1267 | if (int_sts == SVSB_INTSTS_F0_COMPLETE && |
| 1205 | svs_en == SVSB_EN_INIT01) | 1268 | svs_en == SVSB_PTPEN_INIT01) |
| 1206 | svs_init01_isr_handler(svsp); | 1269 | svs_init01_isr_handler(svsp); |
| 1207 | else if (int_sts == SVSB_INTSTS_COMPLETE && | 1270 | else if (int_sts == SVSB_INTSTS_F0_COMPLETE && |
| 1208 | svs_en == SVSB_EN_INIT02) | 1271 | svs_en == SVSB_PTPEN_INIT02) |
| 1209 | svs_init02_isr_handler(svsp); | 1272 | svs_init02_isr_handler(svsp); |
| 1210 | else if (int_sts & SVSB_INTSTS_MONVOP) | 1273 | else if (int_sts & SVSB_INTSTS_FLD_MONVOP) |
| 1211 | svs_mon_mode_isr_handler(svsp); | 1274 | svs_mon_mode_isr_handler(svsp); |
| 1212 | else | 1275 | else |
| 1213 | svs_error_isr_handler(svsp); | 1276 | svs_error_isr_handler(svsp); |
| @@ -1493,8 +1556,8 @@ static int svs_suspend(struct device *dev) · 279 unmodified lines | |||
| 1493 | spin_lock_irqsave(&svs_lock, flags); | 1556 | spin_lock_irqsave(&svs_lock, flags); |
| 1494 | svsp->pbank = svsb; | 1557 | svsp->pbank = svsb; |
| 1495 | svs_switch_bank(svsp); | 1558 | svs_switch_bank(svsp); |
| 1496 | svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN); | 1559 | svs_writel_relaxed(svsp, SVSB_PTPEN_OFF, SVSEN); |
| 1497 | svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS); | 1560 | svs_writel_relaxed(svsp, SVSB_INTSTS_VAL_CLEAN, INTSTS); |
| 1498 | spin_unlock_irqrestore(&svs_lock, flags); | 1561 | spin_unlock_irqrestore(&svs_lock, flags); |
| 1499 | 1562 | ||
| 1500 | svsb->phase = SVSB_PHASE_ERROR; | 1563 | svsb->phase = SVSB_PHASE_ERROR; |
| @@ -1589,7 +1652,7 @@ static int svs_bank_resource_setup(struct svs_platform *svsp) · 88 unmodified lines | |||
| 1589 | 1652 | ||
| 1590 | dev_set_drvdata(svsb->dev, svsp); | 1653 | dev_set_drvdata(svsb->dev, svsp); |
| 1591 | 1654 | ||
| 1592 | ret = dev_pm_opp_of_add_table(svsb->opp_dev); | 1655 | ret = devm_pm_opp_of_add_table(svsb->opp_dev); |
| 1593 | if (ret) { | 1656 | if (ret) { |
| 1594 | dev_err(svsb->dev, "add opp table fail: %d\n", ret); | 1657 | dev_err(svsb->dev, "add opp table fail: %d\n", ret); |
| 1595 | return ret; | 1658 | return ret; |
| @@ -1644,11 +1707,36 @@ static int svs_bank_resource_setup(struct svs_platform *svsp) · 48 unmodified lines | |||
| 1644 | return 0; | 1707 | return 0; |
| 1645 | } | 1708 | } |
| 1646 | 1709 | ||
| 1710 | static int svs_thermal_efuse_get_data(struct svs_platform *svsp) | ||
| 1711 | { | ||
| 1712 | struct nvmem_cell *cell; | ||
| 1713 | |||
| 1714 | /* Thermal efuse parsing */ | ||
| 1715 | cell = nvmem_cell_get(svsp->dev, "t-calibration-data"); | ||
| 1716 | if (IS_ERR_OR_NULL(cell)) { | ||
| 1717 | dev_err(svsp->dev, "no \"t-calibration-data\"? %ld\n", PTR_ERR(cell)); | ||
| 1718 | return PTR_ERR(cell); | ||
| 1719 | } | ||
| 1720 | |||
| 1721 | svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_max); | ||
| 1722 | if (IS_ERR(svsp->tefuse)) { | ||
| 1723 | dev_err(svsp->dev, "cannot read thermal efuse: %ld\n", | ||
| 1724 | PTR_ERR(svsp->tefuse)); | ||
| 1725 | nvmem_cell_put(cell); | ||
| 1726 | return PTR_ERR(svsp->tefuse); | ||
| 1727 | } | ||
| 1728 | |||
| 1729 | svsp->tefuse_max /= sizeof(u32); | ||
| 1730 | nvmem_cell_put(cell); | ||
| 1731 | |||
| 1732 | return 0; | ||
| 1733 | } | ||
| 1734 | |||
| 1647 | static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp) | 1735 | static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp) |
| 1648 | { | 1736 | { |
| 1649 | struct svs_bank *svsb; | 1737 | struct svs_bank *svsb; |
| 1650 | struct nvmem_cell *cell; | ||
| 1651 | u32 idx, i, vmin, golden_temp; | 1738 | u32 idx, i, vmin, golden_temp; |
| 1739 | int ret; | ||
| 1652 | 1740 | ||
| 1653 | for (i = 0; i < svsp->efuse_max; i++) | 1741 | for (i = 0; i < svsp->efuse_max; i++) |
| 1654 | if (svsp->efuse[i]) | 1742 | if (svsp->efuse[i]) |
| @@ -1686,24 +1774,9 @@ static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp) · 31 unmodified lines | |||
| 1686 | svsb->vmax += svsb->dvt_fixed; | 1774 | svsb->vmax += svsb->dvt_fixed; |
| 1687 | } | 1775 | } |
| 1688 | 1776 | ||
| 1689 | /* Thermal efuse parsing */ | 1777 | ret = svs_thermal_efuse_get_data(svsp); |
| 1690 | cell = nvmem_cell_get(svsp->dev, "t-calibration-data"); | 1778 | if (ret) |
| 1691 | if (IS_ERR_OR_NULL(cell)) { | ||
| 1692 | dev_err(svsp->dev, "no \"t-calibration-data\"? %ld\n", | ||
| 1693 | PTR_ERR(cell)); | ||
| 1694 | return false; | ||
| 1695 | } | ||
| 1696 | |||
| 1697 | svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_max); | ||
| 1698 | if (IS_ERR(svsp->tefuse)) { | ||
| 1699 | dev_err(svsp->dev, "cannot read thermal efuse: %ld\n", | ||
| 1700 | PTR_ERR(svsp->tefuse)); | ||
| 1701 | nvmem_cell_put(cell); | ||
| 1702 | return false; | 1779 | return false; |
| 1703 | } | ||
| 1704 | |||
| 1705 | svsp->tefuse_max /= sizeof(u32); | ||
| 1706 | nvmem_cell_put(cell); | ||
| 1707 | 1780 | ||
| 1708 | for (i = 0; i < svsp->tefuse_max; i++) | 1781 | for (i = 0; i < svsp->tefuse_max; i++) |
| 1709 | if (svsp->tefuse[i] != 0) | 1782 | if (svsp->tefuse[i] != 0) |
| @@ -1726,11 +1799,11 @@ static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp) · 16 unmodified lines | |||
| 1726 | static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp) | 1799 | static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp) |
| 1727 | { | 1800 | { |
| 1728 | struct svs_bank *svsb; | 1801 | struct svs_bank *svsb; |
| 1729 | struct nvmem_cell *cell; | ||
| 1730 | int format[6], x_roomt[6], o_vtsmcu[5], o_vtsabb, tb_roomt = 0; | 1802 | int format[6], x_roomt[6], o_vtsmcu[5], o_vtsabb, tb_roomt = 0; |
| 1731 | int adc_ge_t, adc_oe_t, ge, oe, gain, degc_cali, adc_cali_en_t; | 1803 | int adc_ge_t, adc_oe_t, ge, oe, gain, degc_cali, adc_cali_en_t; |
| 1732 | int o_slope, o_slope_sign, ts_id; | 1804 | int o_slope, o_slope_sign, ts_id; |
| 1733 | u32 idx, i, ft_pgm, mts, temp0, temp1, temp2; | 1805 | u32 idx, i, ft_pgm, mts, temp0, temp1, temp2; |
| 1806 | int ret; | ||
| 1734 | 1807 | ||
| 1735 | for (i = 0; i < svsp->efuse_max; i++) | 1808 | for (i = 0; i < svsp->efuse_max; i++) |
| 1736 | if (svsp->efuse[i]) | 1809 | if (svsp->efuse[i]) |
| @@ -1806,24 +1879,9 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp) · 69 unmodified lines | |||
| 1806 | } | 1879 | } |
| 1807 | } | 1880 | } |
| 1808 | 1881 | ||
| 1809 | /* Get thermal efuse by nvmem */ | 1882 | ret = svs_thermal_efuse_get_data(svsp); |
| 1810 | cell = nvmem_cell_get(svsp->dev, "t-calibration-data"); | 1883 | if (ret) |
| 1811 | if (IS_ERR(cell)) { | 1884 | return false; |
| 1812 | dev_err(svsp->dev, "no \"t-calibration-data\"? %ld\n", | ||
| 1813 | PTR_ERR(cell)); | ||
| 1814 | goto remove_mt8183_svsb_mon_mode; | ||
| 1815 | } | ||
| 1816 | |||
| 1817 | svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_max); | ||
| 1818 | if (IS_ERR(svsp->tefuse)) { | ||
| 1819 | dev_err(svsp->dev, "cannot read thermal efuse: %ld\n", | ||
| 1820 | PTR_ERR(svsp->tefuse)); | ||
| 1821 | nvmem_cell_put(cell); | ||
| 1822 | goto remove_mt8183_svsb_mon_mode; | ||
| 1823 | } | ||
| 1824 | |||
| 1825 | svsp->tefuse_max /= sizeof(u32); | ||
| 1826 | nvmem_cell_put(cell); | ||
| 1827 | 1885 | ||
| 1828 | /* Thermal efuse parsing */ | 1886 | /* Thermal efuse parsing */ |
| 1829 | adc_ge_t = (svsp->tefuse[1] >> 22) & GENMASK(9, 0); | 1887 | adc_ge_t = (svsp->tefuse[1] >> 22) & GENMASK(9, 0); |
| @@ -2244,7 +2302,6 @@ static const struct svs_platform_data svs_mt8192_platform_data = { · 414 unmodified lines | |||
| 2244 | .banks = svs_mt8192_banks, | 2302 | .banks = svs_mt8192_banks, |
| 2245 | .efuse_parsing = svs_mt8192_efuse_parsing, | 2303 | .efuse_parsing = svs_mt8192_efuse_parsing, |
| 2246 | .probe = svs_mt8192_platform_probe, | 2304 | .probe = svs_mt8192_platform_probe, |
| 2247 | .irqflags = IRQF_TRIGGER_HIGH, | ||
| 2248 | .regs = svs_regs_v2, | 2305 | .regs = svs_regs_v2, |
| 2249 | .bank_max = ARRAY_SIZE(svs_mt8192_banks), | 2306 | .bank_max = ARRAY_SIZE(svs_mt8192_banks), |
| 2250 | }; | 2307 | }; |
| @@ -2254,7 +2311,6 @@ static const struct svs_platform_data svs_mt8183_platform_data = { · 3 unmodified lines | |||
| 2254 | .banks = svs_mt8183_banks, | 2311 | .banks = svs_mt8183_banks, |
| 2255 | .efuse_parsing = svs_mt8183_efuse_parsing, | 2312 | .efuse_parsing = svs_mt8183_efuse_parsing, |
| 2256 | .probe = svs_mt8183_platform_probe, | 2313 | .probe = svs_mt8183_platform_probe, |
| 2257 | .irqflags = IRQF_TRIGGER_LOW, | ||
| 2258 | .regs = svs_regs_v2, | 2314 | .regs = svs_regs_v2, |
| 2259 | .bank_max = ARRAY_SIZE(svs_mt8183_banks), | 2315 | .bank_max = ARRAY_SIZE(svs_mt8183_banks), |
| 2260 | }; | 2316 | }; |
| @@ -2292,7 +2348,6 @@ static struct svs_platform *svs_platform_probe(struct platform_device *pdev) · 31 unmodified lines | |||
| 2292 | svsp->banks = svsp_data->banks; | 2348 | svsp->banks = svsp_data->banks; |
| 2293 | svsp->efuse_parsing = svsp_data->efuse_parsing; | 2349 | svsp->efuse_parsing = svsp_data->efuse_parsing; |
| 2294 | svsp->probe = svsp_data->probe; | 2350 | svsp->probe = svsp_data->probe; |
| 2295 | svsp->irqflags = svsp_data->irqflags; | ||
| 2296 | svsp->regs = svsp_data->regs; | 2351 | svsp->regs = svsp_data->regs; |
| 2297 | svsp->bank_max = svsp_data->bank_max; | 2352 | svsp->bank_max = svsp_data->bank_max; |
| 2298 | 2353 | ||
| @@ -2306,8 +2361,7 @@ static struct svs_platform *svs_platform_probe(struct platform_device *pdev) · 7 unmodified lines | |||
| 2306 | static int svs_probe(struct platform_device *pdev) | 2361 | static int svs_probe(struct platform_device *pdev) |
| 2307 | { | 2362 | { |
| 2308 | struct svs_platform *svsp; | 2363 | struct svs_platform *svsp; |
| 2309 | unsigned int svsp_irq; | 2364 | int svsp_irq, ret; |
| 2310 | int ret; | ||
| 2311 | 2365 | ||
| 2312 | svsp = svs_platform_probe(pdev); | 2366 | svsp = svs_platform_probe(pdev); |
| 2313 | if (IS_ERR(svsp)) | 2367 | if (IS_ERR(svsp)) |
| @@ -2325,10 +2379,14 @@ static int svs_probe(struct platform_device *pdev) · 11 unmodified lines | |||
| 2325 | goto svs_probe_free_resource; | 2379 | goto svs_probe_free_resource; |
| 2326 | } | 2380 | } |
| 2327 | 2381 | ||
| 2328 | svsp_irq = irq_of_parse_and_map(svsp->dev->of_node, 0); | 2382 | svsp_irq = platform_get_irq(pdev, 0); |
| 2383 | if (svsp_irq < 0) { | ||
| 2384 | ret = svsp_irq; | ||
| 2385 | goto svs_probe_free_resource; | ||
| 2386 | } | ||
| 2387 | |||
| 2329 | ret = devm_request_threaded_irq(svsp->dev, svsp_irq, NULL, svs_isr, | 2388 | ret = devm_request_threaded_irq(svsp->dev, svsp_irq, NULL, svs_isr, |
| 2330 | svsp->irqflags | IRQF_ONESHOT, | 2389 | IRQF_ONESHOT, svsp->name, svsp); |
| 2331 | svsp->name, svsp); | ||
| 2332 | if (ret) { | 2390 | if (ret) { |
| 2333 | dev_err(svsp->dev, "register irq(%d) failed: %d\n", | 2391 | dev_err(svsp->dev, "register irq(%d) failed: %d\n", |
| 2334 | svsp_irq, ret); | 2392 | svsp_irq, ret); |
| @@ -2392,7 +2450,7 @@ static struct platform_driver svs_driver = { · 57 unmodified lines | |||
| 2392 | .driver = { | 2450 | .driver = { |
| 2393 | .name = "mtk-svs", | 2451 | .name = "mtk-svs", |
| 2394 | .pm = &svs_pm_ops, | 2452 | .pm = &svs_pm_ops, |
| 2395 | .of_match_table = of_match_ptr(svs_of_match), | 2453 | .of_match_table = svs_of_match, |
| 2396 | }, | 2454 | }, |
| 2397 | }; | 2455 | }; |
| 2398 | 2456 | ||
| @@ -129,7 +129,7 @@ config QCOM_RPMHPD · 128 unmodified lines | |||
| 129 | 129 | ||
| 130 | config QCOM_RPMPD | 130 | config QCOM_RPMPD |
| 131 | tristate "Qualcomm RPM Power domain driver" | 131 | tristate "Qualcomm RPM Power domain driver" |
| 132 | depends on PM | 132 | depends on PM && OF |
| 133 | depends on QCOM_SMD_RPM | 133 | depends on QCOM_SMD_RPM |
| 134 | select PM_GENERIC_DOMAINS | 134 | select PM_GENERIC_DOMAINS |
| 135 | select PM_GENERIC_DOMAINS_OF | 135 | select PM_GENERIC_DOMAINS_OF |
| @@ -5,6 +5,8 @@ · 4 unmodified lines | |||
| 5 | * Author: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>, based on | 5 | * Author: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>, based on |
| 6 | * previous work of Thara Gopinath and msm-4.9 downstream sources. | 6 | * previous work of Thara Gopinath and msm-4.9 downstream sources. |
| 7 | */ | 7 | */ |
| 8 | |||
| 9 | #include <linux/err.h> | ||
| 8 | #include <linux/interconnect.h> | 10 | #include <linux/interconnect.h> |
| 9 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
| 10 | #include <linux/io.h> | 12 | #include <linux/io.h> |
| @@ -13,6 +15,7 @@ · 2 unmodified lines | |||
| 13 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
| 14 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 15 | #include <linux/pm_opp.h> | 17 | #include <linux/pm_opp.h> |
| 18 | #include <linux/regmap.h> | ||
| 16 | #include <linux/sizes.h> | 19 | #include <linux/sizes.h> |
| 17 | 20 | ||
| 18 | /* | 21 | /* |
| @@ -31,33 +34,44 @@ · 12 unmodified lines | |||
| 31 | /* Internal sampling clock frequency */ | 34 | /* Internal sampling clock frequency */ |
| 32 | #define HW_TIMER_HZ 19200000 | 35 | #define HW_TIMER_HZ 19200000 |
| 33 | 36 | ||
| 34 | #define BWMON_GLOBAL_IRQ_STATUS 0x0 | 37 | #define BWMON_V4_GLOBAL_IRQ_CLEAR 0x008 |
| 35 | #define BWMON_GLOBAL_IRQ_CLEAR 0x8 | 38 | #define BWMON_V4_GLOBAL_IRQ_ENABLE 0x00c |
| 36 | #define BWMON_GLOBAL_IRQ_ENABLE 0xc | 39 | /* |
| 37 | #define BWMON_GLOBAL_IRQ_ENABLE_ENABLE BIT(0) | 40 | * All values here and further are matching regmap fields, so without absolute |
| 38 | 41 | * register offsets. | |
| 39 | #define BWMON_IRQ_STATUS 0x100 | 42 | */ |
| 40 | #define BWMON_IRQ_STATUS_ZONE_SHIFT 4 | 43 | #define BWMON_V4_GLOBAL_IRQ_ENABLE_ENABLE BIT(0) |
| 41 | #define BWMON_IRQ_CLEAR 0x108 | 44 | |
| 42 | #define BWMON_IRQ_ENABLE 0x10c | 45 | #define BWMON_V4_IRQ_STATUS 0x100 |
| 43 | #define BWMON_IRQ_ENABLE_ZONE1_SHIFT 5 | 46 | #define BWMON_V4_IRQ_CLEAR 0x108 |
| 44 | #define BWMON_IRQ_ENABLE_ZONE2_SHIFT 6 | 47 | |
| 45 | #define BWMON_IRQ_ENABLE_ZONE3_SHIFT 7 | 48 | #define BWMON_V4_IRQ_ENABLE 0x10c |
| 46 | #define BWMON_IRQ_ENABLE_MASK (BIT(BWMON_IRQ_ENABLE_ZONE1_SHIFT) | \ | 49 | #define BWMON_IRQ_ENABLE_MASK (BIT(1) | BIT(3)) |
| 47 | BIT(BWMON_IRQ_ENABLE_ZONE3_SHIFT)) | 50 | #define BWMON_V5_IRQ_STATUS 0x000 |
| 48 | 51 | #define BWMON_V5_IRQ_CLEAR 0x008 | |
| 49 | #define BWMON_ENABLE 0x2a0 | 52 | #define BWMON_V5_IRQ_ENABLE 0x00c |
| 53 | |||
| 54 | #define BWMON_V4_ENABLE 0x2a0 | ||
| 55 | #define BWMON_V5_ENABLE 0x010 | ||
| 50 | #define BWMON_ENABLE_ENABLE BIT(0) | 56 | #define BWMON_ENABLE_ENABLE BIT(0) |
| 51 | 57 | ||
| 52 | #define BWMON_CLEAR 0x2a4 | 58 | #define BWMON_V4_CLEAR 0x2a4 |
| 59 | #define BWMON_V5_CLEAR 0x014 | ||
| 53 | #define BWMON_CLEAR_CLEAR BIT(0) | 60 | #define BWMON_CLEAR_CLEAR BIT(0) |
| 61 | #define BWMON_CLEAR_CLEAR_ALL BIT(1) | ||
| 54 | 62 | ||
| 55 | #define BWMON_SAMPLE_WINDOW 0x2a8 | 63 | #define BWMON_V4_SAMPLE_WINDOW 0x2a8 |
| 56 | #define BWMON_THRESHOLD_HIGH 0x2ac | 64 | #define BWMON_V5_SAMPLE_WINDOW 0x020 |
| 57 | #define BWMON_THRESHOLD_MED 0x2b0 | ||
| 58 | #define BWMON_THRESHOLD_LOW 0x2b4 | ||
| 59 | 65 | ||
| 60 | #define BWMON_ZONE_ACTIONS 0x2b8 | 66 | #define BWMON_V4_THRESHOLD_HIGH 0x2ac |
| 67 | #define BWMON_V4_THRESHOLD_MED 0x2b0 | ||
| 68 | #define BWMON_V4_THRESHOLD_LOW 0x2b4 | ||
| 69 | #define BWMON_V5_THRESHOLD_HIGH 0x024 | ||
| 70 | #define BWMON_V5_THRESHOLD_MED 0x028 | ||
| 71 | #define BWMON_V5_THRESHOLD_LOW 0x02c | ||
| 72 | |||
| 73 | #define BWMON_V4_ZONE_ACTIONS 0x2b8 | ||
| 74 | #define BWMON_V5_ZONE_ACTIONS 0x030 | ||
| 61 | /* | 75 | /* |
| 62 | * Actions to perform on some zone 'z' when current zone hits the threshold: | 76 | * Actions to perform on some zone 'z' when current zone hits the threshold: |
| 63 | * Increment counter of zone 'z' | 77 | * Increment counter of zone 'z' |
| @@ -83,55 +97,244 @@ · 19 unmodified lines | |||
| 83 | BWMON_ZONE_ACTIONS_CLEAR(2) | \ | 97 | BWMON_ZONE_ACTIONS_CLEAR(2) | \ |
| 84 | BWMON_ZONE_ACTIONS_CLEAR(1) | \ | 98 | BWMON_ZONE_ACTIONS_CLEAR(1) | \ |
| 85 | BWMON_ZONE_ACTIONS_CLEAR(0)) | 99 | BWMON_ZONE_ACTIONS_CLEAR(0)) |
| 86 | /* Value for BWMON_ZONE_ACTIONS */ | ||
| 87 | #define BWMON_ZONE_ACTIONS_DEFAULT (BWMON_ZONE_ACTIONS_ZONE0 | \ | ||
| 88 | BWMON_ZONE_ACTIONS_ZONE1 << 8 | \ | ||
| 89 | BWMON_ZONE_ACTIONS_ZONE2 << 16 | \ | ||
| 90 | BWMON_ZONE_ACTIONS_ZONE3 << 24) | ||
| 91 | 100 | ||
| 92 | /* | 101 | /* |
| 93 | * There is no clear documentation/explanation of BWMON_THRESHOLD_COUNT | 102 | * There is no clear documentation/explanation of BWMON_V4_THRESHOLD_COUNT |
| 94 | * register. Based on observations, this is number of times one threshold has to | 103 | * register. Based on observations, this is number of times one threshold has to |
| 95 | * be reached, to trigger interrupt in given zone. | 104 | * be reached, to trigger interrupt in given zone. |
| 96 | * | 105 | * |
| 97 | * 0xff are maximum values meant to ignore the zones 0 and 2. | 106 | * 0xff are maximum values meant to ignore the zones 0 and 2. |
| 98 | */ | 107 | */ |
| 99 | #define BWMON_THRESHOLD_COUNT 0x2bc | 108 | #define BWMON_V4_THRESHOLD_COUNT 0x2bc |
| 100 | #define BWMON_THRESHOLD_COUNT_ZONE1_SHIFT 8 | 109 | #define BWMON_V5_THRESHOLD_COUNT 0x034 |
| 101 | #define BWMON_THRESHOLD_COUNT_ZONE2_SHIFT 16 | ||
| 102 | #define BWMON_THRESHOLD_COUNT_ZONE3_SHIFT 24 | ||
| 103 | #define BWMON_THRESHOLD_COUNT_ZONE0_DEFAULT 0xff | 110 | #define BWMON_THRESHOLD_COUNT_ZONE0_DEFAULT 0xff |
| 104 | #define BWMON_THRESHOLD_COUNT_ZONE2_DEFAULT 0xff | 111 | #define BWMON_THRESHOLD_COUNT_ZONE2_DEFAULT 0xff |
| 105 | 112 | ||
| 106 | /* BWMONv4 count registers use count unit of 64 kB */ | 113 | #define BWMON_V4_ZONE_MAX(zone) (0x2e0 + 4 * (zone)) |
| 107 | #define BWMON_COUNT_UNIT_KB 64 | 114 | #define BWMON_V5_ZONE_MAX(zone) (0x044 + 4 * (zone)) |
| 108 | #define BWMON_ZONE_COUNT 0x2d8 | 115 | |
| 109 | #define BWMON_ZONE_MAX(zone) (0x2e0 + 4 * (zone)) | 116 | /* Quirks for specific BWMON types */ |
| 117 | #define BWMON_HAS_GLOBAL_IRQ BIT(0) | ||
| 118 | #define BWMON_NEEDS_FORCE_CLEAR BIT(1) | ||
| 119 | |||
| 120 | enum bwmon_fields { | ||
| 121 | F_GLOBAL_IRQ_CLEAR, | ||
| 122 | F_GLOBAL_IRQ_ENABLE, | ||
| 123 | F_IRQ_STATUS, | ||
| 124 | F_IRQ_CLEAR, | ||
| 125 | F_IRQ_ENABLE, | ||
| 126 | F_ENABLE, | ||
| 127 | F_CLEAR, | ||
| 128 | F_SAMPLE_WINDOW, | ||
| 129 | F_THRESHOLD_HIGH, | ||
| 130 | F_THRESHOLD_MED, | ||
| 131 | F_THRESHOLD_LOW, | ||
| 132 | F_ZONE_ACTIONS_ZONE0, | ||
| 133 | F_ZONE_ACTIONS_ZONE1, | ||
| 134 | F_ZONE_ACTIONS_ZONE2, | ||
| 135 | F_ZONE_ACTIONS_ZONE3, | ||
| 136 | F_THRESHOLD_COUNT_ZONE0, | ||
| 137 | F_THRESHOLD_COUNT_ZONE1, | ||
| 138 | F_THRESHOLD_COUNT_ZONE2, | ||
| 139 | F_THRESHOLD_COUNT_ZONE3, | ||
| 140 | F_ZONE0_MAX, | ||
| 141 | F_ZONE1_MAX, | ||
| 142 | F_ZONE2_MAX, | ||
| 143 | F_ZONE3_MAX, | ||
| 144 | |||
| 145 | F_NUM_FIELDS | ||
| 146 | }; | ||
| 110 | 147 | ||
| 111 | struct icc_bwmon_data { | 148 | struct icc_bwmon_data { |
| 112 | unsigned int sample_ms; | 149 | unsigned int sample_ms; |
| 150 | unsigned int count_unit_kb; /* kbytes */ | ||
| 113 | unsigned int default_highbw_kbps; | 151 | unsigned int default_highbw_kbps; |
| 114 | unsigned int default_medbw_kbps; | 152 | unsigned int default_medbw_kbps; |
| 115 | unsigned int default_lowbw_kbps; | 153 | unsigned int default_lowbw_kbps; |
| 116 | u8 zone1_thres_count; | 154 | u8 zone1_thres_count; |
| 117 | u8 zone3_thres_count; | 155 | u8 zone3_thres_count; |
| 156 | unsigned int quirks; | ||
| 157 | |||
| 158 | const struct regmap_config *regmap_cfg; | ||
| 159 | const struct reg_field *regmap_fields; | ||
| 118 | }; | 160 | }; |
| 119 | 161 | ||
| 120 | struct icc_bwmon { | 162 | struct icc_bwmon { |
| 121 | struct device *dev; | 163 | struct device *dev; |
| 122 | void __iomem *base; | 164 | const struct icc_bwmon_data *data; |
| 123 | int irq; | 165 | int irq; |
| 124 | 166 | ||
| 125 | unsigned int default_lowbw_kbps; | 167 | struct regmap *regmap; |
| 126 | unsigned int sample_ms; | 168 | struct regmap_field *regs[F_NUM_FIELDS]; |
| 169 | |||
| 127 | unsigned int max_bw_kbps; | 170 | unsigned int max_bw_kbps; |
| 128 | unsigned int min_bw_kbps; | 171 | unsigned int min_bw_kbps; |
| 129 | unsigned int target_kbps; | 172 | unsigned int target_kbps; |
| 130 | unsigned int current_kbps; | 173 | unsigned int current_kbps; |
| 131 | }; | 174 | }; |
| 132 | 175 | ||
| 133 | static void bwmon_clear_counters(struct icc_bwmon *bwmon) | 176 | /* BWMON v4 */ |
| 177 | static const struct reg_field msm8998_bwmon_reg_fields[] = { | ||
| 178 | [F_GLOBAL_IRQ_CLEAR] = REG_FIELD(BWMON_V4_GLOBAL_IRQ_CLEAR, 0, 0), | ||
| 179 | [F_GLOBAL_IRQ_ENABLE] = REG_FIELD(BWMON_V4_GLOBAL_IRQ_ENABLE, 0, 0), | ||
| 180 | [F_IRQ_STATUS] = REG_FIELD(BWMON_V4_IRQ_STATUS, 4, 7), | ||
| 181 | [F_IRQ_CLEAR] = REG_FIELD(BWMON_V4_IRQ_CLEAR, 4, 7), | ||
| 182 | [F_IRQ_ENABLE] = REG_FIELD(BWMON_V4_IRQ_ENABLE, 4, 7), | ||
| 183 | /* F_ENABLE covers entire register to disable other features */ | ||
| 184 | [F_ENABLE] = REG_FIELD(BWMON_V4_ENABLE, 0, 31), | ||
| 185 | [F_CLEAR] = REG_FIELD(BWMON_V4_CLEAR, 0, 1), | ||
| 186 | [F_SAMPLE_WINDOW] = REG_FIELD(BWMON_V4_SAMPLE_WINDOW, 0, 23), | ||
| 187 | [F_THRESHOLD_HIGH] = REG_FIELD(BWMON_V4_THRESHOLD_HIGH, 0, 11), | ||
| 188 | [F_THRESHOLD_MED] = REG_FIELD(BWMON_V4_THRESHOLD_MED, 0, 11), | ||
| 189 | [F_THRESHOLD_LOW] = REG_FIELD(BWMON_V4_THRESHOLD_LOW, 0, 11), | ||
| 190 | [F_ZONE_ACTIONS_ZONE0] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 0, 7), | ||
| 191 | [F_ZONE_ACTIONS_ZONE1] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 8, 15), | ||
| 192 | [F_ZONE_ACTIONS_ZONE2] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 16, 23), | ||
| 193 | [F_ZONE_ACTIONS_ZONE3] = REG_FIELD(BWMON_V4_ZONE_ACTIONS, 24, 31), | ||
| 194 | [F_THRESHOLD_COUNT_ZONE0] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 0, 7), | ||
| 195 | [F_THRESHOLD_COUNT_ZONE1] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 8, 15), | ||
| 196 | [F_THRESHOLD_COUNT_ZONE2] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 16, 23), | ||
| 197 | [F_THRESHOLD_COUNT_ZONE3] = REG_FIELD(BWMON_V4_THRESHOLD_COUNT, 24, 31), | ||
| 198 | [F_ZONE0_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(0), 0, 11), | ||
| 199 | [F_ZONE1_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(1), 0, 11), | ||
| 200 | [F_ZONE2_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(2), 0, 11), | ||
| 201 | [F_ZONE3_MAX] = REG_FIELD(BWMON_V4_ZONE_MAX(3), 0, 11), | ||
| 202 | }; | ||
| 203 | |||
| 204 | static const struct regmap_range msm8998_bwmon_reg_noread_ranges[] = { | ||
| 205 | regmap_reg_range(BWMON_V4_GLOBAL_IRQ_CLEAR, BWMON_V4_GLOBAL_IRQ_CLEAR), | ||
| 206 | regmap_reg_range(BWMON_V4_IRQ_CLEAR, BWMON_V4_IRQ_CLEAR), | ||
| 207 | regmap_reg_range(BWMON_V4_CLEAR, BWMON_V4_CLEAR), | ||
| 208 | }; | ||
| 209 | |||
| 210 | static const struct regmap_access_table msm8998_bwmon_reg_read_table = { | ||
| 211 | .no_ranges = msm8998_bwmon_reg_noread_ranges, | ||
| 212 | .n_no_ranges = ARRAY_SIZE(msm8998_bwmon_reg_noread_ranges), | ||
| 213 | }; | ||
| 214 | |||
| 215 | static const struct regmap_range msm8998_bwmon_reg_volatile_ranges[] = { | ||
| 216 | regmap_reg_range(BWMON_V4_IRQ_STATUS, BWMON_V4_IRQ_STATUS), | ||
| 217 | regmap_reg_range(BWMON_V4_ZONE_MAX(0), BWMON_V4_ZONE_MAX(3)), | ||
| 218 | }; | ||
| 219 | |||
| 220 | static const struct regmap_access_table msm8998_bwmon_reg_volatile_table = { | ||
| 221 | .yes_ranges = msm8998_bwmon_reg_volatile_ranges, | ||
| 222 | .n_yes_ranges = ARRAY_SIZE(msm8998_bwmon_reg_volatile_ranges), | ||
| 223 | }; | ||
| 224 | |||
| 225 | /* | ||
| 226 | * Fill the cache for non-readable registers only as rest does not really | ||
| 227 | * matter and can be read from the device. | ||
| 228 | */ | ||
| 229 | static const struct reg_default msm8998_bwmon_reg_defaults[] = { | ||
| 230 | { BWMON_V4_GLOBAL_IRQ_CLEAR, 0x0 }, | ||
| 231 | { BWMON_V4_IRQ_CLEAR, 0x0 }, | ||
| 232 | { BWMON_V4_CLEAR, 0x0 }, | ||
| 233 | }; | ||
| 234 | |||
| 235 | static const struct regmap_config msm8998_bwmon_regmap_cfg = { | ||
| 236 | .reg_bits = 32, | ||
| 237 | .reg_stride = 4, | ||
| 238 | .val_bits = 32, | ||
| 239 | /* | ||
| 240 | * No concurrent access expected - driver has one interrupt handler, | ||
| 241 | * regmap is not shared, no driver or user-space API. | ||
| 242 | */ | ||
| 243 | .disable_locking = true, | ||
| 244 | .rd_table = &msm8998_bwmon_reg_read_table, | ||
| 245 | .volatile_table = &msm8998_bwmon_reg_volatile_table, | ||
| 246 | .reg_defaults = msm8998_bwmon_reg_defaults, | ||
| 247 | .num_reg_defaults = ARRAY_SIZE(msm8998_bwmon_reg_defaults), | ||
| 248 | /* | ||
| 249 | * Cache is necessary for using regmap fields with non-readable | ||
| 250 | * registers. | ||
| 251 | */ | ||
| 252 | .cache_type = REGCACHE_RBTREE, | ||
| 253 | }; | ||
| 254 | |||
| 255 | /* BWMON v5 */ | ||
| 256 | static const struct reg_field sdm845_llcc_bwmon_reg_fields[] = { | ||
| 257 | [F_GLOBAL_IRQ_CLEAR] = {}, | ||
| 258 | [F_GLOBAL_IRQ_ENABLE] = {}, | ||
| 259 | [F_IRQ_STATUS] = REG_FIELD(BWMON_V5_IRQ_STATUS, 0, 3), | ||
| 260 | [F_IRQ_CLEAR] = REG_FIELD(BWMON_V5_IRQ_CLEAR, 0, 3), | ||
| 261 | [F_IRQ_ENABLE] = REG_FIELD(BWMON_V5_IRQ_ENABLE, 0, 3), | ||
| 262 | /* F_ENABLE covers entire register to disable other features */ | ||
| 263 | [F_ENABLE] = REG_FIELD(BWMON_V5_ENABLE, 0, 31), | ||
| 264 | [F_CLEAR] = REG_FIELD(BWMON_V5_CLEAR, 0, 1), | ||
| 265 | [F_SAMPLE_WINDOW] = REG_FIELD(BWMON_V5_SAMPLE_WINDOW, 0, 19), | ||
| 266 | [F_THRESHOLD_HIGH] = REG_FIELD(BWMON_V5_THRESHOLD_HIGH, 0, 11), | ||
| 267 | [F_THRESHOLD_MED] = REG_FIELD(BWMON_V5_THRESHOLD_MED, 0, 11), | ||
| 268 | [F_THRESHOLD_LOW] = REG_FIELD(BWMON_V5_THRESHOLD_LOW, 0, 11), | ||
| 269 | [F_ZONE_ACTIONS_ZONE0] = REG_FIELD(BWMON_V5_ZONE_ACTIONS, 0, 7), | ||
| 270 | [F_ZONE_ACTIONS_ZONE1] = REG_FIELD(BWMON_V5_ZONE_ACTIONS, 8, 15), | ||
| 271 | [F_ZONE_ACTIONS_ZONE2] = REG_FIELD(BWMON_V5_ZONE_ACTIONS, 16, 23), | ||
| 272 | [F_ZONE_ACTIONS_ZONE3] = REG_FIELD(BWMON_V5_ZONE_ACTIONS, 24, 31), | ||
| 273 | [F_THRESHOLD_COUNT_ZONE0] = REG_FIELD(BWMON_V5_THRESHOLD_COUNT, 0, 7), | ||
| 274 | [F_THRESHOLD_COUNT_ZONE1] = REG_FIELD(BWMON_V5_THRESHOLD_COUNT, 8, 15), | ||
| 275 | [F_THRESHOLD_COUNT_ZONE2] = REG_FIELD(BWMON_V5_THRESHOLD_COUNT, 16, 23), | ||
| 276 | [F_THRESHOLD_COUNT_ZONE3] = REG_FIELD(BWMON_V5_THRESHOLD_COUNT, 24, 31), | ||
| 277 | [F_ZONE0_MAX] = REG_FIELD(BWMON_V5_ZONE_MAX(0), 0, 11), | ||
| 278 | [F_ZONE1_MAX] = REG_FIELD(BWMON_V5_ZONE_MAX(1), 0, 11), | ||
| 279 | [F_ZONE2_MAX] = REG_FIELD(BWMON_V5_ZONE_MAX(2), 0, 11), | ||
| 280 | [F_ZONE3_MAX] = REG_FIELD(BWMON_V5_ZONE_MAX(3), 0, 11), | ||
| 281 | }; | ||
| 282 | |||
| 283 | static const struct regmap_range sdm845_llcc_bwmon_reg_noread_ranges[] = { | ||
| 284 | regmap_reg_range(BWMON_V5_IRQ_CLEAR, BWMON_V5_IRQ_CLEAR), | ||
| 285 | regmap_reg_range(BWMON_V5_CLEAR, BWMON_V5_CLEAR), | ||
| 286 | }; | ||
| 287 | |||
| 288 | static const struct regmap_access_table sdm845_llcc_bwmon_reg_read_table = { | ||
| 289 | .no_ranges = sdm845_llcc_bwmon_reg_noread_ranges, | ||
| 290 | .n_no_ranges = ARRAY_SIZE(sdm845_llcc_bwmon_reg_noread_ranges), | ||
| 291 | }; | ||
| 292 | |||
| 293 | static const struct regmap_range sdm845_llcc_bwmon_reg_volatile_ranges[] = { | ||
| 294 | regmap_reg_range(BWMON_V5_IRQ_STATUS, BWMON_V5_IRQ_STATUS), | ||
| 295 | regmap_reg_range(BWMON_V5_ZONE_MAX(0), BWMON_V5_ZONE_MAX(3)), | ||
| 296 | }; | ||
| 297 | |||
| 298 | static const struct regmap_access_table sdm845_llcc_bwmon_reg_volatile_table = { | ||
| 299 | .yes_ranges = sdm845_llcc_bwmon_reg_volatile_ranges, | ||
| 300 | .n_yes_ranges = ARRAY_SIZE(sdm845_llcc_bwmon_reg_volatile_ranges), | ||
| 301 | }; | ||
| 302 | |||
| 303 | /* | ||
| 304 | * Fill the cache for non-readable registers only as rest does not really | ||
| 305 | * matter and can be read from the device. | ||
| 306 | */ | ||
| 307 | static const struct reg_default sdm845_llcc_bwmon_reg_defaults[] = { | ||
| 308 | { BWMON_V5_IRQ_CLEAR, 0x0 }, | ||
| 309 | { BWMON_V5_CLEAR, 0x0 }, | ||
| 310 | }; | ||
| 311 | |||
| 312 | static const struct regmap_config sdm845_llcc_bwmon_regmap_cfg = { | ||
| 313 | .reg_bits = 32, | ||
| 314 | .reg_stride = 4, | ||
| 315 | .val_bits = 32, | ||
| 316 | /* | ||
| 317 | * No concurrent access expected - driver has one interrupt handler, | ||
| 318 | * regmap is not shared, no driver or user-space API. | ||
| 319 | */ | ||
| 320 | .disable_locking = true, | ||
| 321 | .rd_table = &sdm845_llcc_bwmon_reg_read_table, | ||
| 322 | .volatile_table = &sdm845_llcc_bwmon_reg_volatile_table, | ||
| 323 | .reg_defaults = sdm845_llcc_bwmon_reg_defaults, | ||
| 324 | .num_reg_defaults = ARRAY_SIZE(sdm845_llcc_bwmon_reg_defaults), | ||
| 325 | /* | ||
| 326 | * Cache is necessary for using regmap fields with non-readable | ||
| 327 | * registers. | ||
| 328 | */ | ||
| 329 | .cache_type = REGCACHE_RBTREE, | ||
| 330 | }; | ||
| 331 | |||
| 332 | static void bwmon_clear_counters(struct icc_bwmon *bwmon, bool clear_all) | ||
| 134 | { | 333 | { |
| 334 | unsigned int val = BWMON_CLEAR_CLEAR; | ||
| 335 | |||
| 336 | if (clear_all) | ||
| 337 | val |= BWMON_CLEAR_CLEAR_ALL; | ||
| 135 | /* | 338 | /* |
| 136 | * Clear counters. The order and barriers are | 339 | * Clear counters. The order and barriers are |
| 137 | * important. Quoting downstream Qualcomm msm-4.9 tree: | 340 | * important. Quoting downstream Qualcomm msm-4.9 tree: |
| @@ -140,7 +343,9 @@ static void bwmon_clear_counters(struct icc_bwmon *bwmon) · 2 unmodified lines | |||
| 140 | * region. So, we need to make sure the counter clear is completed | 343 | * region. So, we need to make sure the counter clear is completed |
| 141 | * before we try to clear the IRQ or do any other counter operations. | 344 | * before we try to clear the IRQ or do any other counter operations. |
| 142 | */ | 345 | */ |
| 143 | writel(BWMON_CLEAR_CLEAR, bwmon->base + BWMON_CLEAR); | 346 | regmap_field_force_write(bwmon->regs[F_CLEAR], val); |
| 347 | if (bwmon->data->quirks & BWMON_NEEDS_FORCE_CLEAR) | ||
| 348 | regmap_field_force_write(bwmon->regs[F_CLEAR], 0); | ||
| 144 | } | 349 | } |
| 145 | 350 | ||
| 146 | static void bwmon_clear_irq(struct icc_bwmon *bwmon) | 351 | static void bwmon_clear_irq(struct icc_bwmon *bwmon) |
| @@ -161,76 +366,91 @@ static void bwmon_clear_irq(struct icc_bwmon *bwmon) · 14 unmodified lines | |||
| 161 | * clearing here so that local writes don't happen before the | 366 | * clearing here so that local writes don't happen before the |
| 162 | * interrupt is cleared. | 367 | * interrupt is cleared. |
| 163 | */ | 368 | */ |
| 164 | writel(BWMON_IRQ_ENABLE_MASK, bwmon->base + BWMON_IRQ_CLEAR); | 369 | regmap_field_force_write(bwmon->regs[F_IRQ_CLEAR], BWMON_IRQ_ENABLE_MASK); |
| 165 | writel(BIT(0), bwmon->base + BWMON_GLOBAL_IRQ_CLEAR); | 370 | if (bwmon->data->quirks & BWMON_NEEDS_FORCE_CLEAR) |
| 371 | regmap_field_force_write(bwmon->regs[F_IRQ_CLEAR], 0); | ||
| 372 | if (bwmon->data->quirks & BWMON_HAS_GLOBAL_IRQ) | ||
| 373 | regmap_field_force_write(bwmon->regs[F_GLOBAL_IRQ_CLEAR], | ||
| 374 | BWMON_V4_GLOBAL_IRQ_ENABLE_ENABLE); | ||
| 166 | } | 375 | } |
| 167 | 376 | ||
| 168 | static void bwmon_disable(struct icc_bwmon *bwmon) | 377 | static void bwmon_disable(struct icc_bwmon *bwmon) |
| 169 | { | 378 | { |
| 170 | /* Disable interrupts. Strict ordering, see bwmon_clear_irq(). */ | 379 | /* Disable interrupts. Strict ordering, see bwmon_clear_irq(). */ |
| 171 | writel(0x0, bwmon->base + BWMON_GLOBAL_IRQ_ENABLE); | 380 | if (bwmon->data->quirks & BWMON_HAS_GLOBAL_IRQ) |
| 172 | writel(0x0, bwmon->base + BWMON_IRQ_ENABLE); | 381 | regmap_field_write(bwmon->regs[F_GLOBAL_IRQ_ENABLE], 0x0); |
| 382 | regmap_field_write(bwmon->regs[F_IRQ_ENABLE], 0x0); | ||
| 173 | 383 | ||
| 174 | /* | 384 | /* |
| 175 | * Disable bwmon. Must happen before bwmon_clear_irq() to avoid spurious | 385 | * Disable bwmon. Must happen before bwmon_clear_irq() to avoid spurious |
| 176 | * IRQ. | 386 | * IRQ. |
| 177 | */ | 387 | */ |
| 178 | writel(0x0, bwmon->base + BWMON_ENABLE); | 388 | regmap_field_write(bwmon->regs[F_ENABLE], 0x0); |
| 179 | } | 389 | } |
| 180 | 390 | ||
| 181 | static void bwmon_enable(struct icc_bwmon *bwmon, unsigned int irq_enable) | 391 | static void bwmon_enable(struct icc_bwmon *bwmon, unsigned int irq_enable) |
| 182 | { | 392 | { |
| 183 | /* Enable interrupts */ | 393 | /* Enable interrupts */ |
| 184 | writel(BWMON_GLOBAL_IRQ_ENABLE_ENABLE, | 394 | if (bwmon->data->quirks & BWMON_HAS_GLOBAL_IRQ) |
| 185 | bwmon->base + BWMON_GLOBAL_IRQ_ENABLE); | 395 | regmap_field_write(bwmon->regs[F_GLOBAL_IRQ_ENABLE], |
| 186 | writel(irq_enable, bwmon->base + BWMON_IRQ_ENABLE); | 396 | BWMON_V4_GLOBAL_IRQ_ENABLE_ENABLE); |
| 397 | regmap_field_write(bwmon->regs[F_IRQ_ENABLE], irq_enable); | ||
| 187 | 398 | ||
| 188 | /* Enable bwmon */ | 399 | /* Enable bwmon */ |
| 189 | writel(BWMON_ENABLE_ENABLE, bwmon->base + BWMON_ENABLE); | 400 | regmap_field_write(bwmon->regs[F_ENABLE], BWMON_ENABLE_ENABLE); |
| 190 | } | 401 | } |
| 191 | 402 | ||
| 192 | static unsigned int bwmon_kbps_to_count(unsigned int kbps) | 403 | static unsigned int bwmon_kbps_to_count(struct icc_bwmon *bwmon, |
| 404 | unsigned int kbps) | ||
| 193 | { | 405 | { |
| 194 | return kbps / BWMON_COUNT_UNIT_KB; | 406 | return kbps / bwmon->data->count_unit_kb; |
| 195 | } | 407 | } |
| 196 | 408 | ||
| 197 | static void bwmon_set_threshold(struct icc_bwmon *bwmon, unsigned int reg, | 409 | static void bwmon_set_threshold(struct icc_bwmon *bwmon, |
| 198 | unsigned int kbps) | 410 | struct regmap_field *reg, unsigned int kbps) |
| 199 | { | 411 | { |
| 200 | unsigned int thres; | 412 | unsigned int thres; |
| 201 | 413 | ||
| 202 | thres = mult_frac(bwmon_kbps_to_count(kbps), bwmon->sample_ms, | 414 | thres = mult_frac(bwmon_kbps_to_count(bwmon, kbps), |
| 203 | MSEC_PER_SEC); | 415 | bwmon->data->sample_ms, MSEC_PER_SEC); |
| 204 | writel_relaxed(thres, bwmon->base + reg); | 416 | regmap_field_write(reg, thres); |
| 205 | } | 417 | } |
| 206 | 418 | ||
| 207 | static void bwmon_start(struct icc_bwmon *bwmon, | 419 | static void bwmon_start(struct icc_bwmon *bwmon) |
| 208 | const struct icc_bwmon_data *data) | ||
| 209 | { | 420 | { |
| 210 | unsigned int thres_count; | 421 | const struct icc_bwmon_data *data = bwmon->data; |
| 211 | int window; | 422 | int window; |
| 212 | 423 | ||
| 213 | bwmon_clear_counters(bwmon); | 424 | bwmon_clear_counters(bwmon, true); |
| 214 | 425 | ||
| 215 | window = mult_frac(bwmon->sample_ms, HW_TIMER_HZ, MSEC_PER_SEC); | 426 | window = mult_frac(bwmon->data->sample_ms, HW_TIMER_HZ, MSEC_PER_SEC); |
| 216 | /* Maximum sampling window: 0xfffff */ | 427 | /* Maximum sampling window: 0xffffff for v4 and 0xfffff for v5 */ |
| 217 | writel_relaxed(window, bwmon->base + BWMON_SAMPLE_WINDOW); | 428 | regmap_field_write(bwmon->regs[F_SAMPLE_WINDOW], window); |
| 218 | 429 | ||
| 219 | bwmon_set_threshold(bwmon, BWMON_THRESHOLD_HIGH, | 430 | bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_HIGH], |
| 220 | data->default_highbw_kbps); | 431 | data->default_highbw_kbps); |
| 221 | bwmon_set_threshold(bwmon, BWMON_THRESHOLD_MED, | 432 | bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_MED], |
| 222 | data->default_medbw_kbps); | 433 | data->default_medbw_kbps); |
| 223 | bwmon_set_threshold(bwmon, BWMON_THRESHOLD_LOW, | 434 | bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_LOW], |
| 224 | data->default_lowbw_kbps); | 435 | data->default_lowbw_kbps); |
| 225 | 436 | ||
| 226 | thres_count = data->zone3_thres_count << BWMON_THRESHOLD_COUNT_ZONE3_SHIFT | | 437 | regmap_field_write(bwmon->regs[F_THRESHOLD_COUNT_ZONE0], |
| 227 | BWMON_THRESHOLD_COUNT_ZONE2_DEFAULT << BWMON_THRESHOLD_COUNT_ZONE2_SHIFT | | 438 | BWMON_THRESHOLD_COUNT_ZONE0_DEFAULT); |
| 228 | data->zone1_thres_count << BWMON_THRESHOLD_COUNT_ZONE1_SHIFT | | 439 | regmap_field_write(bwmon->regs[F_THRESHOLD_COUNT_ZONE1], |
| 229 | BWMON_THRESHOLD_COUNT_ZONE0_DEFAULT; | 440 | data->zone1_thres_count); |
| 230 | writel_relaxed(thres_count, bwmon->base + BWMON_THRESHOLD_COUNT); | 441 | regmap_field_write(bwmon->regs[F_THRESHOLD_COUNT_ZONE2], |
| 231 | writel_relaxed(BWMON_ZONE_ACTIONS_DEFAULT, | 442 | BWMON_THRESHOLD_COUNT_ZONE2_DEFAULT); |
| 232 | bwmon->base + BWMON_ZONE_ACTIONS); | 443 | regmap_field_write(bwmon->regs[F_THRESHOLD_COUNT_ZONE3], |
| 233 | /* Write barriers in bwmon_clear_irq() */ | 444 | data->zone3_thres_count); |
| 445 | |||
| 446 | regmap_field_write(bwmon->regs[F_ZONE_ACTIONS_ZONE0], | ||
| 447 | BWMON_ZONE_ACTIONS_ZONE0); | ||
| 448 | regmap_field_write(bwmon->regs[F_ZONE_ACTIONS_ZONE1], | ||
| 449 | BWMON_ZONE_ACTIONS_ZONE1); | ||
| 450 | regmap_field_write(bwmon->regs[F_ZONE_ACTIONS_ZONE2], | ||
| 451 | BWMON_ZONE_ACTIONS_ZONE2); | ||
| 452 | regmap_field_write(bwmon->regs[F_ZONE_ACTIONS_ZONE3], | ||
| 453 | BWMON_ZONE_ACTIONS_ZONE3); | ||
| 234 | 454 | ||
| 235 | bwmon_clear_irq(bwmon); | 455 | bwmon_clear_irq(bwmon); |
| 236 | bwmon_enable(bwmon, BWMON_IRQ_ENABLE_MASK); | 456 | bwmon_enable(bwmon, BWMON_IRQ_ENABLE_MASK); |
| @@ -242,7 +462,9 @@ static irqreturn_t bwmon_intr(int irq, void *dev_id) · 5 unmodified lines | |||
| 242 | unsigned int status, max; | 462 | unsigned int status, max; |
| 243 | int zone; | 463 | int zone; |
| 244 | 464 | ||
| 245 | status = readl(bwmon->base + BWMON_IRQ_STATUS); | 465 | if (regmap_field_read(bwmon->regs[F_IRQ_STATUS], &status)) |
| 466 | return IRQ_NONE; | ||
| 467 | |||
| 246 | status &= BWMON_IRQ_ENABLE_MASK; | 468 | status &= BWMON_IRQ_ENABLE_MASK; |
| 247 | if (!status) { | 469 | if (!status) { |
| 248 | /* | 470 | /* |
| @@ -259,15 +481,18 @@ static irqreturn_t bwmon_intr(int irq, void *dev_id) · 10 unmodified lines | |||
| 259 | 481 | ||
| 260 | bwmon_disable(bwmon); | 482 | bwmon_disable(bwmon); |
| 261 | 483 | ||
| 262 | zone = get_bitmask_order(status >> BWMON_IRQ_STATUS_ZONE_SHIFT) - 1; | 484 | zone = get_bitmask_order(status) - 1; |
| 263 | /* | 485 | /* |
| 264 | * Zone max bytes count register returns count units within sampling | 486 | * Zone max bytes count register returns count units within sampling |
| 265 | * window. Downstream kernel for BWMONv4 (called BWMON type 2 in | 487 | * window. Downstream kernel for BWMONv4 (called BWMON type 2 in |
| 266 | * downstream) always increments the max bytes count by one. | 488 | * downstream) always increments the max bytes count by one. |
| 267 | */ | 489 | */ |
| 268 | max = readl(bwmon->base + BWMON_ZONE_MAX(zone)) + 1; | 490 | if (regmap_field_read(bwmon->regs[F_ZONE0_MAX + zone], &max)) |
| 269 | max *= BWMON_COUNT_UNIT_KB; | 491 | return IRQ_NONE; |
| 270 | bwmon->target_kbps = mult_frac(max, MSEC_PER_SEC, bwmon->sample_ms); | 492 | |
| 493 | max += 1; | ||
| 494 | max *= bwmon->data->count_unit_kb; | ||
| 495 | bwmon->target_kbps = mult_frac(max, MSEC_PER_SEC, bwmon->data->sample_ms); | ||
| 271 | 496 | ||
| 272 | return IRQ_WAKE_THREAD; | 497 | return IRQ_WAKE_THREAD; |
| 273 | } | 498 | } |
| @@ -297,16 +522,17 @@ static irqreturn_t bwmon_intr_thread(int irq, void *dev_id) · 23 unmodified lines | |||
| 297 | up_kbps = bwmon->target_kbps + 1; | 522 | up_kbps = bwmon->target_kbps + 1; |
| 298 | 523 | ||
| 299 | if (bwmon->target_kbps >= bwmon->max_bw_kbps) | 524 | if (bwmon->target_kbps >= bwmon->max_bw_kbps) |
| 300 | irq_enable = BIT(BWMON_IRQ_ENABLE_ZONE1_SHIFT); | 525 | irq_enable = BIT(1); |
| 301 | else if (bwmon->target_kbps <= bwmon->min_bw_kbps) | 526 | else if (bwmon->target_kbps <= bwmon->min_bw_kbps) |
| 302 | irq_enable = BIT(BWMON_IRQ_ENABLE_ZONE3_SHIFT); | 527 | irq_enable = BIT(3); |
| 303 | else | 528 | else |
| 304 | irq_enable = BWMON_IRQ_ENABLE_MASK; | 529 | irq_enable = BWMON_IRQ_ENABLE_MASK; |
| 305 | 530 | ||
| 306 | bwmon_set_threshold(bwmon, BWMON_THRESHOLD_HIGH, up_kbps); | 531 | bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_HIGH], |
| 307 | bwmon_set_threshold(bwmon, BWMON_THRESHOLD_MED, down_kbps); | 532 | up_kbps); |
| 308 | /* Write barriers in bwmon_clear_counters() */ | 533 | bwmon_set_threshold(bwmon, bwmon->regs[F_THRESHOLD_MED], |
| 309 | bwmon_clear_counters(bwmon); | 534 | down_kbps); |
| 535 | bwmon_clear_counters(bwmon, false); | ||
| 310 | bwmon_clear_irq(bwmon); | 536 | bwmon_clear_irq(bwmon); |
| 311 | bwmon_enable(bwmon, irq_enable); | 537 | bwmon_enable(bwmon, irq_enable); |
| 312 | 538 | ||
| @@ -324,25 +550,47 @@ out: · 11 unmodified lines | |||
| 324 | return IRQ_HANDLED; | 550 | return IRQ_HANDLED; |
| 325 | } | 551 | } |
| 326 | 552 | ||
| 553 | static int bwmon_init_regmap(struct platform_device *pdev, | ||
| 554 | struct icc_bwmon *bwmon) | ||
| 555 | { | ||
| 556 | struct device *dev = &pdev->dev; | ||
| 557 | void __iomem *base; | ||
| 558 | struct regmap *map; | ||
| 559 | |||
| 560 | base = devm_platform_ioremap_resource(pdev, 0); | ||
| 561 | if (IS_ERR(base)) | ||
| 562 | return dev_err_probe(dev, PTR_ERR(base), | ||
| 563 | "failed to map bwmon registers\n"); | ||
| 564 | |||
| 565 | map = devm_regmap_init_mmio(dev, base, bwmon->data->regmap_cfg); | ||
| 566 | if (IS_ERR(map)) | ||
| 567 | return dev_err_probe(dev, PTR_ERR(map), | ||
| 568 | "failed to initialize regmap\n"); | ||
| 569 | |||
| 570 | BUILD_BUG_ON(ARRAY_SIZE(msm8998_bwmon_reg_fields) != F_NUM_FIELDS); | ||
| 571 | BUILD_BUG_ON(ARRAY_SIZE(sdm845_llcc_bwmon_reg_fields) != F_NUM_FIELDS); | ||
| 572 | |||
| 573 | return devm_regmap_field_bulk_alloc(dev, map, bwmon->regs, | ||
| 574 | bwmon->data->regmap_fields, | ||
| 575 | F_NUM_FIELDS); | ||
| 576 | } | ||
| 577 | |||
| 327 | static int bwmon_probe(struct platform_device *pdev) | 578 | static int bwmon_probe(struct platform_device *pdev) |
| 328 | { | 579 | { |
| 329 | struct device *dev = &pdev->dev; | 580 | struct device *dev = &pdev->dev; |
| 330 | struct dev_pm_opp *opp; | 581 | struct dev_pm_opp *opp; |
| 331 | struct icc_bwmon *bwmon; | 582 | struct icc_bwmon *bwmon; |
| 332 | const struct icc_bwmon_data *data; | ||
| 333 | int ret; | 583 | int ret; |
| 334 | 584 | ||
| 335 | bwmon = devm_kzalloc(dev, sizeof(*bwmon), GFP_KERNEL); | 585 | bwmon = devm_kzalloc(dev, sizeof(*bwmon), GFP_KERNEL); |
| 336 | if (!bwmon) | 586 | if (!bwmon) |
| 337 | return -ENOMEM; | 587 | return -ENOMEM; |
| 338 | 588 | ||
| 339 | data = of_device_get_match_data(dev); | 589 | bwmon->data = of_device_get_match_data(dev); |
| 340 | 590 | ||
| 341 | bwmon->base = devm_platform_ioremap_resource(pdev, 0); | 591 | ret = bwmon_init_regmap(pdev, bwmon); |
| 342 | if (IS_ERR(bwmon->base)) { | 592 | if (ret) |
| 343 | dev_err(dev, "failed to map bwmon registers\n"); | 593 | return ret; |
| 344 | return PTR_ERR(bwmon->base); | ||
| 345 | } | ||
| 346 | 594 | ||
| 347 | bwmon->irq = platform_get_irq(pdev, 0); | 595 | bwmon->irq = platform_get_irq(pdev, 0); |
| 348 | if (bwmon->irq < 0) | 596 | if (bwmon->irq < 0) |
| @@ -362,8 +610,6 @@ static int bwmon_probe(struct platform_device *pdev) · 13 unmodified lines | |||
| 362 | if (IS_ERR(opp)) | 610 | if (IS_ERR(opp)) |
| 363 | return dev_err_probe(dev, ret, "failed to find min peak bandwidth\n"); | 611 | return dev_err_probe(dev, ret, "failed to find min peak bandwidth\n"); |
| 364 | 612 | ||
| 365 | bwmon->sample_ms = data->sample_ms; | ||
| 366 | bwmon->default_lowbw_kbps = data->default_lowbw_kbps; | ||
| 367 | bwmon->dev = dev; | 613 | bwmon->dev = dev; |
| 368 | 614 | ||
| 369 | bwmon_disable(bwmon); | 615 | bwmon_disable(bwmon); |
| @@ -374,7 +620,7 @@ static int bwmon_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 374 | return dev_err_probe(dev, ret, "failed to request IRQ\n"); | 620 | return dev_err_probe(dev, ret, "failed to request IRQ\n"); |
| 375 | 621 | ||
| 376 | platform_set_drvdata(pdev, bwmon); | 622 | platform_set_drvdata(pdev, bwmon); |
| 377 | bwmon_start(bwmon, data); | 623 | bwmon_start(bwmon); |
| 378 | 624 | ||
| 379 | return 0; | 625 | return 0; |
| 380 | } | 626 | } |
| @@ -388,18 +634,55 @@ static int bwmon_remove(struct platform_device *pdev) · 7 unmodified lines | |||
| 388 | return 0; | 634 | return 0; |
| 389 | } | 635 | } |
| 390 | 636 | ||
| 391 | /* BWMON v4 */ | ||
| 392 | static const struct icc_bwmon_data msm8998_bwmon_data = { | 637 | static const struct icc_bwmon_data msm8998_bwmon_data = { |
| 393 | .sample_ms = 4, | 638 | .sample_ms = 4, |
| 639 | .count_unit_kb = 64, | ||
| 394 | .default_highbw_kbps = 4800 * 1024, /* 4.8 GBps */ | 640 | .default_highbw_kbps = 4800 * 1024, /* 4.8 GBps */ |
| 395 | .default_medbw_kbps = 512 * 1024, /* 512 MBps */ | 641 | .default_medbw_kbps = 512 * 1024, /* 512 MBps */ |
| 396 | .default_lowbw_kbps = 0, | 642 | .default_lowbw_kbps = 0, |
| 397 | .zone1_thres_count = 16, | 643 | .zone1_thres_count = 16, |
| 398 | .zone3_thres_count = 1, | 644 | .zone3_thres_count = 1, |
| 645 | .quirks = BWMON_HAS_GLOBAL_IRQ, | ||
| 646 | .regmap_fields = msm8998_bwmon_reg_fields, | ||
| 647 | .regmap_cfg = &msm8998_bwmon_regmap_cfg, | ||
| 648 | }; | ||
| 649 | |||
| 650 | static const struct icc_bwmon_data sdm845_llcc_bwmon_data = { | ||
| 651 | .sample_ms = 4, | ||
| 652 | .count_unit_kb = 1024, | ||
| 653 | .default_highbw_kbps = 800 * 1024, /* 800 MBps */ | ||
| 654 | .default_medbw_kbps = 256 * 1024, /* 256 MBps */ | ||
| 655 | .default_lowbw_kbps = 0, | ||
| 656 | .zone1_thres_count = 16, | ||
| 657 | .zone3_thres_count = 1, | ||
| 658 | .regmap_fields = sdm845_llcc_bwmon_reg_fields, | ||
| 659 | .regmap_cfg = &sdm845_llcc_bwmon_regmap_cfg, | ||
| 660 | }; | ||
| 661 | |||
| 662 | static const struct icc_bwmon_data sc7280_llcc_bwmon_data = { | ||
| 663 | .sample_ms = 4, | ||
| 664 | .count_unit_kb = 64, | ||
| 665 | .default_highbw_kbps = 800 * 1024, /* 800 MBps */ | ||
| 666 | .default_medbw_kbps = 256 * 1024, /* 256 MBps */ | ||
| 667 | .default_lowbw_kbps = 0, | ||
| 668 | .zone1_thres_count = 16, | ||
| 669 | .zone3_thres_count = 1, | ||
| 670 | .quirks = BWMON_NEEDS_FORCE_CLEAR, | ||
| 671 | .regmap_fields = sdm845_llcc_bwmon_reg_fields, | ||
| 672 | .regmap_cfg = &sdm845_llcc_bwmon_regmap_cfg, | ||
| 399 | }; | 673 | }; |
| 400 | 674 | ||
| 401 | static const struct of_device_id bwmon_of_match[] = { | 675 | static const struct of_device_id bwmon_of_match[] = { |
| 402 | { .compatible = "qcom,msm8998-bwmon", .data = &msm8998_bwmon_data }, | 676 | { |
| 677 | .compatible = "qcom,msm8998-bwmon", | ||
| 678 | .data = &msm8998_bwmon_data | ||
| 679 | }, { | ||
| 680 | .compatible = "qcom,sdm845-llcc-bwmon", | ||
| 681 | .data = &sdm845_llcc_bwmon_data | ||
| 682 | }, { | ||
| 683 | .compatible = "qcom,sc7280-llcc-bwmon", | ||
| 684 | .data = &sc7280_llcc_bwmon_data | ||
| 685 | }, | ||
| 403 | {} | 686 | {} |
| 404 | }; | 687 | }; |
| 405 | MODULE_DEVICE_TABLE(of, bwmon_of_match); | 688 | MODULE_DEVICE_TABLE(of, bwmon_of_match); |
| @@ -104,6 +104,7 @@ struct qcom_llcc_config { · 103 unmodified lines | |||
| 104 | int size; | 104 | int size; |
| 105 | bool need_llcc_cfg; | 105 | bool need_llcc_cfg; |
| 106 | const u32 *reg_offset; | 106 | const u32 *reg_offset; |
| 107 | const struct llcc_edac_reg_offset *edac_reg_offset; | ||
| 107 | }; | 108 | }; |
| 108 | 109 | ||
| 109 | enum llcc_reg_offset { | 110 | enum llcc_reg_offset { |
| @@ -296,12 +297,68 @@ static const struct llcc_slice_config sm8450_data[] = { · 186 unmodified lines | |||
| 296 | {LLCC_AENPU, 8, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 }, | 297 | {LLCC_AENPU, 8, 2048, 1, 1, 0xFFFF, 0x0, 0, 0, 0, 0, 0, 0, 0 }, |
| 297 | }; | 298 | }; |
| 298 | 299 | ||
| 299 | static const u32 llcc_v1_2_reg_offset[] = { | 300 | static const struct llcc_edac_reg_offset llcc_v1_edac_reg_offset = { |
| 301 | .trp_ecc_error_status0 = 0x20344, | ||
| 302 | .trp_ecc_error_status1 = 0x20348, | ||
| 303 | .trp_ecc_sb_err_syn0 = 0x2304c, | ||
| 304 | .trp_ecc_db_err_syn0 = 0x20370, | ||
| 305 | .trp_ecc_error_cntr_clear = 0x20440, | ||
| 306 | .trp_interrupt_0_status = 0x20480, | ||
| 307 | .trp_interrupt_0_clear = 0x20484, | ||
| 308 | .trp_interrupt_0_enable = 0x20488, | ||
| 309 | |||
| 310 | /* LLCC Common registers */ | ||
| 311 | .cmn_status0 = 0x3000c, | ||
| 312 | .cmn_interrupt_0_enable = 0x3001c, | ||
| 313 | .cmn_interrupt_2_enable = 0x3003c, | ||
| 314 | |||
| 315 | /* LLCC DRP registers */ | ||
| 316 | .drp_ecc_error_cfg = 0x40000, | ||
| 317 | .drp_ecc_error_cntr_clear = 0x40004, | ||
| 318 | .drp_interrupt_status = 0x41000, | ||
| 319 | .drp_interrupt_clear = 0x41008, | ||
| 320 | .drp_interrupt_enable = 0x4100c, | ||
| 321 | .drp_ecc_error_status0 = 0x42044, | ||
| 322 | .drp_ecc_error_status1 = 0x42048, | ||
| 323 | .drp_ecc_sb_err_syn0 = 0x4204c, | ||
| 324 | .drp_ecc_db_err_syn0 = 0x42070, | ||
| 325 | }; | ||
| 326 | |||
| 327 | static const struct llcc_edac_reg_offset llcc_v2_1_edac_reg_offset = { | ||
| 328 | .trp_ecc_error_status0 = 0x20344, | ||
| 329 | .trp_ecc_error_status1 = 0x20348, | ||
| 330 | .trp_ecc_sb_err_syn0 = 0x2034c, | ||
| 331 | .trp_ecc_db_err_syn0 = 0x20370, | ||
| 332 | .trp_ecc_error_cntr_clear = 0x20440, | ||
| 333 | .trp_interrupt_0_status = 0x20480, | ||
| 334 | .trp_interrupt_0_clear = 0x20484, | ||
| 335 | .trp_interrupt_0_enable = 0x20488, | ||
| 336 | |||
| 337 | /* LLCC Common registers */ | ||
| 338 | .cmn_status0 = 0x3400c, | ||
| 339 | .cmn_interrupt_0_enable = 0x3401c, | ||
| 340 | .cmn_interrupt_2_enable = 0x3403c, | ||
| 341 | |||
| 342 | /* LLCC DRP registers */ | ||
| 343 | .drp_ecc_error_cfg = 0x50000, | ||
| 344 | .drp_ecc_error_cntr_clear = 0x50004, | ||
| 345 | .drp_interrupt_status = 0x50020, | ||
| 346 | .drp_interrupt_clear = 0x50028, | ||
| 347 | .drp_interrupt_enable = 0x5002c, | ||
| 348 | .drp_ecc_error_status0 = 0x520f4, | ||
| 349 | .drp_ecc_error_status1 = 0x520f8, | ||
| 350 | .drp_ecc_sb_err_syn0 = 0x520fc, | ||
| 351 | .drp_ecc_db_err_syn0 = 0x52120, | ||
| 352 | }; | ||
| 353 | |||
| 354 | /* LLCC register offset starting from v1.0.0 */ | ||
| 355 | static const u32 llcc_v1_reg_offset[] = { | ||
| 300 | [LLCC_COMMON_HW_INFO] = 0x00030000, | 356 | [LLCC_COMMON_HW_INFO] = 0x00030000, |
| 301 | [LLCC_COMMON_STATUS0] = 0x0003000c, | 357 | [LLCC_COMMON_STATUS0] = 0x0003000c, |
| 302 | }; | 358 | }; |
| 303 | 359 | ||
| 304 | static const u32 llcc_v21_reg_offset[] = { | 360 | /* LLCC register offset starting from v2.0.1 */ |
| 361 | static const u32 llcc_v2_1_reg_offset[] = { | ||
| 305 | [LLCC_COMMON_HW_INFO] = 0x00034000, | 362 | [LLCC_COMMON_HW_INFO] = 0x00034000, |
| 306 | [LLCC_COMMON_STATUS0] = 0x0003400c, | 363 | [LLCC_COMMON_STATUS0] = 0x0003400c, |
| 307 | }; | 364 | }; |
| @@ -310,70 +367,80 @@ static const struct qcom_llcc_config sc7180_cfg = { · 2 unmodified lines | |||
| 310 | .sct_data = sc7180_data, | 367 | .sct_data = sc7180_data, |
| 311 | .size = ARRAY_SIZE(sc7180_data), | 368 | .size = ARRAY_SIZE(sc7180_data), |
| 312 | .need_llcc_cfg = true, | 369 | .need_llcc_cfg = true, |
| 313 | .reg_offset = llcc_v1_2_reg_offset, | 370 | .reg_offset = llcc_v1_reg_offset, |
| 371 | .edac_reg_offset = &llcc_v1_edac_reg_offset, | ||
| 314 | }; | 372 | }; |
| 315 | 373 | ||
| 316 | static const struct qcom_llcc_config sc7280_cfg = { | 374 | static const struct qcom_llcc_config sc7280_cfg = { |
| 317 | .sct_data = sc7280_data, | 375 | .sct_data = sc7280_data, |
| 318 | .size = ARRAY_SIZE(sc7280_data), | 376 | .size = ARRAY_SIZE(sc7280_data), |
| 319 | .need_llcc_cfg = true, | 377 | .need_llcc_cfg = true, |
| 320 | .reg_offset = llcc_v1_2_reg_offset, | 378 | .reg_offset = llcc_v1_reg_offset, |
| 379 | .edac_reg_offset = &llcc_v1_edac_reg_offset, | ||
| 321 | }; | 380 | }; |
| 322 | 381 | ||
| 323 | static const struct qcom_llcc_config sc8180x_cfg = { | 382 | static const struct qcom_llcc_config sc8180x_cfg = { |
| 324 | .sct_data = sc8180x_data, | 383 | .sct_data = sc8180x_data, |
| 325 | .size = ARRAY_SIZE(sc8180x_data), | 384 | .size = ARRAY_SIZE(sc8180x_data), |
| 326 | .need_llcc_cfg = true, | 385 | .need_llcc_cfg = true, |
| 327 | .reg_offset = llcc_v1_2_reg_offset, | 386 | .reg_offset = llcc_v1_reg_offset, |
| 387 | .edac_reg_offset = &llcc_v1_edac_reg_offset, | ||
| 328 | }; | 388 | }; |
| 329 | 389 | ||
| 330 | static const struct qcom_llcc_config sc8280xp_cfg = { | 390 | static const struct qcom_llcc_config sc8280xp_cfg = { |
| 331 | .sct_data = sc8280xp_data, | 391 | .sct_data = sc8280xp_data, |
| 332 | .size = ARRAY_SIZE(sc8280xp_data), | 392 | .size = ARRAY_SIZE(sc8280xp_data), |
| 333 | .need_llcc_cfg = true, | 393 | .need_llcc_cfg = true, |
| 334 | .reg_offset = llcc_v1_2_reg_offset, | 394 | .reg_offset = llcc_v1_reg_offset, |
| 395 | .edac_reg_offset = &llcc_v1_edac_reg_offset, | ||
| 335 | }; | 396 | }; |
| 336 | 397 | ||
| 337 | static const struct qcom_llcc_config sdm845_cfg = { | 398 | static const struct qcom_llcc_config sdm845_cfg = { |
| 338 | .sct_data = sdm845_data, | 399 | .sct_data = sdm845_data, |
| 339 | .size = ARRAY_SIZE(sdm845_data), | 400 | .size = ARRAY_SIZE(sdm845_data), |
| 340 | .need_llcc_cfg = false, | 401 | .need_llcc_cfg = false, |
| 341 | .reg_offset = llcc_v1_2_reg_offset, | 402 | .reg_offset = llcc_v1_reg_offset, |
| 403 | .edac_reg_offset = &llcc_v1_edac_reg_offset, | ||
| 342 | }; | 404 | }; |
| 343 | 405 | ||
| 344 | static const struct qcom_llcc_config sm6350_cfg = { | 406 | static const struct qcom_llcc_config sm6350_cfg = { |
| 345 | .sct_data = sm6350_data, | 407 | .sct_data = sm6350_data, |
| 346 | .size = ARRAY_SIZE(sm6350_data), | 408 | .size = ARRAY_SIZE(sm6350_data), |
| 347 | .need_llcc_cfg = true, | 409 | .need_llcc_cfg = true, |
| 348 | .reg_offset = llcc_v1_2_reg_offset, | 410 | .reg_offset = llcc_v1_reg_offset, |
| 411 | .edac_reg_offset = &llcc_v1_edac_reg_offset, | ||
| 349 | }; | 412 | }; |
| 350 | 413 | ||
| 351 | static const struct qcom_llcc_config sm8150_cfg = { | 414 | static const struct qcom_llcc_config sm8150_cfg = { |
| 352 | .sct_data = sm8150_data, | 415 | .sct_data = sm8150_data, |
| 353 | .size = ARRAY_SIZE(sm8150_data), | 416 | .size = ARRAY_SIZE(sm8150_data), |
| 354 | .need_llcc_cfg = true, | 417 | .need_llcc_cfg = true, |
| 355 | .reg_offset = llcc_v1_2_reg_offset, | 418 | .reg_offset = llcc_v1_reg_offset, |
| 419 | .edac_reg_offset = &llcc_v1_edac_reg_offset, | ||
| 356 | }; | 420 | }; |
| 357 | 421 | ||
| 358 | static const struct qcom_llcc_config sm8250_cfg = { | 422 | static const struct qcom_llcc_config sm8250_cfg = { |
| 359 | .sct_data = sm8250_data, | 423 | .sct_data = sm8250_data, |
| 360 | .size = ARRAY_SIZE(sm8250_data), | 424 | .size = ARRAY_SIZE(sm8250_data), |
| 361 | .need_llcc_cfg = true, | 425 | .need_llcc_cfg = true, |
| 362 | .reg_offset = llcc_v1_2_reg_offset, | 426 | .reg_offset = llcc_v1_reg_offset, |
| 427 | .edac_reg_offset = &llcc_v1_edac_reg_offset, | ||
| 363 | }; | 428 | }; |
| 364 | 429 | ||
| 365 | static const struct qcom_llcc_config sm8350_cfg = { | 430 | static const struct qcom_llcc_config sm8350_cfg = { |
| 366 | .sct_data = sm8350_data, | 431 | .sct_data = sm8350_data, |
| 367 | .size = ARRAY_SIZE(sm8350_data), | 432 | .size = ARRAY_SIZE(sm8350_data), |
| 368 | .need_llcc_cfg = true, | 433 | .need_llcc_cfg = true, |
| 369 | .reg_offset = llcc_v1_2_reg_offset, | 434 | .reg_offset = llcc_v1_reg_offset, |
| 435 | .edac_reg_offset = &llcc_v1_edac_reg_offset, | ||
| 370 | }; | 436 | }; |
| 371 | 437 | ||
| 372 | static const struct qcom_llcc_config sm8450_cfg = { | 438 | static const struct qcom_llcc_config sm8450_cfg = { |
| 373 | .sct_data = sm8450_data, | 439 | .sct_data = sm8450_data, |
| 374 | .size = ARRAY_SIZE(sm8450_data), | 440 | .size = ARRAY_SIZE(sm8450_data), |
| 375 | .need_llcc_cfg = true, | 441 | .need_llcc_cfg = true, |
| 376 | .reg_offset = llcc_v21_reg_offset, | 442 | .reg_offset = llcc_v2_1_reg_offset, |
| 443 | .edac_reg_offset = &llcc_v2_1_edac_reg_offset, | ||
| 377 | }; | 444 | }; |
| 378 | 445 | ||
| 379 | static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER; | 446 | static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER; |
| @@ -774,6 +841,7 @@ static int qcom_llcc_probe(struct platform_device *pdev) · 394 unmodified lines | |||
| 774 | 841 | ||
| 775 | drv_data->cfg = llcc_cfg; | 842 | drv_data->cfg = llcc_cfg; |
| 776 | drv_data->cfg_size = sz; | 843 | drv_data->cfg_size = sz; |
| 844 | drv_data->edac_reg_offset = cfg->edac_reg_offset; | ||
| 777 | mutex_init(&drv_data->lock); | 845 | mutex_init(&drv_data->lock); |
| 778 | platform_set_drvdata(pdev, drv_data); | 846 | platform_set_drvdata(pdev, drv_data); |
| 779 | 847 | ||
| @@ -246,6 +246,14 @@ static const struct stats_config rpm_data_dba0 = { · 245 unmodified lines | |||
| 246 | .subsystem_stats_in_smem = false, | 246 | .subsystem_stats_in_smem = false, |
| 247 | }; | 247 | }; |
| 248 | 248 | ||
| 249 | static const struct stats_config rpmh_data_sdm845 = { | ||
| 250 | .stats_offset = 0x48, | ||
| 251 | .num_records = 2, | ||
| 252 | .appended_stats_avail = false, | ||
| 253 | .dynamic_offset = false, | ||
| 254 | .subsystem_stats_in_smem = true, | ||
| 255 | }; | ||
| 256 | |||
| 249 | static const struct stats_config rpmh_data = { | 257 | static const struct stats_config rpmh_data = { |
| 250 | .stats_offset = 0x48, | 258 | .stats_offset = 0x48, |
| 251 | .num_records = 3, | 259 | .num_records = 3, |
| @@ -261,6 +269,7 @@ static const struct of_device_id qcom_stats_table[] = { · 9 unmodified lines | |||
| 261 | { .compatible = "qcom,msm8974-rpm-stats", .data = &rpm_data_dba0 }, | 269 | { .compatible = "qcom,msm8974-rpm-stats", .data = &rpm_data_dba0 }, |
| 262 | { .compatible = "qcom,rpm-stats", .data = &rpm_data }, | 270 | { .compatible = "qcom,rpm-stats", .data = &rpm_data }, |
| 263 | { .compatible = "qcom,rpmh-stats", .data = &rpmh_data }, | 271 | { .compatible = "qcom,rpmh-stats", .data = &rpmh_data }, |
| 272 | { .compatible = "qcom,sdm845-rpmh-stats", .data = &rpmh_data_sdm845 }, | ||
| 264 | { } | 273 | { } |
| 265 | }; | 274 | }; |
| 266 | MODULE_DEVICE_TABLE(of, qcom_stats_table); | 275 | MODULE_DEVICE_TABLE(of, qcom_stats_table); |
| @@ -57,11 +57,11 @@ do { \ · 56 unmodified lines | |||
| 57 | #define TLV_TYPE_SIZE sizeof(u8) | 57 | #define TLV_TYPE_SIZE sizeof(u8) |
| 58 | #define OPTIONAL_TLV_TYPE_START 0x10 | 58 | #define OPTIONAL_TLV_TYPE_START 0x10 |
| 59 | 59 | ||
| 60 | static int qmi_encode(struct qmi_elem_info *ei_array, void *out_buf, | 60 | static int qmi_encode(const struct qmi_elem_info *ei_array, void *out_buf, |
| 61 | const void *in_c_struct, u32 out_buf_len, | 61 | const void *in_c_struct, u32 out_buf_len, |
| 62 | int enc_level); | 62 | int enc_level); |
| 63 | 63 | ||
| 64 | static int qmi_decode(struct qmi_elem_info *ei_array, void *out_c_struct, | 64 | static int qmi_decode(const struct qmi_elem_info *ei_array, void *out_c_struct, |
| 65 | const void *in_buf, u32 in_buf_len, int dec_level); | 65 | const void *in_buf, u32 in_buf_len, int dec_level); |
| 66 | 66 | ||
| 67 | /** | 67 | /** |
| @@ -76,10 +76,10 @@ static int qmi_decode(struct qmi_elem_info *ei_array, void *out_c_struct, · 8 unmodified lines | |||
| 76 | * | 76 | * |
| 77 | * Return: struct info of the next element that can be encoded. | 77 | * Return: struct info of the next element that can be encoded. |
| 78 | */ | 78 | */ |
| 79 | static struct qmi_elem_info *skip_to_next_elem(struct qmi_elem_info *ei_array, | 79 | static const struct qmi_elem_info * |
| 80 | int level) | 80 | skip_to_next_elem(const struct qmi_elem_info *ei_array, int level) |
| 81 | { | 81 | { |
| 82 | struct qmi_elem_info *temp_ei = ei_array; | 82 | const struct qmi_elem_info *temp_ei = ei_array; |
| 83 | u8 tlv_type; | 83 | u8 tlv_type; |
| 84 | 84 | ||
| 85 | if (level > 1) { | 85 | if (level > 1) { |
| @@ -101,11 +101,11 @@ static struct qmi_elem_info *skip_to_next_elem(struct qmi_elem_info *ei_array, · 15 unmodified lines | |||
| 101 | * | 101 | * |
| 102 | * Return: Expected minimum length of the QMI message or 0 on error. | 102 | * Return: Expected minimum length of the QMI message or 0 on error. |
| 103 | */ | 103 | */ |
| 104 | static int qmi_calc_min_msg_len(struct qmi_elem_info *ei_array, | 104 | static int qmi_calc_min_msg_len(const struct qmi_elem_info *ei_array, |
| 105 | int level) | 105 | int level) |
| 106 | { | 106 | { |
| 107 | int min_msg_len = 0; | 107 | int min_msg_len = 0; |
| 108 | struct qmi_elem_info *temp_ei = ei_array; | 108 | const struct qmi_elem_info *temp_ei = ei_array; |
| 109 | 109 | ||
| 110 | if (!ei_array) | 110 | if (!ei_array) |
| 111 | return min_msg_len; | 111 | return min_msg_len; |
| @@ -194,13 +194,13 @@ static int qmi_encode_basic_elem(void *buf_dst, const void *buf_src, · 82 unmodified lines | |||
| 194 | * Return: The number of bytes of encoded information on success or negative | 194 | * Return: The number of bytes of encoded information on success or negative |
| 195 | * errno on error. | 195 | * errno on error. |
| 196 | */ | 196 | */ |
| 197 | static int qmi_encode_struct_elem(struct qmi_elem_info *ei_array, | 197 | static int qmi_encode_struct_elem(const struct qmi_elem_info *ei_array, |
| 198 | void *buf_dst, const void *buf_src, | 198 | void *buf_dst, const void *buf_src, |
| 199 | u32 elem_len, u32 out_buf_len, | 199 | u32 elem_len, u32 out_buf_len, |
| 200 | int enc_level) | 200 | int enc_level) |
| 201 | { | 201 | { |
| 202 | int i, rc, encoded_bytes = 0; | 202 | int i, rc, encoded_bytes = 0; |
| 203 | struct qmi_elem_info *temp_ei = ei_array; | 203 | const struct qmi_elem_info *temp_ei = ei_array; |
| 204 | 204 | ||
| 205 | for (i = 0; i < elem_len; i++) { | 205 | for (i = 0; i < elem_len; i++) { |
| 206 | rc = qmi_encode(temp_ei->ei_array, buf_dst, buf_src, | 206 | rc = qmi_encode(temp_ei->ei_array, buf_dst, buf_src, |
| @@ -233,13 +233,13 @@ static int qmi_encode_struct_elem(struct qmi_elem_info *ei_array, · 26 unmodified lines | |||
| 233 | * Return: The number of bytes of encoded information on success or negative | 233 | * Return: The number of bytes of encoded information on success or negative |
| 234 | * errno on error. | 234 | * errno on error. |
| 235 | */ | 235 | */ |
| 236 | static int qmi_encode_string_elem(struct qmi_elem_info *ei_array, | 236 | static int qmi_encode_string_elem(const struct qmi_elem_info *ei_array, |
| 237 | void *buf_dst, const void *buf_src, | 237 | void *buf_dst, const void *buf_src, |
| 238 | u32 out_buf_len, int enc_level) | 238 | u32 out_buf_len, int enc_level) |
| 239 | { | 239 | { |
| 240 | int rc; | 240 | int rc; |
| 241 | int encoded_bytes = 0; | 241 | int encoded_bytes = 0; |
| 242 | struct qmi_elem_info *temp_ei = ei_array; | 242 | const struct qmi_elem_info *temp_ei = ei_array; |
| 243 | u32 string_len = 0; | 243 | u32 string_len = 0; |
| 244 | u32 string_len_sz = 0; | 244 | u32 string_len_sz = 0; |
| 245 | 245 | ||
| @@ -289,11 +289,11 @@ static int qmi_encode_string_elem(struct qmi_elem_info *ei_array, · 43 unmodified lines | |||
| 289 | * Return: The number of bytes of encoded information on success or negative | 289 | * Return: The number of bytes of encoded information on success or negative |
| 290 | * errno on error. | 290 | * errno on error. |
| 291 | */ | 291 | */ |
| 292 | static int qmi_encode(struct qmi_elem_info *ei_array, void *out_buf, | 292 | static int qmi_encode(const struct qmi_elem_info *ei_array, void *out_buf, |
| 293 | const void *in_c_struct, u32 out_buf_len, | 293 | const void *in_c_struct, u32 out_buf_len, |
| 294 | int enc_level) | 294 | int enc_level) |
| 295 | { | 295 | { |
| 296 | struct qmi_elem_info *temp_ei = ei_array; | 296 | const struct qmi_elem_info *temp_ei = ei_array; |
| 297 | u8 opt_flag_value = 0; | 297 | u8 opt_flag_value = 0; |
| 298 | u32 data_len_value = 0, data_len_sz; | 298 | u32 data_len_value = 0, data_len_sz; |
| 299 | u8 *buf_dst = (u8 *)out_buf; | 299 | u8 *buf_dst = (u8 *)out_buf; |
| @@ -468,13 +468,13 @@ static int qmi_decode_basic_elem(void *buf_dst, const void *buf_src, · 168 unmodified lines | |||
| 468 | * Return: The total size of the decoded data elements on success, negative | 468 | * Return: The total size of the decoded data elements on success, negative |
| 469 | * errno on error. | 469 | * errno on error. |
| 470 | */ | 470 | */ |
| 471 | static int qmi_decode_struct_elem(struct qmi_elem_info *ei_array, | 471 | static int qmi_decode_struct_elem(const struct qmi_elem_info *ei_array, |
| 472 | void *buf_dst, const void *buf_src, | 472 | void *buf_dst, const void *buf_src, |
| 473 | u32 elem_len, u32 tlv_len, | 473 | u32 elem_len, u32 tlv_len, |
| 474 | int dec_level) | 474 | int dec_level) |
| 475 | { | 475 | { |
| 476 | int i, rc, decoded_bytes = 0; | 476 | int i, rc, decoded_bytes = 0; |
| 477 | struct qmi_elem_info *temp_ei = ei_array; | 477 | const struct qmi_elem_info *temp_ei = ei_array; |
| 478 | 478 | ||
| 479 | for (i = 0; i < elem_len && decoded_bytes < tlv_len; i++) { | 479 | for (i = 0; i < elem_len && decoded_bytes < tlv_len; i++) { |
| 480 | rc = qmi_decode(temp_ei->ei_array, buf_dst, buf_src, | 480 | rc = qmi_decode(temp_ei->ei_array, buf_dst, buf_src, |
| @@ -514,7 +514,7 @@ static int qmi_decode_struct_elem(struct qmi_elem_info *ei_array, · 33 unmodified lines | |||
| 514 | * Return: The total size of the decoded data elements on success, negative | 514 | * Return: The total size of the decoded data elements on success, negative |
| 515 | * errno on error. | 515 | * errno on error. |
| 516 | */ | 516 | */ |
| 517 | static int qmi_decode_string_elem(struct qmi_elem_info *ei_array, | 517 | static int qmi_decode_string_elem(const struct qmi_elem_info *ei_array, |
| 518 | void *buf_dst, const void *buf_src, | 518 | void *buf_dst, const void *buf_src, |
| 519 | u32 tlv_len, int dec_level) | 519 | u32 tlv_len, int dec_level) |
| 520 | { | 520 | { |
| @@ -522,7 +522,7 @@ static int qmi_decode_string_elem(struct qmi_elem_info *ei_array, · 1 unmodified line | |||
| 522 | int decoded_bytes = 0; | 522 | int decoded_bytes = 0; |
| 523 | u32 string_len = 0; | 523 | u32 string_len = 0; |
| 524 | u32 string_len_sz = 0; | 524 | u32 string_len_sz = 0; |
| 525 | struct qmi_elem_info *temp_ei = ei_array; | 525 | const struct qmi_elem_info *temp_ei = ei_array; |
| 526 | 526 | ||
| 527 | if (dec_level == 1) { | 527 | if (dec_level == 1) { |
| 528 | string_len = tlv_len; | 528 | string_len = tlv_len; |
| @@ -564,10 +564,10 @@ static int qmi_decode_string_elem(struct qmi_elem_info *ei_array, · 35 unmodified lines | |||
| 564 | * | 564 | * |
| 565 | * Return: Pointer to struct info, if found | 565 | * Return: Pointer to struct info, if found |
| 566 | */ | 566 | */ |
| 567 | static struct qmi_elem_info *find_ei(struct qmi_elem_info *ei_array, | 567 | static const struct qmi_elem_info *find_ei(const struct qmi_elem_info *ei_array, |
| 568 | u32 type) | 568 | u32 type) |
| 569 | { | 569 | { |
| 570 | struct qmi_elem_info *temp_ei = ei_array; | 570 | const struct qmi_elem_info *temp_ei = ei_array; |
| 571 | 571 | ||
| 572 | while (temp_ei->data_type != QMI_EOTI) { | 572 | while (temp_ei->data_type != QMI_EOTI) { |
| 573 | if (temp_ei->tlv_type == (u8)type) | 573 | if (temp_ei->tlv_type == (u8)type) |
| @@ -590,11 +590,11 @@ static struct qmi_elem_info *find_ei(struct qmi_elem_info *ei_array, · 16 unmodified lines | |||
| 590 | * Return: The number of bytes of decoded information on success, negative | 590 | * Return: The number of bytes of decoded information on success, negative |
| 591 | * errno on error. | 591 | * errno on error. |
| 592 | */ | 592 | */ |
| 593 | static int qmi_decode(struct qmi_elem_info *ei_array, void *out_c_struct, | 593 | static int qmi_decode(const struct qmi_elem_info *ei_array, void *out_c_struct, |
| 594 | const void *in_buf, u32 in_buf_len, | 594 | const void *in_buf, u32 in_buf_len, |
| 595 | int dec_level) | 595 | int dec_level) |
| 596 | { | 596 | { |
| 597 | struct qmi_elem_info *temp_ei = ei_array; | 597 | const struct qmi_elem_info *temp_ei = ei_array; |
| 598 | u8 opt_flag_value = 1; | 598 | u8 opt_flag_value = 1; |
| 599 | u32 data_len_value = 0, data_len_sz = 0; | 599 | u32 data_len_value = 0, data_len_sz = 0; |
| 600 | u8 *buf_dst = out_c_struct; | 600 | u8 *buf_dst = out_c_struct; |
| @@ -713,7 +713,7 @@ static int qmi_decode(struct qmi_elem_info *ei_array, void *out_c_struct, · 112 unmodified lines | |||
| 713 | * Return: Buffer with encoded message, or negative ERR_PTR() on error | 713 | * Return: Buffer with encoded message, or negative ERR_PTR() on error |
| 714 | */ | 714 | */ |
| 715 | void *qmi_encode_message(int type, unsigned int msg_id, size_t *len, | 715 | void *qmi_encode_message(int type, unsigned int msg_id, size_t *len, |
| 716 | unsigned int txn_id, struct qmi_elem_info *ei, | 716 | unsigned int txn_id, const struct qmi_elem_info *ei, |
| 717 | const void *c_struct) | 717 | const void *c_struct) |
| 718 | { | 718 | { |
| 719 | struct qmi_header *hdr; | 719 | struct qmi_header *hdr; |
| @@ -767,7 +767,7 @@ EXPORT_SYMBOL(qmi_encode_message); · 47 unmodified lines | |||
| 767 | * errno on error. | 767 | * errno on error. |
| 768 | */ | 768 | */ |
| 769 | int qmi_decode_message(const void *buf, size_t len, | 769 | int qmi_decode_message(const void *buf, size_t len, |
| 770 | struct qmi_elem_info *ei, void *c_struct) | 770 | const struct qmi_elem_info *ei, void *c_struct) |
| 771 | { | 771 | { |
| 772 | if (!ei) | 772 | if (!ei) |
| 773 | return -EINVAL; | 773 | return -EINVAL; |
| @@ -781,7 +781,7 @@ int qmi_decode_message(const void *buf, size_t len, · 7 unmodified lines | |||
| 781 | EXPORT_SYMBOL(qmi_decode_message); | 781 | EXPORT_SYMBOL(qmi_decode_message); |
| 782 | 782 | ||
| 783 | /* Common header in all QMI responses */ | 783 | /* Common header in all QMI responses */ |
| 784 | struct qmi_elem_info qmi_response_type_v01_ei[] = { | 784 | const struct qmi_elem_info qmi_response_type_v01_ei[] = { |
| 785 | { | 785 | { |
| 786 | .data_type = QMI_SIGNED_2_BYTE_ENUM, | 786 | .data_type = QMI_SIGNED_2_BYTE_ENUM, |
| 787 | .elem_len = 1, | 787 | .elem_len = 1, |
| @@ -305,7 +305,7 @@ EXPORT_SYMBOL(qmi_add_server); · 304 unmodified lines | |||
| 305 | * Return: Transaction id on success, negative errno on failure. | 305 | * Return: Transaction id on success, negative errno on failure. |
| 306 | */ | 306 | */ |
| 307 | int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn, | 307 | int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn, |
| 308 | struct qmi_elem_info *ei, void *c_struct) | 308 | const struct qmi_elem_info *ei, void *c_struct) |
| 309 | { | 309 | { |
| 310 | int ret; | 310 | int ret; |
| 311 | 311 | ||
| @@ -736,7 +736,8 @@ EXPORT_SYMBOL(qmi_handle_release); · 424 unmodified lines | |||
| 736 | static ssize_t qmi_send_message(struct qmi_handle *qmi, | 736 | static ssize_t qmi_send_message(struct qmi_handle *qmi, |
| 737 | struct sockaddr_qrtr *sq, struct qmi_txn *txn, | 737 | struct sockaddr_qrtr *sq, struct qmi_txn *txn, |
| 738 | int type, int msg_id, size_t len, | 738 | int type, int msg_id, size_t len, |
| 739 | struct qmi_elem_info *ei, const void *c_struct) | 739 | const struct qmi_elem_info *ei, |
| 740 | const void *c_struct) | ||
| 740 | { | 741 | { |
| 741 | struct msghdr msghdr = {}; | 742 | struct msghdr msghdr = {}; |
| 742 | struct kvec iv; | 743 | struct kvec iv; |
| @@ -787,7 +788,7 @@ static ssize_t qmi_send_message(struct qmi_handle *qmi, · 44 unmodified lines | |||
| 787 | */ | 788 | */ |
| 788 | ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, | 789 | ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, |
| 789 | struct qmi_txn *txn, int msg_id, size_t len, | 790 | struct qmi_txn *txn, int msg_id, size_t len, |
| 790 | struct qmi_elem_info *ei, const void *c_struct) | 791 | const struct qmi_elem_info *ei, const void *c_struct) |
| 791 | { | 792 | { |
| 792 | return qmi_send_message(qmi, sq, txn, QMI_REQUEST, msg_id, len, ei, | 793 | return qmi_send_message(qmi, sq, txn, QMI_REQUEST, msg_id, len, ei, |
| 793 | c_struct); | 794 | c_struct); |
| @@ -808,7 +809,7 @@ EXPORT_SYMBOL(qmi_send_request); · 14 unmodified lines | |||
| 808 | */ | 809 | */ |
| 809 | ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, | 810 | ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, |
| 810 | struct qmi_txn *txn, int msg_id, size_t len, | 811 | struct qmi_txn *txn, int msg_id, size_t len, |
| 811 | struct qmi_elem_info *ei, const void *c_struct) | 812 | const struct qmi_elem_info *ei, const void *c_struct) |
| 812 | { | 813 | { |
| 813 | return qmi_send_message(qmi, sq, txn, QMI_RESPONSE, msg_id, len, ei, | 814 | return qmi_send_message(qmi, sq, txn, QMI_RESPONSE, msg_id, len, ei, |
| 814 | c_struct); | 815 | c_struct); |
| @@ -827,7 +828,8 @@ EXPORT_SYMBOL(qmi_send_response); · 12 unmodified lines | |||
| 827 | * Return: 0 on success, negative errno on failure. | 828 | * Return: 0 on success, negative errno on failure. |
| 828 | */ | 829 | */ |
| 829 | ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, | 830 | ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, |
| 830 | int msg_id, size_t len, struct qmi_elem_info *ei, | 831 | int msg_id, size_t len, |
| 832 | const struct qmi_elem_info *ei, | ||
| 831 | const void *c_struct) | 833 | const void *c_struct) |
| 832 | { | 834 | { |
| 833 | struct qmi_txn txn; | 835 | struct qmi_txn txn; |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | |||
| 29 | #define RPMPD_RWLM 0x6d6c7772 | 29 | #define RPMPD_RWLM 0x6d6c7772 |
| 30 | #define RPMPD_RWSC 0x63737772 | 30 | #define RPMPD_RWSC 0x63737772 |
| 31 | #define RPMPD_RWSM 0x6d737772 | 31 | #define RPMPD_RWSM 0x6d737772 |
| 32 | #define RPMPD_RWGX 0x78677772 | ||
| 32 | 33 | ||
| 33 | /* Operation Keys */ | 34 | /* Operation Keys */ |
| 34 | #define KEY_CORNER 0x6e726f63 /* corn */ | 35 | #define KEY_CORNER 0x6e726f63 /* corn */ |
| @@ -433,6 +434,26 @@ static const struct rpmpd_desc sm6125_desc = { · 398 unmodified lines | |||
| 433 | .max_state = RPM_SMD_LEVEL_BINNING, | 434 | .max_state = RPM_SMD_LEVEL_BINNING, |
| 434 | }; | 435 | }; |
| 435 | 436 | ||
| 437 | DEFINE_RPMPD_PAIR(sm6375, vddgx, vddgx_ao, RWGX, LEVEL, 0); | ||
| 438 | static struct rpmpd *sm6375_rpmpds[] = { | ||
| 439 | [SM6375_VDDCX] = &sm6125_vddcx, | ||
| 440 | [SM6375_VDDCX_AO] = &sm6125_vddcx_ao, | ||
| 441 | [SM6375_VDDCX_VFL] = &sm6125_vddcx_vfl, | ||
| 442 | [SM6375_VDDMX] = &sm6125_vddmx, | ||
| 443 | [SM6375_VDDMX_AO] = &sm6125_vddmx_ao, | ||
| 444 | [SM6375_VDDMX_VFL] = &sm6125_vddmx_vfl, | ||
| 445 | [SM6375_VDDGX] = &sm6375_vddgx, | ||
| 446 | [SM6375_VDDGX_AO] = &sm6375_vddgx_ao, | ||
| 447 | [SM6375_VDD_LPI_CX] = &sm6115_vdd_lpi_cx, | ||
| 448 | [SM6375_VDD_LPI_MX] = &sm6115_vdd_lpi_mx, | ||
| 449 | }; | ||
| 450 | |||
| 451 | static const struct rpmpd_desc sm6375_desc = { | ||
| 452 | .rpmpds = sm6375_rpmpds, | ||
| 453 | .num_pds = ARRAY_SIZE(sm6375_rpmpds), | ||
| 454 | .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, | ||
| 455 | }; | ||
| 456 | |||
| 436 | static struct rpmpd *qcm2290_rpmpds[] = { | 457 | static struct rpmpd *qcm2290_rpmpds[] = { |
| 437 | [QCM2290_VDDCX] = &sm6115_vddcx, | 458 | [QCM2290_VDDCX] = &sm6115_vddcx, |
| 438 | [QCM2290_VDDCX_AO] = &sm6115_vddcx_ao, | 459 | [QCM2290_VDDCX_AO] = &sm6115_vddcx_ao, |
| @@ -466,6 +487,7 @@ static const struct of_device_id rpmpd_match_table[] = { · 27 unmodified lines | |||
| 466 | { .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc }, | 487 | { .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc }, |
| 467 | { .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc }, | 488 | { .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc }, |
| 468 | { .compatible = "qcom,sm6125-rpmpd", .data = &sm6125_desc }, | 489 | { .compatible = "qcom,sm6125-rpmpd", .data = &sm6125_desc }, |
| 490 | { .compatible = "qcom,sm6375-rpmpd", .data = &sm6375_desc }, | ||
| 469 | { } | 491 | { } |
| 470 | }; | 492 | }; |
| 471 | MODULE_DEVICE_TABLE(of, rpmpd_match_table); | 493 | MODULE_DEVICE_TABLE(of, rpmpd_match_table); |
| @@ -136,6 +136,7 @@ static void qcom_smem_state_release(struct kref *ref) · 135 unmodified lines | |||
| 136 | struct qcom_smem_state *state = container_of(ref, struct qcom_smem_state, refcount); | 136 | struct qcom_smem_state *state = container_of(ref, struct qcom_smem_state, refcount); |
| 137 | 137 | ||
| 138 | list_del(&state->list); | 138 | list_del(&state->list); |
| 139 | of_node_put(state->of_node); | ||
| 139 | kfree(state); | 140 | kfree(state); |
| 140 | } | 141 | } |
| 141 | 142 | ||
| @@ -205,7 +206,7 @@ struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node, · 63 unmodified lines | |||
| 205 | 206 | ||
| 206 | kref_init(&state->refcount); | 207 | kref_init(&state->refcount); |
| 207 | 208 | ||
| 208 | state->of_node = of_node; | 209 | state->of_node = of_node_get(of_node); |
| 209 | state->ops = *ops; | 210 | state->ops = *ops; |
| 210 | state->priv = priv; | 211 | state->priv = priv; |
| 211 | 212 | ||
| @@ -526,7 +526,7 @@ static int qcom_smsm_probe(struct platform_device *pdev) · 525 unmodified lines | |||
| 526 | for (id = 0; id < smsm->num_hosts; id++) { | 526 | for (id = 0; id < smsm->num_hosts; id++) { |
| 527 | ret = smsm_parse_ipc(smsm, id); | 527 | ret = smsm_parse_ipc(smsm, id); |
| 528 | if (ret < 0) | 528 | if (ret < 0) |
| 529 | return ret; | 529 | goto out_put; |
| 530 | } | 530 | } |
| 531 | 531 | ||
| 532 | /* Acquire the main SMSM state vector */ | 532 | /* Acquire the main SMSM state vector */ |
| @@ -534,13 +534,14 @@ static int qcom_smsm_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 534 | smsm->num_entries * sizeof(u32)); | 534 | smsm->num_entries * sizeof(u32)); |
| 535 | if (ret < 0 && ret != -EEXIST) { | 535 | if (ret < 0 && ret != -EEXIST) { |
| 536 | dev_err(&pdev->dev, "unable to allocate shared state entry\n"); | 536 | dev_err(&pdev->dev, "unable to allocate shared state entry\n"); |
| 537 | return ret; | 537 | goto out_put; |
| 538 | } | 538 | } |
| 539 | 539 | ||
| 540 | states = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL); | 540 | states = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL); |
| 541 | if (IS_ERR(states)) { | 541 | if (IS_ERR(states)) { |
| 542 | dev_err(&pdev->dev, "Unable to acquire shared state entry\n"); | 542 | dev_err(&pdev->dev, "Unable to acquire shared state entry\n"); |
| 543 | return PTR_ERR(states); | 543 | ret = PTR_ERR(states); |
| 544 | goto out_put; | ||
| 544 | } | 545 | } |
| 545 | 546 | ||
| 546 | /* Acquire the list of interrupt mask vectors */ | 547 | /* Acquire the list of interrupt mask vectors */ |
| @@ -548,13 +549,14 @@ static int qcom_smsm_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 548 | ret = qcom_smem_alloc(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, size); | 549 | ret = qcom_smem_alloc(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, size); |
| 549 | if (ret < 0 && ret != -EEXIST) { | 550 | if (ret < 0 && ret != -EEXIST) { |
| 550 | dev_err(&pdev->dev, "unable to allocate smsm interrupt mask\n"); | 551 | dev_err(&pdev->dev, "unable to allocate smsm interrupt mask\n"); |
| 551 | return ret; | 552 | goto out_put; |
| 552 | } | 553 | } |
| 553 | 554 | ||
| 554 | intr_mask = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL); | 555 | intr_mask = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL); |
| 555 | if (IS_ERR(intr_mask)) { | 556 | if (IS_ERR(intr_mask)) { |
| 556 | dev_err(&pdev->dev, "unable to acquire shared memory interrupt mask\n"); | 557 | dev_err(&pdev->dev, "unable to acquire shared memory interrupt mask\n"); |
| 557 | return PTR_ERR(intr_mask); | 558 | ret = PTR_ERR(intr_mask); |
| 559 | goto out_put; | ||
| 558 | } | 560 | } |
| 559 | 561 | ||
| 560 | /* Setup the reference to the local state bits */ | 562 | /* Setup the reference to the local state bits */ |
| @@ -565,7 +567,8 @@ static int qcom_smsm_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 565 | smsm->state = qcom_smem_state_register(local_node, &smsm_state_ops, smsm); | 567 | smsm->state = qcom_smem_state_register(local_node, &smsm_state_ops, smsm); |
| 566 | if (IS_ERR(smsm->state)) { | 568 | if (IS_ERR(smsm->state)) { |
| 567 | dev_err(smsm->dev, "failed to register qcom_smem_state\n"); | 569 | dev_err(smsm->dev, "failed to register qcom_smem_state\n"); |
| 568 | return PTR_ERR(smsm->state); | 570 | ret = PTR_ERR(smsm->state); |
| 571 | goto out_put; | ||
| 569 | } | 572 | } |
| 570 | 573 | ||
| 571 | /* Register handlers for remote processor entries of interest. */ | 574 | /* Register handlers for remote processor entries of interest. */ |
| @@ -595,16 +598,19 @@ static int qcom_smsm_probe(struct platform_device *pdev) · 23 unmodified lines | |||
| 595 | } | 598 | } |
| 596 | 599 | ||
| 597 | platform_set_drvdata(pdev, smsm); | 600 | platform_set_drvdata(pdev, smsm); |
| 601 | of_node_put(local_node); | ||
| 598 | 602 | ||
| 599 | return 0; | 603 | return 0; |
| 600 | 604 | ||
| 601 | unwind_interfaces: | 605 | unwind_interfaces: |
| 606 | of_node_put(node); | ||
| 602 | for (id = 0; id < smsm->num_entries; id++) | 607 | for (id = 0; id < smsm->num_entries; id++) |
| 603 | if (smsm->entries[id].domain) | 608 | if (smsm->entries[id].domain) |
| 604 | irq_domain_remove(smsm->entries[id].domain); | 609 | irq_domain_remove(smsm->entries[id].domain); |
| 605 | 610 | ||
| 606 | qcom_smem_state_unregister(smsm->state); | 611 | qcom_smem_state_unregister(smsm->state); |
| 607 | 612 | out_put: | |
| 613 | of_node_put(local_node); | ||
| 608 | return ret; | 614 | return ret; |
| 609 | } | 615 | } |
| 610 | 616 | ||
| @@ -104,6 +104,7 @@ static const char *const pmic_models[] = { · 103 unmodified lines | |||
| 104 | [36] = "PM8009", | 104 | [36] = "PM8009", |
| 105 | [38] = "PM8150C", | 105 | [38] = "PM8150C", |
| 106 | [41] = "SMB2351", | 106 | [41] = "SMB2351", |
| 107 | [45] = "PM6125", | ||
| 107 | [47] = "PMK8350", | 108 | [47] = "PMK8350", |
| 108 | [48] = "PM8350", | 109 | [48] = "PM8350", |
| 109 | [49] = "PM8350C", | 110 | [49] = "PM8350C", |
| @@ -334,6 +335,7 @@ static const struct soc_id soc_id[] = { · 224 unmodified lines | |||
| 334 | { 482, "SM8450" }, | 335 | { 482, "SM8450" }, |
| 335 | { 487, "SC7280" }, | 336 | { 487, "SC7280" }, |
| 336 | { 495, "SC7180P" }, | 337 | { 495, "SC7180P" }, |
| 338 | { 507, "SM6375" }, | ||
| 337 | }; | 339 | }; |
| 338 | 340 | ||
| 339 | static const char *socinfo_machine(struct device *dev, unsigned int id) | 341 | static const char *socinfo_machine(struct device *dev, unsigned int id) |
| @@ -44,6 +44,7 @@ config ARCH_RZG2L · 43 unmodified lines | |||
| 44 | bool | 44 | bool |
| 45 | select PM | 45 | select PM |
| 46 | select PM_GENERIC_DOMAINS | 46 | select PM_GENERIC_DOMAINS |
| 47 | select RENESAS_RZG2L_IRQC | ||
| 47 | 48 | ||
| 48 | config ARCH_RZN1 | 49 | config ARCH_RZN1 |
| 49 | bool | 50 | bool |
| @@ -332,6 +333,16 @@ config ARCH_R9A09G011 · 282 unmodified lines | |||
| 332 | 333 | ||
| 333 | endif # ARM64 | 334 | endif # ARM64 |
| 334 | 335 | ||
| 336 | if RISCV | ||
| 337 | |||
| 338 | config ARCH_R9A07G043 | ||
| 339 | bool "RISC-V Platform support for RZ/Five" | ||
| 340 | select ARCH_RZG2L | ||
| 341 | help | ||
| 342 | This enables support for the Renesas RZ/Five SoC. | ||
| 343 | |||
| 344 | endif # RISCV | ||
| 345 | |||
| 335 | config RST_RCAR | 346 | config RST_RCAR |
| 336 | bool "Reset Controller support for R-Car" if COMPILE_TEST | 347 | bool "Reset Controller support for R-Car" if COMPILE_TEST |
| 337 | 348 | ||
| @@ -50,6 +50,10 @@ static const struct renesas_family fam_rza2 __initconst __maybe_unused = { · 49 unmodified lines | |||
| 50 | .name = "RZ/A2", | 50 | .name = "RZ/A2", |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | static const struct renesas_family fam_rzfive __initconst __maybe_unused = { | ||
| 54 | .name = "RZ/Five", | ||
| 55 | }; | ||
| 56 | |||
| 53 | static const struct renesas_family fam_rzg1 __initconst __maybe_unused = { | 57 | static const struct renesas_family fam_rzg1 __initconst __maybe_unused = { |
| 54 | .name = "RZ/G1", | 58 | .name = "RZ/G1", |
| 55 | .reg = 0xff000044, /* PRR (Product Register) */ | 59 | .reg = 0xff000044, /* PRR (Product Register) */ |
| @@ -102,6 +106,11 @@ static const struct renesas_soc soc_rmobile_a1 __initconst __maybe_unused = { · 46 unmodified lines | |||
| 102 | .id = 0x40, | 106 | .id = 0x40, |
| 103 | }; | 107 | }; |
| 104 | 108 | ||
| 109 | static const struct renesas_soc soc_rz_five __initconst __maybe_unused = { | ||
| 110 | .family = &fam_rzfive, | ||
| 111 | .id = 0x847c447, | ||
| 112 | }; | ||
| 113 | |||
| 105 | static const struct renesas_soc soc_rz_g1h __initconst __maybe_unused = { | 114 | static const struct renesas_soc soc_rz_g1h __initconst __maybe_unused = { |
| 106 | .family = &fam_rzg1, | 115 | .family = &fam_rzg1, |
| 107 | .id = 0x45, | 116 | .id = 0x45, |
| @@ -320,6 +329,7 @@ static const struct of_device_id renesas_socs[] __initconst = { · 212 unmodified lines | |||
| 320 | { .compatible = "renesas,r8a779m0", .data = &soc_rcar_h3 }, | 329 | { .compatible = "renesas,r8a779m0", .data = &soc_rcar_h3 }, |
| 321 | { .compatible = "renesas,r8a779m1", .data = &soc_rcar_h3 }, | 330 | { .compatible = "renesas,r8a779m1", .data = &soc_rcar_h3 }, |
| 322 | { .compatible = "renesas,r8a779m8", .data = &soc_rcar_h3 }, | 331 | { .compatible = "renesas,r8a779m8", .data = &soc_rcar_h3 }, |
| 332 | { .compatible = "renesas,r8a779mb", .data = &soc_rcar_h3 }, | ||
| 323 | #endif | 333 | #endif |
| 324 | #ifdef CONFIG_ARCH_R8A77960 | 334 | #ifdef CONFIG_ARCH_R8A77960 |
| 325 | { .compatible = "renesas,r8a7796", .data = &soc_rcar_m3_w }, | 335 | { .compatible = "renesas,r8a7796", .data = &soc_rcar_m3_w }, |
| @@ -358,8 +368,12 @@ static const struct of_device_id renesas_socs[] __initconst = { · 32 unmodified lines | |||
| 358 | { .compatible = "renesas,r8a779g0", .data = &soc_rcar_v4h }, | 368 | { .compatible = "renesas,r8a779g0", .data = &soc_rcar_v4h }, |
| 359 | #endif | 369 | #endif |
| 360 | #if defined(CONFIG_ARCH_R9A07G043) | 370 | #if defined(CONFIG_ARCH_R9A07G043) |
| 371 | #ifdef CONFIG_RISCV | ||
| 372 | { .compatible = "renesas,r9a07g043", .data = &soc_rz_five }, | ||
| 373 | #else | ||
| 361 | { .compatible = "renesas,r9a07g043", .data = &soc_rz_g2ul }, | 374 | { .compatible = "renesas,r9a07g043", .data = &soc_rz_g2ul }, |
| 362 | #endif | 375 | #endif |
| 376 | #endif | ||
| 363 | #if defined(CONFIG_ARCH_R9A07G044) | 377 | #if defined(CONFIG_ARCH_R9A07G044) |
| 364 | { .compatible = "renesas,r9a07g044", .data = &soc_rz_g2l }, | 378 | { .compatible = "renesas,r9a07g044", .data = &soc_rz_g2l }, |
| 365 | #endif | 379 | #endif |
| @@ -491,6 +491,22 @@ static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = { · 490 unmodified lines | |||
| 491 | }, | 491 | }, |
| 492 | }; | 492 | }; |
| 493 | 493 | ||
| 494 | static const struct rockchip_iodomain_soc_data soc_data_rv1126_pmu = { | ||
| 495 | .grf_offset = 0x140, | ||
| 496 | .supply_names = { | ||
| 497 | NULL, | ||
| 498 | "vccio1", | ||
| 499 | "vccio2", | ||
| 500 | "vccio3", | ||
| 501 | "vccio4", | ||
| 502 | "vccio5", | ||
| 503 | "vccio6", | ||
| 504 | "vccio7", | ||
| 505 | "pmuio0", | ||
| 506 | "pmuio1", | ||
| 507 | }, | ||
| 508 | }; | ||
| 509 | |||
| 494 | static const struct of_device_id rockchip_iodomain_match[] = { | 510 | static const struct of_device_id rockchip_iodomain_match[] = { |
| 495 | { | 511 | { |
| 496 | .compatible = "rockchip,px30-io-voltage-domain", | 512 | .compatible = "rockchip,px30-io-voltage-domain", |
| @@ -544,6 +560,10 @@ static const struct of_device_id rockchip_iodomain_match[] = { · 47 unmodified lines | |||
| 544 | .compatible = "rockchip,rv1108-pmu-io-voltage-domain", | 560 | .compatible = "rockchip,rv1108-pmu-io-voltage-domain", |
| 545 | .data = &soc_data_rv1108_pmu | 561 | .data = &soc_data_rv1108_pmu |
| 546 | }, | 562 | }, |
| 563 | { | ||
| 564 | .compatible = "rockchip,rv1126-pmu-io-voltage-domain", | ||
| 565 | .data = &soc_data_rv1126_pmu | ||
| 566 | }, | ||
| 547 | { /* sentinel */ }, | 567 | { /* sentinel */ }, |
| 548 | }; | 568 | }; |
| 549 | MODULE_DEVICE_TABLE(of, rockchip_iodomain_match); | 569 | MODULE_DEVICE_TABLE(of, rockchip_iodomain_match); |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/mfd/syscon.h> | 19 | #include <linux/mfd/syscon.h> |
| 20 | #include <soc/rockchip/pm_domains.h> | 20 | #include <soc/rockchip/pm_domains.h> |
| 21 | #include <dt-bindings/power/px30-power.h> | 21 | #include <dt-bindings/power/px30-power.h> |
| 22 | #include <dt-bindings/power/rockchip,rv1126-power.h> | ||
| 22 | #include <dt-bindings/power/rk3036-power.h> | 23 | #include <dt-bindings/power/rk3036-power.h> |
| 23 | #include <dt-bindings/power/rk3066-power.h> | 24 | #include <dt-bindings/power/rk3066-power.h> |
| 24 | #include <dt-bindings/power/rk3128-power.h> | 25 | #include <dt-bindings/power/rk3128-power.h> |
| @@ -30,6 +31,7 @@ · 5 unmodified lines | |||
| 30 | #include <dt-bindings/power/rk3368-power.h> | 31 | #include <dt-bindings/power/rk3368-power.h> |
| 31 | #include <dt-bindings/power/rk3399-power.h> | 32 | #include <dt-bindings/power/rk3399-power.h> |
| 32 | #include <dt-bindings/power/rk3568-power.h> | 33 | #include <dt-bindings/power/rk3568-power.h> |
| 34 | #include <dt-bindings/power/rk3588-power.h> | ||
| 33 | 35 | ||
| 34 | struct rockchip_domain_info { | 36 | struct rockchip_domain_info { |
| 35 | const char *name; | 37 | const char *name; |
| @@ -41,6 +43,9 @@ struct rockchip_domain_info { · 5 unmodified lines | |||
| 41 | bool active_wakeup; | 43 | bool active_wakeup; |
| 42 | int pwr_w_mask; | 44 | int pwr_w_mask; |
| 43 | int req_w_mask; | 45 | int req_w_mask; |
| 46 | int repair_status_mask; | ||
| 47 | u32 pwr_offset; | ||
| 48 | u32 req_offset; | ||
| 44 | }; | 49 | }; |
| 45 | 50 | ||
| 46 | struct rockchip_pmu_info { | 51 | struct rockchip_pmu_info { |
| @@ -49,6 +54,7 @@ struct rockchip_pmu_info { · 2 unmodified lines | |||
| 49 | u32 req_offset; | 54 | u32 req_offset; |
| 50 | u32 idle_offset; | 55 | u32 idle_offset; |
| 51 | u32 ack_offset; | 56 | u32 ack_offset; |
| 57 | u32 repair_status_offset; | ||
| 52 | 58 | ||
| 53 | u32 core_pwrcnt_offset; | 59 | u32 core_pwrcnt_offset; |
| 54 | u32 gpu_pwrcnt_offset; | 60 | u32 gpu_pwrcnt_offset; |
| @@ -113,6 +119,22 @@ struct rockchip_pmu { · 58 unmodified lines | |||
| 113 | .active_wakeup = wakeup, \ | 119 | .active_wakeup = wakeup, \ |
| 114 | } | 120 | } |
| 115 | 121 | ||
| 122 | #define DOMAIN_M_O_R(_name, p_offset, pwr, status, r_status, r_offset, req, idle, ack, wakeup) \ | ||
| 123 | { \ | ||
| 124 | .name = _name, \ | ||
| 125 | .pwr_offset = p_offset, \ | ||
| 126 | .pwr_w_mask = (pwr) << 16, \ | ||
| 127 | .pwr_mask = (pwr), \ | ||
| 128 | .status_mask = (status), \ | ||
| 129 | .repair_status_mask = (r_status), \ | ||
| 130 | .req_offset = r_offset, \ | ||
| 131 | .req_w_mask = (req) << 16, \ | ||
| 132 | .req_mask = (req), \ | ||
| 133 | .idle_mask = (idle), \ | ||
| 134 | .ack_mask = (ack), \ | ||
| 135 | .active_wakeup = wakeup, \ | ||
| 136 | } | ||
| 137 | |||
| 116 | #define DOMAIN_RK3036(_name, req, ack, idle, wakeup) \ | 138 | #define DOMAIN_RK3036(_name, req, ack, idle, wakeup) \ |
| 117 | { \ | 139 | { \ |
| 118 | .name = _name, \ | 140 | .name = _name, \ |
| @@ -126,6 +148,9 @@ struct rockchip_pmu { · 7 unmodified lines | |||
| 126 | #define DOMAIN_PX30(name, pwr, status, req, wakeup) \ | 148 | #define DOMAIN_PX30(name, pwr, status, req, wakeup) \ |
| 127 | DOMAIN_M(name, pwr, status, req, (req) << 16, req, wakeup) | 149 | DOMAIN_M(name, pwr, status, req, (req) << 16, req, wakeup) |
| 128 | 150 | ||
| 151 | #define DOMAIN_RV1126(name, pwr, req, idle, wakeup) \ | ||
| 152 | DOMAIN_M(name, pwr, pwr, req, idle, idle, wakeup) | ||
| 153 | |||
| 129 | #define DOMAIN_RK3288(name, pwr, status, req, wakeup) \ | 154 | #define DOMAIN_RK3288(name, pwr, status, req, wakeup) \ |
| 130 | DOMAIN(name, pwr, status, req, req, (req) << 16, wakeup) | 155 | DOMAIN(name, pwr, status, req, req, (req) << 16, wakeup) |
| 131 | 156 | ||
| @@ -244,6 +269,9 @@ void rockchip_pmu_unblock(void) · 112 unmodified lines | |||
| 244 | } | 269 | } |
| 245 | EXPORT_SYMBOL_GPL(rockchip_pmu_unblock); | 270 | EXPORT_SYMBOL_GPL(rockchip_pmu_unblock); |
| 246 | 271 | ||
| 272 | #define DOMAIN_RK3588(name, p_offset, pwr, status, r_status, r_offset, req, idle, wakeup) \ | ||
| 273 | DOMAIN_M_O_R(name, p_offset, pwr, status, r_status, r_offset, req, idle, idle, wakeup) | ||
| 274 | |||
| 247 | static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd) | 275 | static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd) |
| 248 | { | 276 | { |
| 249 | struct rockchip_pmu *pmu = pd->pmu; | 277 | struct rockchip_pmu *pmu = pd->pmu; |
| @@ -268,6 +296,7 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd, · 18 unmodified lines | |||
| 268 | const struct rockchip_domain_info *pd_info = pd->info; | 296 | const struct rockchip_domain_info *pd_info = pd->info; |
| 269 | struct generic_pm_domain *genpd = &pd->genpd; | 297 | struct generic_pm_domain *genpd = &pd->genpd; |
| 270 | struct rockchip_pmu *pmu = pd->pmu; | 298 | struct rockchip_pmu *pmu = pd->pmu; |
| 299 | u32 pd_req_offset = pd_info->req_offset; | ||
| 271 | unsigned int target_ack; | 300 | unsigned int target_ack; |
| 272 | unsigned int val; | 301 | unsigned int val; |
| 273 | bool is_idle; | 302 | bool is_idle; |
| @@ -276,11 +305,11 @@ static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd, · 2 unmodified lines | |||
| 276 | if (pd_info->req_mask == 0) | 305 | if (pd_info->req_mask == 0) |
| 277 | return 0; | 306 | return 0; |
| 278 | else if (pd_info->req_w_mask) | 307 | else if (pd_info->req_w_mask) |
| 279 | regmap_write(pmu->regmap, pmu->info->req_offset, | 308 | regmap_write(pmu->regmap, pmu->info->req_offset + pd_req_offset, |
| 280 | idle ? (pd_info->req_mask | pd_info->req_w_mask) : | 309 | idle ? (pd_info->req_mask | pd_info->req_w_mask) : |
| 281 | pd_info->req_w_mask); | 310 | pd_info->req_w_mask); |
| 282 | else | 311 | else |
| 283 | regmap_update_bits(pmu->regmap, pmu->info->req_offset, | 312 | regmap_update_bits(pmu->regmap, pmu->info->req_offset + pd_req_offset, |
| 284 | pd_info->req_mask, idle ? -1U : 0); | 313 | pd_info->req_mask, idle ? -1U : 0); |
| 285 | 314 | ||
| 286 | wmb(); | 315 | wmb(); |
| @@ -363,6 +392,12 @@ static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd) · 76 unmodified lines | |||
| 363 | struct rockchip_pmu *pmu = pd->pmu; | 392 | struct rockchip_pmu *pmu = pd->pmu; |
| 364 | unsigned int val; | 393 | unsigned int val; |
| 365 | 394 | ||
| 395 | if (pd->info->repair_status_mask) { | ||
| 396 | regmap_read(pmu->regmap, pmu->info->repair_status_offset, &val); | ||
| 397 | /* 1'b1: power on, 1'b0: power off */ | ||
| 398 | return val & pd->info->repair_status_mask; | ||
| 399 | } | ||
| 400 | |||
| 366 | /* check idle status for idle-only domains */ | 401 | /* check idle status for idle-only domains */ |
| 367 | if (pd->info->status_mask == 0) | 402 | if (pd->info->status_mask == 0) |
| 368 | return !rockchip_pmu_domain_is_idle(pd); | 403 | return !rockchip_pmu_domain_is_idle(pd); |
| @@ -378,16 +413,17 @@ static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, · 9 unmodified lines | |||
| 378 | { | 413 | { |
| 379 | struct rockchip_pmu *pmu = pd->pmu; | 414 | struct rockchip_pmu *pmu = pd->pmu; |
| 380 | struct generic_pm_domain *genpd = &pd->genpd; | 415 | struct generic_pm_domain *genpd = &pd->genpd; |
| 416 | u32 pd_pwr_offset = pd->info->pwr_offset; | ||
| 381 | bool is_on; | 417 | bool is_on; |
| 382 | 418 | ||
| 383 | if (pd->info->pwr_mask == 0) | 419 | if (pd->info->pwr_mask == 0) |
| 384 | return; | 420 | return; |
| 385 | else if (pd->info->pwr_w_mask) | 421 | else if (pd->info->pwr_w_mask) |
| 386 | regmap_write(pmu->regmap, pmu->info->pwr_offset, | 422 | regmap_write(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset, |
| 387 | on ? pd->info->pwr_w_mask : | 423 | on ? pd->info->pwr_w_mask : |
| 388 | (pd->info->pwr_mask | pd->info->pwr_w_mask)); | 424 | (pd->info->pwr_mask | pd->info->pwr_w_mask)); |
| 389 | else | 425 | else |
| 390 | regmap_update_bits(pmu->regmap, pmu->info->pwr_offset, | 426 | regmap_update_bits(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset, |
| 391 | pd->info->pwr_mask, on ? 0 : -1U); | 427 | pd->info->pwr_mask, on ? 0 : -1U); |
| 392 | 428 | ||
| 393 | wmb(); | 429 | wmb(); |
| @@ -514,6 +550,9 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, · 120 unmodified lines | |||
| 514 | node, id); | 550 | node, id); |
| 515 | return -EINVAL; | 551 | return -EINVAL; |
| 516 | } | 552 | } |
| 553 | /* RK3588 has domains with two parents (RKVDEC0/RKVDEC1) */ | ||
| 554 | if (pmu->genpd_data.domains[id]) | ||
| 555 | return 0; | ||
| 517 | 556 | ||
| 518 | pd_info = &pmu->info->domain_info[id]; | 557 | pd_info = &pmu->info->domain_info[id]; |
| 519 | if (!pd_info) { | 558 | if (!pd_info) { |
| @@ -595,14 +634,6 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, · 75 unmodified lines | |||
| 595 | } | 634 | } |
| 596 | } | 635 | } |
| 597 | 636 | ||
| 598 | error = rockchip_pd_power(pd, true); | ||
| 599 | if (error) { | ||
| 600 | dev_err(pmu->dev, | ||
| 601 | "failed to power on domain '%pOFn': %d\n", | ||
| 602 | node, error); | ||
| 603 | goto err_unprepare_clocks; | ||
| 604 | } | ||
| 605 | |||
| 606 | if (pd->info->name) | 637 | if (pd->info->name) |
| 607 | pd->genpd.name = pd->info->name; | 638 | pd->genpd.name = pd->info->name; |
| 608 | else | 639 | else |
| @@ -614,7 +645,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, · 5 unmodified lines | |||
| 614 | pd->genpd.flags = GENPD_FLAG_PM_CLK; | 645 | pd->genpd.flags = GENPD_FLAG_PM_CLK; |
| 615 | if (pd_info->active_wakeup) | 646 | if (pd_info->active_wakeup) |
| 616 | pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP; | 647 | pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP; |
| 617 | pm_genpd_init(&pd->genpd, NULL, false); | 648 | pm_genpd_init(&pd->genpd, NULL, !rockchip_pmu_domain_is_on(pd)); |
| 618 | 649 | ||
| 619 | pmu->genpd_data.domains[id] = &pd->genpd; | 650 | pmu->genpd_data.domains[id] = &pd->genpd; |
| 620 | return 0; | 651 | return 0; |
| @@ -855,6 +886,16 @@ static const struct rockchip_domain_info px30_pm_domains[] = { · 234 unmodified lines | |||
| 855 | [PX30_PD_GPU] = DOMAIN_PX30("gpu", BIT(15), BIT(15), BIT(2), false), | 886 | [PX30_PD_GPU] = DOMAIN_PX30("gpu", BIT(15), BIT(15), BIT(2), false), |
| 856 | }; | 887 | }; |
| 857 | 888 | ||
| 889 | static const struct rockchip_domain_info rv1126_pm_domains[] = { | ||
| 890 | [RV1126_PD_VEPU] = DOMAIN_RV1126("vepu", BIT(2), BIT(9), BIT(9), false), | ||
| 891 | [RV1126_PD_VI] = DOMAIN_RV1126("vi", BIT(4), BIT(6), BIT(6), false), | ||
| 892 | [RV1126_PD_ISPP] = DOMAIN_RV1126("ispp", BIT(1), BIT(8), BIT(8), false), | ||
| 893 | [RV1126_PD_VDPU] = DOMAIN_RV1126("vdpu", BIT(3), BIT(10), BIT(10), false), | ||
| 894 | [RV1126_PD_NVM] = DOMAIN_RV1126("nvm", BIT(7), BIT(11), BIT(11), false), | ||
| 895 | [RV1126_PD_SDIO] = DOMAIN_RV1126("sdio", BIT(8), BIT(13), BIT(13), false), | ||
| 896 | [RV1126_PD_USB] = DOMAIN_RV1126("usb", BIT(9), BIT(15), BIT(15), false), | ||
| 897 | }; | ||
| 898 | |||
| 858 | static const struct rockchip_domain_info rk3036_pm_domains[] = { | 899 | static const struct rockchip_domain_info rk3036_pm_domains[] = { |
| 859 | [RK3036_PD_MSCH] = DOMAIN_RK3036("msch", BIT(14), BIT(23), BIT(30), true), | 900 | [RK3036_PD_MSCH] = DOMAIN_RK3036("msch", BIT(14), BIT(23), BIT(30), true), |
| 860 | [RK3036_PD_CORE] = DOMAIN_RK3036("core", BIT(13), BIT(17), BIT(24), false), | 901 | [RK3036_PD_CORE] = DOMAIN_RK3036("core", BIT(13), BIT(17), BIT(24), false), |
| @@ -982,6 +1023,38 @@ static const struct rockchip_domain_info rk3568_pm_domains[] = { · 121 unmodified lines | |||
| 982 | [RK3568_PD_PIPE] = DOMAIN_RK3568("pipe", BIT(8), BIT(11), false), | 1023 | [RK3568_PD_PIPE] = DOMAIN_RK3568("pipe", BIT(8), BIT(11), false), |
| 983 | }; | 1024 | }; |
| 984 | 1025 | ||
| 1026 | static const struct rockchip_domain_info rk3588_pm_domains[] = { | ||
| 1027 | [RK3588_PD_GPU] = DOMAIN_RK3588("gpu", 0x0, BIT(0), 0, BIT(1), 0x0, BIT(0), BIT(0), false), | ||
| 1028 | [RK3588_PD_NPU] = DOMAIN_RK3588("npu", 0x0, BIT(1), BIT(1), 0, 0x0, 0, 0, false), | ||
| 1029 | [RK3588_PD_VCODEC] = DOMAIN_RK3588("vcodec", 0x0, BIT(2), BIT(2), 0, 0x0, 0, 0, false), | ||
| 1030 | [RK3588_PD_NPUTOP] = DOMAIN_RK3588("nputop", 0x0, BIT(3), 0, BIT(2), 0x0, BIT(1), BIT(1), false), | ||
| 1031 | [RK3588_PD_NPU1] = DOMAIN_RK3588("npu1", 0x0, BIT(4), 0, BIT(3), 0x0, BIT(2), BIT(2), false), | ||
| 1032 | [RK3588_PD_NPU2] = DOMAIN_RK3588("npu2", 0x0, BIT(5), 0, BIT(4), 0x0, BIT(3), BIT(3), false), | ||
| 1033 | [RK3588_PD_VENC0] = DOMAIN_RK3588("venc0", 0x0, BIT(6), 0, BIT(5), 0x0, BIT(4), BIT(4), false), | ||
| 1034 | [RK3588_PD_VENC1] = DOMAIN_RK3588("venc1", 0x0, BIT(7), 0, BIT(6), 0x0, BIT(5), BIT(5), false), | ||
| 1035 | [RK3588_PD_RKVDEC0] = DOMAIN_RK3588("rkvdec0", 0x0, BIT(8), 0, BIT(7), 0x0, BIT(6), BIT(6), false), | ||
| 1036 | [RK3588_PD_RKVDEC1] = DOMAIN_RK3588("rkvdec1", 0x0, BIT(9), 0, BIT(8), 0x0, BIT(7), BIT(7), false), | ||
| 1037 | [RK3588_PD_VDPU] = DOMAIN_RK3588("vdpu", 0x0, BIT(10), 0, BIT(9), 0x0, BIT(8), BIT(8), false), | ||
| 1038 | [RK3588_PD_RGA30] = DOMAIN_RK3588("rga30", 0x0, BIT(11), 0, BIT(10), 0x0, 0, 0, false), | ||
| 1039 | [RK3588_PD_AV1] = DOMAIN_RK3588("av1", 0x0, BIT(12), 0, BIT(11), 0x0, BIT(9), BIT(9), false), | ||
| 1040 | [RK3588_PD_VI] = DOMAIN_RK3588("vi", 0x0, BIT(13), 0, BIT(12), 0x0, BIT(10), BIT(10), false), | ||
| 1041 | [RK3588_PD_FEC] = DOMAIN_RK3588("fec", 0x0, BIT(14), 0, BIT(13), 0x0, 0, 0, false), | ||
| 1042 | [RK3588_PD_ISP1] = DOMAIN_RK3588("isp1", 0x0, BIT(15), 0, BIT(14), 0x0, BIT(11), BIT(11), false), | ||
| 1043 | [RK3588_PD_RGA31] = DOMAIN_RK3588("rga31", 0x4, BIT(0), 0, BIT(15), 0x0, BIT(12), BIT(12), false), | ||
| 1044 | [RK3588_PD_VOP] = DOMAIN_RK3588("vop", 0x4, BIT(1), 0, BIT(16), 0x0, BIT(13) | BIT(14), BIT(13) | BIT(14), false), | ||
| 1045 | [RK3588_PD_VO0] = DOMAIN_RK3588("vo0", 0x4, BIT(2), 0, BIT(17), 0x0, BIT(15), BIT(15), false), | ||
| 1046 | [RK3588_PD_VO1] = DOMAIN_RK3588("vo1", 0x4, BIT(3), 0, BIT(18), 0x4, BIT(0), BIT(16), false), | ||
| 1047 | [RK3588_PD_AUDIO] = DOMAIN_RK3588("audio", 0x4, BIT(4), 0, BIT(19), 0x4, BIT(1), BIT(17), false), | ||
| 1048 | [RK3588_PD_PHP] = DOMAIN_RK3588("php", 0x4, BIT(5), 0, BIT(20), 0x4, BIT(5), BIT(21), false), | ||
| 1049 | [RK3588_PD_GMAC] = DOMAIN_RK3588("gmac", 0x4, BIT(6), 0, BIT(21), 0x0, 0, 0, false), | ||
| 1050 | [RK3588_PD_PCIE] = DOMAIN_RK3588("pcie", 0x4, BIT(7), 0, BIT(22), 0x0, 0, 0, true), | ||
| 1051 | [RK3588_PD_NVM] = DOMAIN_RK3588("nvm", 0x4, BIT(8), BIT(24), 0, 0x4, BIT(2), BIT(18), false), | ||
| 1052 | [RK3588_PD_NVM0] = DOMAIN_RK3588("nvm0", 0x4, BIT(9), 0, BIT(23), 0x0, 0, 0, false), | ||
| 1053 | [RK3588_PD_SDIO] = DOMAIN_RK3588("sdio", 0x4, BIT(10), 0, BIT(24), 0x4, BIT(3), BIT(19), false), | ||
| 1054 | [RK3588_PD_USB] = DOMAIN_RK3588("usb", 0x4, BIT(11), 0, BIT(25), 0x4, BIT(4), BIT(20), true), | ||
| 1055 | [RK3588_PD_SDMMC] = DOMAIN_RK3588("sdmmc", 0x4, BIT(13), 0, BIT(26), 0x0, 0, 0, false), | ||
| 1056 | }; | ||
| 1057 | |||
| 985 | static const struct rockchip_pmu_info px30_pmu = { | 1058 | static const struct rockchip_pmu_info px30_pmu = { |
| 986 | .pwr_offset = 0x18, | 1059 | .pwr_offset = 0x18, |
| 987 | .status_offset = 0x20, | 1060 | .status_offset = 0x20, |
| @@ -1128,6 +1201,29 @@ static const struct rockchip_pmu_info rk3568_pmu = { · 140 unmodified lines | |||
| 1128 | .domain_info = rk3568_pm_domains, | 1201 | .domain_info = rk3568_pm_domains, |
| 1129 | }; | 1202 | }; |
| 1130 | 1203 | ||
| 1204 | static const struct rockchip_pmu_info rk3588_pmu = { | ||
| 1205 | .pwr_offset = 0x14c, | ||
| 1206 | .status_offset = 0x180, | ||
| 1207 | .req_offset = 0x10c, | ||
| 1208 | .idle_offset = 0x120, | ||
| 1209 | .ack_offset = 0x118, | ||
| 1210 | .repair_status_offset = 0x290, | ||
| 1211 | |||
| 1212 | .num_domains = ARRAY_SIZE(rk3588_pm_domains), | ||
| 1213 | .domain_info = rk3588_pm_domains, | ||
| 1214 | }; | ||
| 1215 | |||
| 1216 | static const struct rockchip_pmu_info rv1126_pmu = { | ||
| 1217 | .pwr_offset = 0x110, | ||
| 1218 | .status_offset = 0x108, | ||
| 1219 | .req_offset = 0xc0, | ||
| 1220 | .idle_offset = 0xd8, | ||
| 1221 | .ack_offset = 0xd0, | ||
| 1222 | |||
| 1223 | .num_domains = ARRAY_SIZE(rv1126_pm_domains), | ||
| 1224 | .domain_info = rv1126_pm_domains, | ||
| 1225 | }; | ||
| 1226 | |||
| 1131 | static const struct of_device_id rockchip_pm_domain_dt_match[] = { | 1227 | static const struct of_device_id rockchip_pm_domain_dt_match[] = { |
| 1132 | { | 1228 | { |
| 1133 | .compatible = "rockchip,px30-power-controller", | 1229 | .compatible = "rockchip,px30-power-controller", |
| @@ -1177,6 +1273,14 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = { · 43 unmodified lines | |||
| 1177 | .compatible = "rockchip,rk3568-power-controller", | 1273 | .compatible = "rockchip,rk3568-power-controller", |
| 1178 | .data = (void *)&rk3568_pmu, | 1274 | .data = (void *)&rk3568_pmu, |
| 1179 | }, | 1275 | }, |
| 1276 | { | ||
| 1277 | .compatible = "rockchip,rk3588-power-controller", | ||
| 1278 | .data = (void *)&rk3588_pmu, | ||
| 1279 | }, | ||
| 1280 | { | ||
| 1281 | .compatible = "rockchip,rv1126-power-controller", | ||
| 1282 | .data = (void *)&rv1126_pmu, | ||
| 1283 | }, | ||
| 1180 | { /* sentinel */ }, | 1284 | { /* sentinel */ }, |
| 1181 | }; | 1285 | }; |
| 1182 | 1286 | ||
| @@ -261,30 +261,29 @@ int sunxi_sram_claim(struct device *dev) · 260 unmodified lines | |||
| 261 | } | 261 | } |
| 262 | EXPORT_SYMBOL(sunxi_sram_claim); | 262 | EXPORT_SYMBOL(sunxi_sram_claim); |
| 263 | 263 | ||
| 264 | int sunxi_sram_release(struct device *dev) | 264 | void sunxi_sram_release(struct device *dev) |
| 265 | { | 265 | { |
| 266 | const struct sunxi_sram_data *sram_data; | 266 | const struct sunxi_sram_data *sram_data; |
| 267 | struct sunxi_sram_desc *sram_desc; | 267 | struct sunxi_sram_desc *sram_desc; |
| 268 | 268 | ||
| 269 | if (!dev || !dev->of_node) | 269 | if (!dev || !dev->of_node) |
| 270 | return -EINVAL; | 270 | return; |
| 271 | 271 | ||
| 272 | sram_data = sunxi_sram_of_parse(dev->of_node, NULL); | 272 | sram_data = sunxi_sram_of_parse(dev->of_node, NULL); |
| 273 | if (IS_ERR(sram_data)) | 273 | if (IS_ERR(sram_data)) |
| 274 | return -EINVAL; | 274 | return; |
| 275 | 275 | ||
| 276 | sram_desc = to_sram_desc(sram_data); | 276 | sram_desc = to_sram_desc(sram_data); |
| 277 | 277 | ||
| 278 | spin_lock(&sram_lock); | 278 | spin_lock(&sram_lock); |
| 279 | sram_desc->claimed = false; | 279 | sram_desc->claimed = false; |
| 280 | spin_unlock(&sram_lock); | 280 | spin_unlock(&sram_lock); |
| 281 | |||
| 282 | return 0; | ||
| 283 | } | 281 | } |
| 284 | EXPORT_SYMBOL(sunxi_sram_release); | 282 | EXPORT_SYMBOL(sunxi_sram_release); |
| 285 | 283 | ||
| 286 | struct sunxi_sramc_variant { | 284 | struct sunxi_sramc_variant { |
| 287 | int num_emac_clocks; | 285 | int num_emac_clocks; |
| 286 | bool has_ldo_ctrl; | ||
| 288 | }; | 287 | }; |
| 289 | 288 | ||
| 290 | static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = { | 289 | static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = { |
| @@ -295,6 +294,11 @@ static const struct sunxi_sramc_variant sun8i_h3_sramc_variant = { · 4 unmodified lines | |||
| 295 | .num_emac_clocks = 1, | 294 | .num_emac_clocks = 1, |
| 296 | }; | 295 | }; |
| 297 | 296 | ||
| 297 | static const struct sunxi_sramc_variant sun20i_d1_sramc_variant = { | ||
| 298 | .num_emac_clocks = 1, | ||
| 299 | .has_ldo_ctrl = true, | ||
| 300 | }; | ||
| 301 | |||
| 298 | static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = { | 302 | static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = { |
| 299 | .num_emac_clocks = 1, | 303 | .num_emac_clocks = 1, |
| 300 | }; | 304 | }; |
| @@ -304,27 +308,28 @@ static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = { · 3 unmodified lines | |||
| 304 | }; | 308 | }; |
| 305 | 309 | ||
| 306 | #define SUNXI_SRAM_EMAC_CLOCK_REG 0x30 | 310 | #define SUNXI_SRAM_EMAC_CLOCK_REG 0x30 |
| 311 | #define SUNXI_SYS_LDO_CTRL_REG 0x150 | ||
| 312 | |||
| 307 | static bool sunxi_sram_regmap_accessible_reg(struct device *dev, | 313 | static bool sunxi_sram_regmap_accessible_reg(struct device *dev, |
| 308 | unsigned int reg) | 314 | unsigned int reg) |
| 309 | { | 315 | { |
| 310 | const struct sunxi_sramc_variant *variant; | 316 | const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev); |
| 311 | 317 | ||
| 312 | variant = of_device_get_match_data(dev); | 318 | if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG && |
| 319 | reg < SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4) | ||
| 320 | return true; | ||
| 321 | if (reg == SUNXI_SYS_LDO_CTRL_REG && variant->has_ldo_ctrl) | ||
| 322 | return true; | ||
| 313 | 323 | ||
| 314 | if (reg < SUNXI_SRAM_EMAC_CLOCK_REG) | 324 | return false; |
| 315 | return false; | ||
| 316 | if (reg > SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4) | ||
| 317 | return false; | ||
| 318 | |||
| 319 | return true; | ||
| 320 | } | 325 | } |
| 321 | 326 | ||
| 322 | static struct regmap_config sunxi_sram_emac_clock_regmap = { | 327 | static struct regmap_config sunxi_sram_regmap_config = { |
| 323 | .reg_bits = 32, | 328 | .reg_bits = 32, |
| 324 | .val_bits = 32, | 329 | .val_bits = 32, |
| 325 | .reg_stride = 4, | 330 | .reg_stride = 4, |
| 326 | /* last defined register */ | 331 | /* last defined register */ |
| 327 | .max_register = SUNXI_SRAM_EMAC_CLOCK_REG + 4, | 332 | .max_register = SUNXI_SYS_LDO_CTRL_REG, |
| 328 | /* other devices have no business accessing other registers */ | 333 | /* other devices have no business accessing other registers */ |
| 329 | .readable_reg = sunxi_sram_regmap_accessible_reg, | 334 | .readable_reg = sunxi_sram_regmap_accessible_reg, |
| 330 | .writeable_reg = sunxi_sram_regmap_accessible_reg, | 335 | .writeable_reg = sunxi_sram_regmap_accessible_reg, |
| @@ -332,9 +337,9 @@ static struct regmap_config sunxi_sram_emac_clock_regmap = { · 1 unmodified line | |||
| 332 | 337 | ||
| 333 | static int __init sunxi_sram_probe(struct platform_device *pdev) | 338 | static int __init sunxi_sram_probe(struct platform_device *pdev) |
| 334 | { | 339 | { |
| 335 | struct regmap *emac_clock; | ||
| 336 | const struct sunxi_sramc_variant *variant; | 340 | const struct sunxi_sramc_variant *variant; |
| 337 | struct device *dev = &pdev->dev; | 341 | struct device *dev = &pdev->dev; |
| 342 | struct regmap *regmap; | ||
| 338 | 343 | ||
| 339 | sram_dev = &pdev->dev; | 344 | sram_dev = &pdev->dev; |
| 340 | 345 | ||
| @@ -342,16 +347,16 @@ static int __init sunxi_sram_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 342 | if (!variant) | 347 | if (!variant) |
| 343 | return -EINVAL; | 348 | return -EINVAL; |
| 344 | 349 | ||
| 350 | dev_set_drvdata(dev, (struct sunxi_sramc_variant *)variant); | ||
| 351 | |||
| 345 | base = devm_platform_ioremap_resource(pdev, 0); | 352 | base = devm_platform_ioremap_resource(pdev, 0); |
| 346 | if (IS_ERR(base)) | 353 | if (IS_ERR(base)) |
| 347 | return PTR_ERR(base); | 354 | return PTR_ERR(base); |
| 348 | 355 | ||
| 349 | if (variant->num_emac_clocks > 0) { | 356 | if (variant->num_emac_clocks || variant->has_ldo_ctrl) { |
| 350 | emac_clock = devm_regmap_init_mmio(&pdev->dev, base, | 357 | regmap = devm_regmap_init_mmio(dev, base, &sunxi_sram_regmap_config); |
| 351 | &sunxi_sram_emac_clock_regmap); | 358 | if (IS_ERR(regmap)) |
| 352 | 359 | return PTR_ERR(regmap); | |
| 353 | if (IS_ERR(emac_clock)) | ||
| 354 | return PTR_ERR(emac_clock); | ||
| 355 | } | 360 | } |
| 356 | 361 | ||
| 357 | of_platform_populate(dev->of_node, NULL, NULL, dev); | 362 | of_platform_populate(dev->of_node, NULL, NULL, dev); |
| @@ -382,6 +387,10 @@ static const struct of_device_id sunxi_sram_dt_match[] = { · 24 unmodified lines | |||
| 382 | .compatible = "allwinner,sun8i-h3-system-control", | 387 | .compatible = "allwinner,sun8i-h3-system-control", |
| 383 | .data = &sun8i_h3_sramc_variant, | 388 | .data = &sun8i_h3_sramc_variant, |
| 384 | }, | 389 | }, |
| 390 | { | ||
| 391 | .compatible = "allwinner,sun20i-d1-system-control", | ||
| 392 | .data = &sun20i_d1_sramc_variant, | ||
| 393 | }, | ||
| 385 | { | 394 | { |
| 386 | .compatible = "allwinner,sun50i-a64-sram-controller", | 395 | .compatible = "allwinner,sun50i-a64-sram-controller", |
| 387 | .data = &sun50i_a64_sramc_variant, | 396 | .data = &sun50i_a64_sramc_variant, |
| @@ -136,7 +136,6 @@ config SOC_TEGRA_FUSE · 135 unmodified lines | |||
| 136 | def_bool y | 136 | def_bool y |
| 137 | depends on ARCH_TEGRA | 137 | depends on ARCH_TEGRA |
| 138 | select SOC_BUS | 138 | select SOC_BUS |
| 139 | select TEGRA20_APB_DMA if ARCH_TEGRA_2x_SOC | ||
| 140 | 139 | ||
| 141 | config SOC_TEGRA_FLOWCTRL | 140 | config SOC_TEGRA_FLOWCTRL |
| 142 | bool | 141 | bool |
| @@ -162,3 +161,12 @@ config SOC_TEGRA30_VOLTAGE_COUPLER · 19 unmodified lines | |||
| 162 | bool "Voltage scaling support for Tegra30 SoCs" | 161 | bool "Voltage scaling support for Tegra30 SoCs" |
| 163 | depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST | 162 | depends on ARCH_TEGRA_3x_SOC || COMPILE_TEST |
| 164 | depends on REGULATOR | 163 | depends on REGULATOR |
| 164 | |||
| 165 | config SOC_TEGRA_CBB | ||
| 166 | tristate "Tegra driver to handle error from CBB" | ||
| 167 | depends on ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC | ||
| 168 | default y | ||
| 169 | help | ||
| 170 | Support for handling error from Tegra Control Backbone(CBB). | ||
| 171 | This driver handles the errors from CBB and prints debug | ||
| 172 | information about the failed transactions. | ||
| @@ -1,5 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | obj-y += fuse/ | 2 | obj-y += fuse/ |
| 3 | obj-y += cbb/ | ||
| 3 | 4 | ||
| 4 | obj-y += common.o | 5 | obj-y += common.o |
| 5 | obj-$(CONFIG_SOC_TEGRA_FLOWCTRL) += flowctrl.o | 6 | obj-$(CONFIG_SOC_TEGRA_FLOWCTRL) += flowctrl.o |
| @@ -0,0 +1,9 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | # | ||
| 3 | # Control Backbone Driver code. | ||
| 4 | # | ||
| 5 | ifdef CONFIG_SOC_TEGRA_CBB | ||
| 6 | obj-y += tegra-cbb.o | ||
| 7 | obj-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-cbb.o | ||
| 8 | obj-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-cbb.o | ||
| 9 | endif | ||
| @@ -0,0 +1,190 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/clk.h> | ||
| 7 | #include <linux/cpufeature.h> | ||
| 8 | #include <linux/debugfs.h> | ||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/of.h> | ||
| 11 | #include <linux/of_device.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <linux/device.h> | ||
| 14 | #include <linux/io.h> | ||
| 15 | #include <linux/of_irq.h> | ||
| 16 | #include <linux/of_address.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/ioport.h> | ||
| 19 | #include <linux/version.h> | ||
| 20 | #include <soc/tegra/fuse.h> | ||
| 21 | #include <soc/tegra/tegra-cbb.h> | ||
| 22 | |||
| 23 | void tegra_cbb_print_err(struct seq_file *file, const char *fmt, ...) | ||
| 24 | { | ||
| 25 | struct va_format vaf; | ||
| 26 | va_list args; | ||
| 27 | |||
| 28 | va_start(args, fmt); | ||
| 29 | |||
| 30 | if (file) { | ||
| 31 | seq_vprintf(file, fmt, args); | ||
| 32 | } else { | ||
| 33 | vaf.fmt = fmt; | ||
| 34 | vaf.va = &args; | ||
| 35 | pr_crit("%pV", &vaf); | ||
| 36 | } | ||
| 37 | |||
| 38 | va_end(args); | ||
| 39 | } | ||
| 40 | |||
| 41 | void tegra_cbb_print_cache(struct seq_file *file, u32 cache) | ||
| 42 | { | ||
| 43 | const char *buff_str, *mod_str, *rd_str, *wr_str; | ||
| 44 | |||
| 45 | buff_str = (cache & BIT(0)) ? "Bufferable " : ""; | ||
| 46 | mod_str = (cache & BIT(1)) ? "Modifiable " : ""; | ||
| 47 | rd_str = (cache & BIT(2)) ? "Read-Allocate " : ""; | ||
| 48 | wr_str = (cache & BIT(3)) ? "Write-Allocate" : ""; | ||
| 49 | |||
| 50 | if (cache == 0x0) | ||
| 51 | buff_str = "Device Non-Bufferable"; | ||
| 52 | |||
| 53 | tegra_cbb_print_err(file, "\t Cache\t\t\t: 0x%x -- %s%s%s%s\n", | ||
| 54 | cache, buff_str, mod_str, rd_str, wr_str); | ||
| 55 | } | ||
| 56 | |||
| 57 | void tegra_cbb_print_prot(struct seq_file *file, u32 prot) | ||
| 58 | { | ||
| 59 | const char *data_str, *secure_str, *priv_str; | ||
| 60 | |||
| 61 | data_str = (prot & 0x4) ? "Instruction" : "Data"; | ||
| 62 | secure_str = (prot & 0x2) ? "Non-Secure" : "Secure"; | ||
| 63 | priv_str = (prot & 0x1) ? "Privileged" : "Unprivileged"; | ||
| 64 | |||
| 65 | tegra_cbb_print_err(file, "\t Protection\t\t: 0x%x -- %s, %s, %s Access\n", | ||
| 66 | prot, priv_str, secure_str, data_str); | ||
| 67 | } | ||
| 68 | |||
| 69 | static int tegra_cbb_err_show(struct seq_file *file, void *data) | ||
| 70 | { | ||
| 71 | struct tegra_cbb *cbb = file->private; | ||
| 72 | |||
| 73 | return cbb->ops->debugfs_show(cbb, file, data); | ||
| 74 | } | ||
| 75 | |||
| 76 | static int tegra_cbb_err_open(struct inode *inode, struct file *file) | ||
| 77 | { | ||
| 78 | return single_open(file, tegra_cbb_err_show, inode->i_private); | ||
| 79 | } | ||
| 80 | |||
| 81 | static const struct file_operations tegra_cbb_err_fops = { | ||
| 82 | .open = tegra_cbb_err_open, | ||
| 83 | .read = seq_read, | ||
| 84 | .llseek = seq_lseek, | ||
| 85 | .release = single_release | ||
| 86 | }; | ||
| 87 | |||
| 88 | static int tegra_cbb_err_debugfs_init(struct tegra_cbb *cbb) | ||
| 89 | { | ||
| 90 | static struct dentry *root; | ||
| 91 | |||
| 92 | if (!root) { | ||
| 93 | root = debugfs_create_file("tegra_cbb_err", 0444, NULL, cbb, &tegra_cbb_err_fops); | ||
| 94 | if (IS_ERR_OR_NULL(root)) { | ||
| 95 | pr_err("%s(): could not create debugfs node\n", __func__); | ||
| 96 | return PTR_ERR(root); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | void tegra_cbb_stall_enable(struct tegra_cbb *cbb) | ||
| 104 | { | ||
| 105 | if (cbb->ops->stall_enable) | ||
| 106 | cbb->ops->stall_enable(cbb); | ||
| 107 | } | ||
| 108 | |||
| 109 | void tegra_cbb_fault_enable(struct tegra_cbb *cbb) | ||
| 110 | { | ||
| 111 | if (cbb->ops->fault_enable) | ||
| 112 | cbb->ops->fault_enable(cbb); | ||
| 113 | } | ||
| 114 | |||
| 115 | void tegra_cbb_error_clear(struct tegra_cbb *cbb) | ||
| 116 | { | ||
| 117 | if (cbb->ops->error_clear) | ||
| 118 | cbb->ops->error_clear(cbb); | ||
| 119 | } | ||
| 120 | |||
| 121 | u32 tegra_cbb_get_status(struct tegra_cbb *cbb) | ||
| 122 | { | ||
| 123 | if (cbb->ops->get_status) | ||
| 124 | return cbb->ops->get_status(cbb); | ||
| 125 | |||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | |||
| 129 | int tegra_cbb_get_irq(struct platform_device *pdev, unsigned int *nonsec_irq, | ||
| 130 | unsigned int *sec_irq) | ||
| 131 | { | ||
| 132 | unsigned int index = 0; | ||
| 133 | int num_intr = 0, irq; | ||
| 134 | |||
| 135 | num_intr = platform_irq_count(pdev); | ||
| 136 | if (!num_intr) | ||
| 137 | return -EINVAL; | ||
| 138 | |||
| 139 | if (num_intr == 2) { | ||
| 140 | irq = platform_get_irq(pdev, index); | ||
| 141 | if (irq <= 0) { | ||
| 142 | dev_err(&pdev->dev, "failed to get non-secure IRQ: %d\n", irq); | ||
| 143 | return -ENOENT; | ||
| 144 | } | ||
| 145 | |||
| 146 | *nonsec_irq = irq; | ||
| 147 | index++; | ||
| 148 | } | ||
| 149 | |||
| 150 | irq = platform_get_irq(pdev, index); | ||
| 151 | if (irq <= 0) { | ||
| 152 | dev_err(&pdev->dev, "failed to get secure IRQ: %d\n", irq); | ||
| 153 | return -ENOENT; | ||
| 154 | } | ||
| 155 | |||
| 156 | *sec_irq = irq; | ||
| 157 | |||
| 158 | if (num_intr == 1) | ||
| 159 | dev_dbg(&pdev->dev, "secure IRQ: %u\n", *sec_irq); | ||
| 160 | |||
| 161 | if (num_intr == 2) | ||
| 162 | dev_dbg(&pdev->dev, "secure IRQ: %u, non-secure IRQ: %u\n", *sec_irq, *nonsec_irq); | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | int tegra_cbb_register(struct tegra_cbb *cbb) | ||
| 168 | { | ||
| 169 | int ret; | ||
| 170 | |||
| 171 | if (IS_ENABLED(CONFIG_DEBUG_FS)) { | ||
| 172 | ret = tegra_cbb_err_debugfs_init(cbb); | ||
| 173 | if (ret) { | ||
| 174 | dev_err(cbb->dev, "failed to create debugfs\n"); | ||
| 175 | return ret; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | /* register interrupt handler for errors due to different initiators */ | ||
| 180 | ret = cbb->ops->interrupt_enable(cbb); | ||
| 181 | if (ret < 0) { | ||
| 182 | dev_err(cbb->dev, "Failed to register CBB Interrupt ISR"); | ||
| 183 | return ret; | ||
| 184 | } | ||
| 185 | |||
| 186 | cbb->ops->error_enable(cbb); | ||
| 187 | dsb(sy); | ||
| 188 | |||
| 189 | return 0; | ||
| 190 | } | ||
| @@ -0,0 +1,2364 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved | ||
| 4 | * | ||
| 5 | * The driver handles Error's from Control Backbone(CBB) generated due to | ||
| 6 | * illegal accesses. When an error is reported from a NOC within CBB, | ||
| 7 | * the driver checks ErrVld status of all three Error Logger's of that NOC. | ||
| 8 | * It then prints debug information about failed transaction using ErrLog | ||
| 9 | * registers of error logger which has ErrVld set. Currently, SLV, DEC, | ||
| 10 | * TMO, SEC, UNS are the codes which are supported by CBB. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/clk.h> | ||
| 14 | #include <linux/cpufeature.h> | ||
| 15 | #include <linux/debugfs.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/of.h> | ||
| 18 | #include <linux/of_device.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/device.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/of_irq.h> | ||
| 23 | #include <linux/of_address.h> | ||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/ioport.h> | ||
| 26 | #include <linux/version.h> | ||
| 27 | #include <soc/tegra/fuse.h> | ||
| 28 | #include <soc/tegra/tegra-cbb.h> | ||
| 29 | |||
| 30 | #define ERRLOGGER_0_ID_COREID_0 0x00000000 | ||
| 31 | #define ERRLOGGER_0_ID_REVISIONID_0 0x00000004 | ||
| 32 | #define ERRLOGGER_0_FAULTEN_0 0x00000008 | ||
| 33 | #define ERRLOGGER_0_ERRVLD_0 0x0000000c | ||
| 34 | #define ERRLOGGER_0_ERRCLR_0 0x00000010 | ||
| 35 | #define ERRLOGGER_0_ERRLOG0_0 0x00000014 | ||
| 36 | #define ERRLOGGER_0_ERRLOG1_0 0x00000018 | ||
| 37 | #define ERRLOGGER_0_RSVD_00_0 0x0000001c | ||
| 38 | #define ERRLOGGER_0_ERRLOG3_0 0x00000020 | ||
| 39 | #define ERRLOGGER_0_ERRLOG4_0 0x00000024 | ||
| 40 | #define ERRLOGGER_0_ERRLOG5_0 0x00000028 | ||
| 41 | #define ERRLOGGER_0_STALLEN_0 0x00000038 | ||
| 42 | |||
| 43 | #define ERRLOGGER_1_ID_COREID_0 0x00000080 | ||
| 44 | #define ERRLOGGER_1_ID_REVISIONID_0 0x00000084 | ||
| 45 | #define ERRLOGGER_1_FAULTEN_0 0x00000088 | ||
| 46 | #define ERRLOGGER_1_ERRVLD_0 0x0000008c | ||
| 47 | #define ERRLOGGER_1_ERRCLR_0 0x00000090 | ||
| 48 | #define ERRLOGGER_1_ERRLOG0_0 0x00000094 | ||
| 49 | #define ERRLOGGER_1_ERRLOG1_0 0x00000098 | ||
| 50 | #define ERRLOGGER_1_RSVD_00_0 0x0000009c | ||
| 51 | #define ERRLOGGER_1_ERRLOG3_0 0x000000a0 | ||
| 52 | #define ERRLOGGER_1_ERRLOG4_0 0x000000a4 | ||
| 53 | #define ERRLOGGER_1_ERRLOG5_0 0x000000a8 | ||
| 54 | #define ERRLOGGER_1_STALLEN_0 0x000000b8 | ||
| 55 | |||
| 56 | #define ERRLOGGER_2_ID_COREID_0 0x00000100 | ||
| 57 | #define ERRLOGGER_2_ID_REVISIONID_0 0x00000104 | ||
| 58 | #define ERRLOGGER_2_FAULTEN_0 0x00000108 | ||
| 59 | #define ERRLOGGER_2_ERRVLD_0 0x0000010c | ||
| 60 | #define ERRLOGGER_2_ERRCLR_0 0x00000110 | ||
| 61 | #define ERRLOGGER_2_ERRLOG0_0 0x00000114 | ||
| 62 | #define ERRLOGGER_2_ERRLOG1_0 0x00000118 | ||
| 63 | #define ERRLOGGER_2_RSVD_00_0 0x0000011c | ||
| 64 | #define ERRLOGGER_2_ERRLOG3_0 0x00000120 | ||
| 65 | #define ERRLOGGER_2_ERRLOG4_0 0x00000124 | ||
| 66 | #define ERRLOGGER_2_ERRLOG5_0 0x00000128 | ||
| 67 | #define ERRLOGGER_2_STALLEN_0 0x00000138 | ||
| 68 | |||
| 69 | #define CBB_NOC_INITFLOW GENMASK(23, 20) | ||
| 70 | #define CBB_NOC_TARGFLOW GENMASK(19, 16) | ||
| 71 | #define CBB_NOC_TARG_SUBRANGE GENMASK(15, 9) | ||
| 72 | #define CBB_NOC_SEQID GENMASK(8, 0) | ||
| 73 | |||
| 74 | #define BPMP_NOC_INITFLOW GENMASK(20, 18) | ||
| 75 | #define BPMP_NOC_TARGFLOW GENMASK(17, 13) | ||
| 76 | #define BPMP_NOC_TARG_SUBRANGE GENMASK(12, 9) | ||
| 77 | #define BPMP_NOC_SEQID GENMASK(8, 0) | ||
| 78 | |||
| 79 | #define AON_NOC_INITFLOW GENMASK(22, 21) | ||
| 80 | #define AON_NOC_TARGFLOW GENMASK(20, 15) | ||
| 81 | #define AON_NOC_TARG_SUBRANGE GENMASK(14, 9) | ||
| 82 | #define AON_NOC_SEQID GENMASK(8, 0) | ||
| 83 | |||
| 84 | #define SCE_NOC_INITFLOW GENMASK(21, 19) | ||
| 85 | #define SCE_NOC_TARGFLOW GENMASK(18, 14) | ||
| 86 | #define SCE_NOC_TARG_SUBRANGE GENMASK(13, 9) | ||
| 87 | #define SCE_NOC_SEQID GENMASK(8, 0) | ||
| 88 | |||
| 89 | #define CBB_NOC_AXCACHE GENMASK(3, 0) | ||
| 90 | #define CBB_NOC_NON_MOD GENMASK(4, 4) | ||
| 91 | #define CBB_NOC_AXPROT GENMASK(7, 5) | ||
| 92 | #define CBB_NOC_FALCONSEC GENMASK(9, 8) | ||
| 93 | #define CBB_NOC_GRPSEC GENMASK(16, 10) | ||
| 94 | #define CBB_NOC_VQC GENMASK(18, 17) | ||
| 95 | #define CBB_NOC_MSTR_ID GENMASK(22, 19) | ||
| 96 | #define CBB_NOC_AXI_ID GENMASK(30, 23) | ||
| 97 | |||
| 98 | #define CLUSTER_NOC_AXCACHE GENMASK(3, 0) | ||
| 99 | #define CLUSTER_NOC_AXPROT GENMASK(6, 4) | ||
| 100 | #define CLUSTER_NOC_FALCONSEC GENMASK(8, 7) | ||
| 101 | #define CLUSTER_NOC_GRPSEC GENMASK(15, 9) | ||
| 102 | #define CLUSTER_NOC_VQC GENMASK(17, 16) | ||
| 103 | #define CLUSTER_NOC_MSTR_ID GENMASK(21, 18) | ||
| 104 | |||
| 105 | #define USRBITS_MSTR_ID GENMASK(21, 18) | ||
| 106 | |||
| 107 | #define CBB_ERR_OPC GENMASK(4, 1) | ||
| 108 | #define CBB_ERR_ERRCODE GENMASK(10, 8) | ||
| 109 | #define CBB_ERR_LEN1 GENMASK(27, 16) | ||
| 110 | |||
| 111 | #define DMAAPB_X_RAW_INTERRUPT_STATUS 0x2ec | ||
| 112 | |||
| 113 | struct tegra194_cbb_packet_header { | ||
| 114 | bool lock; // [0] | ||
| 115 | u8 opc; // [4:1] | ||
| 116 | u8 errcode; // [10:8]= RD, RDW, RDL, RDX, WR, WRW, WRC, PRE, URG | ||
| 117 | u16 len1; // [27:16] | ||
| 118 | bool format; // [31] = 1 -> FlexNoC versions 2.7 & above | ||
| 119 | }; | ||
| 120 | |||
| 121 | struct tegra194_cbb_aperture { | ||
| 122 | u8 initflow; | ||
| 123 | u8 targflow; | ||
| 124 | u8 targ_subrange; | ||
| 125 | u8 init_mapping; | ||
| 126 | u32 init_localaddress; | ||
| 127 | u8 targ_mapping; | ||
| 128 | u32 targ_localaddress; | ||
| 129 | u16 seqid; | ||
| 130 | }; | ||
| 131 | |||
| 132 | struct tegra194_cbb_userbits { | ||
| 133 | u8 axcache; | ||
| 134 | u8 non_mod; | ||
| 135 | u8 axprot; | ||
| 136 | u8 falconsec; | ||
| 137 | u8 grpsec; | ||
| 138 | u8 vqc; | ||
| 139 | u8 mstr_id; | ||
| 140 | u8 axi_id; | ||
| 141 | }; | ||
| 142 | |||
| 143 | struct tegra194_cbb_noc_data { | ||
| 144 | const char *name; | ||
| 145 | bool erd_mask_inband_err; | ||
| 146 | const char * const *master_id; | ||
| 147 | unsigned int max_aperture; | ||
| 148 | const struct tegra194_cbb_aperture *noc_aperture; | ||
| 149 | const char * const *routeid_initflow; | ||
| 150 | const char * const *routeid_targflow; | ||
| 151 | void (*parse_routeid)(struct tegra194_cbb_aperture *info, u64 routeid); | ||
| 152 | void (*parse_userbits)(struct tegra194_cbb_userbits *usrbits, u32 elog_5); | ||
| 153 | }; | ||
| 154 | |||
| 155 | struct tegra194_axi2apb_bridge { | ||
| 156 | struct resource res; | ||
| 157 | void __iomem *base; | ||
| 158 | }; | ||
| 159 | |||
| 160 | struct tegra194_cbb { | ||
| 161 | struct tegra_cbb base; | ||
| 162 | |||
| 163 | const struct tegra194_cbb_noc_data *noc; | ||
| 164 | struct resource *res; | ||
| 165 | |||
| 166 | void __iomem *regs; | ||
| 167 | unsigned int num_intr; | ||
| 168 | unsigned int sec_irq; | ||
| 169 | unsigned int nonsec_irq; | ||
| 170 | u32 errlog0; | ||
| 171 | u32 errlog1; | ||
| 172 | u32 errlog2; | ||
| 173 | u32 errlog3; | ||
| 174 | u32 errlog4; | ||
| 175 | u32 errlog5; | ||
| 176 | |||
| 177 | struct tegra194_axi2apb_bridge *bridges; | ||
| 178 | unsigned int num_bridges; | ||
| 179 | }; | ||
| 180 | |||
| 181 | static inline struct tegra194_cbb *to_tegra194_cbb(struct tegra_cbb *cbb) | ||
| 182 | { | ||
| 183 | return container_of(cbb, struct tegra194_cbb, base); | ||
| 184 | } | ||
| 185 | |||
| 186 | static LIST_HEAD(cbb_list); | ||
| 187 | static DEFINE_SPINLOCK(cbb_lock); | ||
| 188 | |||
| 189 | static const char * const tegra194_cbb_trantype[] = { | ||
| 190 | "RD - Read, Incrementing", | ||
| 191 | "RDW - Read, Wrap", /* Not Supported */ | ||
| 192 | "RDX - Exclusive Read", /* Not Supported */ | ||
| 193 | "RDL - Linked Read", /* Not Supported */ | ||
| 194 | "WR - Write, Incrementing", | ||
| 195 | "WRW - Write, Wrap", /* Not Supported */ | ||
| 196 | "WRC - Exclusive Write", /* Not Supported */ | ||
| 197 | "PRE - Preamble Sequence for Fixed Accesses" | ||
| 198 | }; | ||
| 199 | |||
| 200 | static const char * const tegra194_axi2apb_error[] = { | ||
| 201 | "SFIFONE - Status FIFO Not Empty interrupt", | ||
| 202 | "SFIFOF - Status FIFO Full interrupt", | ||
| 203 | "TIM - Timer(Timeout) interrupt", | ||
| 204 | "SLV - SLVERR interrupt", | ||
| 205 | "NULL", | ||
| 206 | "ERBF - Early response buffer Full interrupt", | ||
| 207 | "NULL", | ||
| 208 | "RDFIFOF - Read Response FIFO Full interrupt", | ||
| 209 | "WRFIFOF - Write Response FIFO Full interrupt", | ||
| 210 | "CH0DFIFOF - Ch0 Data FIFO Full interrupt", | ||
| 211 | "CH1DFIFOF - Ch1 Data FIFO Full interrupt", | ||
| 212 | "CH2DFIFOF - Ch2 Data FIFO Full interrupt", | ||
| 213 | "UAT - Unsupported alignment type error", | ||
| 214 | "UBS - Unsupported burst size error", | ||
| 215 | "UBE - Unsupported Byte Enable error", | ||
| 216 | "UBT - Unsupported burst type error", | ||
| 217 | "BFS - Block Firewall security error", | ||
| 218 | "ARFS - Address Range Firewall security error", | ||
| 219 | "CH0RFIFOF - Ch0 Request FIFO Full interrupt", | ||
| 220 | "CH1RFIFOF - Ch1 Request FIFO Full interrupt", | ||
| 221 | "CH2RFIFOF - Ch2 Request FIFO Full interrupt" | ||
| 222 | }; | ||
| 223 | |||
| 224 | static const char * const tegra194_master_id[] = { | ||
| 225 | [0x0] = "CCPLEX", | ||
| 226 | [0x1] = "CCPLEX_DPMU", | ||
| 227 | [0x2] = "BPMP", | ||
| 228 | [0x3] = "AON", | ||
| 229 | [0x4] = "SCE", | ||
| 230 | [0x5] = "GPCDMA_PERIPHERAL", | ||
| 231 | [0x6] = "TSECA", | ||
| 232 | [0x7] = "TSECB", | ||
| 233 | [0x8] = "JTAGM_DFT", | ||
| 234 | [0x9] = "CORESIGHT_AXIAP", | ||
| 235 | [0xa] = "APE", | ||
| 236 | [0xb] = "PEATR", | ||
| 237 | [0xc] = "NVDEC", | ||
| 238 | [0xd] = "RCE", | ||
| 239 | [0xe] = "NVDEC1" | ||
| 240 | }; | ||
| 241 | |||
| 242 | static const struct tegra_cbb_error tegra194_cbb_errors[] = { | ||
| 243 | { | ||
| 244 | .code = "SLV", | ||
| 245 | .source = "Target", | ||
| 246 | .desc = "Target error detected by CBB slave" | ||
| 247 | }, { | ||
| 248 | .code = "DEC", | ||
| 249 | .source = "Initiator NIU", | ||
| 250 | .desc = "Address decode error" | ||
| 251 | }, { | ||
| 252 | .code = "UNS", | ||
| 253 | .source = "Target NIU", | ||
| 254 | .desc = "Unsupported request. Not a valid transaction" | ||
| 255 | }, { | ||
| 256 | .code = "DISC", /* Not Supported by CBB */ | ||
| 257 | .source = "Power Disconnect", | ||
| 258 | .desc = "Disconnected target or domain" | ||
| 259 | }, { | ||
| 260 | .code = "SEC", | ||
| 261 | .source = "Initiator NIU or Firewall", | ||
| 262 | .desc = "Security violation. Firewall error" | ||
| 263 | }, { | ||
| 264 | .code = "HIDE", /* Not Supported by CBB */ | ||
| 265 | .source = "Firewall", | ||
| 266 | .desc = "Hidden security violation, reported as OK to initiator" | ||
| 267 | }, { | ||
| 268 | .code = "TMO", | ||
| 269 | .source = "Target NIU", | ||
| 270 | .desc = "Target time-out error" | ||
| 271 | }, { | ||
| 272 | .code = "RSV", | ||
| 273 | .source = "None", | ||
| 274 | .desc = "Reserved" | ||
| 275 | } | ||
| 276 | }; | ||
| 277 | |||
| 278 | /* | ||
| 279 | * CBB NOC aperture lookup table as per file "cbb_central_noc_Structure.info". | ||
| 280 | */ | ||
| 281 | static const char * const tegra194_cbbcentralnoc_routeid_initflow[] = { | ||
| 282 | [0x0] = "aon_p2ps/I/aon", | ||
| 283 | [0x1] = "ape_p2ps/I/ape_p2ps", | ||
| 284 | [0x2] = "bpmp_p2ps/I/bpmp_p2ps", | ||
| 285 | [0x3] = "ccroc_p2ps/I/ccroc_p2ps", | ||
| 286 | [0x4] = "csite_p2ps/I/0", | ||
| 287 | [0x5] = "gpcdma_mmio_p2ps/I/0", | ||
| 288 | [0x6] = "jtag_p2ps/I/0", | ||
| 289 | [0x7] = "nvdec1_p2ps/I/0", | ||
| 290 | [0x8] = "nvdec_p2ps/I/0", | ||
| 291 | [0x9] = "rce_p2ps/I/rce_p2ps", | ||
| 292 | [0xa] = "sce_p2ps/I/sce_p2ps", | ||
| 293 | [0xb] = "tseca_p2ps/I/0", | ||
| 294 | [0xc] = "tsecb_p2ps/I/0", | ||
| 295 | [0xd] = "RESERVED", | ||
| 296 | [0xe] = "RESERVED", | ||
| 297 | [0xf] = "RESERVED" | ||
| 298 | }; | ||
| 299 | |||
| 300 | static const char * const tegra194_cbbcentralnoc_routeid_targflow[] = { | ||
| 301 | [0x0] = "SVC/T/intreg", | ||
| 302 | [0x1] = "axis_satellite_axi2apb_p2pm/T/axis_satellite_axi2apb_p2pm", | ||
| 303 | [0x2] = "axis_satellite_grout/T/axis_satellite_grout", | ||
| 304 | [0x3] = "cbb_firewall/T/cbb_firewall", | ||
| 305 | [0x4] = "gpu_p2pm/T/gpu_p2pm", | ||
| 306 | [0x5] = "host1x_p2pm/T/host1x_p2pm", | ||
| 307 | [0x6] = "sapb_3_p2pm/T/sapb_3_p2pm", | ||
| 308 | [0x7] = "smmu0_p2pm/T/smmu0_p2pm", | ||
| 309 | [0x8] = "smmu1_p2pm/T/smmu1_p2pm", | ||
| 310 | [0x9] = "smmu2_p2pm/T/smmu2_p2pm", | ||
| 311 | [0xa] = "stm_p2pm/T/stm_p2pm", | ||
| 312 | [0xb] = "RESERVED", | ||
| 313 | [0xc] = "RESERVED", | ||
| 314 | [0xd] = "RESERVED", | ||
| 315 | [0xe] = "RESERVED", | ||
| 316 | [0xf] = "RESERVED" | ||
| 317 | }; | ||
| 318 | |||
| 319 | /* | ||
| 320 | * Fields of CBB NOC lookup table: | ||
| 321 | * Init flow, Targ flow, Targ subrange, Init mapping, Init localAddress, | ||
| 322 | * Targ mapping, Targ localAddress | ||
| 323 | * ---------------------------------------------------------------------------- | ||
| 324 | */ | ||
| 325 | static const struct tegra194_cbb_aperture tegra194_cbbcentralnoc_apert_lookup[] = { | ||
| 326 | { 0x0, 0x0, 0x00, 0x0, 0x02300000, 0, 0x00000000 }, | ||
| 327 | { 0x0, 0x1, 0x00, 0x0, 0x02003000, 0, 0x02003000 }, | ||
| 328 | { 0x0, 0x1, 0x01, 0x0, 0x02006000, 2, 0x02006000 }, | ||
| 329 | { 0x0, 0x1, 0x02, 0x0, 0x02016000, 3, 0x02016000 }, | ||
| 330 | { 0x0, 0x1, 0x03, 0x0, 0x0201d000, 4, 0x0201d000 }, | ||
| 331 | { 0x0, 0x1, 0x04, 0x0, 0x0202b000, 6, 0x0202b000 }, | ||
| 332 | { 0x0, 0x1, 0x05, 0x0, 0x02434000, 20, 0x02434000 }, | ||
| 333 | { 0x0, 0x1, 0x06, 0x0, 0x02436000, 21, 0x02436000 }, | ||
| 334 | { 0x0, 0x1, 0x07, 0x0, 0x02438000, 22, 0x02438000 }, | ||
| 335 | { 0x0, 0x1, 0x08, 0x0, 0x02445000, 24, 0x02445000 }, | ||
| 336 | { 0x0, 0x1, 0x09, 0x0, 0x02446000, 25, 0x02446000 }, | ||
| 337 | { 0x0, 0x1, 0x0a, 0x0, 0x02004000, 1, 0x02004000 }, | ||
| 338 | { 0x0, 0x1, 0x0b, 0x0, 0x0201e000, 5, 0x0201e000 }, | ||
| 339 | { 0x0, 0x1, 0x0c, 0x0, 0x0202c000, 7, 0x0202c000 }, | ||
| 340 | { 0x0, 0x1, 0x0d, 0x0, 0x02204000, 8, 0x02204000 }, | ||
| 341 | { 0x0, 0x1, 0x0e, 0x0, 0x02214000, 9, 0x02214000 }, | ||
| 342 | { 0x0, 0x1, 0x0f, 0x0, 0x02224000, 10, 0x02224000 }, | ||
| 343 | { 0x0, 0x1, 0x10, 0x0, 0x02234000, 11, 0x02234000 }, | ||
| 344 | { 0x0, 0x1, 0x11, 0x0, 0x02244000, 12, 0x02244000 }, | ||
| 345 | { 0x0, 0x1, 0x12, 0x0, 0x02254000, 13, 0x02254000 }, | ||
| 346 | { 0x0, 0x1, 0x13, 0x0, 0x02264000, 14, 0x02264000 }, | ||
| 347 | { 0x0, 0x1, 0x14, 0x0, 0x02274000, 15, 0x02274000 }, | ||
| 348 | { 0x0, 0x1, 0x15, 0x0, 0x02284000, 16, 0x02284000 }, | ||
| 349 | { 0x0, 0x1, 0x16, 0x0, 0x0243a000, 23, 0x0243a000 }, | ||
| 350 | { 0x0, 0x1, 0x17, 0x0, 0x02370000, 17, 0x02370000 }, | ||
| 351 | { 0x0, 0x1, 0x18, 0x0, 0x023d0000, 18, 0x023d0000 }, | ||
| 352 | { 0x0, 0x1, 0x19, 0x0, 0x023e0000, 19, 0x023e0000 }, | ||
| 353 | { 0x0, 0x1, 0x1a, 0x0, 0x02450000, 26, 0x02450000 }, | ||
| 354 | { 0x0, 0x1, 0x1b, 0x0, 0x02460000, 27, 0x02460000 }, | ||
| 355 | { 0x0, 0x1, 0x1c, 0x0, 0x02490000, 28, 0x02490000 }, | ||
| 356 | { 0x0, 0x1, 0x1d, 0x0, 0x03130000, 31, 0x03130000 }, | ||
| 357 | { 0x0, 0x1, 0x1e, 0x0, 0x03160000, 32, 0x03160000 }, | ||
| 358 | { 0x0, 0x1, 0x1f, 0x0, 0x03270000, 33, 0x03270000 }, | ||
| 359 | { 0x0, 0x1, 0x20, 0x0, 0x032e0000, 35, 0x032e0000 }, | ||
| 360 | { 0x0, 0x1, 0x21, 0x0, 0x03300000, 36, 0x03300000 }, | ||
| 361 | { 0x0, 0x1, 0x22, 0x0, 0x13090000, 40, 0x13090000 }, | ||
| 362 | { 0x0, 0x1, 0x23, 0x0, 0x20120000, 43, 0x20120000 }, | ||
| 363 | { 0x0, 0x1, 0x24, 0x0, 0x20170000, 44, 0x20170000 }, | ||
| 364 | { 0x0, 0x1, 0x25, 0x0, 0x20190000, 45, 0x20190000 }, | ||
| 365 | { 0x0, 0x1, 0x26, 0x0, 0x201b0000, 46, 0x201b0000 }, | ||
| 366 | { 0x0, 0x1, 0x27, 0x0, 0x20250000, 47, 0x20250000 }, | ||
| 367 | { 0x0, 0x1, 0x28, 0x0, 0x20260000, 48, 0x20260000 }, | ||
| 368 | { 0x0, 0x1, 0x29, 0x0, 0x20420000, 49, 0x20420000 }, | ||
| 369 | { 0x0, 0x1, 0x2a, 0x0, 0x20460000, 50, 0x20460000 }, | ||
| 370 | { 0x0, 0x1, 0x2b, 0x0, 0x204f0000, 51, 0x204f0000 }, | ||
| 371 | { 0x0, 0x1, 0x2c, 0x0, 0x20520000, 52, 0x20520000 }, | ||
| 372 | { 0x0, 0x1, 0x2d, 0x0, 0x20580000, 53, 0x20580000 }, | ||
| 373 | { 0x0, 0x1, 0x2e, 0x0, 0x205a0000, 54, 0x205a0000 }, | ||
| 374 | { 0x0, 0x1, 0x2f, 0x0, 0x205c0000, 55, 0x205c0000 }, | ||
| 375 | { 0x0, 0x1, 0x30, 0x0, 0x20690000, 56, 0x20690000 }, | ||
| 376 | { 0x0, 0x1, 0x31, 0x0, 0x20770000, 57, 0x20770000 }, | ||
| 377 | { 0x0, 0x1, 0x32, 0x0, 0x20790000, 58, 0x20790000 }, | ||
| 378 | { 0x0, 0x1, 0x33, 0x0, 0x20880000, 59, 0x20880000 }, | ||
| 379 | { 0x0, 0x1, 0x34, 0x0, 0x20990000, 62, 0x20990000 }, | ||
| 380 | { 0x0, 0x1, 0x35, 0x0, 0x20e10000, 65, 0x20e10000 }, | ||
| 381 | { 0x0, 0x1, 0x36, 0x0, 0x20e70000, 66, 0x20e70000 }, | ||
| 382 | { 0x0, 0x1, 0x37, 0x0, 0x20e80000, 67, 0x20e80000 }, | ||
| 383 | { 0x0, 0x1, 0x38, 0x0, 0x20f30000, 68, 0x20f30000 }, | ||
| 384 | { 0x0, 0x1, 0x39, 0x0, 0x20f50000, 69, 0x20f50000 }, | ||
| 385 | { 0x0, 0x1, 0x3a, 0x0, 0x20fc0000, 70, 0x20fc0000 }, | ||
| 386 | { 0x0, 0x1, 0x3b, 0x0, 0x21110000, 72, 0x21110000 }, | ||
| 387 | { 0x0, 0x1, 0x3c, 0x0, 0x21270000, 73, 0x21270000 }, | ||
| 388 | { 0x0, 0x1, 0x3d, 0x0, 0x21290000, 74, 0x21290000 }, | ||
| 389 | { 0x0, 0x1, 0x3e, 0x0, 0x21840000, 75, 0x21840000 }, | ||
| 390 | { 0x0, 0x1, 0x3f, 0x0, 0x21880000, 76, 0x21880000 }, | ||
| 391 | { 0x0, 0x1, 0x40, 0x0, 0x218d0000, 77, 0x218d0000 }, | ||
| 392 | { 0x0, 0x1, 0x41, 0x0, 0x21950000, 78, 0x21950000 }, | ||
| 393 | { 0x0, 0x1, 0x42, 0x0, 0x21960000, 79, 0x21960000 }, | ||
| 394 | { 0x0, 0x1, 0x43, 0x0, 0x21a10000, 80, 0x21a10000 }, | ||
| 395 | { 0x0, 0x1, 0x44, 0x0, 0x024a0000, 29, 0x024a0000 }, | ||
| 396 | { 0x0, 0x1, 0x45, 0x0, 0x024c0000, 30, 0x024c0000 }, | ||
| 397 | { 0x0, 0x1, 0x46, 0x0, 0x032c0000, 34, 0x032c0000 }, | ||
| 398 | { 0x0, 0x1, 0x47, 0x0, 0x03400000, 37, 0x03400000 }, | ||
| 399 | { 0x0, 0x1, 0x48, 0x0, 0x130a0000, 41, 0x130a0000 }, | ||
| 400 | { 0x0, 0x1, 0x49, 0x0, 0x130c0000, 42, 0x130c0000 }, | ||
| 401 | { 0x0, 0x1, 0x4a, 0x0, 0x208a0000, 60, 0x208a0000 }, | ||
| 402 | { 0x0, 0x1, 0x4b, 0x0, 0x208c0000, 61, 0x208c0000 }, | ||
| 403 | { 0x0, 0x1, 0x4c, 0x0, 0x209a0000, 63, 0x209a0000 }, | ||
| 404 | { 0x0, 0x1, 0x4d, 0x0, 0x21a40000, 81, 0x21a40000 }, | ||
| 405 | { 0x0, 0x1, 0x4e, 0x0, 0x03440000, 38, 0x03440000 }, | ||
| 406 | { 0x0, 0x1, 0x4f, 0x0, 0x20d00000, 64, 0x20d00000 }, | ||
| 407 | { 0x0, 0x1, 0x50, 0x0, 0x21000000, 71, 0x21000000 }, | ||
| 408 | { 0x0, 0x1, 0x51, 0x0, 0x0b000000, 39, 0x0b000000 }, | ||
| 409 | { 0x0, 0x2, 0x00, 0x0, 0x00000000, 0, 0x00000000 }, | ||
| 410 | { 0x0, 0x3, 0x00, 0x0, 0x02340000, 0, 0x00000000 }, | ||
| 411 | { 0x0, 0x4, 0x00, 0x0, 0x17000000, 0, 0x17000000 }, | ||
| 412 | { 0x0, 0x4, 0x01, 0x0, 0x18000000, 1, 0x18000000 }, | ||
| 413 | { 0x0, 0x5, 0x00, 0x0, 0x13e80000, 1, 0x13e80000 }, | ||
| 414 | { 0x0, 0x5, 0x01, 0x0, 0x15810000, 12, 0x15810000 }, | ||
| 415 | { 0x0, 0x5, 0x02, 0x0, 0x15840000, 14, 0x15840000 }, | ||
| 416 | { 0x0, 0x5, 0x03, 0x0, 0x15a40000, 17, 0x15a40000 }, | ||
| 417 | { 0x0, 0x5, 0x04, 0x0, 0x13f00000, 3, 0x13f00000 }, | ||
| 418 | { 0x0, 0x5, 0x05, 0x0, 0x15820000, 13, 0x15820000 }, | ||
| 419 | { 0x0, 0x5, 0x06, 0x0, 0x13ec0000, 2, 0x13ec0000 }, | ||
| 420 | { 0x0, 0x5, 0x07, 0x0, 0x15200000, 6, 0x15200000 }, | ||
| 421 | { 0x0, 0x5, 0x08, 0x0, 0x15340000, 7, 0x15340000 }, | ||
| 422 | { 0x0, 0x5, 0x09, 0x0, 0x15380000, 8, 0x15380000 }, | ||
| 423 | { 0x0, 0x5, 0x0a, 0x0, 0x15500000, 10, 0x15500000 }, | ||
| 424 | { 0x0, 0x5, 0x0b, 0x0, 0x155c0000, 11, 0x155c0000 }, | ||
| 425 | { 0x0, 0x5, 0x0c, 0x0, 0x15a00000, 16, 0x15a00000 }, | ||
| 426 | { 0x0, 0x5, 0x0d, 0x0, 0x13e00000, 0, 0x13e00000 }, | ||
| 427 | { 0x0, 0x5, 0x0e, 0x0, 0x15100000, 5, 0x15100000 }, | ||
| 428 | { 0x0, 0x5, 0x0f, 0x0, 0x15480000, 9, 0x15480000 }, | ||
| 429 | { 0x0, 0x5, 0x10, 0x0, 0x15880000, 15, 0x15880000 }, | ||
| 430 | { 0x0, 0x5, 0x11, 0x0, 0x15a80000, 18, 0x15a80000 }, | ||
| 431 | { 0x0, 0x5, 0x12, 0x0, 0x15b00000, 19, 0x15b00000 }, | ||
| 432 | { 0x0, 0x5, 0x13, 0x0, 0x14800000, 4, 0x14800000 }, | ||
| 433 | { 0x0, 0x5, 0x14, 0x0, 0x15c00000, 20, 0x15c00000 }, | ||
| 434 | { 0x0, 0x5, 0x15, 0x0, 0x16000000, 21, 0x16000000 }, | ||
| 435 | { 0x0, 0x6, 0x00, 0x0, 0x02000000, 4, 0x02000000 }, | ||
| 436 | { 0x0, 0x6, 0x01, 0x0, 0x02007000, 5, 0x02007000 }, | ||
| 437 | { 0x0, 0x6, 0x02, 0x0, 0x02008000, 6, 0x02008000 }, | ||
| 438 | { 0x0, 0x6, 0x03, 0x0, 0x02013000, 7, 0x02013000 }, | ||
| 439 | { 0x0, 0x6, 0x04, 0x0, 0x0201c000, 8, 0x0201c000 }, | ||
| 440 | { 0x0, 0x6, 0x05, 0x0, 0x02020000, 9, 0x02020000 }, | ||
| 441 | { 0x0, 0x6, 0x06, 0x0, 0x0202a000, 10, 0x0202a000 }, | ||
| 442 | { 0x0, 0x6, 0x07, 0x0, 0x0202e000, 11, 0x0202e000 }, | ||
| 443 | { 0x0, 0x6, 0x08, 0x0, 0x06400000, 33, 0x06400000 }, | ||
| 444 | { 0x0, 0x6, 0x09, 0x0, 0x02038000, 12, 0x02038000 }, | ||
| 445 | { 0x0, 0x6, 0x0a, 0x0, 0x00100000, 0, 0x00100000 }, | ||
| 446 | { 0x0, 0x6, 0x0b, 0x0, 0x023b0000, 13, 0x023b0000 }, | ||
| 447 | { 0x0, 0x6, 0x0c, 0x0, 0x02800000, 16, 0x02800000 }, | ||
| 448 | { 0x0, 0x6, 0x0d, 0x0, 0x030e0000, 22, 0x030e0000 }, | ||
| 449 | { 0x0, 0x6, 0x0e, 0x0, 0x03800000, 23, 0x03800000 }, | ||
| 450 | { 0x0, 0x6, 0x0f, 0x0, 0x03980000, 25, 0x03980000 }, | ||
| 451 | { 0x0, 0x6, 0x10, 0x0, 0x03a60000, 26, 0x03a60000 }, | ||
| 452 | { 0x0, 0x6, 0x11, 0x0, 0x03d80000, 31, 0x03d80000 }, | ||
| 453 | { 0x0, 0x6, 0x12, 0x0, 0x20000000, 36, 0x20000000 }, | ||
| 454 | { 0x0, 0x6, 0x13, 0x0, 0x20050000, 38, 0x20050000 }, | ||
| 455 | { 0x0, 0x6, 0x14, 0x0, 0x201e0000, 40, 0x201e0000 }, | ||
| 456 | { 0x0, 0x6, 0x15, 0x0, 0x20280000, 42, 0x20280000 }, | ||
| 457 | { 0x0, 0x6, 0x16, 0x0, 0x202c0000, 43, 0x202c0000 }, | ||
| 458 | { 0x0, 0x6, 0x17, 0x0, 0x20390000, 44, 0x20390000 }, | ||
| 459 | { 0x0, 0x6, 0x18, 0x0, 0x20430000, 45, 0x20430000 }, | ||
| 460 | { 0x0, 0x6, 0x19, 0x0, 0x20440000, 46, 0x20440000 }, | ||
| 461 | { 0x0, 0x6, 0x1a, 0x0, 0x204e0000, 47, 0x204e0000 }, | ||
| 462 | { 0x0, 0x6, 0x1b, 0x0, 0x20550000, 48, 0x20550000 }, | ||
| 463 | { 0x0, 0x6, 0x1c, 0x0, 0x20570000, 49, 0x20570000 }, | ||
| 464 | { 0x0, 0x6, 0x1d, 0x0, 0x20590000, 50, 0x20590000 }, | ||
| 465 | { 0x0, 0x6, 0x1e, 0x0, 0x20730000, 52, 0x20730000 }, | ||
| 466 | { 0x0, 0x6, 0x1f, 0x0, 0x209f0000, 54, 0x209f0000 }, | ||
| 467 | { 0x0, 0x6, 0x20, 0x0, 0x20e20000, 55, 0x20e20000 }, | ||
| 468 | { 0x0, 0x6, 0x21, 0x0, 0x20ed0000, 56, 0x20ed0000 }, | ||
| 469 | { 0x0, 0x6, 0x22, 0x0, 0x20fd0000, 57, 0x20fd0000 }, | ||
| 470 | { 0x0, 0x6, 0x23, 0x0, 0x21120000, 59, 0x21120000 }, | ||
| 471 | { 0x0, 0x6, 0x24, 0x0, 0x211a0000, 60, 0x211a0000 }, | ||
| 472 | { 0x0, 0x6, 0x25, 0x0, 0x21850000, 61, 0x21850000 }, | ||
| 473 | { 0x0, 0x6, 0x26, 0x0, 0x21860000, 62, 0x21860000 }, | ||
| 474 | { 0x0, 0x6, 0x27, 0x0, 0x21890000, 63, 0x21890000 }, | ||
| 475 | { 0x0, 0x6, 0x28, 0x0, 0x21970000, 64, 0x21970000 }, | ||
| 476 | { 0x0, 0x6, 0x29, 0x0, 0x21990000, 65, 0x21990000 }, | ||
| 477 | { 0x0, 0x6, 0x2a, 0x0, 0x21a00000, 66, 0x21a00000 }, | ||
| 478 | { 0x0, 0x6, 0x2b, 0x0, 0x21a90000, 68, 0x21a90000 }, | ||
| 479 | { 0x0, 0x6, 0x2c, 0x0, 0x21ac0000, 70, 0x21ac0000 }, | ||
| 480 | { 0x0, 0x6, 0x2d, 0x0, 0x01f80000, 3, 0x01f80000 }, | ||
| 481 | { 0x0, 0x6, 0x2e, 0x0, 0x024e0000, 14, 0x024e0000 }, | ||
| 482 | { 0x0, 0x6, 0x2f, 0x0, 0x030c0000, 21, 0x030c0000 }, | ||
| 483 | { 0x0, 0x6, 0x30, 0x0, 0x03820000, 24, 0x03820000 }, | ||
| 484 | { 0x0, 0x6, 0x31, 0x0, 0x03aa0000, 27, 0x03aa0000 }, | ||
| 485 | { 0x0, 0x6, 0x32, 0x0, 0x03c80000, 29, 0x03c80000 }, | ||
| 486 | { 0x0, 0x6, 0x33, 0x0, 0x130e0000, 34, 0x130e0000 }, | ||
| 487 | { 0x0, 0x6, 0x34, 0x0, 0x20020000, 37, 0x20020000 }, | ||
| 488 | { 0x0, 0x6, 0x35, 0x0, 0x20060000, 39, 0x20060000 }, | ||
| 489 | { 0x0, 0x6, 0x36, 0x0, 0x20200000, 41, 0x20200000 }, | ||
| 490 | { 0x0, 0x6, 0x37, 0x0, 0x206a0000, 51, 0x206a0000 }, | ||
| 491 | { 0x0, 0x6, 0x38, 0x0, 0x20740000, 53, 0x20740000 }, | ||
| 492 | { 0x0, 0x6, 0x39, 0x0, 0x20fe0000, 58, 0x20fe0000 }, | ||
| 493 | { 0x0, 0x6, 0x3a, 0x0, 0x21a20000, 67, 0x21a20000 }, | ||
| 494 | { 0x0, 0x6, 0x3b, 0x0, 0x21aa0000, 69, 0x21aa0000 }, | ||
| 495 | { 0x0, 0x6, 0x3c, 0x0, 0x02b80000, 17, 0x02b80000 }, | ||
| 496 | { 0x0, 0x6, 0x3d, 0x0, 0x03080000, 20, 0x03080000 }, | ||
| 497 | { 0x0, 0x6, 0x3e, 0x0, 0x13100000, 35, 0x13100000 }, | ||
| 498 | { 0x0, 0x6, 0x3f, 0x0, 0x01f00000, 2, 0x01f00000 }, | ||
| 499 | { 0x0, 0x6, 0x40, 0x0, 0x03000000, 19, 0x03000000 }, | ||
| 500 | { 0x0, 0x6, 0x41, 0x0, 0x03c00000, 28, 0x03c00000 }, | ||
| 501 | { 0x0, 0x6, 0x42, 0x0, 0x03d00000, 30, 0x03d00000 }, | ||
| 502 | { 0x0, 0x6, 0x43, 0x0, 0x01700000, 1, 0x01700000 }, | ||
| 503 | { 0x0, 0x6, 0x44, 0x0, 0x02c00000, 18, 0x02c00000 }, | ||
| 504 | { 0x0, 0x6, 0x45, 0x0, 0x02600000, 15, 0x02600000 }, | ||
| 505 | { 0x0, 0x6, 0x46, 0x0, 0x06000000, 32, 0x06000000 }, | ||
| 506 | { 0x0, 0x6, 0x47, 0x0, 0x24000000, 71, 0x24000000 }, | ||
| 507 | { 0x0, 0x7, 0x00, 0x0, 0x12000000, 0, 0x12000000 }, | ||
| 508 | { 0x0, 0x8, 0x00, 0x0, 0x11000000, 0, 0x11000000 }, | ||
| 509 | { 0x0, 0x9, 0x00, 0x0, 0x10000000, 0, 0x10000000 }, | ||
| 510 | { 0x0, 0xa, 0x00, 0x0, 0x22000000, 0, 0x22000000 } | ||
| 511 | }; | ||
| 512 | |||
| 513 | /* | ||
| 514 | * BPMP NOC aperture lookup table as per file "BPMP_NOC_Structure.info". | ||
| 515 | */ | ||
| 516 | static const char * const tegra194_bpmpnoc_routeid_initflow[] = { | ||
| 517 | [0x0] = "cbb_i/I/0", | ||
| 518 | [0x1] = "cpu_m_i/I/0", | ||
| 519 | [0x2] = "cpu_p_i/I/0", | ||
| 520 | [0x3] = "cvc_i/I/0", | ||
| 521 | [0x4] = "dma_m_i/I/0", | ||
| 522 | [0x5] = "dma_p_i/I/0", | ||
| 523 | [0x6] = "RESERVED", | ||
| 524 | [0x7] = "RESERVED" | ||
| 525 | }; | ||
| 526 | |||
| 527 | static const char * const tegra194_bpmpnoc_routeid_targflow[] = { | ||
| 528 | [0x00] = "multiport0_t/T/actmon", | ||
| 529 | [0x01] = "multiport0_t/T/ast_0", | ||
| 530 | [0x02] = "multiport0_t/T/ast_1", | ||
| 531 | [0x03] = "multiport0_t/T/atcm_cfg", | ||
| 532 | [0x04] = "multiport0_t/T/car", | ||
| 533 | [0x05] = "multiport0_t/T/central_pwr_mgr", | ||
| 534 | [0x06] = "multiport0_t/T/central_vtg_ctlr", | ||
| 535 | [0x07] = "multiport0_t/T/cfg", | ||
| 536 | [0x08] = "multiport0_t/T/dma", | ||
| 537 | [0x09] = "multiport0_t/T/err_collator", | ||
| 538 | [0x0a] = "multiport0_t/T/err_collator_car", | ||
| 539 | [0x0b] = "multiport0_t/T/fpga_misc", | ||
| 540 | [0x0c] = "multiport0_t/T/fpga_uart", | ||
| 541 | [0x0d] = "multiport0_t/T/gte", | ||
| 542 | [0x0e] = "multiport0_t/T/hsp", | ||
| 543 | [0x0f] = "multiport0_t/T/misc", | ||
| 544 | [0x10] = "multiport0_t/T/pm", | ||
| 545 | [0x11] = "multiport0_t/T/simon0", | ||
| 546 | [0x12] = "multiport0_t/T/simon1", | ||
| 547 | [0x13] = "multiport0_t/T/simon2", | ||
| 548 | [0x14] = "multiport0_t/T/simon3", | ||
| 549 | [0x15] = "multiport0_t/T/simon4", | ||
| 550 | [0x16] = "multiport0_t/T/soc_therm", | ||
| 551 | [0x17] = "multiport0_t/T/tke", | ||
| 552 | [0x18] = "multiport0_t/T/vic_0", | ||
| 553 | [0x19] = "multiport0_t/T/vic_1", | ||
| 554 | [0x1a] = "ast0_t/T/0", | ||
| 555 | [0x1b] = "ast1_t/T/0", | ||
| 556 | [0x1c] = "bpmp_noc_firewall/T/0", | ||
| 557 | [0x1d] = "cbb_t/T/0", | ||
| 558 | [0x1e] = "cpu_t/T/0", | ||
| 559 | [0x1f] = "svc_t/T/0" | ||
| 560 | }; | ||
| 561 | |||
| 562 | /* | ||
| 563 | * Fields of BPMP NOC lookup table: | ||
| 564 | * Init flow, Targ flow, Targ subrange, Init mapping, Init localAddress, | ||
| 565 | * Targ mapping, Targ localAddress | ||
| 566 | * ---------------------------------------------------------------------------- | ||
| 567 | */ | ||
| 568 | static const struct tegra194_cbb_aperture tegra194_bpmpnoc_apert_lookup[] = { | ||
| 569 | { 0x0, 0x1c, 0x0, 0x0, 0x0d640000, 0, 0x00000000 }, | ||
| 570 | { 0x0, 0x1e, 0x0, 0x0, 0x0d400000, 0, 0x0d400000 }, | ||
| 571 | { 0x0, 0x00, 0x0, 0x0, 0x0d230000, 0, 0x00000000 }, | ||
| 572 | { 0x0, 0x01, 0x0, 0x0, 0x0d040000, 0, 0x00000000 }, | ||
| 573 | { 0x0, 0x02, 0x0, 0x0, 0x0d050000, 0, 0x00000000 }, | ||
| 574 | { 0x0, 0x03, 0x0, 0x0, 0x0d000000, 0, 0x00000000 }, | ||
| 575 | { 0x0, 0x04, 0x0, 0x0, 0x20ae0000, 3, 0x000e0000 }, | ||
| 576 | { 0x0, 0x04, 0x1, 0x0, 0x20ac0000, 2, 0x000c0000 }, | ||
| 577 | { 0x0, 0x04, 0x2, 0x0, 0x20a80000, 1, 0x00080000 }, | ||
| 578 | { 0x0, 0x04, 0x3, 0x0, 0x20a00000, 0, 0x00000000 }, | ||
| 579 | { 0x0, 0x05, 0x0, 0x0, 0x0d2a0000, 0, 0x00000000 }, | ||
| 580 | { 0x0, 0x06, 0x0, 0x0, 0x0d290000, 0, 0x00000000 }, | ||
| 581 | { 0x0, 0x07, 0x0, 0x0, 0x0d2c0000, 0, 0x00000000 }, | ||
| 582 | { 0x0, 0x08, 0x0, 0x0, 0x0d0e0000, 4, 0x00080000 }, | ||
| 583 | { 0x0, 0x08, 0x1, 0x0, 0x0d060000, 0, 0x00000000 }, | ||
| 584 | { 0x0, 0x08, 0x2, 0x0, 0x0d080000, 1, 0x00020000 }, | ||
| 585 | { 0x0, 0x08, 0x3, 0x0, 0x0d0a0000, 2, 0x00040000 }, | ||
| 586 | { 0x0, 0x08, 0x4, 0x0, 0x0d0c0000, 3, 0x00060000 }, | ||
| 587 | { 0x0, 0x09, 0x0, 0x0, 0x0d650000, 0, 0x00000000 }, | ||
| 588 | { 0x0, 0x0a, 0x0, 0x0, 0x20af0000, 0, 0x00000000 }, | ||
| 589 | { 0x0, 0x0b, 0x0, 0x0, 0x0d3e0000, 0, 0x00000000 }, | ||
| 590 | { 0x0, 0x0c, 0x0, 0x0, 0x0d3d0000, 0, 0x00000000 }, | ||
| 591 | { 0x0, 0x0d, 0x0, 0x0, 0x0d1e0000, 0, 0x00000000 }, | ||
| 592 | { 0x0, 0x0e, 0x0, 0x0, 0x0d150000, 0, 0x00000000 }, | ||
| 593 | { 0x0, 0x0e, 0x1, 0x0, 0x0d160000, 1, 0x00010000 }, | ||
| 594 | { 0x0, 0x0e, 0x2, 0x0, 0x0d170000, 2, 0x00020000 }, | ||
| 595 | { 0x0, 0x0e, 0x3, 0x0, 0x0d180000, 3, 0x00030000 }, | ||
| 596 | { 0x0, 0x0e, 0x4, 0x0, 0x0d190000, 4, 0x00040000 }, | ||
| 597 | { 0x0, 0x0e, 0x5, 0x0, 0x0d1a0000, 5, 0x00050000 }, | ||
| 598 | { 0x0, 0x0e, 0x6, 0x0, 0x0d1b0000, 6, 0x00060000 }, | ||
| 599 | { 0x0, 0x0e, 0x7, 0x0, 0x0d1c0000, 7, 0x00070000 }, | ||
| 600 | { 0x0, 0x0e, 0x8, 0x0, 0x0d1d0000, 8, 0x00080000 }, | ||
| 601 | { 0x0, 0x0f, 0x0, 0x0, 0x0d660000, 0, 0x00000000 }, | ||
| 602 | { 0x0, 0x10, 0x0, 0x0, 0x0d1f0000, 0, 0x00000000 }, | ||
| 603 | { 0x0, 0x10, 0x1, 0x0, 0x0d200000, 1, 0x00010000 }, | ||
| 604 | { 0x0, 0x10, 0x2, 0x0, 0x0d210000, 2, 0x00020000 }, | ||
| 605 | { 0x0, 0x10, 0x3, 0x0, 0x0d220000, 3, 0x00030000 }, | ||
| 606 | { 0x0, 0x11, 0x0, 0x0, 0x0d240000, 0, 0x00000000 }, | ||
| 607 | { 0x0, 0x12, 0x0, 0x0, 0x0d250000, 0, 0x00000000 }, | ||
| 608 | { 0x0, 0x13, 0x0, 0x0, 0x0d260000, 0, 0x00000000 }, | ||
| 609 | { 0x0, 0x14, 0x0, 0x0, 0x0d270000, 0, 0x00000000 }, | ||
| 610 | { 0x0, 0x15, 0x0, 0x0, 0x0d2b0000, 0, 0x00000000 }, | ||
| 611 | { 0x0, 0x16, 0x0, 0x0, 0x0d280000, 0, 0x00000000 }, | ||
| 612 | { 0x0, 0x17, 0x0, 0x0, 0x0d0f0000, 0, 0x00000000 }, | ||
| 613 | { 0x0, 0x17, 0x1, 0x0, 0x0d100000, 1, 0x00010000 }, | ||
| 614 | { 0x0, 0x17, 0x2, 0x0, 0x0d110000, 2, 0x00020000 }, | ||
| 615 | { 0x0, 0x17, 0x3, 0x0, 0x0d120000, 3, 0x00030000 }, | ||
| 616 | { 0x0, 0x17, 0x4, 0x0, 0x0d130000, 4, 0x00040000 }, | ||
| 617 | { 0x0, 0x17, 0x5, 0x0, 0x0d140000, 5, 0x00050000 }, | ||
| 618 | { 0x0, 0x18, 0x0, 0x0, 0x0d020000, 0, 0x00000000 }, | ||
| 619 | { 0x0, 0x19, 0x0, 0x0, 0x0d030000, 0, 0x00000000 }, | ||
| 620 | { 0x0, 0x1f, 0x0, 0x0, 0x0d600000, 0, 0x00000000 }, | ||
| 621 | { 0x0, 0x1f, 0x1, 0x0, 0x00000000, 0, 0x00000000 }, | ||
| 622 | { 0x1, 0x1a, 0x0, 0x0, 0x40000000, 0, 0x40000000 }, | ||
| 623 | { 0x1, 0x1a, 0x1, 0x1, 0x80000000, 1, 0x80000000 }, | ||
| 624 | { 0x1, 0x1a, 0x2, 0x0, 0x00000000, 0, 0x00000000 }, | ||
| 625 | { 0x2, 0x1c, 0x0, 0x0, 0x0d640000, 0, 0x00000000 }, | ||
| 626 | { 0x2, 0x1d, 0x0, 0x0, 0x20b00000, 8, 0x20b00000 }, | ||
| 627 | { 0x2, 0x1d, 0x1, 0x0, 0x20800000, 7, 0x20800000 }, | ||
| 628 | { 0x2, 0x1d, 0x2, 0x0, 0x20c00000, 9, 0x20c00000 }, | ||
| 629 | { 0x2, 0x1d, 0x3, 0x0, 0x0d800000, 3, 0x0d800000 }, | ||
| 630 | { 0x2, 0x1d, 0x4, 0x0, 0x20000000, 6, 0x20000000 }, | ||
| 631 | { 0x2, 0x1d, 0x5, 0x0, 0x0c000000, 2, 0x0c000000 }, | ||
| 632 | { 0x2, 0x1d, 0x6, 0x0, 0x21000000, 10, 0x21000000 }, | ||
| 633 | { 0x2, 0x1d, 0x7, 0x0, 0x0e000000, 4, 0x0e000000 }, | ||
| 634 | { 0x2, 0x1d, 0x8, 0x0, 0x22000000, 11, 0x22000000 }, | ||
| 635 | { 0x2, 0x1d, 0x9, 0x0, 0x08000000, 1, 0x08000000 }, | ||
| 636 | { 0x2, 0x1d, 0xa, 0x0, 0x24000000, 12, 0x24000000 }, | ||
| 637 | { 0x2, 0x1d, 0xb, 0x0, 0x00000000, 0, 0x00000000 }, | ||
| 638 | { 0x2, 0x1d, 0xc, 0x0, 0x28000000, 13, 0x28000000 }, | ||
| 639 | { 0x2, 0x1d, 0xd, 0x0, 0x10000000, 5, 0x10000000 }, | ||
| 640 | { 0x2, 0x1d, 0xe, 0x0, 0x30000000, 14, 0x30000000 }, | ||
| 641 | { 0x2, 0x00, 0x0, 0x0, 0x0d230000, 0, 0x00000000 }, | ||
| 642 | { 0x2, 0x01, 0x0, 0x0, 0x0d040000, 0, 0x00000000 }, | ||
| 643 | { 0x2, 0x02, 0x0, 0x0, 0x0d050000, 0, 0x00000000 }, | ||
| 644 | { 0x2, 0x03, 0x0, 0x0, 0x0d000000, 0, 0x00000000 }, | ||
| 645 | { 0x2, 0x04, 0x0, 0x0, 0x20ae0000, 3, 0x000e0000 }, | ||
| 646 | { 0x2, 0x04, 0x1, 0x0, 0x20ac0000, 2, 0x000c0000 }, | ||
| 647 | { 0x2, 0x04, 0x2, 0x0, 0x20a80000, 1, 0x00080000 }, | ||
| 648 | { 0x2, 0x04, 0x3, 0x0, 0x20a00000, 0, 0x00000000 }, | ||
| 649 | { 0x2, 0x05, 0x0, 0x0, 0x0d2a0000, 0, 0x00000000 }, | ||
| 650 | { 0x2, 0x06, 0x0, 0x0, 0x0d290000, 0, 0x00000000 }, | ||
| 651 | { 0x2, 0x07, 0x0, 0x0, 0x0d2c0000, 0, 0x00000000 }, | ||
| 652 | { 0x2, 0x08, 0x0, 0x0, 0x0d0e0000, 4, 0x00080000 }, | ||
| 653 | { 0x2, 0x08, 0x1, 0x0, 0x0d060000, 0, 0x00000000 }, | ||
| 654 | { 0x2, 0x08, 0x2, 0x0, 0x0d080000, 1, 0x00020000 }, | ||
| 655 | { 0x2, 0x08, 0x3, 0x0, 0x0d0a0000, 2, 0x00040000 }, | ||
| 656 | { 0x2, 0x08, 0x4, 0x0, 0x0d0c0000, 3, 0x00060000 }, | ||
| 657 | { 0x2, 0x09, 0x0, 0x0, 0x0d650000, 0, 0x00000000 }, | ||
| 658 | { 0x2, 0x0a, 0x0, 0x0, 0x20af0000, 0, 0x00000000 }, | ||
| 659 | { 0x2, 0x0b, 0x0, 0x0, 0x0d3e0000, 0, 0x00000000 }, | ||
| 660 | { 0x2, 0x0c, 0x0, 0x0, 0x0d3d0000, 0, 0x00000000 }, | ||
| 661 | { 0x2, 0x0d, 0x0, 0x0, 0x0d1e0000, 0, 0x00000000 }, | ||
| 662 | { 0x2, 0x0e, 0x0, 0x0, 0x0d150000, 0, 0x00000000 }, | ||
| 663 | { 0x2, 0x0e, 0x1, 0x0, 0x0d160000, 1, 0x00010000 }, | ||
| 664 | { 0x2, 0x0e, 0x2, 0x0, 0x0d170000, 2, 0x00020000 }, | ||
| 665 | { 0x2, 0x0e, 0x3, 0x0, 0x0d180000, 3, 0x00030000 }, | ||
| 666 | { 0x2, 0x0e, 0x4, 0x0, 0x0d190000, 4, 0x00040000 }, | ||
| 667 | { 0x2, 0x0e, 0x5, 0x0, 0x0d1a0000, 5, 0x00050000 }, | ||
| 668 | { 0x2, 0x0e, 0x6, 0x0, 0x0d1b0000, 6, 0x00060000 }, | ||
| 669 | { 0x2, 0x0e, 0x7, 0x0, 0x0d1c0000, 7, 0x00070000 }, | ||
| 670 | { 0x2, 0x0e, 0x8, 0x0, 0x0d1d0000, 8, 0x00080000 }, | ||
| 671 | { 0x2, 0x0f, 0x0, 0x0, 0x0d660000, 0, 0x00000000 }, | ||
| 672 | { 0x2, 0x10, 0x0, 0x0, 0x0d1f0000, 0, 0x00000000 }, | ||
| 673 | { 0x2, 0x10, 0x1, 0x0, 0x0d200000, 1, 0x00010000 }, | ||
| 674 | { 0x2, 0x10, 0x2, 0x0, 0x0d210000, 2, 0x00020000 }, | ||
| 675 | { 0x2, 0x10, 0x3, 0x0, 0x0d220000, 3, 0x00030000 }, | ||
| 676 | { 0x2, 0x11, 0x0, 0x0, 0x0d240000, 0, 0x00000000 }, | ||
| 677 | { 0x2, 0x12, 0x0, 0x0, 0x0d250000, 0, 0x00000000 }, | ||
| 678 | { 0x2, 0x13, 0x0, 0x0, 0x0d260000, 0, 0x00000000 }, | ||
| 679 | { 0x2, 0x14, 0x0, 0x0, 0x0d270000, 0, 0x00000000 }, | ||
| 680 | { 0x2, 0x15, 0x0, 0x0, 0x0d2b0000, 0, 0x00000000 }, | ||
| 681 | { 0x2, 0x16, 0x0, 0x0, 0x0d280000, 0, 0x00000000 }, | ||
| 682 | { 0x2, 0x17, 0x0, 0x0, 0x0d0f0000, 0, 0x00000000 }, | ||
| 683 | { 0x2, 0x17, 0x1, 0x0, 0x0d100000, 1, 0x00010000 }, | ||
| 684 | { 0x2, 0x17, 0x2, 0x0, 0x0d110000, 2, 0x00020000 }, | ||
| 685 | { 0x2, 0x17, 0x3, 0x0, 0x0d120000, 3, 0x00030000 }, | ||
| 686 | { 0x2, 0x17, 0x4, 0x0, 0x0d130000, 4, 0x00040000 }, | ||
| 687 | { 0x2, 0x17, 0x5, 0x0, 0x0d140000, 5, 0x00050000 }, | ||
| 688 | { 0x2, 0x18, 0x0, 0x0, 0x0d020000, 0, 0x00000000 }, | ||
| 689 | { 0x2, 0x19, 0x0, 0x0, 0x0d030000, 0, 0x00000000 }, | ||
| 690 | { 0x2, 0x1f, 0x0, 0x0, 0x0d600000, 0, 0x00000000 }, | ||
| 691 | { 0x2, 0x1f, 0x1, 0x0, 0x00000000, 0, 0x00000000 }, | ||
| 692 | { 0x3, 0x1b, 0x0, 0x0, 0x40000000, 0, 0x40000000 }, | ||
| 693 | { 0x3, 0x1b, 0x1, 0x1, 0x80000000, 1, 0x80000000 }, | ||
| 694 | { 0x3, 0x1c, 0x0, 0x2, 0x0d640000, 0, 0x00000000 }, | ||
| 695 | { 0x3, 0x1d, 0x0, 0x2, 0x20b00000, 8, 0x20b00000 }, | ||
| 696 | { 0x3, 0x1d, 0x1, 0x2, 0x20800000, 7, 0x20800000 }, | ||
| 697 | { 0x3, 0x1d, 0x2, 0x2, 0x20c00000, 9, 0x20c00000 }, | ||
| 698 | { 0x3, 0x1d, 0x3, 0x2, 0x0d800000, 3, 0x0d800000 }, | ||
| 699 | { 0x3, 0x1d, 0x4, 0x2, 0x20000000, 6, 0x20000000 }, | ||
| 700 | { 0x3, 0x1d, 0x5, 0x2, 0x0c000000, 2, 0x0c000000 }, | ||
| 701 | { 0x3, 0x1d, 0x6, 0x2, 0x21000000, 10, 0x21000000 }, | ||
| 702 | { 0x3, 0x1d, 0x7, 0x2, 0x0e000000, 4, 0x0e000000 }, | ||
| 703 | { 0x3, 0x1d, 0x8, 0x2, 0x22000000, 11, 0x22000000 }, | ||
| 704 | { 0x3, 0x1d, 0x9, 0x2, 0x08000000, 1, 0x08000000 }, | ||
| 705 | { 0x3, 0x1d, 0xa, 0x2, 0x24000000, 12, 0x24000000 }, | ||
| 706 | { 0x3, 0x1d, 0xb, 0x2, 0x00000000, 0, 0x00000000 }, | ||
| 707 | { 0x3, 0x1d, 0xc, 0x2, 0x28000000, 13, 0x28000000 }, | ||
| 708 | { 0x3, 0x1d, 0xd, 0x2, 0x10000000, 5, 0x10000000 }, | ||
| 709 | { 0x3, 0x1d, 0xe, 0x2, 0x30000000, 14, 0x30000000 }, | ||
| 710 | { 0x3, 0x1e, 0x0, 0x2, 0x0d400000, 0, 0x0d400000 }, | ||
| 711 | { 0x3, 0x00, 0x0, 0x2, 0x0d230000, 0, 0x00000000 }, | ||
| 712 | { 0x3, 0x01, 0x0, 0x2, 0x0d040000, 0, 0x00000000 }, | ||
| 713 | { 0x3, 0x02, 0x0, 0x2, 0x0d050000, 0, 0x00000000 }, | ||
| 714 | { 0x3, 0x03, 0x0, 0x2, 0x0d000000, 0, 0x00000000 }, | ||
| 715 | { 0x3, 0x04, 0x0, 0x2, 0x20ae0000, 3, 0x000e0000 }, | ||
| 716 | { 0x3, 0x04, 0x1, 0x2, 0x20ac0000, 2, 0x000c0000 }, | ||
| 717 | { 0x3, 0x04, 0x2, 0x2, 0x20a80000, 1, 0x00080000 }, | ||
| 718 | { 0x3, 0x04, 0x3, 0x2, 0x20a00000, 0, 0x00000000 }, | ||
| 719 | { 0x3, 0x05, 0x0, 0x2, 0x0d2a0000, 0, 0x00000000 }, | ||
| 720 | { 0x3, 0x06, 0x0, 0x2, 0x0d290000, 0, 0x00000000 }, | ||
| 721 | { 0x3, 0x07, 0x0, 0x2, 0x0d2c0000, 0, 0x00000000 }, | ||
| 722 | { 0x3, 0x08, 0x0, 0x2, 0x0d0e0000, 4, 0x00080000 }, | ||
| 723 | { 0x3, 0x08, 0x1, 0x2, 0x0d060000, 0, 0x00000000 }, | ||
| 724 | { 0x3, 0x08, 0x2, 0x2, 0x0d080000, 1, 0x00020000 }, | ||
| 725 | { 0x3, 0x08, 0x3, 0x2, 0x0d0a0000, 2, 0x00040000 }, | ||
| 726 | { 0x3, 0x08, 0x4, 0x2, 0x0d0c0000, 3, 0x00060000 }, | ||
| 727 | { 0x3, 0x09, 0x0, 0x2, 0x0d650000, 0, 0x00000000 }, | ||
| 728 | { 0x3, 0x0a, 0x0, 0x2, 0x20af0000, 0, 0x00000000 }, | ||
| 729 | { 0x3, 0x0b, 0x0, 0x2, 0x0d3e0000, 0, 0x00000000 }, | ||
| 730 | { 0x3, 0x0c, 0x0, 0x2, 0x0d3d0000, 0, 0x00000000 }, | ||
| 731 | { 0x3, 0x0d, 0x0, 0x2, 0x0d1e0000, 0, 0x00000000 }, | ||
| 732 | { 0x3, 0x0e, 0x0, 0x2, 0x0d150000, 0, 0x00000000 }, | ||
| 733 | { 0x3, 0x0e, 0x1, 0x2, 0x0d160000, 1, 0x00010000 }, | ||
| 734 | { 0x3, 0x0e, 0x2, 0x2, 0x0d170000, 2, 0x00020000 }, | ||
| 735 | { 0x3, 0x0e, 0x3, 0x2, 0x0d180000, 3, 0x00030000 }, | ||
| 736 | { 0x3, 0x0e, 0x4, 0x2, 0x0d190000, 4, 0x00040000 }, | ||
| 737 | { 0x3, 0x0e, 0x5, 0x2, 0x0d1a0000, 5, 0x00050000 }, | ||
| 738 | { 0x3, 0x0e, 0x6, 0x2, 0x0d1b0000, 6, 0x00060000 }, | ||
| 739 | { 0x3, 0x0e, 0x7, 0x2, 0x0d1c0000, 7, 0x00070000 }, | ||
| 740 | { 0x3, 0x0e, 0x8, 0x2, 0x0d1d0000, 8, 0x00080000 }, | ||
| 741 | { 0x3, 0x0f, 0x0, 0x2, 0x0d660000, 0, 0x00000000 }, | ||
| 742 | { 0x3, 0x10, 0x0, 0x2, 0x0d1f0000, 0, 0x00000000 }, | ||
| 743 | { 0x3, 0x10, 0x1, 0x2, 0x0d200000, 1, 0x00010000 }, | ||
| 744 | { 0x3, 0x10, 0x2, 0x2, 0x0d210000, 2, 0x00020000 }, | ||
| 745 | { 0x3, 0x10, 0x3, 0x2, 0x0d220000, 3, 0x00030000 }, | ||
| 746 | { 0x3, 0x11, 0x0, 0x2, 0x0d240000, 0, 0x00000000 }, | ||
| 747 | { 0x3, 0x12, 0x0, 0x2, 0x0d250000, 0, 0x00000000 }, | ||
| 748 | { 0x3, 0x13, 0x0, 0x2, 0x0d260000, 0, 0x00000000 }, | ||
| 749 | { 0x3, 0x14, 0x0, 0x2, 0x0d270000, 0, 0x00000000 }, | ||
| 750 | { 0x3, 0x15, 0x0, 0x2, 0x0d2b0000, 0, 0x00000000 }, | ||
| 751 | { 0x3, 0x16, 0x0, 0x2, 0x0d280000, 0, 0x00000000 }, | ||
| 752 | { 0x3, 0x17, 0x0, 0x2, 0x0d0f0000, 0, 0x00000000 }, | ||
| 753 | { 0x3, 0x17, 0x1, 0x2, 0x0d100000, 1, 0x00010000 }, | ||
| 754 | { 0x3, 0x17, 0x2, 0x2, 0x0d110000, 2, 0x00020000 }, | ||
| 755 | { 0x3, 0x17, 0x3, 0x2, 0x0d120000, 3, 0x00030000 }, | ||
| 756 | { 0x3, 0x17, 0x4, 0x2, 0x0d130000, 4, 0x00040000 }, | ||
| 757 | { 0x3, 0x17, 0x5, 0x2, 0x0d140000, 5, 0x00050000 }, | ||
| 758 | { 0x3, 0x18, 0x0, 0x2, 0x0d020000, 0, 0x00000000 }, | ||
| 759 | { 0x3, 0x19, 0x0, 0x2, 0x0d030000, 0, 0x00000000 }, | ||
| 760 | { 0x3, 0x1f, 0x0, 0x2, 0x0d600000, 0, 0x00000000 }, | ||
| 761 | { 0x3, 0x1f, 0x1, 0x0, 0x00000000, 0, 0x00000000 }, | ||
| 762 | { 0x4, 0x1b, 0x0, 0x0, 0x40000000, 0, 0x40000000 }, | ||
| 763 | { 0x4, 0x1b, 0x1, 0x1, 0x80000000, 1, 0x80000000 }, | ||
| 764 | { 0x4, 0x1e, 0x0, 0x2, 0x0d400000, 0, 0x0d400000 }, | ||
| 765 | { 0x4, 0x1e, 0x1, 0x0, 0x00000000, 0, 0x00000000 }, | ||
| 766 | { 0x5, 0x1c, 0x0, 0x0, 0x0d640000, 0, 0x00000000 }, | ||
| 767 | { 0x5, 0x1d, 0x0, 0x0, 0x20b00000, 8, 0x20b00000 }, | ||
| 768 | { 0x5, 0x1d, 0x1, 0x0, 0x20800000, 7, 0x20800000 }, | ||
| 769 | { 0x5, 0x1d, 0x2, 0x0, 0x20c00000, 9, 0x20c00000 }, | ||
| 770 | { 0x5, 0x1d, 0x3, 0x0, 0x0d800000, 3, 0x0d800000 }, | ||
| 771 | { 0x5, 0x1d, 0x4, 0x0, 0x20000000, 6, 0x20000000 }, | ||
| 772 | { 0x5, 0x1d, 0x5, 0x0, 0x0c000000, 2, 0x0c000000 }, | ||
| 773 | { 0x5, 0x1d, 0x6, 0x0, 0x21000000, 10, 0x21000000 }, | ||
| 774 | { 0x5, 0x1d, 0x7, 0x0, 0x0e000000, 4, 0x0e000000 }, | ||
| 775 | { 0x5, 0x1d, 0x8, 0x0, 0x22000000, 11, 0x22000000 }, | ||
| 776 | { 0x5, 0x1d, 0x9, 0x0, 0x08000000, 1, 0x08000000 }, | ||
| 777 | { 0x5, 0x1d, 0xa, 0x0, 0x24000000, 12, 0x24000000 }, | ||
| 778 | { 0x5, 0x1d, 0xb, 0x0, 0x00000000, 0, 0x00000000 }, | ||
| 779 | { 0x5, 0x1d, 0xc, 0x0, 0x28000000, 13, 0x28000000 }, | ||
| 780 | { 0x5, 0x1d, 0xd, 0x0, 0x10000000, 5, 0x10000000 }, | ||
| 781 | { 0x5, 0x1d, 0xe, 0x0, 0x30000000, 14, 0x30000000 }, | ||
| 782 | { 0x5, 0x00, 0x0, 0x0, 0x0d230000, 0, 0x00000000 }, | ||
| 783 | { 0x5, 0x01, 0x0, 0x0, 0x0d040000, 0, 0x00000000 }, | ||
| 784 | { 0x5, 0x02, 0x0, 0x0, 0x0d050000, 0, 0x00000000 }, | ||
| 785 | { 0x5, 0x03, 0x0, 0x0, 0x0d000000, 0, 0x00000000 }, | ||
| 786 | { 0x5, 0x04, 0x0, 0x0, 0x20ae0000, 3, 0x000e0000 }, | ||
| 787 | { 0x5, 0x04, 0x1, 0x0, 0x20ac0000, 2, 0x000c0000 }, | ||
| 788 | { 0x5, 0x04, 0x2, 0x0, 0x20a80000, 1, 0x00080000 }, | ||
| 789 | { 0x5, 0x04, 0x3, 0x0, 0x20a00000, 0, 0x00000000 }, | ||
| 790 | { 0x5, 0x05, 0x0, 0x0, 0x0d2a0000, 0, 0x00000000 }, | ||
| 791 | { 0x5, 0x06, 0x0, 0x0, 0x0d290000, 0, 0x00000000 }, | ||
| 792 | { 0x5, 0x07, 0x0, 0x0, 0x0d2c0000, 0, 0x00000000 }, | ||
| 793 | { 0x5, 0x08, 0x0, 0x0, 0x0d0e0000, 4, 0x00080000 }, | ||
| 794 | { 0x5, 0x08, 0x1, 0x0, 0x0d060000, 0, 0x00000000 }, | ||
| 795 | { 0x5, 0x08, 0x2, 0x0, 0x0d080000, 1, 0x00020000 }, | ||
| 796 | { 0x5, 0x08, 0x3, 0x0, 0x0d0a0000, 2, 0x00040000 }, | ||
| 797 | { 0x5, 0x08, 0x4, 0x0, 0x0d0c0000, 3, 0x00060000 }, | ||
| 798 | { 0x5, 0x09, 0x0, 0x0, 0x0d650000, 0, 0x00000000 }, | ||
| 799 | { 0x5, 0x0a, 0x0, 0x0, 0x20af0000, 0, 0x00000000 }, | ||
| 800 | { 0x5, 0x0b, 0x0, 0x0, 0x0d3e0000, 0, 0x00000000 }, | ||
| 801 | { 0x5, 0x0c, 0x0, 0x0, 0x0d3d0000, 0, 0x00000000 }, | ||
| 802 | { 0x5, 0x0d, 0x0, 0x0, 0x0d1e0000, 0, 0x00000000 }, | ||
| 803 | { 0x5, 0x0e, 0x0, 0x0, 0x0d150000, 0, 0x00000000 }, | ||
| 804 | { 0x5, 0x0e, 0x1, 0x0, 0x0d160000, 1, 0x00010000 }, | ||
| 805 | { 0x5, 0x0e, 0x2, 0x0, 0x0d170000, 2, 0x00020000 }, | ||
| 806 | { 0x5, 0x0e, 0x3, 0x0, 0x0d180000, 3, 0x00030000 }, | ||
| 807 | { 0x5, 0x0e, 0x4, 0x0, 0x0d190000, 4, 0x00040000 }, | ||
| 808 | { 0x5, 0x0e, 0x5, 0x0, 0x0d1a0000, 5, 0x00050000 }, | ||
| 809 | { 0x5, 0x0e, 0x6, 0x0, 0x0d1b0000, 6, 0x00060000 }, | ||
| 810 | { 0x5, 0x0e, 0x7, 0x0, 0x0d1c0000, 7, 0x00070000 }, | ||
| 811 | { 0x5, 0x0e, 0x8, 0x0, 0x0d1d0000, 8, 0x00080000 }, | ||
| 812 | { 0x5, 0x0f, 0x0, 0x0, 0x0d660000, 0, 0x00000000 }, | ||
| 813 | { 0x5, 0x10, 0x0, 0x0, 0x0d1f0000, 0, 0x00000000 }, | ||
| 814 | { 0x5, 0x10, 0x1, 0x0, 0x0d200000, 1, 0x00010000 }, | ||
| 815 | { 0x5, 0x10, 0x2, 0x0, 0x0d210000, 2, 0x00020000 }, | ||
| 816 | { 0x5, 0x10, 0x3, 0x0, 0x0d220000, 3, 0x00030000 }, | ||
| 817 | { 0x5, 0x11, 0x0, 0x0, 0x0d240000, 0, 0x00000000 }, | ||
| 818 | { 0x5, 0x12, 0x0, 0x0, 0x0d250000, 0, 0x00000000 }, | ||
| 819 | { 0x5, 0x13, 0x0, 0x0, 0x0d260000, 0, 0x00000000 }, | ||
| 820 | { 0x5, 0x14, 0x0, 0x0, 0x0d270000, 0, 0x00000000 }, | ||
| 821 | { 0x5, 0x15, 0x0, 0x0, 0x0d2b0000, 0, 0x00000000 }, | ||
| 822 | { 0x5, 0x16, 0x0, 0x0, 0x0d280000, 0, 0x00000000 }, | ||
| 823 | { 0x5, 0x17, 0x0, 0x0, 0x0d0f0000, 0, 0x00000000 }, | ||
| 824 | { 0x5, 0x17, 0x1, 0x0, 0x0d100000, 1, 0x00010000 }, | ||
| 825 | { 0x5, 0x17, 0x2, 0x0, 0x0d110000, 2, 0x00020000 }, | ||
| 826 | { 0x5, 0x17, 0x3, 0x0, 0x0d120000, 3, 0x00030000 }, | ||
| 827 | { 0x5, 0x17, 0x4, 0x0, 0x0d130000, 4, 0x00040000 }, | ||
| 828 | { 0x5, 0x17, 0x5, 0x0, 0x0d140000, 5, 0x00050000 }, | ||
| 829 | { 0x5, 0x18, 0x0, 0x0, 0x0d020000, 0, 0x00000000 }, | ||
| 830 | { 0x5, 0x19, 0x0, 0x0, 0x0d030000, 0, 0x00000000 }, | ||
| 831 | { 0x5, 0x1f, 0x0, 0x0, 0x0d600000, 0, 0x00000000 }, | ||
| 832 | { 0x5, 0x1f, 0x1, 0x0, 0x00000000, 0, 0x00000000 } | ||
| 833 | }; | ||
| 834 | |||
| 835 | /* | ||
| 836 | * AON NOC aperture lookup table as per file "AON_NOC_Structure.info". | ||
| 837 | */ | ||
| 838 | static const char * const tegra194_aonnoc_routeid_initflow[] = { | ||
| 839 | [0x0] = "cbb_i/I/0", | ||
| 840 | [0x1] = "cpu_p_i/I/0", | ||
| 841 | [0x2] = "dma_m_i/I/0", | ||
| 842 | [0x3] = "dma_p_i/I/0" | ||
| 843 | }; | ||
| 844 | |||
| 845 | static const char * const tegra194_aonnoc_routeid_targflow[] = { | ||
| 846 | [0x00] = "multiport1_t/T/aon_misc", | ||
| 847 | [0x01] = "multiport1_t/T/avic0", | ||
| 848 | [0x02] = "multiport1_t/T/avic1", | ||
| 849 | [0x03] = "multiport1_t/T/can1", | ||
| 850 | [0x04] = "multiport1_t/T/can2", | ||
| 851 | [0x05] = "multiport1_t/T/dma", | ||
| 852 | [0x06] = "multiport1_t/T/dmic", | ||
| 853 | [0x07] = "multiport1_t/T/err_collator", | ||
| 854 | [0x08] = "multiport1_t/T/fpga_misc", | ||
| 855 | [0x09] = "multiport1_t/T/gte", | ||
| 856 | [0x0a] = "multiport1_t/T/hsp", | ||
| 857 | [0x0b] = "multiport1_t/T/i2c2", | ||
| 858 | [0x0c] = "multiport1_t/T/i2c8", | ||
| 859 | [0x0d] = "multiport1_t/T/pwm", | ||
| 860 | [0x0e] = "multiport1_t/T/spi2", | ||
| 861 | [0x0f] = "multiport1_t/T/tke", | ||
| 862 | [0x10] = "multiport1_t/T/uartg", | ||
| 863 | [0x11] = "RESERVED", | ||
| 864 | [0x12] = "RESERVED", | ||
| 865 | [0x13] = "RESERVED", | ||
| 866 | [0x14] = "RESERVED", | ||
| 867 | [0x15] = "RESERVED", | ||
| 868 | [0x16] = "RESERVED", | ||
| 869 | [0x17] = "RESERVED", | ||
| 870 | [0x18] = "RESERVED", | ||
| 871 | [0x19] = "RESERVED", | ||
| 872 | [0x1a] = "RESERVED", | ||
| 873 | [0x1b] = "RESERVED", | ||
| 874 | [0x1c] = "RESERVED", | ||
| 875 | [0x1d] = "RESERVED", | ||
| 876 | [0x1e] = "RESERVED", | ||
| 877 | [0x1f] = "RESERVED", | ||
| 878 | [0x20] = "multiport0_t/T/aovc", | ||
| 879 | [0x21] = "multiport0_t/T/atcm", | ||
| 880 | [0x22] = "multiport0_t/T/cast", | ||
| 881 | [0x23] = "multiport0_t/T/dast", | ||
| 882 | [0x24] = "multiport0_t/T/err_collator_car", | ||
| 883 | [0x25] = "multiport0_t/T/gpio", | ||
| 884 | [0x26] = "multiport0_t/T/i2c10", | ||
| 885 | [0x27] = "multiport0_t/T/mss", | ||
| 886 | [0x28] = "multiport0_t/T/padctl_a12", | ||
| 887 | [0x29] = "multiport0_t/T/padctl_a14", | ||
| 888 | [0x2a] = "multiport0_t/T/padctl_a15", | ||
| 889 | [0x2b] = "multiport0_t/T/rtc", | ||
| 890 | [0x2c] = "multiport0_t/T/tsc", | ||
| 891 | [0x2d] = "RESERVED", | ||
| 892 | [0x2e] = "RESERVED", | ||
| 893 | [0x2f] = "RESERVED", | ||
| 894 | [0x30] = "multiport2_t/T/aon_vref_ro", | ||
| 895 | [0x31] = "multiport2_t/T/aopm", | ||
| 896 | [0x32] = "multiport2_t/T/car", | ||
| 897 | [0x33] = "multiport2_t/T/pmc", | ||
| 898 | [0x34] = "ast1_t/T/0", | ||
| 899 | [0x35] = "cbb_t/T/0", | ||
| 900 | [0x36] = "cpu_t/T/0", | ||
| 901 | [0x37] = "firewall_t/T/0", | ||
| 902 | [0x38] = "svc_t/T/0", | ||
| 903 | [0x39] = "uartc/T/uartc", | ||
| 904 | [0x3a] = "RESERVED", | ||
| 905 | [0x3b] = "RESERVED", | ||
| 906 | [0x3c] = "RESERVED", | ||
| 907 | [0x3d] = "RESERVED", | ||
| 908 | [0x3e] = "RESERVED", | ||
| 909 | [0x3f] = "RESERVED" | ||
| 910 | }; | ||
| 911 | |||
| 912 | /* | ||
| 913 | * Fields of AON NOC lookup table: | ||
| 914 | * Init flow, Targ flow, Targ subrange, Init mapping, Init localAddress, | ||
| 915 | * Targ mapping, Targ localAddress | ||
| 916 | * ---------------------------------------------------------------------------- | ||
| 917 | */ | ||
| 918 | static const struct tegra194_cbb_aperture tegra194_aonnoc_aperture_lookup[] = { | ||
| 919 | { 0x0, 0x37, 0x00, 0, 0x0c640000, 0, 0x00000000 }, | ||
| 920 | { 0x0, 0x20, 0x00, 0, 0x0c3b0000, 0, 0x00000000 }, | ||
| 921 | { 0x0, 0x21, 0x00, 0, 0x0c000000, 0, 0x00000000 }, | ||
| 922 | { 0x0, 0x22, 0x00, 0, 0x0c040000, 0, 0x00000000 }, | ||
| 923 | { 0x0, 0x23, 0x00, 0, 0x0c050000, 0, 0x00000000 }, | ||
| 924 | { 0x0, 0x24, 0x00, 0, 0x20cf0000, 0, 0x00000000 }, | ||
| 925 | { 0x0, 0x25, 0x00, 0, 0x0c2f0000, 0, 0x00000000 }, | ||
| 926 | { 0x0, 0x26, 0x00, 0, 0x0c230000, 0, 0x00000000 }, | ||
| 927 | { 0x0, 0x27, 0x00, 0, 0x0c350000, 0, 0x00000000 }, | ||
| 928 | { 0x0, 0x28, 0x00, 0, 0x0c301000, 0, 0x00000000 }, | ||
| 929 | { 0x0, 0x29, 0x00, 0, 0x0c302000, 0, 0x00000000 }, | ||
| 930 | { 0x0, 0x2a, 0x00, 0, 0x0c303000, 0, 0x00000000 }, | ||
| 931 | { 0x0, 0x2b, 0x00, 0, 0x0c2a0000, 0, 0x00000000 }, | ||
| 932 | { 0x0, 0x2c, 0x00, 0, 0x0c2b0000, 0, 0x00000000 }, | ||
| 933 | { 0x0, 0x2c, 0x01, 0, 0x0c2c0000, 1, 0x00010000 }, | ||
| 934 | { 0x0, 0x2c, 0x02, 0, 0x0c2d0000, 2, 0x00020000 }, | ||
| 935 | { 0x0, 0x2c, 0x03, 0, 0x0c2e0000, 3, 0x00030000 }, | ||
| 936 | { 0x0, 0x00, 0x00, 0, 0x0c660000, 0, 0x00000000 }, | ||
| 937 | { 0x0, 0x01, 0x00, 0, 0x0c020000, 0, 0x00000000 }, | ||
| 938 | { 0x0, 0x02, 0x00, 0, 0x0c030000, 0, 0x00000000 }, | ||
| 939 | { 0x0, 0x03, 0x00, 0, 0x0c310000, 0, 0x00000000 }, | ||
| 940 | { 0x0, 0x04, 0x00, 0, 0x0c320000, 0, 0x00000000 }, | ||
| 941 | { 0x0, 0x05, 0x00, 0, 0x0c0a0000, 2, 0x00040000 }, | ||
| 942 | { 0x0, 0x05, 0x01, 0, 0x0c0b0000, 3, 0x00050000 }, | ||
| 943 | { 0x0, 0x05, 0x02, 0, 0x0c0e0000, 5, 0x00080000 }, | ||
| 944 | { 0x0, 0x05, 0x03, 0, 0x0c060000, 0, 0x00000000 }, | ||
| 945 | { 0x0, 0x05, 0x04, 0, 0x0c080000, 1, 0x00020000 }, | ||
| 946 | { 0x0, 0x05, 0x05, 0, 0x0c0c0000, 4, 0x00060000 }, | ||
| 947 | { 0x0, 0x06, 0x00, 0, 0x0c330000, 0, 0x00000000 }, | ||
| 948 | { 0x0, 0x07, 0x00, 0, 0x0c650000, 0, 0x00000000 }, | ||
| 949 | { 0x0, 0x08, 0x00, 0, 0x0c3e0000, 0, 0x00000000 }, | ||
| 950 | { 0x0, 0x09, 0x00, 0, 0x0c1e0000, 0, 0x00000000 }, | ||
| 951 | { 0x0, 0x0a, 0x00, 0, 0x0c150000, 0, 0x00000000 }, | ||
| 952 | { 0x0, 0x0a, 0x01, 0, 0x0c160000, 1, 0x00010000 }, | ||
| 953 | { 0x0, 0x0a, 0x02, 0, 0x0c170000, 2, 0x00020000 }, | ||
| 954 | { 0x0, 0x0a, 0x03, 0, 0x0c180000, 3, 0x00030000 }, | ||
| 955 | { 0x0, 0x0a, 0x04, 0, 0x0c190000, 4, 0x00040000 }, | ||
| 956 | { 0x0, 0x0a, 0x05, 0, 0x0c1a0000, 5, 0x00050000 }, | ||
| 957 | { 0x0, 0x0a, 0x06, 0, 0x0c1b0000, 6, 0x00060000 }, | ||
| 958 | { 0x0, 0x0a, 0x07, 0, 0x0c1c0000, 7, 0x00070000 }, | ||
| 959 | { 0x0, 0x0a, 0x08, 0, 0x0c1d0000, 8, 0x00080000 }, | ||
| 960 | { 0x0, 0x0b, 0x00, 0, 0x0c240000, 0, 0x00000000 }, | ||
| 961 | { 0x0, 0x0c, 0x00, 0, 0x0c250000, 0, 0x00000000 }, | ||
| 962 | { 0x0, 0x0d, 0x00, 0, 0x0c340000, 0, 0x00000000 }, | ||
| 963 | { 0x0, 0x0e, 0x00, 0, 0x0c260000, 0, 0x00000000 }, | ||
| 964 | { 0x0, 0x0f, 0x00, 0, 0x0c0f0000, 0, 0x00000000 }, | ||
| 965 | { 0x0, 0x0f, 0x01, 0, 0x0c100000, 1, 0x00010000 }, | ||
| 966 | { 0x0, 0x0f, 0x02, 0, 0x0c110000, 2, 0x00020000 }, | ||
| 967 | { 0x0, 0x0f, 0x03, 0, 0x0c120000, 3, 0x00030000 }, | ||
| 968 | { 0x0, 0x0f, 0x04, 0, 0x0c130000, 4, 0x00040000 }, | ||
| 969 | { 0x0, 0x0f, 0x05, 0, 0x0c140000, 5, 0x00050000 }, | ||
| 970 | { 0x0, 0x10, 0x00, 0, 0x0c290000, 0, 0x00000000 }, | ||
| 971 | { 0x0, 0x30, 0x00, 0, 0x20ce0000, 0, 0x00000000 }, | ||
| 972 | { 0x0, 0x31, 0x00, 0, 0x0c1f0000, 0, 0x00000000 }, | ||
| 973 | { 0x0, 0x31, 0x01, 0, 0x0c200000, 1, 0x00010000 }, | ||
| 974 | { 0x0, 0x31, 0x02, 0, 0x0c210000, 2, 0x00020000 }, | ||
| 975 | { 0x0, 0x31, 0x03, 0, 0x0c220000, 3, 0x00030000 }, | ||
| 976 | { 0x0, 0x32, 0x00, 0, 0x20cc0000, 3, 0x001c0000 }, | ||
| 977 | { 0x0, 0x32, 0x01, 0, 0x20c80000, 2, 0x00180000 }, | ||
| 978 | { 0x0, 0x32, 0x02, 0, 0x20c00000, 1, 0x00100000 }, | ||
| 979 | { 0x0, 0x32, 0x03, 0, 0x20b00000, 0, 0x00000000 }, | ||
| 980 | { 0x0, 0x33, 0x00, 0, 0x0c360000, 0, 0x00000000 }, | ||
| 981 | { 0x0, 0x33, 0x01, 0, 0x0c370000, 1, 0x00010000 }, | ||
| 982 | { 0x0, 0x33, 0x02, 0, 0x0c3a0000, 3, 0x00040000 }, | ||
| 983 | { 0x0, 0x33, 0x03, 0, 0x0c380000, 2, 0x00020000 }, | ||
| 984 | { 0x0, 0x38, 0x00, 0, 0x0c600000, 0, 0x00000000 }, | ||
| 985 | { 0x0, 0x38, 0x01, 0, 0x00000000, 0, 0x00000000 }, | ||
| 986 | { 0x0, 0x39, 0x00, 0, 0x0c280000, 0, 0x00000000 }, | ||
| 987 | { 0x1, 0x35, 0x00, 0, 0x00000000, 0, 0x00000000 }, | ||
| 988 | { 0x1, 0x35, 0x01, 0, 0x00100000, 1, 0x00100000 }, | ||
| 989 | { 0x1, 0x35, 0x02, 0, 0x05a00000, 11, 0x05a00000 }, | ||
| 990 | { 0x1, 0x35, 0x03, 0, 0x05b00000, 32, 0x05b00000 }, | ||
| 991 | { 0x1, 0x35, 0x04, 0, 0x05c00000, 33, 0x05c00000 }, | ||
| 992 | { 0x1, 0x35, 0x05, 0, 0x05d00000, 12, 0x05d00000 }, | ||
| 993 | { 0x1, 0x35, 0x06, 0, 0x20000000, 19, 0x20000000 }, | ||
| 994 | { 0x1, 0x35, 0x07, 0, 0x20100000, 20, 0x20100000 }, | ||
| 995 | { 0x1, 0x35, 0x08, 0, 0x20a00000, 24, 0x20a00000 }, | ||
| 996 | { 0x1, 0x35, 0x09, 0, 0x20d00000, 25, 0x20d00000 }, | ||
| 997 | { 0x1, 0x35, 0x0a, 0, 0x00200000, 2, 0x00200000 }, | ||
| 998 | { 0x1, 0x35, 0x0b, 0, 0x05800000, 10, 0x05800000 }, | ||
| 999 | { 0x1, 0x35, 0x0c, 0, 0x05e00000, 13, 0x05e00000 }, | ||
| 1000 | { 0x1, 0x35, 0x0d, 0, 0x20200000, 21, 0x20200000 }, | ||
| 1001 | { 0x1, 0x35, 0x0e, 0, 0x20800000, 23, 0x20800000 }, | ||
| 1002 | { 0x1, 0x35, 0x0f, 0, 0x20e00000, 26, 0x20e00000 }, | ||
| 1003 | { 0x1, 0x35, 0x10, 0, 0x00400000, 3, 0x00400000 }, | ||
| 1004 | { 0x1, 0x35, 0x11, 0, 0x20400000, 22, 0x20400000 }, | ||
| 1005 | { 0x1, 0x35, 0x12, 0, 0x00800000, 4, 0x00800000 }, | ||
| 1006 | { 0x1, 0x35, 0x13, 0, 0x05000000, 9, 0x05000000 }, | ||
| 1007 | { 0x1, 0x35, 0x14, 0, 0x0c800000, 34, 0x0c800000 }, | ||
| 1008 | { 0x1, 0x35, 0x15, 0, 0x01000000, 5, 0x01000000 }, | ||
| 1009 | { 0x1, 0x35, 0x16, 0, 0x03000000, 7, 0x03000000 }, | ||
| 1010 | { 0x1, 0x35, 0x17, 0, 0x04000000, 8, 0x04000000 }, | ||
| 1011 | { 0x1, 0x35, 0x18, 0, 0x0d000000, 16, 0x0d000000 }, | ||
| 1012 | { 0x1, 0x35, 0x19, 0, 0x21000000, 27, 0x21000000 }, | ||
| 1013 | { 0x1, 0x35, 0x1a, 0, 0x02000000, 6, 0x02000000 }, | ||
| 1014 | { 0x1, 0x35, 0x1b, 0, 0x06000000, 14, 0x06000000 }, | ||
| 1015 | { 0x1, 0x35, 0x1c, 0, 0x0e000000, 17, 0x0e000000 }, | ||
| 1016 | { 0x1, 0x35, 0x1d, 0, 0x22000000, 28, 0x22000000 }, | ||
| 1017 | { 0x1, 0x35, 0x1e, 0, 0x08000000, 15, 0x08000000 }, | ||
| 1018 | { 0x1, 0x35, 0x1f, 0, 0x24000000, 29, 0x24000000 }, | ||
| 1019 | { 0x1, 0x35, 0x20, 0, 0x28000000, 30, 0x28000000 }, | ||
| 1020 | { 0x1, 0x35, 0x21, 0, 0x10000000, 18, 0x10000000 }, | ||
| 1021 | { 0x1, 0x35, 0x22, 0, 0x30000000, 31, 0x30000000 }, | ||
| 1022 | { 0x1, 0x37, 0x00, 0, 0x0c640000, 0, 0x00000000 }, | ||
| 1023 | { 0x1, 0x20, 0x00, 0, 0x0c3b0000, 0, 0x00000000 }, | ||
| 1024 | { 0x1, 0x21, 0x00, 0, 0x0c000000, 0, 0x00000000 }, | ||
| 1025 | { 0x1, 0x22, 0x00, 0, 0x0c040000, 0, 0x00000000 }, | ||
| 1026 | { 0x1, 0x23, 0x00, 0, 0x0c050000, 0, 0x00000000 }, | ||
| 1027 | { 0x1, 0x24, 0x00, 0, 0x20cf0000, 0, 0x00000000 }, | ||
| 1028 | { 0x1, 0x25, 0x00, 0, 0x0c2f0000, 0, 0x00000000 }, | ||
| 1029 | { 0x1, 0x26, 0x00, 0, 0x0c230000, 0, 0x00000000 }, | ||
| 1030 | { 0x1, 0x27, 0x00, 0, 0x0c350000, 0, 0x00000000 }, | ||
| 1031 | { 0x1, 0x28, 0x00, 0, 0x0c301000, 0, 0x00000000 }, | ||
| 1032 | { 0x1, 0x29, 0x00, 0, 0x0c302000, 0, 0x00000000 }, | ||
| 1033 | { 0x1, 0x2a, 0x00, 0, 0x0c303000, 0, 0x00000000 }, | ||
| 1034 | { 0x1, 0x2b, 0x00, 0, 0x0c2a0000, 0, 0x00000000 }, | ||
| 1035 | { 0x1, 0x2c, 0x00, 0, 0x0c2b0000, 0, 0x00000000 }, | ||
| 1036 | { 0x1, 0x2c, 0x01, 0, 0x0c2c0000, 1, 0x00010000 }, | ||
| 1037 | { 0x1, 0x2c, 0x02, 0, 0x0c2d0000, 2, 0x00020000 }, | ||
| 1038 | { 0x1, 0x2c, 0x03, 0, 0x0c2e0000, 3, 0x00030000 }, | ||
| 1039 | { 0x1, 0x00, 0x00, 0, 0x0c660000, 0, 0x00000000 }, | ||
| 1040 | { 0x1, 0x01, 0x00, 0, 0x0c020000, 0, 0x00000000 }, | ||
| 1041 | { 0x1, 0x02, 0x00, 0, 0x0c030000, 0, 0x00000000 }, | ||
| 1042 | { 0x1, 0x03, 0x00, 0, 0x0c310000, 0, 0x00000000 }, | ||
| 1043 | { 0x1, 0x04, 0x00, 0, 0x0c320000, 0, 0x00000000 }, | ||
| 1044 | { 0x1, 0x05, 0x00, 0, 0x0c0a0000, 2, 0x00040000 }, | ||
| 1045 | { 0x1, 0x05, 0x01, 0, 0x0c0b0000, 3, 0x00050000 }, | ||
| 1046 | { 0x1, 0x05, 0x02, 0, 0x0c0e0000, 5, 0x00080000 }, | ||
| 1047 | { 0x1, 0x05, 0x03, 0, 0x0c060000, 0, 0x00000000 }, | ||
| 1048 | { 0x1, 0x05, 0x04, 0, 0x0c080000, 1, 0x00020000 }, | ||
| 1049 | { 0x1, 0x05, 0x05, 0, 0x0c0c0000, 4, 0x00060000 }, | ||
| 1050 | { 0x1, 0x06, 0x00, 0, 0x0c330000, 0, 0x00000000 }, | ||
| 1051 | { 0x1, 0x07, 0x00, 0, 0x0c650000, 0, 0x00000000 }, | ||
| 1052 | { 0x1, 0x08, 0x00, 0, 0x0c3e0000, 0, 0x00000000 }, | ||
| 1053 | { 0x1, 0x09, 0x00, 0, 0x0c1e0000, 0, 0x00000000 }, | ||
| 1054 | { 0x1, 0x0a, 0x00, 0, 0x0c150000, 0, 0x00000000 }, | ||
| 1055 | { 0x1, 0x0a, 0x01, 0, 0x0c160000, 1, 0x00010000 }, | ||
| 1056 | { 0x1, 0x0a, 0x02, 0, 0x0c170000, 2, 0x00020000 }, | ||
| 1057 | { 0x1, 0x0a, 0x03, 0, 0x0c180000, 3, 0x00030000 }, | ||
| 1058 | { 0x1, 0x0a, 0x04, 0, 0x0c190000, 4, 0x00040000 }, | ||
| 1059 | { 0x1, 0x0a, 0x05, 0, 0x0c1a0000, 5, 0x00050000 }, | ||
| 1060 | { 0x1, 0x0a, 0x06, 0, 0x0c1b0000, 6, 0x00060000 }, | ||
| 1061 | { 0x1, 0x0a, 0x07, 0, 0x0c1c0000, 7, 0x00070000 }, | ||
| 1062 | { 0x1, 0x0a, 0x08, 0, 0x0c1d0000, 8, 0x00080000 }, | ||
| 1063 | { 0x1, 0x0b, 0x00, 0, 0x0c240000, 0, 0x00000000 }, | ||
| 1064 | { 0x1, 0x0c, 0x00, 0, 0x0c250000, 0, 0x00000000 }, | ||
| 1065 | { 0x1, 0x0d, 0x00, 0, 0x0c340000, 0, 0x00000000 }, | ||
| 1066 | { 0x1, 0x0e, 0x00, 0, 0x0c260000, 0, 0x00000000 }, | ||
| 1067 | { 0x1, 0x0f, 0x00, 0, 0x0c0f0000, 0, 0x00000000 }, | ||
| 1068 | { 0x1, 0x0f, 0x01, 0, 0x0c100000, 1, 0x00010000 }, | ||
| 1069 | { 0x1, 0x0f, 0x02, 0, 0x0c110000, 2, 0x00020000 }, | ||
| 1070 | { 0x1, 0x0f, 0x03, 0, 0x0c120000, 3, 0x00030000 }, | ||
| 1071 | { 0x1, 0x0f, 0x04, 0, 0x0c130000, 4, 0x00040000 }, | ||
| 1072 | { 0x1, 0x0f, 0x05, 0, 0x0c140000, 5, 0x00050000 }, | ||
| 1073 | { 0x1, 0x10, 0x00, 0, 0x0c290000, 0, 0x00000000 }, | ||
| 1074 | { 0x1, 0x30, 0x00, 0, 0x20ce0000, 0, 0x00000000 }, | ||
| 1075 | { 0x1, 0x31, 0x00, 0, 0x0c1f0000, 0, 0x00000000 }, | ||
| 1076 | { 0x1, 0x31, 0x01, 0, 0x0c200000, 1, 0x00010000 }, | ||
| 1077 | { 0x1, 0x31, 0x02, 0, 0x0c210000, 2, 0x00020000 }, | ||
| 1078 | { 0x1, 0x31, 0x03, 0, 0x0c220000, 3, 0x00030000 }, | ||
| 1079 | { 0x1, 0x32, 0x00, 0, 0x20cc0000, 3, 0x001c0000 }, | ||
| 1080 | { 0x1, 0x32, 0x01, 0, 0x20c80000, 2, 0x00180000 }, | ||
| 1081 | { 0x1, 0x32, 0x02, 0, 0x20c00000, 1, 0x00100000 }, | ||
| 1082 | { 0x1, 0x32, 0x03, 0, 0x20b00000, 0, 0x00000000 }, | ||
| 1083 | { 0x1, 0x33, 0x00, 0, 0x0c360000, 0, 0x00000000 }, | ||
| 1084 | { 0x1, 0x33, 0x01, 0, 0x0c370000, 1, 0x00010000 }, | ||
| 1085 | { 0x1, 0x33, 0x02, 0, 0x0c3a0000, 3, 0x00040000 }, | ||
| 1086 | { 0x1, 0x33, 0x03, 0, 0x0c380000, 2, 0x00020000 }, | ||
| 1087 | { 0x1, 0x38, 0x00, 0, 0x0c600000, 0, 0x00000000 }, | ||
| 1088 | { 0x1, 0x38, 0x01, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1089 | { 0x1, 0x39, 0x00, 0, 0x0c280000, 0, 0x00000000 }, | ||
| 1090 | { 0x2, 0x34, 0x00, 0, 0x40000000, 0, 0x40000000 }, | ||
| 1091 | { 0x2, 0x34, 0x01, 0, 0x80000000, 1, 0x80000000 }, | ||
| 1092 | { 0x2, 0x36, 0x00, 0, 0x0c400000, 0, 0x0c400000 }, | ||
| 1093 | { 0x2, 0x36, 0x01, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1094 | { 0x3, 0x35, 0x00, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1095 | { 0x3, 0x35, 0x01, 0, 0x00100000, 1, 0x00100000 }, | ||
| 1096 | { 0x3, 0x35, 0x02, 0, 0x05a00000, 11, 0x05a00000 }, | ||
| 1097 | { 0x3, 0x35, 0x03, 0, 0x05b00000, 32, 0x05b00000 }, | ||
| 1098 | { 0x3, 0x35, 0x04, 0, 0x05c00000, 33, 0x05c00000 }, | ||
| 1099 | { 0x3, 0x35, 0x05, 0, 0x05d00000, 12, 0x05d00000 }, | ||
| 1100 | { 0x3, 0x35, 0x06, 0, 0x20000000, 19, 0x20000000 }, | ||
| 1101 | { 0x3, 0x35, 0x07, 0, 0x20100000, 20, 0x20100000 }, | ||
| 1102 | { 0x3, 0x35, 0x08, 0, 0x20a00000, 24, 0x20a00000 }, | ||
| 1103 | { 0x3, 0x35, 0x09, 0, 0x20d00000, 25, 0x20d00000 }, | ||
| 1104 | { 0x3, 0x35, 0x0a, 0, 0x00200000, 2, 0x00200000 }, | ||
| 1105 | { 0x3, 0x35, 0x0b, 0, 0x05800000, 10, 0x05800000 }, | ||
| 1106 | { 0x3, 0x35, 0x0c, 0, 0x05e00000, 13, 0x05e00000 }, | ||
| 1107 | { 0x3, 0x35, 0x0d, 0, 0x20200000, 21, 0x20200000 }, | ||
| 1108 | { 0x3, 0x35, 0x0e, 0, 0x20800000, 23, 0x20800000 }, | ||
| 1109 | { 0x3, 0x35, 0x0f, 0, 0x20e00000, 26, 0x20e00000 }, | ||
| 1110 | { 0x3, 0x35, 0x10, 0, 0x00400000, 3, 0x00400000 }, | ||
| 1111 | { 0x3, 0x35, 0x11, 0, 0x20400000, 22, 0x20400000 }, | ||
| 1112 | { 0x3, 0x35, 0x12, 0, 0x00800000, 4, 0x00800000 }, | ||
| 1113 | { 0x3, 0x35, 0x13, 0, 0x50000000, 9, 0x05000000 }, | ||
| 1114 | { 0x3, 0x35, 0x14, 0, 0xc0800000, 34, 0x0c800000 }, | ||
| 1115 | { 0x3, 0x35, 0x15, 0, 0x10000000, 5, 0x01000000 }, | ||
| 1116 | { 0x3, 0x35, 0x16, 0, 0x30000000, 7, 0x03000000 }, | ||
| 1117 | { 0x3, 0x35, 0x17, 0, 0x04000000, 8, 0x04000000 }, | ||
| 1118 | { 0x3, 0x35, 0x18, 0, 0x0d000000, 16, 0x0d000000 }, | ||
| 1119 | { 0x3, 0x35, 0x19, 0, 0x21000000, 27, 0x21000000 }, | ||
| 1120 | { 0x3, 0x35, 0x1a, 0, 0x02000000, 6, 0x02000000 }, | ||
| 1121 | { 0x3, 0x35, 0x1b, 0, 0x06000000, 14, 0x06000000 }, | ||
| 1122 | { 0x3, 0x35, 0x1c, 0, 0x0e000000, 17, 0x0e000000 }, | ||
| 1123 | { 0x3, 0x35, 0x1d, 0, 0x22000000, 28, 0x22000000 }, | ||
| 1124 | { 0x3, 0x35, 0x1e, 0, 0x08000000, 15, 0x08000000 }, | ||
| 1125 | { 0x3, 0x35, 0x1f, 0, 0x24000000, 29, 0x24000000 }, | ||
| 1126 | { 0x3, 0x35, 0x20, 0, 0x28000000, 30, 0x28000000 }, | ||
| 1127 | { 0x3, 0x35, 0x21, 0, 0x10000000, 18, 0x10000000 }, | ||
| 1128 | { 0x3, 0x35, 0x22, 0, 0x30000000, 31, 0x30000000 }, | ||
| 1129 | { 0x3, 0x37, 0x00, 0, 0x0c640000, 0, 0x00000000 }, | ||
| 1130 | { 0x3, 0x20, 0x00, 0, 0x0c3b0000, 0, 0x00000000 }, | ||
| 1131 | { 0x3, 0x21, 0x00, 0, 0x0c000000, 0, 0x00000000 }, | ||
| 1132 | { 0x3, 0x22, 0x00, 0, 0x0c040000, 0, 0x00000000 }, | ||
| 1133 | { 0x3, 0x23, 0x00, 0, 0x0c050000, 0, 0x00000000 }, | ||
| 1134 | { 0x3, 0x24, 0x00, 0, 0x20cf0000, 0, 0x00000000 }, | ||
| 1135 | { 0x3, 0x25, 0x00, 0, 0x0c2f0000, 0, 0x00000000 }, | ||
| 1136 | { 0x3, 0x26, 0x00, 0, 0x0c230000, 0, 0x00000000 }, | ||
| 1137 | { 0x3, 0x27, 0x00, 0, 0x0c350000, 0, 0x00000000 }, | ||
| 1138 | { 0x3, 0x28, 0x00, 0, 0x0c301000, 0, 0x00000000 }, | ||
| 1139 | { 0x3, 0x29, 0x00, 0, 0x0c302000, 0, 0x00000000 }, | ||
| 1140 | { 0x3, 0x2a, 0x00, 0, 0x0c303000, 0, 0x00000000 }, | ||
| 1141 | { 0x3, 0x2b, 0x00, 0, 0x0c2a0000, 0, 0x00000000 }, | ||
| 1142 | { 0x3, 0x2c, 0x00, 0, 0x0c2b0000, 0, 0x00000000 }, | ||
| 1143 | { 0x3, 0x2c, 0x01, 0, 0x0c2c0000, 1, 0x00010000 }, | ||
| 1144 | { 0x3, 0x2c, 0x02, 0, 0x0c2d0000, 2, 0x00020000 }, | ||
| 1145 | { 0x3, 0x2c, 0x03, 0, 0x0c2e0000, 3, 0x00030000 }, | ||
| 1146 | { 0x3, 0x00, 0x00, 0, 0x0c660000, 0, 0x00000000 }, | ||
| 1147 | { 0x3, 0x01, 0x00, 0, 0x0c020000, 0, 0x00000000 }, | ||
| 1148 | { 0x3, 0x02, 0x00, 0, 0x0c030000, 0, 0x00000000 }, | ||
| 1149 | { 0x3, 0x03, 0x00, 0, 0x0c310000, 0, 0x00000000 }, | ||
| 1150 | { 0x3, 0x04, 0x00, 0, 0x0c320000, 0, 0x00000000 }, | ||
| 1151 | { 0x3, 0x05, 0x00, 0, 0x0c0a0000, 2, 0x00040000 }, | ||
| 1152 | { 0x3, 0x05, 0x01, 0, 0x0c0b0000, 3, 0x00050000 }, | ||
| 1153 | { 0x3, 0x05, 0x02, 0, 0x0c0e0000, 5, 0x00080000 }, | ||
| 1154 | { 0x3, 0x05, 0x03, 0, 0x0c060000, 0, 0x00000000 }, | ||
| 1155 | { 0x3, 0x05, 0x04, 0, 0x0c080000, 1, 0x00020000 }, | ||
| 1156 | { 0x3, 0x05, 0x05, 0, 0x0c0c0000, 4, 0x00060000 }, | ||
| 1157 | { 0x3, 0x06, 0x00, 0, 0x0c330000, 0, 0x00000000 }, | ||
| 1158 | { 0x3, 0x07, 0x00, 0, 0x0c650000, 0, 0x00000000 }, | ||
| 1159 | { 0x3, 0x08, 0x00, 0, 0x0c3e0000, 0, 0x00000000 }, | ||
| 1160 | { 0x3, 0x09, 0x00, 0, 0x0c1e0000, 0, 0x00000000 }, | ||
| 1161 | { 0x3, 0x0a, 0x00, 0, 0x0c150000, 0, 0x00000000 }, | ||
| 1162 | { 0x3, 0x0a, 0x01, 0, 0x0c160000, 1, 0x00010000 }, | ||
| 1163 | { 0x3, 0x0a, 0x02, 0, 0x0c170000, 2, 0x00020000 }, | ||
| 1164 | { 0x3, 0x0a, 0x03, 0, 0x0c180000, 3, 0x00030000 }, | ||
| 1165 | { 0x3, 0x0a, 0x04, 0, 0x0c190000, 4, 0x00040000 }, | ||
| 1166 | { 0x3, 0x0a, 0x05, 0, 0x0c1a0000, 5, 0x00050000 }, | ||
| 1167 | { 0x3, 0x0a, 0x06, 0, 0x0c1b0000, 6, 0x00060000 }, | ||
| 1168 | { 0x3, 0x0a, 0x07, 0, 0x0c1c0000, 7, 0x00070000 }, | ||
| 1169 | { 0x3, 0x0a, 0x08, 0, 0x0c1d0000, 8, 0x00080000 }, | ||
| 1170 | { 0x3, 0x0b, 0x00, 0, 0x0c240000, 0, 0x00000000 }, | ||
| 1171 | { 0x3, 0x0c, 0x00, 0, 0x0c250000, 0, 0x00000000 }, | ||
| 1172 | { 0x3, 0x0d, 0x00, 0, 0x0c340000, 0, 0x00000000 }, | ||
| 1173 | { 0x3, 0x0e, 0x00, 0, 0x0c260000, 0, 0x00000000 }, | ||
| 1174 | { 0x3, 0x0f, 0x00, 0, 0x0c0f0000, 0, 0x00000000 }, | ||
| 1175 | { 0x3, 0x0f, 0x01, 0, 0x0c100000, 1, 0x00010000 }, | ||
| 1176 | { 0x3, 0x0f, 0x02, 0, 0x0c110000, 2, 0x00020000 }, | ||
| 1177 | { 0x3, 0x0f, 0x03, 0, 0x0c120000, 3, 0x00030000 }, | ||
| 1178 | { 0x3, 0x0f, 0x04, 0, 0x0c130000, 4, 0x00040000 }, | ||
| 1179 | { 0x3, 0x0f, 0x05, 0, 0x0c140000, 5, 0x00050000 }, | ||
| 1180 | { 0x3, 0x10, 0x00, 0, 0x0c290000, 0, 0x00000000 }, | ||
| 1181 | { 0x3, 0x30, 0x00, 0, 0x20ce0000, 0, 0x00000000 }, | ||
| 1182 | { 0x3, 0x31, 0x00, 0, 0x0c1f0000, 0, 0x00000000 }, | ||
| 1183 | { 0x3, 0x31, 0x01, 0, 0x0c200000, 1, 0x00010000 }, | ||
| 1184 | { 0x3, 0x31, 0x02, 0, 0x0c210000, 2, 0x00020000 }, | ||
| 1185 | { 0x3, 0x31, 0x03, 0, 0x0c220000, 3, 0x00030000 }, | ||
| 1186 | { 0x3, 0x32, 0x00, 0, 0x20cc0000, 3, 0x001c0000 }, | ||
| 1187 | { 0x3, 0x32, 0x01, 0, 0x20c80000, 2, 0x00180000 }, | ||
| 1188 | { 0x3, 0x32, 0x02, 0, 0x20c00000, 1, 0x00100000 }, | ||
| 1189 | { 0x3, 0x32, 0x03, 0, 0x20b00000, 0, 0x00000000 }, | ||
| 1190 | { 0x3, 0x33, 0x00, 0, 0x0c360000, 0, 0x00000000 }, | ||
| 1191 | { 0x3, 0x33, 0x01, 0, 0x0c370000, 1, 0x00010000 }, | ||
| 1192 | { 0x3, 0x33, 0x02, 0, 0x0c3a0000, 3, 0x00040000 }, | ||
| 1193 | { 0x3, 0x33, 0x03, 0, 0x0c380000, 2, 0x00020000 }, | ||
| 1194 | { 0x3, 0x38, 0x00, 0, 0x0c600000, 0, 0x00000000 }, | ||
| 1195 | { 0x3, 0x38, 0x01, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1196 | { 0x3, 0x39, 0x00, 0, 0x0c280000, 0, 0x00000000 } | ||
| 1197 | }; | ||
| 1198 | |||
| 1199 | /* | ||
| 1200 | * SCE/RCE NOC aperture lookup table as per file "AON_NOC_Structure.info". | ||
| 1201 | */ | ||
| 1202 | static const char * const tegra194_scenoc_routeid_initflow[] = { | ||
| 1203 | [0x0] = "cbb_i/I/0", | ||
| 1204 | [0x1] = "cpu_m_i/I/0", | ||
| 1205 | [0x2] = "cpu_p_i/I/0", | ||
| 1206 | [0x3] = "dma_m_i/I/0", | ||
| 1207 | [0x4] = "dma_p_i/I/0", | ||
| 1208 | [0x5] = "RESERVED", | ||
| 1209 | [0x6] = "RESERVED", | ||
| 1210 | [0x7] = "RESERVED" | ||
| 1211 | }; | ||
| 1212 | |||
| 1213 | static const char * const tegra194_scenoc_routeid_targflow[] = { | ||
| 1214 | [0x00] = "multiport0_t/T/atcm_cfg", | ||
| 1215 | [0x01] = "multiport0_t/T/car", | ||
| 1216 | [0x02] = "multiport0_t/T/cast", | ||
| 1217 | [0x03] = "multiport0_t/T/cfg", | ||
| 1218 | [0x04] = "multiport0_t/T/dast", | ||
| 1219 | [0x05] = "multiport0_t/T/dma", | ||
| 1220 | [0x06] = "multiport0_t/T/err_collator", | ||
| 1221 | [0x07] = "multiport0_t/T/err_collator_car", | ||
| 1222 | [0x08] = "multiport0_t/T/fpga_misc", | ||
| 1223 | [0x09] = "multiport0_t/T/fpga_uart", | ||
| 1224 | [0x0a] = "multiport0_t/T/gte", | ||
| 1225 | [0x0b] = "multiport0_t/T/hsp", | ||
| 1226 | [0x0c] = "multiport0_t/T/misc", | ||
| 1227 | [0x0d] = "multiport0_t/T/pm", | ||
| 1228 | [0x0e] = "multiport0_t/T/tke", | ||
| 1229 | [0x0f] = "RESERVED", | ||
| 1230 | [0x10] = "multiport1_t/T/hsm", | ||
| 1231 | [0x11] = "multiport1_t/T/vic0", | ||
| 1232 | [0x12] = "multiport1_t/T/vic1", | ||
| 1233 | [0x13] = "ast0_t/T/0", | ||
| 1234 | [0x14] = "ast1_t/T/0", | ||
| 1235 | [0x15] = "cbb_t/T/0", | ||
| 1236 | [0x16] = "cpu_t/T/0", | ||
| 1237 | [0x17] = "sce_noc_firewall/T/0", | ||
| 1238 | [0x18] = "svc_t/T/0", | ||
| 1239 | [0x19] = "RESERVED", | ||
| 1240 | [0x1a] = "RESERVED", | ||
| 1241 | [0x1b] = "RESERVED", | ||
| 1242 | [0x1c] = "RESERVED", | ||
| 1243 | [0x1d] = "RESERVED", | ||
| 1244 | [0x1e] = "RESERVED", | ||
| 1245 | [0x1f] = "RESERVED" | ||
| 1246 | }; | ||
| 1247 | |||
| 1248 | /* | ||
| 1249 | * Fields of SCE/RCE NOC lookup table: | ||
| 1250 | * Init flow, Targ flow, Targ subrange, Init mapping, Init localAddress, | ||
| 1251 | * Targ mapping, Targ localAddress | ||
| 1252 | * ---------------------------------------------------------------------------- | ||
| 1253 | */ | ||
| 1254 | static const struct tegra194_cbb_aperture tegra194_scenoc_apert_lookup[] = { | ||
| 1255 | { 0x0, 0x16, 0x0, 0, 0x0b400000, 0, 0x0b400000 }, | ||
| 1256 | { 0x0, 0x16, 0x1, 0, 0x0bc00000, 1, 0x0bc00000 }, | ||
| 1257 | { 0x0, 0x0, 0x0, 0, 0x0b000000, 0, 0x00000000 }, | ||
| 1258 | { 0x0, 0x0, 0x1, 0, 0x0b800000, 1, 0x00000000 }, | ||
| 1259 | { 0x0, 0x1, 0x0, 0, 0x20de0000, 3, 0x000e0000 }, | ||
| 1260 | { 0x0, 0x1, 0x1, 0, 0x210e0000, 7, 0x000e0000 }, | ||
| 1261 | { 0x0, 0x1, 0x2, 0, 0x20dc0000, 2, 0x000c0000 }, | ||
| 1262 | { 0x0, 0x1, 0x3, 0, 0x210c0000, 6, 0x000c0000 }, | ||
| 1263 | { 0x0, 0x1, 0x4, 0, 0x20d80000, 1, 0x00080000 }, | ||
| 1264 | { 0x0, 0x1, 0x5, 0, 0x21080000, 5, 0x00080000 }, | ||
| 1265 | { 0x0, 0x1, 0x6, 0, 0x20d00000, 0, 0x00000000 }, | ||
| 1266 | { 0x0, 0x1, 0x7, 0, 0x21000000, 4, 0x00000000 }, | ||
| 1267 | { 0x0, 0x2, 0x0, 0, 0x0b040000, 0, 0x00000000 }, | ||
| 1268 | { 0x0, 0x2, 0x1, 0, 0x0b840000, 1, 0x00000000 }, | ||
| 1269 | { 0x0, 0x3, 0x0, 0, 0x0b230000, 0, 0x00000000 }, | ||
| 1270 | { 0x0, 0x3, 0x1, 0, 0x0ba30000, 1, 0x00000000 }, | ||
| 1271 | { 0x0, 0x4, 0x0, 0, 0x0b050000, 0, 0x00000000 }, | ||
| 1272 | { 0x0, 0x4, 0x1, 0, 0x0b850000, 1, 0x00000000 }, | ||
| 1273 | { 0x0, 0x5, 0x0, 0, 0x0b060000, 0, 0x00000000 }, | ||
| 1274 | { 0x0, 0x5, 0x1, 0, 0x0b070000, 1, 0x00010000 }, | ||
| 1275 | { 0x0, 0x5, 0x2, 0, 0x0b080000, 2, 0x00020000 }, | ||
| 1276 | { 0x0, 0x5, 0x3, 0, 0x0b090000, 3, 0x00030000 }, | ||
| 1277 | { 0x0, 0x5, 0x4, 0, 0x0b0a0000, 4, 0x00040000 }, | ||
| 1278 | { 0x0, 0x5, 0x5, 0, 0x0b0b0000, 5, 0x00050000 }, | ||
| 1279 | { 0x0, 0x5, 0x6, 0, 0x0b0c0000, 6, 0x00060000 }, | ||
| 1280 | { 0x0, 0x5, 0x7, 0, 0x0b0d0000, 7, 0x00070000 }, | ||
| 1281 | { 0x0, 0x5, 0x8, 0, 0x0b0e0000, 8, 0x00080000 }, | ||
| 1282 | { 0x0, 0x5, 0x9, 0, 0x0b860000, 9, 0x00000000 }, | ||
| 1283 | { 0x0, 0x5, 0xa, 0, 0x0b870000, 10, 0x00010000 }, | ||
| 1284 | { 0x0, 0x5, 0xb, 0, 0x0b880000, 11, 0x00020000 }, | ||
| 1285 | { 0x0, 0x5, 0xc, 0, 0x0b890000, 12, 0x00030000 }, | ||
| 1286 | { 0x0, 0x5, 0xd, 0, 0x0b8a0000, 13, 0x00040000 }, | ||
| 1287 | { 0x0, 0x5, 0xe, 0, 0x0b8b0000, 14, 0x00050000 }, | ||
| 1288 | { 0x0, 0x5, 0xf, 0, 0x0b8c0000, 15, 0x00060000 }, | ||
| 1289 | { 0x0, 0x5, 0x10, 0, 0x0b8d0000, 16, 0x00070000 }, | ||
| 1290 | { 0x0, 0x5, 0x11, 0, 0x0b8e0000, 17, 0x00080000 }, | ||
| 1291 | { 0x0, 0x6, 0x0, 0, 0x0b650000, 0, 0x00000000 }, | ||
| 1292 | { 0x0, 0x6, 0x1, 0, 0x0be50000, 1, 0x00000000 }, | ||
| 1293 | { 0x0, 0x7, 0x0, 0, 0x20df0000, 0, 0x00000000 }, | ||
| 1294 | { 0x0, 0x7, 0x1, 0, 0x210f0000, 1, 0x00000000 }, | ||
| 1295 | { 0x0, 0x8, 0x0, 0, 0x0b3e0000, 0, 0x00000000 }, | ||
| 1296 | { 0x0, 0x8, 0x1, 0, 0x0bbe0000, 1, 0x00000000 }, | ||
| 1297 | { 0x0, 0x9, 0x0, 0, 0x0b3d0000, 0, 0x00000000 }, | ||
| 1298 | { 0x0, 0x9, 0x1, 0, 0x0bbd0000, 1, 0x00000000 }, | ||
| 1299 | { 0x0, 0xa, 0x0, 0, 0x0b1e0000, 0, 0x00000000 }, | ||
| 1300 | { 0x0, 0xa, 0x1, 0, 0x0b9e0000, 1, 0x00000000 }, | ||
| 1301 | { 0x0, 0xb, 0x0, 0, 0x0b150000, 0, 0x00000000 }, | ||
| 1302 | { 0x0, 0xb, 0x1, 0, 0x0b160000, 1, 0x00010000 }, | ||
| 1303 | { 0x0, 0xb, 0x2, 0, 0x0b170000, 2, 0x00020000 }, | ||
| 1304 | { 0x0, 0xb, 0x3, 0, 0x0b180000, 3, 0x00030000 }, | ||
| 1305 | { 0x0, 0xb, 0x4, 0, 0x0b190000, 4, 0x00040000 }, | ||
| 1306 | { 0x0, 0xb, 0x5, 0, 0x0b1a0000, 5, 0x00050000 }, | ||
| 1307 | { 0x0, 0xb, 0x6, 0, 0x0b1b0000, 6, 0x00060000 }, | ||
| 1308 | { 0x0, 0xb, 0x7, 0, 0x0b1c0000, 7, 0x00070000 }, | ||
| 1309 | { 0x0, 0xb, 0x8, 0, 0x0b1d0000, 8, 0x00080000 }, | ||
| 1310 | { 0x0, 0xb, 0x9, 0, 0x0b950000, 9, 0x00000000 }, | ||
| 1311 | { 0x0, 0xb, 0xa, 0, 0x0b960000, 10, 0x00010000 }, | ||
| 1312 | { 0x0, 0xb, 0xb, 0, 0x0b970000, 11, 0x00020000 }, | ||
| 1313 | { 0x0, 0xb, 0xc, 0, 0x0b980000, 12, 0x00030000 }, | ||
| 1314 | { 0x0, 0xb, 0xd, 0, 0x0b990000, 13, 0x00040000 }, | ||
| 1315 | { 0x0, 0xb, 0xe, 0, 0x0b9a0000, 14, 0x00050000 }, | ||
| 1316 | { 0x0, 0xb, 0xf, 0, 0x0b9b0000, 15, 0x00060000 }, | ||
| 1317 | { 0x0, 0xb, 0x10, 0, 0x0b9c0000, 16, 0x00070000 }, | ||
| 1318 | { 0x0, 0xb, 0x11, 0, 0x0b9d0000, 17, 0x00080000 }, | ||
| 1319 | { 0x0, 0xc, 0x0, 0, 0x0b660000, 0, 0x00000000 }, | ||
| 1320 | { 0x0, 0xc, 0x1, 0, 0x0be60000, 1, 0x00000000 }, | ||
| 1321 | { 0x0, 0xd, 0x0, 0, 0x0b1f0000, 0, 0x00000000 }, | ||
| 1322 | { 0x0, 0xd, 0x1, 0, 0x0b200000, 1, 0x00010000 }, | ||
| 1323 | { 0x0, 0xd, 0x2, 0, 0x0b210000, 2, 0x00020000 }, | ||
| 1324 | { 0x0, 0xd, 0x3, 0, 0x0b220000, 3, 0x00030000 }, | ||
| 1325 | { 0x0, 0xd, 0x4, 0, 0x0b9f0000, 4, 0x00000000 }, | ||
| 1326 | { 0x0, 0xd, 0x5, 0, 0x0ba00000, 5, 0x00010000 }, | ||
| 1327 | { 0x0, 0xd, 0x6, 0, 0x0ba10000, 6, 0x00020000 }, | ||
| 1328 | { 0x0, 0xd, 0x7, 0, 0x0ba20000, 7, 0x00030000 }, | ||
| 1329 | { 0x0, 0xe, 0x0, 0, 0x0b0f0000, 0, 0x00000000 }, | ||
| 1330 | { 0x0, 0xe, 0x1, 0, 0x0b100000, 1, 0x00010000 }, | ||
| 1331 | { 0x0, 0xe, 0x2, 0, 0x0b110000, 2, 0x00020000 }, | ||
| 1332 | { 0x0, 0xe, 0x3, 0, 0x0b120000, 3, 0x00030000 }, | ||
| 1333 | { 0x0, 0xe, 0x4, 0, 0x0b130000, 4, 0x00040000 }, | ||
| 1334 | { 0x0, 0xe, 0x5, 0, 0x0b140000, 5, 0x00050000 }, | ||
| 1335 | { 0x0, 0xe, 0x6, 0, 0x0b8f0000, 6, 0x00000000 }, | ||
| 1336 | { 0x0, 0xe, 0x7, 0, 0x0b900000, 7, 0x00010000 }, | ||
| 1337 | { 0x0, 0xe, 0x8, 0, 0x0b910000, 8, 0x00020000 }, | ||
| 1338 | { 0x0, 0xe, 0x9, 0, 0x0b920000, 9, 0x00030000 }, | ||
| 1339 | { 0x0, 0xe, 0xa, 0, 0x0b930000, 10, 0x00040000 }, | ||
| 1340 | { 0x0, 0xe, 0xb, 0, 0x0b940000, 11, 0x00050000 }, | ||
| 1341 | { 0x0, 0x10, 0x0, 0, 0x0b240000, 0, 0x00000000 }, | ||
| 1342 | { 0x0, 0x10, 0x1, 0, 0x0ba40000, 1, 0x00000000 }, | ||
| 1343 | { 0x0, 0x11, 0x0, 0, 0x0b020000, 0, 0x00000000 }, | ||
| 1344 | { 0x0, 0x11, 0x1, 0, 0x0b820000, 1, 0x00000000 }, | ||
| 1345 | { 0x0, 0x12, 0x0, 0, 0x0b030000, 0, 0x00000000 }, | ||
| 1346 | { 0x0, 0x12, 0x1, 0, 0x0b830000, 1, 0x00000000 }, | ||
| 1347 | { 0x0, 0x17, 0x0, 0, 0x0b640000, 0, 0x00000000 }, | ||
| 1348 | { 0x0, 0x17, 0x1, 0, 0x0be40000, 1, 0x00000000 }, | ||
| 1349 | { 0x0, 0x18, 0x0, 0, 0x0b600000, 0, 0x00000000 }, | ||
| 1350 | { 0x0, 0x18, 0x1, 0, 0x0be00000, 1, 0x00000000 }, | ||
| 1351 | { 0x0, 0x18, 0x2, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1352 | { 0x0, 0x18, 0x3, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1353 | { 0x1, 0x13, 0x0, 0, 0x40000000, 0, 0x40000000 }, | ||
| 1354 | { 0x1, 0x13, 0x1, 1, 0x80000000, 1, 0x80000000 }, | ||
| 1355 | { 0x1, 0x13, 0x2, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1356 | { 0x2, 0x15, 0x0, 0, 0x20c00000, 8, 0x20c00000 }, | ||
| 1357 | { 0x2, 0x15, 0x1, 0, 0x21100000, 22, 0x21100000 }, | ||
| 1358 | { 0x2, 0x15, 0x2, 0, 0x20e00000, 9, 0x20e00000 }, | ||
| 1359 | { 0x2, 0x15, 0x3, 0, 0x21200000, 23, 0x21200000 }, | ||
| 1360 | { 0x2, 0x15, 0x4, 0, 0x20800000, 7, 0x20800000 }, | ||
| 1361 | { 0x2, 0x15, 0x5, 0, 0x21400000, 24, 0x21400000 }, | ||
| 1362 | { 0x2, 0x15, 0x6, 0, 0x0b000000, 18, 0x0b000000 }, | ||
| 1363 | { 0x2, 0x15, 0x7, 0, 0x0b800000, 3, 0x0b800000 }, | ||
| 1364 | { 0x2, 0x15, 0x8, 0, 0x20000000, 6, 0x20000000 }, | ||
| 1365 | { 0x2, 0x15, 0x9, 0, 0x21800000, 25, 0x21800000 }, | ||
| 1366 | { 0x2, 0x15, 0xa, 0, 0x0a000000, 2, 0x0a000000 }, | ||
| 1367 | { 0x2, 0x15, 0xb, 0, 0x0a000000, 17, 0x0a000000 }, | ||
| 1368 | { 0x2, 0x15, 0xc, 0, 0x20000000, 21, 0x20000000 }, | ||
| 1369 | { 0x2, 0x15, 0xd, 0, 0x21000000, 10, 0x21000000 }, | ||
| 1370 | { 0x2, 0x15, 0xe, 0, 0x08000000, 1, 0x08000000 }, | ||
| 1371 | { 0x2, 0x15, 0xf, 0, 0x08000000, 16, 0x08000000 }, | ||
| 1372 | { 0x2, 0x15, 0x10, 0, 0x22000000, 11, 0x22000000 }, | ||
| 1373 | { 0x2, 0x15, 0x11, 0, 0x22000000, 26, 0x22000000 }, | ||
| 1374 | { 0x2, 0x15, 0x12, 0, 0x0c000000, 4, 0x0c000000 }, | ||
| 1375 | { 0x2, 0x15, 0x13, 0, 0x0c000000, 19, 0x0c000000 }, | ||
| 1376 | { 0x2, 0x15, 0x14, 0, 0x24000000, 12, 0x24000000 }, | ||
| 1377 | { 0x2, 0x15, 0x15, 0, 0x24000000, 27, 0x24000000 }, | ||
| 1378 | { 0x2, 0x15, 0x16, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1379 | { 0x2, 0x15, 0x17, 0, 0x00000000, 15, 0x00000000 }, | ||
| 1380 | { 0x2, 0x15, 0x18, 0, 0x28000000, 13, 0x28000000 }, | ||
| 1381 | { 0x2, 0x15, 0x19, 0, 0x28000000, 28, 0x28000000 }, | ||
| 1382 | { 0x2, 0x15, 0x1a, 0, 0x10000000, 5, 0x10000000 }, | ||
| 1383 | { 0x2, 0x15, 0x1b, 0, 0x10000000, 20, 0x10000000 }, | ||
| 1384 | { 0x2, 0x15, 0x1c, 0, 0x30000000, 14, 0x30000000 }, | ||
| 1385 | { 0x2, 0x15, 0x1d, 0, 0x30000000, 29, 0x30000000 }, | ||
| 1386 | { 0x2, 0x0, 0x0, 0, 0x0b000000, 0, 0x00000000 }, | ||
| 1387 | { 0x2, 0x0, 0x1, 0, 0x0b800000, 1, 0x00000000 }, | ||
| 1388 | { 0x2, 0x1, 0x0, 0, 0x20de0000, 3, 0x000e0000 }, | ||
| 1389 | { 0x2, 0x1, 0x1, 0, 0x210e0000, 7, 0x000e0000 }, | ||
| 1390 | { 0x2, 0x1, 0x2, 0, 0x20dc0000, 2, 0x000c0000 }, | ||
| 1391 | { 0x2, 0x1, 0x3, 0, 0x210c0000, 6, 0x000c0000 }, | ||
| 1392 | { 0x2, 0x1, 0x4, 0, 0x20d80000, 1, 0x00080000 }, | ||
| 1393 | { 0x2, 0x1, 0x5, 0, 0x21080000, 5, 0x00080000 }, | ||
| 1394 | { 0x2, 0x1, 0x6, 0, 0x20d00000, 0, 0x00000000 }, | ||
| 1395 | { 0x2, 0x1, 0x7, 0, 0x21000000, 4, 0x00000000 }, | ||
| 1396 | { 0x2, 0x2, 0x0, 0, 0x0b040000, 0, 0x00000000 }, | ||
| 1397 | { 0x2, 0x2, 0x1, 0, 0x0b840000, 1, 0x00000000 }, | ||
| 1398 | { 0x2, 0x3, 0x0, 0, 0x0b230000, 0, 0x00000000 }, | ||
| 1399 | { 0x2, 0x3, 0x1, 0, 0x0ba30000, 1, 0x00000000 }, | ||
| 1400 | { 0x2, 0x4, 0x0, 0, 0x0b050000, 0, 0x00000000 }, | ||
| 1401 | { 0x2, 0x4, 0x1, 0, 0x0b850000, 1, 0x00000000 }, | ||
| 1402 | { 0x2, 0x5, 0x0, 0, 0x0b060000, 0, 0x00000000 }, | ||
| 1403 | { 0x2, 0x5, 0x1, 0, 0x0b070000, 1, 0x00010000 }, | ||
| 1404 | { 0x2, 0x5, 0x2, 0, 0x0b080000, 2, 0x00020000 }, | ||
| 1405 | { 0x2, 0x5, 0x3, 0, 0x0b090000, 3, 0x00030000 }, | ||
| 1406 | { 0x2, 0x5, 0x4, 0, 0x0b0a0000, 4, 0x00040000 }, | ||
| 1407 | { 0x2, 0x5, 0x5, 0, 0x0b0b0000, 5, 0x00050000 }, | ||
| 1408 | { 0x2, 0x5, 0x6, 0, 0x0b0c0000, 6, 0x00060000 }, | ||
| 1409 | { 0x2, 0x5, 0x7, 0, 0x0b0d0000, 7, 0x00070000 }, | ||
| 1410 | { 0x2, 0x5, 0x8, 0, 0x0b0e0000, 8, 0x00080000 }, | ||
| 1411 | { 0x2, 0x5, 0x9, 0, 0x0b860000, 9, 0x00000000 }, | ||
| 1412 | { 0x2, 0x5, 0xa, 0, 0x0b870000, 10, 0x00010000 }, | ||
| 1413 | { 0x2, 0x5, 0xb, 0, 0x0b880000, 11, 0x00020000 }, | ||
| 1414 | { 0x2, 0x5, 0xc, 0, 0x0b890000, 12, 0x00030000 }, | ||
| 1415 | { 0x2, 0x5, 0xd, 0, 0x0b8a0000, 13, 0x00040000 }, | ||
| 1416 | { 0x2, 0x5, 0xe, 0, 0x0b8b0000, 14, 0x00050000 }, | ||
| 1417 | { 0x2, 0x5, 0xf, 0, 0x0b8c0000, 15, 0x00060000 }, | ||
| 1418 | { 0x2, 0x5, 0x10, 0, 0x0b8d0000, 16, 0x00070000 }, | ||
| 1419 | { 0x2, 0x5, 0x11, 0, 0x0b8e0000, 17, 0x00080000 }, | ||
| 1420 | { 0x2, 0x6, 0x0, 0, 0x0b650000, 0, 0x00000000 }, | ||
| 1421 | { 0x2, 0x6, 0x1, 0, 0x0be50000, 1, 0x00000000 }, | ||
| 1422 | { 0x2, 0x7, 0x0, 0, 0x20df0000, 0, 0x00000000 }, | ||
| 1423 | { 0x2, 0x7, 0x1, 0, 0x210f0000, 1, 0x00000000 }, | ||
| 1424 | { 0x2, 0x8, 0x0, 0, 0x0b3e0000, 0, 0x00000000 }, | ||
| 1425 | { 0x2, 0x8, 0x1, 0, 0x0bbe0000, 1, 0x00000000 }, | ||
| 1426 | { 0x2, 0x9, 0x0, 0, 0x0b3d0000, 0, 0x00000000 }, | ||
| 1427 | { 0x2, 0x9, 0x1, 0, 0x0bbd0000, 1, 0x00000000 }, | ||
| 1428 | { 0x2, 0xa, 0x0, 0, 0x0b1e0000, 0, 0x00000000 }, | ||
| 1429 | { 0x2, 0xa, 0x1, 0, 0x0b9e0000, 1, 0x00000000 }, | ||
| 1430 | { 0x2, 0xb, 0x0, 0, 0x0b150000, 0, 0x00000000 }, | ||
| 1431 | { 0x2, 0xb, 0x1, 0, 0x0b160000, 1, 0x00010000 }, | ||
| 1432 | { 0x2, 0xb, 0x2, 0, 0x0b170000, 2, 0x00020000 }, | ||
| 1433 | { 0x2, 0xb, 0x3, 0, 0x0b180000, 3, 0x00030000 }, | ||
| 1434 | { 0x2, 0xb, 0x4, 0, 0x0b190000, 4, 0x00040000 }, | ||
| 1435 | { 0x2, 0xb, 0x5, 0, 0x0b1a0000, 5, 0x00050000 }, | ||
| 1436 | { 0x2, 0xb, 0x6, 0, 0x0b1b0000, 6, 0x00060000 }, | ||
| 1437 | { 0x2, 0xb, 0x7, 0, 0x0b1c0000, 7, 0x00070000 }, | ||
| 1438 | { 0x2, 0xb, 0x8, 0, 0x0b1d0000, 8, 0x00080000 }, | ||
| 1439 | { 0x2, 0xb, 0x9, 0, 0x0b950000, 9, 0x00000000 }, | ||
| 1440 | { 0x2, 0xb, 0xa, 0, 0x0b960000, 10, 0x00010000 }, | ||
| 1441 | { 0x2, 0xb, 0xb, 0, 0x0b970000, 11, 0x00020000 }, | ||
| 1442 | { 0x2, 0xb, 0xc, 0, 0x0b980000, 12, 0x00030000 }, | ||
| 1443 | { 0x2, 0xb, 0xd, 0, 0x0b990000, 13, 0x00040000 }, | ||
| 1444 | { 0x2, 0xb, 0xe, 0, 0x0b9a0000, 14, 0x00050000 }, | ||
| 1445 | { 0x2, 0xb, 0xf, 0, 0x0b9b0000, 15, 0x00060000 }, | ||
| 1446 | { 0x2, 0xb, 0x10, 0, 0x0b9c0000, 16, 0x00070000 }, | ||
| 1447 | { 0x2, 0xb, 0x11, 0, 0x0b9d0000, 17, 0x00080000 }, | ||
| 1448 | { 0x2, 0xc, 0x0, 0, 0x0b660000, 0, 0x00000000 }, | ||
| 1449 | { 0x2, 0xc, 0x1, 0, 0x0be60000, 1, 0x00000000 }, | ||
| 1450 | { 0x2, 0xd, 0x0, 0, 0x0b1f0000, 0, 0x00000000 }, | ||
| 1451 | { 0x2, 0xd, 0x1, 0, 0x0b200000, 1, 0x00010000 }, | ||
| 1452 | { 0x2, 0xd, 0x2, 0, 0x0b210000, 2, 0x00020000 }, | ||
| 1453 | { 0x2, 0xd, 0x3, 0, 0x0b220000, 3, 0x00030000 }, | ||
| 1454 | { 0x2, 0xd, 0x4, 0, 0x0b9f0000, 4, 0x00000000 }, | ||
| 1455 | { 0x2, 0xd, 0x5, 0, 0x0ba00000, 5, 0x00010000 }, | ||
| 1456 | { 0x2, 0xd, 0x6, 0, 0x0ba10000, 6, 0x00020000 }, | ||
| 1457 | { 0x2, 0xd, 0x7, 0, 0x0ba20000, 7, 0x00030000 }, | ||
| 1458 | { 0x2, 0xe, 0x0, 0, 0x0b0f0000, 0, 0x00000000 }, | ||
| 1459 | { 0x2, 0xe, 0x1, 0, 0x0b100000, 1, 0x00010000 }, | ||
| 1460 | { 0x2, 0xe, 0x2, 0, 0x0b110000, 2, 0x00020000 }, | ||
| 1461 | { 0x2, 0xe, 0x3, 0, 0x0b120000, 3, 0x00030000 }, | ||
| 1462 | { 0x2, 0xe, 0x4, 0, 0x0b130000, 4, 0x00040000 }, | ||
| 1463 | { 0x2, 0xe, 0x5, 0, 0x0b140000, 5, 0x00050000 }, | ||
| 1464 | { 0x2, 0xe, 0x6, 0, 0x0b8f0000, 6, 0x00000000 }, | ||
| 1465 | { 0x2, 0xe, 0x7, 0, 0x0b900000, 7, 0x00010000 }, | ||
| 1466 | { 0x2, 0xe, 0x8, 0, 0x0b910000, 8, 0x00020000 }, | ||
| 1467 | { 0x2, 0xe, 0x9, 0, 0x0b920000, 9, 0x00030000 }, | ||
| 1468 | { 0x2, 0xe, 0xa, 0, 0x0b930000, 10, 0x00040000 }, | ||
| 1469 | { 0x2, 0xe, 0xb, 0, 0x0b940000, 11, 0x00050000 }, | ||
| 1470 | { 0x2, 0x10, 0x0, 0, 0x0b240000, 0, 0x00000000 }, | ||
| 1471 | { 0x2, 0x10, 0x1, 0, 0x0ba40000, 1, 0x00000000 }, | ||
| 1472 | { 0x2, 0x11, 0x0, 0, 0x0b020000, 0, 0x00000000 }, | ||
| 1473 | { 0x2, 0x11, 0x1, 0, 0x0b820000, 1, 0x00000000 }, | ||
| 1474 | { 0x2, 0x12, 0x0, 0, 0x0b030000, 0, 0x00000000 }, | ||
| 1475 | { 0x2, 0x12, 0x1, 0, 0x0b830000, 1, 0x00000000 }, | ||
| 1476 | { 0x2, 0x17, 0x0, 0, 0x0b640000, 0, 0x00000000 }, | ||
| 1477 | { 0x2, 0x17, 0x1, 0, 0x0be40000, 1, 0x00000000 }, | ||
| 1478 | { 0x2, 0x18, 0x0, 0, 0x0b600000, 0, 0x00000000 }, | ||
| 1479 | { 0x2, 0x18, 0x1, 0, 0x0be00000, 1, 0x00000000 }, | ||
| 1480 | { 0x2, 0x18, 0x2, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1481 | { 0x2, 0x18, 0x3, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1482 | { 0x3, 0x14, 0x0, 0, 0x40000000, 0, 0x40000000 }, | ||
| 1483 | { 0x3, 0x14, 0x1, 1, 0x80000000, 1, 0x80000000 }, | ||
| 1484 | { 0x3, 0x16, 0x0, 2, 0x0b400000, 0, 0x0b400000 }, | ||
| 1485 | { 0x3, 0x16, 0x1, 2, 0x0bc00000, 1, 0x0bc00000 }, | ||
| 1486 | { 0x3, 0x16, 0x2, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1487 | { 0x3, 0x16, 0x3, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1488 | { 0x4, 0x15, 0x0, 0, 0x20c00000, 8, 0x20c00000 }, | ||
| 1489 | { 0x4, 0x15, 0x1, 0, 0x21100000, 22, 0x21100000 }, | ||
| 1490 | { 0x4, 0x15, 0x2, 0, 0x20e00000, 9, 0x20e00000 }, | ||
| 1491 | { 0x4, 0x15, 0x3, 0, 0x21200000, 23, 0x21200000 }, | ||
| 1492 | { 0x4, 0x15, 0x4, 0, 0x20800000, 7, 0x20800000 }, | ||
| 1493 | { 0x4, 0x15, 0x5, 0, 0x21400000, 24, 0x21400000 }, | ||
| 1494 | { 0x4, 0x15, 0x6, 0, 0x0b000000, 18, 0x0b000000 }, | ||
| 1495 | { 0x4, 0x15, 0x7, 0, 0x0b800000, 3, 0x0b800000 }, | ||
| 1496 | { 0x4, 0x15, 0x8, 0, 0x20000000, 6, 0x20000000 }, | ||
| 1497 | { 0x4, 0x15, 0x9, 0, 0x21800000, 25, 0x21800000 }, | ||
| 1498 | { 0x4, 0x15, 0xa, 0, 0x0a000000, 2, 0x0a000000 }, | ||
| 1499 | { 0x4, 0x15, 0xb, 0, 0x0a000000, 17, 0x0a000000 }, | ||
| 1500 | { 0x4, 0x15, 0xc, 0, 0x20000000, 21, 0x20000000 }, | ||
| 1501 | { 0x4, 0x15, 0xd, 0, 0x21000000, 10, 0x21000000 }, | ||
| 1502 | { 0x4, 0x15, 0xe, 0, 0x08000000, 1, 0x08000000 }, | ||
| 1503 | { 0x4, 0x15, 0xf, 0, 0x08000000, 16, 0x08000000 }, | ||
| 1504 | { 0x4, 0x15, 0x10, 0, 0x22000000, 11, 0x22000000 }, | ||
| 1505 | { 0x4, 0x15, 0x11, 0, 0x22000000, 26, 0x22000000 }, | ||
| 1506 | { 0x4, 0x15, 0x12, 0, 0x0c000000, 4, 0x0c000000 }, | ||
| 1507 | { 0x4, 0x15, 0x13, 0, 0x0c000000, 19, 0x0c000000 }, | ||
| 1508 | { 0x4, 0x15, 0x14, 0, 0x24000000, 12, 0x24000000 }, | ||
| 1509 | { 0x4, 0x15, 0x15, 0, 0x24000000, 27, 0x24000000 }, | ||
| 1510 | { 0x4, 0x15, 0x16, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1511 | { 0x4, 0x15, 0x17, 0, 0x00000000, 15, 0x00000000 }, | ||
| 1512 | { 0x4, 0x15, 0x18, 0, 0x28000000, 13, 0x28000000 }, | ||
| 1513 | { 0x4, 0x15, 0x19, 0, 0x28000000, 28, 0x28000000 }, | ||
| 1514 | { 0x4, 0x15, 0x1a, 0, 0x10000000, 5, 0x10000000 }, | ||
| 1515 | { 0x4, 0x15, 0x1b, 0, 0x10000000, 20, 0x10000000 }, | ||
| 1516 | { 0x4, 0x15, 0x1c, 0, 0x30000000, 14, 0x30000000 }, | ||
| 1517 | { 0x4, 0x15, 0x1d, 0, 0x30000000, 29, 0x30000000 }, | ||
| 1518 | { 0x4, 0x0, 0x0, 0, 0x0b000000, 0, 0x00000000 }, | ||
| 1519 | { 0x4, 0x0, 0x1, 0, 0x0b800000, 1, 0x00000000 }, | ||
| 1520 | { 0x4, 0x1, 0x0, 0, 0x20de0000, 3, 0x000e0000 }, | ||
| 1521 | { 0x4, 0x1, 0x1, 0, 0x210e0000, 7, 0x000e0000 }, | ||
| 1522 | { 0x4, 0x1, 0x2, 0, 0x20dc0000, 2, 0x000c0000 }, | ||
| 1523 | { 0x4, 0x1, 0x3, 0, 0x210c0000, 6, 0x000c0000 }, | ||
| 1524 | { 0x4, 0x1, 0x4, 0, 0x20d80000, 1, 0x00080000 }, | ||
| 1525 | { 0x4, 0x1, 0x5, 0, 0x21080000, 5, 0x00080000 }, | ||
| 1526 | { 0x4, 0x1, 0x6, 0, 0x20d00000, 0, 0x00000000 }, | ||
| 1527 | { 0x4, 0x1, 0x7, 0, 0x21000000, 4, 0x00000000 }, | ||
| 1528 | { 0x4, 0x2, 0x0, 0, 0x0b040000, 0, 0x00000000 }, | ||
| 1529 | { 0x4, 0x2, 0x1, 0, 0x0b840000, 1, 0x00000000 }, | ||
| 1530 | { 0x4, 0x3, 0x0, 0, 0x0b230000, 0, 0x00000000 }, | ||
| 1531 | { 0x4, 0x3, 0x1, 0, 0x0ba30000, 1, 0x00000000 }, | ||
| 1532 | { 0x4, 0x4, 0x0, 0, 0x0b050000, 0, 0x00000000 }, | ||
| 1533 | { 0x4, 0x4, 0x1, 0, 0x0b850000, 1, 0x00000000 }, | ||
| 1534 | { 0x4, 0x5, 0x0, 0, 0x0b060000, 0, 0x00000000 }, | ||
| 1535 | { 0x4, 0x5, 0x1, 0, 0x0b070000, 1, 0x00010000 }, | ||
| 1536 | { 0x4, 0x5, 0x2, 0, 0x0b080000, 2, 0x00020000 }, | ||
| 1537 | { 0x4, 0x5, 0x3, 0, 0x0b090000, 3, 0x00030000 }, | ||
| 1538 | { 0x4, 0x5, 0x4, 0, 0x0b0a0000, 4, 0x00040000 }, | ||
| 1539 | { 0x4, 0x5, 0x5, 0, 0x0b0b0000, 5, 0x00050000 }, | ||
| 1540 | { 0x4, 0x5, 0x6, 0, 0x0b0c0000, 6, 0x00060000 }, | ||
| 1541 | { 0x4, 0x5, 0x7, 0, 0x0b0d0000, 7, 0x00070000 }, | ||
| 1542 | { 0x4, 0x5, 0x8, 0, 0x0b0e0000, 8, 0x00080000 }, | ||
| 1543 | { 0x4, 0x5, 0x9, 0, 0x0b860000, 9, 0x00000000 }, | ||
| 1544 | { 0x4, 0x5, 0xa, 0, 0x0b870000, 10, 0x00010000 }, | ||
| 1545 | { 0x4, 0x5, 0xb, 0, 0x0b880000, 11, 0x00020000 }, | ||
| 1546 | { 0x4, 0x5, 0xc, 0, 0x0b890000, 12, 0x00030000 }, | ||
| 1547 | { 0x4, 0x5, 0xd, 0, 0x0b8a0000, 13, 0x00040000 }, | ||
| 1548 | { 0x4, 0x5, 0xe, 0, 0x0b8b0000, 14, 0x00050000 }, | ||
| 1549 | { 0x4, 0x5, 0xf, 0, 0x0b8c0000, 15, 0x00060000 }, | ||
| 1550 | { 0x4, 0x5, 0x10, 0, 0x0b8d0000, 16, 0x00070000 }, | ||
| 1551 | { 0x4, 0x5, 0x11, 0, 0x0b8e0000, 17, 0x00080000 }, | ||
| 1552 | { 0x4, 0x6, 0x0, 0, 0x0b650000, 0, 0x00000000 }, | ||
| 1553 | { 0x4, 0x6, 0x1, 0, 0x0be50000, 1, 0x00000000 }, | ||
| 1554 | { 0x4, 0x7, 0x0, 0, 0x20df0000, 0, 0x00000000 }, | ||
| 1555 | { 0x4, 0x7, 0x1, 0, 0x210f0000, 1, 0x00000000 }, | ||
| 1556 | { 0x4, 0x8, 0x0, 0, 0x0b3e0000, 0, 0x00000000 }, | ||
| 1557 | { 0x4, 0x8, 0x1, 0, 0x0bbe0000, 1, 0x00000000 }, | ||
| 1558 | { 0x4, 0x9, 0x0, 0, 0x0b3d0000, 0, 0x00000000 }, | ||
| 1559 | { 0x4, 0x9, 0x1, 0, 0x0bbd0000, 1, 0x00000000 }, | ||
| 1560 | { 0x4, 0xa, 0x0, 0, 0x0b1e0000, 0, 0x00000000 }, | ||
| 1561 | { 0x4, 0xa, 0x1, 0, 0x0b9e0000, 1, 0x00000000 }, | ||
| 1562 | { 0x4, 0xb, 0x0, 0, 0x0b150000, 0, 0x00000000 }, | ||
| 1563 | { 0x4, 0xb, 0x1, 0, 0x0b160000, 1, 0x00010000 }, | ||
| 1564 | { 0x4, 0xb, 0x2, 0, 0x0b170000, 2, 0x00020000 }, | ||
| 1565 | { 0x4, 0xb, 0x3, 0, 0x0b180000, 3, 0x00030000 }, | ||
| 1566 | { 0x4, 0xb, 0x4, 0, 0x0b190000, 4, 0x00040000 }, | ||
| 1567 | { 0x4, 0xb, 0x5, 0, 0x0b1a0000, 5, 0x00050000 }, | ||
| 1568 | { 0x4, 0xb, 0x6, 0, 0x0b1b0000, 6, 0x00060000 }, | ||
| 1569 | { 0x4, 0xb, 0x7, 0, 0x0b1c0000, 7, 0x00070000 }, | ||
| 1570 | { 0x4, 0xb, 0x8, 0, 0x0b1d0000, 8, 0x00080000 }, | ||
| 1571 | { 0x4, 0xb, 0x9, 0, 0x0b950000, 9, 0x00000000 }, | ||
| 1572 | { 0x4, 0xb, 0xa, 0, 0x0b960000, 10, 0x00010000 }, | ||
| 1573 | { 0x4, 0xb, 0xb, 0, 0x0b970000, 11, 0x00020000 }, | ||
| 1574 | { 0x4, 0xb, 0xc, 0, 0x0b980000, 12, 0x00030000 }, | ||
| 1575 | { 0x4, 0xb, 0xd, 0, 0x0b990000, 13, 0x00040000 }, | ||
| 1576 | { 0x4, 0xb, 0xe, 0, 0x0b9a0000, 14, 0x00050000 }, | ||
| 1577 | { 0x4, 0xb, 0xf, 0, 0x0b9b0000, 15, 0x00060000 }, | ||
| 1578 | { 0x4, 0xb, 0x10, 0, 0x0b9c0000, 16, 0x00070000 }, | ||
| 1579 | { 0x4, 0xb, 0x11, 0, 0x0b9d0000, 17, 0x00080000 }, | ||
| 1580 | { 0x4, 0xc, 0x0, 0, 0x0b660000, 0, 0x00000000 }, | ||
| 1581 | { 0x4, 0xc, 0x1, 0, 0x0be60000, 1, 0x00000000 }, | ||
| 1582 | { 0x4, 0xd, 0x0, 0, 0x0b1f0000, 0, 0x00000000 }, | ||
| 1583 | { 0x4, 0xd, 0x1, 0, 0x0b200000, 1, 0x00010000 }, | ||
| 1584 | { 0x4, 0xd, 0x2, 0, 0x0b210000, 2, 0x00020000 }, | ||
| 1585 | { 0x4, 0xd, 0x3, 0, 0x0b220000, 3, 0x00030000 }, | ||
| 1586 | { 0x4, 0xd, 0x4, 0, 0x0b9f0000, 4, 0x00000000 }, | ||
| 1587 | { 0x4, 0xd, 0x5, 0, 0x0ba00000, 5, 0x00010000 }, | ||
| 1588 | { 0x4, 0xd, 0x6, 0, 0x0ba10000, 6, 0x00020000 }, | ||
| 1589 | { 0x4, 0xd, 0x7, 0, 0x0ba20000, 7, 0x00030000 }, | ||
| 1590 | { 0x4, 0xe, 0x0, 0, 0x0b0f0000, 0, 0x00000000 }, | ||
| 1591 | { 0x4, 0xe, 0x1, 0, 0x0b100000, 1, 0x00010000 }, | ||
| 1592 | { 0x4, 0xe, 0x2, 0, 0x0b110000, 2, 0x00020000 }, | ||
| 1593 | { 0x4, 0xe, 0x3, 0, 0x0b120000, 3, 0x00030000 }, | ||
| 1594 | { 0x4, 0xe, 0x4, 0, 0x0b130000, 4, 0x00040000 }, | ||
| 1595 | { 0x4, 0xe, 0x5, 0, 0x0b140000, 5, 0x00050000 }, | ||
| 1596 | { 0x4, 0xe, 0x6, 0, 0x0b8f0000, 6, 0x00000000 }, | ||
| 1597 | { 0x4, 0xe, 0x7, 0, 0x0b900000, 7, 0x00010000 }, | ||
| 1598 | { 0x4, 0xe, 0x8, 0, 0x0b910000, 8, 0x00020000 }, | ||
| 1599 | { 0x4, 0xe, 0x9, 0, 0x0b920000, 9, 0x00030000 }, | ||
| 1600 | { 0x4, 0xe, 0xa, 0, 0x0b930000, 10, 0x00040000 }, | ||
| 1601 | { 0x4, 0xe, 0xb, 0, 0x0b940000, 11, 0x00050000 }, | ||
| 1602 | { 0x4, 0x10, 0x0, 0, 0x0b240000, 0, 0x00000000 }, | ||
| 1603 | { 0x4, 0x10, 0x1, 0, 0x0ba40000, 1, 0x00000000 }, | ||
| 1604 | { 0x4, 0x11, 0x0, 0, 0x0b020000, 0, 0x00000000 }, | ||
| 1605 | { 0x4, 0x11, 0x1, 0, 0x0b820000, 1, 0x00000000 }, | ||
| 1606 | { 0x4, 0x12, 0x0, 0, 0x0b030000, 0, 0x00000000 }, | ||
| 1607 | { 0x4, 0x12, 0x1, 0, 0x0b830000, 1, 0x00000000 }, | ||
| 1608 | { 0x4, 0x17, 0x0, 0, 0x0b640000, 0, 0x00000000 }, | ||
| 1609 | { 0x4, 0x17, 0x1, 0, 0x0be40000, 1, 0x00000000 }, | ||
| 1610 | { 0x4, 0x18, 0x0, 0, 0x0b600000, 0, 0x00000000 }, | ||
| 1611 | { 0x4, 0x18, 0x1, 0, 0x0be00000, 1, 0x00000000 }, | ||
| 1612 | { 0x4, 0x18, 0x2, 0, 0x00000000, 0, 0x00000000 }, | ||
| 1613 | { 0x4, 0x18, 0x3, 0, 0x00000000, 0, 0x00000000 } | ||
| 1614 | }; | ||
| 1615 | |||
| 1616 | static void cbbcentralnoc_parse_routeid(struct tegra194_cbb_aperture *info, u64 routeid) | ||
| 1617 | { | ||
| 1618 | info->initflow = FIELD_GET(CBB_NOC_INITFLOW, routeid); | ||
| 1619 | info->targflow = FIELD_GET(CBB_NOC_TARGFLOW, routeid); | ||
| 1620 | info->targ_subrange = FIELD_GET(CBB_NOC_TARG_SUBRANGE, routeid); | ||
| 1621 | info->seqid = FIELD_GET(CBB_NOC_SEQID, routeid); | ||
| 1622 | } | ||
| 1623 | |||
| 1624 | static void bpmpnoc_parse_routeid(struct tegra194_cbb_aperture *info, u64 routeid) | ||
| 1625 | { | ||
| 1626 | info->initflow = FIELD_GET(BPMP_NOC_INITFLOW, routeid); | ||
| 1627 | info->targflow = FIELD_GET(BPMP_NOC_TARGFLOW, routeid); | ||
| 1628 | info->targ_subrange = FIELD_GET(BPMP_NOC_TARG_SUBRANGE, routeid); | ||
| 1629 | info->seqid = FIELD_GET(BPMP_NOC_SEQID, routeid); | ||
| 1630 | } | ||
| 1631 | |||
| 1632 | static void aonnoc_parse_routeid(struct tegra194_cbb_aperture *info, u64 routeid) | ||
| 1633 | { | ||
| 1634 | info->initflow = FIELD_GET(AON_NOC_INITFLOW, routeid); | ||
| 1635 | info->targflow = FIELD_GET(AON_NOC_TARGFLOW, routeid); | ||
| 1636 | info->targ_subrange = FIELD_GET(AON_NOC_TARG_SUBRANGE, routeid); | ||
| 1637 | info->seqid = FIELD_GET(AON_NOC_SEQID, routeid); | ||
| 1638 | } | ||
| 1639 | |||
| 1640 | static void scenoc_parse_routeid(struct tegra194_cbb_aperture *info, u64 routeid) | ||
| 1641 | { | ||
| 1642 | info->initflow = FIELD_GET(SCE_NOC_INITFLOW, routeid); | ||
| 1643 | info->targflow = FIELD_GET(SCE_NOC_TARGFLOW, routeid); | ||
| 1644 | info->targ_subrange = FIELD_GET(SCE_NOC_TARG_SUBRANGE, routeid); | ||
| 1645 | info->seqid = FIELD_GET(SCE_NOC_SEQID, routeid); | ||
| 1646 | } | ||
| 1647 | |||
| 1648 | static void cbbcentralnoc_parse_userbits(struct tegra194_cbb_userbits *usrbits, u32 elog_5) | ||
| 1649 | { | ||
| 1650 | usrbits->axcache = FIELD_GET(CBB_NOC_AXCACHE, elog_5); | ||
| 1651 | usrbits->non_mod = FIELD_GET(CBB_NOC_NON_MOD, elog_5); | ||
| 1652 | usrbits->axprot = FIELD_GET(CBB_NOC_AXPROT, elog_5); | ||
| 1653 | usrbits->falconsec = FIELD_GET(CBB_NOC_FALCONSEC, elog_5); | ||
| 1654 | usrbits->grpsec = FIELD_GET(CBB_NOC_GRPSEC, elog_5); | ||
| 1655 | usrbits->vqc = FIELD_GET(CBB_NOC_VQC, elog_5); | ||
| 1656 | usrbits->mstr_id = FIELD_GET(CBB_NOC_MSTR_ID, elog_5) - 1; | ||
| 1657 | usrbits->axi_id = FIELD_GET(CBB_NOC_AXI_ID, elog_5); | ||
| 1658 | } | ||
| 1659 | |||
| 1660 | static void clusternoc_parse_userbits(struct tegra194_cbb_userbits *usrbits, u32 elog_5) | ||
| 1661 | { | ||
| 1662 | usrbits->axcache = FIELD_GET(CLUSTER_NOC_AXCACHE, elog_5); | ||
| 1663 | usrbits->axprot = FIELD_GET(CLUSTER_NOC_AXCACHE, elog_5); | ||
| 1664 | usrbits->falconsec = FIELD_GET(CLUSTER_NOC_FALCONSEC, elog_5); | ||
| 1665 | usrbits->grpsec = FIELD_GET(CLUSTER_NOC_GRPSEC, elog_5); | ||
| 1666 | usrbits->vqc = FIELD_GET(CLUSTER_NOC_VQC, elog_5); | ||
| 1667 | usrbits->mstr_id = FIELD_GET(CLUSTER_NOC_MSTR_ID, elog_5) - 1; | ||
| 1668 | } | ||
| 1669 | |||
| 1670 | static void tegra194_cbb_fault_enable(struct tegra_cbb *cbb) | ||
| 1671 | { | ||
| 1672 | struct tegra194_cbb *priv = to_tegra194_cbb(cbb); | ||
| 1673 | |||
| 1674 | writel(1, priv->regs + ERRLOGGER_0_FAULTEN_0); | ||
| 1675 | writel(1, priv->regs + ERRLOGGER_1_FAULTEN_0); | ||
| 1676 | writel(1, priv->regs + ERRLOGGER_2_FAULTEN_0); | ||
| 1677 | } | ||
| 1678 | |||
| 1679 | static void tegra194_cbb_stall_enable(struct tegra_cbb *cbb) | ||
| 1680 | { | ||
| 1681 | struct tegra194_cbb *priv = to_tegra194_cbb(cbb); | ||
| 1682 | |||
| 1683 | writel(1, priv->regs + ERRLOGGER_0_STALLEN_0); | ||
| 1684 | writel(1, priv->regs + ERRLOGGER_1_STALLEN_0); | ||
| 1685 | writel(1, priv->regs + ERRLOGGER_2_STALLEN_0); | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | static void tegra194_cbb_error_clear(struct tegra_cbb *cbb) | ||
| 1689 | { | ||
| 1690 | struct tegra194_cbb *priv = to_tegra194_cbb(cbb); | ||
| 1691 | |||
| 1692 | writel(1, priv->regs + ERRLOGGER_0_ERRCLR_0); | ||
| 1693 | writel(1, priv->regs + ERRLOGGER_1_ERRCLR_0); | ||
| 1694 | writel(1, priv->regs + ERRLOGGER_2_ERRCLR_0); | ||
| 1695 | dsb(sy); | ||
| 1696 | } | ||
| 1697 | |||
| 1698 | static u32 tegra194_cbb_get_status(struct tegra_cbb *cbb) | ||
| 1699 | { | ||
| 1700 | struct tegra194_cbb *priv = to_tegra194_cbb(cbb); | ||
| 1701 | u32 value; | ||
| 1702 | |||
| 1703 | value = readl(priv->regs + ERRLOGGER_0_ERRVLD_0); | ||
| 1704 | value |= (readl(priv->regs + ERRLOGGER_1_ERRVLD_0) << 1); | ||
| 1705 | value |= (readl(priv->regs + ERRLOGGER_2_ERRVLD_0) << 2); | ||
| 1706 | |||
| 1707 | dsb(sy); | ||
| 1708 | return value; | ||
| 1709 | } | ||
| 1710 | |||
| 1711 | static u32 tegra194_axi2apb_status(void __iomem *addr) | ||
| 1712 | { | ||
| 1713 | u32 value; | ||
| 1714 | |||
| 1715 | value = readl(addr + DMAAPB_X_RAW_INTERRUPT_STATUS); | ||
| 1716 | writel(0xffffffff, addr + DMAAPB_X_RAW_INTERRUPT_STATUS); | ||
| 1717 | |||
| 1718 | return value; | ||
| 1719 | } | ||
| 1720 | |||
| 1721 | static bool tegra194_axi2apb_fatal(struct seq_file *file, unsigned int bridge, u32 status) | ||
| 1722 | { | ||
| 1723 | bool is_fatal = true; | ||
| 1724 | size_t i; | ||
| 1725 | |||
| 1726 | for (i = 0; i < ARRAY_SIZE(tegra194_axi2apb_error); i++) { | ||
| 1727 | if (status & BIT(i)) { | ||
| 1728 | tegra_cbb_print_err(file, "\t AXI2APB_%d bridge error: %s\n", | ||
| 1729 | bridge + 1, tegra194_axi2apb_error[i]); | ||
| 1730 | if (strstr(tegra194_axi2apb_error[i], "Firewall")) | ||
| 1731 | is_fatal = false; | ||
| 1732 | } | ||
| 1733 | } | ||
| 1734 | |||
| 1735 | return is_fatal; | ||
| 1736 | } | ||
| 1737 | |||
| 1738 | /* | ||
| 1739 | * Fetch InitlocalAddress from NOC Aperture lookup table | ||
| 1740 | * using Targflow, Targsubrange | ||
| 1741 | */ | ||
| 1742 | static u32 get_init_localaddress(const struct tegra194_cbb_aperture *info, | ||
| 1743 | const struct tegra194_cbb_aperture *aper, unsigned int max) | ||
| 1744 | { | ||
| 1745 | unsigned int t_f = 0, t_sr = 0; | ||
| 1746 | u32 addr = 0; | ||
| 1747 | |||
| 1748 | for (t_f = 0; t_f < max; t_f++) { | ||
| 1749 | if (aper[t_f].targflow == info->targflow) { | ||
| 1750 | t_sr = t_f; | ||
| 1751 | |||
| 1752 | do { | ||
| 1753 | if (aper[t_sr].targ_subrange == info->targ_subrange) { | ||
| 1754 | addr = aper[t_sr].init_localaddress; | ||
| 1755 | return addr; | ||
| 1756 | } | ||
| 1757 | |||
| 1758 | if (t_sr >= max) | ||
| 1759 | return 0; | ||
| 1760 | |||
| 1761 | t_sr++; | ||
| 1762 | } while (aper[t_sr].targflow == aper[t_sr - 1].targflow); | ||
| 1763 | |||
| 1764 | t_f = t_sr; | ||
| 1765 | } | ||
| 1766 | } | ||
| 1767 | |||
| 1768 | return addr; | ||
| 1769 | } | ||
| 1770 | |||
| 1771 | static void print_errlog5(struct seq_file *file, struct tegra194_cbb *cbb) | ||
| 1772 | { | ||
| 1773 | struct tegra194_cbb_userbits userbits; | ||
| 1774 | |||
| 1775 | cbb->noc->parse_userbits(&userbits, cbb->errlog5); | ||
| 1776 | |||
| 1777 | if (!strcmp(cbb->noc->name, "cbb-noc")) { | ||
| 1778 | tegra_cbb_print_err(file, "\t Non-Modify\t\t: %#x\n", userbits.non_mod); | ||
| 1779 | tegra_cbb_print_err(file, "\t AXI ID\t\t: %#x\n", userbits.axi_id); | ||
| 1780 | } | ||
| 1781 | |||
| 1782 | tegra_cbb_print_err(file, "\t Master ID\t\t: %s\n", | ||
| 1783 | cbb->noc->master_id[userbits.mstr_id]); | ||
| 1784 | tegra_cbb_print_err(file, "\t Security Group(GRPSEC): %#x\n", userbits.grpsec); | ||
| 1785 | tegra_cbb_print_cache(file, userbits.axcache); | ||
| 1786 | tegra_cbb_print_prot(file, userbits.axprot); | ||
| 1787 | tegra_cbb_print_err(file, "\t FALCONSEC\t\t: %#x\n", userbits.falconsec); | ||
| 1788 | tegra_cbb_print_err(file, "\t Virtual Queuing Channel(VQC): %#x\n", userbits.vqc); | ||
| 1789 | } | ||
| 1790 | |||
| 1791 | /* | ||
| 1792 | * Fetch Base Address/InitlocalAddress from NOC aperture lookup table using TargFlow & | ||
| 1793 | * Targ_subRange extracted from RouteId. Perform address reconstruction as below: | ||
| 1794 | * | ||
| 1795 | * Address = Base Address + (ErrLog3 + ErrLog4) | ||
| 1796 | */ | ||
| 1797 | static void | ||
| 1798 | print_errlog3_4(struct seq_file *file, u32 errlog3, u32 errlog4, | ||
| 1799 | const struct tegra194_cbb_aperture *info, | ||
| 1800 | const struct tegra194_cbb_aperture *aperture, unsigned int max) | ||
| 1801 | { | ||
| 1802 | u64 addr = (u64)errlog4 << 32 | errlog3; | ||
| 1803 | |||
| 1804 | /* | ||
| 1805 | * If errlog4[7] = "1", then it's a joker entry. Joker entries are a rare phenomenon and | ||
| 1806 | * such addresses are not reliable. Debugging should be done using only the RouteId | ||
| 1807 | * information. | ||
| 1808 | */ | ||
| 1809 | if (errlog4 & 0x80) | ||
| 1810 | tegra_cbb_print_err(file, "\t debug using RouteId alone as below address is a " | ||
| 1811 | "joker entry and not reliable"); | ||
| 1812 | |||
| 1813 | addr += get_init_localaddress(info, aperture, max); | ||
| 1814 | |||
| 1815 | tegra_cbb_print_err(file, "\t Address accessed\t: %#llx\n", addr); | ||
| 1816 | } | ||
| 1817 | |||
| 1818 | /* | ||
| 1819 | * Get RouteId from ErrLog1+ErrLog2 registers and fetch values of | ||
| 1820 | * InitFlow, TargFlow, Targ_subRange and SeqId values from RouteId | ||
| 1821 | */ | ||
| 1822 | static void | ||
| 1823 | print_errlog1_2(struct seq_file *file, struct tegra194_cbb *cbb, | ||
| 1824 | struct tegra194_cbb_aperture *info) | ||
| 1825 | { | ||
| 1826 | u64 routeid = (u64)cbb->errlog2 << 32 | cbb->errlog1; | ||
| 1827 | u32 seqid = 0; | ||
| 1828 | |||
| 1829 | tegra_cbb_print_err(file, "\t RouteId\t\t: %#llx\n", routeid); | ||
| 1830 | |||
| 1831 | cbb->noc->parse_routeid(info, routeid); | ||
| 1832 | |||
| 1833 | tegra_cbb_print_err(file, "\t InitFlow\t\t: %s\n", | ||
| 1834 | cbb->noc->routeid_initflow[info->initflow]); | ||
| 1835 | |||
| 1836 | tegra_cbb_print_err(file, "\t Targflow\t\t: %s\n", | ||
| 1837 | cbb->noc->routeid_targflow[info->targflow]); | ||
| 1838 | |||
| 1839 | tegra_cbb_print_err(file, "\t TargSubRange\t\t: %d\n", info->targ_subrange); | ||
| 1840 | tegra_cbb_print_err(file, "\t SeqId\t\t\t: %d\n", seqid); | ||
| 1841 | } | ||
| 1842 | |||
| 1843 | /* | ||
| 1844 | * Print transcation type, error code and description from ErrLog0 for all | ||
| 1845 | * errors. For NOC slave errors, all relevant error info is printed using | ||
| 1846 | * ErrLog0 only. But additional information is printed for errors from | ||
| 1847 | * APB slaves because for them: | ||
| 1848 | * - All errors are logged as SLV(slave) errors due to APB having only single | ||
| 1849 | * bit pslverr to report all errors. | ||
| 1850 | * - Exact cause is printed by reading DMAAPB_X_RAW_INTERRUPT_STATUS register. | ||
| 1851 | * - The driver prints information showing AXI2APB bridge and exact error | ||
| 1852 | * only if there is error in any AXI2APB slave. | ||
| 1853 | * - There is still no way to disambiguate a DEC error from SLV error type. | ||
| 1854 | */ | ||
| 1855 | static bool print_errlog0(struct seq_file *file, struct tegra194_cbb *cbb) | ||
| 1856 | { | ||
| 1857 | struct tegra194_cbb_packet_header hdr; | ||
| 1858 | bool is_fatal = true; | ||
| 1859 | |||
| 1860 | hdr.lock = cbb->errlog0 & 0x1; | ||
| 1861 | hdr.opc = FIELD_GET(CBB_ERR_OPC, cbb->errlog0); | ||
| 1862 | hdr.errcode = FIELD_GET(CBB_ERR_ERRCODE, cbb->errlog0); | ||
| 1863 | hdr.len1 = FIELD_GET(CBB_ERR_LEN1, cbb->errlog0); | ||
| 1864 | hdr.format = (cbb->errlog0 >> 31); | ||
| 1865 | |||
| 1866 | tegra_cbb_print_err(file, "\t Transaction Type\t: %s\n", | ||
| 1867 | tegra194_cbb_trantype[hdr.opc]); | ||
| 1868 | tegra_cbb_print_err(file, "\t Error Code\t\t: %s\n", | ||
| 1869 | tegra194_cbb_errors[hdr.errcode].code); | ||
| 1870 | tegra_cbb_print_err(file, "\t Error Source\t\t: %s\n", | ||
| 1871 | tegra194_cbb_errors[hdr.errcode].source); | ||
| 1872 | tegra_cbb_print_err(file, "\t Error Description\t: %s\n", | ||
| 1873 | tegra194_cbb_errors[hdr.errcode].desc); | ||
| 1874 | |||
| 1875 | /* | ||
| 1876 | * Do not crash system for errors which are only notifications to indicate a transaction | ||
| 1877 | * was not allowed to be attempted. | ||
| 1878 | */ | ||
| 1879 | if (!strcmp(tegra194_cbb_errors[hdr.errcode].code, "SEC") || | ||
| 1880 | !strcmp(tegra194_cbb_errors[hdr.errcode].code, "DEC") || | ||
| 1881 | !strcmp(tegra194_cbb_errors[hdr.errcode].code, "UNS") || | ||
| 1882 | !strcmp(tegra194_cbb_errors[hdr.errcode].code, "DISC")) { | ||
| 1883 | is_fatal = false; | ||
| 1884 | } else if (!strcmp(tegra194_cbb_errors[hdr.errcode].code, "SLV") && | ||
| 1885 | cbb->num_bridges > 0) { | ||
| 1886 | unsigned int i; | ||
| 1887 | u32 status; | ||
| 1888 | |||
| 1889 | /* For all SLV errors, read DMAAPB_X_RAW_INTERRUPT_STATUS | ||
| 1890 | * register to get error status for all AXI2APB bridges. | ||
| 1891 | * Print bridge details if a bit is set in a bridge's | ||
| 1892 | * status register due to error in a APB slave connected | ||
| 1893 | * to that bridge. For other NOC slaves, none of the status | ||
| 1894 | * register will be set. | ||
| 1895 | */ | ||
| 1896 | |||
| 1897 | for (i = 0; i < cbb->num_bridges; i++) { | ||
| 1898 | status = tegra194_axi2apb_status(cbb->bridges[i].base); | ||
| 1899 | |||
| 1900 | if (status) | ||
| 1901 | is_fatal = tegra194_axi2apb_fatal(file, i, status); | ||
| 1902 | } | ||
| 1903 | } | ||
| 1904 | |||
| 1905 | tegra_cbb_print_err(file, "\t Packet header Lock\t: %d\n", hdr.lock); | ||
| 1906 | tegra_cbb_print_err(file, "\t Packet header Len1\t: %d\n", hdr.len1); | ||
| 1907 | |||
| 1908 | if (hdr.format) | ||
| 1909 | tegra_cbb_print_err(file, "\t NOC protocol version\t: %s\n", | ||
| 1910 | "version >= 2.7"); | ||
| 1911 | else | ||
| 1912 | tegra_cbb_print_err(file, "\t NOC protocol version\t: %s\n", | ||
| 1913 | "version < 2.7"); | ||
| 1914 | |||
| 1915 | return is_fatal; | ||
| 1916 | } | ||
| 1917 | |||
| 1918 | /* | ||
| 1919 | * Print debug information about failed transaction using | ||
| 1920 | * ErrLog registers of error loggger having ErrVld set | ||
| 1921 | */ | ||
| 1922 | static bool print_errloggerX_info(struct seq_file *file, struct tegra194_cbb *cbb, | ||
| 1923 | int errloggerX) | ||
| 1924 | { | ||
| 1925 | struct tegra194_cbb_aperture info = { 0, }; | ||
| 1926 | bool is_fatal = true; | ||
| 1927 | |||
| 1928 | tegra_cbb_print_err(file, "\tError Logger\t\t: %d\n", errloggerX); | ||
| 1929 | |||
| 1930 | if (errloggerX == 0) { | ||
| 1931 | cbb->errlog0 = readl(cbb->regs + ERRLOGGER_0_ERRLOG0_0); | ||
| 1932 | cbb->errlog1 = readl(cbb->regs + ERRLOGGER_0_ERRLOG1_0); | ||
| 1933 | cbb->errlog2 = readl(cbb->regs + ERRLOGGER_0_RSVD_00_0); | ||
| 1934 | cbb->errlog3 = readl(cbb->regs + ERRLOGGER_0_ERRLOG3_0); | ||
| 1935 | cbb->errlog4 = readl(cbb->regs + ERRLOGGER_0_ERRLOG4_0); | ||
| 1936 | cbb->errlog5 = readl(cbb->regs + ERRLOGGER_0_ERRLOG5_0); | ||
| 1937 | } else if (errloggerX == 1) { | ||
| 1938 | cbb->errlog0 = readl(cbb->regs + ERRLOGGER_1_ERRLOG0_0); | ||
| 1939 | cbb->errlog1 = readl(cbb->regs + ERRLOGGER_1_ERRLOG1_0); | ||
| 1940 | cbb->errlog2 = readl(cbb->regs + ERRLOGGER_1_RSVD_00_0); | ||
| 1941 | cbb->errlog3 = readl(cbb->regs + ERRLOGGER_1_ERRLOG3_0); | ||
| 1942 | cbb->errlog4 = readl(cbb->regs + ERRLOGGER_1_ERRLOG4_0); | ||
| 1943 | cbb->errlog5 = readl(cbb->regs + ERRLOGGER_1_ERRLOG5_0); | ||
| 1944 | } else if (errloggerX == 2) { | ||
| 1945 | cbb->errlog0 = readl(cbb->regs + ERRLOGGER_2_ERRLOG0_0); | ||
| 1946 | cbb->errlog1 = readl(cbb->regs + ERRLOGGER_2_ERRLOG1_0); | ||
| 1947 | cbb->errlog2 = readl(cbb->regs + ERRLOGGER_2_RSVD_00_0); | ||
| 1948 | cbb->errlog3 = readl(cbb->regs + ERRLOGGER_2_ERRLOG3_0); | ||
| 1949 | cbb->errlog4 = readl(cbb->regs + ERRLOGGER_2_ERRLOG4_0); | ||
| 1950 | cbb->errlog5 = readl(cbb->regs + ERRLOGGER_2_ERRLOG5_0); | ||
| 1951 | } | ||
| 1952 | |||
| 1953 | tegra_cbb_print_err(file, "\tErrLog0\t\t\t: %#x\n", cbb->errlog0); | ||
| 1954 | is_fatal = print_errlog0(file, cbb); | ||
| 1955 | |||
| 1956 | tegra_cbb_print_err(file, "\tErrLog1\t\t\t: %#x\n", cbb->errlog1); | ||
| 1957 | tegra_cbb_print_err(file, "\tErrLog2\t\t\t: %#x\n", cbb->errlog2); | ||
| 1958 | print_errlog1_2(file, cbb, &info); | ||
| 1959 | |||
| 1960 | tegra_cbb_print_err(file, "\tErrLog3\t\t\t: %#x\n", cbb->errlog3); | ||
| 1961 | tegra_cbb_print_err(file, "\tErrLog4\t\t\t: %#x\n", cbb->errlog4); | ||
| 1962 | print_errlog3_4(file, cbb->errlog3, cbb->errlog4, &info, cbb->noc->noc_aperture, | ||
| 1963 | cbb->noc->max_aperture); | ||
| 1964 | |||
| 1965 | tegra_cbb_print_err(file, "\tErrLog5\t\t\t: %#x\n", cbb->errlog5); | ||
| 1966 | |||
| 1967 | if (cbb->errlog5) | ||
| 1968 | print_errlog5(file, cbb); | ||
| 1969 | |||
| 1970 | return is_fatal; | ||
| 1971 | } | ||
| 1972 | |||
| 1973 | static bool print_errlog(struct seq_file *file, struct tegra194_cbb *cbb, u32 errvld) | ||
| 1974 | { | ||
| 1975 | bool is_fatal = true; | ||
| 1976 | |||
| 1977 | pr_crit("**************************************\n"); | ||
| 1978 | pr_crit("CPU:%d, Error:%s\n", smp_processor_id(), cbb->noc->name); | ||
| 1979 | |||
| 1980 | if (errvld & 0x1) | ||
| 1981 | is_fatal = print_errloggerX_info(file, cbb, 0); | ||
| 1982 | else if (errvld & 0x2) | ||
| 1983 | is_fatal = print_errloggerX_info(file, cbb, 1); | ||
| 1984 | else if (errvld & 0x4) | ||
| 1985 | is_fatal = print_errloggerX_info(file, cbb, 2); | ||
| 1986 | |||
| 1987 | tegra_cbb_error_clear(&cbb->base); | ||
| 1988 | tegra_cbb_print_err(file, "\t**************************************\n"); | ||
| 1989 | return is_fatal; | ||
| 1990 | } | ||
| 1991 | |||
| 1992 | #ifdef CONFIG_DEBUG_FS | ||
| 1993 | static DEFINE_MUTEX(cbb_err_mutex); | ||
| 1994 | |||
| 1995 | static int tegra194_cbb_debugfs_show(struct tegra_cbb *cbb, struct seq_file *file, void *data) | ||
| 1996 | { | ||
| 1997 | struct tegra_cbb *noc; | ||
| 1998 | |||
| 1999 | mutex_lock(&cbb_err_mutex); | ||
| 2000 | |||
| 2001 | list_for_each_entry(noc, &cbb_list, node) { | ||
| 2002 | struct tegra194_cbb *priv = to_tegra194_cbb(noc); | ||
| 2003 | u32 status; | ||
| 2004 | |||
| 2005 | status = tegra_cbb_get_status(noc); | ||
| 2006 | if (status) | ||
| 2007 | print_errlog(file, priv, status); | ||
| 2008 | } | ||
| 2009 | |||
| 2010 | mutex_unlock(&cbb_err_mutex); | ||
| 2011 | |||
| 2012 | return 0; | ||
| 2013 | } | ||
| 2014 | #endif | ||
| 2015 | |||
| 2016 | /* | ||
| 2017 | * Handler for CBB errors from different initiators | ||
| 2018 | */ | ||
| 2019 | static irqreturn_t tegra194_cbb_err_isr(int irq, void *data) | ||
| 2020 | { | ||
| 2021 | bool is_inband_err = false, is_fatal = false; | ||
| 2022 | //struct tegra194_cbb *cbb = data; | ||
| 2023 | struct tegra_cbb *noc; | ||
| 2024 | unsigned long flags; | ||
| 2025 | u8 mstr_id = 0; | ||
| 2026 | |||
| 2027 | spin_lock_irqsave(&cbb_lock, flags); | ||
| 2028 | |||
| 2029 | /* XXX only process interrupts for "cbb" instead of iterating over all NOCs? */ | ||
| 2030 | list_for_each_entry(noc, &cbb_list, node) { | ||
| 2031 | struct tegra194_cbb *priv = to_tegra194_cbb(noc); | ||
| 2032 | u32 status = 0; | ||
| 2033 | |||
| 2034 | status = tegra_cbb_get_status(noc); | ||
| 2035 | |||
| 2036 | if (status && ((irq == priv->sec_irq) || (irq == priv->nonsec_irq))) { | ||
| 2037 | tegra_cbb_print_err(NULL, "CPU:%d, Error: %s@%llx, irq=%d\n", | ||
| 2038 | smp_processor_id(), priv->noc->name, priv->res->start, | ||
| 2039 | irq); | ||
| 2040 | |||
| 2041 | mstr_id = FIELD_GET(USRBITS_MSTR_ID, priv->errlog5) - 1; | ||
| 2042 | is_fatal = print_errlog(NULL, priv, status); | ||
| 2043 | |||
| 2044 | /* | ||
| 2045 | * If illegal request is from CCPLEX(0x1) | ||
| 2046 | * initiator then call BUG() to crash system. | ||
| 2047 | */ | ||
| 2048 | if ((mstr_id == 0x1) && priv->noc->erd_mask_inband_err) | ||
| 2049 | is_inband_err = 1; | ||
| 2050 | } | ||
| 2051 | } | ||
| 2052 | |||
| 2053 | spin_unlock_irqrestore(&cbb_lock, flags); | ||
| 2054 | |||
| 2055 | if (is_inband_err) { | ||
| 2056 | if (is_fatal) | ||
| 2057 | BUG(); | ||
| 2058 | else | ||
| 2059 | WARN(true, "Warning due to CBB Error\n"); | ||
| 2060 | } | ||
| 2061 | |||
| 2062 | return IRQ_HANDLED; | ||
| 2063 | } | ||
| 2064 | |||
| 2065 | /* | ||
| 2066 | * Register handler for CBB_NONSECURE & CBB_SECURE interrupts | ||
| 2067 | * for reporting CBB errors | ||
| 2068 | */ | ||
| 2069 | static int tegra194_cbb_interrupt_enable(struct tegra_cbb *cbb) | ||
| 2070 | { | ||
| 2071 | struct tegra194_cbb *priv = to_tegra194_cbb(cbb); | ||
| 2072 | struct device *dev = cbb->dev; | ||
| 2073 | int err; | ||
| 2074 | |||
| 2075 | if (priv->sec_irq) { | ||
| 2076 | err = devm_request_irq(dev, priv->sec_irq, tegra194_cbb_err_isr, 0, dev_name(dev), | ||
| 2077 | priv); | ||
| 2078 | if (err) { | ||
| 2079 | dev_err(dev, "failed to register interrupt %u: %d\n", priv->sec_irq, err); | ||
| 2080 | return err; | ||
| 2081 | } | ||
| 2082 | } | ||
| 2083 | |||
| 2084 | if (priv->nonsec_irq) { | ||
| 2085 | err = devm_request_irq(dev, priv->nonsec_irq, tegra194_cbb_err_isr, 0, | ||
| 2086 | dev_name(dev), priv); | ||
| 2087 | if (err) { | ||
| 2088 | dev_err(dev, "failed to register interrupt %u: %d\n", priv->nonsec_irq, | ||
| 2089 | err); | ||
| 2090 | return err; | ||
| 2091 | } | ||
| 2092 | } | ||
| 2093 | |||
| 2094 | return 0; | ||
| 2095 | } | ||
| 2096 | |||
| 2097 | static void tegra194_cbb_error_enable(struct tegra_cbb *cbb) | ||
| 2098 | { | ||
| 2099 | /* | ||
| 2100 | * Set “StallEn=1” to enable queuing of error packets till | ||
| 2101 | * first is served & cleared | ||
| 2102 | */ | ||
| 2103 | tegra_cbb_stall_enable(cbb); | ||
| 2104 | |||
| 2105 | /* set “FaultEn=1” to enable error reporting signal “Fault” */ | ||
| 2106 | tegra_cbb_fault_enable(cbb); | ||
| 2107 | } | ||
| 2108 | |||
| 2109 | static const struct tegra_cbb_ops tegra194_cbb_ops = { | ||
| 2110 | .get_status = tegra194_cbb_get_status, | ||
| 2111 | .error_clear = tegra194_cbb_error_clear, | ||
| 2112 | .fault_enable = tegra194_cbb_fault_enable, | ||
| 2113 | .stall_enable = tegra194_cbb_stall_enable, | ||
| 2114 | .error_enable = tegra194_cbb_error_enable, | ||
| 2115 | .interrupt_enable = tegra194_cbb_interrupt_enable, | ||
| 2116 | #ifdef CONFIG_DEBUG_FS | ||
| 2117 | .debugfs_show = tegra194_cbb_debugfs_show, | ||
| 2118 | #endif | ||
| 2119 | }; | ||
| 2120 | |||
| 2121 | static struct tegra194_cbb_noc_data tegra194_cbb_central_noc_data = { | ||
| 2122 | .name = "cbb-noc", | ||
| 2123 | .erd_mask_inband_err = true, | ||
| 2124 | .master_id = tegra194_master_id, | ||
| 2125 | .noc_aperture = tegra194_cbbcentralnoc_apert_lookup, | ||
| 2126 | .max_aperture = ARRAY_SIZE(tegra194_cbbcentralnoc_apert_lookup), | ||
| 2127 | .routeid_initflow = tegra194_cbbcentralnoc_routeid_initflow, | ||
| 2128 | .routeid_targflow = tegra194_cbbcentralnoc_routeid_targflow, | ||
| 2129 | .parse_routeid = cbbcentralnoc_parse_routeid, | ||
| 2130 | .parse_userbits = cbbcentralnoc_parse_userbits | ||
| 2131 | }; | ||
| 2132 | |||
| 2133 | static struct tegra194_cbb_noc_data tegra194_aon_noc_data = { | ||
| 2134 | .name = "aon-noc", | ||
| 2135 | .erd_mask_inband_err = false, | ||
| 2136 | .master_id = tegra194_master_id, | ||
| 2137 | .noc_aperture = tegra194_aonnoc_aperture_lookup, | ||
| 2138 | .max_aperture = ARRAY_SIZE(tegra194_aonnoc_aperture_lookup), | ||
| 2139 | .routeid_initflow = tegra194_aonnoc_routeid_initflow, | ||
| 2140 | .routeid_targflow = tegra194_aonnoc_routeid_targflow, | ||
| 2141 | .parse_routeid = aonnoc_parse_routeid, | ||
| 2142 | .parse_userbits = clusternoc_parse_userbits | ||
| 2143 | }; | ||
| 2144 | |||
| 2145 | static struct tegra194_cbb_noc_data tegra194_bpmp_noc_data = { | ||
| 2146 | .name = "bpmp-noc", | ||
| 2147 | .erd_mask_inband_err = false, | ||
| 2148 | .master_id = tegra194_master_id, | ||
| 2149 | .noc_aperture = tegra194_bpmpnoc_apert_lookup, | ||
| 2150 | .max_aperture = ARRAY_SIZE(tegra194_bpmpnoc_apert_lookup), | ||
| 2151 | .routeid_initflow = tegra194_bpmpnoc_routeid_initflow, | ||
| 2152 | .routeid_targflow = tegra194_bpmpnoc_routeid_targflow, | ||
| 2153 | .parse_routeid = bpmpnoc_parse_routeid, | ||
| 2154 | .parse_userbits = clusternoc_parse_userbits | ||
| 2155 | }; | ||
| 2156 | |||
| 2157 | static struct tegra194_cbb_noc_data tegra194_rce_noc_data = { | ||
| 2158 | .name = "rce-noc", | ||
| 2159 | .erd_mask_inband_err = false, | ||
| 2160 | .master_id = tegra194_master_id, | ||
| 2161 | .noc_aperture = tegra194_scenoc_apert_lookup, | ||
| 2162 | .max_aperture = ARRAY_SIZE(tegra194_scenoc_apert_lookup), | ||
| 2163 | .routeid_initflow = tegra194_scenoc_routeid_initflow, | ||
| 2164 | .routeid_targflow = tegra194_scenoc_routeid_targflow, | ||
| 2165 | .parse_routeid = scenoc_parse_routeid, | ||
| 2166 | .parse_userbits = clusternoc_parse_userbits | ||
| 2167 | }; | ||
| 2168 | |||
| 2169 | static struct tegra194_cbb_noc_data tegra194_sce_noc_data = { | ||
| 2170 | .name = "sce-noc", | ||
| 2171 | .erd_mask_inband_err = false, | ||
| 2172 | .master_id = tegra194_master_id, | ||
| 2173 | .noc_aperture = tegra194_scenoc_apert_lookup, | ||
| 2174 | .max_aperture = ARRAY_SIZE(tegra194_scenoc_apert_lookup), | ||
| 2175 | .routeid_initflow = tegra194_scenoc_routeid_initflow, | ||
| 2176 | .routeid_targflow = tegra194_scenoc_routeid_targflow, | ||
| 2177 | .parse_routeid = scenoc_parse_routeid, | ||
| 2178 | .parse_userbits = clusternoc_parse_userbits | ||
| 2179 | }; | ||
| 2180 | |||
| 2181 | static const struct of_device_id tegra194_cbb_match[] = { | ||
| 2182 | { .compatible = "nvidia,tegra194-cbb-noc", .data = &tegra194_cbb_central_noc_data }, | ||
| 2183 | { .compatible = "nvidia,tegra194-aon-noc", .data = &tegra194_aon_noc_data }, | ||
| 2184 | { .compatible = "nvidia,tegra194-bpmp-noc", .data = &tegra194_bpmp_noc_data }, | ||
| 2185 | { .compatible = "nvidia,tegra194-rce-noc", .data = &tegra194_rce_noc_data }, | ||
| 2186 | { .compatible = "nvidia,tegra194-sce-noc", .data = &tegra194_sce_noc_data }, | ||
| 2187 | { /* sentinel */ } | ||
| 2188 | }; | ||
| 2189 | MODULE_DEVICE_TABLE(of, tegra194_cbb_match); | ||
| 2190 | |||
| 2191 | static int tegra194_cbb_get_bridges(struct tegra194_cbb *cbb, struct device_node *np) | ||
| 2192 | { | ||
| 2193 | struct tegra_cbb *entry; | ||
| 2194 | struct resource res; | ||
| 2195 | unsigned long flags; | ||
| 2196 | unsigned int i; | ||
| 2197 | int err; | ||
| 2198 | |||
| 2199 | spin_lock_irqsave(&cbb_lock, flags); | ||
| 2200 | |||
| 2201 | list_for_each_entry(entry, &cbb_list, node) { | ||
| 2202 | struct tegra194_cbb *priv = to_tegra194_cbb(entry); | ||
| 2203 | |||
| 2204 | if (priv->bridges) { | ||
| 2205 | cbb->num_bridges = priv->num_bridges; | ||
| 2206 | cbb->bridges = priv->bridges; | ||
| 2207 | break; | ||
| 2208 | } | ||
| 2209 | } | ||
| 2210 | |||
| 2211 | spin_unlock_irqrestore(&cbb_lock, flags); | ||
| 2212 | |||
| 2213 | if (!cbb->bridges) { | ||
| 2214 | while (of_address_to_resource(np, cbb->num_bridges, &res) == 0) | ||
| 2215 | cbb->num_bridges++; | ||
| 2216 | |||
| 2217 | cbb->bridges = devm_kcalloc(cbb->base.dev, cbb->num_bridges, | ||
| 2218 | sizeof(*cbb->bridges), GFP_KERNEL); | ||
| 2219 | if (!cbb->bridges) | ||
| 2220 | return -ENOMEM; | ||
| 2221 | |||
| 2222 | for (i = 0; i < cbb->num_bridges; i++) { | ||
| 2223 | err = of_address_to_resource(np, i, &cbb->bridges[i].res); | ||
| 2224 | if (err < 0) | ||
| 2225 | return err; | ||
| 2226 | |||
| 2227 | cbb->bridges[i].base = devm_ioremap_resource(cbb->base.dev, | ||
| 2228 | &cbb->bridges[i].res); | ||
| 2229 | if (IS_ERR(cbb->bridges[i].base)) { | ||
| 2230 | dev_err(cbb->base.dev, "failed to map AXI2APB range\n"); | ||
| 2231 | return PTR_ERR(cbb->bridges[i].base); | ||
| 2232 | } | ||
| 2233 | } | ||
| 2234 | } | ||
| 2235 | |||
| 2236 | if (cbb->num_bridges > 0) { | ||
| 2237 | dev_dbg(cbb->base.dev, "AXI2APB bridge info present:\n"); | ||
| 2238 | |||
| 2239 | for (i = 0; i < cbb->num_bridges; i++) | ||
| 2240 | dev_dbg(cbb->base.dev, " %u: %pR\n", i, &cbb->bridges[i].res); | ||
| 2241 | } | ||
| 2242 | |||
| 2243 | return 0; | ||
| 2244 | } | ||
| 2245 | |||
| 2246 | static int tegra194_cbb_probe(struct platform_device *pdev) | ||
| 2247 | { | ||
| 2248 | const struct tegra194_cbb_noc_data *noc; | ||
| 2249 | struct tegra194_cbb *cbb; | ||
| 2250 | struct device_node *np; | ||
| 2251 | unsigned long flags; | ||
| 2252 | int err; | ||
| 2253 | |||
| 2254 | noc = of_device_get_match_data(&pdev->dev); | ||
| 2255 | |||
| 2256 | if (noc->erd_mask_inband_err) { | ||
| 2257 | /* | ||
| 2258 | * Set Error Response Disable(ERD) bit to mask SError/inband | ||
| 2259 | * error and only trigger interrupts for illegal access from | ||
| 2260 | * CCPLEX initiator. | ||
| 2261 | */ | ||
| 2262 | err = tegra194_miscreg_mask_serror(); | ||
| 2263 | if (err) { | ||
| 2264 | dev_err(&pdev->dev, "couldn't mask inband errors\n"); | ||
| 2265 | return err; | ||
| 2266 | } | ||
| 2267 | } | ||
| 2268 | |||
| 2269 | cbb = devm_kzalloc(&pdev->dev, sizeof(*cbb), GFP_KERNEL); | ||
| 2270 | if (!cbb) | ||
| 2271 | return -ENOMEM; | ||
| 2272 | |||
| 2273 | INIT_LIST_HEAD(&cbb->base.node); | ||
| 2274 | cbb->base.ops = &tegra194_cbb_ops; | ||
| 2275 | cbb->base.dev = &pdev->dev; | ||
| 2276 | cbb->noc = noc; | ||
| 2277 | |||
| 2278 | cbb->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &cbb->res); | ||
| 2279 | if (IS_ERR(cbb->regs)) | ||
| 2280 | return PTR_ERR(cbb->regs); | ||
| 2281 | |||
| 2282 | err = tegra_cbb_get_irq(pdev, &cbb->nonsec_irq, &cbb->sec_irq); | ||
| 2283 | if (err) | ||
| 2284 | return err; | ||
| 2285 | |||
| 2286 | np = of_parse_phandle(pdev->dev.of_node, "nvidia,axi2apb", 0); | ||
| 2287 | if (np) { | ||
| 2288 | err = tegra194_cbb_get_bridges(cbb, np); | ||
| 2289 | of_node_put(np); | ||
| 2290 | if (err < 0) | ||
| 2291 | return err; | ||
| 2292 | } | ||
| 2293 | |||
| 2294 | platform_set_drvdata(pdev, cbb); | ||
| 2295 | |||
| 2296 | spin_lock_irqsave(&cbb_lock, flags); | ||
| 2297 | list_add(&cbb->base.node, &cbb_list); | ||
| 2298 | spin_unlock_irqrestore(&cbb_lock, flags); | ||
| 2299 | |||
| 2300 | return tegra_cbb_register(&cbb->base); | ||
| 2301 | } | ||
| 2302 | |||
| 2303 | static int tegra194_cbb_remove(struct platform_device *pdev) | ||
| 2304 | { | ||
| 2305 | struct tegra194_cbb *cbb = platform_get_drvdata(pdev); | ||
| 2306 | struct tegra_cbb *noc, *tmp; | ||
| 2307 | unsigned long flags; | ||
| 2308 | |||
| 2309 | spin_lock_irqsave(&cbb_lock, flags); | ||
| 2310 | |||
| 2311 | list_for_each_entry_safe(noc, tmp, &cbb_list, node) { | ||
| 2312 | struct tegra194_cbb *priv = to_tegra194_cbb(noc); | ||
| 2313 | |||
| 2314 | if (cbb->res->start == priv->res->start) { | ||
| 2315 | list_del(&noc->node); | ||
| 2316 | break; | ||
| 2317 | } | ||
| 2318 | } | ||
| 2319 | |||
| 2320 | spin_unlock_irqrestore(&cbb_lock, flags); | ||
| 2321 | |||
| 2322 | return 0; | ||
| 2323 | } | ||
| 2324 | |||
| 2325 | static int __maybe_unused tegra194_cbb_resume_noirq(struct device *dev) | ||
| 2326 | { | ||
| 2327 | struct tegra194_cbb *cbb = dev_get_drvdata(dev); | ||
| 2328 | |||
| 2329 | tegra194_cbb_error_enable(&cbb->base); | ||
| 2330 | dsb(sy); | ||
| 2331 | |||
| 2332 | dev_dbg(dev, "%s resumed\n", cbb->noc->name); | ||
| 2333 | return 0; | ||
| 2334 | } | ||
| 2335 | |||
| 2336 | static const struct dev_pm_ops tegra194_cbb_pm = { | ||
| 2337 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, tegra194_cbb_resume_noirq) | ||
| 2338 | }; | ||
| 2339 | |||
| 2340 | static struct platform_driver tegra194_cbb_driver = { | ||
| 2341 | .probe = tegra194_cbb_probe, | ||
| 2342 | .remove = tegra194_cbb_remove, | ||
| 2343 | .driver = { | ||
| 2344 | .name = "tegra194-cbb", | ||
| 2345 | .of_match_table = of_match_ptr(tegra194_cbb_match), | ||
| 2346 | .pm = &tegra194_cbb_pm, | ||
| 2347 | }, | ||
| 2348 | }; | ||
| 2349 | |||
| 2350 | static int __init tegra194_cbb_init(void) | ||
| 2351 | { | ||
| 2352 | return platform_driver_register(&tegra194_cbb_driver); | ||
| 2353 | } | ||
| 2354 | pure_initcall(tegra194_cbb_init); | ||
| 2355 | |||
| 2356 | static void __exit tegra194_cbb_exit(void) | ||
| 2357 | { | ||
| 2358 | platform_driver_unregister(&tegra194_cbb_driver); | ||
| 2359 | } | ||
| 2360 | module_exit(tegra194_cbb_exit); | ||
| 2361 | |||
| 2362 | MODULE_AUTHOR("Sumit Gupta <sumitg@nvidia.com>"); | ||
| 2363 | MODULE_DESCRIPTION("Control Backbone error handling driver for Tegra194"); | ||
| 2364 | MODULE_LICENSE("GPL"); | ||
| @@ -0,0 +1,1113 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved | ||
| 4 | * | ||
| 5 | * The driver handles Error's from Control Backbone(CBB) version 2.0. | ||
| 6 | * generated due to illegal accesses. The driver prints debug information | ||
| 7 | * about failed transaction on receiving interrupt from Error Notifier. | ||
| 8 | * Error types supported by CBB2.0 are: | ||
| 9 | * UNSUPPORTED_ERR, PWRDOWN_ERR, TIMEOUT_ERR, FIREWALL_ERR, DECODE_ERR, | ||
| 10 | * SLAVE_ERR | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/acpi.h> | ||
| 14 | #include <linux/clk.h> | ||
| 15 | #include <linux/cpufeature.h> | ||
| 16 | #include <linux/debugfs.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/of.h> | ||
| 19 | #include <linux/of_device.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/device.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | #include <linux/of_irq.h> | ||
| 24 | #include <linux/of_address.h> | ||
| 25 | #include <linux/interrupt.h> | ||
| 26 | #include <linux/ioport.h> | ||
| 27 | #include <linux/version.h> | ||
| 28 | #include <soc/tegra/fuse.h> | ||
| 29 | #include <soc/tegra/tegra-cbb.h> | ||
| 30 | |||
| 31 | #define FABRIC_EN_CFG_INTERRUPT_ENABLE_0_0 0x0 | ||
| 32 | #define FABRIC_EN_CFG_STATUS_0_0 0x40 | ||
| 33 | #define FABRIC_EN_CFG_ADDR_INDEX_0_0 0x60 | ||
| 34 | #define FABRIC_EN_CFG_ADDR_LOW_0 0x80 | ||
| 35 | #define FABRIC_EN_CFG_ADDR_HI_0 0x84 | ||
| 36 | |||
| 37 | #define FABRIC_MN_MASTER_ERR_EN_0 0x200 | ||
| 38 | #define FABRIC_MN_MASTER_ERR_FORCE_0 0x204 | ||
| 39 | #define FABRIC_MN_MASTER_ERR_STATUS_0 0x208 | ||
| 40 | #define FABRIC_MN_MASTER_ERR_OVERFLOW_STATUS_0 0x20c | ||
| 41 | |||
| 42 | #define FABRIC_MN_MASTER_LOG_ERR_STATUS_0 0x300 | ||
| 43 | #define FABRIC_MN_MASTER_LOG_ADDR_LOW_0 0x304 | ||
| 44 | #define FABRIC_MN_MASTER_LOG_ADDR_HIGH_0 0x308 | ||
| 45 | #define FABRIC_MN_MASTER_LOG_ATTRIBUTES0_0 0x30c | ||
| 46 | #define FABRIC_MN_MASTER_LOG_ATTRIBUTES1_0 0x310 | ||
| 47 | #define FABRIC_MN_MASTER_LOG_ATTRIBUTES2_0 0x314 | ||
| 48 | #define FABRIC_MN_MASTER_LOG_USER_BITS0_0 0x318 | ||
| 49 | |||
| 50 | #define AXI_SLV_TIMEOUT_STATUS_0_0 0x8 | ||
| 51 | #define APB_BLOCK_TMO_STATUS_0 0xc00 | ||
| 52 | #define APB_BLOCK_NUM_TMO_OFFSET 0x20 | ||
| 53 | |||
| 54 | #define FAB_EM_EL_MSTRID GENMASK(29, 24) | ||
| 55 | #define FAB_EM_EL_VQC GENMASK(17, 16) | ||
| 56 | #define FAB_EM_EL_GRPSEC GENMASK(14, 8) | ||
| 57 | #define FAB_EM_EL_FALCONSEC GENMASK(1, 0) | ||
| 58 | |||
| 59 | #define FAB_EM_EL_FABID GENMASK(20, 16) | ||
| 60 | #define FAB_EM_EL_SLAVEID GENMASK(7, 0) | ||
| 61 | |||
| 62 | #define FAB_EM_EL_ACCESSID GENMASK(7, 0) | ||
| 63 | |||
| 64 | #define FAB_EM_EL_AXCACHE GENMASK(27, 24) | ||
| 65 | #define FAB_EM_EL_AXPROT GENMASK(22, 20) | ||
| 66 | #define FAB_EM_EL_BURSTLENGTH GENMASK(19, 12) | ||
| 67 | #define FAB_EM_EL_BURSTTYPE GENMASK(9, 8) | ||
| 68 | #define FAB_EM_EL_BEATSIZE GENMASK(6, 4) | ||
| 69 | #define FAB_EM_EL_ACCESSTYPE GENMASK(0, 0) | ||
| 70 | |||
| 71 | #define USRBITS_MSTR_ID GENMASK(29, 24) | ||
| 72 | |||
| 73 | #define REQ_SOCKET_ID GENMASK(27, 24) | ||
| 74 | |||
| 75 | enum tegra234_cbb_fabric_ids { | ||
| 76 | CBB_FAB_ID, | ||
| 77 | SCE_FAB_ID, | ||
| 78 | RCE_FAB_ID, | ||
| 79 | DCE_FAB_ID, | ||
| 80 | AON_FAB_ID, | ||
| 81 | PSC_FAB_ID, | ||
| 82 | BPMP_FAB_ID, | ||
| 83 | FSI_FAB_ID, | ||
| 84 | MAX_FAB_ID, | ||
| 85 | }; | ||
| 86 | |||
| 87 | struct tegra234_slave_lookup { | ||
| 88 | const char *name; | ||
| 89 | unsigned int offset; | ||
| 90 | }; | ||
| 91 | |||
| 92 | struct tegra234_cbb_fabric { | ||
| 93 | const char *name; | ||
| 94 | phys_addr_t off_mask_erd; | ||
| 95 | bool erd_mask_inband_err; | ||
| 96 | const char * const *master_id; | ||
| 97 | unsigned int notifier_offset; | ||
| 98 | const struct tegra_cbb_error *errors; | ||
| 99 | const struct tegra234_slave_lookup *slave_map; | ||
| 100 | }; | ||
| 101 | |||
| 102 | struct tegra234_cbb { | ||
| 103 | struct tegra_cbb base; | ||
| 104 | |||
| 105 | const struct tegra234_cbb_fabric *fabric; | ||
| 106 | struct resource *res; | ||
| 107 | void __iomem *regs; | ||
| 108 | |||
| 109 | int num_intr; | ||
| 110 | int sec_irq; | ||
| 111 | |||
| 112 | /* record */ | ||
| 113 | void __iomem *mon; | ||
| 114 | unsigned int type; | ||
| 115 | u32 mask; | ||
| 116 | u64 access; | ||
| 117 | u32 mn_attr0; | ||
| 118 | u32 mn_attr1; | ||
| 119 | u32 mn_attr2; | ||
| 120 | u32 mn_user_bits; | ||
| 121 | }; | ||
| 122 | |||
| 123 | static inline struct tegra234_cbb *to_tegra234_cbb(struct tegra_cbb *cbb) | ||
| 124 | { | ||
| 125 | return container_of(cbb, struct tegra234_cbb, base); | ||
| 126 | } | ||
| 127 | |||
| 128 | static LIST_HEAD(cbb_list); | ||
| 129 | static DEFINE_SPINLOCK(cbb_lock); | ||
| 130 | |||
| 131 | static void tegra234_cbb_fault_enable(struct tegra_cbb *cbb) | ||
| 132 | { | ||
| 133 | struct tegra234_cbb *priv = to_tegra234_cbb(cbb); | ||
| 134 | void __iomem *addr; | ||
| 135 | |||
| 136 | addr = priv->regs + priv->fabric->notifier_offset; | ||
| 137 | writel(0x1ff, addr + FABRIC_EN_CFG_INTERRUPT_ENABLE_0_0); | ||
| 138 | dsb(sy); | ||
| 139 | } | ||
| 140 | |||
| 141 | static void tegra234_cbb_error_clear(struct tegra_cbb *cbb) | ||
| 142 | { | ||
| 143 | struct tegra234_cbb *priv = to_tegra234_cbb(cbb); | ||
| 144 | |||
| 145 | writel(0x3f, priv->mon + FABRIC_MN_MASTER_ERR_STATUS_0); | ||
| 146 | dsb(sy); | ||
| 147 | } | ||
| 148 | |||
| 149 | static u32 tegra234_cbb_get_status(struct tegra_cbb *cbb) | ||
| 150 | { | ||
| 151 | struct tegra234_cbb *priv = to_tegra234_cbb(cbb); | ||
| 152 | void __iomem *addr; | ||
| 153 | u32 value; | ||
| 154 | |||
| 155 | addr = priv->regs + priv->fabric->notifier_offset; | ||
| 156 | value = readl(addr + FABRIC_EN_CFG_STATUS_0_0); | ||
| 157 | dsb(sy); | ||
| 158 | |||
| 159 | return value; | ||
| 160 | } | ||
| 161 | |||
| 162 | static void tegra234_cbb_mask_serror(struct tegra234_cbb *cbb) | ||
| 163 | { | ||
| 164 | writel(0x1, cbb->regs + cbb->fabric->off_mask_erd); | ||
| 165 | dsb(sy); | ||
| 166 | } | ||
| 167 | |||
| 168 | static u32 tegra234_cbb_get_tmo_slv(void __iomem *addr) | ||
| 169 | { | ||
| 170 | u32 timeout; | ||
| 171 | |||
| 172 | timeout = readl(addr); | ||
| 173 | return timeout; | ||
| 174 | } | ||
| 175 | |||
| 176 | static void tegra234_cbb_tmo_slv(struct seq_file *file, const char *slave, void __iomem *addr, | ||
| 177 | u32 status) | ||
| 178 | { | ||
| 179 | tegra_cbb_print_err(file, "\t %s : %#x\n", slave, status); | ||
| 180 | } | ||
| 181 | |||
| 182 | static void tegra234_cbb_lookup_apbslv(struct seq_file *file, const char *slave, | ||
| 183 | void __iomem *base) | ||
| 184 | { | ||
| 185 | unsigned int block = 0; | ||
| 186 | void __iomem *addr; | ||
| 187 | char name[64]; | ||
| 188 | u32 status; | ||
| 189 | |||
| 190 | status = tegra234_cbb_get_tmo_slv(base); | ||
| 191 | if (status) | ||
| 192 | tegra_cbb_print_err(file, "\t %s_BLOCK_TMO_STATUS : %#x\n", slave, status); | ||
| 193 | |||
| 194 | while (status) { | ||
| 195 | if (status & BIT(0)) { | ||
| 196 | u32 timeout, clients, client = 0; | ||
| 197 | |||
| 198 | addr = base + APB_BLOCK_NUM_TMO_OFFSET + (block * 4); | ||
| 199 | timeout = tegra234_cbb_get_tmo_slv(addr); | ||
| 200 | clients = timeout; | ||
| 201 | |||
| 202 | while (timeout) { | ||
| 203 | if (timeout & BIT(0)) { | ||
| 204 | if (clients != 0xffffffff) | ||
| 205 | clients &= BIT(client); | ||
| 206 | |||
| 207 | sprintf(name, "%s_BLOCK%d_TMO", slave, block); | ||
| 208 | |||
| 209 | tegra234_cbb_tmo_slv(file, name, addr, clients); | ||
| 210 | } | ||
| 211 | |||
| 212 | timeout >>= 1; | ||
| 213 | client++; | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | status >>= 1; | ||
| 218 | block++; | ||
| 219 | } | ||
| 220 | } | ||
| 221 | |||
| 222 | static void tegra234_lookup_slave_timeout(struct seq_file *file, struct tegra234_cbb *cbb, | ||
| 223 | u8 slave_id, u8 fab_id) | ||
| 224 | { | ||
| 225 | const struct tegra234_slave_lookup *map = cbb->fabric->slave_map; | ||
| 226 | void __iomem *addr; | ||
| 227 | |||
| 228 | /* | ||
| 229 | * 1) Get slave node name and address mapping using slave_id. | ||
| 230 | * 2) Check if the timed out slave node is APB or AXI. | ||
| 231 | * 3) If AXI, then print timeout register and reset axi slave | ||
| 232 | * using <FABRIC>_SN_<>_SLV_TIMEOUT_STATUS_0_0 register. | ||
| 233 | * 4) If APB, then perform an additional lookup to find the client | ||
| 234 | * which timed out. | ||
| 235 | * a) Get block number from the index of set bit in | ||
| 236 | * <FABRIC>_SN_AXI2APB_<>_BLOCK_TMO_STATUS_0 register. | ||
| 237 | * b) Get address of register repective to block number i.e. | ||
| 238 | * <FABRIC>_SN_AXI2APB_<>_BLOCK<index-set-bit>_TMO_0. | ||
| 239 | * c) Read the register in above step to get client_id which | ||
| 240 | * timed out as per the set bits. | ||
| 241 | * d) Reset the timedout client and print details. | ||
| 242 | * e) Goto step-a till all bits are set. | ||
| 243 | */ | ||
| 244 | |||
| 245 | addr = cbb->regs + map[slave_id].offset; | ||
| 246 | |||
| 247 | if (strstr(map[slave_id].name, "AXI2APB")) { | ||
| 248 | addr += APB_BLOCK_TMO_STATUS_0; | ||
| 249 | |||
| 250 | tegra234_cbb_lookup_apbslv(file, map[slave_id].name, addr); | ||
| 251 | } else { | ||
| 252 | char name[64]; | ||
| 253 | u32 status; | ||
| 254 | |||
| 255 | addr += AXI_SLV_TIMEOUT_STATUS_0_0; | ||
| 256 | |||
| 257 | status = tegra234_cbb_get_tmo_slv(addr); | ||
| 258 | if (status) { | ||
| 259 | sprintf(name, "%s_SLV_TIMEOUT_STATUS", map[slave_id].name); | ||
| 260 | tegra234_cbb_tmo_slv(file, name, addr, status); | ||
| 261 | } | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 265 | static void tegra234_cbb_print_error(struct seq_file *file, struct tegra234_cbb *cbb, u32 status, | ||
| 266 | u32 overflow) | ||
| 267 | { | ||
| 268 | unsigned int type = 0; | ||
| 269 | |||
| 270 | if (status & (status - 1)) | ||
| 271 | tegra_cbb_print_err(file, "\t Multiple type of errors reported\n"); | ||
| 272 | |||
| 273 | while (status) { | ||
| 274 | if (status & 0x1) | ||
| 275 | tegra_cbb_print_err(file, "\t Error Code\t\t: %s\n", | ||
| 276 | cbb->fabric->errors[type].code); | ||
| 277 | |||
| 278 | status >>= 1; | ||
| 279 | type++; | ||
| 280 | } | ||
| 281 | |||
| 282 | type = 0; | ||
| 283 | |||
| 284 | while (overflow) { | ||
| 285 | if (overflow & 0x1) | ||
| 286 | tegra_cbb_print_err(file, "\t Overflow\t\t: Multiple %s\n", | ||
| 287 | cbb->fabric->errors[type].code); | ||
| 288 | |||
| 289 | overflow >>= 1; | ||
| 290 | type++; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | |||
| 294 | static void print_errlog_err(struct seq_file *file, struct tegra234_cbb *cbb) | ||
| 295 | { | ||
| 296 | u8 cache_type, prot_type, burst_length, mstr_id, grpsec, vqc, falconsec, beat_size; | ||
| 297 | u8 access_type, access_id, requester_socket_id, local_socket_id, slave_id, fab_id; | ||
| 298 | char fabric_name[20]; | ||
| 299 | bool is_numa = false; | ||
| 300 | u8 burst_type; | ||
| 301 | |||
| 302 | if (num_possible_nodes() > 1) | ||
| 303 | is_numa = true; | ||
| 304 | |||
| 305 | mstr_id = FIELD_GET(FAB_EM_EL_MSTRID, cbb->mn_user_bits); | ||
| 306 | vqc = FIELD_GET(FAB_EM_EL_VQC, cbb->mn_user_bits); | ||
| 307 | grpsec = FIELD_GET(FAB_EM_EL_GRPSEC, cbb->mn_user_bits); | ||
| 308 | falconsec = FIELD_GET(FAB_EM_EL_FALCONSEC, cbb->mn_user_bits); | ||
| 309 | |||
| 310 | /* | ||
| 311 | * For SOC with multiple NUMA nodes, print cross socket access | ||
| 312 | * errors only if initiator/master_id is CCPLEX, CPMU or GPU. | ||
| 313 | */ | ||
| 314 | if (is_numa) { | ||
| 315 | local_socket_id = numa_node_id(); | ||
| 316 | requester_socket_id = FIELD_GET(REQ_SOCKET_ID, cbb->mn_attr2); | ||
| 317 | |||
| 318 | if (requester_socket_id != local_socket_id) { | ||
| 319 | if ((mstr_id != 0x1) && (mstr_id != 0x2) && (mstr_id != 0xB)) | ||
| 320 | return; | ||
| 321 | } | ||
| 322 | } | ||
| 323 | |||
| 324 | fab_id = FIELD_GET(FAB_EM_EL_FABID, cbb->mn_attr2); | ||
| 325 | slave_id = FIELD_GET(FAB_EM_EL_SLAVEID, cbb->mn_attr2); | ||
| 326 | |||
| 327 | access_id = FIELD_GET(FAB_EM_EL_ACCESSID, cbb->mn_attr1); | ||
| 328 | |||
| 329 | cache_type = FIELD_GET(FAB_EM_EL_AXCACHE, cbb->mn_attr0); | ||
| 330 | prot_type = FIELD_GET(FAB_EM_EL_AXPROT, cbb->mn_attr0); | ||
| 331 | burst_length = FIELD_GET(FAB_EM_EL_BURSTLENGTH, cbb->mn_attr0); | ||
| 332 | burst_type = FIELD_GET(FAB_EM_EL_BURSTTYPE, cbb->mn_attr0); | ||
| 333 | beat_size = FIELD_GET(FAB_EM_EL_BEATSIZE, cbb->mn_attr0); | ||
| 334 | access_type = FIELD_GET(FAB_EM_EL_ACCESSTYPE, cbb->mn_attr0); | ||
| 335 | |||
| 336 | tegra_cbb_print_err(file, "\n"); | ||
| 337 | tegra_cbb_print_err(file, "\t Error Code\t\t: %s\n", | ||
| 338 | cbb->fabric->errors[cbb->type].code); | ||
| 339 | |||
| 340 | tegra_cbb_print_err(file, "\t MASTER_ID\t\t: %s\n", cbb->fabric->master_id[mstr_id]); | ||
| 341 | tegra_cbb_print_err(file, "\t Address\t\t: %#llx\n", cbb->access); | ||
| 342 | |||
| 343 | tegra_cbb_print_cache(file, cache_type); | ||
| 344 | tegra_cbb_print_prot(file, prot_type); | ||
| 345 | |||
| 346 | tegra_cbb_print_err(file, "\t Access_Type\t\t: %s", (access_type) ? "Write\n" : "Read\n"); | ||
| 347 | tegra_cbb_print_err(file, "\t Access_ID\t\t: %#x", access_id); | ||
| 348 | |||
| 349 | if (fab_id == PSC_FAB_ID) | ||
| 350 | strcpy(fabric_name, "psc-fabric"); | ||
| 351 | else if (fab_id == FSI_FAB_ID) | ||
| 352 | strcpy(fabric_name, "fsi-fabric"); | ||
| 353 | else | ||
| 354 | strcpy(fabric_name, cbb->fabric->name); | ||
| 355 | |||
| 356 | if (is_numa) { | ||
| 357 | tegra_cbb_print_err(file, "\t Requester_Socket_Id\t: %#x\n", | ||
| 358 | requester_socket_id); | ||
| 359 | tegra_cbb_print_err(file, "\t Local_Socket_Id\t: %#x\n", | ||
| 360 | local_socket_id); | ||
| 361 | tegra_cbb_print_err(file, "\t No. of NUMA_NODES\t: %#x\n", | ||
| 362 | num_possible_nodes()); | ||
| 363 | } | ||
| 364 | |||
| 365 | tegra_cbb_print_err(file, "\t Fabric\t\t: %s\n", fabric_name); | ||
| 366 | tegra_cbb_print_err(file, "\t Slave_Id\t\t: %#x\n", slave_id); | ||
| 367 | tegra_cbb_print_err(file, "\t Burst_length\t\t: %#x\n", burst_length); | ||
| 368 | tegra_cbb_print_err(file, "\t Burst_type\t\t: %#x\n", burst_type); | ||
| 369 | tegra_cbb_print_err(file, "\t Beat_size\t\t: %#x\n", beat_size); | ||
| 370 | tegra_cbb_print_err(file, "\t VQC\t\t\t: %#x\n", vqc); | ||
| 371 | tegra_cbb_print_err(file, "\t GRPSEC\t\t: %#x\n", grpsec); | ||
| 372 | tegra_cbb_print_err(file, "\t FALCONSEC\t\t: %#x\n", falconsec); | ||
| 373 | |||
| 374 | if ((fab_id == PSC_FAB_ID) || (fab_id == FSI_FAB_ID)) | ||
| 375 | return; | ||
| 376 | |||
| 377 | if (!strcmp(cbb->fabric->errors[cbb->type].code, "TIMEOUT_ERR")) { | ||
| 378 | tegra234_lookup_slave_timeout(file, cbb, slave_id, fab_id); | ||
| 379 | return; | ||
| 380 | } | ||
| 381 | |||
| 382 | tegra_cbb_print_err(file, "\t Slave\t\t\t: %s\n", cbb->fabric->slave_map[slave_id].name); | ||
| 383 | } | ||
| 384 | |||
| 385 | static int print_errmonX_info(struct seq_file *file, struct tegra234_cbb *cbb) | ||
| 386 | { | ||
| 387 | u32 overflow, status, error; | ||
| 388 | |||
| 389 | status = readl(cbb->mon + FABRIC_MN_MASTER_ERR_STATUS_0); | ||
| 390 | if (!status) { | ||
| 391 | pr_err("Error Notifier received a spurious notification\n"); | ||
| 392 | return -ENODATA; | ||
| 393 | } | ||
| 394 | |||
| 395 | if (status == 0xffffffff) { | ||
| 396 | pr_err("CBB registers returning all 1's which is invalid\n"); | ||
| 397 | return -EINVAL; | ||
| 398 | } | ||
| 399 | |||
| 400 | overflow = readl(cbb->mon + FABRIC_MN_MASTER_ERR_OVERFLOW_STATUS_0); | ||
| 401 | |||
| 402 | tegra234_cbb_print_error(file, cbb, status, overflow); | ||
| 403 | |||
| 404 | error = readl(cbb->mon + FABRIC_MN_MASTER_LOG_ERR_STATUS_0); | ||
| 405 | if (!error) { | ||
| 406 | pr_info("Error Monitor doesn't have Error Logger\n"); | ||
| 407 | return -EINVAL; | ||
| 408 | } | ||
| 409 | |||
| 410 | cbb->type = 0; | ||
| 411 | |||
| 412 | while (error) { | ||
| 413 | if (error & BIT(0)) { | ||
| 414 | u32 hi, lo; | ||
| 415 | |||
| 416 | hi = readl(cbb->mon + FABRIC_MN_MASTER_LOG_ADDR_HIGH_0); | ||
| 417 | lo = readl(cbb->mon + FABRIC_MN_MASTER_LOG_ADDR_LOW_0); | ||
| 418 | |||
| 419 | cbb->access = (u64)hi << 32 | lo; | ||
| 420 | |||
| 421 | cbb->mn_attr0 = readl(cbb->mon + FABRIC_MN_MASTER_LOG_ATTRIBUTES0_0); | ||
| 422 | cbb->mn_attr1 = readl(cbb->mon + FABRIC_MN_MASTER_LOG_ATTRIBUTES1_0); | ||
| 423 | cbb->mn_attr2 = readl(cbb->mon + FABRIC_MN_MASTER_LOG_ATTRIBUTES2_0); | ||
| 424 | cbb->mn_user_bits = readl(cbb->mon + FABRIC_MN_MASTER_LOG_USER_BITS0_0); | ||
| 425 | |||
| 426 | print_errlog_err(file, cbb); | ||
| 427 | } | ||
| 428 | |||
| 429 | cbb->type++; | ||
| 430 | error >>= 1; | ||
| 431 | } | ||
| 432 | |||
| 433 | return 0; | ||
| 434 | } | ||
| 435 | |||
| 436 | static int print_err_notifier(struct seq_file *file, struct tegra234_cbb *cbb, u32 status) | ||
| 437 | { | ||
| 438 | unsigned int index = 0; | ||
| 439 | int err; | ||
| 440 | |||
| 441 | pr_crit("**************************************\n"); | ||
| 442 | pr_crit("CPU:%d, Error:%s, Errmon:%d\n", smp_processor_id(), | ||
| 443 | cbb->fabric->name, status); | ||
| 444 | |||
| 445 | while (status) { | ||
| 446 | if (status & BIT(0)) { | ||
| 447 | unsigned int notifier = cbb->fabric->notifier_offset; | ||
| 448 | u32 hi, lo, mask = BIT(index); | ||
| 449 | phys_addr_t addr; | ||
| 450 | u64 offset; | ||
| 451 | |||
| 452 | writel(mask, cbb->regs + notifier + FABRIC_EN_CFG_ADDR_INDEX_0_0); | ||
| 453 | hi = readl(cbb->regs + notifier + FABRIC_EN_CFG_ADDR_HI_0); | ||
| 454 | lo = readl(cbb->regs + notifier + FABRIC_EN_CFG_ADDR_LOW_0); | ||
| 455 | |||
| 456 | addr = (u64)hi << 32 | lo; | ||
| 457 | |||
| 458 | offset = addr - cbb->res->start; | ||
| 459 | cbb->mon = cbb->regs + offset; | ||
| 460 | cbb->mask = BIT(index); | ||
| 461 | |||
| 462 | err = print_errmonX_info(file, cbb); | ||
| 463 | tegra234_cbb_error_clear(&cbb->base); | ||
| 464 | if (err) | ||
| 465 | return err; | ||
| 466 | } | ||
| 467 | |||
| 468 | status >>= 1; | ||
| 469 | index++; | ||
| 470 | } | ||
| 471 | |||
| 472 | tegra_cbb_print_err(file, "\t**************************************\n"); | ||
| 473 | return 0; | ||
| 474 | } | ||
| 475 | |||
| 476 | #ifdef CONFIG_DEBUG_FS | ||
| 477 | static DEFINE_MUTEX(cbb_debugfs_mutex); | ||
| 478 | |||
| 479 | static int tegra234_cbb_debugfs_show(struct tegra_cbb *cbb, struct seq_file *file, void *data) | ||
| 480 | { | ||
| 481 | int err = 0; | ||
| 482 | |||
| 483 | mutex_lock(&cbb_debugfs_mutex); | ||
| 484 | |||
| 485 | list_for_each_entry(cbb, &cbb_list, node) { | ||
| 486 | struct tegra234_cbb *priv = to_tegra234_cbb(cbb); | ||
| 487 | u32 status; | ||
| 488 | |||
| 489 | status = tegra_cbb_get_status(&priv->base); | ||
| 490 | if (status) { | ||
| 491 | err = print_err_notifier(file, priv, status); | ||
| 492 | if (err) | ||
| 493 | break; | ||
| 494 | } | ||
| 495 | } | ||
| 496 | |||
| 497 | mutex_unlock(&cbb_debugfs_mutex); | ||
| 498 | return err; | ||
| 499 | } | ||
| 500 | #endif | ||
| 501 | |||
| 502 | /* | ||
| 503 | * Handler for CBB errors | ||
| 504 | */ | ||
| 505 | static irqreturn_t tegra234_cbb_isr(int irq, void *data) | ||
| 506 | { | ||
| 507 | bool is_inband_err = false; | ||
| 508 | struct tegra_cbb *cbb; | ||
| 509 | unsigned long flags; | ||
| 510 | u8 mstr_id; | ||
| 511 | int err; | ||
| 512 | |||
| 513 | spin_lock_irqsave(&cbb_lock, flags); | ||
| 514 | |||
| 515 | list_for_each_entry(cbb, &cbb_list, node) { | ||
| 516 | struct tegra234_cbb *priv = to_tegra234_cbb(cbb); | ||
| 517 | u32 status = tegra_cbb_get_status(cbb); | ||
| 518 | |||
| 519 | if (status && (irq == priv->sec_irq)) { | ||
| 520 | tegra_cbb_print_err(NULL, "CPU:%d, Error: %s@%llx, irq=%d\n", | ||
| 521 | smp_processor_id(), priv->fabric->name, | ||
| 522 | priv->res->start, irq); | ||
| 523 | |||
| 524 | err = print_err_notifier(NULL, priv, status); | ||
| 525 | if (err) | ||
| 526 | goto unlock; | ||
| 527 | |||
| 528 | mstr_id = FIELD_GET(USRBITS_MSTR_ID, priv->mn_user_bits); | ||
| 529 | |||
| 530 | /* | ||
| 531 | * If illegal request is from CCPLEX(id:0x1) master then call BUG() to | ||
| 532 | * crash system. | ||
| 533 | */ | ||
| 534 | if ((mstr_id == 0x1) && priv->fabric->off_mask_erd) | ||
| 535 | is_inband_err = 1; | ||
| 536 | } | ||
| 537 | } | ||
| 538 | |||
| 539 | unlock: | ||
| 540 | spin_unlock_irqrestore(&cbb_lock, flags); | ||
| 541 | WARN_ON(is_inband_err); | ||
| 542 | return IRQ_HANDLED; | ||
| 543 | } | ||
| 544 | |||
| 545 | /* | ||
| 546 | * Register handler for CBB_SECURE interrupt for reporting errors | ||
| 547 | */ | ||
| 548 | static int tegra234_cbb_interrupt_enable(struct tegra_cbb *cbb) | ||
| 549 | { | ||
| 550 | struct tegra234_cbb *priv = to_tegra234_cbb(cbb); | ||
| 551 | |||
| 552 | if (priv->sec_irq) { | ||
| 553 | int err = devm_request_irq(cbb->dev, priv->sec_irq, tegra234_cbb_isr, 0, | ||
| 554 | dev_name(cbb->dev), priv); | ||
| 555 | if (err) { | ||
| 556 | dev_err(cbb->dev, "failed to register interrupt %u: %d\n", priv->sec_irq, | ||
| 557 | err); | ||
| 558 | return err; | ||
| 559 | } | ||
| 560 | } | ||
| 561 | |||
| 562 | return 0; | ||
| 563 | } | ||
| 564 | |||
| 565 | static void tegra234_cbb_error_enable(struct tegra_cbb *cbb) | ||
| 566 | { | ||
| 567 | tegra_cbb_fault_enable(cbb); | ||
| 568 | } | ||
| 569 | |||
| 570 | static const struct tegra_cbb_ops tegra234_cbb_ops = { | ||
| 571 | .get_status = tegra234_cbb_get_status, | ||
| 572 | .error_clear = tegra234_cbb_error_clear, | ||
| 573 | .fault_enable = tegra234_cbb_fault_enable, | ||
| 574 | .error_enable = tegra234_cbb_error_enable, | ||
| 575 | .interrupt_enable = tegra234_cbb_interrupt_enable, | ||
| 576 | #ifdef CONFIG_DEBUG_FS | ||
| 577 | .debugfs_show = tegra234_cbb_debugfs_show, | ||
| 578 | #endif | ||
| 579 | }; | ||
| 580 | |||
| 581 | static const char * const tegra234_master_id[] = { | ||
| 582 | [0x00] = "TZ", | ||
| 583 | [0x01] = "CCPLEX", | ||
| 584 | [0x02] = "CCPMU", | ||
| 585 | [0x03] = "BPMP_FW", | ||
| 586 | [0x04] = "AON", | ||
| 587 | [0x05] = "SCE", | ||
| 588 | [0x06] = "GPCDMA_P", | ||
| 589 | [0x07] = "TSECA_NONSECURE", | ||
| 590 | [0x08] = "TSECA_LIGHTSECURE", | ||
| 591 | [0x09] = "TSECA_HEAVYSECURE", | ||
| 592 | [0x0a] = "CORESIGHT", | ||
| 593 | [0x0b] = "APE", | ||
| 594 | [0x0c] = "PEATRANS", | ||
| 595 | [0x0d] = "JTAGM_DFT", | ||
| 596 | [0x0e] = "RCE", | ||
| 597 | [0x0f] = "DCE", | ||
| 598 | [0x10] = "PSC_FW_USER", | ||
| 599 | [0x11] = "PSC_FW_SUPERVISOR", | ||
| 600 | [0x12] = "PSC_FW_MACHINE", | ||
| 601 | [0x13] = "PSC_BOOT", | ||
| 602 | [0x14] = "BPMP_BOOT", | ||
| 603 | [0x15] = "NVDEC_NONSECURE", | ||
| 604 | [0x16] = "NVDEC_LIGHTSECURE", | ||
| 605 | [0x17] = "NVDEC_HEAVYSECURE", | ||
| 606 | [0x18] = "CBB_INTERNAL", | ||
| 607 | [0x19] = "RSVD" | ||
| 608 | }; | ||
| 609 | |||
| 610 | static const struct tegra_cbb_error tegra234_cbb_errors[] = { | ||
| 611 | { | ||
| 612 | .code = "SLAVE_ERR", | ||
| 613 | .desc = "Slave being accessed responded with an error" | ||
| 614 | }, { | ||
| 615 | .code = "DECODE_ERR", | ||
| 616 | .desc = "Attempt to access an address hole" | ||
| 617 | }, { | ||
| 618 | .code = "FIREWALL_ERR", | ||
| 619 | .desc = "Attempt to access a region which is firewall protected" | ||
| 620 | }, { | ||
| 621 | .code = "TIMEOUT_ERR", | ||
| 622 | .desc = "No response returned by slave" | ||
| 623 | }, { | ||
| 624 | .code = "PWRDOWN_ERR", | ||
| 625 | .desc = "Attempt to access a portion of fabric that is powered down" | ||
| 626 | }, { | ||
| 627 | .code = "UNSUPPORTED_ERR", | ||
| 628 | .desc = "Attempt to access a slave through an unsupported access" | ||
| 629 | } | ||
| 630 | }; | ||
| 631 | |||
| 632 | static const struct tegra234_slave_lookup tegra234_aon_slave_map[] = { | ||
| 633 | { "AXI2APB", 0x00000 }, | ||
| 634 | { "AST", 0x14000 }, | ||
| 635 | { "CBB", 0x15000 }, | ||
| 636 | { "CPU", 0x16000 }, | ||
| 637 | }; | ||
| 638 | |||
| 639 | static const struct tegra234_cbb_fabric tegra234_aon_fabric = { | ||
| 640 | .name = "aon-fabric", | ||
| 641 | .master_id = tegra234_master_id, | ||
| 642 | .slave_map = tegra234_aon_slave_map, | ||
| 643 | .errors = tegra234_cbb_errors, | ||
| 644 | .notifier_offset = 0x17000, | ||
| 645 | }; | ||
| 646 | |||
| 647 | static const struct tegra234_slave_lookup tegra234_bpmp_slave_map[] = { | ||
| 648 | { "AXI2APB", 0x00000 }, | ||
| 649 | { "AST0", 0x15000 }, | ||
| 650 | { "AST1", 0x16000 }, | ||
| 651 | { "CBB", 0x17000 }, | ||
| 652 | { "CPU", 0x18000 }, | ||
| 653 | }; | ||
| 654 | |||
| 655 | static const struct tegra234_cbb_fabric tegra234_bpmp_fabric = { | ||
| 656 | .name = "bpmp-fabric", | ||
| 657 | .master_id = tegra234_master_id, | ||
| 658 | .slave_map = tegra234_bpmp_slave_map, | ||
| 659 | .errors = tegra234_cbb_errors, | ||
| 660 | .notifier_offset = 0x19000, | ||
| 661 | }; | ||
| 662 | |||
| 663 | static const struct tegra234_slave_lookup tegra234_cbb_slave_map[] = { | ||
| 664 | { "AON", 0x40000 }, | ||
| 665 | { "BPMP", 0x41000 }, | ||
| 666 | { "CBB", 0x42000 }, | ||
| 667 | { "HOST1X", 0x43000 }, | ||
| 668 | { "STM", 0x44000 }, | ||
| 669 | { "FSI", 0x45000 }, | ||
| 670 | { "PSC", 0x46000 }, | ||
| 671 | { "PCIE_C1", 0x47000 }, | ||
| 672 | { "PCIE_C2", 0x48000 }, | ||
| 673 | { "PCIE_C3", 0x49000 }, | ||
| 674 | { "PCIE_C0", 0x4a000 }, | ||
| 675 | { "PCIE_C4", 0x4b000 }, | ||
| 676 | { "GPU", 0x4c000 }, | ||
| 677 | { "SMMU0", 0x4d000 }, | ||
| 678 | { "SMMU1", 0x4e000 }, | ||
| 679 | { "SMMU2", 0x4f000 }, | ||
| 680 | { "SMMU3", 0x50000 }, | ||
| 681 | { "SMMU4", 0x51000 }, | ||
| 682 | { "PCIE_C10", 0x52000 }, | ||
| 683 | { "PCIE_C7", 0x53000 }, | ||
| 684 | { "PCIE_C8", 0x54000 }, | ||
| 685 | { "PCIE_C9", 0x55000 }, | ||
| 686 | { "PCIE_C5", 0x56000 }, | ||
| 687 | { "PCIE_C6", 0x57000 }, | ||
| 688 | { "DCE", 0x58000 }, | ||
| 689 | { "RCE", 0x59000 }, | ||
| 690 | { "SCE", 0x5a000 }, | ||
| 691 | { "AXI2APB_1", 0x70000 }, | ||
| 692 | { "AXI2APB_10", 0x71000 }, | ||
| 693 | { "AXI2APB_11", 0x72000 }, | ||
| 694 | { "AXI2APB_12", 0x73000 }, | ||
| 695 | { "AXI2APB_13", 0x74000 }, | ||
| 696 | { "AXI2APB_14", 0x75000 }, | ||
| 697 | { "AXI2APB_15", 0x76000 }, | ||
| 698 | { "AXI2APB_16", 0x77000 }, | ||
| 699 | { "AXI2APB_17", 0x78000 }, | ||
| 700 | { "AXI2APB_18", 0x79000 }, | ||
| 701 | { "AXI2APB_19", 0x7a000 }, | ||
| 702 | { "AXI2APB_2", 0x7b000 }, | ||
| 703 | { "AXI2APB_20", 0x7c000 }, | ||
| 704 | { "AXI2APB_21", 0x7d000 }, | ||
| 705 | { "AXI2APB_22", 0x7e000 }, | ||
| 706 | { "AXI2APB_23", 0x7f000 }, | ||
| 707 | { "AXI2APB_25", 0x80000 }, | ||
| 708 | { "AXI2APB_26", 0x81000 }, | ||
| 709 | { "AXI2APB_27", 0x82000 }, | ||
| 710 | { "AXI2APB_28", 0x83000 }, | ||
| 711 | { "AXI2APB_29", 0x84000 }, | ||
| 712 | { "AXI2APB_30", 0x85000 }, | ||
| 713 | { "AXI2APB_31", 0x86000 }, | ||
| 714 | { "AXI2APB_32", 0x87000 }, | ||
| 715 | { "AXI2APB_33", 0x88000 }, | ||
| 716 | { "AXI2APB_34", 0x89000 }, | ||
| 717 | { "AXI2APB_35", 0x92000 }, | ||
| 718 | { "AXI2APB_4", 0x8b000 }, | ||
| 719 | { "AXI2APB_5", 0x8c000 }, | ||
| 720 | { "AXI2APB_6", 0x8d000 }, | ||
| 721 | { "AXI2APB_7", 0x8e000 }, | ||
| 722 | { "AXI2APB_8", 0x8f000 }, | ||
| 723 | { "AXI2APB_9", 0x90000 }, | ||
| 724 | { "AXI2APB_3", 0x91000 }, | ||
| 725 | }; | ||
| 726 | |||
| 727 | static const struct tegra234_cbb_fabric tegra234_cbb_fabric = { | ||
| 728 | .name = "cbb-fabric", | ||
| 729 | .master_id = tegra234_master_id, | ||
| 730 | .slave_map = tegra234_cbb_slave_map, | ||
| 731 | .errors = tegra234_cbb_errors, | ||
| 732 | .notifier_offset = 0x60000, | ||
| 733 | .off_mask_erd = 0x3a004 | ||
| 734 | }; | ||
| 735 | |||
| 736 | static const struct tegra234_slave_lookup tegra234_dce_slave_map[] = { | ||
| 737 | { "AXI2APB", 0x00000 }, | ||
| 738 | { "AST0", 0x15000 }, | ||
| 739 | { "AST1", 0x16000 }, | ||
| 740 | { "CPU", 0x18000 }, | ||
| 741 | }; | ||
| 742 | |||
| 743 | static const struct tegra234_cbb_fabric tegra234_dce_fabric = { | ||
| 744 | .name = "dce-fabric", | ||
| 745 | .master_id = tegra234_master_id, | ||
| 746 | .slave_map = tegra234_dce_slave_map, | ||
| 747 | .errors = tegra234_cbb_errors, | ||
| 748 | .notifier_offset = 0x19000, | ||
| 749 | }; | ||
| 750 | |||
| 751 | static const struct tegra234_slave_lookup tegra234_rce_slave_map[] = { | ||
| 752 | { "AXI2APB", 0x00000 }, | ||
| 753 | { "AST0", 0x15000 }, | ||
| 754 | { "AST1", 0x16000 }, | ||
| 755 | { "CPU", 0x18000 }, | ||
| 756 | }; | ||
| 757 | |||
| 758 | static const struct tegra234_cbb_fabric tegra234_rce_fabric = { | ||
| 759 | .name = "rce-fabric", | ||
| 760 | .master_id = tegra234_master_id, | ||
| 761 | .slave_map = tegra234_rce_slave_map, | ||
| 762 | .errors = tegra234_cbb_errors, | ||
| 763 | .notifier_offset = 0x19000, | ||
| 764 | }; | ||
| 765 | |||
| 766 | static const struct tegra234_slave_lookup tegra234_sce_slave_map[] = { | ||
| 767 | { "AXI2APB", 0x00000 }, | ||
| 768 | { "AST0", 0x15000 }, | ||
| 769 | { "AST1", 0x16000 }, | ||
| 770 | { "CBB", 0x17000 }, | ||
| 771 | { "CPU", 0x18000 }, | ||
| 772 | }; | ||
| 773 | |||
| 774 | static const struct tegra234_cbb_fabric tegra234_sce_fabric = { | ||
| 775 | .name = "sce-fabric", | ||
| 776 | .master_id = tegra234_master_id, | ||
| 777 | .slave_map = tegra234_sce_slave_map, | ||
| 778 | .errors = tegra234_cbb_errors, | ||
| 779 | .notifier_offset = 0x19000, | ||
| 780 | }; | ||
| 781 | |||
| 782 | static const char * const tegra241_master_id[] = { | ||
| 783 | [0x0] = "TZ", | ||
| 784 | [0x1] = "CCPLEX", | ||
| 785 | [0x2] = "CCPMU", | ||
| 786 | [0x3] = "BPMP_FW", | ||
| 787 | [0x4] = "PSC_FW_USER", | ||
| 788 | [0x5] = "PSC_FW_SUPERVISOR", | ||
| 789 | [0x6] = "PSC_FW_MACHINE", | ||
| 790 | [0x7] = "PSC_BOOT", | ||
| 791 | [0x8] = "BPMP_BOOT", | ||
| 792 | [0x9] = "JTAGM_DFT", | ||
| 793 | [0xa] = "CORESIGHT", | ||
| 794 | [0xb] = "GPU", | ||
| 795 | [0xc] = "PEATRANS", | ||
| 796 | [0xd ... 0x3f] = "RSVD" | ||
| 797 | }; | ||
| 798 | |||
| 799 | /* | ||
| 800 | * Possible causes for Slave and Timeout errors. | ||
| 801 | * SLAVE_ERR: | ||
| 802 | * Slave being accessed responded with an error. Slave could return | ||
| 803 | * an error for various cases : | ||
| 804 | * Unsupported access, clamp setting when power gated, register | ||
| 805 | * level firewall(SCR), address hole within the slave, etc | ||
| 806 | * | ||
| 807 | * TIMEOUT_ERR: | ||
| 808 | * No response returned by slave. Can be due to slave being clock | ||
| 809 | * gated, under reset, powered down or slave inability to respond | ||
| 810 | * for an internal slave issue | ||
| 811 | */ | ||
| 812 | static const struct tegra_cbb_error tegra241_cbb_errors[] = { | ||
| 813 | { | ||
| 814 | .code = "SLAVE_ERR", | ||
| 815 | .desc = "Slave being accessed responded with an error." | ||
| 816 | }, { | ||
| 817 | .code = "DECODE_ERR", | ||
| 818 | .desc = "Attempt to access an address hole or Reserved region of memory." | ||
| 819 | }, { | ||
| 820 | .code = "FIREWALL_ERR", | ||
| 821 | .desc = "Attempt to access a region which is firewalled." | ||
| 822 | }, { | ||
| 823 | .code = "TIMEOUT_ERR", | ||
| 824 | .desc = "No response returned by slave." | ||
| 825 | }, { | ||
| 826 | .code = "PWRDOWN_ERR", | ||
| 827 | .desc = "Attempt to access a portion of the fabric that is powered down." | ||
| 828 | }, { | ||
| 829 | .code = "UNSUPPORTED_ERR", | ||
| 830 | .desc = "Attempt to access a slave through an unsupported access." | ||
| 831 | }, { | ||
| 832 | .code = "POISON_ERR", | ||
| 833 | .desc = "Slave responds with poison error to indicate error in data." | ||
| 834 | }, { | ||
| 835 | .code = "RSVD" | ||
| 836 | }, { | ||
| 837 | .code = "RSVD" | ||
| 838 | }, { | ||
| 839 | .code = "RSVD" | ||
| 840 | }, { | ||
| 841 | .code = "RSVD" | ||
| 842 | }, { | ||
| 843 | .code = "RSVD" | ||
| 844 | }, { | ||
| 845 | .code = "RSVD" | ||
| 846 | }, { | ||
| 847 | .code = "RSVD" | ||
| 848 | }, { | ||
| 849 | .code = "RSVD" | ||
| 850 | }, { | ||
| 851 | .code = "RSVD" | ||
| 852 | }, { | ||
| 853 | .code = "NO_SUCH_ADDRESS_ERR", | ||
| 854 | .desc = "The address belongs to the pri_target range but there is no register " | ||
| 855 | "implemented at the address." | ||
| 856 | }, { | ||
| 857 | .code = "TASK_ERR", | ||
| 858 | .desc = "Attempt to update a PRI task when the current task has still not " | ||
| 859 | "completed." | ||
| 860 | }, { | ||
| 861 | .code = "EXTERNAL_ERR", | ||
| 862 | .desc = "Indicates that an external PRI register access met with an error due to " | ||
| 863 | "any issue in the unit." | ||
| 864 | }, { | ||
| 865 | .code = "INDEX_ERR", | ||
| 866 | .desc = "Applicable to PRI index aperture pair, when the programmed index is " | ||
| 867 | "outside the range defined in the manual." | ||
| 868 | }, { | ||
| 869 | .code = "RESET_ERR", | ||
| 870 | .desc = "Target in Reset Error: Attempt to access a SubPri or external PRI " | ||
| 871 | "register but they are in reset." | ||
| 872 | }, { | ||
| 873 | .code = "REGISTER_RST_ERR", | ||
| 874 | .desc = "Attempt to access a PRI register but the register is partial or " | ||
| 875 | "completely in reset." | ||
| 876 | }, { | ||
| 877 | .code = "POWER_GATED_ERR", | ||
| 878 | .desc = "Returned by external PRI client when the external access goes to a power " | ||
| 879 | "gated domain." | ||
| 880 | }, { | ||
| 881 | .code = "SUBPRI_FS_ERR", | ||
| 882 | .desc = "Subpri is floorswept: Attempt to access a subpri through the main pri " | ||
| 883 | "target but subPri logic is floorswept." | ||
| 884 | }, { | ||
| 885 | .code = "SUBPRI_CLK_OFF_ERR", | ||
| 886 | .desc = "Subpri clock is off: Attempt to access a subpri through the main pri " | ||
| 887 | "target but subPris clock is gated/off." | ||
| 888 | }, | ||
| 889 | }; | ||
| 890 | |||
| 891 | static const struct tegra234_slave_lookup tegra241_cbb_slave_map[] = { | ||
| 892 | { "CCPLEX", 0x50000 }, | ||
| 893 | { "PCIE_C8", 0x51000 }, | ||
| 894 | { "PCIE_C9", 0x52000 }, | ||
| 895 | { "RSVD", 0x00000 }, | ||
| 896 | { "RSVD", 0x00000 }, | ||
| 897 | { "RSVD", 0x00000 }, | ||
| 898 | { "RSVD", 0x00000 }, | ||
| 899 | { "RSVD", 0x00000 }, | ||
| 900 | { "RSVD", 0x00000 }, | ||
| 901 | { "RSVD", 0x00000 }, | ||
| 902 | { "RSVD", 0x00000 }, | ||
| 903 | { "AON", 0x5b000 }, | ||
| 904 | { "BPMP", 0x5c000 }, | ||
| 905 | { "RSVD", 0x00000 }, | ||
| 906 | { "RSVD", 0x00000 }, | ||
| 907 | { "PSC", 0x5d000 }, | ||
| 908 | { "STM", 0x5e000 }, | ||
| 909 | { "AXI2APB_1", 0x70000 }, | ||
| 910 | { "AXI2APB_10", 0x71000 }, | ||
| 911 | { "AXI2APB_11", 0x72000 }, | ||
| 912 | { "AXI2APB_12", 0x73000 }, | ||
| 913 | { "AXI2APB_13", 0x74000 }, | ||
| 914 | { "AXI2APB_14", 0x75000 }, | ||
| 915 | { "AXI2APB_15", 0x76000 }, | ||
| 916 | { "AXI2APB_16", 0x77000 }, | ||
| 917 | { "AXI2APB_17", 0x78000 }, | ||
| 918 | { "AXI2APB_18", 0x79000 }, | ||
| 919 | { "AXI2APB_19", 0x7a000 }, | ||
| 920 | { "AXI2APB_2", 0x7b000 }, | ||
| 921 | { "AXI2APB_20", 0x7c000 }, | ||
| 922 | { "AXI2APB_4", 0x87000 }, | ||
| 923 | { "AXI2APB_5", 0x88000 }, | ||
| 924 | { "AXI2APB_6", 0x89000 }, | ||
| 925 | { "AXI2APB_7", 0x8a000 }, | ||
| 926 | { "AXI2APB_8", 0x8b000 }, | ||
| 927 | { "AXI2APB_9", 0x8c000 }, | ||
| 928 | { "AXI2APB_3", 0x8d000 }, | ||
| 929 | { "AXI2APB_21", 0x7d000 }, | ||
| 930 | { "AXI2APB_22", 0x7e000 }, | ||
| 931 | { "AXI2APB_23", 0x7f000 }, | ||
| 932 | { "AXI2APB_24", 0x80000 }, | ||
| 933 | { "AXI2APB_25", 0x81000 }, | ||
| 934 | { "AXI2APB_26", 0x82000 }, | ||
| 935 | { "AXI2APB_27", 0x83000 }, | ||
| 936 | { "AXI2APB_28", 0x84000 }, | ||
| 937 | { "PCIE_C4", 0x53000 }, | ||
| 938 | { "PCIE_C5", 0x54000 }, | ||
| 939 | { "PCIE_C6", 0x55000 }, | ||
| 940 | { "PCIE_C7", 0x56000 }, | ||
| 941 | { "PCIE_C2", 0x57000 }, | ||
| 942 | { "PCIE_C3", 0x58000 }, | ||
| 943 | { "PCIE_C0", 0x59000 }, | ||
| 944 | { "PCIE_C1", 0x5a000 }, | ||
| 945 | { "AXI2APB_29", 0x85000 }, | ||
| 946 | { "AXI2APB_30", 0x86000 }, | ||
| 947 | }; | ||
| 948 | |||
| 949 | static const struct tegra234_cbb_fabric tegra241_cbb_fabric = { | ||
| 950 | .name = "cbb-fabric", | ||
| 951 | .master_id = tegra241_master_id, | ||
| 952 | .slave_map = tegra241_cbb_slave_map, | ||
| 953 | .errors = tegra241_cbb_errors, | ||
| 954 | .notifier_offset = 0x60000, | ||
| 955 | .off_mask_erd = 0x40004, | ||
| 956 | }; | ||
| 957 | |||
| 958 | static const struct tegra234_slave_lookup tegra241_bpmp_slave_map[] = { | ||
| 959 | { "RSVD", 0x00000 }, | ||
| 960 | { "RSVD", 0x00000 }, | ||
| 961 | { "CBB", 0x15000 }, | ||
| 962 | { "CPU", 0x16000 }, | ||
| 963 | { "AXI2APB", 0x00000 }, | ||
| 964 | { "DBB0", 0x17000 }, | ||
| 965 | { "DBB1", 0x18000 }, | ||
| 966 | }; | ||
| 967 | |||
| 968 | static const struct tegra234_cbb_fabric tegra241_bpmp_fabric = { | ||
| 969 | .name = "bpmp-fabric", | ||
| 970 | .master_id = tegra241_master_id, | ||
| 971 | .slave_map = tegra241_bpmp_slave_map, | ||
| 972 | .errors = tegra241_cbb_errors, | ||
| 973 | .notifier_offset = 0x19000, | ||
| 974 | }; | ||
| 975 | |||
| 976 | static const struct of_device_id tegra234_cbb_dt_ids[] = { | ||
| 977 | { .compatible = "nvidia,tegra234-cbb-fabric", .data = &tegra234_cbb_fabric }, | ||
| 978 | { .compatible = "nvidia,tegra234-aon-fabric", .data = &tegra234_aon_fabric }, | ||
| 979 | { .compatible = "nvidia,tegra234-bpmp-fabric", .data = &tegra234_bpmp_fabric }, | ||
| 980 | { .compatible = "nvidia,tegra234-dce-fabric", .data = &tegra234_dce_fabric }, | ||
| 981 | { .compatible = "nvidia,tegra234-rce-fabric", .data = &tegra234_rce_fabric }, | ||
| 982 | { .compatible = "nvidia,tegra234-sce-fabric", .data = &tegra234_sce_fabric }, | ||
| 983 | { /* sentinel */ }, | ||
| 984 | }; | ||
| 985 | MODULE_DEVICE_TABLE(of, tegra234_cbb_dt_ids); | ||
| 986 | |||
| 987 | struct tegra234_cbb_acpi_uid { | ||
| 988 | const char *hid; | ||
| 989 | const char *uid; | ||
| 990 | const struct tegra234_cbb_fabric *fabric; | ||
| 991 | }; | ||
| 992 | |||
| 993 | static const struct tegra234_cbb_acpi_uid tegra234_cbb_acpi_uids[] = { | ||
| 994 | { "NVDA1070", "1", &tegra241_cbb_fabric }, | ||
| 995 | { "NVDA1070", "2", &tegra241_bpmp_fabric }, | ||
| 996 | { }, | ||
| 997 | }; | ||
| 998 | |||
| 999 | static const struct | ||
| 1000 | tegra234_cbb_fabric *tegra234_cbb_acpi_get_fabric(struct acpi_device *adev) | ||
| 1001 | { | ||
| 1002 | const struct tegra234_cbb_acpi_uid *entry; | ||
| 1003 | |||
| 1004 | for (entry = tegra234_cbb_acpi_uids; entry->hid; entry++) { | ||
| 1005 | if (acpi_dev_hid_uid_match(adev, entry->hid, entry->uid)) | ||
| 1006 | return entry->fabric; | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | return NULL; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | static const struct acpi_device_id tegra241_cbb_acpi_ids[] = { | ||
| 1013 | { "NVDA1070" }, | ||
| 1014 | { }, | ||
| 1015 | }; | ||
| 1016 | MODULE_DEVICE_TABLE(acpi, tegra241_cbb_acpi_ids); | ||
| 1017 | |||
| 1018 | static int tegra234_cbb_probe(struct platform_device *pdev) | ||
| 1019 | { | ||
| 1020 | const struct tegra234_cbb_fabric *fabric; | ||
| 1021 | struct tegra234_cbb *cbb; | ||
| 1022 | unsigned long flags = 0; | ||
| 1023 | int err; | ||
| 1024 | |||
| 1025 | if (pdev->dev.of_node) { | ||
| 1026 | fabric = of_device_get_match_data(&pdev->dev); | ||
| 1027 | } else { | ||
| 1028 | struct acpi_device *device = ACPI_COMPANION(&pdev->dev); | ||
| 1029 | if (!device) | ||
| 1030 | return -ENODEV; | ||
| 1031 | |||
| 1032 | fabric = tegra234_cbb_acpi_get_fabric(device); | ||
| 1033 | if (!fabric) { | ||
| 1034 | dev_err(&pdev->dev, "no device match found\n"); | ||
| 1035 | return -ENODEV; | ||
| 1036 | } | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | cbb = devm_kzalloc(&pdev->dev, sizeof(*cbb), GFP_KERNEL); | ||
| 1040 | if (!cbb) | ||
| 1041 | return -ENOMEM; | ||
| 1042 | |||
| 1043 | INIT_LIST_HEAD(&cbb->base.node); | ||
| 1044 | cbb->base.ops = &tegra234_cbb_ops; | ||
| 1045 | cbb->base.dev = &pdev->dev; | ||
| 1046 | cbb->fabric = fabric; | ||
| 1047 | |||
| 1048 | cbb->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &cbb->res); | ||
| 1049 | if (IS_ERR(cbb->regs)) | ||
| 1050 | return PTR_ERR(cbb->regs); | ||
| 1051 | |||
| 1052 | err = tegra_cbb_get_irq(pdev, NULL, &cbb->sec_irq); | ||
| 1053 | if (err) | ||
| 1054 | return err; | ||
| 1055 | |||
| 1056 | platform_set_drvdata(pdev, cbb); | ||
| 1057 | |||
| 1058 | spin_lock_irqsave(&cbb_lock, flags); | ||
| 1059 | list_add(&cbb->base.node, &cbb_list); | ||
| 1060 | spin_unlock_irqrestore(&cbb_lock, flags); | ||
| 1061 | |||
| 1062 | /* set ERD bit to mask SError and generate interrupt to report error */ | ||
| 1063 | if (cbb->fabric->off_mask_erd) | ||
| 1064 | tegra234_cbb_mask_serror(cbb); | ||
| 1065 | |||
| 1066 | return tegra_cbb_register(&cbb->base); | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | static int tegra234_cbb_remove(struct platform_device *pdev) | ||
| 1070 | { | ||
| 1071 | return 0; | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | static int __maybe_unused tegra234_cbb_resume_noirq(struct device *dev) | ||
| 1075 | { | ||
| 1076 | struct tegra234_cbb *cbb = dev_get_drvdata(dev); | ||
| 1077 | |||
| 1078 | tegra234_cbb_error_enable(&cbb->base); | ||
| 1079 | |||
| 1080 | dev_dbg(dev, "%s resumed\n", cbb->fabric->name); | ||
| 1081 | |||
| 1082 | return 0; | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | static const struct dev_pm_ops tegra234_cbb_pm = { | ||
| 1086 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, tegra234_cbb_resume_noirq) | ||
| 1087 | }; | ||
| 1088 | |||
| 1089 | static struct platform_driver tegra234_cbb_driver = { | ||
| 1090 | .probe = tegra234_cbb_probe, | ||
| 1091 | .remove = tegra234_cbb_remove, | ||
| 1092 | .driver = { | ||
| 1093 | .name = "tegra234-cbb", | ||
| 1094 | .of_match_table = tegra234_cbb_dt_ids, | ||
| 1095 | .acpi_match_table = tegra241_cbb_acpi_ids, | ||
| 1096 | .pm = &tegra234_cbb_pm, | ||
| 1097 | }, | ||
| 1098 | }; | ||
| 1099 | |||
| 1100 | static int __init tegra234_cbb_init(void) | ||
| 1101 | { | ||
| 1102 | return platform_driver_register(&tegra234_cbb_driver); | ||
| 1103 | } | ||
| 1104 | pure_initcall(tegra234_cbb_init); | ||
| 1105 | |||
| 1106 | static void __exit tegra234_cbb_exit(void) | ||
| 1107 | { | ||
| 1108 | platform_driver_unregister(&tegra234_cbb_driver); | ||
| 1109 | } | ||
| 1110 | module_exit(tegra234_cbb_exit); | ||
| 1111 | |||
| 1112 | MODULE_DESCRIPTION("Control Backbone 2.0 error handling driver for Tegra234"); | ||
| 1113 | MODULE_LICENSE("GPL"); | ||
| @@ -568,6 +568,7 @@ static int __init tegra_init_fuse(void) · 567 unmodified lines | |||
| 568 | np = of_find_matching_node(NULL, car_match); | 568 | np = of_find_matching_node(NULL, car_match); |
| 569 | if (np) { | 569 | if (np) { |
| 570 | void __iomem *base = of_iomap(np, 0); | 570 | void __iomem *base = of_iomap(np, 0); |
| 571 | of_node_put(np); | ||
| 571 | if (base) { | 572 | if (base) { |
| 572 | tegra_enable_fuse_clk(base); | 573 | tegra_enable_fuse_clk(base); |
| 573 | iounmap(base); | 574 | iounmap(base); |
| @@ -16,12 +16,16 @@ · 15 unmodified lines | |||
| 16 | 16 | ||
| 17 | #define FUSE_SKU_INFO 0x10 | 17 | #define FUSE_SKU_INFO 0x10 |
| 18 | 18 | ||
| 19 | #define ERD_ERR_CONFIG 0x120c | ||
| 20 | #define ERD_MASK_INBAND_ERR 0x1 | ||
| 21 | |||
| 19 | #define PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT 4 | 22 | #define PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT 4 |
| 20 | #define PMC_STRAPPING_OPT_A_RAM_CODE_MASK_LONG \ | 23 | #define PMC_STRAPPING_OPT_A_RAM_CODE_MASK_LONG \ |
| 21 | (0xf << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT) | 24 | (0xf << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT) |
| 22 | #define PMC_STRAPPING_OPT_A_RAM_CODE_MASK_SHORT \ | 25 | #define PMC_STRAPPING_OPT_A_RAM_CODE_MASK_SHORT \ |
| 23 | (0x3 << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT) | 26 | (0x3 << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT) |
| 24 | 27 | ||
| 28 | static void __iomem *apbmisc_base; | ||
| 25 | static bool long_ram_code; | 29 | static bool long_ram_code; |
| 26 | static u32 strapping; | 30 | static u32 strapping; |
| 27 | static u32 chipid; | 31 | static u32 chipid; |
| @@ -93,6 +97,28 @@ u32 tegra_read_ram_code(void) · 65 unmodified lines | |||
| 93 | } | 97 | } |
| 94 | EXPORT_SYMBOL_GPL(tegra_read_ram_code); | 98 | EXPORT_SYMBOL_GPL(tegra_read_ram_code); |
| 95 | 99 | ||
| 100 | /* | ||
| 101 | * The function sets ERD(Error Response Disable) bit. | ||
| 102 | * This allows to mask inband errors and always send an | ||
| 103 | * OKAY response from CBB to the master which caused error. | ||
| 104 | */ | ||
| 105 | int tegra194_miscreg_mask_serror(void) | ||
| 106 | { | ||
| 107 | if (!apbmisc_base) | ||
| 108 | return -EPROBE_DEFER; | ||
| 109 | |||
| 110 | if (!of_machine_is_compatible("nvidia,tegra194")) { | ||
| 111 | WARN(1, "Only supported for Tegra194 devices!\n"); | ||
| 112 | return -EOPNOTSUPP; | ||
| 113 | } | ||
| 114 | |||
| 115 | writel_relaxed(ERD_MASK_INBAND_ERR, | ||
| 116 | apbmisc_base + ERD_ERR_CONFIG); | ||
| 117 | |||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | EXPORT_SYMBOL(tegra194_miscreg_mask_serror); | ||
| 121 | |||
| 96 | static const struct of_device_id apbmisc_match[] __initconst = { | 122 | static const struct of_device_id apbmisc_match[] __initconst = { |
| 97 | { .compatible = "nvidia,tegra20-apbmisc", }, | 123 | { .compatible = "nvidia,tegra20-apbmisc", }, |
| 98 | { .compatible = "nvidia,tegra186-misc", }, | 124 | { .compatible = "nvidia,tegra186-misc", }, |
| @@ -134,7 +160,7 @@ void __init tegra_init_revision(void) · 35 unmodified lines | |||
| 134 | 160 | ||
| 135 | void __init tegra_init_apbmisc(void) | 161 | void __init tegra_init_apbmisc(void) |
| 136 | { | 162 | { |
| 137 | void __iomem *apbmisc_base, *strapping_base; | 163 | void __iomem *strapping_base; |
| 138 | struct resource apbmisc, straps; | 164 | struct resource apbmisc, straps; |
| 139 | struct device_node *np; | 165 | struct device_node *np; |
| 140 | 166 | ||
| @@ -182,12 +208,12 @@ void __init tegra_init_apbmisc(void) · 41 unmodified lines | |||
| 182 | */ | 208 | */ |
| 183 | if (of_address_to_resource(np, 0, &apbmisc) < 0) { | 209 | if (of_address_to_resource(np, 0, &apbmisc) < 0) { |
| 184 | pr_err("failed to get APBMISC registers\n"); | 210 | pr_err("failed to get APBMISC registers\n"); |
| 185 | return; | 211 | goto put; |
| 186 | } | 212 | } |
| 187 | 213 | ||
| 188 | if (of_address_to_resource(np, 1, &straps) < 0) { | 214 | if (of_address_to_resource(np, 1, &straps) < 0) { |
| 189 | pr_err("failed to get strapping options registers\n"); | 215 | pr_err("failed to get strapping options registers\n"); |
| 190 | return; | 216 | goto put; |
| 191 | } | 217 | } |
| 192 | } | 218 | } |
| 193 | 219 | ||
| @@ -196,7 +222,6 @@ void __init tegra_init_apbmisc(void) · 2 unmodified lines | |||
| 196 | pr_err("failed to map APBMISC registers\n"); | 222 | pr_err("failed to map APBMISC registers\n"); |
| 197 | } else { | 223 | } else { |
| 198 | chipid = readl_relaxed(apbmisc_base + 4); | 224 | chipid = readl_relaxed(apbmisc_base + 4); |
| 199 | iounmap(apbmisc_base); | ||
| 200 | } | 225 | } |
| 201 | 226 | ||
| 202 | strapping_base = ioremap(straps.start, resource_size(&straps)); | 227 | strapping_base = ioremap(straps.start, resource_size(&straps)); |
| @@ -208,4 +233,7 @@ void __init tegra_init_apbmisc(void) · 5 unmodified lines | |||
| 208 | } | 233 | } |
| 209 | 234 | ||
| 210 | long_ram_code = of_property_read_bool(np, "nvidia,long-ram-code"); | 235 | long_ram_code = of_property_read_bool(np, "nvidia,long-ram-code"); |
| 236 | |||
| 237 | put: | ||
| 238 | of_node_put(np); | ||
| 211 | } | 239 | } |
| @@ -296,6 +296,17 @@ struct tegra_wake_event { · 295 unmodified lines | |||
| 296 | } gpio; | 296 | } gpio; |
| 297 | }; | 297 | }; |
| 298 | 298 | ||
| 299 | #define TEGRA_WAKE_SIMPLE(_name, _id) \ | ||
| 300 | { \ | ||
| 301 | .name = _name, \ | ||
| 302 | .id = _id, \ | ||
| 303 | .irq = 0, \ | ||
| 304 | .gpio = { \ | ||
| 305 | .instance = UINT_MAX, \ | ||
| 306 | .pin = UINT_MAX, \ | ||
| 307 | }, \ | ||
| 308 | } | ||
| 309 | |||
| 299 | #define TEGRA_WAKE_IRQ(_name, _id, _irq) \ | 310 | #define TEGRA_WAKE_IRQ(_name, _id, _irq) \ |
| 300 | { \ | 311 | { \ |
| 301 | .name = _name, \ | 312 | .name = _name, \ |
| @@ -2239,6 +2250,7 @@ static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq, · 1937 unmodified lines | |||
| 2239 | for (i = 0; i < soc->num_wake_events; i++) { | 2250 | for (i = 0; i < soc->num_wake_events; i++) { |
| 2240 | const struct tegra_wake_event *event = &soc->wake_events[i]; | 2251 | const struct tegra_wake_event *event = &soc->wake_events[i]; |
| 2241 | 2252 | ||
| 2253 | /* IRQ and simple wake events */ | ||
| 2242 | if (fwspec->param_count == 2) { | 2254 | if (fwspec->param_count == 2) { |
| 2243 | struct irq_fwspec spec; | 2255 | struct irq_fwspec spec; |
| 2244 | 2256 | ||
| @@ -2251,6 +2263,12 @@ static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq, · 6 unmodified lines | |||
| 2251 | if (err < 0) | 2263 | if (err < 0) |
| 2252 | break; | 2264 | break; |
| 2253 | 2265 | ||
| 2266 | /* simple hierarchies stop at the PMC level */ | ||
| 2267 | if (event->irq == 0) { | ||
| 2268 | err = irq_domain_disconnect_hierarchy(domain->parent, virq); | ||
| 2269 | break; | ||
| 2270 | } | ||
| 2271 | |||
| 2254 | spec.fwnode = &pmc->dev->of_node->fwnode; | 2272 | spec.fwnode = &pmc->dev->of_node->fwnode; |
| 2255 | spec.param_count = 3; | 2273 | spec.param_count = 3; |
| 2256 | spec.param[0] = GIC_SPI; | 2274 | spec.param[0] = GIC_SPI; |
| @@ -2263,6 +2281,7 @@ static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq, · 6 unmodified lines | |||
| 2263 | break; | 2281 | break; |
| 2264 | } | 2282 | } |
| 2265 | 2283 | ||
| 2284 | /* GPIO wake events */ | ||
| 2266 | if (fwspec->param_count == 3) { | 2285 | if (fwspec->param_count == 3) { |
| 2267 | if (event->gpio.instance != fwspec->param[0] || | 2286 | if (event->gpio.instance != fwspec->param[0] || |
| 2268 | event->gpio.pin != fwspec->param[1]) | 2287 | event->gpio.pin != fwspec->param[1]) |
| @@ -2274,7 +2293,7 @@ static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq, · 5 unmodified lines | |||
| 2274 | 2293 | ||
| 2275 | /* GPIO hierarchies stop at the PMC level */ | 2294 | /* GPIO hierarchies stop at the PMC level */ |
| 2276 | if (!err && domain->parent) | 2295 | if (!err && domain->parent) |
| 2277 | err = irq_domain_disconnect_hierarchy(domain->parent, | 2296 | err = irq_domain_disconnect_hierarchy(domain->parent, |
| 2278 | virq); | 2297 | virq); |
| 2279 | break; | 2298 | break; |
| 2280 | } | 2299 | } |
| @@ -2885,17 +2904,10 @@ static int tegra_pmc_probe(struct platform_device *pdev) · 604 unmodified lines | |||
| 2885 | pmc->scratch = base; | 2904 | pmc->scratch = base; |
| 2886 | } | 2905 | } |
| 2887 | 2906 | ||
| 2888 | pmc->clk = devm_clk_get(&pdev->dev, "pclk"); | 2907 | pmc->clk = devm_clk_get_optional(&pdev->dev, "pclk"); |
| 2889 | if (IS_ERR(pmc->clk)) { | 2908 | if (IS_ERR(pmc->clk)) |
| 2890 | err = PTR_ERR(pmc->clk); | 2909 | return dev_err_probe(&pdev->dev, PTR_ERR(pmc->clk), |
| 2891 | 2910 | "failed to get pclk\n"); | |
| 2892 | if (err != -ENOENT) { | ||
| 2893 | dev_err(&pdev->dev, "failed to get pclk: %d\n", err); | ||
| 2894 | return err; | ||
| 2895 | } | ||
| 2896 | |||
| 2897 | pmc->clk = NULL; | ||
| 2898 | } | ||
| 2899 | 2911 | ||
| 2900 | /* | 2912 | /* |
| 2901 | * PMC should be last resort for restarting since it soft-resets | 2913 | * PMC should be last resort for restarting since it soft-resets |
| @@ -3757,6 +3769,13 @@ static const struct tegra_wake_event tegra194_wake_events[] = { · 855 unmodified lines | |||
| 3757 | TEGRA_WAKE_IRQ("pmu", 24, 209), | 3769 | TEGRA_WAKE_IRQ("pmu", 24, 209), |
| 3758 | TEGRA_WAKE_GPIO("power", 29, 1, TEGRA194_AON_GPIO(EE, 4)), | 3770 | TEGRA_WAKE_GPIO("power", 29, 1, TEGRA194_AON_GPIO(EE, 4)), |
| 3759 | TEGRA_WAKE_IRQ("rtc", 73, 10), | 3771 | TEGRA_WAKE_IRQ("rtc", 73, 10), |
| 3772 | TEGRA_WAKE_SIMPLE("usb3-port-0", 76), | ||
| 3773 | TEGRA_WAKE_SIMPLE("usb3-port-1", 77), | ||
| 3774 | TEGRA_WAKE_SIMPLE("usb3-port-2-3", 78), | ||
| 3775 | TEGRA_WAKE_SIMPLE("usb2-port-0", 79), | ||
| 3776 | TEGRA_WAKE_SIMPLE("usb2-port-1", 80), | ||
| 3777 | TEGRA_WAKE_SIMPLE("usb2-port-2", 81), | ||
| 3778 | TEGRA_WAKE_SIMPLE("usb2-port-3", 82), | ||
| 3760 | }; | 3779 | }; |
| 3761 | 3780 | ||
| 3762 | static const struct tegra_pmc_soc tegra194_pmc_soc = { | 3781 | static const struct tegra_pmc_soc tegra194_pmc_soc = { |
| @@ -4025,7 +4044,7 @@ static int __init tegra_pmc_early_init(void) · 262 unmodified lines | |||
| 4025 | return -ENXIO; | 4044 | return -ENXIO; |
| 4026 | } | 4045 | } |
| 4027 | 4046 | ||
| 4028 | if (np) { | 4047 | if (of_device_is_available(np)) { |
| 4029 | pmc->soc = match->data; | 4048 | pmc->soc = match->data; |
| 4030 | 4049 | ||
| 4031 | if (pmc->soc->maybe_tz_only) | 4050 | if (pmc->soc->maybe_tz_only) |
| @@ -271,8 +271,8 @@ static int optee_ffa_shm_register(struct tee_context *ctx, struct tee_shm *shm, · 270 unmodified lines | |||
| 271 | unsigned long start) | 271 | unsigned long start) |
| 272 | { | 272 | { |
| 273 | struct optee *optee = tee_get_drvdata(ctx->teedev); | 273 | struct optee *optee = tee_get_drvdata(ctx->teedev); |
| 274 | const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops; | ||
| 275 | struct ffa_device *ffa_dev = optee->ffa.ffa_dev; | 274 | struct ffa_device *ffa_dev = optee->ffa.ffa_dev; |
| 275 | const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops; | ||
| 276 | struct ffa_mem_region_attributes mem_attr = { | 276 | struct ffa_mem_region_attributes mem_attr = { |
| 277 | .receiver = ffa_dev->vm_id, | 277 | .receiver = ffa_dev->vm_id, |
| 278 | .attrs = FFA_MEM_RW, | 278 | .attrs = FFA_MEM_RW, |
| @@ -294,14 +294,14 @@ static int optee_ffa_shm_register(struct tee_context *ctx, struct tee_shm *shm, · 15 unmodified lines | |||
| 294 | if (rc) | 294 | if (rc) |
| 295 | return rc; | 295 | return rc; |
| 296 | args.sg = sgt.sgl; | 296 | args.sg = sgt.sgl; |
| 297 | rc = ffa_ops->memory_share(ffa_dev, &args); | 297 | rc = mem_ops->memory_share(&args); |
| 298 | sg_free_table(&sgt); | 298 | sg_free_table(&sgt); |
| 299 | if (rc) | 299 | if (rc) |
| 300 | return rc; | 300 | return rc; |
| 301 | 301 | ||
| 302 | rc = optee_shm_add_ffa_handle(optee, shm, args.g_handle); | 302 | rc = optee_shm_add_ffa_handle(optee, shm, args.g_handle); |
| 303 | if (rc) { | 303 | if (rc) { |
| 304 | ffa_ops->memory_reclaim(args.g_handle, 0); | 304 | mem_ops->memory_reclaim(args.g_handle, 0); |
| 305 | return rc; | 305 | return rc; |
| 306 | } | 306 | } |
| 307 | 307 | ||
| @@ -314,8 +314,9 @@ static int optee_ffa_shm_unregister(struct tee_context *ctx, · 6 unmodified lines | |||
| 314 | struct tee_shm *shm) | 314 | struct tee_shm *shm) |
| 315 | { | 315 | { |
| 316 | struct optee *optee = tee_get_drvdata(ctx->teedev); | 316 | struct optee *optee = tee_get_drvdata(ctx->teedev); |
| 317 | const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops; | ||
| 318 | struct ffa_device *ffa_dev = optee->ffa.ffa_dev; | 317 | struct ffa_device *ffa_dev = optee->ffa.ffa_dev; |
| 318 | const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops; | ||
| 319 | const struct ffa_mem_ops *mem_ops = ffa_dev->ops->mem_ops; | ||
| 319 | u64 global_handle = shm->sec_world_id; | 320 | u64 global_handle = shm->sec_world_id; |
| 320 | struct ffa_send_direct_data data = { | 321 | struct ffa_send_direct_data data = { |
| 321 | .data0 = OPTEE_FFA_UNREGISTER_SHM, | 322 | .data0 = OPTEE_FFA_UNREGISTER_SHM, |
| @@ -327,11 +328,11 @@ static int optee_ffa_shm_unregister(struct tee_context *ctx, · 5 unmodified lines | |||
| 327 | optee_shm_rem_ffa_handle(optee, global_handle); | 328 | optee_shm_rem_ffa_handle(optee, global_handle); |
| 328 | shm->sec_world_id = 0; | 329 | shm->sec_world_id = 0; |
| 329 | 330 | ||
| 330 | rc = ffa_ops->sync_send_receive(ffa_dev, &data); | 331 | rc = msg_ops->sync_send_receive(ffa_dev, &data); |
| 331 | if (rc) | 332 | if (rc) |
| 332 | pr_err("Unregister SHM id 0x%llx rc %d\n", global_handle, rc); | 333 | pr_err("Unregister SHM id 0x%llx rc %d\n", global_handle, rc); |
| 333 | 334 | ||
| 334 | rc = ffa_ops->memory_reclaim(global_handle, 0); | 335 | rc = mem_ops->memory_reclaim(global_handle, 0); |
| 335 | if (rc) | 336 | if (rc) |
| 336 | pr_err("mem_reclaim: 0x%llx %d", global_handle, rc); | 337 | pr_err("mem_reclaim: 0x%llx %d", global_handle, rc); |
| 337 | 338 | ||
| @@ -342,7 +343,7 @@ static int optee_ffa_shm_unregister_supp(struct tee_context *ctx, · 4 unmodified lines | |||
| 342 | struct tee_shm *shm) | 343 | struct tee_shm *shm) |
| 343 | { | 344 | { |
| 344 | struct optee *optee = tee_get_drvdata(ctx->teedev); | 345 | struct optee *optee = tee_get_drvdata(ctx->teedev); |
| 345 | const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops; | 346 | const struct ffa_mem_ops *mem_ops; |
| 346 | u64 global_handle = shm->sec_world_id; | 347 | u64 global_handle = shm->sec_world_id; |
| 347 | int rc; | 348 | int rc; |
| 348 | 349 | ||
| @@ -353,7 +354,8 @@ static int optee_ffa_shm_unregister_supp(struct tee_context *ctx, · 4 unmodified lines | |||
| 353 | */ | 354 | */ |
| 354 | 355 | ||
| 355 | optee_shm_rem_ffa_handle(optee, global_handle); | 356 | optee_shm_rem_ffa_handle(optee, global_handle); |
| 356 | rc = ffa_ops->memory_reclaim(global_handle, 0); | 357 | mem_ops = optee->ffa.ffa_dev->ops->mem_ops; |
| 358 | rc = mem_ops->memory_reclaim(global_handle, 0); | ||
| 357 | if (rc) | 359 | if (rc) |
| 358 | pr_err("mem_reclaim: 0x%llx %d", global_handle, rc); | 360 | pr_err("mem_reclaim: 0x%llx %d", global_handle, rc); |
| 359 | 361 | ||
| @@ -529,8 +531,8 @@ static int optee_ffa_yielding_call(struct tee_context *ctx, · 169 unmodified lines | |||
| 529 | struct optee_msg_arg *rpc_arg) | 531 | struct optee_msg_arg *rpc_arg) |
| 530 | { | 532 | { |
| 531 | struct optee *optee = tee_get_drvdata(ctx->teedev); | 533 | struct optee *optee = tee_get_drvdata(ctx->teedev); |
| 532 | const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops; | ||
| 533 | struct ffa_device *ffa_dev = optee->ffa.ffa_dev; | 534 | struct ffa_device *ffa_dev = optee->ffa.ffa_dev; |
| 535 | const struct ffa_msg_ops *msg_ops = ffa_dev->ops->msg_ops; | ||
| 534 | struct optee_call_waiter w; | 536 | struct optee_call_waiter w; |
| 535 | u32 cmd = data->data0; | 537 | u32 cmd = data->data0; |
| 536 | u32 w4 = data->data1; | 538 | u32 w4 = data->data1; |
| @@ -541,7 +543,7 @@ static int optee_ffa_yielding_call(struct tee_context *ctx, · 4 unmodified lines | |||
| 541 | /* Initialize waiter */ | 543 | /* Initialize waiter */ |
| 542 | optee_cq_wait_init(&optee->call_queue, &w); | 544 | optee_cq_wait_init(&optee->call_queue, &w); |
| 543 | while (true) { | 545 | while (true) { |
| 544 | rc = ffa_ops->sync_send_receive(ffa_dev, data); | 546 | rc = msg_ops->sync_send_receive(ffa_dev, data); |
| 545 | if (rc) | 547 | if (rc) |
| 546 | goto done; | 548 | goto done; |
| 547 | 549 | ||
| @@ -576,7 +578,7 @@ static int optee_ffa_yielding_call(struct tee_context *ctx, · 28 unmodified lines | |||
| 576 | * OP-TEE has returned with a RPC request. | 578 | * OP-TEE has returned with a RPC request. |
| 577 | * | 579 | * |
| 578 | * Note that data->data4 (passed in register w7) is already | 580 | * Note that data->data4 (passed in register w7) is already |
| 579 | * filled in by ffa_ops->sync_send_receive() returning | 581 | * filled in by ffa_mem_ops->sync_send_receive() returning |
| 580 | * above. | 582 | * above. |
| 581 | */ | 583 | */ |
| 582 | cond_resched(); | 584 | cond_resched(); |
| @@ -652,14 +654,15 @@ static int optee_ffa_do_call_with_arg(struct tee_context *ctx, · 69 unmodified lines | |||
| 652 | */ | 654 | */ |
| 653 | 655 | ||
| 654 | static bool optee_ffa_api_is_compatbile(struct ffa_device *ffa_dev, | 656 | static bool optee_ffa_api_is_compatbile(struct ffa_device *ffa_dev, |
| 655 | const struct ffa_dev_ops *ops) | 657 | const struct ffa_ops *ops) |
| 656 | { | 658 | { |
| 659 | const struct ffa_msg_ops *msg_ops = ops->msg_ops; | ||
| 657 | struct ffa_send_direct_data data = { OPTEE_FFA_GET_API_VERSION }; | 660 | struct ffa_send_direct_data data = { OPTEE_FFA_GET_API_VERSION }; |
| 658 | int rc; | 661 | int rc; |
| 659 | 662 | ||
| 660 | ops->mode_32bit_set(ffa_dev); | 663 | msg_ops->mode_32bit_set(ffa_dev); |
| 661 | 664 | ||
| 662 | rc = ops->sync_send_receive(ffa_dev, &data); | 665 | rc = msg_ops->sync_send_receive(ffa_dev, &data); |
| 663 | if (rc) { | 666 | if (rc) { |
| 664 | pr_err("Unexpected error %d\n", rc); | 667 | pr_err("Unexpected error %d\n", rc); |
| 665 | return false; | 668 | return false; |
| @@ -672,7 +675,7 @@ static bool optee_ffa_api_is_compatbile(struct ffa_device *ffa_dev, · 6 unmodified lines | |||
| 672 | } | 675 | } |
| 673 | 676 | ||
| 674 | data = (struct ffa_send_direct_data){ OPTEE_FFA_GET_OS_VERSION }; | 677 | data = (struct ffa_send_direct_data){ OPTEE_FFA_GET_OS_VERSION }; |
| 675 | rc = ops->sync_send_receive(ffa_dev, &data); | 678 | rc = msg_ops->sync_send_receive(ffa_dev, &data); |
| 676 | if (rc) { | 679 | if (rc) { |
| 677 | pr_err("Unexpected error %d\n", rc); | 680 | pr_err("Unexpected error %d\n", rc); |
| 678 | return false; | 681 | return false; |
| @@ -687,14 +690,14 @@ static bool optee_ffa_api_is_compatbile(struct ffa_device *ffa_dev, · 8 unmodified lines | |||
| 687 | } | 690 | } |
| 688 | 691 | ||
| 689 | static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev, | 692 | static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev, |
| 690 | const struct ffa_dev_ops *ops, | 693 | const struct ffa_ops *ops, |
| 691 | u32 *sec_caps, | 694 | u32 *sec_caps, |
| 692 | unsigned int *rpc_param_count) | 695 | unsigned int *rpc_param_count) |
| 693 | { | 696 | { |
| 694 | struct ffa_send_direct_data data = { OPTEE_FFA_EXCHANGE_CAPABILITIES }; | 697 | struct ffa_send_direct_data data = { OPTEE_FFA_EXCHANGE_CAPABILITIES }; |
| 695 | int rc; | 698 | int rc; |
| 696 | 699 | ||
| 697 | rc = ops->sync_send_receive(ffa_dev, &data); | 700 | rc = ops->msg_ops->sync_send_receive(ffa_dev, &data); |
| 698 | if (rc) { | 701 | if (rc) { |
| 699 | pr_err("Unexpected error %d", rc); | 702 | pr_err("Unexpected error %d", rc); |
| 700 | return false; | 703 | return false; |
| @@ -783,7 +786,7 @@ static void optee_ffa_remove(struct ffa_device *ffa_dev) · 82 unmodified lines | |||
| 783 | 786 | ||
| 784 | static int optee_ffa_probe(struct ffa_device *ffa_dev) | 787 | static int optee_ffa_probe(struct ffa_device *ffa_dev) |
| 785 | { | 788 | { |
| 786 | const struct ffa_dev_ops *ffa_ops; | 789 | const struct ffa_ops *ffa_ops; |
| 787 | unsigned int rpc_param_count; | 790 | unsigned int rpc_param_count; |
| 788 | struct tee_shm_pool *pool; | 791 | struct tee_shm_pool *pool; |
| 789 | struct tee_device *teedev; | 792 | struct tee_device *teedev; |
| @@ -793,11 +796,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev) · 3 unmodified lines | |||
| 793 | u32 sec_caps; | 796 | u32 sec_caps; |
| 794 | int rc; | 797 | int rc; |
| 795 | 798 | ||
| 796 | ffa_ops = ffa_dev_ops_get(ffa_dev); | 799 | ffa_ops = ffa_dev->ops; |
| 797 | if (!ffa_ops) { | ||
| 798 | pr_warn("failed \"method\" init: ffa\n"); | ||
| 799 | return -ENOENT; | ||
| 800 | } | ||
| 801 | 800 | ||
| 802 | if (!optee_ffa_api_is_compatbile(ffa_dev, ffa_ops)) | 801 | if (!optee_ffa_api_is_compatbile(ffa_dev, ffa_ops)) |
| 803 | return -EINVAL; | 802 | return -EINVAL; |
| @@ -821,7 +820,6 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev) · 17 unmodified lines | |||
| 821 | 820 | ||
| 822 | optee->ops = &optee_ffa_ops; | 821 | optee->ops = &optee_ffa_ops; |
| 823 | optee->ffa.ffa_dev = ffa_dev; | 822 | optee->ffa.ffa_dev = ffa_dev; |
| 824 | optee->ffa.ffa_ops = ffa_ops; | ||
| 825 | optee->rpc_param_count = rpc_param_count; | 823 | optee->rpc_param_count = rpc_param_count; |
| 826 | 824 | ||
| 827 | teedev = tee_device_alloc(&optee_ffa_clnt_desc, NULL, optee->pool, | 825 | teedev = tee_device_alloc(&optee_ffa_clnt_desc, NULL, optee->pool, |
| @@ -111,7 +111,6 @@ struct optee_smc { · 110 unmodified lines | |||
| 111 | */ | 111 | */ |
| 112 | struct optee_ffa { | 112 | struct optee_ffa { |
| 113 | struct ffa_device *ffa_dev; | 113 | struct ffa_device *ffa_dev; |
| 114 | const struct ffa_dev_ops *ffa_ops; | ||
| 115 | /* Serializes access to @global_ids */ | 114 | /* Serializes access to @global_ids */ |
| 116 | struct mutex mutex; | 115 | struct mutex mutex; |
| 117 | struct rhashtable global_ids; | 116 | struct rhashtable global_ids; |
| @@ -1083,8 +1083,8 @@ config SERIAL_TIMBERDALE · 1082 unmodified lines | |||
| 1083 | config SERIAL_BCM63XX | 1083 | config SERIAL_BCM63XX |
| 1084 | tristate "Broadcom BCM63xx/BCM33xx UART support" | 1084 | tristate "Broadcom BCM63xx/BCM33xx UART support" |
| 1085 | select SERIAL_CORE | 1085 | select SERIAL_CORE |
| 1086 | depends on ARCH_BCM4908 || ARCH_BCMBCA || BCM63XX || BMIPS_GENERIC || COMPILE_TEST | 1086 | depends on ARCH_BCMBCA || BCM63XX || BMIPS_GENERIC || COMPILE_TEST |
| 1087 | default ARCH_BCM4908 || ARCH_BCMBCA || BCM63XX || BMIPS_GENERIC | 1087 | default ARCH_BCMBCA || BCM63XX || BMIPS_GENERIC |
| 1088 | help | 1088 | help |
| 1089 | This enables the driver for the onchip UART core found on | 1089 | This enables the driver for the onchip UART core found on |
| 1090 | the following chipsets: | 1090 | the following chipsets: |
| @@ -1799,7 +1799,7 @@ config BCM7038_WDT · 1798 unmodified lines | |||
| 1799 | tristate "BCM63xx/BCM7038 Watchdog" | 1799 | tristate "BCM63xx/BCM7038 Watchdog" |
| 1800 | select WATCHDOG_CORE | 1800 | select WATCHDOG_CORE |
| 1801 | depends on HAS_IOMEM | 1801 | depends on HAS_IOMEM |
| 1802 | depends on ARCH_BCM4908 || ARCH_BRCMSTB || BMIPS_GENERIC || BCM63XX || COMPILE_TEST | 1802 | depends on ARCH_BCMBCA || ARCH_BRCMSTB || BMIPS_GENERIC || BCM63XX || COMPILE_TEST |
| 1803 | help | 1803 | help |
| 1804 | Watchdog driver for the built-in hardware in Broadcom 7038 and | 1804 | Watchdog driver for the built-in hardware in Broadcom 7038 and |
| 1805 | later SoCs used in set-top boxes. BCM7038 was made public | 1805 | later SoCs used in set-top boxes. BCM7038 was made public |
| @@ -281,7 +281,6 @@ · 280 unmodified lines | |||
| 281 | #define IMX8MM_CLK_CLKOUT2_DIV 256 | 281 | #define IMX8MM_CLK_CLKOUT2_DIV 256 |
| 282 | #define IMX8MM_CLK_CLKOUT2 257 | 282 | #define IMX8MM_CLK_CLKOUT2 257 |
| 283 | 283 | ||
| 284 | |||
| 285 | #define IMX8MM_CLK_END 258 | 284 | #define IMX8MM_CLK_END 258 |
| 286 | 285 | ||
| 287 | #endif | 286 | #endif |
| @@ -37,10 +37,14 @@ · 36 unmodified lines | |||
| 37 | #define IMX_SC_R_DC_0_BLIT2 21 | 37 | #define IMX_SC_R_DC_0_BLIT2 21 |
| 38 | #define IMX_SC_R_DC_0_BLIT_OUT 22 | 38 | #define IMX_SC_R_DC_0_BLIT_OUT 22 |
| 39 | #define IMX_SC_R_PERF 23 | 39 | #define IMX_SC_R_PERF 23 |
| 40 | #define IMX_SC_R_USB_1_PHY 24 | ||
| 40 | #define IMX_SC_R_DC_0_WARP 25 | 41 | #define IMX_SC_R_DC_0_WARP 25 |
| 42 | #define IMX_SC_R_V2X_MU_0 26 | ||
| 43 | #define IMX_SC_R_V2X_MU_1 27 | ||
| 41 | #define IMX_SC_R_DC_0_VIDEO0 28 | 44 | #define IMX_SC_R_DC_0_VIDEO0 28 |
| 42 | #define IMX_SC_R_DC_0_VIDEO1 29 | 45 | #define IMX_SC_R_DC_0_VIDEO1 29 |
| 43 | #define IMX_SC_R_DC_0_FRAC0 30 | 46 | #define IMX_SC_R_DC_0_FRAC0 30 |
| 47 | #define IMX_SC_R_V2X_MU_2 31 | ||
| 44 | #define IMX_SC_R_DC_0 32 | 48 | #define IMX_SC_R_DC_0 32 |
| 45 | #define IMX_SC_R_GPU_2_PID0 33 | 49 | #define IMX_SC_R_GPU_2_PID0 33 |
| 46 | #define IMX_SC_R_DC_0_PLL_0 34 | 50 | #define IMX_SC_R_DC_0_PLL_0 34 |
| @@ -49,7 +53,10 @@ · 2 unmodified lines | |||
| 49 | #define IMX_SC_R_DC_1_BLIT1 37 | 53 | #define IMX_SC_R_DC_1_BLIT1 37 |
| 50 | #define IMX_SC_R_DC_1_BLIT2 38 | 54 | #define IMX_SC_R_DC_1_BLIT2 38 |
| 51 | #define IMX_SC_R_DC_1_BLIT_OUT 39 | 55 | #define IMX_SC_R_DC_1_BLIT_OUT 39 |
| 56 | #define IMX_SC_R_V2X_MU_3 40 | ||
| 57 | #define IMX_SC_R_V2X_MU_4 41 | ||
| 52 | #define IMX_SC_R_DC_1_WARP 42 | 58 | #define IMX_SC_R_DC_1_WARP 42 |
| 59 | #define IMX_SC_R_SECVIO 44 | ||
| 53 | #define IMX_SC_R_DC_1_VIDEO0 45 | 60 | #define IMX_SC_R_DC_1_VIDEO0 45 |
| 54 | #define IMX_SC_R_DC_1_VIDEO1 46 | 61 | #define IMX_SC_R_DC_1_VIDEO1 46 |
| 55 | #define IMX_SC_R_DC_1_FRAC0 47 | 62 | #define IMX_SC_R_DC_1_FRAC0 47 |
| @@ -0,0 +1,15 @@ | |||
| 1 | /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ | ||
| 2 | /* | ||
| 3 | * Copyright 2022 NXP | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef __DT_BINDINGS_IMX93_POWER_H__ | ||
| 7 | #define __DT_BINDINGS_IMX93_POWER_H__ | ||
| 8 | |||
| 9 | #define IMX93_MEDIABLK_PD_MIPI_DSI 0 | ||
| 10 | #define IMX93_MEDIABLK_PD_MIPI_CSI 1 | ||
| 11 | #define IMX93_MEDIABLK_PD_PXP 2 | ||
| 12 | #define IMX93_MEDIABLK_PD_LCDIF 3 | ||
| 13 | #define IMX93_MEDIABLK_PD_ISI 4 | ||
| 14 | |||
| 15 | #endif | ||
| @@ -49,5 +49,11 @@ · 48 unmodified lines | |||
| 49 | #define IMX8MP_HDMIBLK_PD_TRNG 4 | 49 | #define IMX8MP_HDMIBLK_PD_TRNG 4 |
| 50 | #define IMX8MP_HDMIBLK_PD_HDMI_TX 5 | 50 | #define IMX8MP_HDMIBLK_PD_HDMI_TX 5 |
| 51 | #define IMX8MP_HDMIBLK_PD_HDMI_TX_PHY 6 | 51 | #define IMX8MP_HDMIBLK_PD_HDMI_TX_PHY 6 |
| 52 | #define IMX8MP_HDMIBLK_PD_HDCP 7 | ||
| 53 | #define IMX8MP_HDMIBLK_PD_HRV 8 | ||
| 54 | |||
| 55 | #define IMX8MP_VPUBLK_PD_G1 0 | ||
| 56 | #define IMX8MP_VPUBLK_PD_G2 1 | ||
| 57 | #define IMX8MP_VPUBLK_PD_VC8000E 2 | ||
| 52 | 58 | ||
| 53 | #endif | 59 | #endif |
| @@ -36,6 +36,18 @@ · 35 unmodified lines | |||
| 36 | #define SM6350_MSS 4 | 36 | #define SM6350_MSS 4 |
| 37 | #define SM6350_MX 5 | 37 | #define SM6350_MX 5 |
| 38 | 38 | ||
| 39 | /* SM6350 Power Domain Indexes */ | ||
| 40 | #define SM6375_VDDCX 0 | ||
| 41 | #define SM6375_VDDCX_AO 1 | ||
| 42 | #define SM6375_VDDCX_VFL 2 | ||
| 43 | #define SM6375_VDDMX 3 | ||
| 44 | #define SM6375_VDDMX_AO 4 | ||
| 45 | #define SM6375_VDDMX_VFL 5 | ||
| 46 | #define SM6375_VDDGX 6 | ||
| 47 | #define SM6375_VDDGX_AO 7 | ||
| 48 | #define SM6375_VDD_LPI_CX 8 | ||
| 49 | #define SM6375_VDD_LPI_MX 9 | ||
| 50 | |||
| 39 | /* SM8150 Power Domain Indexes */ | 51 | /* SM8150 Power Domain Indexes */ |
| 40 | #define SM8150_MSS 0 | 52 | #define SM8150_MSS 0 |
| 41 | #define SM8150_EBI 1 | 53 | #define SM8150_EBI 1 |
| @@ -0,0 +1,69 @@ | |||
| 1 | /* SPDX-License-Identifier: (GPL-2.0 or MIT) */ | ||
| 2 | #ifndef __DT_BINDINGS_POWER_RK3588_POWER_H__ | ||
| 3 | #define __DT_BINDINGS_POWER_RK3588_POWER_H__ | ||
| 4 | |||
| 5 | /* VD_LITDSU */ | ||
| 6 | #define RK3588_PD_CPU_0 0 | ||
| 7 | #define RK3588_PD_CPU_1 1 | ||
| 8 | #define RK3588_PD_CPU_2 2 | ||
| 9 | #define RK3588_PD_CPU_3 3 | ||
| 10 | |||
| 11 | /* VD_BIGCORE0 */ | ||
| 12 | #define RK3588_PD_CPU_4 4 | ||
| 13 | #define RK3588_PD_CPU_5 5 | ||
| 14 | |||
| 15 | /* VD_BIGCORE1 */ | ||
| 16 | #define RK3588_PD_CPU_6 6 | ||
| 17 | #define RK3588_PD_CPU_7 7 | ||
| 18 | |||
| 19 | /* VD_NPU */ | ||
| 20 | #define RK3588_PD_NPU 8 | ||
| 21 | #define RK3588_PD_NPUTOP 9 | ||
| 22 | #define RK3588_PD_NPU1 10 | ||
| 23 | #define RK3588_PD_NPU2 11 | ||
| 24 | |||
| 25 | /* VD_GPU */ | ||
| 26 | #define RK3588_PD_GPU 12 | ||
| 27 | |||
| 28 | /* VD_VCODEC */ | ||
| 29 | #define RK3588_PD_VCODEC 13 | ||
| 30 | #define RK3588_PD_RKVDEC0 14 | ||
| 31 | #define RK3588_PD_RKVDEC1 15 | ||
| 32 | #define RK3588_PD_VENC0 16 | ||
| 33 | #define RK3588_PD_VENC1 17 | ||
| 34 | |||
| 35 | /* VD_DD01 */ | ||
| 36 | #define RK3588_PD_DDR01 18 | ||
| 37 | |||
| 38 | /* VD_DD23 */ | ||
| 39 | #define RK3588_PD_DDR23 19 | ||
| 40 | |||
| 41 | /* VD_LOGIC */ | ||
| 42 | #define RK3588_PD_CENTER 20 | ||
| 43 | #define RK3588_PD_VDPU 21 | ||
| 44 | #define RK3588_PD_RGA30 22 | ||
| 45 | #define RK3588_PD_AV1 23 | ||
| 46 | #define RK3588_PD_VOP 24 | ||
| 47 | #define RK3588_PD_VO0 25 | ||
| 48 | #define RK3588_PD_VO1 26 | ||
| 49 | #define RK3588_PD_VI 27 | ||
| 50 | #define RK3588_PD_ISP1 28 | ||
| 51 | #define RK3588_PD_FEC 29 | ||
| 52 | #define RK3588_PD_RGA31 30 | ||
| 53 | #define RK3588_PD_USB 31 | ||
| 54 | #define RK3588_PD_PHP 32 | ||
| 55 | #define RK3588_PD_GMAC 33 | ||
| 56 | #define RK3588_PD_PCIE 34 | ||
| 57 | #define RK3588_PD_NVM 35 | ||
| 58 | #define RK3588_PD_NVM0 36 | ||
| 59 | #define RK3588_PD_SDIO 37 | ||
| 60 | #define RK3588_PD_AUDIO 38 | ||
| 61 | #define RK3588_PD_SECURE 39 | ||
| 62 | #define RK3588_PD_SDMMC 40 | ||
| 63 | #define RK3588_PD_CRYPTO 41 | ||
| 64 | #define RK3588_PD_BUS 42 | ||
| 65 | |||
| 66 | /* VD_PMU */ | ||
| 67 | #define RK3588_PD_PMU1 43 | ||
| 68 | |||
| 69 | #endif | ||
| @@ -0,0 +1,35 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | |||
| 3 | #ifndef __DT_BINDINGS_POWER_RV1126_POWER_H__ | ||
| 4 | #define __DT_BINDINGS_POWER_RV1126_POWER_H__ | ||
| 5 | |||
| 6 | /* VD_CORE */ | ||
| 7 | #define RV1126_PD_CPU_0 0 | ||
| 8 | #define RV1126_PD_CPU_1 1 | ||
| 9 | #define RV1126_PD_CPU_2 2 | ||
| 10 | #define RV1126_PD_CPU_3 3 | ||
| 11 | #define RV1126_PD_CORE_ALIVE 4 | ||
| 12 | |||
| 13 | /* VD_PMU */ | ||
| 14 | #define RV1126_PD_PMU 5 | ||
| 15 | #define RV1126_PD_PMU_ALIVE 6 | ||
| 16 | |||
| 17 | /* VD_NPU */ | ||
| 18 | #define RV1126_PD_NPU 7 | ||
| 19 | |||
| 20 | /* VD_VEPU */ | ||
| 21 | #define RV1126_PD_VEPU 8 | ||
| 22 | |||
| 23 | /* VD_LOGIC */ | ||
| 24 | #define RV1126_PD_VI 9 | ||
| 25 | #define RV1126_PD_VO 10 | ||
| 26 | #define RV1126_PD_ISPP 11 | ||
| 27 | #define RV1126_PD_VDPU 12 | ||
| 28 | #define RV1126_PD_CRYPTO 13 | ||
| 29 | #define RV1126_PD_DDR 14 | ||
| 30 | #define RV1126_PD_NVM 15 | ||
| 31 | #define RV1126_PD_SDIO 16 | ||
| 32 | #define RV1126_PD_USB 17 | ||
| 33 | #define RV1126_PD_LOGIC_ALIVE 18 | ||
| 34 | |||
| 35 | #endif | ||
| @@ -17,6 +17,7 @@ struct ffa_device { · 16 unmodified lines | |||
| 17 | bool mode_32bit; | 17 | bool mode_32bit; |
| 18 | uuid_t uuid; | 18 | uuid_t uuid; |
| 19 | struct device dev; | 19 | struct device dev; |
| 20 | const struct ffa_ops *ops; | ||
| 20 | }; | 21 | }; |
| 21 | 22 | ||
| 22 | #define to_ffa_dev(d) container_of(d, struct ffa_device, dev) | 23 | #define to_ffa_dev(d) container_of(d, struct ffa_device, dev) |
| @@ -47,17 +48,18 @@ static inline void *ffa_dev_get_drvdata(struct ffa_device *fdev) · 24 unmodified lines | |||
| 47 | } | 48 | } |
| 48 | 49 | ||
| 49 | #if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT) | 50 | #if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT) |
| 50 | struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id); | 51 | struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id, |
| 52 | const struct ffa_ops *ops); | ||
| 51 | void ffa_device_unregister(struct ffa_device *ffa_dev); | 53 | void ffa_device_unregister(struct ffa_device *ffa_dev); |
| 52 | int ffa_driver_register(struct ffa_driver *driver, struct module *owner, | 54 | int ffa_driver_register(struct ffa_driver *driver, struct module *owner, |
| 53 | const char *mod_name); | 55 | const char *mod_name); |
| 54 | void ffa_driver_unregister(struct ffa_driver *driver); | 56 | void ffa_driver_unregister(struct ffa_driver *driver); |
| 55 | bool ffa_device_is_valid(struct ffa_device *ffa_dev); | 57 | bool ffa_device_is_valid(struct ffa_device *ffa_dev); |
| 56 | const struct ffa_dev_ops *ffa_dev_ops_get(struct ffa_device *dev); | ||
| 57 | 58 | ||
| 58 | #else | 59 | #else |
| 59 | static inline | 60 | static inline |
| 60 | struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id) | 61 | struct ffa_device *ffa_device_register(const uuid_t *uuid, int vm_id, |
| 62 | const struct ffa_ops *ops) | ||
| 61 | { | 63 | { |
| 62 | return NULL; | 64 | return NULL; |
| 63 | } | 65 | } |
| @@ -76,11 +78,6 @@ static inline void ffa_driver_unregister(struct ffa_driver *driver) {} · 12 unmodified lines | |||
| 76 | static inline | 78 | static inline |
| 77 | bool ffa_device_is_valid(struct ffa_device *ffa_dev) { return false; } | 79 | bool ffa_device_is_valid(struct ffa_device *ffa_dev) { return false; } |
| 78 | 80 | ||
| 79 | static inline | ||
| 80 | const struct ffa_dev_ops *ffa_dev_ops_get(struct ffa_device *dev) | ||
| 81 | { | ||
| 82 | return NULL; | ||
| 83 | } | ||
| 84 | #endif /* CONFIG_ARM_FFA_TRANSPORT */ | 81 | #endif /* CONFIG_ARM_FFA_TRANSPORT */ |
| 85 | 82 | ||
| 86 | #define ffa_register(driver) \ | 83 | #define ffa_register(driver) \ |
| @@ -109,7 +106,10 @@ struct ffa_partition_info { · 22 unmodified lines | |||
| 109 | #define FFA_PARTITION_DIRECT_SEND BIT(1) | 106 | #define FFA_PARTITION_DIRECT_SEND BIT(1) |
| 110 | /* partition can send and receive indirect messages. */ | 107 | /* partition can send and receive indirect messages. */ |
| 111 | #define FFA_PARTITION_INDIRECT_MSG BIT(2) | 108 | #define FFA_PARTITION_INDIRECT_MSG BIT(2) |
| 109 | /* partition runs in the AArch64 execution state. */ | ||
| 110 | #define FFA_PARTITION_AARCH64_EXEC BIT(8) | ||
| 112 | u32 properties; | 111 | u32 properties; |
| 112 | u32 uuid[4]; | ||
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| 115 | /* For use with FFA_MSG_SEND_DIRECT_{REQ,RESP} which pass data via registers */ | 115 | /* For use with FFA_MSG_SEND_DIRECT_{REQ,RESP} which pass data via registers */ |
| @@ -257,18 +257,28 @@ struct ffa_mem_ops_args { · 141 unmodified lines | |||
| 257 | struct ffa_mem_region_attributes *attrs; | 257 | struct ffa_mem_region_attributes *attrs; |
| 258 | }; | 258 | }; |
| 259 | 259 | ||
| 260 | struct ffa_dev_ops { | 260 | struct ffa_info_ops { |
| 261 | u32 (*api_version_get)(void); | 261 | u32 (*api_version_get)(void); |
| 262 | int (*partition_info_get)(const char *uuid_str, | 262 | int (*partition_info_get)(const char *uuid_str, |
| 263 | struct ffa_partition_info *buffer); | 263 | struct ffa_partition_info *buffer); |
| 264 | }; | ||
| 265 | |||
| 266 | struct ffa_msg_ops { | ||
| 264 | void (*mode_32bit_set)(struct ffa_device *dev); | 267 | void (*mode_32bit_set)(struct ffa_device *dev); |
| 265 | int (*sync_send_receive)(struct ffa_device *dev, | 268 | int (*sync_send_receive)(struct ffa_device *dev, |
| 266 | struct ffa_send_direct_data *data); | 269 | struct ffa_send_direct_data *data); |
| 270 | }; | ||
| 271 | |||
| 272 | struct ffa_mem_ops { | ||
| 267 | int (*memory_reclaim)(u64 g_handle, u32 flags); | 273 | int (*memory_reclaim)(u64 g_handle, u32 flags); |
| 268 | int (*memory_share)(struct ffa_device *dev, | 274 | int (*memory_share)(struct ffa_mem_ops_args *args); |
| 269 | struct ffa_mem_ops_args *args); | 275 | int (*memory_lend)(struct ffa_mem_ops_args *args); |
| 270 | int (*memory_lend)(struct ffa_device *dev, | 276 | }; |
| 271 | struct ffa_mem_ops_args *args); | 277 | |
| 278 | struct ffa_ops { | ||
| 279 | const struct ffa_info_ops *info_ops; | ||
| 280 | const struct ffa_msg_ops *msg_ops; | ||
| 281 | const struct ffa_mem_ops *mem_ops; | ||
| 272 | }; | 282 | }; |
| 273 | 283 | ||
| 274 | #endif /* _LINUX_ARM_FFA_H */ | 284 | #endif /* _LINUX_ARM_FFA_H */ |
| @@ -152,4 +152,16 @@ int apple_rtkit_send_message(struct apple_rtkit *rtk, u8 ep, u64 message, · 151 unmodified lines | |||
| 152 | int apple_rtkit_send_message_wait(struct apple_rtkit *rtk, u8 ep, u64 message, | 152 | int apple_rtkit_send_message_wait(struct apple_rtkit *rtk, u8 ep, u64 message, |
| 153 | unsigned long timeout, bool atomic); | 153 | unsigned long timeout, bool atomic); |
| 154 | 154 | ||
| 155 | /* | ||
| 156 | * Process incoming messages in atomic context. | ||
| 157 | * This only guarantees that messages arrive as far as the recv_message_early | ||
| 158 | * callback; drivers expecting to handle incoming messages synchronously | ||
| 159 | * by calling this function must do it that way. | ||
| 160 | * Will return 1 if some data was processed, 0 if none was, or a | ||
| 161 | * negative error code on failure. | ||
| 162 | * | ||
| 163 | * @rtk: RTKit reference | ||
| 164 | */ | ||
| 165 | int apple_rtkit_poll(struct apple_rtkit *rtk); | ||
| 166 | |||
| 155 | #endif /* _LINUX_APPLE_RTKIT_H_ */ | 167 | #endif /* _LINUX_APPLE_RTKIT_H_ */ |
| @@ -65,4 +65,6 @@ void mtk_mmsys_ddp_disconnect(struct device *dev, · 64 unmodified lines | |||
| 65 | enum mtk_ddp_comp_id cur, | 65 | enum mtk_ddp_comp_id cur, |
| 66 | enum mtk_ddp_comp_id next); | 66 | enum mtk_ddp_comp_id next); |
| 67 | 67 | ||
| 68 | void mtk_mmsys_ddp_dpi_fmt_config(struct device *dev, u32 val); | ||
| 69 | |||
| 68 | #endif /* __MTK_MMSYS_H */ | 70 | #endif /* __MTK_MMSYS_H */ |
| @@ -20,6 +20,8 @@ enum mtk_mutex_mod_index { · 19 unmodified lines | |||
| 20 | MUTEX_MOD_IDX_MDP_WDMA, | 20 | MUTEX_MOD_IDX_MDP_WDMA, |
| 21 | MUTEX_MOD_IDX_MDP_AAL0, | 21 | MUTEX_MOD_IDX_MDP_AAL0, |
| 22 | MUTEX_MOD_IDX_MDP_CCORR0, | 22 | MUTEX_MOD_IDX_MDP_CCORR0, |
| 23 | MUTEX_MOD_IDX_MDP_HDR0, | ||
| 24 | MUTEX_MOD_IDX_MDP_COLOR0, | ||
| 23 | 25 | ||
| 24 | MUTEX_MOD_IDX_MAX /* ALWAYS keep at the end */ | 26 | MUTEX_MOD_IDX_MAX /* ALWAYS keep at the end */ |
| 25 | }; | 27 | }; |
| @@ -22,4 +22,7 @@ · 21 unmodified lines | |||
| 22 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, MTK_SIP_SMC_CONVENTION, \ | 22 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, MTK_SIP_SMC_CONVENTION, \ |
| 23 | ARM_SMCCC_OWNER_SIP, fn_id) | 23 | ARM_SMCCC_OWNER_SIP, fn_id) |
| 24 | 24 | ||
| 25 | /* IOMMU related SMC call */ | ||
| 26 | #define MTK_SIP_KERNEL_IOMMU_CONTROL MTK_SIP_SMC_CMD(0x514) | ||
| 27 | |||
| 25 | #endif | 28 | #endif |
| @@ -78,11 +78,40 @@ struct llcc_edac_reg_data { · 77 unmodified lines | |||
| 78 | u8 ways_shift; | 78 | u8 ways_shift; |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | struct llcc_edac_reg_offset { | ||
| 82 | /* LLCC TRP registers */ | ||
| 83 | u32 trp_ecc_error_status0; | ||
| 84 | u32 trp_ecc_error_status1; | ||
| 85 | u32 trp_ecc_sb_err_syn0; | ||
| 86 | u32 trp_ecc_db_err_syn0; | ||
| 87 | u32 trp_ecc_error_cntr_clear; | ||
| 88 | u32 trp_interrupt_0_status; | ||
| 89 | u32 trp_interrupt_0_clear; | ||
| 90 | u32 trp_interrupt_0_enable; | ||
| 91 | |||
| 92 | /* LLCC Common registers */ | ||
| 93 | u32 cmn_status0; | ||
| 94 | u32 cmn_interrupt_0_enable; | ||
| 95 | u32 cmn_interrupt_2_enable; | ||
| 96 | |||
| 97 | /* LLCC DRP registers */ | ||
| 98 | u32 drp_ecc_error_cfg; | ||
| 99 | u32 drp_ecc_error_cntr_clear; | ||
| 100 | u32 drp_interrupt_status; | ||
| 101 | u32 drp_interrupt_clear; | ||
| 102 | u32 drp_interrupt_enable; | ||
| 103 | u32 drp_ecc_error_status0; | ||
| 104 | u32 drp_ecc_error_status1; | ||
| 105 | u32 drp_ecc_sb_err_syn0; | ||
| 106 | u32 drp_ecc_db_err_syn0; | ||
| 107 | }; | ||
| 108 | |||
| 81 | /** | 109 | /** |
| 82 | * struct llcc_drv_data - Data associated with the llcc driver | 110 | * struct llcc_drv_data - Data associated with the llcc driver |
| 83 | * @regmap: regmap associated with the llcc device | 111 | * @regmap: regmap associated with the llcc device |
| 84 | * @bcast_regmap: regmap associated with llcc broadcast offset | 112 | * @bcast_regmap: regmap associated with llcc broadcast offset |
| 85 | * @cfg: pointer to the data structure for slice configuration | 113 | * @cfg: pointer to the data structure for slice configuration |
| 114 | * @edac_reg_offset: Offset of the LLCC EDAC registers | ||
| 86 | * @lock: mutex associated with each slice | 115 | * @lock: mutex associated with each slice |
| 87 | * @cfg_size: size of the config data table | 116 | * @cfg_size: size of the config data table |
| 88 | * @max_slices: max slices as read from device tree | 117 | * @max_slices: max slices as read from device tree |
| @@ -96,6 +125,7 @@ struct llcc_drv_data { · 7 unmodified lines | |||
| 96 | struct regmap *regmap; | 125 | struct regmap *regmap; |
| 97 | struct regmap *bcast_regmap; | 126 | struct regmap *bcast_regmap; |
| 98 | const struct llcc_slice_config *cfg; | 127 | const struct llcc_slice_config *cfg; |
| 128 | const struct llcc_edac_reg_offset *edac_reg_offset; | ||
| 99 | struct mutex lock; | 129 | struct mutex lock; |
| 100 | u32 cfg_size; | 130 | u32 cfg_size; |
| 101 | u32 max_slices; | 131 | u32 max_slices; |
| @@ -75,7 +75,7 @@ struct qmi_elem_info { · 74 unmodified lines | |||
| 75 | enum qmi_array_type array_type; | 75 | enum qmi_array_type array_type; |
| 76 | u8 tlv_type; | 76 | u8 tlv_type; |
| 77 | u32 offset; | 77 | u32 offset; |
| 78 | struct qmi_elem_info *ei_array; | 78 | const struct qmi_elem_info *ei_array; |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | #define QMI_RESULT_SUCCESS_V01 0 | 81 | #define QMI_RESULT_SUCCESS_V01 0 |
| @@ -102,7 +102,7 @@ struct qmi_response_type_v01 { · 20 unmodified lines | |||
| 102 | u16 error; | 102 | u16 error; |
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | extern struct qmi_elem_info qmi_response_type_v01_ei[]; | 105 | extern const struct qmi_elem_info qmi_response_type_v01_ei[]; |
| 106 | 106 | ||
| 107 | /** | 107 | /** |
| 108 | * struct qmi_service - context to track lookup-results | 108 | * struct qmi_service - context to track lookup-results |
| @@ -173,7 +173,7 @@ struct qmi_txn { · 64 unmodified lines | |||
| 173 | struct completion completion; | 173 | struct completion completion; |
| 174 | int result; | 174 | int result; |
| 175 | 175 | ||
| 176 | struct qmi_elem_info *ei; | 176 | const struct qmi_elem_info *ei; |
| 177 | void *dest; | 177 | void *dest; |
| 178 | }; | 178 | }; |
| 179 | 179 | ||
| @@ -189,7 +189,7 @@ struct qmi_msg_handler { · 9 unmodified lines | |||
| 189 | unsigned int type; | 189 | unsigned int type; |
| 190 | unsigned int msg_id; | 190 | unsigned int msg_id; |
| 191 | 191 | ||
| 192 | struct qmi_elem_info *ei; | 192 | const struct qmi_elem_info *ei; |
| 193 | 193 | ||
| 194 | size_t decoded_size; | 194 | size_t decoded_size; |
| 195 | void (*fn)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, | 195 | void (*fn)(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, |
| @@ -249,23 +249,23 @@ void qmi_handle_release(struct qmi_handle *qmi); · 53 unmodified lines | |||
| 249 | 249 | ||
| 250 | ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, | 250 | ssize_t qmi_send_request(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, |
| 251 | struct qmi_txn *txn, int msg_id, size_t len, | 251 | struct qmi_txn *txn, int msg_id, size_t len, |
| 252 | struct qmi_elem_info *ei, const void *c_struct); | 252 | const struct qmi_elem_info *ei, const void *c_struct); |
| 253 | ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, | 253 | ssize_t qmi_send_response(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, |
| 254 | struct qmi_txn *txn, int msg_id, size_t len, | 254 | struct qmi_txn *txn, int msg_id, size_t len, |
| 255 | struct qmi_elem_info *ei, const void *c_struct); | 255 | const struct qmi_elem_info *ei, const void *c_struct); |
| 256 | ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, | 256 | ssize_t qmi_send_indication(struct qmi_handle *qmi, struct sockaddr_qrtr *sq, |
| 257 | int msg_id, size_t len, struct qmi_elem_info *ei, | 257 | int msg_id, size_t len, const struct qmi_elem_info *ei, |
| 258 | const void *c_struct); | 258 | const void *c_struct); |
| 259 | 259 | ||
| 260 | void *qmi_encode_message(int type, unsigned int msg_id, size_t *len, | 260 | void *qmi_encode_message(int type, unsigned int msg_id, size_t *len, |
| 261 | unsigned int txn_id, struct qmi_elem_info *ei, | 261 | unsigned int txn_id, const struct qmi_elem_info *ei, |
| 262 | const void *c_struct); | 262 | const void *c_struct); |
| 263 | 263 | ||
| 264 | int qmi_decode_message(const void *buf, size_t len, | 264 | int qmi_decode_message(const void *buf, size_t len, |
| 265 | struct qmi_elem_info *ei, void *c_struct); | 265 | const struct qmi_elem_info *ei, void *c_struct); |
| 266 | 266 | ||
| 267 | int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn, | 267 | int qmi_txn_init(struct qmi_handle *qmi, struct qmi_txn *txn, |
| 268 | struct qmi_elem_info *ei, void *c_struct); | 268 | const struct qmi_elem_info *ei, void *c_struct); |
| 269 | int qmi_txn_wait(struct qmi_txn *txn, unsigned long timeout); | 269 | int qmi_txn_wait(struct qmi_txn *txn, unsigned long timeout); |
| 270 | void qmi_txn_cancel(struct qmi_txn *txn); | 270 | void qmi_txn_cancel(struct qmi_txn *txn); |
| 271 | 271 | ||
| @@ -14,6 +14,6 @@ · 13 unmodified lines | |||
| 14 | #define _SUNXI_SRAM_H_ | 14 | #define _SUNXI_SRAM_H_ |
| 15 | 15 | ||
| 16 | int sunxi_sram_claim(struct device *dev); | 16 | int sunxi_sram_claim(struct device *dev); |
| 17 | int sunxi_sram_release(struct device *dev); | 17 | void sunxi_sram_release(struct device *dev); |
| 18 | 18 | ||
| 19 | #endif /* _SUNXI_SRAM_H_ */ | 19 | #endif /* _SUNXI_SRAM_H_ */ |
| @@ -11,6 +11,11 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | #if IS_ENABLED(CONFIG_MTK_SMI) | 12 | #if IS_ENABLED(CONFIG_MTK_SMI) |
| 13 | 13 | ||
| 14 | enum iommu_atf_cmd { | ||
| 15 | IOMMU_ATF_CMD_CONFIG_SMI_LARB, /* For mm master to en/disable iommu */ | ||
| 16 | IOMMU_ATF_CMD_MAX, | ||
| 17 | }; | ||
| 18 | |||
| 14 | #define MTK_SMI_MMU_EN(port) BIT(port) | 19 | #define MTK_SMI_MMU_EN(port) BIT(port) |
| 15 | 20 | ||
| 16 | struct mtk_smi_larb_iommu { | 21 | struct mtk_smi_larb_iommu { |
| @@ -58,6 +58,7 @@ u32 tegra_read_chipid(void); · 57 unmodified lines | |||
| 58 | u8 tegra_get_chip_id(void); | 58 | u8 tegra_get_chip_id(void); |
| 59 | u8 tegra_get_platform(void); | 59 | u8 tegra_get_platform(void); |
| 60 | bool tegra_is_silicon(void); | 60 | bool tegra_is_silicon(void); |
| 61 | int tegra194_miscreg_mask_serror(void); | ||
| 61 | #else | 62 | #else |
| 62 | static struct tegra_sku_info tegra_sku_info __maybe_unused; | 63 | static struct tegra_sku_info tegra_sku_info __maybe_unused; |
| 63 | 64 | ||
| @@ -95,6 +96,11 @@ static inline bool tegra_is_silicon(void) · 31 unmodified lines | |||
| 95 | { | 96 | { |
| 96 | return false; | 97 | return false; |
| 97 | } | 98 | } |
| 99 | |||
| 100 | static inline int tegra194_miscreg_mask_serror(void) | ||
| 101 | { | ||
| 102 | return false; | ||
| 103 | } | ||
| 98 | #endif | 104 | #endif |
| 99 | 105 | ||
| 100 | struct device *tegra_soc_device_register(void); | 106 | struct device *tegra_soc_device_register(void); |
| @@ -0,0 +1,47 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2021-2022, NVIDIA CORPORATION. All rights reserved | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef TEGRA_CBB_H | ||
| 7 | #define TEGRA_CBB_H | ||
| 8 | |||
| 9 | #include <linux/list.h> | ||
| 10 | |||
| 11 | struct tegra_cbb_error { | ||
| 12 | const char *code; | ||
| 13 | const char *source; | ||
| 14 | const char *desc; | ||
| 15 | }; | ||
| 16 | |||
| 17 | struct tegra_cbb { | ||
| 18 | struct device *dev; | ||
| 19 | const struct tegra_cbb_ops *ops; | ||
| 20 | struct list_head node; | ||
| 21 | }; | ||
| 22 | |||
| 23 | struct tegra_cbb_ops { | ||
| 24 | int (*debugfs_show)(struct tegra_cbb *cbb, struct seq_file *s, void *v); | ||
| 25 | int (*interrupt_enable)(struct tegra_cbb *cbb); | ||
| 26 | void (*error_enable)(struct tegra_cbb *cbb); | ||
| 27 | void (*fault_enable)(struct tegra_cbb *cbb); | ||
| 28 | void (*stall_enable)(struct tegra_cbb *cbb); | ||
| 29 | void (*error_clear)(struct tegra_cbb *cbb); | ||
| 30 | u32 (*get_status)(struct tegra_cbb *cbb); | ||
| 31 | }; | ||
| 32 | |||
| 33 | int tegra_cbb_get_irq(struct platform_device *pdev, unsigned int *nonsec_irq, | ||
| 34 | unsigned int *sec_irq); | ||
| 35 | __printf(2, 3) | ||
| 36 | void tegra_cbb_print_err(struct seq_file *file, const char *fmt, ...); | ||
| 37 | |||
| 38 | void tegra_cbb_print_cache(struct seq_file *file, u32 cache); | ||
| 39 | void tegra_cbb_print_prot(struct seq_file *file, u32 prot); | ||
| 40 | int tegra_cbb_register(struct tegra_cbb *cbb); | ||
| 41 | |||
| 42 | void tegra_cbb_fault_enable(struct tegra_cbb *cbb); | ||
| 43 | void tegra_cbb_stall_enable(struct tegra_cbb *cbb); | ||
| 44 | void tegra_cbb_error_clear(struct tegra_cbb *cbb); | ||
| 45 | u32 tegra_cbb_get_status(struct tegra_cbb *cbb); | ||
| 46 | |||
| 47 | #endif /* TEGRA_CBB_H */ | ||
| @@ -48,12 +48,26 @@ · 47 unmodified lines | |||
| 48 | #define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7) | 48 | #define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7) |
| 49 | 49 | ||
| 50 | #define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10) | 50 | #define PSCI_1_0_FN_PSCI_FEATURES PSCI_0_2_FN(10) |
| 51 | #define PSCI_1_0_FN_CPU_FREEZE PSCI_0_2_FN(11) | ||
| 52 | #define PSCI_1_0_FN_CPU_DEFAULT_SUSPEND PSCI_0_2_FN(12) | ||
| 53 | #define PSCI_1_0_FN_NODE_HW_STATE PSCI_0_2_FN(13) | ||
| 51 | #define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14) | 54 | #define PSCI_1_0_FN_SYSTEM_SUSPEND PSCI_0_2_FN(14) |
| 52 | #define PSCI_1_0_FN_SET_SUSPEND_MODE PSCI_0_2_FN(15) | 55 | #define PSCI_1_0_FN_SET_SUSPEND_MODE PSCI_0_2_FN(15) |
| 56 | #define PSCI_1_0_FN_STAT_RESIDENCY PSCI_0_2_FN(16) | ||
| 57 | #define PSCI_1_0_FN_STAT_COUNT PSCI_0_2_FN(17) | ||
| 58 | |||
| 53 | #define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) | 59 | #define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) |
| 60 | #define PSCI_1_1_FN_MEM_PROTECT PSCI_0_2_FN(19) | ||
| 61 | #define PSCI_1_1_FN_MEM_PROTECT_CHECK_RANGE PSCI_0_2_FN(19) | ||
| 54 | 62 | ||
| 63 | #define PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND PSCI_0_2_FN64(12) | ||
| 64 | #define PSCI_1_0_FN64_NODE_HW_STATE PSCI_0_2_FN64(13) | ||
| 55 | #define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) | 65 | #define PSCI_1_0_FN64_SYSTEM_SUSPEND PSCI_0_2_FN64(14) |
| 66 | #define PSCI_1_0_FN64_STAT_RESIDENCY PSCI_0_2_FN64(16) | ||
| 67 | #define PSCI_1_0_FN64_STAT_COUNT PSCI_0_2_FN64(17) | ||
| 68 | |||
| 56 | #define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) | 69 | #define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) |
| 70 | #define PSCI_1_1_FN64_MEM_PROTECT_CHECK_RANGE PSCI_0_2_FN64(19) | ||
| 57 | 71 | ||
| 58 | /* PSCI v0.2 power state encoding for CPU_SUSPEND function */ | 72 | /* PSCI v0.2 power state encoding for CPU_SUSPEND function */ |
| 59 | #define PSCI_0_2_POWER_STATE_ID_MASK 0xffff | 73 | #define PSCI_0_2_POWER_STATE_ID_MASK 0xffff |
| @@ -42,7 +42,7 @@ struct test_name_type_v01 { · 41 unmodified lines | |||
| 42 | char name[TEST_MAX_NAME_SIZE_V01]; | 42 | char name[TEST_MAX_NAME_SIZE_V01]; |
| 43 | }; | 43 | }; |
| 44 | 44 | ||
| 45 | static struct qmi_elem_info test_name_type_v01_ei[] = { | 45 | static const struct qmi_elem_info test_name_type_v01_ei[] = { |
| 46 | { | 46 | { |
| 47 | .data_type = QMI_DATA_LEN, | 47 | .data_type = QMI_DATA_LEN, |
| 48 | .elem_len = 1, | 48 | .elem_len = 1, |
| @@ -71,7 +71,7 @@ struct test_ping_req_msg_v01 { · 22 unmodified lines | |||
| 71 | struct test_name_type_v01 client_name; | 71 | struct test_name_type_v01 client_name; |
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | static struct qmi_elem_info test_ping_req_msg_v01_ei[] = { | 74 | static const struct qmi_elem_info test_ping_req_msg_v01_ei[] = { |
| 75 | { | 75 | { |
| 76 | .data_type = QMI_UNSIGNED_1_BYTE, | 76 | .data_type = QMI_UNSIGNED_1_BYTE, |
| 77 | .elem_len = 4, | 77 | .elem_len = 4, |
| @@ -113,7 +113,7 @@ struct test_ping_resp_msg_v01 { · 35 unmodified lines | |||
| 113 | struct test_name_type_v01 service_name; | 113 | struct test_name_type_v01 service_name; |
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| 116 | static struct qmi_elem_info test_ping_resp_msg_v01_ei[] = { | 116 | static const struct qmi_elem_info test_ping_resp_msg_v01_ei[] = { |
| 117 | { | 117 | { |
| 118 | .data_type = QMI_STRUCT, | 118 | .data_type = QMI_STRUCT, |
| 119 | .elem_len = 1, | 119 | .elem_len = 1, |
| @@ -172,7 +172,7 @@ struct test_data_req_msg_v01 { · 52 unmodified lines | |||
| 172 | struct test_name_type_v01 client_name; | 172 | struct test_name_type_v01 client_name; |
| 173 | }; | 173 | }; |
| 174 | 174 | ||
| 175 | static struct qmi_elem_info test_data_req_msg_v01_ei[] = { | 175 | static const struct qmi_elem_info test_data_req_msg_v01_ei[] = { |
| 176 | { | 176 | { |
| 177 | .data_type = QMI_DATA_LEN, | 177 | .data_type = QMI_DATA_LEN, |
| 178 | .elem_len = 1, | 178 | .elem_len = 1, |
| @@ -224,7 +224,7 @@ struct test_data_resp_msg_v01 { · 45 unmodified lines | |||
| 224 | struct test_name_type_v01 service_name; | 224 | struct test_name_type_v01 service_name; |
| 225 | }; | 225 | }; |
| 226 | 226 | ||
| 227 | static struct qmi_elem_info test_data_resp_msg_v01_ei[] = { | 227 | static const struct qmi_elem_info test_data_resp_msg_v01_ei[] = { |
| 228 | { | 228 | { |
| 229 | .data_type = QMI_STRUCT, | 229 | .data_type = QMI_STRUCT, |
| 230 | .elem_len = 1, | 230 | .elem_len = 1, |