mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-30 01:52:51 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			30970 lines
		
	
	
		
			958 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			30970 lines
		
	
	
		
			958 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From ea120b770155e6a18b94ac28c0afac85acd40105 Mon Sep 17 00:00:00 2001
 | |
| From: John Crispin <john@phrozen.org>
 | |
| Date: Thu, 7 Sep 2023 05:51:43 +0200
 | |
| Subject: [PATCH] ipq807x: drop upstream target
 | |
| 
 | |
| Signed-off-by: John Crispin <john@phrozen.org>
 | |
| ---
 | |
|  target/linux/ipq807x/Makefile                 |    22 -
 | |
|  .../ipq807x/base-files/etc/board.d/01_leds    |    33 -
 | |
|  .../ipq807x/base-files/etc/board.d/02_network |    52 -
 | |
|  .../etc/hotplug.d/firmware/11-ath11k-caldata  |    43 -
 | |
|  .../ipq807x/base-files/etc/init.d/bootcount   |    13 -
 | |
|  .../ipq807x/base-files/lib/upgrade/buffalo.sh |    55 -
 | |
|  .../ipq807x/base-files/lib/upgrade/mmc.sh     |    83 -
 | |
|  .../base-files/lib/upgrade/platform.sh        |   116 -
 | |
|  target/linux/ipq807x/config-5.15              |   509 -
 | |
|  .../arm64/boot/dts/qcom/ipq8070-cax1800.dts   |   322 -
 | |
|  .../arm64/boot/dts/qcom/ipq8071-ax3600.dts    |    73 -
 | |
|  .../arm64/boot/dts/qcom/ipq8071-ax3600.dtsi   |   311 -
 | |
|  .../arch/arm64/boot/dts/qcom/ipq8071-ax6.dts  |    46 -
 | |
|  .../arm64/boot/dts/qcom/ipq8071-eap102.dts    |   389 -
 | |
|  .../arch/arm64/boot/dts/qcom/ipq8072-301w.dts |   410 -
 | |
|  .../arm64/boot/dts/qcom/ipq8072-ax9000.dts    |   522 -
 | |
|  .../arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts  |   243 -
 | |
|  .../arch/arm64/boot/dts/qcom/ipq8072-haze.dts |   308 -
 | |
|  .../arm64/boot/dts/qcom/ipq8072-wax218.dts    |   191 -
 | |
|  .../arm64/boot/dts/qcom/ipq8074-512m.dtsi     |    19 -
 | |
|  .../arm64/boot/dts/qcom/ipq8074-ac-cpu.dtsi   |   153 -
 | |
|  .../boot/dts/qcom/ipq8074-cpr-regulator.dtsi  |   228 -
 | |
|  .../arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi |   531 -
 | |
|  .../arm64/boot/dts/qcom/ipq8074-hk-cpu.dtsi   |   218 -
 | |
|  .../arm64/boot/dts/qcom/ipq8074-nbg7815.dts   |   445 -
 | |
|  .../boot/dts/qcom/ipq8074-wxr-5950ax12.dts    |   376 -
 | |
|  target/linux/ipq807x/generic/target.mk        |     1 -
 | |
|  target/linux/ipq807x/image/Makefile           |    17 -
 | |
|  target/linux/ipq807x/image/generic.mk         |   175 -
 | |
|  ...-arm64-dts-qcom-ipq8074-add-SPMI-bus.patch |    43 -
 | |
|  ...pdate-BAM-DMA-node-name-per-DT-schem.patch |    26 -
 | |
|  ...4-dts-qcom-ipq8074-Add-QUP5-I2C-node.patch |    40 -
 | |
|  ...sm8996-Move-clock-cells-to-QMP-PHY-c.patch |    53 -
 | |
|  ...-arm64-dts-qcom-ipq8074-add-MDIO-bus.patch |    36 -
 | |
|  ...64-dts-qcom-ipq8074-add-SMEM-support.patch |    51 -
 | |
|  ...ipq8074-add-the-reserved-memory-node.patch |    30 -
 | |
|  ...om-ipq8074-enable-the-GICv2m-support.patch |    36 -
 | |
|  ...pq8074-drop-the-clock-frequency-prop.patch |    25 -
 | |
|  ...lign-dmas-in-I2C-SPI-UART-with-DT-sc.patch |    61 -
 | |
|  ...lign-clocks-in-I2C-SPI-with-DT-schem.patch |    68 -
 | |
|  ...orrect-DWC3-node-names-and-unit-addr.patch |    36 -
 | |
|  ...pq8074-add-dedicated-qcom-ipq8074-dw.patch |    36 -
 | |
|  ...align-DWC3-USB-clocks-with-DT-schema.patch |    39 -
 | |
|  ...64-dts-qcom-adjust-whitespace-around.patch |    36 -
 | |
|  ...ts-qcom-Fix-sdhci-node-names-use-mmc.patch |    34 -
 | |
|  ...ix-ordering-of-clocks-clock-names-fo.patch |    47 -
 | |
|  ...ck-qcom-ipq8074-add-PPE-crypto-clock.patch |    25 -
 | |
|  ...lk-qcom-ipq8074-add-PPE-crypto-clock.patch |    52 -
 | |
|  ...ngs-clock-qcom-ipq8074-add-USB-GDSCs.patch |    25 -
 | |
|  ...-v6.0-clk-qcom-ipq8074-add-USB-GDSCs.patch |    79 -
 | |
|  ...s-qcom-ipq8074-add-USB-power-domains.patch |    43 -
 | |
|  ...pq8074-move-ARMv8-timer-out-of-SoC-n.patch |    50 -
 | |
|  ...-dts-qcom-ipq8074-add-reset-to-SDHCI.patch |    27 -
 | |
|  ...com-ipq8074-drop-USB-PHY-clock-index.patch |    36 -
 | |
|  ...s-ipc-Consolidate-msm8994-type-apcs_.patch |    74 -
 | |
|  ...s-ipc-add-IPQ8074-APSS-clock-support.patch |    30 -
 | |
|  ...arm64-dts-qcom-ipq8074-add-APCS-node.patch |    37 -
 | |
|  ...pq8074-add-size-address-cells-to-DTS.patch |    54 -
 | |
|  ...ipq8074-add-interrupt-parent-to-DTSI.patch |    50 -
 | |
|  ...align-SDHCI-reg-names-with-DT-schema.patch |    28 -
 | |
|  ...q-pll-use-OF-match-data-for-Alpha-PL.patch |    70 -
 | |
|  ...q-pll-update-IPQ6018-Alpha-PLL-confi.patch |    40 -
 | |
|  ...apss-ipq-pll-add-support-for-IPQ8074.patch |    47 -
 | |
|  ...1-clk-qcom-clk-rcg2-add-rcg2-mux-ops.patch |    51 -
 | |
|  ...apss-ipq6018-fix-apcs_alias0_clk_src.patch |    63 -
 | |
|  ...64-dts-qcom-ipq8074-add-A53-PLL-node.patch |    32 -
 | |
|  ...pq8074-correct-APCS-register-space-s.patch |    32 -
 | |
|  ...tsens-Add-support-for-combined-inter.patch |   134 -
 | |
|  ...tsens-Allow-configuring-min-and-max-.patch |   101 -
 | |
|  ...al-drivers-tsens-Add-IPQ8074-support.patch |    74 -
 | |
|  ...4-dts-qcom-ipq8074-add-thermal-nodes.patch |   130 -
 | |
|  ...-dts-qcom-ipq8074-add-clocks-to-APCS.patch |    29 -
 | |
|  ...-qcom-ipq8074-convert-to-parent-data.patch |  3601 -----
 | |
|  ...k-qcom-ipq8074-add-missing-networkin.patch |    39 -
 | |
|  ...pq8074-add-missing-networking-resets.patch |    41 -
 | |
|  ...074-populate-fw_name-for-all-parents.patch |   152 -
 | |
|  ...pq8074-pass-XO-and-sleep-clocks-to-G.patch |    36 -
 | |
|  ...eplace-deprecated-perst-gpio-with-pe.patch |    52 -
 | |
|  ...r-to-look-up-an-SPMI-device-from-a-d.patch |    57 -
 | |
|  ...-pmic-Sort-compatibles-in-the-driver.patch |    60 -
 | |
|  ...ic-Add-missing-PMICs-supported-by-so.patch |    65 -
 | |
|  ...ic-expose-the-PMIC-revid-information.patch |   417 -
 | |
|  ...-pmic-read-fab-id-on-supported-PMICs.patch |    52 -
 | |
|  ...om-spmi-pmic-Add-support-for-PMP8074.patch |    27 -
 | |
|  ...or-qcom_spmi-add-support-for-HT_P150.patch |    58 -
 | |
|  ...or-qcom_spmi-add-support-for-HT_P600.patch |    59 -
 | |
|  ...pmi-add-support-for-PMP8074-regulato.patch |    68 -
 | |
|  ...om-pmic-gpio-add-support-for-PMP8074.patch |    25 -
 | |
|  ...i-adc5-add-ADC5_VREF_VADC-to-rev2-AD.patch |    26 -
 | |
|  ...v6.2-arm64-dts-qcom-add-PMP8074-DTSI.patch |   149 -
 | |
|  ...s-qcom-ipq8074-hk01-add-VQMMC-supply.patch |    37 -
 | |
|  ...ts-qcom-hk01-use-GPIO-flags-for-tlmm.patch |    42 -
 | |
|  ...m64-dts-qcom-ipq8074-Fix-up-comments.patch |    82 -
 | |
|  ...pq8074-align-TLMM-pin-configuration-.patch |    60 -
 | |
|  ...qcom-socinfo-Add-IPQ8074-family-ID-s.patch |    50 -
 | |
|  ...ie-make-pipe-clock-rate-configurable.patch |    47 -
 | |
|  ...e-add-IPQ8074-PCIe-Gen3-QMP-PHY-supp.patch |   200 -
 | |
|  ...3_RELATED-DBI-definitions-to-common-.patch |    46 -
 | |
|  ...slot-capabilities-using-PCI_EXP_SLTC.patch |    51 -
 | |
|  ...-ops-with-struct-pcie_cfg-in-pcie-ma.patch |   122 -
 | |
|  ...77-v6.0-PCI-qcom-Add-IPQ60xx-support.patch |   220 -
 | |
|  ...che-CFG-register-updates-for-parked-.patch |   288 -
 | |
|  ...qcom-document-qcom-msm-id-and-qcom-b.patch |   207 -
 | |
|  ...2-introduce-support-for-multiple-con.patch |   203 -
 | |
|  ...8074-rework-nss_port5-6-clock-to-mul.patch |   129 -
 | |
|  ...ts-ipq8074-add-reserved-memory-nodes.patch |    70 -
 | |
|  ...pq8074-set-Gen2-PCIe-pcie-max-link-s.patch |    24 -
 | |
|  ...om-Add-support-for-IPQ8074-Gen3-port.patch |    23 -
 | |
|  ...pq8074-pass-QMP-PCI-PHY-PIPE-clocks-.patch |    30 -
 | |
|  ...qcom-ipq8074-use-msi-parent-for-PCIe.patch |    43 -
 | |
|  ...remoteproc-qcom-Add-PRNG-proxy-clock.patch |   155 -
 | |
|  ...moteproc-qcom-Add-secure-PIL-support.patch |   143 -
 | |
|  ...Add-support-for-split-q6-m3-wlan-fir.patch |   103 -
 | |
|  ...oc-qcom-Add-ssr-subdevice-identifier.patch |    24 -
 | |
|  ...Update-regmap-offsets-for-halt-regis.patch |    79 -
 | |
|  ...ngs-clock-qcom-Add-reset-for-WCSSAON.patch |    26 -
 | |
|  .../0118-clk-qcom-Add-WCSSAON-reset.patch     |    25 -
 | |
|  ...c-wcss-disable-auto-boot-for-IPQ8074.patch |    48 -
 | |
|  ...com-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch |   120 -
 | |
|  ...0121-arm64-dts-ipq8074-Add-WLAN-node.patch |   135 -
 | |
|  ...0122-arm64-dts-ipq8074-add-CPU-clock.patch |    59 -
 | |
|  ...q8074-add-cooling-cells-to-CPU-nodes.patch |    48 -
 | |
|  ...-move-SMEM-item-struct-and-defines-t.patch |   168 -
 | |
|  ...nvmem-reuse-socinfo-SMEM-item-struct.patch |    50 -
 | |
|  ...com-nvmem-use-SoC-ID-s-from-bindings.patch |    46 -
 | |
|  ...em-make-qcom_cpufreq_get_msm_id-retu.patch |   106 -
 | |
|  ...q-qcom-nvmem-add-support-for-IPQ8074.patch |   100 -
 | |
|  ...64-dts-qcom-ipq8074-add-QFPROM-fuses.patch |   128 -
 | |
|  ...4-dts-qcom-ipq8074-add-CPU-OPP-table.patch |   102 -
 | |
|  ...q8074-populate-fw_name-for-usb3phy-s.patch |    38 -
 | |
|  .../0900-power-Add-Qualcomm-APM.patch         |  1047 --
 | |
|  ...egulator-add-Qualcomm-CPR-regulators.patch | 12147 ----------------
 | |
|  ...rm64-dts-ipq8074-add-label-to-clocks.patch |    24 -
 | |
|  133 files changed, 29893 deletions(-)
 | |
|  delete mode 100644 target/linux/ipq807x/Makefile
 | |
|  delete mode 100644 target/linux/ipq807x/base-files/etc/board.d/01_leds
 | |
|  delete mode 100644 target/linux/ipq807x/base-files/etc/board.d/02_network
 | |
|  delete mode 100644 target/linux/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
 | |
|  delete mode 100755 target/linux/ipq807x/base-files/etc/init.d/bootcount
 | |
|  delete mode 100644 target/linux/ipq807x/base-files/lib/upgrade/buffalo.sh
 | |
|  delete mode 100644 target/linux/ipq807x/base-files/lib/upgrade/mmc.sh
 | |
|  delete mode 100644 target/linux/ipq807x/base-files/lib/upgrade/platform.sh
 | |
|  delete mode 100644 target/linux/ipq807x/config-5.15
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dts
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax6.dts
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-512m.dtsi
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-ac-cpu.dtsi
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-cpr-regulator.dtsi
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-hk-cpu.dtsi
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts
 | |
|  delete mode 100644 target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts
 | |
|  delete mode 100644 target/linux/ipq807x/generic/target.mk
 | |
|  delete mode 100644 target/linux/ipq807x/image/Makefile
 | |
|  delete mode 100644 target/linux/ipq807x/image/generic.mk
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0001-v5.16-arm64-dts-qcom-ipq8074-add-SPMI-bus.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0002-v5.16-arm64-dts-qcom-Update-BAM-DMA-node-name-per-DT-schem.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0003-v5.16-arm64-dts-qcom-ipq8074-Add-QUP5-I2C-node.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0004-v5.16-arm64-dts-qcom-msm8996-Move-clock-cells-to-QMP-PHY-c.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0007-v5.17-arm64-dts-qcom-ipq8074-add-MDIO-bus.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0008-v5.18-arm64-dts-qcom-ipq8074-add-SMEM-support.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0009-v5.18-arm64-dts-qcom-ipq8074-add-the-reserved-memory-node.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0010-v5.18-arm64-dts-qcom-ipq8074-enable-the-GICv2m-support.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0011-v5.18-arm64-dts-qcom-ipq8074-drop-the-clock-frequency-prop.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0012-v5.19-arm64-dts-qcom-align-dmas-in-I2C-SPI-UART-with-DT-sc.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0013-v5.19-arm64-dts-qcom-align-clocks-in-I2C-SPI-with-DT-schem.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0014-v5.19-arm64-dts-qcom-correct-DWC3-node-names-and-unit-addr.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0015-v5.19-arm64-dts-qcom-ipq8074-add-dedicated-qcom-ipq8074-dw.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0016-v5.19-arm64-dts-qcom-align-DWC3-USB-clocks-with-DT-schema.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0017-v6.0-arm64-dts-qcom-adjust-whitespace-around.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0018-v6.0-arm64-dts-qcom-Fix-sdhci-node-names-use-mmc.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0019-v6.0-arm64-dts-qcom-Fix-ordering-of-clocks-clock-names-fo.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0020-v6.0-dt-bindings-clock-qcom-ipq8074-add-PPE-crypto-clock.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0021-v6.0-clk-qcom-ipq8074-add-PPE-crypto-clock.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0022-v6.0-dt-bindings-clock-qcom-ipq8074-add-USB-GDSCs.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0023-v6.0-clk-qcom-ipq8074-add-USB-GDSCs.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0024-v6.0-arm64-dts-qcom-ipq8074-add-USB-power-domains.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0025-v6.0-arm64-dts-qcom-ipq8074-move-ARMv8-timer-out-of-SoC-n.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0026-v6.0-arm64-dts-qcom-ipq8074-add-reset-to-SDHCI.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0027-v6.0-arm64-dts-qcom-ipq8074-drop-USB-PHY-clock-index.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0028-v5.16-mailbox-qcom-apcs-ipc-Consolidate-msm8994-type-apcs_.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0029-v6.1-mailbox-qcom-apcs-ipc-add-IPQ8074-APSS-clock-support.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0030-v6.0-arm64-dts-qcom-ipq8074-add-APCS-node.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0031-v6.0-arm64-dts-qcom-ipq8074-add-size-address-cells-to-DTS.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0032-v6.0-arm64-dts-qcom-ipq8074-add-interrupt-parent-to-DTSI.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0033-v6.1-arm64-dts-qcom-align-SDHCI-reg-names-with-DT-schema.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0035-v6.1-clk-qcom-apss-ipq-pll-use-OF-match-data-for-Alpha-PL.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0036-v6.1-clk-qcom-apss-ipq-pll-update-IPQ6018-Alpha-PLL-confi.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0037-v6.1-clk-qcom-apss-ipq-pll-add-support-for-IPQ8074.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0038-v6.1-clk-qcom-clk-rcg2-add-rcg2-mux-ops.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0039-v6.1-clk-qcom-apss-ipq6018-fix-apcs_alias0_clk_src.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0040-v6.2-arm64-dts-qcom-ipq8074-add-A53-PLL-node.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0041-v6.1-arm64-dts-qcom-ipq8074-correct-APCS-register-space-s.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0042-v6.2-thermal-drivers-tsens-Add-support-for-combined-inter.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0043-v6.2-thermal-drivers-tsens-Allow-configuring-min-and-max-.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0044-v6.2-thermal-drivers-tsens-Add-IPQ8074-support.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0045-v6.2-arm64-dts-qcom-ipq8074-add-thermal-nodes.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0046-v6.2-arm64-dts-qcom-ipq8074-add-clocks-to-APCS.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0047-v6.2-clk-qcom-ipq8074-convert-to-parent-data.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0050-v6.2-dt-bindings-clock-qcom-ipq8074-add-missing-networkin.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0051-v6.2-clk-qcom-ipq8074-add-missing-networking-resets.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0052-v6.2-clk-qcom-ipq8074-populate-fw_name-for-all-parents.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0053-v6.2-arm64-dts-qcom-ipq8074-pass-XO-and-sleep-clocks-to-G.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0054-v6.1-arm64-dts-qcom-replace-deprecated-perst-gpio-with-pe.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0055-v6.0-spmi-add-a-helper-to-look-up-an-SPMI-device-from-a-d.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0056-v5.16-mfd-qcom-spmi-pmic-Sort-compatibles-in-the-driver.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0057-v5.16-mfd-qcom-spmi-pmic-Add-missing-PMICs-supported-by-so.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0058-v6.0-mfd-qcom-spmi-pmic-expose-the-PMIC-revid-information.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0059-v6.0-mfd-qcom-spmi-pmic-read-fab-id-on-supported-PMICs.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0060-v6.1-mfd-qcom-spmi-pmic-Add-support-for-PMP8074.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0061-v6.0-regulator-qcom_spmi-add-support-for-HT_P150.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0062-v6.0-regulator-qcom_spmi-add-support-for-HT_P600.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0063-v6.0-regulator-qcom_spmi-add-support-for-PMP8074-regulato.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0064-v6.0-pinctrl-qcom-pmic-gpio-add-support-for-PMP8074.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0065-v6.1-iio-adc-qcom-spmi-adc5-add-ADC5_VREF_VADC-to-rev2-AD.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0066-v6.2-arm64-dts-qcom-add-PMP8074-DTSI.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0067-v6.2-arm64-dts-qcom-ipq8074-hk01-add-VQMMC-supply.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0068-v6.2-arm64-dts-qcom-hk01-use-GPIO-flags-for-tlmm.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0069-v6.2-arm64-dts-qcom-ipq8074-Fix-up-comments.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0070-v6.2-arm64-dts-qcom-ipq8074-align-TLMM-pin-configuration-.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0071-v5.16-soc-qcom-socinfo-Add-IPQ8074-family-ID-s.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0072-v6.0-phy-qcom-qmp-pcie-make-pipe-clock-rate-configurable.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0073-v6.0-phy-qcom-qmp-pcie-add-IPQ8074-PCIe-Gen3-QMP-PHY-supp.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0074-v6.0-PCI-dwc-Move-GEN3_RELATED-DBI-definitions-to-common-.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0075-v6.0-PCI-qcom-Define-slot-capabilities-using-PCI_EXP_SLTC.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0076-v5.16-PCI-qcom-Replace-ops-with-struct-pcie_cfg-in-pcie-ma.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0077-v6.0-PCI-qcom-Add-IPQ60xx-support.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0078-v5.19-clk-qcom-rcg2-Cache-CFG-register-updates-for-parked-.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0079-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0100-clk-qcom-clk-rcg2-introduce-support-for-multiple-con.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0101-clk-qcom-gcc-ipq8074-rework-nss_port5-6-clock-to-mul.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0106-arm64-dts-qcom-ipq8074-set-Gen2-PCIe-pcie-max-link-s.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0107-PCI-qcom-Add-support-for-IPQ8074-Gen3-port.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0110-arm64-dts-qcom-ipq8074-pass-QMP-PCI-PHY-PIPE-clocks-.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0112-remoteproc-qcom-Add-PRNG-proxy-clock.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0113-remoteproc-qcom-Add-secure-PIL-support.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0114-remoteproc-qcom-Add-support-for-split-q6-m3-wlan-fir.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0115-remoteproc-qcom-Add-ssr-subdevice-identifier.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0116-remoteproc-qcom-Update-regmap-offsets-for-halt-regis.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0117-dt-bindings-clock-qcom-Add-reset-for-WCSSAON.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0118-clk-qcom-Add-WCSSAON-reset.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0119-remoteproc-wcss-disable-auto-boot-for-IPQ8074.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0121-arm64-dts-ipq8074-Add-WLAN-node.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0122-arm64-dts-ipq8074-add-CPU-clock.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0123-arm64-dts-ipq8074-add-cooling-cells-to-CPU-nodes.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0124-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0125-cpufreq-qcom-nvmem-reuse-socinfo-SMEM-item-struct.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0126-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0127-cpufreq-qcom-nvmem-make-qcom_cpufreq_get_msm_id-retu.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0128-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0129-arm64-dts-qcom-ipq8074-add-QFPROM-fuses.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0130-arm64-dts-qcom-ipq8074-add-CPU-OPP-table.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0131-clk-qcom-ipq8074-populate-fw_name-for-usb3phy-s.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0900-power-Add-Qualcomm-APM.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0901-regulator-add-Qualcomm-CPR-regulators.patch
 | |
|  delete mode 100644 target/linux/ipq807x/patches-5.15/0902-arm64-dts-ipq8074-add-label-to-clocks.patch
 | |
| 
 | |
| diff --git a/target/linux/ipq807x/Makefile b/target/linux/ipq807x/Makefile
 | |
| deleted file mode 100644
 | |
| index f423acd76c..0000000000
 | |
| --- a/target/linux/ipq807x/Makefile
 | |
| +++ /dev/null
 | |
| @@ -1,22 +0,0 @@
 | |
| -include $(TOPDIR)/rules.mk
 | |
| -
 | |
| -ARCH:=aarch64
 | |
| -BOARD:=ipq807x
 | |
| -BOARDNAME:=Qualcomm Atheros IPQ807x
 | |
| -FEATURES:=squashfs ramdisk fpu nand rtc emmc
 | |
| -KERNELNAME:=Image dtbs
 | |
| -CPU_TYPE:=cortex-a53
 | |
| -SUBTARGETS:=generic
 | |
| -
 | |
| -KERNEL_PATCHVER:=5.15
 | |
| -
 | |
| -include $(INCLUDE_DIR)/target.mk
 | |
| -DEFAULT_PACKAGES += \
 | |
| -	kmod-usb3 kmod-usb-dwc3 kmod-usb-dwc3-qcom \
 | |
| -	kmod-leds-gpio kmod-gpio-button-hotplug \
 | |
| -	kmod-phy-aquantia kmod-qca-nss-dp \
 | |
| -	ath11k-firmware-ipq8074 kmod-ath11k-ahb \
 | |
| -	wpad-basic-mbedtls uboot-envtools \
 | |
| -	e2fsprogs kmod-fs-ext4 losetup
 | |
| -
 | |
| -$(eval $(call BuildTarget))
 | |
| diff --git a/target/linux/ipq807x/base-files/etc/board.d/01_leds b/target/linux/ipq807x/base-files/etc/board.d/01_leds
 | |
| deleted file mode 100644
 | |
| index a89b4c1564..0000000000
 | |
| --- a/target/linux/ipq807x/base-files/etc/board.d/01_leds
 | |
| +++ /dev/null
 | |
| @@ -1,33 +0,0 @@
 | |
| -
 | |
| -. /lib/functions/uci-defaults.sh
 | |
| -
 | |
| -board_config_update
 | |
| -
 | |
| -board=$(board_name)
 | |
| -
 | |
| -case "$board" in
 | |
| -edgecore,eap102)
 | |
| -	ucidef_set_led_netdev "wan" "WAN" "green:wanpoe" "wan"
 | |
| -	;;
 | |
| -netgear,wax218)
 | |
| -	ucidef_set_led_netdev "lan" "LAN" "blue:lan" "lan"
 | |
| -	ucidef_set_led_wlan "wlan5g" "WIFI 5GHz" "blue:wlan5g" "phy0radio"
 | |
| -	ucidef_set_led_wlan "wlan2g" "WIFI 2.4GHz" "blue:wlan2g" "phy1radio"
 | |
| -	;;
 | |
| -redmi,ax6|\
 | |
| -xiaomi,ax3600)
 | |
| -	ucidef_set_led_netdev "wan" "WAN" "blue:network" "wan"
 | |
| -	;;
 | |
| -qnap,301w)
 | |
| -	ucidef_set_led_netdev "lan1" "LAN1" "green:lan1" "lan1"
 | |
| -	ucidef_set_led_netdev "lan2" "LAN2" "green:lan2" "lan2"
 | |
| -	ucidef_set_led_netdev "lan3" "LAN3" "green:lan3" "lan3"
 | |
| -	ucidef_set_led_netdev "lan4" "LAN4" "green:lan4" "lan4"
 | |
| -	ucidef_set_led_netdev "10G_1" "10G_1" "green:10g_1" "10g-1"
 | |
| -	ucidef_set_led_netdev "10G_2" "10G_2" "green:10g_2" "10g-2"
 | |
| -	;;
 | |
| -esac
 | |
| -
 | |
| -board_config_flush
 | |
| -
 | |
| -exit 0
 | |
| diff --git a/target/linux/ipq807x/base-files/etc/board.d/02_network b/target/linux/ipq807x/base-files/etc/board.d/02_network
 | |
| deleted file mode 100644
 | |
| index 21364337fb..0000000000
 | |
| --- a/target/linux/ipq807x/base-files/etc/board.d/02_network
 | |
| +++ /dev/null
 | |
| @@ -1,52 +0,0 @@
 | |
| -#
 | |
| -# Copyright (c) 2015 The Linux Foundation. All rights reserved.
 | |
| -# Copyright (c) 2011-2015 OpenWrt.org
 | |
| -#
 | |
| -
 | |
| -. /lib/functions/uci-defaults.sh
 | |
| -. /lib/functions/system.sh
 | |
| -
 | |
| -ipq807x_setup_interfaces()
 | |
| -{
 | |
| -	local board="$1"
 | |
| -
 | |
| -	case "$board" in
 | |
| -	buffalo,wxr-5950ax12|\
 | |
| -	dynalink,dl-wrx36|\
 | |
| -	xiaomi,ax9000)
 | |
| -		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" "wan"
 | |
| -		;;
 | |
| -	edgecore,eap102)
 | |
| -		ucidef_set_interfaces_lan_wan "lan" "wan"
 | |
| -		;;
 | |
| -	edimax,cax1800)
 | |
| -		ucidef_set_interfaces_lan_wan "lan"
 | |
| -		;;
 | |
| -	netgear,wax218)
 | |
| -		ucidef_set_interface_lan "lan" "dhcp"
 | |
| -		;;
 | |
| -	prpl,haze)
 | |
| -		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan"
 | |
| -		;;
 | |
| -	qnap,301w)
 | |
| -		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 10g-2" "10g-1"
 | |
| -		;;
 | |
| -	redmi,ax6|\
 | |
| -	xiaomi,ax3600)
 | |
| -		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3" "wan"
 | |
| -		;;
 | |
| -	zyxel,nbg7815)
 | |
| -		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 10g" "wan"
 | |
| -		;;
 | |
| -	*)
 | |
| -		echo "Unsupported hardware. Network interfaces not initialized"
 | |
| -		;;
 | |
| -	esac
 | |
| -}
 | |
| -
 | |
| -board_config_update
 | |
| -board=$(board_name)
 | |
| -ipq807x_setup_interfaces $board
 | |
| -board_config_flush
 | |
| -
 | |
| -exit 0
 | |
| diff --git a/target/linux/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata b/target/linux/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
 | |
| deleted file mode 100644
 | |
| index 13cb07477e..0000000000
 | |
| --- a/target/linux/ipq807x/base-files/etc/hotplug.d/firmware/11-ath11k-caldata
 | |
| +++ /dev/null
 | |
| @@ -1,43 +0,0 @@
 | |
| -#!/bin/sh
 | |
| -
 | |
| -[ -e /lib/firmware/$FIRMWARE ] && exit 0
 | |
| -
 | |
| -. /lib/functions/caldata.sh
 | |
| -
 | |
| -board=$(board_name)
 | |
| -
 | |
| -case "$FIRMWARE" in
 | |
| -"ath11k/IPQ8074/hw2.0/cal-ahb-c000000.wifi.bin")
 | |
| -	case "$board" in
 | |
| -	buffalo,wxr-5950ax12|\
 | |
| -	edgecore,eap102|\
 | |
| -	edimax,cax1800|\
 | |
| -	dynalink,dl-wrx36|\
 | |
| -	netgear,wax218|\
 | |
| -	qnap,301w|\
 | |
| -	redmi,ax6|\
 | |
| -	xiaomi,ax3600|\
 | |
| -	xiaomi,ax9000|\
 | |
| -	zyxel,nbg7815)
 | |
| -		caldata_extract "0:art" 0x1000 0x20000
 | |
| -		;;
 | |
| -	prpl,haze)
 | |
| -                caldata_extract_mmc "0:ART" 0x1000 0x20000
 | |
| -		;;
 | |
| -	esac
 | |
| -	;;
 | |
| -"ath11k/QCN9074/hw1.0/cal-pci-0000:01:00.0.bin"|\
 | |
| -"ath11k/QCN9074/hw1.0/cal-pci-0001:01:00.0.bin")
 | |
| -	case "$board" in
 | |
| -	prpl,haze)
 | |
| -                caldata_extract_mmc "0:ART" 0x26800 0x20000
 | |
| -		;;
 | |
| -	xiaomi,ax9000)
 | |
| -		caldata_extract "0:art" 0x26800 0x20000
 | |
| -		;;
 | |
| -	esac
 | |
| -	;;
 | |
| -*)
 | |
| -	exit 1
 | |
| -	;;
 | |
| -esac
 | |
| diff --git a/target/linux/ipq807x/base-files/etc/init.d/bootcount b/target/linux/ipq807x/base-files/etc/init.d/bootcount
 | |
| deleted file mode 100755
 | |
| index 6917446a9b..0000000000
 | |
| --- a/target/linux/ipq807x/base-files/etc/init.d/bootcount
 | |
| +++ /dev/null
 | |
| @@ -1,13 +0,0 @@
 | |
| -#!/bin/sh /etc/rc.common
 | |
| -
 | |
| -START=99
 | |
| -
 | |
| -boot() {
 | |
| -	case $(board_name) in
 | |
| -	edgecore,eap102)
 | |
| -		fw_setenv upgrade_available 0
 | |
| -		# Unset changed flag after sysupgrade complete
 | |
| -		fw_setenv changed
 | |
| -	;;
 | |
| -	esac
 | |
| -}
 | |
| diff --git a/target/linux/ipq807x/base-files/lib/upgrade/buffalo.sh b/target/linux/ipq807x/base-files/lib/upgrade/buffalo.sh
 | |
| deleted file mode 100644
 | |
| index d0ed258890..0000000000
 | |
| --- a/target/linux/ipq807x/base-files/lib/upgrade/buffalo.sh
 | |
| +++ /dev/null
 | |
| @@ -1,55 +0,0 @@
 | |
| -. /lib/functions.sh
 | |
| -
 | |
| -# Prepare UBI devices for OpenWrt installation
 | |
| -# - rootfs (mtd22)
 | |
| -#   - remove "ubi_rootfs" volume (rootfs on stock)
 | |
| -#   - remove "fw_hash" volume (firmware hash)
 | |
| -# - user_property (mtd24)
 | |
| -#   - remove "user_property_ubi" volume (user configuration)
 | |
| -#   - remove "extra_property" volume (gzipped syslog)
 | |
| -buffalo_upgrade_prepare() {
 | |
| -	local ubi_rootdev ubi_propdev
 | |
| -
 | |
| -	if ! ubi_rootdev="$(nand_attach_ubi rootfs)" || \
 | |
| -	   ! ubi_propdev="$(nand_attach_ubi user_property)"; then
 | |
| -		echo "failed to attach UBI volume \"rootfs\" or \"user_property\", rebooting..."
 | |
| -		reboot -f
 | |
| -	fi
 | |
| -
 | |
| -	ubirmvol /dev/$ubi_rootdev -N ubi_rootfs &> /dev/null || true
 | |
| -	ubirmvol /dev/$ubi_rootdev -N fw_hash &> /dev/null || true
 | |
| -
 | |
| -	ubirmvol /dev/$ubi_propdev -N user_property_ubi &> /dev/null || true
 | |
| -	ubirmvol /dev/$ubi_propdev -N extra_property &> /dev/null || true
 | |
| -}
 | |
| -
 | |
| -# Re-create small dummy ubi_rootfs volume and update
 | |
| -# fw_hash volume to pass the checking by U-Boot
 | |
| -# - rootfs (mtd22)
 | |
| -#   - re-create "ubi_rootfs" volume
 | |
| -#   - re-create and update "fw_hash" volume
 | |
| -# - rootfs_recover (mtd23)
 | |
| -#   - update "fw_hash" volume
 | |
| -buffalo_upgrade_optvol() {
 | |
| -	local ubi_rootdev ubi_rcvrdev
 | |
| -	local hashvol_root hashvol_rcvr
 | |
| -
 | |
| -	if ! ubi_rootdev="$(nand_attach_ubi rootfs)" || \
 | |
| -	   ! ubi_rcvrdev="$(nand_attach_ubi rootfs_recover)"; then
 | |
| -		echo "failed to attach UBI volume \"rootfs\" or \"rootfs_recover\", rebooting..."
 | |
| -		reboot -f
 | |
| -	fi
 | |
| -
 | |
| -	ubimkvol /dev/$ubi_rootdev -N ubi_rootfs -S 1
 | |
| -	ubimkvol /dev/$ubi_rootdev -N fw_hash -S 1 -t static
 | |
| -
 | |
| -	if ! hashvol_root="$(nand_find_volume $ubi_rootdev fw_hash)" || \
 | |
| -	   ! hashvol_rcvr="$(nand_find_volume $ubi_rcvrdev fw_hash)"; then
 | |
| -		echo "\"fw_hash\" volume in \"rootfs\" or \"rootfs_recover\" not found, rebooting..."
 | |
| -		reboot -f
 | |
| -	fi
 | |
| -
 | |
| -	echo -n "00000000000000000000000000000000" > /tmp/dummyhash.txt
 | |
| -	ubiupdatevol /dev/$hashvol_root /tmp/dummyhash.txt
 | |
| -	ubiupdatevol /dev/$hashvol_rcvr /tmp/dummyhash.txt
 | |
| -}
 | |
| diff --git a/target/linux/ipq807x/base-files/lib/upgrade/mmc.sh b/target/linux/ipq807x/base-files/lib/upgrade/mmc.sh
 | |
| deleted file mode 100644
 | |
| index dac9ddd568..0000000000
 | |
| --- a/target/linux/ipq807x/base-files/lib/upgrade/mmc.sh
 | |
| +++ /dev/null
 | |
| @@ -1,83 +0,0 @@
 | |
| -#
 | |
| -# Copyright (C) 2016 lede-project.org
 | |
| -#
 | |
| -
 | |
| -# this can be used as a generic mmc upgrade script
 | |
| -# just add a device entry in platform.sh, 
 | |
| -# define "kernelname" and "rootfsname" and call mmc_do_upgrade
 | |
| -# after the kernel and rootfs flash a loopdev (as overlay) is 
 | |
| -# setup on top of the rootfs partition
 | |
| -# for the proper function a padded rootfs image is needed, basically 
 | |
| -# append "pad-to 64k" to the image definition
 | |
| -# this is based on the ipq806x zyxel.sh mmc upgrade
 | |
| -
 | |
| -. /lib/functions.sh
 | |
| -
 | |
| -mmc_do_upgrade() {
 | |
| -	local tar_file="$1"
 | |
| -	local rootfs=
 | |
| -	local kernel=
 | |
| -
 | |
| -			[ -z "$kernel" ] && kernel=$(find_mmc_part ${kernelname})
 | |
| -			[ -z "$rootfs" ] && rootfs=$(find_mmc_part ${rootfsname})
 | |
| -
 | |
| -			[ -z "$kernel" ] && echo "Upgrade failed: kernel partition not found! Rebooting..." && reboot -f
 | |
| -			[ -z "$rootfs" ] && echo "Upgrade failed: rootfs partition not found! Rebooting..." && reboot -f
 | |
| -
 | |
| -	mmc_do_flash $tar_file $kernel $rootfs
 | |
| -
 | |
| -	return 0
 | |
| -}
 | |
| -
 | |
| -mmc_do_flash() {
 | |
| -	local tar_file=$1
 | |
| -	local kernel=$2
 | |
| -	local rootfs=$3
 | |
| -	
 | |
| -	# keep sure its unbound
 | |
| -	losetup --detach-all || {
 | |
| -		echo Failed to detach all loop devices. Skip this try.
 | |
| -		reboot -f
 | |
| -	}
 | |
| -
 | |
| -	# use the first found directory in the tar archive
 | |
| -	local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
 | |
| -	board_dir=${board_dir%/}
 | |
| -
 | |
| -	echo "flashing kernel to $kernel"
 | |
| -	tar xf $tar_file ${board_dir}/kernel -O >$kernel
 | |
| -
 | |
| -	echo "flashing rootfs to ${rootfs}"
 | |
| -	tar xf $tar_file ${board_dir}/root -O >"${rootfs}"
 | |
| -
 | |
| -	# a padded rootfs is needed for overlay fs creation
 | |
| -	local offset=$(tar xf $tar_file ${board_dir}/root -O | wc -c)
 | |
| -	[ $offset -lt 65536 ] && {
 | |
| -		echo Wrong size for rootfs: $offset
 | |
| -		sleep 10
 | |
| -		reboot -f
 | |
| -	}
 | |
| -
 | |
| -	# Mount loop for rootfs_data
 | |
| -	local loopdev="$(losetup -f)"
 | |
| -	losetup -o $offset $loopdev $rootfs || {
 | |
| -		echo "Failed to mount looped rootfs_data."
 | |
| -		sleep 10
 | |
| -		reboot -f
 | |
| -	}
 | |
| -
 | |
| -	echo "Format new rootfs_data at position ${offset}."
 | |
| -	mkfs.ext4 -F -L rootfs_data $loopdev
 | |
| -	mkdir /tmp/new_root
 | |
| -	mount -t ext4 $loopdev /tmp/new_root && {
 | |
| -		echo "Saving config to rootfs_data at position ${offset}."
 | |
| -		cp -v "$UPGRADE_BACKUP" "/tmp/new_root/$BACKUP_FILE"
 | |
| -		umount /tmp/new_root
 | |
| -	}
 | |
| -
 | |
| -	# Cleanup
 | |
| -	losetup -d $loopdev >/dev/null 2>&1
 | |
| -	sync
 | |
| -	umount -a
 | |
| -	reboot -f
 | |
| -}
 | |
| diff --git a/target/linux/ipq807x/base-files/lib/upgrade/platform.sh b/target/linux/ipq807x/base-files/lib/upgrade/platform.sh
 | |
| deleted file mode 100644
 | |
| index 346cc390f3..0000000000
 | |
| --- a/target/linux/ipq807x/base-files/lib/upgrade/platform.sh
 | |
| +++ /dev/null
 | |
| @@ -1,116 +0,0 @@
 | |
| -PART_NAME=firmware
 | |
| -REQUIRE_IMAGE_METADATA=1
 | |
| -
 | |
| -RAMFS_COPY_BIN='fw_printenv fw_setenv head'
 | |
| -RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
 | |
| -
 | |
| -xiaomi_initramfs_prepare() {
 | |
| -	# Wipe UBI if running initramfs
 | |
| -	[ "$(rootfs_type)" = "tmpfs" ] || return 0
 | |
| -
 | |
| -	local rootfs_mtdnum="$( find_mtd_index rootfs )"
 | |
| -	if [ ! "$rootfs_mtdnum" ]; then
 | |
| -		echo "unable to find mtd partition rootfs"
 | |
| -		return 1
 | |
| -	fi
 | |
| -
 | |
| -	local kern_mtdnum="$( find_mtd_index ubi_kernel )"
 | |
| -	if [ ! "$kern_mtdnum" ]; then
 | |
| -		echo "unable to find mtd partition ubi_kernel"
 | |
| -		return 1
 | |
| -	fi
 | |
| -
 | |
| -	ubidetach -m "$rootfs_mtdnum"
 | |
| -	ubiformat /dev/mtd$rootfs_mtdnum -y
 | |
| -
 | |
| -	ubidetach -m "$kern_mtdnum"
 | |
| -	ubiformat /dev/mtd$kern_mtdnum -y
 | |
| -}
 | |
| -
 | |
| -platform_check_image() {
 | |
| -	return 0;
 | |
| -}
 | |
| -
 | |
| -platform_pre_upgrade() {
 | |
| -	case "$(board_name)" in
 | |
| -	redmi,ax6|\
 | |
| -	xiaomi,ax3600|\
 | |
| -	xiaomi,ax9000)
 | |
| -		xiaomi_initramfs_prepare
 | |
| -		;;
 | |
| -	esac
 | |
| -}
 | |
| -
 | |
| -platform_do_upgrade() {
 | |
| -	case "$(board_name)" in
 | |
| -	buffalo,wxr-5950ax12)
 | |
| -		CI_KERN_UBIPART="rootfs"
 | |
| -		CI_ROOT_UBIPART="user_property"
 | |
| -		buffalo_upgrade_prepare
 | |
| -		nand_do_flash_file "$1" || nand_do_upgrade_failed
 | |
| -		nand_do_restore_config || nand_do_upgrade_failed
 | |
| -		buffalo_upgrade_optvol
 | |
| -		;;
 | |
| -	dynalink,dl-wrx36)
 | |
| -		nand_do_upgrade "$1"
 | |
| -		;;
 | |
| -	edgecore,eap102)
 | |
| -		active="$(fw_printenv -n active)"
 | |
| -		if [ "$active" -eq "1" ]; then
 | |
| -			CI_UBIPART="rootfs2"
 | |
| -		else
 | |
| -			CI_UBIPART="rootfs1"
 | |
| -		fi
 | |
| -		# force altbootcmd which handles partition change in u-boot
 | |
| -		fw_setenv bootcount 3
 | |
| -		fw_setenv upgrade_available 1
 | |
| -		nand_do_upgrade "$1"
 | |
| -		;;
 | |
| -	edimax,cax1800|\
 | |
| -	netgear,wax218)
 | |
| -		nand_do_upgrade "$1"
 | |
| -		;;
 | |
| -	prpl,haze|\
 | |
| -	qnap,301w)
 | |
| -		kernelname="0:HLOS"
 | |
| -		rootfsname="rootfs"
 | |
| -		mmc_do_upgrade "$1"
 | |
| -		;;
 | |
| -	zyxel,nbg7815)
 | |
| -		local config_mtdnum="$(find_mtd_index 0:bootconfig)"
 | |
| -		[ -z "$config_mtdnum" ] && reboot
 | |
| -		part_num="$(hexdump -e '1/1 "%01x|"' -n 1 -s 168 -C /dev/mtd$config_mtdnum | cut -f 1 -d "|" | head -n1)"
 | |
| -		if [ "$part_num" -eq "0" ]; then
 | |
| -			kernelname="0:HLOS"
 | |
| -			rootfsname="rootfs"
 | |
| -			mmc_do_upgrade "$1"
 | |
| -		else
 | |
| -			kernelname="0:HLOS_1"
 | |
| -			rootfsname="rootfs_1"
 | |
| -			mmc_do_upgrade "$1"
 | |
| -		fi
 | |
| -		;;
 | |
| -	redmi,ax6|\
 | |
| -	xiaomi,ax3600|\
 | |
| -	xiaomi,ax9000)
 | |
| -		# Make sure that UART is enabled
 | |
| -		fw_setenv boot_wait on
 | |
| -		fw_setenv uart_en 1
 | |
| -
 | |
| -		# Enforce single partition.
 | |
| -		fw_setenv flag_boot_rootfs 0
 | |
| -		fw_setenv flag_last_success 0
 | |
| -		fw_setenv flag_boot_success 1
 | |
| -		fw_setenv flag_try_sys1_failed 8
 | |
| -		fw_setenv flag_try_sys2_failed 8
 | |
| -
 | |
| -		# Kernel and rootfs are placed in 2 different UBI
 | |
| -		CI_KERN_UBIPART="ubi_kernel"
 | |
| -		CI_ROOT_UBIPART="rootfs"
 | |
| -		nand_do_upgrade "$1"
 | |
| -		;;
 | |
| -	*)
 | |
| -		default_do_upgrade "$1"
 | |
| -		;;
 | |
| -	esac
 | |
| -}
 | |
| diff --git a/target/linux/ipq807x/config-5.15 b/target/linux/ipq807x/config-5.15
 | |
| deleted file mode 100644
 | |
| index a3d0628be9..0000000000
 | |
| --- a/target/linux/ipq807x/config-5.15
 | |
| +++ /dev/null
 | |
| @@ -1,509 +0,0 @@
 | |
| -CONFIG_64BIT=y
 | |
| -# CONFIG_APQ_GCC_8084 is not set
 | |
| -# CONFIG_APQ_MMCC_8084 is not set
 | |
| -CONFIG_ARCH_DMA_ADDR_T_64BIT=y
 | |
| -CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 | |
| -CONFIG_ARCH_KEEP_MEMBLOCK=y
 | |
| -CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
 | |
| -CONFIG_ARCH_MMAP_RND_BITS=18
 | |
| -CONFIG_ARCH_MMAP_RND_BITS_MAX=24
 | |
| -CONFIG_ARCH_MMAP_RND_BITS_MIN=18
 | |
| -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11
 | |
| -CONFIG_ARCH_PROC_KCORE_TEXT=y
 | |
| -CONFIG_ARCH_QCOM=y
 | |
| -CONFIG_ARCH_SPARSEMEM_ENABLE=y
 | |
| -CONFIG_ARCH_STACKWALK=y
 | |
| -CONFIG_ARCH_SUSPEND_POSSIBLE=y
 | |
| -CONFIG_ARCH_WANTS_NO_INSTR=y
 | |
| -CONFIG_ARM64=y
 | |
| -CONFIG_ARM64_4K_PAGES=y
 | |
| -CONFIG_ARM64_CRYPTO=y
 | |
| -CONFIG_ARM64_ERRATUM_1165522=y
 | |
| -CONFIG_ARM64_ERRATUM_1286807=y
 | |
| -CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
 | |
| -CONFIG_ARM64_PAGE_SHIFT=12
 | |
| -CONFIG_ARM64_PA_BITS=48
 | |
| -CONFIG_ARM64_PA_BITS_48=y
 | |
| -CONFIG_ARM64_PTR_AUTH=y
 | |
| -CONFIG_ARM64_PTR_AUTH_KERNEL=y
 | |
| -CONFIG_ARM64_SVE=y
 | |
| -CONFIG_ARM64_TAGGED_ADDR_ABI=y
 | |
| -CONFIG_ARM64_VA_BITS=39
 | |
| -CONFIG_ARM64_VA_BITS_39=y
 | |
| -CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y
 | |
| -CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT=y
 | |
| -CONFIG_ARM_AMBA=y
 | |
| -CONFIG_ARM_ARCH_TIMER=y
 | |
| -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
 | |
| -CONFIG_ARM_CPUIDLE=y
 | |
| -CONFIG_ARM_GIC=y
 | |
| -CONFIG_ARM_GIC_V2M=y
 | |
| -CONFIG_ARM_GIC_V3=y
 | |
| -CONFIG_ARM_GIC_V3_ITS=y
 | |
| -CONFIG_ARM_GIC_V3_ITS_PCI=y
 | |
| -# CONFIG_ARM_MHU_V2 is not set
 | |
| -CONFIG_ARM_PSCI_CPUIDLE=y
 | |
| -CONFIG_ARM_PSCI_CPUIDLE_DOMAIN=y
 | |
| -CONFIG_ARM_PSCI_FW=y
 | |
| -# CONFIG_ARM_QCOM_CPUFREQ_HW is not set
 | |
| -CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
 | |
| -CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
 | |
| -CONFIG_BLK_DEV_LOOP=y
 | |
| -CONFIG_BLK_DEV_SD=y
 | |
| -CONFIG_BLK_MQ_PCI=y
 | |
| -CONFIG_BLK_MQ_VIRTIO=y
 | |
| -CONFIG_BLK_PM=y
 | |
| -CONFIG_CAVIUM_TX2_ERRATUM_219=y
 | |
| -CONFIG_CC_HAVE_SHADOW_CALL_STACK=y
 | |
| -CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG=y
 | |
| -CONFIG_CLONE_BACKWARDS=y
 | |
| -CONFIG_COMMON_CLK=y
 | |
| -CONFIG_COMMON_CLK_QCOM=y
 | |
| -# CONFIG_COMPAT_32BIT_TIME is not set
 | |
| -CONFIG_COREDUMP=y
 | |
| -CONFIG_CPUFREQ_DT=y
 | |
| -CONFIG_CPUFREQ_DT_PLATDEV=y
 | |
| -CONFIG_CPU_FREQ=y
 | |
| -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
 | |
| -CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
 | |
| -CONFIG_CPU_FREQ_GOV_ATTR_SET=y
 | |
| -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
 | |
| -# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
 | |
| -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 | |
| -# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
 | |
| -CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
 | |
| -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
 | |
| -CONFIG_CPU_FREQ_STAT=y
 | |
| -CONFIG_CPU_FREQ_THERMAL=y
 | |
| -CONFIG_CPU_IDLE=y
 | |
| -CONFIG_CPU_IDLE_GOV_MENU=y
 | |
| -CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
 | |
| -CONFIG_CPU_LITTLE_ENDIAN=y
 | |
| -CONFIG_CPU_PM=y
 | |
| -CONFIG_CPU_RMAP=y
 | |
| -CONFIG_CPU_THERMAL=y
 | |
| -CONFIG_CRC16=y
 | |
| -CONFIG_CRC8=y
 | |
| -CONFIG_CRYPTO_AUTHENC=y
 | |
| -CONFIG_CRYPTO_CBC=y
 | |
| -CONFIG_CRYPTO_DEFLATE=y
 | |
| -CONFIG_CRYPTO_DEV_QCE=y
 | |
| -CONFIG_CRYPTO_DEV_QCE_AEAD=y
 | |
| -# CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD is not set
 | |
| -CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL=y
 | |
| -# CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA is not set
 | |
| -# CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER is not set
 | |
| -CONFIG_CRYPTO_DEV_QCE_SHA=y
 | |
| -CONFIG_CRYPTO_DEV_QCE_SKCIPHER=y
 | |
| -CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN=512
 | |
| -CONFIG_CRYPTO_DEV_QCOM_RNG=y
 | |
| -CONFIG_CRYPTO_ECB=y
 | |
| -CONFIG_CRYPTO_HASH_INFO=y
 | |
| -CONFIG_CRYPTO_HW=y
 | |
| -CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
 | |
| -CONFIG_CRYPTO_LIB_DES=y
 | |
| -CONFIG_CRYPTO_LIB_SHA256=y
 | |
| -CONFIG_CRYPTO_LZO=y
 | |
| -CONFIG_CRYPTO_RNG=y
 | |
| -CONFIG_CRYPTO_RNG2=y
 | |
| -CONFIG_CRYPTO_SHA1=y
 | |
| -CONFIG_CRYPTO_SHA256=y
 | |
| -CONFIG_CRYPTO_XTS=y
 | |
| -CONFIG_CRYPTO_ZSTD=y
 | |
| -CONFIG_DCACHE_WORD_ACCESS=y
 | |
| -CONFIG_DEV_COREDUMP=y
 | |
| -CONFIG_DMADEVICES=y
 | |
| -CONFIG_DMA_DIRECT_REMAP=y
 | |
| -CONFIG_DMA_ENGINE=y
 | |
| -CONFIG_DMA_OF=y
 | |
| -CONFIG_DMA_REMAP=y
 | |
| -CONFIG_DMA_VIRTUAL_CHANNELS=y
 | |
| -CONFIG_DTC=y
 | |
| -CONFIG_DT_IDLE_STATES=y
 | |
| -CONFIG_EDAC_SUPPORT=y
 | |
| -CONFIG_FIXED_PHY=y
 | |
| -CONFIG_FIX_EARLYCON_MEM=y
 | |
| -CONFIG_FRAME_POINTER=y
 | |
| -CONFIG_FUJITSU_ERRATUM_010001=y
 | |
| -CONFIG_FWNODE_MDIO=y
 | |
| -CONFIG_FW_LOADER_PAGED_BUF=y
 | |
| -CONFIG_GENERIC_ALLOCATOR=y
 | |
| -CONFIG_GENERIC_ARCH_TOPOLOGY=y
 | |
| -CONFIG_GENERIC_BUG=y
 | |
| -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
 | |
| -CONFIG_GENERIC_CLOCKEVENTS=y
 | |
| -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
 | |
| -CONFIG_GENERIC_CPU_AUTOPROBE=y
 | |
| -CONFIG_GENERIC_CPU_VULNERABILITIES=y
 | |
| -CONFIG_GENERIC_CSUM=y
 | |
| -CONFIG_GENERIC_EARLY_IOREMAP=y
 | |
| -CONFIG_GENERIC_FIND_FIRST_BIT=y
 | |
| -CONFIG_GENERIC_GETTIMEOFDAY=y
 | |
| -CONFIG_GENERIC_IDLE_POLL_SETUP=y
 | |
| -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
 | |
| -CONFIG_GENERIC_IRQ_SHOW=y
 | |
| -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
 | |
| -CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
 | |
| -CONFIG_GENERIC_MSI_IRQ=y
 | |
| -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y
 | |
| -CONFIG_GENERIC_PCI_IOMAP=y
 | |
| -CONFIG_GENERIC_PHY=y
 | |
| -CONFIG_GENERIC_PINCONF=y
 | |
| -CONFIG_GENERIC_PINCTRL_GROUPS=y
 | |
| -CONFIG_GENERIC_PINMUX_FUNCTIONS=y
 | |
| -CONFIG_GENERIC_SCHED_CLOCK=y
 | |
| -CONFIG_GENERIC_SMP_IDLE_THREAD=y
 | |
| -CONFIG_GENERIC_STRNCPY_FROM_USER=y
 | |
| -CONFIG_GENERIC_STRNLEN_USER=y
 | |
| -CONFIG_GENERIC_TIME_VSYSCALL=y
 | |
| -CONFIG_GLOB=y
 | |
| -CONFIG_GPIOLIB_IRQCHIP=y
 | |
| -CONFIG_GPIO_CDEV=y
 | |
| -CONFIG_HANDLE_DOMAIN_IRQ=y
 | |
| -CONFIG_HARDIRQS_SW_RESEND=y
 | |
| -CONFIG_HAS_DMA=y
 | |
| -CONFIG_HAS_IOMEM=y
 | |
| -CONFIG_HAS_IOPORT_MAP=y
 | |
| -CONFIG_HWSPINLOCK=y
 | |
| -CONFIG_HWSPINLOCK_QCOM=y
 | |
| -CONFIG_I2C=y
 | |
| -CONFIG_I2C_BOARDINFO=y
 | |
| -CONFIG_I2C_CHARDEV=y
 | |
| -CONFIG_I2C_HELPER_AUTO=y
 | |
| -# CONFIG_I2C_QCOM_CCI is not set
 | |
| -CONFIG_I2C_QUP=y
 | |
| -CONFIG_IIO=y
 | |
| -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
 | |
| -CONFIG_INITRAMFS_SOURCE=""
 | |
| -CONFIG_IPQ_APSS_6018=y
 | |
| -CONFIG_IPQ_APSS_PLL=y
 | |
| -# CONFIG_IPQ_GCC_4019 is not set
 | |
| -# CONFIG_IPQ_GCC_6018 is not set
 | |
| -# CONFIG_IPQ_GCC_806X is not set
 | |
| -CONFIG_IPQ_GCC_8074=y
 | |
| -# CONFIG_IPQ_LCC_806X is not set
 | |
| -CONFIG_IRQCHIP=y
 | |
| -CONFIG_IRQ_DOMAIN=y
 | |
| -CONFIG_IRQ_DOMAIN_HIERARCHY=y
 | |
| -CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS=y
 | |
| -CONFIG_IRQ_FORCED_THREADING=y
 | |
| -CONFIG_IRQ_WORK=y
 | |
| -# CONFIG_KPSS_XCC is not set
 | |
| -CONFIG_LIBFDT=y
 | |
| -CONFIG_LOCK_DEBUGGING_SUPPORT=y
 | |
| -CONFIG_LOCK_SPIN_ON_OWNER=y
 | |
| -CONFIG_LZO_COMPRESS=y
 | |
| -CONFIG_LZO_DECOMPRESS=y
 | |
| -CONFIG_MAILBOX=y
 | |
| -# CONFIG_MAILBOX_TEST is not set
 | |
| -CONFIG_MDIO_BUS=y
 | |
| -CONFIG_MDIO_DEVICE=y
 | |
| -CONFIG_MDIO_DEVRES=y
 | |
| -CONFIG_MDIO_IPQ4019=y
 | |
| -# CONFIG_MDM_GCC_9615 is not set
 | |
| -# CONFIG_MDM_LCC_9615 is not set
 | |
| -CONFIG_MEMFD_CREATE=y
 | |
| -# CONFIG_MFD_HI6421_SPMI is not set
 | |
| -# CONFIG_MFD_QCOM_RPM is not set
 | |
| -CONFIG_MFD_SPMI_PMIC=y
 | |
| -CONFIG_MFD_SYSCON=y
 | |
| -CONFIG_MIGRATION=y
 | |
| -CONFIG_MMC=y
 | |
| -CONFIG_MMC_BLOCK=y
 | |
| -CONFIG_MMC_BLOCK_MINORS=32
 | |
| -CONFIG_MMC_CQHCI=y
 | |
| -CONFIG_MMC_SDHCI=y
 | |
| -CONFIG_MMC_SDHCI_IO_ACCESSORS=y
 | |
| -CONFIG_MMC_SDHCI_MSM=y
 | |
| -# CONFIG_MMC_SDHCI_PCI is not set
 | |
| -CONFIG_MMC_SDHCI_PLTFM=y
 | |
| -CONFIG_MODULES_USE_ELF_RELA=y
 | |
| -# CONFIG_MSM_GCC_8660 is not set
 | |
| -# CONFIG_MSM_GCC_8916 is not set
 | |
| -# CONFIG_MSM_GCC_8939 is not set
 | |
| -# CONFIG_MSM_GCC_8960 is not set
 | |
| -# CONFIG_MSM_GCC_8974 is not set
 | |
| -# CONFIG_MSM_GCC_8994 is not set
 | |
| -# CONFIG_MSM_GCC_8996 is not set
 | |
| -# CONFIG_MSM_GCC_8998 is not set
 | |
| -# CONFIG_MSM_GPUCC_8998 is not set
 | |
| -# CONFIG_MSM_LCC_8960 is not set
 | |
| -# CONFIG_MSM_MMCC_8960 is not set
 | |
| -# CONFIG_MSM_MMCC_8974 is not set
 | |
| -# CONFIG_MSM_MMCC_8996 is not set
 | |
| -# CONFIG_MSM_MMCC_8998 is not set
 | |
| -CONFIG_MTD_NAND_CORE=y
 | |
| -CONFIG_MTD_NAND_ECC=y
 | |
| -CONFIG_MTD_NAND_ECC_SW_HAMMING=y
 | |
| -CONFIG_MTD_NAND_QCOM=y
 | |
| -CONFIG_MTD_QCOMSMEM_PARTS=y
 | |
| -CONFIG_MTD_RAW_NAND=y
 | |
| -CONFIG_MTD_SPI_NOR=y
 | |
| -CONFIG_MTD_UBI=y
 | |
| -CONFIG_MTD_UBI_BEB_LIMIT=20
 | |
| -CONFIG_MTD_UBI_BLOCK=y
 | |
| -CONFIG_MTD_UBI_WL_THRESHOLD=4096
 | |
| -CONFIG_MUTEX_SPIN_ON_OWNER=y
 | |
| -CONFIG_NEED_DMA_MAP_STATE=y
 | |
| -CONFIG_NEED_SG_DMA_LENGTH=y
 | |
| -CONFIG_NET_FLOW_LIMIT=y
 | |
| -CONFIG_NET_SELFTESTS=y
 | |
| -CONFIG_NET_SWITCHDEV=y
 | |
| -CONFIG_NLS=y
 | |
| -CONFIG_NO_HZ_COMMON=y
 | |
| -CONFIG_NO_HZ_IDLE=y
 | |
| -CONFIG_NR_CPUS=4
 | |
| -CONFIG_NVIDIA_CARMEL_CNP_ERRATUM=y
 | |
| -CONFIG_NVMEM=y
 | |
| -CONFIG_NVMEM_QCOM_QFPROM=y
 | |
| -# CONFIG_NVMEM_SPMI_SDAM is not set
 | |
| -CONFIG_NVMEM_SYSFS=y
 | |
| -CONFIG_NVMEM_U_BOOT_ENV=y
 | |
| -CONFIG_OF=y
 | |
| -CONFIG_OF_ADDRESS=y
 | |
| -CONFIG_OF_EARLY_FLATTREE=y
 | |
| -CONFIG_OF_FLATTREE=y
 | |
| -CONFIG_OF_GPIO=y
 | |
| -CONFIG_OF_IRQ=y
 | |
| -CONFIG_OF_KOBJ=y
 | |
| -CONFIG_OF_MDIO=y
 | |
| -CONFIG_PADATA=y
 | |
| -CONFIG_PARTITION_PERCPU=y
 | |
| -CONFIG_PCI=y
 | |
| -CONFIG_PCIEAER=y
 | |
| -CONFIG_PCIEASPM=y
 | |
| -CONFIG_PCIEASPM_DEFAULT=y
 | |
| -# CONFIG_PCIEASPM_PERFORMANCE is not set
 | |
| -# CONFIG_PCIEASPM_POWERSAVE is not set
 | |
| -# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set
 | |
| -CONFIG_PCIEPORTBUS=y
 | |
| -CONFIG_PCIE_DW=y
 | |
| -CONFIG_PCIE_DW_HOST=y
 | |
| -CONFIG_PCIE_PME=y
 | |
| -CONFIG_PCIE_QCOM=y
 | |
| -CONFIG_PCI_DOMAINS=y
 | |
| -CONFIG_PCI_DOMAINS_GENERIC=y
 | |
| -CONFIG_PCI_MSI=y
 | |
| -CONFIG_PCI_MSI_IRQ_DOMAIN=y
 | |
| -CONFIG_PGTABLE_LEVELS=3
 | |
| -CONFIG_PHYLIB=y
 | |
| -CONFIG_PHYS_ADDR_T_64BIT=y
 | |
| -# CONFIG_PHY_QCOM_APQ8064_SATA is not set
 | |
| -# CONFIG_PHY_QCOM_IPQ4019_USB is not set
 | |
| -# CONFIG_PHY_QCOM_IPQ806X_SATA is not set
 | |
| -# CONFIG_PHY_QCOM_IPQ806X_USB is not set
 | |
| -# CONFIG_PHY_QCOM_PCIE2 is not set
 | |
| -CONFIG_PHY_QCOM_QMP=y
 | |
| -CONFIG_PHY_QCOM_QUSB2=y
 | |
| -# CONFIG_PHY_QCOM_USB_HS_28NM is not set
 | |
| -# CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2 is not set
 | |
| -# CONFIG_PHY_QCOM_USB_SS is not set
 | |
| -CONFIG_PINCTRL=y
 | |
| -# CONFIG_PINCTRL_APQ8064 is not set
 | |
| -# CONFIG_PINCTRL_APQ8084 is not set
 | |
| -# CONFIG_PINCTRL_IPQ4019 is not set
 | |
| -# CONFIG_PINCTRL_IPQ6018 is not set
 | |
| -# CONFIG_PINCTRL_IPQ8064 is not set
 | |
| -CONFIG_PINCTRL_IPQ8074=y
 | |
| -# CONFIG_PINCTRL_MDM9615 is not set
 | |
| -CONFIG_PINCTRL_MSM=y
 | |
| -# CONFIG_PINCTRL_MSM8226 is not set
 | |
| -# CONFIG_PINCTRL_MSM8660 is not set
 | |
| -# CONFIG_PINCTRL_MSM8916 is not set
 | |
| -# CONFIG_PINCTRL_MSM8960 is not set
 | |
| -# CONFIG_PINCTRL_MSM8976 is not set
 | |
| -# CONFIG_PINCTRL_MSM8994 is not set
 | |
| -# CONFIG_PINCTRL_MSM8996 is not set
 | |
| -# CONFIG_PINCTRL_MSM8998 is not set
 | |
| -CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 | |
| -# CONFIG_PINCTRL_QCOM_SSBI_PMIC is not set
 | |
| -# CONFIG_PINCTRL_QCS404 is not set
 | |
| -# CONFIG_PINCTRL_SC7180 is not set
 | |
| -# CONFIG_PINCTRL_SDM660 is not set
 | |
| -# CONFIG_PINCTRL_SDM845 is not set
 | |
| -# CONFIG_PINCTRL_SM8150 is not set
 | |
| -# CONFIG_PINCTRL_SM8250 is not set
 | |
| -CONFIG_PM=y
 | |
| -# CONFIG_PM8916_WATCHDOG is not set
 | |
| -CONFIG_PM_CLK=y
 | |
| -CONFIG_PM_GENERIC_DOMAINS=y
 | |
| -CONFIG_PM_GENERIC_DOMAINS_OF=y
 | |
| -CONFIG_PM_OPP=y
 | |
| -CONFIG_POWER_RESET=y
 | |
| -# CONFIG_POWER_RESET_MSM is not set
 | |
| -# CONFIG_POWER_RESET_QCOM_PON is not set
 | |
| -CONFIG_POWER_SUPPLY=y
 | |
| -CONFIG_PRINTK_TIME=y
 | |
| -CONFIG_PTP_1588_CLOCK_OPTIONAL=y
 | |
| -# CONFIG_QCOM_A53PLL is not set
 | |
| -# CONFIG_QCOM_AOSS_QMP is not set
 | |
| -CONFIG_QCOM_APCS_IPC=y
 | |
| -CONFIG_QCOM_APM=y
 | |
| -# CONFIG_QCOM_APR is not set
 | |
| -CONFIG_QCOM_BAM_DMA=y
 | |
| -# CONFIG_QCOM_CLK_APCC_MSM8996 is not set
 | |
| -# CONFIG_QCOM_CLK_APCS_MSM8916 is not set
 | |
| -# CONFIG_QCOM_CLK_APCS_SDX55 is not set
 | |
| -# CONFIG_QCOM_COINCELL is not set
 | |
| -# CONFIG_QCOM_COMMAND_DB is not set
 | |
| -# CONFIG_QCOM_CPR is not set
 | |
| -# CONFIG_QCOM_EBI2 is not set
 | |
| -# CONFIG_QCOM_FASTRPC is not set
 | |
| -CONFIG_QCOM_GDSC=y
 | |
| -# CONFIG_QCOM_GENI_SE is not set
 | |
| -# CONFIG_QCOM_GSBI is not set
 | |
| -# CONFIG_QCOM_HFPLL is not set
 | |
| -# CONFIG_QCOM_IPCC is not set
 | |
| -# CONFIG_QCOM_LLCC is not set
 | |
| -CONFIG_QCOM_MDT_LOADER=y
 | |
| -# CONFIG_QCOM_OCMEM is not set
 | |
| -# CONFIG_QCOM_PDC is not set
 | |
| -CONFIG_QCOM_PIL_INFO=y
 | |
| -# CONFIG_QCOM_Q6V5_ADSP is not set
 | |
| -CONFIG_QCOM_Q6V5_COMMON=y
 | |
| -# CONFIG_QCOM_Q6V5_MSS is not set
 | |
| -# CONFIG_QCOM_Q6V5_PAS is not set
 | |
| -CONFIG_QCOM_Q6V5_WCSS=y
 | |
| -# CONFIG_QCOM_RMTFS_MEM is not set
 | |
| -# CONFIG_QCOM_RPMH is not set
 | |
| -CONFIG_QCOM_RPROC_COMMON=y
 | |
| -CONFIG_QCOM_SCM=y
 | |
| -# CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is not set
 | |
| -# CONFIG_QCOM_SMD_RPM is not set
 | |
| -CONFIG_QCOM_SMEM=y
 | |
| -CONFIG_QCOM_SMEM_STATE=y
 | |
| -CONFIG_QCOM_SMP2P=y
 | |
| -# CONFIG_QCOM_SMSM is not set
 | |
| -CONFIG_QCOM_SOCINFO=y
 | |
| -CONFIG_QCOM_SPMI_ADC5=y
 | |
| -# CONFIG_QCOM_SYSMON is not set
 | |
| -CONFIG_QCOM_TSENS=y
 | |
| -CONFIG_QCOM_VADC_COMMON=y
 | |
| -# CONFIG_QCOM_WCNSS_CTRL is not set
 | |
| -# CONFIG_QCOM_WCNSS_PIL is not set
 | |
| -CONFIG_QCOM_WDT=y
 | |
| -# CONFIG_QCS_GCC_404 is not set
 | |
| -# CONFIG_QCS_Q6SSTOP_404 is not set
 | |
| -# CONFIG_QCS_TURING_404 is not set
 | |
| -CONFIG_QUEUED_RWLOCKS=y
 | |
| -CONFIG_QUEUED_SPINLOCKS=y
 | |
| -CONFIG_RAS=y
 | |
| -CONFIG_RATIONAL=y
 | |
| -CONFIG_REGMAP=y
 | |
| -CONFIG_REGMAP_MMIO=y
 | |
| -CONFIG_REGMAP_SPMI=y
 | |
| -CONFIG_REGULATOR=y
 | |
| -CONFIG_REGULATOR_CPR3=y
 | |
| -# CONFIG_REGULATOR_CPR3_NPU is not set
 | |
| -CONFIG_REGULATOR_CPR4_APSS=y
 | |
| -CONFIG_REGULATOR_FIXED_VOLTAGE=y
 | |
| -# CONFIG_REGULATOR_QCOM_LABIBB is not set
 | |
| -CONFIG_REGULATOR_QCOM_SPMI=y
 | |
| -# CONFIG_REGULATOR_QCOM_USB_VBUS is not set
 | |
| -# CONFIG_REGULATOR_VQMMC_IPQ4019 is not set
 | |
| -CONFIG_RELOCATABLE=y
 | |
| -CONFIG_REMOTEPROC=y
 | |
| -CONFIG_REMOTEPROC_CDEV=y
 | |
| -CONFIG_RESET_CONTROLLER=y
 | |
| -# CONFIG_RESET_QCOM_AOSS is not set
 | |
| -# CONFIG_RESET_QCOM_PDC is not set
 | |
| -CONFIG_RFS_ACCEL=y
 | |
| -CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
 | |
| -CONFIG_RPMSG=y
 | |
| -CONFIG_RPMSG_CHAR=y
 | |
| -# CONFIG_RPMSG_NS is not set
 | |
| -CONFIG_RPMSG_QCOM_GLINK=y
 | |
| -CONFIG_RPMSG_QCOM_GLINK_RPM=y
 | |
| -CONFIG_RPMSG_QCOM_GLINK_SMEM=y
 | |
| -CONFIG_RPMSG_QCOM_SMD=y
 | |
| -CONFIG_RPS=y
 | |
| -CONFIG_RTC_CLASS=y
 | |
| -CONFIG_RTC_DRV_PM8XXX=y
 | |
| -CONFIG_RTC_I2C_AND_SPI=y
 | |
| -CONFIG_RWSEM_SPIN_ON_OWNER=y
 | |
| -# CONFIG_SCHED_CORE is not set
 | |
| -CONFIG_SCHED_MC=y
 | |
| -CONFIG_SCHED_SMT=y
 | |
| -CONFIG_SCHED_THERMAL_PRESSURE=y
 | |
| -CONFIG_SCSI=y
 | |
| -CONFIG_SCSI_COMMON=y
 | |
| -# CONFIG_SCSI_LOWLEVEL is not set
 | |
| -# CONFIG_SCSI_PROC_FS is not set
 | |
| -# CONFIG_SC_DISPCC_7180 is not set
 | |
| -# CONFIG_SC_GCC_7180 is not set
 | |
| -# CONFIG_SC_GPUCC_7180 is not set
 | |
| -# CONFIG_SC_LPASS_CORECC_7180 is not set
 | |
| -# CONFIG_SC_MSS_7180 is not set
 | |
| -# CONFIG_SC_VIDEOCC_7180 is not set
 | |
| -# CONFIG_SDM_CAMCC_845 is not set
 | |
| -# CONFIG_SDM_DISPCC_845 is not set
 | |
| -# CONFIG_SDM_GCC_660 is not set
 | |
| -# CONFIG_SDM_GCC_845 is not set
 | |
| -# CONFIG_SDM_GPUCC_845 is not set
 | |
| -# CONFIG_SDM_LPASSCC_845 is not set
 | |
| -# CONFIG_SDM_VIDEOCC_845 is not set
 | |
| -CONFIG_SERIAL_8250_FSL=y
 | |
| -CONFIG_SERIAL_MCTRL_GPIO=y
 | |
| -CONFIG_SERIAL_MSM=y
 | |
| -CONFIG_SERIAL_MSM_CONSOLE=y
 | |
| -CONFIG_SGL_ALLOC=y
 | |
| -CONFIG_SG_POOL=y
 | |
| -CONFIG_SMP=y
 | |
| -# CONFIG_SM_GCC_8150 is not set
 | |
| -# CONFIG_SM_GCC_8250 is not set
 | |
| -# CONFIG_SM_GPUCC_8150 is not set
 | |
| -# CONFIG_SM_GPUCC_8250 is not set
 | |
| -# CONFIG_SM_VIDEOCC_8150 is not set
 | |
| -# CONFIG_SM_VIDEOCC_8250 is not set
 | |
| -CONFIG_SOCK_RX_QUEUE_MAPPING=y
 | |
| -CONFIG_SOC_BUS=y
 | |
| -CONFIG_SPARSEMEM=y
 | |
| -CONFIG_SPARSEMEM_EXTREME=y
 | |
| -CONFIG_SPARSEMEM_VMEMMAP=y
 | |
| -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
 | |
| -CONFIG_SPARSE_IRQ=y
 | |
| -CONFIG_SPI=y
 | |
| -CONFIG_SPI_MASTER=y
 | |
| -CONFIG_SPI_MEM=y
 | |
| -CONFIG_SPI_QUP=y
 | |
| -CONFIG_SPMI=y
 | |
| -# CONFIG_SPMI_HISI3670 is not set
 | |
| -CONFIG_SPMI_MSM_PMIC_ARB=y
 | |
| -# CONFIG_SPMI_PMIC_CLKDIV is not set
 | |
| -CONFIG_SRCU=y
 | |
| -CONFIG_SWIOTLB=y
 | |
| -CONFIG_SWPHY=y
 | |
| -CONFIG_SYSCTL_EXCEPTION_TRACE=y
 | |
| -CONFIG_THERMAL=y
 | |
| -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
 | |
| -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
 | |
| -CONFIG_THERMAL_GOV_STEP_WISE=y
 | |
| -CONFIG_THERMAL_OF=y
 | |
| -CONFIG_THREAD_INFO_IN_TASK=y
 | |
| -CONFIG_TICK_CPU_ACCOUNTING=y
 | |
| -CONFIG_TIMER_OF=y
 | |
| -CONFIG_TIMER_PROBE=y
 | |
| -CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
 | |
| -CONFIG_TREE_RCU=y
 | |
| -CONFIG_TREE_SRCU=y
 | |
| -CONFIG_UBIFS_FS=y
 | |
| -CONFIG_UBIFS_FS_ADVANCED_COMPR=y
 | |
| -# CONFIG_UCLAMP_TASK is not set
 | |
| -CONFIG_UNMAP_KERNEL_AT_EL0=y
 | |
| -CONFIG_USB=y
 | |
| -CONFIG_USB_COMMON=y
 | |
| -CONFIG_USB_SUPPORT=y
 | |
| -CONFIG_VIRTIO=y
 | |
| -# CONFIG_VIRTIO_BLK is not set
 | |
| -# CONFIG_VIRTIO_NET is not set
 | |
| -CONFIG_VMAP_STACK=y
 | |
| -CONFIG_WANT_DEV_COREDUMP=y
 | |
| -CONFIG_WATCHDOG_CORE=y
 | |
| -CONFIG_WATCHDOG_SYSFS=y
 | |
| -CONFIG_XPS=y
 | |
| -CONFIG_XXHASH=y
 | |
| -CONFIG_ZLIB_DEFLATE=y
 | |
| -CONFIG_ZLIB_INFLATE=y
 | |
| -CONFIG_ZONE_DMA32=y
 | |
| -CONFIG_ZSTD_COMPRESS=y
 | |
| -CONFIG_ZSTD_DECOMPRESS=y
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts
 | |
| deleted file mode 100644
 | |
| index 2c9cbd5b3c..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8070-cax1800.dts
 | |
| +++ /dev/null
 | |
| @@ -1,322 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 | |
| -/* Copyright (c) 2021, Dirk Buchwalder <buchwalder@posteo.de> */
 | |
| -
 | |
| -/dts-v1/;
 | |
| -
 | |
| -#include "ipq8074-512m.dtsi"
 | |
| -#include "ipq8074-ac-cpu.dtsi"
 | |
| -#include "ipq8074-ess.dtsi"
 | |
| -#include <dt-bindings/gpio/gpio.h>
 | |
| -#include <dt-bindings/input/input.h>
 | |
| -
 | |
| -/ {
 | |
| -	model = "Edimax CAX1800";
 | |
| -	compatible = "edimax,cax1800", "qcom,ipq8074";
 | |
| -
 | |
| -	aliases {
 | |
| -		serial0 = &blsp1_uart5;
 | |
| -		led-boot = &led_system_red;
 | |
| -		led-failsafe = &led_system_red;
 | |
| -		led-running = &led_system_green;
 | |
| -		led-upgrade = &led_system_red;
 | |
| -		/* Aliases as required by u-boot to patch MAC addresses */
 | |
| -		ethernet0 = &dp5;
 | |
| -		label-mac-device = &dp5;
 | |
| -	};
 | |
| -
 | |
| -	chosen {
 | |
| -		stdout-path = "serial0:115200n8";
 | |
| -		bootargs-append = " root=/dev/ubiblock0_1";
 | |
| -	};
 | |
| -
 | |
| -	keys {
 | |
| -		compatible = "gpio-keys";
 | |
| -
 | |
| -		reset {
 | |
| -			label = "reset";
 | |
| -			gpios = <&tlmm 32 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_RESTART>;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	leds {
 | |
| -		compatible = "gpio-leds";
 | |
| -
 | |
| -		led_system_red: system-red {
 | |
| -			label = "red:system";
 | |
| -			gpios = <&tlmm 25 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		led_system_green: system-green {
 | |
| -			label = "green:system";
 | |
| -			gpios = <&tlmm 26 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		led_system_blue: system-blue {
 | |
| -			label = "blue:system";
 | |
| -			gpios = <&tlmm 27 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&tlmm {
 | |
| -	mdio_pins: mdio-pins {
 | |
| -		mdc {
 | |
| -			pins = "gpio68";
 | |
| -			function = "mdc";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		mdio {
 | |
| -			pins = "gpio69";
 | |
| -			function = "mdio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&blsp1_uart5 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&prng {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&cryptobam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&crypto {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_bam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_nand {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	nand@0 {
 | |
| -		reg = <0>;
 | |
| -		nand-ecc-strength = <4>;
 | |
| -		nand-ecc-step-size = <512>;
 | |
| -		nand-bus-width = <8>;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "fixed-partitions";
 | |
| -			#address-cells = <1>;
 | |
| -			#size-cells = <1>;
 | |
| -
 | |
| -			partition@0 {
 | |
| -				label = "rootfs";
 | |
| -				reg = <0x0000000 0x3400000>;
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&blsp1_spi1 {
 | |
| -	pinctrl-0 = <&spi_0_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	cs-select = <0>;
 | |
| -	status = "ok";
 | |
| -
 | |
| -	m25p80@0 {
 | |
| -		#address-cells = <1>;
 | |
| -		#size-cells = <1>;
 | |
| -		reg = <0>;
 | |
| -		compatible = "jedec,spi-nor";
 | |
| -		spi-max-frequency = <50000000>;
 | |
| -		use-default-sizes;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "fixed-partitions";
 | |
| -			#address-cells = <1>;
 | |
| -			#size-cells = <1>;
 | |
| -
 | |
| -			partition@0 {
 | |
| -				label = "0:sbl1";
 | |
| -				reg = <0x0 0x50000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@50000 {
 | |
| -				label = "0:mibib";
 | |
| -				reg = <0x50000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@60000 {
 | |
| -				label = "0:bootconfig";
 | |
| -				reg = <0x60000 0x20000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@80000 {
 | |
| -				label = "0:bootconfig1";
 | |
| -				reg = <0x80000 0x20000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@a0000 {
 | |
| -				label = "0:qsee";
 | |
| -				reg = <0xa0000 0x180000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@220000 {
 | |
| -				label = "0:qsee_1";
 | |
| -				reg = <0x220000 0x180000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3a0000 {
 | |
| -				label = "0:devcfg";
 | |
| -				reg = <0x3a0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3b0000 {
 | |
| -				label = "0:devcfg_1";
 | |
| -				reg = <0x3b0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3c0000 {
 | |
| -				label = "0:apdp";
 | |
| -				reg = <0x3c0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3d0000 {
 | |
| -				label = "0:apdp_1";
 | |
| -				reg = <0x3d0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3e0000 {
 | |
| -				label = "0:rpm";
 | |
| -				reg = <0x3e0000 0x40000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@420000 {
 | |
| -				label = "0:rpm_1";
 | |
| -				reg = <0x420000 0x40000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@460000 {
 | |
| -				label = "0:cdt";
 | |
| -				reg = <0x460000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@470000 {
 | |
| -				label = "0:cdt_1";
 | |
| -				reg = <0x470000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@480000 {
 | |
| -				label = "0:appsblenv";
 | |
| -				reg = <0x480000 0x10000>;
 | |
| -			};
 | |
| -
 | |
| -			partition@490000 {
 | |
| -				label = "0:appsbl";
 | |
| -				reg = <0x490000 0xa0000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@530000 {
 | |
| -				label = "0:appsbl_1";
 | |
| -				reg = <0x530000 0xa0000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@5d0000 {
 | |
| -				label = "0:art";
 | |
| -				reg = <0x5d0000 0x40000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@610000 {
 | |
| -				label = "0:ethphyfw";
 | |
| -				reg = <0x610000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&mdio {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	pinctrl-0 = <&mdio_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -
 | |
| -	reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
 | |
| -
 | |
| -	qca8075: ethernet-phy@4 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <4>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&switch {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	switch_cpu_bmp = <0x1>;  /* cpu port bitmap */
 | |
| -	switch_lan_bmp = <0x1e>; /* lan port bitmap */
 | |
| -	switch_wan_bmp = <0x20>; /* wan port bitmap */
 | |
| -	switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/
 | |
| -	switch_mac_mode1 = <0xff>; /* mac mode for uniphy instance1*/
 | |
| -	switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
 | |
| -	bm_tick_mode = <0>; /* bm tick mode */
 | |
| -	tm_tick_mode = <0>; /* tm tick mode */
 | |
| -
 | |
| -	qcom,port_phyinfo {
 | |
| -		port@0 {
 | |
| -			port_id = <1>;
 | |
| -			phy_address = <0>;
 | |
| -		};
 | |
| -		port@1 {
 | |
| -			port_id = <2>;
 | |
| -			phy_address = <1>;
 | |
| -		};
 | |
| -		port@2 {
 | |
| -			port_id = <3>;
 | |
| -			phy_address = <2>;
 | |
| -		};
 | |
| -		port@3 {
 | |
| -			port_id = <4>;
 | |
| -			phy_address = <3>;
 | |
| -		};
 | |
| -		port@4 {
 | |
| -			port_id = <5>;
 | |
| -			phy_address = <4>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&edma {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&dp5 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075>;
 | |
| -	label = "lan";
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	qcom,ath11k-calibration-variant = "Edimax-CAX1800";
 | |
| -	qcom,ath11k-fw-memory-mode = <1>;
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dts
 | |
| deleted file mode 100644
 | |
| index f3e82e2251..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dts
 | |
| +++ /dev/null
 | |
| @@ -1,73 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 | |
| -/* Copyright (c) 2021, Robert Marko <robimarko@gmail.com> */
 | |
| -
 | |
| -/dts-v1/;
 | |
| -
 | |
| -#include "ipq8071-ax3600.dtsi"
 | |
| -
 | |
| -/ {
 | |
| -	model = "Xiaomi AX3600";
 | |
| -	compatible = "xiaomi,ax3600", "qcom,ipq8074";
 | |
| -
 | |
| -	leds {
 | |
| -		compatible = "gpio-leds";
 | |
| -
 | |
| -		led_system_blue: system-blue {
 | |
| -			label = "blue:system";
 | |
| -			gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		led_system_yellow: system-yellow {
 | |
| -			label = "yellow:system";
 | |
| -			gpios = <&tlmm 43 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		network-yellow {
 | |
| -			label = "yellow:network";
 | |
| -			gpios = <&tlmm 22 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		network-blue {
 | |
| -			label = "blue:network";
 | |
| -			gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		aiot {
 | |
| -			label = "blue:aiot";
 | |
| -			gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>;
 | |
| -			linux,default-trigger = "phy0tpt";
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&pcie_qmp0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&pcie0 {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	perst-gpio = <&tlmm 52 GPIO_ACTIVE_HIGH>;
 | |
| -
 | |
| -	bridge@0,0 {
 | |
| -		reg = <0x00000000 0 0 0 0>;
 | |
| -		#address-cells = <3>;
 | |
| -		#size-cells = <2>;
 | |
| -		ranges;
 | |
| -
 | |
| -		wifi0: wifi@1,0 {
 | |
| -			status = "okay";
 | |
| -
 | |
| -			compatible = "qcom,ath10k";
 | |
| -			reg = <0x00010000 0 0 0 0>;
 | |
| -
 | |
| -			qcom,ath10k-calibration-variant = "Xiaomi-AX3600";
 | |
| -			nvmem-cell-names = "calibration";
 | |
| -			nvmem-cells = <&caldata_qca9889>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	qcom,ath11k-calibration-variant = "Xiaomi-AX3600";
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi
 | |
| deleted file mode 100644
 | |
| index c18cef52f3..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax3600.dtsi
 | |
| +++ /dev/null
 | |
| @@ -1,311 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 | |
| -/* Copyright (c) 2021, Robert Marko <robimarko@gmail.com> */
 | |
| -
 | |
| -#include "ipq8074-512m.dtsi"
 | |
| -#include "ipq8074-ac-cpu.dtsi"
 | |
| -#include "ipq8074-ess.dtsi"
 | |
| -#include <dt-bindings/gpio/gpio.h>
 | |
| -#include <dt-bindings/input/input.h>
 | |
| -
 | |
| -/ {
 | |
| -	aliases {
 | |
| -		serial0 = &blsp1_uart5;
 | |
| -		led-boot = &led_system_yellow;
 | |
| -		led-failsafe = &led_system_yellow;
 | |
| -		led-running = &led_system_blue;
 | |
| -		led-upgrade = &led_system_yellow;
 | |
| -		label-mac-device = &dp2;
 | |
| -	};
 | |
| -
 | |
| -	chosen {
 | |
| -		stdout-path = "serial0:115200n8";
 | |
| -		bootargs-append = " root=/dev/ubiblock0_0";
 | |
| -	};
 | |
| -
 | |
| -	keys {
 | |
| -		compatible = "gpio-keys";
 | |
| -
 | |
| -		reset {
 | |
| -			label = "reset";
 | |
| -			gpios = <&tlmm 34 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_RESTART>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&tlmm {
 | |
| -	mdio_pins: mdio-pins {
 | |
| -		mdc {
 | |
| -			pins = "gpio68";
 | |
| -			function = "mdc";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		mdio {
 | |
| -			pins = "gpio69";
 | |
| -			function = "mdio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&blsp1_uart5 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&prng {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&cryptobam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&crypto {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_bam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_nand {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	/*
 | |
| -	 * Bootloader will find the NAND DT node by the compatible and
 | |
| -	 * then "fixup" it by adding the partitions from the SMEM table
 | |
| -	 * using the legacy bindings thus making it impossible for us
 | |
| -	 * to change the partition table or utilize NVMEM for calibration.
 | |
| -	 * So add a dummy partitions node that bootloader will populate
 | |
| -	 * and set it as disabled so the kernel ignores it instead of
 | |
| -	 * printing warnings due to the broken way bootloader adds the
 | |
| -	 * partitions.
 | |
| -	 */
 | |
| -	partitions {
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -
 | |
| -	nand@0 {
 | |
| -		reg = <0>;
 | |
| -		nand-ecc-strength = <4>;
 | |
| -		nand-ecc-step-size = <512>;
 | |
| -		nand-bus-width = <8>;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "fixed-partitions";
 | |
| -			#address-cells = <1>;
 | |
| -			#size-cells = <1>;
 | |
| -
 | |
| -			partition@0 {
 | |
| -				label = "0:sbl1";
 | |
| -				reg = <0x0 0x100000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@100000 {
 | |
| -				label = "0:mibib";
 | |
| -				reg = <0x100000 0x100000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@200000 {
 | |
| -				label = "0:qsee";
 | |
| -				reg = <0x200000 0x300000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@500000 {
 | |
| -				label = "0:devcfg";
 | |
| -				reg = <0x500000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@580000 {
 | |
| -				label = "0:rpm";
 | |
| -				reg = <0x580000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@600000 {
 | |
| -				label = "0:cdt";
 | |
| -				reg = <0x600000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@680000 {
 | |
| -				label = "0:appsblenv";
 | |
| -				reg = <0x680000 0x80000>;
 | |
| -			};
 | |
| -
 | |
| -			partition@700000 {
 | |
| -				label = "0:appsbl";
 | |
| -				reg = <0x700000 0x100000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@800000 {
 | |
| -				label = "0:art";
 | |
| -				reg = <0x800000 0x80000>;
 | |
| -				read-only;
 | |
| -
 | |
| -				compatible = "nvmem-cells";
 | |
| -				#address-cells = <1>;
 | |
| -				#size-cells = <1>;
 | |
| -
 | |
| -				macaddr_dp2: macaddr@6 {
 | |
| -					reg = <0x6 0x6>;
 | |
| -				};
 | |
| -
 | |
| -				macaddr_dp3: macaddr@c {
 | |
| -					reg = <0xc 0x6>;
 | |
| -				};
 | |
| -
 | |
| -				macaddr_dp4: macaddr@12 {
 | |
| -					reg = <0x12 0x6>;
 | |
| -				};
 | |
| -
 | |
| -				macaddr_dp5: macaddr@18 {
 | |
| -					reg = <0x18 0x6>;
 | |
| -				};
 | |
| -
 | |
| -				caldata_qca9889: caldata@4d000 {
 | |
| -					reg = <0x33000 0x844>;
 | |
| -				};
 | |
| -			};
 | |
| -
 | |
| -			partition@880000 {
 | |
| -				label = "bdata";
 | |
| -				reg = <0x880000 0x80000>;
 | |
| -			};
 | |
| -
 | |
| -			partition@900000 {
 | |
| -				/* This is crash + crash_syslog parts combined */
 | |
| -				label = "pstore";
 | |
| -				reg = <0x900000 0x100000>;
 | |
| -			};
 | |
| -
 | |
| -			/* Make the first rootfs a dedicated ubi partition for kernel */
 | |
| -			partition@a00000 {
 | |
| -				label = "ubi_kernel";
 | |
| -				reg = <0xa00000 0x23c0000>;
 | |
| -			};
 | |
| -
 | |
| -			/* Place the real rootfs in the original second rootfs and
 | |
| -			 * expand it to the end of the nand
 | |
| -			 */
 | |
| -			rootfs: partition@2dc0000 {
 | |
| -				label = "rootfs";
 | |
| -				reg = <0x2dc0000 0xd240000>;
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&mdio {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	pinctrl-0 = <&mdio_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
 | |
| -
 | |
| -	qca8075_1: ethernet-phy@1 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <1>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_2: ethernet-phy@2 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <2>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_3: ethernet-phy@3 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <3>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_4: ethernet-phy@4 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <4>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&switch {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	switch_cpu_bmp = <0x1>;  /* cpu port bitmap */
 | |
| -	switch_lan_bmp = <0x1e>; /* lan port bitmap */
 | |
| -	switch_wan_bmp = <0x20>; /* wan port bitmap */
 | |
| -	switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/
 | |
| -	switch_mac_mode1 = <0xff>; /* mac mode for uniphy instance1*/
 | |
| -	switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
 | |
| -	bm_tick_mode = <0>; /* bm tick mode */
 | |
| -	tm_tick_mode = <0>; /* tm tick mode */
 | |
| -
 | |
| -	qcom,port_phyinfo {
 | |
| -		port@0 {
 | |
| -			port_id = <1>;
 | |
| -			phy_address = <0>;
 | |
| -		};
 | |
| -		port@1 {
 | |
| -			port_id = <2>;
 | |
| -			phy_address = <1>;
 | |
| -		};
 | |
| -		port@2 {
 | |
| -			port_id = <3>;
 | |
| -			phy_address = <2>;
 | |
| -		};
 | |
| -		port@3 {
 | |
| -			port_id = <4>;
 | |
| -			phy_address = <3>;
 | |
| -		};
 | |
| -		port@4 {
 | |
| -			port_id = <5>;
 | |
| -			phy_address = <4>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&edma {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&dp2 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_1>;
 | |
| -	label = "wan";
 | |
| -	nvmem-cells = <&macaddr_dp2>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp3 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_2>;
 | |
| -	label = "lan1";
 | |
| -	nvmem-cells = <&macaddr_dp3>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp4 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_3>;
 | |
| -	label = "lan2";
 | |
| -	nvmem-cells = <&macaddr_dp4>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp5 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_4>;
 | |
| -	label = "lan3";
 | |
| -	nvmem-cells = <&macaddr_dp5>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	qcom,ath11k-fw-memory-mode = <1>;
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax6.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax6.dts
 | |
| deleted file mode 100644
 | |
| index 6611a8fe27..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-ax6.dts
 | |
| +++ /dev/null
 | |
| @@ -1,46 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 | |
| -/* Copyright (c) 2021, Zhijun You <hujy652@gmail.com> */
 | |
| -
 | |
| -/dts-v1/;
 | |
| -
 | |
| -#include "ipq8071-ax3600.dtsi"
 | |
| -
 | |
| -/ {
 | |
| -	model = "Redmi AX6";
 | |
| -	compatible = "redmi,ax6", "qcom,ipq8074";
 | |
| -
 | |
| -	leds {
 | |
| -		compatible = "gpio-leds";
 | |
| -
 | |
| -		led_system_blue: system-blue {
 | |
| -			label = "blue:system";
 | |
| -			gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		led_system_yellow: system-yellow {
 | |
| -			label = "yellow:system";
 | |
| -			gpios = <&tlmm 22 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		network-blue {
 | |
| -			label = "blue:network";
 | |
| -			gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		network-yellow {
 | |
| -			label = "yellow:network";
 | |
| -			gpios = <&tlmm 43 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -/* AX6 can both have NAND of 256MiB or 128MiB.
 | |
| - * To be on the safe side, assume 128MiB of NAND.
 | |
| - */
 | |
| -&rootfs {
 | |
| -	reg = <0x2dc0000 0x5220000>;
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	qcom,ath11k-calibration-variant = "Redmi-AX6";
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts
 | |
| deleted file mode 100644
 | |
| index 357b6368d9..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8071-eap102.dts
 | |
| +++ /dev/null
 | |
| @@ -1,389 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 | |
| -/* Copyright (c) 2022, Matthew Hagan <mnhagan88@gmail.com> */
 | |
| -
 | |
| -/dts-v1/;
 | |
| -
 | |
| -#include "ipq8074.dtsi"
 | |
| -#include "ipq8074-ac-cpu.dtsi"
 | |
| -#include "ipq8074-ess.dtsi"
 | |
| -#include <dt-bindings/gpio/gpio.h>
 | |
| -#include <dt-bindings/input/input.h>
 | |
| -
 | |
| -/ {
 | |
| -	model = "Edgecore EAP102";
 | |
| -	compatible = "edgecore,eap102", "qcom,ipq8074";
 | |
| -
 | |
| -	aliases {
 | |
| -		serial0 = &blsp1_uart5;
 | |
| -		serial1 = &blsp1_uart3;
 | |
| -		led-boot = &led_system_green;
 | |
| -		led-failsafe = &led_system_green;
 | |
| -		led-running = &led_system_green;
 | |
| -		led-upgrade = &led_system_green;
 | |
| -		/* Aliases as required by u-boot to patch MAC addresses */
 | |
| -		ethernet0 = &dp5;
 | |
| -		ethernet1 = &dp6;
 | |
| -		label-mac-device = &dp5;
 | |
| -	};
 | |
| -
 | |
| -	chosen {
 | |
| -		stdout-path = "serial0:115200n8";
 | |
| -		bootargs-append = " root=/dev/ubiblock0_1";
 | |
| -	};
 | |
| -
 | |
| -	keys {
 | |
| -		compatible = "gpio-keys";
 | |
| -		pinctrl-0 = <&button_pins>;
 | |
| -		pinctrl-names = "default";
 | |
| -
 | |
| -		reset {
 | |
| -			label = "reset";
 | |
| -			gpios = <&tlmm 66 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_RESTART>;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	leds {
 | |
| -		compatible = "gpio-leds";
 | |
| -
 | |
| -		led_wanpoe {
 | |
| -			label = "green:wanpoe";
 | |
| -			gpios = <&tlmm 46 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		led_wlan2g {
 | |
| -			label = "green:wlan2g";
 | |
| -			gpio = <&tlmm 47 GPIO_ACTIVE_HIGH>;
 | |
| -			linux,default-trigger = "phy1radio";
 | |
| -		};
 | |
| -
 | |
| -		led_wlan5g {
 | |
| -			label = "green:wlan5g";
 | |
| -			gpio = <&tlmm 48 GPIO_ACTIVE_HIGH>;
 | |
| -			linux,default-trigger = "phy0radio";
 | |
| -		};
 | |
| -
 | |
| -		led_system_green: led_system {
 | |
| -			label = "green:power";
 | |
| -			gpios = <&tlmm 50 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&tlmm {
 | |
| -	mdio_pins: mdio-pins {
 | |
| -		mdc {
 | |
| -			pins = "gpio68";
 | |
| -			function = "mdc";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		mdio {
 | |
| -			pins = "gpio69";
 | |
| -			function = "mdio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	button_pins: button_pins {
 | |
| -		reset_button {
 | |
| -			pins = "gpio66";
 | |
| -			function = "gpio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&blsp1_spi1 {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	flash@0 {
 | |
| -		#address-cells = <1>;
 | |
| -		#size-cells = <1>;
 | |
| -		reg = <0>;
 | |
| -		compatible = "jedec,spi-nor";
 | |
| -		spi-max-frequency = <50000000>;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "fixed-partitions";
 | |
| -			#address-cells = <1>;
 | |
| -			#size-cells = <1>;
 | |
| -
 | |
| -			partition@0 {
 | |
| -				label = "0:sbl1";
 | |
| -				reg = <0x0 0x50000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@50000 {
 | |
| -				label = "0:mibib";
 | |
| -				reg = <0x50000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@60000 {
 | |
| -				label = "0:bootconfig";
 | |
| -				reg = <0x60000 0x20000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@80000 {
 | |
| -				label = "0:bootconfig1";
 | |
| -				reg = <0x80000 0x20000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@a0000 {
 | |
| -				label = "0:qsee";
 | |
| -				reg = <0xa0000 0x180000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@220000 {
 | |
| -				label = "0:qsee_1";
 | |
| -				reg = <0x220000 0x180000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3a0000 {
 | |
| -				label = "0:devcfg";
 | |
| -				reg = <0x3a0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3b0000 {
 | |
| -				label = "0:devcfg_1";
 | |
| -				reg = <0x3b0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3c0000 {
 | |
| -				label = "0:apdp";
 | |
| -				reg = <0x3c0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3d0000 {
 | |
| -				label = "0:apdp_1";
 | |
| -				reg = <0x3d0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3e0000 {
 | |
| -				label = "0:rpm";
 | |
| -				reg = <0x3e0000 0x40000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@420000 {
 | |
| -				label = "0:rpm_1";
 | |
| -				reg = <0x420000 0x40000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@460000 {
 | |
| -				label = "0:cdt";
 | |
| -				reg = <0x460000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@470000 {
 | |
| -				label = "0:cdt_1";
 | |
| -				reg = <0x470000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@480000 {
 | |
| -				label = "0:appsblenv";
 | |
| -				reg = <0x480000 0x10000>;
 | |
| -			};
 | |
| -
 | |
| -			partition@490000 {
 | |
| -				label = "0:appsbl";
 | |
| -				reg = <0x490000 0xc0000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@550000 {
 | |
| -				label = "0:appsbl_1";
 | |
| -				reg = <0x530000 0xc0000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@610000 {
 | |
| -				label = "0:art";
 | |
| -				reg = <0x610000 0x40000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@650000 {
 | |
| -				label = "0:ethphyfw";
 | |
| -				reg = <0x650000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@6d0000 {
 | |
| -				label = "0:product_info";
 | |
| -				reg = <0x6d0000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@750000 {
 | |
| -				label = "priv_data1";
 | |
| -				reg = <0x750000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@760000 {
 | |
| -				label = "priv_data2";
 | |
| -				reg = <0x760000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&blsp1_uart3 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&blsp1_uart5 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&crypto {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&cryptobam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&prng {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_bam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qusb_phy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&ssphy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&usb_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_nand {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	nand@0 {
 | |
| -		reg = <0>;
 | |
| -		nand-ecc-strength = <8>;
 | |
| -		nand-ecc-step-size = <512>;
 | |
| -		nand-bus-width = <8>;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "fixed-partitions";
 | |
| -			#address-cells = <1>;
 | |
| -			#size-cells = <1>;
 | |
| -
 | |
| -			partition@0 {
 | |
| -				label = "rootfs1";
 | |
| -				reg = <0x0000000 0x3400000>;
 | |
| -			};
 | |
| -
 | |
| -			partition@3400000 {
 | |
| -				label = "0:wififw";
 | |
| -				reg = <0x3400000 0x800000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3c00000 {
 | |
| -				label = "rootfs2";
 | |
| -				reg = <0x3c00000 0x3400000>;
 | |
| -			};
 | |
| -
 | |
| -			partition@7000000 {
 | |
| -				label = "0:wififw_1";
 | |
| -				reg = <0x7000000 0x800000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&mdio {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	pinctrl-0 = <&mdio_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -
 | |
| -	qca8081_24: ethernet-phy@24 {
 | |
| -		compatible = "ethernet-phy-id004d.d101";
 | |
| -		reg = <24>;
 | |
| -		reset-gpios = <&tlmm 33 GPIO_ACTIVE_LOW>;
 | |
| -	};
 | |
| -
 | |
| -	qca8081_28: ethernet-phy@28 {
 | |
| -		compatible = "ethernet-phy-id004d.d101";
 | |
| -		reg = <28>;
 | |
| -		reset-gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&switch {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	switch_cpu_bmp = <0x1>;  /* cpu port bitmap */
 | |
| -	switch_lan_bmp = <0x3e>; /* lan port bitmap */
 | |
| -	switch_wan_bmp = <0x40>; /* wan port bitmap */
 | |
| -	switch_mac_mode = <0xff>; /* mac mode for uniphy instance0*/
 | |
| -	switch_mac_mode1 = <0xf>; /* mac mode for uniphy instance1*/
 | |
| -	switch_mac_mode2 = <0xf>; /* mac mode for uniphy instance2*/
 | |
| -	bm_tick_mode = <0>; /* bm tick mode */
 | |
| -	tm_tick_mode = <0>; /* tm tick mode */
 | |
| -
 | |
| -	qcom,port_phyinfo {
 | |
| -		port@4 {
 | |
| -			port_id = <5>;
 | |
| -			phy_address = <24>;
 | |
| -			port_mac_sel = "QGMAC_PORT";
 | |
| -		};
 | |
| -		port@5 {
 | |
| -			port_id = <6>;
 | |
| -			phy_address = <28>;
 | |
| -			port_mac_sel = "QGMAC_PORT";
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&edma {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&dp5 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8081_28>;
 | |
| -	label = "wan";
 | |
| -};
 | |
| -
 | |
| -&dp6 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8081_24>;
 | |
| -	label = "lan";
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	qcom,ath11k-calibration-variant = "Edgecore-EAP102";
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts
 | |
| deleted file mode 100644
 | |
| index 5521a480b8..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-301w.dts
 | |
| +++ /dev/null
 | |
| @@ -1,410 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 | |
| -/* Copyright (c) 2021, Dirk Buchwalder <buchwalder@posteo.de> */
 | |
| -
 | |
| -/dts-v1/;
 | |
| -
 | |
| -#include "ipq8074.dtsi"
 | |
| -#include "ipq8074-hk-cpu.dtsi"
 | |
| -#include "ipq8074-ess.dtsi"
 | |
| -#include <dt-bindings/gpio/gpio.h>
 | |
| -#include <dt-bindings/input/input.h>
 | |
| -#include <dt-bindings/leds/common.h>
 | |
| -
 | |
| -/ {
 | |
| -	model = "QNAP 301w";
 | |
| -	compatible = "qnap,301w", "qcom,ipq8074";
 | |
| -
 | |
| -	aliases {
 | |
| -		serial0 = &blsp1_uart5;
 | |
| -		/*
 | |
| -		 * Aliases as required by u-boot
 | |
| -		 * to patch MAC addresses
 | |
| -		 */
 | |
| -		led-boot = &led_system_red;
 | |
| -		led-failsafe = &led_system_red;
 | |
| -		led-running = &led_pwr_green;
 | |
| -		led-upgrade = &led_system_red;
 | |
| -		ethernet0 = &dp1;
 | |
| -		ethernet1 = &dp2;
 | |
| -		ethernet2 = &dp3;
 | |
| -		ethernet3 = &dp4;
 | |
| -		ethernet4 = &dp5;
 | |
| -		ethernet5 = &dp6_syn;
 | |
| -		label-mac-device = &dp1;
 | |
| -	};
 | |
| -
 | |
| -	chosen {
 | |
| -		stdout-path = "serial0:115200n8";
 | |
| -	};
 | |
| -
 | |
| -	keys {
 | |
| -		compatible = "gpio-keys";
 | |
| -		pinctrl-0 = <&button_pins>;
 | |
| -		pinctrl-names = "default";
 | |
| -
 | |
| -		wps-button {
 | |
| -			label = "wps";
 | |
| -			gpios = <&tlmm 57 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_WPS_BUTTON>;
 | |
| -		};
 | |
| -
 | |
| -		reset-button {
 | |
| -			label = "reset";
 | |
| -			gpios = <&tlmm 67 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_RESTART>;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	leds {
 | |
| -		compatible = "gpio-leds";
 | |
| -		pinctrl-0 = <&leds_pins>;
 | |
| -		pinctrl-names = "default";
 | |
| -
 | |
| -		led_system_green: led-system-green {
 | |
| -			label = "green:system";
 | |
| -			gpios = <&tlmm 1 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_GREEN>;
 | |
| -		};
 | |
| -
 | |
| -		led_system_red: led-system-red {
 | |
| -			label = "red:system";
 | |
| -			gpios = <&tlmm 3 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_RED>;
 | |
| -		};
 | |
| -
 | |
| -		led_pwr_green: led-pwr-green {
 | |
| -			label = "green:pwr";
 | |
| -			gpios = <&tlmm 4 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_GREEN>;
 | |
| -		};
 | |
| -
 | |
| -		led-wifi-green {
 | |
| -			label = "green:wifi";
 | |
| -			gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_GREEN>;
 | |
| -		};
 | |
| -
 | |
| -		led-lan4-green {
 | |
| -			label = "green:lan4";
 | |
| -			gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_GREEN>;
 | |
| -		};
 | |
| -
 | |
| -		led-lan4-amber {
 | |
| -			label = "amber:lan4";
 | |
| -			gpios = <&tlmm 7 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_AMBER>;
 | |
| -		};
 | |
| -
 | |
| -		led-lan3-green {
 | |
| -			label = "green:lan3";
 | |
| -			gpios = <&tlmm 8 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_GREEN>;
 | |
| -		};
 | |
| -
 | |
| -		led-lan3-amber {
 | |
| -			label = "amber:lan3";
 | |
| -			gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_AMBER>;
 | |
| -		};
 | |
| -
 | |
| -		led-lan2-green {
 | |
| -			label = "green:lan2";
 | |
| -			gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_GREEN>;
 | |
| -		};
 | |
| -
 | |
| -		led-lan2-amber {
 | |
| -			label = "amber:lan2";
 | |
| -			gpios = <&tlmm 13 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_AMBER>;
 | |
| -		};
 | |
| -
 | |
| -		led-lan1-green {
 | |
| -			label = "green:lan1";
 | |
| -			gpios = <&tlmm 14 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_GREEN>;
 | |
| -		};
 | |
| -
 | |
| -		led-lan1-amber {
 | |
| -			label = "amber:lan1";
 | |
| -			gpios = <&tlmm 15 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_AMBER>;
 | |
| -		};
 | |
| -
 | |
| -		led-10g-1-green {
 | |
| -			label = "green:10g_1";
 | |
| -			gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_GREEN>;
 | |
| -		};
 | |
| -
 | |
| -		led-10g-1-amber {
 | |
| -			label = "amber:10g_1";
 | |
| -			gpios = <&tlmm 56 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_AMBER>;
 | |
| -		};
 | |
| -
 | |
| -		led-10g-2-green {
 | |
| -			label = "green:10g_2";
 | |
| -			gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_GREEN>;
 | |
| -		};
 | |
| -
 | |
| -		led-10g-2-amber {
 | |
| -			label = "amber:10g_2";
 | |
| -			gpios = <&tlmm 52 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_AMBER>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&tlmm {
 | |
| -
 | |
| -	mdio_pins: mdio-state {
 | |
| -		mdc-pins {
 | |
| -			pins = "gpio68";
 | |
| -			function = "mdc";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		mdio-pins {
 | |
| -			pins = "gpio69";
 | |
| -			function = "mdio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	button_pins: button-state {
 | |
| -		wps-pins {
 | |
| -			pins = "gpio57";
 | |
| -			function = "gpio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		rst-pins {
 | |
| -			pins = "gpio67";
 | |
| -			function = "gpio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	leds_pins: leds-state {
 | |
| -		pins = "gpio1", "gpio3", "gpio4", "gpio6", "gpio7", "gpio8",
 | |
| -		       "gpio11", "gpio12", "gpio13", "gpio14", "gpio15", "gpio42",
 | |
| -		       "gpio51", "gpio52", "gpio54", "gpio56";
 | |
| -		function = "gpio";
 | |
| -		drive-strength = <8>;
 | |
| -		bias-pull-down;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&blsp1_uart5 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&prng {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&ssphy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qusb_phy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&ssphy_1 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qusb_phy_1 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&usb_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&usb_1 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&cryptobam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&crypto {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_bam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&blsp1_spi1 { /* BLSP1 QUP1 */
 | |
| -	pinctrl-0 = <&spi_0_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	cs-gpios = <0>;
 | |
| -	status = "okay";
 | |
| -
 | |
| -	flash@0 {
 | |
| -		#address-cells = <1>;
 | |
| -		#size-cells = <1>;
 | |
| -		reg = <0>;
 | |
| -		compatible = "jedec,spi-nor";
 | |
| -		spi-max-frequency = <50000000>;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "qcom,smem-part";
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&mdio {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	pinctrl-0 = <&mdio_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
 | |
| -
 | |
| -	aqr113c_0: ethernet-phy@0 {
 | |
| -		compatible ="ethernet-phy-ieee802.3-c45";
 | |
| -		reg = <0>;
 | |
| -		reset-gpios = <&tlmm 59 GPIO_ACTIVE_LOW>;
 | |
| -	};
 | |
| -
 | |
| -	aqr113c_8: ethernet-phy@8 {
 | |
| -		compatible ="ethernet-phy-ieee802.3-c45";
 | |
| -		reg = <8>;
 | |
| -		reset-gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_16: ethernet-phy@16 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <16>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_17: ethernet-phy@17 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <17>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_18: ethernet-phy@18 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <18>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_19: ethernet-phy@19 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <19>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&sdhc_1 {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	/* According to the stock dts from the QNAP gpl drop
 | |
| -	 * the emmc has a problem with the hs400 > hs200 speed switch.
 | |
| -	 * Therefore remove the mmc-hs400-1_8v property
 | |
| -	*/
 | |
| -	/delete-property/ mmc-hs400-1_8v;
 | |
| -	mmc-hs200-1_8v;
 | |
| -	mmc-ddr-1_8v;
 | |
| -	vqmmc-supply = <&l11>;
 | |
| -};
 | |
| -
 | |
| -&switch {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	switch_cpu_bmp = <0x1>;  /* cpu port bitmap */
 | |
| -	switch_lan_bmp = <0x3e>; /* lan port bitmap */
 | |
| -	switch_wan_bmp = <0xc0>; /* wan port bitmap */
 | |
| -	switch_mac_mode = <0xb>; /* mac mode for uniphy instance0*/
 | |
| -	switch_mac_mode1 = <0xd>; /* mac mode for uniphy instance1*/
 | |
| -	switch_mac_mode2 = <0xd>; /* mac mode for uniphy instance2*/
 | |
| -	bm_tick_mode = <0>; /* bm tick mode */
 | |
| -	tm_tick_mode = <0>; /* tm tick mode */
 | |
| -
 | |
| -	qcom,port_phyinfo {
 | |
| -		port@0 {
 | |
| -			port_id = <1>;
 | |
| -			phy_address = <16>;
 | |
| -		};
 | |
| -		port@1 {
 | |
| -			port_id = <2>;
 | |
| -			phy_address = <17>;
 | |
| -		};
 | |
| -		port@2 {
 | |
| -			port_id = <3>;
 | |
| -			phy_address = <18>;
 | |
| -		};
 | |
| -		port@3 {
 | |
| -			port_id = <4>;
 | |
| -			phy_address = <19>;
 | |
| -		};
 | |
| -		port@4 {
 | |
| -			port_id = <5>;
 | |
| -			phy_address = <8>;
 | |
| -			compatible = "ethernet-phy-ieee802.3-c45";
 | |
| -			ethernet-phy-ieee802.3-c45;
 | |
| -		};
 | |
| -		port@5 {
 | |
| -			port_id = <6>;
 | |
| -			phy_address = <0>;
 | |
| -			compatible = "ethernet-phy-ieee802.3-c45";
 | |
| -			ethernet-phy-ieee802.3-c45;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&edma {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&dp1 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_16>;
 | |
| -	label = "lan4";
 | |
| -};
 | |
| -
 | |
| -&dp2 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_17>;
 | |
| -	label = "lan3";
 | |
| -};
 | |
| -
 | |
| -&dp3 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_18>;
 | |
| -	label = "lan2";
 | |
| -};
 | |
| -
 | |
| -&dp4 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_19>;
 | |
| -	label = "lan1";
 | |
| -};
 | |
| -
 | |
| -&dp5 {
 | |
| -	status = "okay";
 | |
| -	qcom,mactype = <1>;
 | |
| -	phy-handle = <&aqr113c_8>;
 | |
| -	label = "10g-1";
 | |
| -};
 | |
| -
 | |
| -&dp6_syn {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&aqr113c_0>;
 | |
| -	label = "10g-2";
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	qcom,ath11k-calibration-variant = "QNAP-301w";
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts
 | |
| deleted file mode 100644
 | |
| index 801aa05604..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-ax9000.dts
 | |
| +++ /dev/null
 | |
| @@ -1,522 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 | |
| -/* Copyright (c) 2021, Robert Marko <robimarko@gmail.com> */
 | |
| -
 | |
| -/dts-v1/;
 | |
| -
 | |
| -#include "ipq8074.dtsi"
 | |
| -#include "ipq8074-hk-cpu.dtsi"
 | |
| -#include "ipq8074-ess.dtsi"
 | |
| -#include <dt-bindings/gpio/gpio.h>
 | |
| -#include <dt-bindings/input/input.h>
 | |
| -#include <dt-bindings/leds/common.h>
 | |
| -
 | |
| -/ {
 | |
| -	model = "Xiaomi AX9000";
 | |
| -	compatible = "xiaomi,ax9000", "qcom,ipq8074";
 | |
| -
 | |
| -	aliases {
 | |
| -		serial0 = &blsp1_uart5;
 | |
| -		led-boot = &led_system_yellow;
 | |
| -		led-failsafe = &led_system_yellow;
 | |
| -		led-running = &led_system_blue;
 | |
| -		led-upgrade = &led_system_yellow;
 | |
| -		label-mac-device = &dp5;
 | |
| -	};
 | |
| -
 | |
| -	chosen {
 | |
| -		stdout-path = "serial0:115200n8";
 | |
| -		bootargs-append = " root=/dev/ubiblock0_0";
 | |
| -	};
 | |
| -
 | |
| -	keys {
 | |
| -		compatible = "gpio-keys";
 | |
| -
 | |
| -		reset {
 | |
| -			label = "reset";
 | |
| -			gpios = <&tlmm 47 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_RESTART>;
 | |
| -		};
 | |
| -
 | |
| -		wps {
 | |
| -			label = "wps"; /* Labeled Mesh on the device */
 | |
| -			gpios = <&tlmm 46 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_WPS_BUTTON>;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	leds {
 | |
| -		compatible = "gpio-leds";
 | |
| -
 | |
| -		led_system_blue: system-blue {
 | |
| -			label = "blue:system";
 | |
| -			gpios = <&tlmm 48 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_BLUE>;
 | |
| -		};
 | |
| -
 | |
| -		led_system_yellow: system-yellow {
 | |
| -			label = "yellow:system";
 | |
| -			gpios = <&tlmm 52 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_YELLOW>;
 | |
| -		};
 | |
| -
 | |
| -		network-yellow {
 | |
| -			label = "yellow:network";
 | |
| -			gpios = <&tlmm 50 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_YELLOW>;
 | |
| -		};
 | |
| -
 | |
| -		network-blue {
 | |
| -			label = "blue:network";
 | |
| -			gpios = <&tlmm 51 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_BLUE>;
 | |
| -		};
 | |
| -
 | |
| -		top-red {
 | |
| -			label = "red:top";
 | |
| -			gpios = <&tlmm 63 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_RED>;
 | |
| -			default-state = "keep";
 | |
| -		};
 | |
| -
 | |
| -		top-green {
 | |
| -			label = "green:top";
 | |
| -			gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_GREEN>;
 | |
| -			default-state = "keep";
 | |
| -		};
 | |
| -
 | |
| -		top-blue {
 | |
| -			label = "blue:top";
 | |
| -			gpios = <&tlmm 66 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_BLUE>;
 | |
| -			default-state = "keep";
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&tlmm {
 | |
| -	mdio_pins: mdio-pins {
 | |
| -		mdc {
 | |
| -			pins = "gpio68";
 | |
| -			function = "mdc";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		mdio {
 | |
| -			pins = "gpio69";
 | |
| -			function = "mdio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	i2c_pins: i2c-pins {
 | |
| -		pins = "gpio0", "gpio2";
 | |
| -		function = "blsp5_i2c";
 | |
| -		drive-strength = <8>;
 | |
| -		bias-disable;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&blsp1_uart5 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&blsp1_i2c6 {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	pinctrl-0 = <&i2c_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -};
 | |
| -
 | |
| -&prng {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&cryptobam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&crypto {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_bam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_nand {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	/*
 | |
| -	 * Bootloader will find the NAND DT node by the compatible and
 | |
| -	 * then "fixup" it by adding the partitions from the SMEM table
 | |
| -	 * using the legacy bindings thus making it impossible for us
 | |
| -	 * to change the partition table or utilize NVMEM for calibration.
 | |
| -	 * So add a dummy partitions node that bootloader will populate
 | |
| -	 * and set it as disabled so the kernel ignores it instead of
 | |
| -	 * printing warnings due to the broken way bootloader adds the
 | |
| -	 * partitions.
 | |
| -	 */
 | |
| -	partitions {
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -
 | |
| -	nand@0 {
 | |
| -		reg = <0>;
 | |
| -		nand-ecc-strength = <4>;
 | |
| -		nand-ecc-step-size = <512>;
 | |
| -		nand-bus-width = <8>;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "fixed-partitions";
 | |
| -			#address-cells = <1>;
 | |
| -			#size-cells = <1>;
 | |
| -
 | |
| -			partition@0 {
 | |
| -				label = "0:sbl1";
 | |
| -				reg = <0x0 0x100000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@100000 {
 | |
| -				label = "0:mibib";
 | |
| -				reg = <0x100000 0x100000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@200000 {
 | |
| -				label = "0:bootconfig";
 | |
| -				reg = <0x200000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@280000 {
 | |
| -				label = "0:bootconfig1";
 | |
| -				reg = <0x280000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@300000 {
 | |
| -				label = "0:qsee";
 | |
| -				reg = <0x300000 0x300000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@600000 {
 | |
| -				label = "0:qsee_1";
 | |
| -				reg = <0x600000 0x300000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@900000 {
 | |
| -				label = "0:devcfg";
 | |
| -				reg = <0x900000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@980000 {
 | |
| -				label = "0:devcfg_1";
 | |
| -				reg = <0x980000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@a00000 {
 | |
| -				label = "0:apdp";
 | |
| -				reg = <0xa00000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@a80000 {
 | |
| -				label = "0:apdp_1";
 | |
| -				reg = <0xa80000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@b00000 {
 | |
| -				label = "0:rpm";
 | |
| -				reg = <0xb00000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@b80000 {
 | |
| -				label = "0:rpm_1";
 | |
| -				reg = <0xb80000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@c00000 {
 | |
| -				label = "0:cdt";
 | |
| -				reg = <0xc00000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@c80000 {
 | |
| -				label = "0:cdt_1";
 | |
| -				reg = <0xc80000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@d00000 {
 | |
| -				label = "0:appsblenv";
 | |
| -				reg = <0xd00000 0x80000>;
 | |
| -			};
 | |
| -
 | |
| -			partition@d80000 {
 | |
| -				label = "0:appsbl";
 | |
| -				reg = <0xd80000 0x100000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@e80000 {
 | |
| -				label = "0:appsbl_1";
 | |
| -				reg = <0xe80000 0x100000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@f80000 {
 | |
| -				label = "0:art";
 | |
| -				reg = <0xf80000 0x80000>;
 | |
| -				read-only;
 | |
| -
 | |
| -				compatible = "nvmem-cells";
 | |
| -				#address-cells = <1>;
 | |
| -				#size-cells = <1>;
 | |
| -
 | |
| -				macaddr_dp1: macaddr@0 {
 | |
| -					reg = <0x0 0x6>;
 | |
| -				};
 | |
| -
 | |
| -				macaddr_dp2: macaddr@6 {
 | |
| -					reg = <0x6 0x6>;
 | |
| -				};
 | |
| -
 | |
| -				macaddr_dp3: macaddr@c {
 | |
| -					reg = <0xc 0x6>;
 | |
| -				};
 | |
| -
 | |
| -				macaddr_dp4: macaddr@12 {
 | |
| -					reg = <0x12 0x6>;
 | |
| -				};
 | |
| -
 | |
| -				macaddr_dp5: macaddr@18 {
 | |
| -					reg = <0x18 0x6>;
 | |
| -				};
 | |
| -
 | |
| -				caldata_qca9889: caldata@4d000 {
 | |
| -					reg = <0x4d000 0x844>;
 | |
| -				};
 | |
| -			};
 | |
| -
 | |
| -			partition@1000000 {
 | |
| -				label = "bdata";
 | |
| -				reg = <0x1000000 0x80000>;
 | |
| -			};
 | |
| -
 | |
| -			partition@1080000 {
 | |
| -				/* This is crash + crash_syslog parts combined */
 | |
| -				label = "pstore";
 | |
| -				reg = <0x1080000 0x100000>;
 | |
| -			};
 | |
| -
 | |
| -			partition@1180000 {
 | |
| -				label = "ubi_kernel";
 | |
| -				reg = <0x1180000 0x3800000>;
 | |
| -			};
 | |
| -
 | |
| -			partition@4980000 {
 | |
| -				label = "rootfs";
 | |
| -				reg = <0x4980000 0xb680000>;
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&qusb_phy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&ssphy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&usb_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&mdio {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	pinctrl-0 = <&mdio_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
 | |
| -
 | |
| -	qca8075_0: ethernet-phy@0 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <0>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_1: ethernet-phy@1 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <1>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_2: ethernet-phy@2 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <2>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_3: ethernet-phy@3 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <3>;
 | |
| -	};
 | |
| -
 | |
| -	qca8081: ethernet-phy@24 {
 | |
| -		compatible = "ethernet-phy-id004d.d101";
 | |
| -		reg = <24>;
 | |
| -		reset-gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&switch {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	switch_cpu_bmp = <0x1>;  /* cpu port bitmap */
 | |
| -	switch_lan_bmp = <0x1e>; /* lan port bitmap */
 | |
| -	switch_wan_bmp = <0x20>; /* wan port bitmap */
 | |
| -	switch_mac_mode = <0xb>; /* mac mode for uniphy instance0*/
 | |
| -	switch_mac_mode1 = <0xc>; /* mac mode for uniphy instance1*/
 | |
| -	switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
 | |
| -	bm_tick_mode = <0>; /* bm tick mode */
 | |
| -	tm_tick_mode = <0>; /* tm tick mode */
 | |
| -
 | |
| -	qcom,port_phyinfo {
 | |
| -		port@0 {
 | |
| -			port_id = <1>;
 | |
| -			phy_address = <0>;
 | |
| -		};
 | |
| -		port@1 {
 | |
| -			port_id = <2>;
 | |
| -			phy_address = <1>;
 | |
| -		};
 | |
| -		port@2 {
 | |
| -			port_id = <3>;
 | |
| -			phy_address = <2>;
 | |
| -		};
 | |
| -		port@3 {
 | |
| -			port_id = <4>;
 | |
| -			phy_address = <3>;
 | |
| -		};
 | |
| -		port@4 {
 | |
| -			port_id = <5>;
 | |
| -			phy_address = <24>;
 | |
| -			port_mac_sel = "QGMAC_PORT";
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&edma {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&dp1 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_0>;
 | |
| -	label = "lan4";
 | |
| -	nvmem-cells = <&macaddr_dp1>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp2 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_1>;
 | |
| -	label = "lan3";
 | |
| -	nvmem-cells = <&macaddr_dp2>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp3 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_2>;
 | |
| -	label = "lan2";
 | |
| -	nvmem-cells = <&macaddr_dp3>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp4 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_3>;
 | |
| -	label = "lan1";
 | |
| -	nvmem-cells = <&macaddr_dp4>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp5 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8081>;
 | |
| -	label = "wan";
 | |
| -	nvmem-cells = <&macaddr_dp5>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&pcie_qmp0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&pcie0 {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	perst-gpio = <&tlmm 58 GPIO_ACTIVE_LOW>;
 | |
| -
 | |
| -	bridge@0,0 {
 | |
| -		reg = <0x00000000 0 0 0 0>;
 | |
| -		#address-cells = <3>;
 | |
| -		#size-cells = <2>;
 | |
| -		ranges;
 | |
| -
 | |
| -		wifi@1,0 {
 | |
| -			status = "okay";
 | |
| -
 | |
| -			/* ath11k has no DT compatible for PCI cards */
 | |
| -			compatible = "pci17cb,1104";
 | |
| -			reg = <0x00010000 0 0 0 0>;
 | |
| -
 | |
| -			qcom,ath11k-calibration-variant = "Xiaomi-AX9000";
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&pcie_qmp1 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&pcie1 {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	perst-gpio = <&tlmm 62 GPIO_ACTIVE_HIGH>;
 | |
| -
 | |
| -	bridge@1,0 {
 | |
| -		reg = <0x00010000 0 0 0 0>;
 | |
| -		#address-cells = <3>;
 | |
| -		#size-cells = <2>;
 | |
| -		ranges;
 | |
| -
 | |
| -		wifi@1,0 {
 | |
| -			status = "okay";
 | |
| -
 | |
| -			compatible = "qcom,ath10k";
 | |
| -			reg = <0x00010000 0 0 0 0>;
 | |
| -
 | |
| -			qcom,ath10k-calibration-variant = "Xiaomi-AX9000";
 | |
| -			nvmem-cell-names = "calibration";
 | |
| -			nvmem-cells = <&caldata_qca9889>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	qcom,ath11k-calibration-variant = "Xiaomi-AX9000";
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts
 | |
| deleted file mode 100644
 | |
| index 5468e9e1fb..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-dl-wrx36.dts
 | |
| +++ /dev/null
 | |
| @@ -1,243 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 | |
| -/* Copyright (c) 2022, Robert Marko <robimarko@gmail.com> */
 | |
| -
 | |
| -/dts-v1/;
 | |
| -
 | |
| -#include "ipq8074.dtsi"
 | |
| -#include "ipq8074-hk-cpu.dtsi"
 | |
| -#include "ipq8074-ess.dtsi"
 | |
| -#include <dt-bindings/gpio/gpio.h>
 | |
| -#include <dt-bindings/input/input.h>
 | |
| -#include <dt-bindings/leds/common.h>
 | |
| -
 | |
| -/ {
 | |
| -	model = "Dynalink DL-WRX36";
 | |
| -	compatible = "dynalink,dl-wrx36", "qcom,ipq8074";
 | |
| -
 | |
| -	aliases {
 | |
| -		led-boot = &led_system_red;
 | |
| -		led-failsafe = &led_system_red;
 | |
| -		led-running = &led_system_blue;
 | |
| -		led-upgrade = &led_system_red;
 | |
| -		serial0 = &blsp1_uart5;
 | |
| -		/* Aliases as required by u-boot to patch MAC addresses */
 | |
| -		ethernet0 = &dp6_syn;
 | |
| -		ethernet1 = &dp4;
 | |
| -		ethernet2 = &dp3;
 | |
| -		ethernet3 = &dp2;
 | |
| -		ethernet4 = &dp1;
 | |
| -		label-mac-device = &dp6_syn;
 | |
| -	};
 | |
| -
 | |
| -	chosen {
 | |
| -		stdout-path = "serial0:115200n8";
 | |
| -		bootargs-append = " root=/dev/ubiblock0_1";
 | |
| -	};
 | |
| -
 | |
| -	keys {
 | |
| -		compatible = "gpio-keys";
 | |
| -
 | |
| -		reset {
 | |
| -			label = "reset";
 | |
| -			gpios = <&tlmm 34 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_RESTART>;
 | |
| -		};
 | |
| -
 | |
| -		wps {
 | |
| -			label = "wps";
 | |
| -			gpios = <&tlmm 63 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_WPS_BUTTON>;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	leds {
 | |
| -		compatible = "gpio-leds";
 | |
| -
 | |
| -		led_system_blue: system-blue {
 | |
| -			label = "blue:system";
 | |
| -			gpios = <&tlmm 26 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_BLUE>;
 | |
| -		};
 | |
| -
 | |
| -		led_system_red: system-red {
 | |
| -			label = "red:system";
 | |
| -			gpios = <&tlmm 25 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_RED>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&tlmm {
 | |
| -	mdio_pins: mdio-pins {
 | |
| -		mdc {
 | |
| -			pins = "gpio68";
 | |
| -			function = "mdc";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		mdio {
 | |
| -			pins = "gpio69";
 | |
| -			function = "mdio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&blsp1_uart5 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&prng {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&cryptobam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&crypto {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_bam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_nand {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	nand@0 {
 | |
| -		reg = <0>;
 | |
| -		nand-ecc-strength = <8>;
 | |
| -		nand-ecc-step-size = <512>;
 | |
| -		nand-bus-width = <8>;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "qcom,smem-part";
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&qusb_phy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&ssphy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&usb_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&mdio {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	pinctrl-0 = <&mdio_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
 | |
| -
 | |
| -	qca8075_0: ethernet-phy@0 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <0>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_1: ethernet-phy@1 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <1>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_2: ethernet-phy@2 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <2>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_3: ethernet-phy@3 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <3>;
 | |
| -	};
 | |
| -
 | |
| -	qca8081: ethernet-phy@28 {
 | |
| -		compatible = "ethernet-phy-id004d.d101";
 | |
| -		reg = <28>;
 | |
| -		reset-gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&switch {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	switch_cpu_bmp = <0x1>;  /* cpu port bitmap */
 | |
| -	switch_lan_bmp = <0x3e>; /* lan port bitmap */
 | |
| -	switch_wan_bmp = <0x40>; /* wan port bitmap */
 | |
| -	switch_mac_mode = <0xb>; /* mac mode for uniphy instance0*/
 | |
| -	switch_mac_mode1 = <0xff>; /* mac mode for uniphy instance1*/
 | |
| -	switch_mac_mode2 = <0xc>; /* mac mode for uniphy instance2*/
 | |
| -	bm_tick_mode = <0>; /* bm tick mode */
 | |
| -	tm_tick_mode = <0>; /* tm tick mode */
 | |
| -
 | |
| -	qcom,port_phyinfo {
 | |
| -		port@0 {
 | |
| -			port_id = <1>;
 | |
| -			phy_address = <0>;
 | |
| -		};
 | |
| -		port@1 {
 | |
| -			port_id = <2>;
 | |
| -			phy_address = <1>;
 | |
| -		};
 | |
| -		port@2 {
 | |
| -			port_id = <3>;
 | |
| -			phy_address = <2>;
 | |
| -		};
 | |
| -		port@3 {
 | |
| -			port_id = <4>;
 | |
| -			phy_address = <3>;
 | |
| -		};
 | |
| -		port@5 {
 | |
| -			port_id = <6>;
 | |
| -			phy_address = <28>;
 | |
| -			port_mac_sel = "QGMAC_PORT";
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&edma {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&dp1 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_0>;
 | |
| -	label = "lan4";
 | |
| -};
 | |
| -
 | |
| -&dp2 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_1>;
 | |
| -	label = "lan3";
 | |
| -};
 | |
| -
 | |
| -&dp3 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_2>;
 | |
| -	label = "lan2";
 | |
| -};
 | |
| -
 | |
| -&dp4 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_3>;
 | |
| -	label = "lan1";
 | |
| -};
 | |
| -
 | |
| -&dp6_syn {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8081>;
 | |
| -	label = "wan";
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	status = "okay";
 | |
| -	qcom,ath11k-calibration-variant = "Dynalink-DL-WRX36";
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts
 | |
| deleted file mode 100644
 | |
| index 8a5200b4eb..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-haze.dts
 | |
| +++ /dev/null
 | |
| @@ -1,308 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 | |
| -
 | |
| -/dts-v1/;
 | |
| -
 | |
| -#include "ipq8074.dtsi"
 | |
| -#include "ipq8074-hk-cpu.dtsi"
 | |
| -#include "ipq8074-ess.dtsi"
 | |
| -#include <dt-bindings/gpio/gpio.h>
 | |
| -#include <dt-bindings/input/input.h>
 | |
| -#include <dt-bindings/leds/common.h>
 | |
| -
 | |
| -/ {
 | |
| -	model = "prpl Foundation Haze";
 | |
| -	compatible = "prpl,haze", "qcom,ipq8074";
 | |
| -
 | |
| -	aliases {
 | |
| -		serial0 = &blsp1_uart5;
 | |
| -		/* Aliases are required by U-Boot to patch MAC addresses */
 | |
| -		ethernet0 = &dp6_syn;
 | |
| -		ethernet1 = &dp4;
 | |
| -		ethernet2 = &dp3;
 | |
| -		ethernet3 = &dp2;
 | |
| -		label-mac-device = &dp6_syn;
 | |
| -	};
 | |
| -
 | |
| -	chosen {
 | |
| -		stdout-path = "serial0:115200n8";
 | |
| -	};
 | |
| -
 | |
| -	keys {
 | |
| -		compatible = "gpio-keys";
 | |
| -		pinctrl-0 = <&button_pins>;
 | |
| -		pinctrl-names = "default";
 | |
| -
 | |
| -		wps-button {
 | |
| -			label = "wps";
 | |
| -			gpios = <&tlmm 42 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_WPS_BUTTON>;
 | |
| -		};
 | |
| -
 | |
| -		reset-button {
 | |
| -			label = "reset";
 | |
| -			gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_RESTART>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&tlmm {
 | |
| -	mdio_pins: mdio-state {
 | |
| -		mdc-pins {
 | |
| -			pins = "gpio68";
 | |
| -			function = "mdc";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		mdio-pins {
 | |
| -			pins = "gpio69";
 | |
| -			function = "mdio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	button_pins: button-state {
 | |
| -		wps-pins {
 | |
| -			pins = "gpio42";
 | |
| -			function = "gpio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		rst-pins {
 | |
| -			pins = "gpio44";
 | |
| -			function = "gpio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&blsp1_uart5 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&prng {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&ssphy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qusb_phy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&ssphy_1 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qusb_phy_1 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&usb_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&usb_1 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&cryptobam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&crypto {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_bam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&blsp1_spi1 { /* BLSP1 QUP1 */
 | |
| -	pinctrl-0 = <&spi_0_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	cs-gpios = <0>;
 | |
| -	status = "okay";
 | |
| -
 | |
| -	flash@0 {
 | |
| -		#address-cells = <1>;
 | |
| -		#size-cells = <1>;
 | |
| -		reg = <0>;
 | |
| -		compatible = "jedec,spi-nor";
 | |
| -		spi-max-frequency = <50000000>;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "qcom,smem-part";
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&mdio {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	pinctrl-0 = <&mdio_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	reset-gpios = <&tlmm 22 GPIO_ACTIVE_LOW>;
 | |
| -
 | |
| -	qca8075_1: ethernet-phy@0 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <0>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_2: ethernet-phy@1 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <1>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_3: ethernet-phy@2 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <2>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_4: ethernet-phy@3 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <3>;
 | |
| -	};
 | |
| -
 | |
| -	aqr113c: ethernet-phy@5 {
 | |
| -		compatible ="ethernet-phy-ieee802.3-c45";
 | |
| -		reg = <8>;
 | |
| -		reset-gpios = <&tlmm 43 GPIO_ACTIVE_LOW>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&sdhc_1 {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	vqmmc-supply = <&l11>;
 | |
| -};
 | |
| -
 | |
| -&switch {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	switch_cpu_bmp = <0x1>;  /* cpu port bitmap */
 | |
| -	switch_lan_bmp = <0x1e>; /* lan port bitmap */
 | |
| -	switch_wan_bmp = <0x60>; /* wan port bitmap */
 | |
| -	switch_mac_mode = <0x0>; /* mac mode for uniphy instance0*/
 | |
| -	switch_mac_mode1 = <0xe>; /* mac mode for uniphy instance1*/
 | |
| -	switch_mac_mode2 = <0xd>; /* mac mode for uniphy instance2*/
 | |
| -	bm_tick_mode = <0>; /* bm tick mode */
 | |
| -	tm_tick_mode = <0>; /* tm tick mode */
 | |
| -
 | |
| -	qcom,port_phyinfo {
 | |
| -		port@0 {
 | |
| -			port_id = <1>;
 | |
| -			phy_address = <0>;
 | |
| -		};
 | |
| -		port@1 {
 | |
| -			port_id = <2>;
 | |
| -			phy_address = <1>;
 | |
| -		};
 | |
| -		port@2 {
 | |
| -			port_id = <3>;
 | |
| -			phy_address = <2>;
 | |
| -		};
 | |
| -		port@3 {
 | |
| -			port_id = <4>;
 | |
| -			phy_address = <3>;
 | |
| -		};
 | |
| -		port@4 {
 | |
| -			port_id = <6>;
 | |
| -			phy_address = <8>;
 | |
| -			compatible = "ethernet-phy-ieee802.3-c45";
 | |
| -			ethernet-phy-ieee802.3-c45;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&edma {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -/* Dummy LAN port */
 | |
| -&dp1 {
 | |
| -	status = "disabled";
 | |
| -	phy-handle = <&qca8075_1>;
 | |
| -	label = "lan4";
 | |
| -};
 | |
| -
 | |
| -&dp2 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_2>;
 | |
| -	label = "lan3";
 | |
| -};
 | |
| -
 | |
| -&dp3 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_3>;
 | |
| -	label = "lan2";
 | |
| -};
 | |
| -
 | |
| -&dp4 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_4>;
 | |
| -	label = "lan1";
 | |
| -};
 | |
| -
 | |
| -&dp6_syn {
 | |
| -	status = "okay";
 | |
| -	qcom,mactype = <1>;
 | |
| -	phy-handle = <&aqr113c>;
 | |
| -	label = "wan";
 | |
| -};
 | |
| -
 | |
| -&pcie_qmp0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&pcie0 {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	perst-gpio = <&tlmm 58 GPIO_ACTIVE_LOW>;
 | |
| -
 | |
| -	bridge@0,0 {
 | |
| -		reg = <0x00020000 0 0 0 0>;
 | |
| -		#address-cells = <3>;
 | |
| -		#size-cells = <2>;
 | |
| -		ranges;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&pcie_qmp1 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&pcie1 {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	perst-gpio = <&tlmm 61 GPIO_ACTIVE_LOW>;
 | |
| -
 | |
| -	bridge@1,0 {
 | |
| -		reg = <0x00010000 0 0 0 0>;
 | |
| -		#address-cells = <3>;
 | |
| -		#size-cells = <2>;
 | |
| -		ranges;
 | |
| -
 | |
| -		wifi@1,0 {
 | |
| -			status = "okay";
 | |
| -
 | |
| -			/* ath11k has no DT compatible for PCI cards */
 | |
| -			compatible = "pci17cb,1104";
 | |
| -			reg = <0x00010000 0 0 0 0>;
 | |
| -
 | |
| -			qcom,ath11k-calibration-variant = "prpl-Haze";
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	qcom,ath11k-calibration-variant = "prpl-Haze";
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts
 | |
| deleted file mode 100644
 | |
| index 5bfcdcc8ca..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8072-wax218.dts
 | |
| +++ /dev/null
 | |
| @@ -1,191 +0,0 @@
 | |
| -/dts-v1/;
 | |
| -
 | |
| -#include "ipq8074.dtsi"
 | |
| -#include "ipq8074-hk-cpu.dtsi"
 | |
| -#include "ipq8074-ess.dtsi"
 | |
| -
 | |
| -#include <dt-bindings/input/input.h>
 | |
| -#include <dt-bindings/gpio/gpio.h>
 | |
| -
 | |
| -/ {
 | |
| -	model = "Netgear WAX218";
 | |
| -	compatible = "netgear,wax218", "qcom,ipq8074";
 | |
| -
 | |
| -	aliases {
 | |
| -		serial0 = &blsp1_uart5;
 | |
| -		led-boot = &led_power_amber;
 | |
| -		led-failsafe = &led_power_amber;
 | |
| -		led-running = &led_power_amber;
 | |
| -		led-upgrade = &led_power_amber;
 | |
| -	};
 | |
| -
 | |
| -	chosen {
 | |
| -		stdout-path = "serial0:115200n8";
 | |
| -		/*
 | |
| -		 * Netgear's U-Boot adds "ubi.mtd=rootfs root=mtd:ubi_rootfs"
 | |
| -		 * That fails to create a UBI block device, so add it here.
 | |
| -		*/
 | |
| -		bootargs-append = " ubi.block=0,rootfs root=/dev/ubiblock0_1";
 | |
| -	};
 | |
| -
 | |
| -	keys {
 | |
| -		compatible = "gpio-keys";
 | |
| -
 | |
| -		reset {
 | |
| -			label = "reset";
 | |
| -			gpios = <&tlmm 52 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_RESTART>;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	led_spi {
 | |
| -		compatible = "spi-gpio";
 | |
| -		#address-cells = <1>;
 | |
| -		#size-cells = <0>;
 | |
| -
 | |
| -		sck-gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>;
 | |
| -		mosi-gpios = <&tlmm 19 GPIO_ACTIVE_HIGH>;
 | |
| -
 | |
| -		led_gpio: led_gpio@0 {
 | |
| -			compatible = "fairchild,74hc595";
 | |
| -			reg = <0>;
 | |
| -			gpio-controller;
 | |
| -			#gpio-cells = <2>;
 | |
| -			registers-number = <1>;
 | |
| -			enable-gpios = <&tlmm 20 GPIO_ACTIVE_HIGH>;
 | |
| -			spi-max-frequency = <1000000>;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	leds {
 | |
| -		compatible = "gpio-leds";
 | |
| -
 | |
| -		led_power_amber: led_power {
 | |
| -			label = "amber:power";
 | |
| -			gpios = <&led_gpio 1 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		led_lan {
 | |
| -			label = "blue:lan";
 | |
| -			gpios = <&led_gpio 2 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		led_wlan_2g {
 | |
| -			label = "blue:wlan2g";
 | |
| -			gpios = <&led_gpio 3 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -
 | |
| -		led_wlan_5g {
 | |
| -			label = "blue:wlan5g";
 | |
| -			gpios = <&led_gpio 4 GPIO_ACTIVE_HIGH>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&edma {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&switch {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	switch_cpu_bmp = <0x1>;
 | |
| -	switch_lan_bmp = <0x3e>;
 | |
| -	switch_wan_bmp = <0x40>;
 | |
| -	switch_mac_mode = <0x00>;
 | |
| -	switch_mac_mode1 = <0xff>;
 | |
| -	switch_mac_mode2 = <0x0f>;
 | |
| -	bm_tick_mode = <0>;
 | |
| -	tm_tick_mode = <0>;
 | |
| -
 | |
| -	qcom,port_phyinfo {
 | |
| -		port@5 {
 | |
| -			port_id = <6>;
 | |
| -			phy_address = <28>;
 | |
| -			port_mac_sel = "QGMAC_PORT";
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&tlmm {
 | |
| -	mdio_pins: mdio-pins {
 | |
| -		mdc {
 | |
| -			pins = "gpio68";
 | |
| -			function = "mdc";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		mdio {
 | |
| -			pins = "gpio69";
 | |
| -			function = "mdio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&mdio {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	pinctrl-0 = <&mdio_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	reset-gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
 | |
| -
 | |
| -	qca8081_28: ethernet-phy@28 {
 | |
| -		reg = <28>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&dp6_syn {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8081_28>;
 | |
| -	label = "lan";
 | |
| -	nvmem-cells = <&macaddr_ubootenv_ethaddr>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&qpic_bam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_nand {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	nand@0 {
 | |
| -		reg = <0>;
 | |
| -		nand-ecc-strength = <4>;
 | |
| -		nand-ecc-step-size = <512>;
 | |
| -		nand-bus-width = <8>;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "qcom,smem-part";
 | |
| -
 | |
| -			partition-0-appsblenv {
 | |
| -				compatible = "fixed-partitions";
 | |
| -				label = "0:appsblenv";
 | |
| -				read-only;
 | |
| -				#address-cells = <1>;
 | |
| -				#size-cells = <1>;
 | |
| -
 | |
| -				partition@0 {
 | |
| -					compatible = "u-boot,env";
 | |
| -					label = "env-data";
 | |
| -					reg = <0x0 0x40000>;
 | |
| -
 | |
| -					macaddr_ubootenv_ethaddr: ethaddr {};
 | |
| -				};
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&blsp1_uart5 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	qcom,ath11k-calibration-variant = "Netgear-WAX218";
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-512m.dtsi b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-512m.dtsi
 | |
| deleted file mode 100644
 | |
| index dace4008b3..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-512m.dtsi
 | |
| +++ /dev/null
 | |
| @@ -1,19 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-only
 | |
| -
 | |
| -#include "ipq8074.dtsi"
 | |
| -
 | |
| -&tzapp_region {
 | |
| -	reg = <0x0 0x4a400000 0x0 0x100000>;
 | |
| -};
 | |
| -
 | |
| -&q6_region {
 | |
| -	reg = <0x0 0x4b000000 0x0 0x3700000>;
 | |
| -};
 | |
| -
 | |
| -&q6_etr_region {
 | |
| -	reg = <0x0 0x4e700000 0x0 0x100000>;
 | |
| -};
 | |
| -
 | |
| -&m3_dump_region {
 | |
| -	reg = <0x0 0x4e800000 0x0 0x100000>;
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-ac-cpu.dtsi b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-ac-cpu.dtsi
 | |
| deleted file mode 100644
 | |
| index dbc9baa2b9..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-ac-cpu.dtsi
 | |
| +++ /dev/null
 | |
| @@ -1,153 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-only
 | |
| -
 | |
| -#include <dt-bindings/thermal/thermal.h>
 | |
| -#include "ipq8074-cpr-regulator.dtsi"
 | |
| -
 | |
| -&CPU0 {
 | |
| -	cpu-supply = <&apc_vreg>;
 | |
| -	voltage-tolerance = <1>;
 | |
| -};
 | |
| -
 | |
| -&CPU1 {
 | |
| -	cpu-supply = <&apc_vreg>;
 | |
| -	voltage-tolerance = <1>;
 | |
| -};
 | |
| -
 | |
| -&CPU2 {
 | |
| -	cpu-supply = <&apc_vreg>;
 | |
| -	voltage-tolerance = <1>;
 | |
| -};
 | |
| -
 | |
| -&CPU3 {
 | |
| -	cpu-supply = <&apc_vreg>;
 | |
| -	voltage-tolerance = <1>;
 | |
| -};
 | |
| -&cpu0_thermal {
 | |
| -	trips {
 | |
| -		cpu0_passive: cpu-passive {
 | |
| -			temperature = <95000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu0_crit: cpu_crit {
 | |
| -			temperature = <110000>;
 | |
| -			hysteresis = <1000>;
 | |
| -			type = "critical";
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	cooling-maps {
 | |
| -		map0 {
 | |
| -			trip = <&cpu0_passive>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&cpu1_thermal {
 | |
| -	trips {
 | |
| -		cpu1_passive: cpu-passive {
 | |
| -			temperature = <95000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu1_crit: cpu_crit {
 | |
| -			temperature = <110000>;
 | |
| -			hysteresis = <1000>;
 | |
| -			type = "critical";
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	cooling-maps {
 | |
| -		map0 {
 | |
| -			trip = <&cpu1_passive>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&cpu2_thermal {
 | |
| -	trips {
 | |
| -		cpu2_passive: cpu-passive {
 | |
| -			temperature = <95000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu2_crit: cpu_crit {
 | |
| -			temperature = <110000>;
 | |
| -			hysteresis = <1000>;
 | |
| -			type = "critical";
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	cooling-maps {
 | |
| -		map0 {
 | |
| -			trip = <&cpu2_passive>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&cpu3_thermal {
 | |
| -	trips {
 | |
| -		cpu3_passive: cpu-passive {
 | |
| -			temperature = <95000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu3_crit: cpu_crit {
 | |
| -			temperature = <110000>;
 | |
| -			hysteresis = <1000>;
 | |
| -			type = "critical";
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	cooling-maps {
 | |
| -		map0 {
 | |
| -			trip = <&cpu3_passive>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&cluster_thermal {
 | |
| -	trips {
 | |
| -		cluster_passive: cluster-passive {
 | |
| -			temperature = <95000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cluster_crit: cluster_crit {
 | |
| -			temperature = <110000>;
 | |
| -			hysteresis = <1000>;
 | |
| -			type = "critical";
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	cooling-maps {
 | |
| -		map0 {
 | |
| -			trip = <&cluster_passive>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-cpr-regulator.dtsi b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-cpr-regulator.dtsi
 | |
| deleted file mode 100644
 | |
| index e351a2e759..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-cpr-regulator.dtsi
 | |
| +++ /dev/null
 | |
| @@ -1,228 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-only
 | |
| -
 | |
| -#include "pmp8074.dtsi"
 | |
| -
 | |
| -&soc {
 | |
| -	apc_apm: apm@b111000 {
 | |
| -		compatible = "qcom,ipq807x-apm";
 | |
| -		reg = <0xb111000 0x1000>;
 | |
| -		reg-names = "pm-apcc-glb";
 | |
| -		qcom,apm-post-halt-delay = <0x2>;
 | |
| -		qcom,apm-halt-clk-delay = <0x11>;
 | |
| -		qcom,apm-resume-clk-delay = <0x10>;
 | |
| -		qcom,apm-sel-switch-delay = <0x01>;
 | |
| -	};
 | |
| -
 | |
| -	apc_cpr: cpr4-ctrl@b018000 {
 | |
| -		compatible = "qcom,cpr4-ipq807x-apss-regulator";
 | |
| -		reg = <0xb018000 0x4000>, <0xa4000 0x1000>, <0x0193d008 0x4>;
 | |
| -		reg-names = "cpr_ctrl", "fuse_base", "cpr_tcsr_reg";
 | |
| -		interrupts = <GIC_SPI 15 IRQ_TYPE_EDGE_RISING>;
 | |
| -		interrupt-names = "cpr";
 | |
| -		qcom,cpr-ctrl-name = "apc";
 | |
| -		qcom,cpr-sensor-time = <1000>;
 | |
| -		qcom,cpr-loop-time = <5000000>;
 | |
| -		qcom,cpr-idle-cycles = <15>;
 | |
| -		qcom,cpr-step-quot-init-min = <12>;
 | |
| -		qcom,cpr-step-quot-init-max = <14>;
 | |
| -		qcom,cpr-count-mode = <0>;		/* All-at-once */
 | |
| -		qcom,cpr-count-repeat = <14>;
 | |
| -		qcom,cpr-down-error-step-limit = <1>;
 | |
| -		qcom,cpr-up-error-step-limit = <1>;
 | |
| -		qcom,apm-ctrl = <&apc_apm>;
 | |
| -		qcom,apm-threshold-voltage = <848000>;
 | |
| -		vdd-supply = <&s3>;
 | |
| -		qcom,voltage-step = <8000>;
 | |
| -
 | |
| -		thread@0 {
 | |
| -			qcom,cpr-thread-id = <0>;
 | |
| -			qcom,cpr-consecutive-up = <0>;
 | |
| -			qcom,cpr-consecutive-down = <0>;
 | |
| -			qcom,cpr-up-threshold = <4>;
 | |
| -			qcom,cpr-down-threshold = <1>;
 | |
| -
 | |
| -			apc_vreg: regulator {
 | |
| -				regulator-name = "apc_corner";
 | |
| -				regulator-min-microvolt = <1>;
 | |
| -				regulator-max-microvolt = <6>;
 | |
| -				qcom,cpr-part-types = <2>;
 | |
| -				qcom,cpr-parts-voltage = <1048000>;
 | |
| -				qcom,cpr-parts-voltage-v2 = <992000>;
 | |
| -				qcom,cpr-fuse-corners = <4>;
 | |
| -				qcom,cpr-fuse-combos = <8>;
 | |
| -				qcom,cpr-corners = <6>;
 | |
| -				qcom,cpr-speed-bins = <1>;
 | |
| -				qcom,cpr-speed-bin-corners = <6>;
 | |
| -				qcom,cpr-corner-fmax-map = <1 3 5 6>;
 | |
| -				qcom,allow-voltage-interpolation;
 | |
| -				qcom,allow-quotient-interpolation;
 | |
| -				qcom,cpr-scaled-open-loop-voltage-as-ceiling;
 | |
| -				qcom,cpr-voltage-ceiling =
 | |
| -					<840000 904000 944000
 | |
| -					 984000 992000 1064000>;
 | |
| -				qcom,cpr-voltage-floor =
 | |
| -					<592000 648000 712000
 | |
| -					 744000 784000 848000>;
 | |
| -				qcom,corner-frequencies =
 | |
| -					<1017600000 1382400000 1651200000
 | |
| -					1843200000 1920000000 2208000000>;
 | |
| -
 | |
| -				/* TT/FF parts i.e. turbo L1 OL voltage < 1048 mV */
 | |
| -				qcom,cpr-open-loop-voltage-fuse-adjustment-0 =
 | |
| -					/* Speed bin 0; CPR rev 0..7 */
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0 12000>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>;
 | |
| -
 | |
| -				/* SS parts i.e turbo L1 OL voltage >= 1048 mV */
 | |
| -				qcom,cpr-open-loop-voltage-fuse-adjustment-1 =
 | |
| -					/* Speed bin 0; CPR rev 0..7 */
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					< 20000  26000      0 20000>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>;
 | |
| -
 | |
| -				/* v2 - FF parts i.e. turbo L1 OL voltage < 992 mV */
 | |
| -				qcom,cpr-open-loop-voltage-fuse-adjustment-v2-0 =
 | |
| -                                        /* Speed bin 0; CPR rev 0..7 */
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>;
 | |
| -
 | |
| -				/* v2 - SS/TT parts i.e turbo L1 OL voltage >= 992 mV */
 | |
| -				qcom,cpr-open-loop-voltage-fuse-adjustment-v2-1 =
 | |
| -					/* Speed bin 0; CPR rev 0..7 */
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0   7000  36000  4000>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>;
 | |
| -
 | |
| -				/* v2 - FF parts i.e. turbo L1 OL voltage < 992 mV */
 | |
| -				qcom,cpr-closed-loop-voltage-adjustment-v2-0 =
 | |
| -					/* Speed bin 0; CPR rev 0..7 */
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>;
 | |
| -
 | |
| -				/* v2 - SS/TT parts i.e turbo L1 OL voltage >= 992 mV */
 | |
| -				qcom,cpr-closed-loop-voltage-adjustment-v2-1 =
 | |
| -					/* Speed bin 0; CPR rev 0..7 */
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      19000 0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>,
 | |
| -					<     0      0      0     0>;
 | |
| -
 | |
| -				qcom,cpr-ro-scaling-factor =
 | |
| -					< 3970 4150 0    2280 2520 2470 2250 2280
 | |
| -					  2390 2330 2530 2500  850 2900 2510 2170 >,
 | |
| -					< 3970 4150 0    2280 2520 2470 2250 2280
 | |
| -					  2390 2330 2530 2500  850 2900 2510 2170 >,
 | |
| -					< 3970 4150 0    2280 2520 2470 2250 2280
 | |
| -					  2390 2330 2530 2500  850 2900 2510 2170 >,
 | |
| -					< 3970 4150 0    2280 2520 2470 2250 2280
 | |
| -					  2390 2330 2530 2500  850 2900 2510 2170 >;
 | |
| -
 | |
| -				qcom,cpr-floor-to-ceiling-max-range =
 | |
| -					< 40000 40000 40000 40000 40000 40000>,
 | |
| -					< 40000 40000 40000 40000 40000 40000>,
 | |
| -					< 40000 40000 40000 40000 40000 40000>,
 | |
| -					< 40000 40000 40000 40000 40000 40000>,
 | |
| -					< 40000 40000 40000 40000 40000 40000>,
 | |
| -					< 40000 40000 40000 40000 40000 40000>,
 | |
| -					< 40000 40000 40000 40000 40000 40000>,
 | |
| -					< 40000 40000 40000 40000 40000 40000>;
 | |
| -				regulator-always-on;
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	npu_cpr: npu-cpr {
 | |
| -		compatible = "qcom,cpr3-ipq807x-npu-regulator";
 | |
| -		reg = <0xa4000 0x1000>, <0x0193d008 0x4>;
 | |
| -		reg-names = "fuse_base", "cpr_tcsr_reg";
 | |
| -		qcom,cpr-ctrl-name = "npu";
 | |
| -		vdd-supply = <&s4>;
 | |
| -		qcom,voltage-step = <8000>;
 | |
| -		thread@0 {
 | |
| -			qcom,cpr-thread-id = <0>;
 | |
| -			qcom,cpr-consecutive-up = <0>;
 | |
| -			qcom,cpr-consecutive-down = <2>;
 | |
| -			qcom,cpr-up-threshold = <2>;
 | |
| -			qcom,cpr-down-threshold = <1>;
 | |
| -
 | |
| -			npu_vreg: regulator {
 | |
| -				regulator-name = "npu_corner";
 | |
| -				regulator-min-microvolt = <1>;
 | |
| -				regulator-max-microvolt = <3>;
 | |
| -				qcom,cpr-part-types = <2>;
 | |
| -				qcom,cpr-parts-voltage = <968000>;
 | |
| -				qcom,cpr-parts-voltage-v2 = <832001>;
 | |
| -				qcom,cpr-cold-temp-threshold-v2 = <30>;
 | |
| -				qcom,cpr-fuse-corners = <2>;
 | |
| -				qcom,cpr-fuse-combos = <1>;
 | |
| -				qcom,cpr-corners = <2>;
 | |
| -				qcom,cpr-speed-bins = <1>;
 | |
| -				qcom,cpr-speed-bin-corners = <2>;
 | |
| -				qcom,allow-voltage-interpolation;
 | |
| -				qcom,cpr-corner-fmax-map = <1 2>;
 | |
| -				qcom,cpr-voltage-ceiling =
 | |
| -					<912000 992000>;
 | |
| -				qcom,cpr-voltage-floor =
 | |
| -					<752000 792000>;
 | |
| -				qcom,corner-frequencies =
 | |
| -					<1497600000 1689600000>;
 | |
| -
 | |
| -				/* TT/FF parts i.e. turbo OL voltage < 968 mV */
 | |
| -				qcom,cpr-open-loop-voltage-fuse-adjustment-0 =
 | |
| -					< 40000   40000>;
 | |
| -
 | |
| -				/* SS parts i.e turbo OL voltage >= 968 mV */
 | |
| -				qcom,cpr-open-loop-voltage-fuse-adjustment-1 =
 | |
| -					< 24000   24000>;
 | |
| -
 | |
| -				/* FF parts i.e. turbo OL voltage <= 832 mV */
 | |
| -				qcom,cpr-open-loop-voltage-fuse-adjustment-v2-0=
 | |
| -					<40000   40000>;
 | |
| -
 | |
| -				 /* TT/SS parts i.e turbo OL voltage > 832 mV */
 | |
| -				qcom,cpr-open-loop-voltage-fuse-adjustment-v2-1=
 | |
| -					<40000   40000>;
 | |
| -
 | |
| -				/* FF parts i.e. turbo OL voltage <= 832 mV */
 | |
| -				qcom,cpr-cold-temp-voltage-adjustment-v2-0 =
 | |
| -					<0   0>;
 | |
| -
 | |
| -				/* TT/SS parts i.e turbo OL voltage > 832 mV */
 | |
| -				qcom,cpr-cold-temp-voltage-adjustment-v2-1 =
 | |
| -					<35000   27000>;
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi
 | |
| deleted file mode 100644
 | |
| index 129266c50d..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-ess.dtsi
 | |
| +++ /dev/null
 | |
| @@ -1,531 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-only
 | |
| -
 | |
| -&clocks {
 | |
| -	bias_pll_cc_clk {
 | |
| -		compatible = "fixed-clock";
 | |
| -		clock-frequency = <300000000>;
 | |
| -		#clock-cells = <0>;
 | |
| -	};
 | |
| -
 | |
| -	bias_pll_nss_noc_clk {
 | |
| -		compatible = "fixed-clock";
 | |
| -		clock-frequency = <416500000>;
 | |
| -		#clock-cells = <0>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&soc {
 | |
| -	switch: ess-switch@3a000000 {
 | |
| -		compatible = "qcom,ess-switch-ipq807x";
 | |
| -		reg = <0x3a000000 0x1000000>;
 | |
| -		switch_access_mode = "local bus";
 | |
| -		switch_cpu_bmp = <0x1>;  /* cpu port bitmap */
 | |
| -		switch_inner_bmp = <0x80>; /*inner port bitmap*/
 | |
| -		clocks = <&gcc GCC_CMN_12GPLL_AHB_CLK>,
 | |
| -			 <&gcc GCC_CMN_12GPLL_SYS_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_AHB_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_SYS_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY1_AHB_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY1_SYS_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY2_AHB_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY2_SYS_CLK>,
 | |
| -			 <&gcc GCC_PORT1_MAC_CLK>,
 | |
| -			 <&gcc GCC_PORT2_MAC_CLK>,
 | |
| -			 <&gcc GCC_PORT3_MAC_CLK>,
 | |
| -			 <&gcc GCC_PORT4_MAC_CLK>,
 | |
| -			 <&gcc GCC_PORT5_MAC_CLK>,
 | |
| -			 <&gcc GCC_PORT6_MAC_CLK>,
 | |
| -			 <&gcc GCC_NSS_PPE_CLK>,
 | |
| -			 <&gcc GCC_NSS_PPE_CFG_CLK>,
 | |
| -			 <&gcc GCC_NSSNOC_PPE_CLK>,
 | |
| -			 <&gcc GCC_NSSNOC_PPE_CFG_CLK>,
 | |
| -			 <&gcc GCC_NSS_EDMA_CLK>,
 | |
| -			 <&gcc GCC_NSS_EDMA_CFG_CLK>,
 | |
| -			 <&gcc GCC_NSS_PPE_IPE_CLK>,
 | |
| -			 <&gcc GCC_NSS_PPE_BTQ_CLK>,
 | |
| -			 <&gcc GCC_MDIO_AHB_CLK>,
 | |
| -			 <&gcc GCC_NSS_NOC_CLK>,
 | |
| -			 <&gcc GCC_NSSNOC_SNOC_CLK>,
 | |
| -			 <&gcc GCC_MEM_NOC_NSS_AXI_CLK>,
 | |
| -			 <&gcc GCC_NSS_CRYPTO_CLK>,
 | |
| -			 <&gcc GCC_NSS_IMEM_CLK>,
 | |
| -			 <&gcc GCC_NSS_PTP_REF_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT1_RX_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT1_TX_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT2_RX_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT2_TX_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT3_RX_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT3_TX_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT4_RX_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT4_TX_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT5_RX_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT5_TX_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT6_RX_CLK>,
 | |
| -			 <&gcc GCC_NSS_PORT6_TX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_PORT1_RX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_PORT1_TX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_PORT2_RX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_PORT2_TX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_PORT3_RX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_PORT3_TX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_PORT4_RX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_PORT4_TX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_PORT5_RX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY0_PORT5_TX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY1_PORT5_RX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY1_PORT5_TX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY2_PORT6_RX_CLK>,
 | |
| -			 <&gcc GCC_UNIPHY2_PORT6_TX_CLK>,
 | |
| -			 <&gcc NSS_PORT5_RX_CLK_SRC>,
 | |
| -			 <&gcc NSS_PORT5_TX_CLK_SRC>;
 | |
| -		clock-names = "cmn_ahb_clk", "cmn_sys_clk",
 | |
| -			      "uniphy0_ahb_clk", "uniphy0_sys_clk",
 | |
| -			      "uniphy1_ahb_clk", "uniphy1_sys_clk",
 | |
| -			      "uniphy2_ahb_clk", "uniphy2_sys_clk",
 | |
| -			      "port1_mac_clk", "port2_mac_clk",
 | |
| -			      "port3_mac_clk", "port4_mac_clk",
 | |
| -			      "port5_mac_clk", "port6_mac_clk",
 | |
| -			      "nss_ppe_clk", "nss_ppe_cfg_clk",
 | |
| -			      "nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk",
 | |
| -			      "nss_edma_clk", "nss_edma_cfg_clk",
 | |
| -			      "nss_ppe_ipe_clk", "nss_ppe_btq_clk",
 | |
| -			      "gcc_mdio_ahb_clk", "gcc_nss_noc_clk",
 | |
| -			      "gcc_nssnoc_snoc_clk",
 | |
| -			      "gcc_mem_noc_nss_axi_clk",
 | |
| -			      "gcc_nss_crypto_clk",
 | |
| -			      "gcc_nss_imem_clk",
 | |
| -			      "gcc_nss_ptp_ref_clk",
 | |
| -			      "nss_port1_rx_clk", "nss_port1_tx_clk",
 | |
| -			      "nss_port2_rx_clk", "nss_port2_tx_clk",
 | |
| -			      "nss_port3_rx_clk", "nss_port3_tx_clk",
 | |
| -			      "nss_port4_rx_clk", "nss_port4_tx_clk",
 | |
| -			      "nss_port5_rx_clk", "nss_port5_tx_clk",
 | |
| -			      "nss_port6_rx_clk", "nss_port6_tx_clk",
 | |
| -			      "uniphy0_port1_rx_clk",
 | |
| -			      "uniphy0_port1_tx_clk",
 | |
| -			      "uniphy0_port2_rx_clk",
 | |
| -			      "uniphy0_port2_tx_clk",
 | |
| -			      "uniphy0_port3_rx_clk",
 | |
| -			      "uniphy0_port3_tx_clk",
 | |
| -			      "uniphy0_port4_rx_clk",
 | |
| -			      "uniphy0_port4_tx_clk",
 | |
| -			      "uniphy0_port5_rx_clk",
 | |
| -			      "uniphy0_port5_tx_clk",
 | |
| -			      "uniphy1_port5_rx_clk",
 | |
| -			      "uniphy1_port5_tx_clk",
 | |
| -			      "uniphy2_port6_rx_clk",
 | |
| -			      "uniphy2_port6_tx_clk",
 | |
| -			      "nss_port5_rx_clk_src",
 | |
| -			      "nss_port5_tx_clk_src";
 | |
| -		resets = <&gcc GCC_PPE_FULL_RESET>,
 | |
| -			 <&gcc GCC_UNIPHY0_SOFT_RESET>,
 | |
| -			 <&gcc GCC_UNIPHY0_XPCS_RESET>,
 | |
| -			 <&gcc GCC_UNIPHY1_SOFT_RESET>,
 | |
| -			 <&gcc GCC_UNIPHY1_XPCS_RESET>,
 | |
| -			 <&gcc GCC_UNIPHY2_SOFT_RESET>,
 | |
| -			 <&gcc GCC_UNIPHY2_XPCS_RESET>,
 | |
| -			 <&gcc GCC_NSSPORT1_RESET>,
 | |
| -			 <&gcc GCC_NSSPORT2_RESET>,
 | |
| -			 <&gcc GCC_NSSPORT3_RESET>,
 | |
| -			 <&gcc GCC_NSSPORT4_RESET>,
 | |
| -			 <&gcc GCC_NSSPORT5_RESET>,
 | |
| -			 <&gcc GCC_NSSPORT6_RESET>;
 | |
| -		reset-names = "ppe_rst", "uniphy0_soft_rst",
 | |
| -			      "uniphy0_xpcs_rst", "uniphy1_soft_rst",
 | |
| -			      "uniphy1_xpcs_rst", "uniphy2_soft_rst",
 | |
| -			      "uniphy2_xpcs_rst", "nss_port1_rst",
 | |
| -			      "nss_port2_rst", "nss_port3_rst",
 | |
| -			      "nss_port4_rst", "nss_port5_rst",
 | |
| -			      "nss_port6_rst";
 | |
| -		mdio-bus = <&mdio>;
 | |
| -		status = "disabled";
 | |
| -
 | |
| -		port_scheduler_resource {
 | |
| -			port@0 {
 | |
| -				port_id = <0>;
 | |
| -				ucast_queue = <0 143>;
 | |
| -				mcast_queue = <256 271>;
 | |
| -				l0sp = <0 35>;
 | |
| -				l0cdrr = <0 47>;
 | |
| -				l0edrr = <0 47>;
 | |
| -				l1cdrr = <0 7>;
 | |
| -				l1edrr = <0 7>;
 | |
| -			};
 | |
| -			port@1 {
 | |
| -				port_id = <1>;
 | |
| -				ucast_queue = <144 159>;
 | |
| -				mcast_queue = <272 275>;
 | |
| -				l0sp = <36 39>;
 | |
| -				l0cdrr = <48 63>;
 | |
| -				l0edrr = <48 63>;
 | |
| -				l1cdrr = <8 11>;
 | |
| -				l1edrr = <8 11>;
 | |
| -			};
 | |
| -			port@2 {
 | |
| -				port_id = <2>;
 | |
| -				ucast_queue = <160 175>;
 | |
| -				mcast_queue = <276 279>;
 | |
| -				l0sp = <40 43>;
 | |
| -				l0cdrr = <64 79>;
 | |
| -				l0edrr = <64 79>;
 | |
| -				l1cdrr = <12 15>;
 | |
| -				l1edrr = <12 15>;
 | |
| -			};
 | |
| -			port@3 {
 | |
| -				port_id = <3>;
 | |
| -				ucast_queue = <176 191>;
 | |
| -				mcast_queue = <280 283>;
 | |
| -				l0sp = <44 47>;
 | |
| -				l0cdrr = <80 95>;
 | |
| -				l0edrr = <80 95>;
 | |
| -				l1cdrr = <16 19>;
 | |
| -				l1edrr = <16 19>;
 | |
| -			};
 | |
| -			port@4 {
 | |
| -				port_id = <4>;
 | |
| -				ucast_queue = <192 207>;
 | |
| -				mcast_queue = <284 287>;
 | |
| -				l0sp = <48 51>;
 | |
| -				l0cdrr = <96 111>;
 | |
| -				l0edrr = <96 111>;
 | |
| -				l1cdrr = <20 23>;
 | |
| -				l1edrr = <20 23>;
 | |
| -			};
 | |
| -			port@5 {
 | |
| -				port_id = <5>;
 | |
| -				ucast_queue = <208 223>;
 | |
| -				mcast_queue = <288 291>;
 | |
| -				l0sp = <52 55>;
 | |
| -				l0cdrr = <112 127>;
 | |
| -				l0edrr = <112 127>;
 | |
| -				l1cdrr = <24 27>;
 | |
| -				l1edrr = <24 27>;
 | |
| -			};
 | |
| -			port@6 {
 | |
| -				port_id = <6>;
 | |
| -				ucast_queue = <224 239>;
 | |
| -				mcast_queue = <292 295>;
 | |
| -				l0sp = <56 59>;
 | |
| -				l0cdrr = <128 143>;
 | |
| -				l0edrr = <128 143>;
 | |
| -				l1cdrr = <28 31>;
 | |
| -				l1edrr = <28 31>;
 | |
| -			};
 | |
| -			port@7 {
 | |
| -				port_id = <7>;
 | |
| -				ucast_queue = <240 255>;
 | |
| -				mcast_queue = <296 299>;
 | |
| -				l0sp = <60 63>;
 | |
| -				l0cdrr = <144 159>;
 | |
| -				l0edrr = <144 159>;
 | |
| -				l1cdrr = <32 35>;
 | |
| -				l1edrr = <32 35>;
 | |
| -			};
 | |
| -		};
 | |
| -		port_scheduler_config {
 | |
| -			port@0 {
 | |
| -				port_id = <0>;
 | |
| -				l1scheduler {
 | |
| -					group@0 {
 | |
| -						sp = <0 1>; /*L0 SPs*/
 | |
| -						/*cpri cdrr epri edrr*/
 | |
| -						cfg = <0 0 0 0>;
 | |
| -					};
 | |
| -				};
 | |
| -				l0scheduler {
 | |
| -					group@0 {
 | |
| -						/*unicast queues*/
 | |
| -						ucast_queue = <0 4 8>;
 | |
| -						/*multicast queues*/
 | |
| -						mcast_queue = <256 260>;
 | |
| -						/*sp cpri cdrr epri edrr*/
 | |
| -						cfg = <0 0 0 0 0>;
 | |
| -					};
 | |
| -					group@1 {
 | |
| -						ucast_queue = <1 5 9>;
 | |
| -						mcast_queue = <257 261>;
 | |
| -						cfg = <0 1 1 1 1>;
 | |
| -					};
 | |
| -					group@2 {
 | |
| -						ucast_queue = <2 6 10>;
 | |
| -						mcast_queue = <258 262>;
 | |
| -						cfg = <0 2 2 2 2>;
 | |
| -					};
 | |
| -					group@3 {
 | |
| -						ucast_queue = <3 7 11>;
 | |
| -						mcast_queue = <259 263>;
 | |
| -						cfg = <0 3 3 3 3>;
 | |
| -					};
 | |
| -				};
 | |
| -			};
 | |
| -			port@1 {
 | |
| -				port_id = <1>;
 | |
| -				l1scheduler {
 | |
| -					group@0 {
 | |
| -						sp = <36>;
 | |
| -						cfg = <0 8 0 8>;
 | |
| -					};
 | |
| -					group@1 {
 | |
| -						sp = <37>;
 | |
| -						cfg = <1 9 1 9>;
 | |
| -					};
 | |
| -				};
 | |
| -				l0scheduler {
 | |
| -					group@0 {
 | |
| -						ucast_queue = <144>;
 | |
| -						ucast_loop_pri = <16>;
 | |
| -						mcast_queue = <272>;
 | |
| -						mcast_loop_pri = <4>;
 | |
| -						cfg = <36 0 48 0 48>;
 | |
| -					};
 | |
| -				};
 | |
| -			};
 | |
| -			port@2 {
 | |
| -				port_id = <2>;
 | |
| -				l1scheduler {
 | |
| -					group@0 {
 | |
| -						sp = <40>;
 | |
| -						cfg = <0 12 0 12>;
 | |
| -					};
 | |
| -					group@1 {
 | |
| -						sp = <41>;
 | |
| -						cfg = <1 13 1 13>;
 | |
| -					};
 | |
| -				};
 | |
| -				l0scheduler {
 | |
| -					group@0 {
 | |
| -						ucast_queue = <160>;
 | |
| -						ucast_loop_pri = <16>;
 | |
| -						mcast_queue = <276>;
 | |
| -						mcast_loop_pri = <4>;
 | |
| -						cfg = <40 0 64 0 64>;
 | |
| -					};
 | |
| -				};
 | |
| -			};
 | |
| -			port@3 {
 | |
| -				port_id = <3>;
 | |
| -				l1scheduler {
 | |
| -					group@0 {
 | |
| -						sp = <44>;
 | |
| -						cfg = <0 16 0 16>;
 | |
| -					};
 | |
| -					group@1 {
 | |
| -						sp = <45>;
 | |
| -						cfg = <1 17 1 17>;
 | |
| -					};
 | |
| -				};
 | |
| -				l0scheduler {
 | |
| -					group@0 {
 | |
| -						ucast_queue = <176>;
 | |
| -						ucast_loop_pri = <16>;
 | |
| -						mcast_queue = <280>;
 | |
| -						mcast_loop_pri = <4>;
 | |
| -						cfg = <44 0 80 0 80>;
 | |
| -					};
 | |
| -				};
 | |
| -			};
 | |
| -			port@4 {
 | |
| -				port_id = <4>;
 | |
| -				l1scheduler {
 | |
| -					group@0 {
 | |
| -						sp = <48>;
 | |
| -						cfg = <0 20 0 20>;
 | |
| -					};
 | |
| -					group@1 {
 | |
| -						sp = <49>;
 | |
| -						cfg = <1 21 1 21>;
 | |
| -					};
 | |
| -				};
 | |
| -				l0scheduler {
 | |
| -					group@0 {
 | |
| -						ucast_queue = <192>;
 | |
| -						ucast_loop_pri = <16>;
 | |
| -						mcast_queue = <284>;
 | |
| -						mcast_loop_pri = <4>;
 | |
| -						cfg = <48 0 96 0 96>;
 | |
| -					};
 | |
| -				};
 | |
| -			};
 | |
| -			port@5 {
 | |
| -				port_id = <5>;
 | |
| -				l1scheduler {
 | |
| -					group@0 {
 | |
| -						sp = <52>;
 | |
| -						cfg = <0 24 0 24>;
 | |
| -					};
 | |
| -					group@1 {
 | |
| -						sp = <53>;
 | |
| -						cfg = <1 25 1 25>;
 | |
| -					};
 | |
| -				};
 | |
| -				l0scheduler {
 | |
| -					group@0 {
 | |
| -						ucast_queue = <208>;
 | |
| -						ucast_loop_pri = <16>;
 | |
| -						mcast_queue = <288>;
 | |
| -						mcast_loop_pri = <4>;
 | |
| -						cfg = <52 0 112 0 112>;
 | |
| -					};
 | |
| -				};
 | |
| -			};
 | |
| -			port@6 {
 | |
| -				port_id = <6>;
 | |
| -				l1scheduler {
 | |
| -					group@0 {
 | |
| -						sp = <56>;
 | |
| -						cfg = <0 28 0 28>;
 | |
| -					};
 | |
| -					group@1 {
 | |
| -						sp = <57>;
 | |
| -						cfg = <1 29 1 29>;
 | |
| -					};
 | |
| -				};
 | |
| -				l0scheduler {
 | |
| -					group@0 {
 | |
| -						ucast_queue = <224>;
 | |
| -						ucast_loop_pri = <16>;
 | |
| -						mcast_queue = <292>;
 | |
| -						mcast_loop_pri = <4>;
 | |
| -						cfg = <56 0 128 0 128>;
 | |
| -					};
 | |
| -				};
 | |
| -			};
 | |
| -			port@7 {
 | |
| -				port_id = <7>;
 | |
| -				l1scheduler {
 | |
| -					group@0 {
 | |
| -						sp = <60>;
 | |
| -						cfg = <0 32 0 32>;
 | |
| -					};
 | |
| -					group@1 {
 | |
| -						sp = <61>;
 | |
| -						cfg = <1 33 1 33>;
 | |
| -					};
 | |
| -				};
 | |
| -				l0scheduler {
 | |
| -					group@0 {
 | |
| -						ucast_queue = <240>;
 | |
| -						ucast_loop_pri = <16>;
 | |
| -						mcast_queue = <296>;
 | |
| -						cfg = <60 0 144 0 144>;
 | |
| -					};
 | |
| -				};
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	ess-uniphy@7a00000 {
 | |
| -		compatible = "qcom,ess-uniphy";
 | |
| -		reg = <0x7a00000 0x30000>;
 | |
| -		uniphy_access_mode = "local bus";
 | |
| -	};
 | |
| -
 | |
| -	edma: edma@3ab00000 {
 | |
| -		compatible = "qcom,edma";
 | |
| -		reg = <0x3ab00000 0x76900>;
 | |
| -		reg-names = "edma-reg-base";
 | |
| -		qcom,txdesc-ring-start = <23>;
 | |
| -		qcom,txdesc-rings = <1>;
 | |
| -		qcom,txcmpl-ring-start = <7>;
 | |
| -		qcom,txcmpl-rings = <1>;
 | |
| -		qcom,rxfill-ring-start = <7>;
 | |
| -		qcom,rxfill-rings = <1>;
 | |
| -		qcom,rxdesc-ring-start = <15>;
 | |
| -		qcom,rxdesc-rings = <1>;
 | |
| -		interrupts = <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
 | |
| -			     <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>,
 | |
| -			     <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>,
 | |
| -			     <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>;
 | |
| -		resets = <&gcc GCC_EDMA_HW_RESET>;
 | |
| -		reset-names = "edma_rst";
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -
 | |
| -	dp1: dp1 {
 | |
| -		device_type = "network";
 | |
| -		compatible = "qcom,nss-dp";
 | |
| -		qcom,id = <1>;
 | |
| -		reg = <0x3a001000 0x200>;
 | |
| -		qcom,mactype = <0>;
 | |
| -		local-mac-address = [000000000000];
 | |
| -		phy-mode = "sgmii";
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -
 | |
| -	dp2: dp2 {
 | |
| -		device_type = "network";
 | |
| -		compatible = "qcom,nss-dp";
 | |
| -		qcom,id = <2>;
 | |
| -		reg = <0x3a001200 0x200>;
 | |
| -		qcom,mactype = <0>;
 | |
| -		local-mac-address = [000000000000];
 | |
| -		phy-mode = "sgmii";
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -
 | |
| -	dp3: dp3 {
 | |
| -		device_type = "network";
 | |
| -		compatible = "qcom,nss-dp";
 | |
| -		qcom,id = <3>;
 | |
| -		reg = <0x3a001400 0x200>;
 | |
| -		qcom,mactype = <0>;
 | |
| -		local-mac-address = [000000000000];
 | |
| -		phy-mode = "sgmii";
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -
 | |
| -	dp4: dp4 {
 | |
| -		device_type = "network";
 | |
| -		compatible = "qcom,nss-dp";
 | |
| -		qcom,id = <4>;
 | |
| -		reg = <0x3a001600 0x200>;
 | |
| -		qcom,mactype = <0>;
 | |
| -		local-mac-address = [000000000000];
 | |
| -		phy-mode = "sgmii";
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -
 | |
| -	dp5: dp5 {
 | |
| -		device_type = "network";
 | |
| -		compatible = "qcom,nss-dp";
 | |
| -		qcom,id = <5>;
 | |
| -		reg = <0x3a001800 0x200>;
 | |
| -		qcom,mactype = <0>;
 | |
| -		local-mac-address = [000000000000];
 | |
| -		phy-mode = "sgmii";
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -
 | |
| -	dp6: dp6 {
 | |
| -		device_type = "network";
 | |
| -		compatible = "qcom,nss-dp";
 | |
| -		qcom,id = <6>;
 | |
| -		reg = <0x3a001a00 0x200>;
 | |
| -		qcom,mactype = <0>;
 | |
| -		local-mac-address = [000000000000];
 | |
| -		phy-mode = "sgmii";
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -
 | |
| -	dp5_syn: dp5-syn {
 | |
| -		device_type = "network";
 | |
| -		compatible = "qcom,nss-dp";
 | |
| -		qcom,id = <5>;
 | |
| -		reg = <0x3a003000 0x3fff>;
 | |
| -		qcom,mactype = <1>;
 | |
| -		local-mac-address = [000000000000];
 | |
| -		phy-mode = "sgmii";
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -
 | |
| -	dp6_syn: dp6-syn {
 | |
| -		device_type = "network";
 | |
| -		compatible = "qcom,nss-dp";
 | |
| -		qcom,id = <6>;
 | |
| -		reg = <0x3a007000 0x3fff>;
 | |
| -		qcom,mactype = <1>;
 | |
| -		local-mac-address = [000000000000];
 | |
| -		phy-mode = "sgmii";
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-hk-cpu.dtsi b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-hk-cpu.dtsi
 | |
| deleted file mode 100644
 | |
| index 8485814969..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-hk-cpu.dtsi
 | |
| +++ /dev/null
 | |
| @@ -1,218 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-only
 | |
| -
 | |
| -#include <dt-bindings/thermal/thermal.h>
 | |
| -#include "ipq8074-cpr-regulator.dtsi"
 | |
| -
 | |
| -&CPU0 {
 | |
| -	cpu-supply = <&apc_vreg>;
 | |
| -	voltage-tolerance = <1>;
 | |
| -};
 | |
| -
 | |
| -&CPU1 {
 | |
| -	cpu-supply = <&apc_vreg>;
 | |
| -	voltage-tolerance = <1>;
 | |
| -};
 | |
| -
 | |
| -&CPU2 {
 | |
| -	cpu-supply = <&apc_vreg>;
 | |
| -	voltage-tolerance = <1>;
 | |
| -};
 | |
| -
 | |
| -&CPU3 {
 | |
| -	cpu-supply = <&apc_vreg>;
 | |
| -	voltage-tolerance = <1>;
 | |
| -};
 | |
| -&cpu0_thermal {
 | |
| -	trips {
 | |
| -		cpu0_passive_low: cpu-passive-low {
 | |
| -			temperature = <95000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu0_passive_high: cpu-passive-high {
 | |
| -			temperature = <100000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu0_crit: cpu_crit {
 | |
| -			temperature = <110000>;
 | |
| -			hysteresis = <1000>;
 | |
| -			type = "critical";
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	cooling-maps {
 | |
| -		map0 {
 | |
| -			trip = <&cpu0_passive_low>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -		map1 {
 | |
| -			trip = <&cpu0_passive_high>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&cpu1_thermal {
 | |
| -	trips {
 | |
| -		cpu1_passive_low: cpu-passive-low {
 | |
| -			temperature = <95000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu1_passive_high: cpu-passive-high {
 | |
| -			temperature = <100000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu1_crit: cpu_crit {
 | |
| -			temperature = <110000>;
 | |
| -			hysteresis = <1000>;
 | |
| -			type = "critical";
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	cooling-maps {
 | |
| -		map0 {
 | |
| -			trip = <&cpu1_passive_low>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -		map1 {
 | |
| -			trip = <&cpu1_passive_high>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&cpu2_thermal {
 | |
| -	trips {
 | |
| -		cpu2_passive_low: cpu-passive-low {
 | |
| -			temperature = <95000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu2_passive_high: cpu-passive-high {
 | |
| -			temperature = <100000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu2_crit: cpu_crit {
 | |
| -			temperature = <110000>;
 | |
| -			hysteresis = <1000>;
 | |
| -			type = "critical";
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	cooling-maps {
 | |
| -		map0 {
 | |
| -			trip = <&cpu2_passive_low>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -		map1 {
 | |
| -			trip = <&cpu2_passive_high>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&cpu3_thermal {
 | |
| -	trips {
 | |
| -		cpu3_passive_low: cpu-passive-low {
 | |
| -			temperature = <95000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu3_passive_high: cpu-passive-high {
 | |
| -			temperature = <100000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cpu3_crit: cpu_crit {
 | |
| -			temperature = <110000>;
 | |
| -			hysteresis = <1000>;
 | |
| -			type = "critical";
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	cooling-maps {
 | |
| -		map0 {
 | |
| -			trip = <&cpu3_passive_low>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -		map1 {
 | |
| -			trip = <&cpu3_passive_high>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&cluster_thermal {
 | |
| -	trips {
 | |
| -		cluster_passive_low: cluster-passive {
 | |
| -			temperature = <95000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cluster_passive_high: cluster-passive-high {
 | |
| -			temperature = <100000>;
 | |
| -			hysteresis = <2000>;
 | |
| -			type = "passive";
 | |
| -		};
 | |
| -
 | |
| -		cluster_crit: cluster_crit {
 | |
| -			temperature = <110000>;
 | |
| -			hysteresis = <1000>;
 | |
| -			type = "critical";
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	cooling-maps {
 | |
| -		map0 {
 | |
| -			trip = <&cluster_passive_low>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -		map1 {
 | |
| -			trip = <&cluster_passive_high>;
 | |
| -			cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
 | |
| -					 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts
 | |
| deleted file mode 100644
 | |
| index d113b233ec..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-nbg7815.dts
 | |
| +++ /dev/null
 | |
| @@ -1,445 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 | |
| -/*
 | |
| - * Copyright (c) 2022, Karol Przybylski <itor@o2.pl>
 | |
| - * Copyright (c) 2023, Andre Valentin <avalentin@marcant.net>
 | |
| - */
 | |
| -
 | |
| -/dts-v1/;
 | |
| -
 | |
| -#include "ipq8074.dtsi"
 | |
| -#include "ipq8074-hk-cpu.dtsi"
 | |
| -#include "ipq8074-ess.dtsi"
 | |
| -#include <dt-bindings/gpio/gpio.h>
 | |
| -#include <dt-bindings/leds/common.h>
 | |
| -#include <dt-bindings/input/input.h>
 | |
| -
 | |
| -
 | |
| -/ {
 | |
| -	model = "Zyxel NBG7815";
 | |
| -	compatible = "zyxel,nbg7815", "qcom,ipq8074";
 | |
| -
 | |
| -	aliases {
 | |
| -		serial0 = &blsp1_uart5;
 | |
| -		serial1 = &blsp1_uart3;
 | |
| -		/* Alias as required by u-boot to patch MAC addresses */
 | |
| -		ethernet0 = &dp1;
 | |
| -		label-mac-device = &dp1;
 | |
| -	};
 | |
| -
 | |
| -	chosen {
 | |
| -		stdout-path = "serial0:115200n8";
 | |
| -	};
 | |
| -
 | |
| -	keys {
 | |
| -		compatible = "gpio-keys";
 | |
| -
 | |
| -		reset {
 | |
| -			label = "reset";
 | |
| -			linux,code = <KEY_RESTART>;
 | |
| -			gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&tlmm {
 | |
| -	mdio_pins: mdio-pins {
 | |
| -		mdc {
 | |
| -			pins = "gpio68";
 | |
| -			function = "mdc";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		mdio {
 | |
| -			pins = "gpio69";
 | |
| -			function = "mdio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -
 | |
| -&blsp1_uart3 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&blsp1_uart5 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&prng {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&cryptobam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&crypto {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_bam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -
 | |
| -&blsp1_spi1 {
 | |
| -	pinctrl-0 = <&spi_0_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	cs-gpios = <0>;
 | |
| -	status = "okay";
 | |
| -
 | |
| -	/*
 | |
| -	 * Bootloader will find the NAND DT node by the compatible and
 | |
| -	 * then "fixup" it by adding the partitions from the SMEM table
 | |
| -	 * using the legacy bindings thus making it impossible for us
 | |
| -	 * to change the partition table or utilize NVMEM for calibration.
 | |
| -	 * So add a dummy partitions node that bootloader will populate
 | |
| -	 * and set it as disabled so the kernel ignores it instead of
 | |
| -	 * printing warnings due to the broken way bootloader adds the
 | |
| -	 * partitions.
 | |
| -	 */
 | |
| -	partitions {
 | |
| -		status = "disabled";
 | |
| -	};
 | |
| -
 | |
| -
 | |
| -	flash@0 {
 | |
| -		#address-cells = <1>;
 | |
| -		#size-cells = <1>;
 | |
| -		reg = <0>;
 | |
| -		compatible = "jedec,spi-nor";
 | |
| -		spi-max-frequency = <50000000>;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "fixed-partitions";
 | |
| -			#address-cells = <1>;
 | |
| -			#size-cells = <1>;
 | |
| -
 | |
| -			partition@0 {
 | |
| -				label = "0:sbl1";
 | |
| -				reg = <0x0 0x50000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@50000 {
 | |
| -				label = "0:mibib";
 | |
| -				reg = <0x50000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@60000 {
 | |
| -				label = "0:bootconfig";
 | |
| -				reg = <0x60000 0x20000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@80000 {
 | |
| -				label = "0:bootconfig1";
 | |
| -				reg = <0x80000 0x20000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@a0000 {
 | |
| -				label = "0:qsee";
 | |
| -				reg = <0xa0000 0x180000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@220000 {
 | |
| -				label = "0:qsee_1";
 | |
| -				reg = <0x220000 0x180000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3a0000 {
 | |
| -				label = "0:devcfg";
 | |
| -				reg = <0x3a0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3b0000 {
 | |
| -				label = "0:devcfg_1";
 | |
| -				reg = <0x3b0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3c0000 {
 | |
| -				label = "0:apdp";
 | |
| -				reg = <0x3c0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3d0000 {
 | |
| -				label = "0:apdp_1";
 | |
| -				reg = <0x3d0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@3e0000 {
 | |
| -				label = "0:rpm";
 | |
| -				reg = <0x3e0000 0x40000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@420000 {
 | |
| -				label = "0:rpm_1";
 | |
| -				reg = <0x420000 0x40000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@460000 {
 | |
| -				label = "0:cdt";
 | |
| -				reg = <0x460000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@470000 {
 | |
| -				label = "0:cdt_1";
 | |
| -				reg = <0x470000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@480000 {
 | |
| -				label = "0:appsbl";
 | |
| -				reg = <0x480000 0xc0000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@540000 {
 | |
| -				label = "0:appsbl_1";
 | |
| -				reg = <0x540000 0xc0000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@600000 {
 | |
| -				compatible = "u-boot,env";
 | |
| -				label = "0:appsblenv";
 | |
| -				reg = <0x600000 0x10000>;
 | |
| -
 | |
| -				macaddr_lan: ethaddr {
 | |
| -					#nvmem-cell-cells = <1>;
 | |
| -				};
 | |
| -			};
 | |
| -
 | |
| -			partition@610000 {
 | |
| -				label = "0:art";
 | |
| -				reg = <0x610000 0x40000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@650000 {
 | |
| -				label = "0:ethphyfw";
 | |
| -				reg = <0x650000 0x80000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@6d0000 {
 | |
| -				label = "0:crt";
 | |
| -				reg = <0x6d0000 0x10000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -
 | |
| -			partition@6e0000 {
 | |
| -				label = "dual_flag";
 | |
| -				reg = <0x6e0000 0x10000>;
 | |
| -			};
 | |
| -
 | |
| -			partition@6f0000 {
 | |
| -				label = "reserved";
 | |
| -				reg = <0x6f0000 0x110000>;
 | |
| -				read-only;
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&mdio {
 | |
| -	status = "okay";
 | |
| -	pinctrl-0 = <&mdio_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;
 | |
| -
 | |
| -	qca8075_1: ethernet-phy@0 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <0>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_2: ethernet-phy@1 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <1>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_3: ethernet-phy@2 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <2>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_4: ethernet-phy@3 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <3>;
 | |
| -	};
 | |
| -
 | |
| -	qca8081: ethernet-phy@4{
 | |
| -		compatible = "ethernet-phy-id004d.d101";
 | |
| -		reg = <28>;
 | |
| -		reset-gpios = <&tlmm 31 GPIO_ACTIVE_LOW>;
 | |
| -	};
 | |
| -
 | |
| -	aqr113c: ethernet-phy@5 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c45";
 | |
| -		reg = <8>;
 | |
| -		reset-gpios = <&tlmm 63 GPIO_ACTIVE_LOW>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&switch {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	switch_cpu_bmp = <0x1>;
 | |
| -	switch_lan_bmp = <0x3e>;
 | |
| -	switch_wan_bmp = <0x40>;
 | |
| -	switch_mac_mode = <0x0>;
 | |
| -	switch_mac_mode1 = <0xf>;
 | |
| -	switch_mac_mode2 = <0xd>;
 | |
| -	bm_tick_mode = <0>;
 | |
| -	tm_tick_mode = <0>;
 | |
| -
 | |
| -	qcom,port_phyinfo {
 | |
| -		port@0 {
 | |
| -			port_id = <1>;
 | |
| -			phy_address = <0>;
 | |
| -		};
 | |
| -
 | |
| -		port@1 {
 | |
| -			port_id = <2>;
 | |
| -			phy_address = <1>;
 | |
| -		};
 | |
| -
 | |
| -		port@2 {
 | |
| -			port_id = <3>;
 | |
| -			phy_address = <2>;
 | |
| -		};
 | |
| -
 | |
| -		port@3 {
 | |
| -			port_id = <4>;
 | |
| -			phy_address = <3>;
 | |
| -		};
 | |
| -
 | |
| -		port@4 {
 | |
| -			port_id = <5>;
 | |
| -			phy_address = <28>;
 | |
| -			port_mac_sel = "QGMAC_PORT";
 | |
| -		};
 | |
| -
 | |
| -		port@5 {
 | |
| -			port_id = <6>;
 | |
| -			ethernet-phy-ieee802.3-c45;
 | |
| -			phy_address = <8>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&edma {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&dp1 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_1>;
 | |
| -	label = "lan1";
 | |
| -	nvmem-cells = <&macaddr_lan 0>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp2 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_2>;
 | |
| -	label = "lan2";
 | |
| -	nvmem-cells = <&macaddr_lan 0>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp3 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_3>;
 | |
| -	label = "lan3";
 | |
| -	nvmem-cells = <&macaddr_lan 0>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp4 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_4>;
 | |
| -	label = "lan4";
 | |
| -	nvmem-cells = <&macaddr_lan 0>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp5 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8081>;
 | |
| -	label = "wan";
 | |
| -	nvmem-cells = <&macaddr_lan 1>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp6_syn {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&aqr113c>;
 | |
| -	label = "10g";
 | |
| -	nvmem-cells = <&macaddr_lan 0>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&blsp1_i2c2 {
 | |
| -	pinctrl-0 = <&i2c_0_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	status = "okay";
 | |
| -
 | |
| -	tmp103@70 {
 | |
| -		compatible = "ti,tmp103";
 | |
| -		reg = <0x70>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&sdhc_1 {
 | |
| -	status = "okay";
 | |
| -	/* unstable, problem with the hs400 > h200 speed switch */
 | |
| -	/delete-property/ mmc-hs400-1_8v;
 | |
| -	mmc-hs200-1_8v;
 | |
| -	mmc-ddr-1_8v;
 | |
| -	vqmmc-supply = <&l11>;
 | |
| -};
 | |
| -
 | |
| -&ssphy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qusb_phy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&ssphy_1 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qusb_phy_1 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&usb_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&usb_1 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	qcom,ath11k-calibration-variant = "Zyxel-NBG7815";
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts b/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts
 | |
| deleted file mode 100644
 | |
| index 32386dc93e..0000000000
 | |
| --- a/target/linux/ipq807x/files/arch/arm64/boot/dts/qcom/ipq8074-wxr-5950ax12.dts
 | |
| +++ /dev/null
 | |
| @@ -1,376 +0,0 @@
 | |
| -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
 | |
| -
 | |
| -/dts-v1/;
 | |
| -
 | |
| -#include "ipq8074.dtsi"
 | |
| -#include "ipq8074-hk-cpu.dtsi"
 | |
| -#include "ipq8074-ess.dtsi"
 | |
| -#include <dt-bindings/gpio/gpio.h>
 | |
| -#include <dt-bindings/leds/common.h>
 | |
| -#include <dt-bindings/input/input.h>
 | |
| -
 | |
| -/ {
 | |
| -	model = "Buffalo WXR-5950AX12";
 | |
| -	compatible = "buffalo,wxr-5950ax12", "qcom,ipq8074";
 | |
| -
 | |
| -	aliases {
 | |
| -		serial0 = &blsp1_uart5;
 | |
| -		led-boot = &led_power_white;
 | |
| -		led-failsafe = &led_power_red;
 | |
| -		led-running = &led_power_white;
 | |
| -		led-upgrade = &led_power_white;
 | |
| -		label-mac-device = &dp5_syn;
 | |
| -	};
 | |
| -
 | |
| -	chosen {
 | |
| -		stdout-path = "serial0:115200n8";
 | |
| -		bootargs-append = " ubi.mtd=user_property root=/dev/ubiblock1_0";
 | |
| -	};
 | |
| -
 | |
| -	leds {
 | |
| -		compatible = "gpio-leds";
 | |
| -
 | |
| -		led-0 {
 | |
| -			label = "white:router";
 | |
| -			gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_WHITE>;
 | |
| -		};
 | |
| -
 | |
| -		led-1 {
 | |
| -			label = "red:router";
 | |
| -			gpios = <&tlmm 22 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_RED>;
 | |
| -		};
 | |
| -
 | |
| -		led_power_red: led-2 {
 | |
| -			label = "red:power";
 | |
| -			gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_RED>;
 | |
| -			function = LED_FUNCTION_POWER;
 | |
| -		};
 | |
| -
 | |
| -		led_power_white: led-3 {
 | |
| -			label = "white:power";
 | |
| -			gpios = <&tlmm 34 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_WHITE>;
 | |
| -			function = LED_FUNCTION_POWER;
 | |
| -		};
 | |
| -
 | |
| -		led-4 {
 | |
| -			label = "white:internet";
 | |
| -			gpios = <&tlmm 43 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_WHITE>;
 | |
| -		};
 | |
| -
 | |
| -		led-5 {
 | |
| -			label = "red:internet";
 | |
| -			gpios = <&tlmm 44 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_RED>;
 | |
| -		};
 | |
| -
 | |
| -		led-6 {
 | |
| -			label = "red:wireless";
 | |
| -			gpios = <&tlmm 55 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_RED>;
 | |
| -			function = LED_FUNCTION_WLAN;
 | |
| -		};
 | |
| -
 | |
| -		led-7 {
 | |
| -			label = "white:wireless";
 | |
| -			gpios = <&tlmm 56 GPIO_ACTIVE_HIGH>;
 | |
| -			color = <LED_COLOR_ID_WHITE>;
 | |
| -			function = LED_FUNCTION_WLAN;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	keys {
 | |
| -		compatible = "gpio-keys";
 | |
| -
 | |
| -		/*
 | |
| -		 * mode: 3x position switch
 | |
| -		 *
 | |
| -		 * - ROUTER
 | |
| -		 * - AP
 | |
| -		 * - WB (Wireless Bridge)
 | |
| -		 */
 | |
| -		ap {
 | |
| -			label = "mode-ap";
 | |
| -			gpios = <&tlmm 29 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <BTN_0>;
 | |
| -		};
 | |
| -
 | |
| -		bridge {
 | |
| -			label = "mode-wb";
 | |
| -			gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <BTN_1>;
 | |
| -		};
 | |
| -
 | |
| -		/*
 | |
| -		 * op: 2x position switch
 | |
| -		 *
 | |
| -		 * - AUTO
 | |
| -		 * - MANUAL (select Router/AP/WB manually)
 | |
| -		 */
 | |
| -		manual {
 | |
| -			label = "op-manual";
 | |
| -			gpios = <&tlmm 52 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <BTN_2>;
 | |
| -		};
 | |
| -
 | |
| -		wps {
 | |
| -			label = "wps";
 | |
| -			gpios = <&tlmm 51 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_WPS_BUTTON>;
 | |
| -		};
 | |
| -
 | |
| -		reset {
 | |
| -			label = "reset";
 | |
| -			gpios = <&tlmm 54 GPIO_ACTIVE_LOW>;
 | |
| -			linux,code = <KEY_RESTART>;
 | |
| -		};
 | |
| -	};
 | |
| -
 | |
| -	reg_usb_vbus: regulator-5v-vbus {
 | |
| -		compatible = "regulator-fixed";
 | |
| -		regulator-name = "vbus";
 | |
| -		regulator-min-microvolt = <5000000>;
 | |
| -		regulator-max-microvolt = <5000000>;
 | |
| -		gpio = <&tlmm 64 GPIO_ACTIVE_HIGH>;
 | |
| -		enable-active-high;
 | |
| -		regulator-always-on;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&tlmm {
 | |
| -	mdio_pins: mdio-pins {
 | |
| -		mdc {
 | |
| -			pins = "gpio68";
 | |
| -			function = "mdc";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -
 | |
| -		mdio {
 | |
| -			pins = "gpio69";
 | |
| -			function = "mdio";
 | |
| -			drive-strength = <8>;
 | |
| -			bias-pull-up;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&blsp1_uart5 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&prng {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&cryptobam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&crypto {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_bam {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qpic_nand {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	nand@0 {
 | |
| -		reg = <0>;
 | |
| -		nand-ecc-strength = <4>;
 | |
| -		nand-ecc-step-size = <512>;
 | |
| -		nand-bus-width = <8>;
 | |
| -
 | |
| -		partitions {
 | |
| -			compatible = "qcom,smem-part";
 | |
| -
 | |
| -			partition-0-appsblenv {
 | |
| -				compatible = "fixed-partitions";
 | |
| -				label = "0:appsblenv";
 | |
| -				read-only;
 | |
| -				#address-cells = <1>;
 | |
| -				#size-cells = <1>;
 | |
| -
 | |
| -				partition@0 {
 | |
| -					compatible = "u-boot,env";
 | |
| -					label = "env-data";
 | |
| -					reg = <0x0 0x40000>;
 | |
| -
 | |
| -					macaddr_appsblenv_ethaddr: ethaddr {
 | |
| -					};
 | |
| -				};
 | |
| -			};
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&mdio {
 | |
| -	status = "okay";
 | |
| -	pinctrl-0 = <&mdio_pins>;
 | |
| -	pinctrl-names = "default";
 | |
| -	/*
 | |
| -	 * RESET pins of phy chips
 | |
| -	 *
 | |
| -	 * WXR-5950AX12 has 2x RESET pins for QCA8075 and AQR113C.
 | |
| -	 * The pin of QCA8075 is for the chip and not phys in the chip, the
 | |
| -	 * pin of AQR113C is for 2x chips. So both pins are not appropriate
 | |
| -	 * to declare them as reset-gpios in phy nodes.
 | |
| -	 * Multiple entries in reset-gpios of mdio may not be supported, but
 | |
| -	 * leave the following as-is to show that the those reset pin exists.
 | |
| -	 */
 | |
| -	reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>, /* QCA8075 RESET */
 | |
| -		      <&tlmm 63 GPIO_ACTIVE_LOW>; /* AQR113C RESET (2x) */
 | |
| -
 | |
| -	aqr113c_1: ethernet-phy@0 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c45";
 | |
| -		reg = <0x0>;
 | |
| -	};
 | |
| -
 | |
| -	aqr113c_2: ethernet-phy@8 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c45";
 | |
| -		reg = <0x8>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_1: ethernet-phy@18 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <0x18>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_2: ethernet-phy@19 {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <0x19>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_3: ethernet-phy@1a {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <0x1a>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_4: ethernet-phy@1b {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <0x1b>;
 | |
| -	};
 | |
| -
 | |
| -	qca8075_5: ethernet-phy@1c {
 | |
| -		compatible = "ethernet-phy-ieee802.3-c22";
 | |
| -		reg = <0x1c>;
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&switch {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	switch_cpu_bmp = <0x1>;
 | |
| -	switch_lan_bmp = <0x3e>;
 | |
| -	switch_wan_bmp = <0x40>;
 | |
| -	switch_mac_mode = <0xb>;
 | |
| -	switch_mac_mode1 = <0xd>;
 | |
| -	switch_mac_mode2 = <0xd>;
 | |
| -	bm_tick_mode = <0>;
 | |
| -	tm_tick_mode = <0>;
 | |
| -
 | |
| -	qcom,port_phyinfo {
 | |
| -		port@0 {
 | |
| -			port_id = <1>;
 | |
| -			phy_address = <0x18>;
 | |
| -		};
 | |
| -
 | |
| -		port@1 {
 | |
| -			port_id = <2>;
 | |
| -			phy_address = <0x19>;
 | |
| -		};
 | |
| -
 | |
| -		port@2 {
 | |
| -			port_id = <3>;
 | |
| -			phy_address = <0x1a>;
 | |
| -		};
 | |
| -
 | |
| -		port@3 {
 | |
| -			port_id = <4>;
 | |
| -			phy_address = <0x1b>;
 | |
| -		};
 | |
| -
 | |
| -		port@4 {
 | |
| -			port_id = <5>;
 | |
| -			ethernet-phy-ieee802.3-c45;
 | |
| -			phy_address = <0x0>;
 | |
| -		};
 | |
| -
 | |
| -		port@5 {
 | |
| -			port_id = <6>;
 | |
| -			ethernet-phy-ieee802.3-c45;
 | |
| -			phy_address = <0x8>;
 | |
| -		};
 | |
| -	};
 | |
| -};
 | |
| -
 | |
| -&edma {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&dp2 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_2>;
 | |
| -	label = "lan4";
 | |
| -	nvmem-cells = <&macaddr_appsblenv_ethaddr>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp3 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_3>;
 | |
| -	label = "lan3";
 | |
| -	nvmem-cells = <&macaddr_appsblenv_ethaddr>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp4 {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&qca8075_4>;
 | |
| -	label = "lan2";
 | |
| -	nvmem-cells = <&macaddr_appsblenv_ethaddr>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp5_syn {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&aqr113c_1>;
 | |
| -	label = "wan";
 | |
| -	nvmem-cells = <&macaddr_appsblenv_ethaddr>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&dp6_syn {
 | |
| -	status = "okay";
 | |
| -	phy-handle = <&aqr113c_2>;
 | |
| -	label = "lan1";
 | |
| -	nvmem-cells = <&macaddr_appsblenv_ethaddr>;
 | |
| -	nvmem-cell-names = "mac-address";
 | |
| -};
 | |
| -
 | |
| -&ssphy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&qusb_phy_0 {
 | |
| -	status = "okay";
 | |
| -};
 | |
| -
 | |
| -&usb_0 {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	vbus-supply = <®_usb_vbus>;
 | |
| -};
 | |
| -
 | |
| -&wifi {
 | |
| -	status = "okay";
 | |
| -
 | |
| -	qcom,ath11k-calibration-variant = "Buffalo-WXR-5950AX12";
 | |
| -};
 | |
| diff --git a/target/linux/ipq807x/generic/target.mk b/target/linux/ipq807x/generic/target.mk
 | |
| deleted file mode 100644
 | |
| index f5cb1fb19b..0000000000
 | |
| --- a/target/linux/ipq807x/generic/target.mk
 | |
| +++ /dev/null
 | |
| @@ -1 +0,0 @@
 | |
| -BOARDNAME:=Generic
 | |
| diff --git a/target/linux/ipq807x/image/Makefile b/target/linux/ipq807x/image/Makefile
 | |
| deleted file mode 100644
 | |
| index f59ad0c15f..0000000000
 | |
| --- a/target/linux/ipq807x/image/Makefile
 | |
| +++ /dev/null
 | |
| @@ -1,17 +0,0 @@
 | |
| -include $(TOPDIR)/rules.mk
 | |
| -include $(INCLUDE_DIR)/image.mk
 | |
| -
 | |
| -define Device/Default
 | |
| -	PROFILES := Default
 | |
| -	KERNEL_LOADADDR := 0x41000000
 | |
| -	DEVICE_DTS = $$(SOC)-$(lastword $(subst _, ,$(1)))
 | |
| -	DEVICE_DTS_CONFIG := config@1
 | |
| -	DEVICE_DTS_DIR := $(DTS_DIR)/qcom
 | |
| -	IMAGES := sysupgrade.bin
 | |
| -	IMAGE/sysupgrade.bin = sysupgrade-tar | append-metadata
 | |
| -	IMAGE/sysupgrade.bin/squashfs :=
 | |
| -endef
 | |
| -
 | |
| -include $(SUBTARGET).mk
 | |
| -
 | |
| -$(eval $(call BuildImage))
 | |
| diff --git a/target/linux/ipq807x/image/generic.mk b/target/linux/ipq807x/image/generic.mk
 | |
| deleted file mode 100644
 | |
| index 124cdfc3b2..0000000000
 | |
| --- a/target/linux/ipq807x/image/generic.mk
 | |
| +++ /dev/null
 | |
| @@ -1,175 +0,0 @@
 | |
| -define Device/FitImage
 | |
| -	KERNEL_SUFFIX := -uImage.itb
 | |
| -	KERNEL = kernel-bin | libdeflate-gzip | fit gzip $$(KDIR)/image-$$(DEVICE_DTS).dtb
 | |
| -	KERNEL_NAME := Image
 | |
| -endef
 | |
| -
 | |
| -define Device/FitImageLzma
 | |
| -	KERNEL_SUFFIX := -uImage.itb
 | |
| -	KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb
 | |
| -	KERNEL_NAME := Image
 | |
| -endef
 | |
| -
 | |
| -define Device/EmmcImage
 | |
| -	IMAGES += factory.bin sysupgrade.bin
 | |
| -	IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 64k
 | |
| -	IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-to 64k | sysupgrade-tar rootfs=$$$$@ | append-metadata
 | |
| -endef
 | |
| -
 | |
| -define Device/UbiFit
 | |
| -	KERNEL_IN_UBI := 1
 | |
| -	IMAGES := factory.ubi sysupgrade.bin
 | |
| -	IMAGE/factory.ubi := append-ubi
 | |
| -	IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
 | |
| -endef
 | |
| -
 | |
| -define Device/buffalo_wxr-5950ax12
 | |
| -	$(call Device/FitImage)
 | |
| -	DEVICE_VENDOR := Buffalo
 | |
| -	DEVICE_MODEL := WXR-5950AX12
 | |
| -	BLOCKSIZE := 128k
 | |
| -	PAGESIZE := 2048
 | |
| -	DEVICE_DTS_CONFIG := config@hk01
 | |
| -	SOC := ipq8074
 | |
| -	IMAGES := sysupgrade.bin
 | |
| -	IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
 | |
| -	DEVICE_PACKAGES := ipq-wifi-buffalo_wxr-5950ax12
 | |
| -endef
 | |
| -TARGET_DEVICES += buffalo_wxr-5950ax12
 | |
| -
 | |
| -define Device/dynalink_dl-wrx36
 | |
| -	$(call Device/FitImage)
 | |
| -	$(call Device/UbiFit)
 | |
| -	DEVICE_VENDOR := Dynalink
 | |
| -	DEVICE_MODEL := DL-WRX36
 | |
| -	BLOCKSIZE := 128k
 | |
| -	PAGESIZE := 2048
 | |
| -	DEVICE_DTS_CONFIG := config@rt5010w-d350-rev0
 | |
| -	SOC := ipq8072
 | |
| -	DEVICE_PACKAGES := ipq-wifi-dynalink_dl-wrx36
 | |
| -endef
 | |
| -TARGET_DEVICES += dynalink_dl-wrx36
 | |
| -
 | |
| -define Device/edgecore_eap102
 | |
| -	$(call Device/FitImage)
 | |
| -	$(call Device/UbiFit)
 | |
| -	DEVICE_VENDOR := Edgecore
 | |
| -	DEVICE_MODEL := EAP102
 | |
| -	BLOCKSIZE := 128k
 | |
| -	PAGESIZE := 2048
 | |
| -	DEVICE_DTS_CONFIG := config@ac02
 | |
| -	SOC := ipq8071
 | |
| -	DEVICE_PACKAGES := ipq-wifi-edgecore_eap102
 | |
| -	IMAGE/factory.ubi := append-ubi | qsdk-ipq-factory-nand
 | |
| -endef
 | |
| -TARGET_DEVICES += edgecore_eap102
 | |
| -
 | |
| -define Device/edimax_cax1800
 | |
| -	$(call Device/FitImage)
 | |
| -	$(call Device/UbiFit)
 | |
| -	DEVICE_VENDOR := Edimax
 | |
| -	DEVICE_MODEL := CAX1800
 | |
| -	BLOCKSIZE := 128k
 | |
| -	PAGESIZE := 2048
 | |
| -	DEVICE_DTS_CONFIG := config@ac03
 | |
| -	SOC := ipq8070
 | |
| -	DEVICE_PACKAGES := ipq-wifi-edimax_cax1800
 | |
| -endef
 | |
| -TARGET_DEVICES += edimax_cax1800
 | |
| -
 | |
| -define Device/netgear_wax218
 | |
| -	$(call Device/FitImage)
 | |
| -	$(call Device/UbiFit)
 | |
| -	ARTIFACTS := web-ui-factory.fit
 | |
| -	DEVICE_VENDOR := Netgear
 | |
| -	DEVICE_MODEL := WAX218
 | |
| -	DEVICE_DTS_CONFIG := config@hk07
 | |
| -	BLOCKSIZE := 128k
 | |
| -	PAGESIZE := 2048
 | |
| -	SOC := ipq8072
 | |
| -	ARTIFACT/web-ui-factory.fit := append-image initramfs-uImage.itb | \
 | |
| -		ubinize-kernel | qsdk-ipq-factory-nand
 | |
| -	DEVICE_PACKAGES := kmod-spi-gpio kmod-spi-bitbang kmod-gpio-nxp-74hc164 \
 | |
| -		ipq-wifi-netgear_wax218
 | |
| -endef
 | |
| -TARGET_DEVICES += netgear_wax218
 | |
| -
 | |
| -define Device/prpl_haze
 | |
| -	$(call Device/FitImage)
 | |
| -	$(call Device/EmmcImage)
 | |
| -	DEVICE_VENDOR := prpl Foundation
 | |
| -	DEVICE_MODEL := Haze
 | |
| -	DEVICE_DTS_CONFIG := config@hk09
 | |
| -	SOC := ipq8072
 | |
| -	DEVICE_PACKAGES += ath11k-firmware-qcn9074 ipq-wifi-prpl_haze kmod-ath11k-pci
 | |
| -endef
 | |
| -TARGET_DEVICES += prpl_haze
 | |
| -
 | |
| -define Device/qnap_301w
 | |
| -	$(call Device/FitImage)
 | |
| -	$(call Device/EmmcImage)
 | |
| -	DEVICE_VENDOR := QNAP
 | |
| -	DEVICE_MODEL := 301w
 | |
| -	DEVICE_DTS_CONFIG := config@hk01
 | |
| -	KERNEL_SIZE := 16384k
 | |
| -	SOC := ipq8072
 | |
| -	DEVICE_PACKAGES += ipq-wifi-qnap_301w
 | |
| -endef
 | |
| -TARGET_DEVICES += qnap_301w
 | |
| -
 | |
| -define Device/redmi_ax6
 | |
| -	$(call Device/xiaomi_ax3600)
 | |
| -	DEVICE_VENDOR := Redmi
 | |
| -	DEVICE_MODEL := AX6
 | |
| -	DEVICE_PACKAGES := ipq-wifi-redmi_ax6
 | |
| -endef
 | |
| -TARGET_DEVICES += redmi_ax6
 | |
| -
 | |
| -define Device/xiaomi_ax3600
 | |
| -	$(call Device/FitImage)
 | |
| -	$(call Device/UbiFit)
 | |
| -	DEVICE_VENDOR := Xiaomi
 | |
| -	DEVICE_MODEL := AX3600
 | |
| -	BLOCKSIZE := 128k
 | |
| -	PAGESIZE := 2048
 | |
| -	DEVICE_DTS_CONFIG := config@ac04
 | |
| -	SOC := ipq8071
 | |
| -	KERNEL_SIZE := 36608k
 | |
| -	DEVICE_PACKAGES := ipq-wifi-xiaomi_ax3600 kmod-ath10k-ct-smallbuffers ath10k-firmware-qca9887-ct
 | |
| -ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
 | |
| -	ARTIFACTS := initramfs-factory.ubi
 | |
| -	ARTIFACT/initramfs-factory.ubi := append-image-stage initramfs-uImage.itb | ubinize-kernel
 | |
| -endif
 | |
| -endef
 | |
| -TARGET_DEVICES += xiaomi_ax3600
 | |
| -
 | |
| -define Device/xiaomi_ax9000
 | |
| -	$(call Device/FitImage)
 | |
| -	$(call Device/UbiFit)
 | |
| -	DEVICE_VENDOR := Xiaomi
 | |
| -	DEVICE_MODEL := AX9000
 | |
| -	BLOCKSIZE := 128k
 | |
| -	PAGESIZE := 2048
 | |
| -	DEVICE_DTS_CONFIG := config@hk14
 | |
| -	SOC := ipq8072
 | |
| -	KERNEL_SIZE := 57344k
 | |
| -	DEVICE_PACKAGES := ipq-wifi-xiaomi_ax9000 kmod-ath11k-pci ath11k-firmware-qcn9074 \
 | |
| -	kmod-ath10k-ct ath10k-firmware-qca9887-ct
 | |
| -ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),)
 | |
| -	ARTIFACTS := initramfs-factory.ubi
 | |
| -	ARTIFACT/initramfs-factory.ubi := append-image-stage initramfs-uImage.itb | ubinize-kernel
 | |
| -endif
 | |
| -endef
 | |
| -TARGET_DEVICES += xiaomi_ax9000
 | |
| -
 | |
| -define Device/zyxel_nbg7815
 | |
| -	$(call Device/FitImage)
 | |
| -	$(call Device/EmmcImage)
 | |
| -	DEVICE_VENDOR := ZYXEL
 | |
| -	DEVICE_MODEL := NBG7815
 | |
| -	DEVICE_DTS_CONFIG := config@nbg7815
 | |
| -	SOC := ipq8074
 | |
| -	DEVICE_PACKAGES += ipq-wifi-zyxel_nbg7815 kmod-ath11k-pci kmod-hwmon-tmp103 \
 | |
| -		kmod-bluetooth
 | |
| -endef
 | |
| -TARGET_DEVICES += zyxel_nbg7815
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0001-v5.16-arm64-dts-qcom-ipq8074-add-SPMI-bus.patch b/target/linux/ipq807x/patches-5.15/0001-v5.16-arm64-dts-qcom-ipq8074-add-SPMI-bus.patch
 | |
| deleted file mode 100644
 | |
| index f1c0923301..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0001-v5.16-arm64-dts-qcom-ipq8074-add-SPMI-bus.patch
 | |
| +++ /dev/null
 | |
| @@ -1,43 +0,0 @@
 | |
| -From adf62d2727d4aa2b587e2db59eafb5be776a653c Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sun, 5 Sep 2021 18:58:16 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add SPMI bus
 | |
| -
 | |
| -IPQ8074 uses SPMI for communication with the PMIC, so
 | |
| -since its already supported add the DT node for it.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20210905165816.655275-1-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 19 +++++++++++++++++++
 | |
| - 1 file changed, 19 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -320,6 +320,25 @@
 | |
| - 			#reset-cells = <0x1>;
 | |
| - 		};
 | |
| - 
 | |
| -+		spmi_bus: spmi@200f000 {
 | |
| -+			compatible = "qcom,spmi-pmic-arb";
 | |
| -+			reg = <0x0200f000 0x001000>,
 | |
| -+			      <0x02400000 0x800000>,
 | |
| -+			      <0x02c00000 0x800000>,
 | |
| -+			      <0x03800000 0x200000>,
 | |
| -+			      <0x0200a000 0x000700>;
 | |
| -+			reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
 | |
| -+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
 | |
| -+			interrupt-names = "periph_irq";
 | |
| -+			qcom,ee = <0>;
 | |
| -+			qcom,channel = <0>;
 | |
| -+			#address-cells = <2>;
 | |
| -+			#size-cells = <0>;
 | |
| -+			interrupt-controller;
 | |
| -+			#interrupt-cells = <4>;
 | |
| -+			cell-index = <0>;
 | |
| -+		};
 | |
| -+
 | |
| - 		sdhc_1: sdhci@7824900 {
 | |
| - 			compatible = "qcom,sdhci-msm-v4";
 | |
| - 			reg = <0x7824900 0x500>, <0x7824000 0x800>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0002-v5.16-arm64-dts-qcom-Update-BAM-DMA-node-name-per-DT-schem.patch b/target/linux/ipq807x/patches-5.15/0002-v5.16-arm64-dts-qcom-Update-BAM-DMA-node-name-per-DT-schem.patch
 | |
| deleted file mode 100644
 | |
| index 0e31970a82..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0002-v5.16-arm64-dts-qcom-Update-BAM-DMA-node-name-per-DT-schem.patch
 | |
| +++ /dev/null
 | |
| @@ -1,26 +0,0 @@
 | |
| -From 94343612f165fc8b4f95fcbe6fd044d6f63d4a28 Mon Sep 17 00:00:00 2001
 | |
| -From: Shawn Guo <shawn.guo@linaro.org>
 | |
| -Date: Tue, 31 Aug 2021 13:23:25 +0800
 | |
| -Subject: [PATCH] arm64: dts: qcom: Update BAM DMA node name per DT schema
 | |
| -
 | |
| -Follow dma-controller.yaml schema to use `dma-controller` as node name
 | |
| -of BAM DMA devices.
 | |
| -
 | |
| -Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20210831052325.21229-1-shawn.guo@linaro.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +-
 | |
| - 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -239,7 +239,7 @@
 | |
| - 			status = "disabled";
 | |
| - 		};
 | |
| - 
 | |
| --		cryptobam: dma@704000 {
 | |
| -+		cryptobam: dma-controller@704000 {
 | |
| - 			compatible = "qcom,bam-v1.7.0";
 | |
| - 			reg = <0x00704000 0x20000>;
 | |
| - 			interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0003-v5.16-arm64-dts-qcom-ipq8074-Add-QUP5-I2C-node.patch b/target/linux/ipq807x/patches-5.15/0003-v5.16-arm64-dts-qcom-ipq8074-Add-QUP5-I2C-node.patch
 | |
| deleted file mode 100644
 | |
| index b20cbe1b37..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0003-v5.16-arm64-dts-qcom-ipq8074-Add-QUP5-I2C-node.patch
 | |
| +++ /dev/null
 | |
| @@ -1,40 +0,0 @@
 | |
| -From ccc5b088058bccdf454bd296867c47e56c415cde Mon Sep 17 00:00:00 2001
 | |
| -From: Chukun Pan <amadeus@jmu.edu.cn>
 | |
| -Date: Fri, 1 Oct 2021 22:54:21 +0800
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: Add QUP5 I2C node
 | |
| -
 | |
| -Add node to support the QUP5 I2C controller inside of IPQ8074.
 | |
| -It is exactly the same as QUP2 controllers.
 | |
| -Some routers like ZTE MF269 use this bus.
 | |
| -
 | |
| -Signed-off-by: Chukun Pan <amadeus@jmu.edu.cn>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20211001145421.18302-1-amadeus@jmu.edu.cn
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 15 +++++++++++++++
 | |
| - 1 file changed, 15 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -457,6 +457,21 @@
 | |
| - 			status = "disabled";
 | |
| - 		};
 | |
| - 
 | |
| -+		blsp1_i2c5: i2c@78b9000 {
 | |
| -+			compatible = "qcom,i2c-qup-v2.2.1";
 | |
| -+			#address-cells = <1>;
 | |
| -+			#size-cells = <0>;
 | |
| -+			reg = <0x78b9000 0x600>;
 | |
| -+			interrupts = <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>;
 | |
| -+			clocks = <&gcc GCC_BLSP1_AHB_CLK>,
 | |
| -+				 <&gcc GCC_BLSP1_QUP5_I2C_APPS_CLK>;
 | |
| -+			clock-names = "iface", "core";
 | |
| -+			clock-frequency = <400000>;
 | |
| -+			dmas = <&blsp_dma 21>, <&blsp_dma 20>;
 | |
| -+			dma-names = "rx", "tx";
 | |
| -+			status = "disabled";
 | |
| -+		};
 | |
| -+
 | |
| - 		blsp1_i2c6: i2c@78ba000 {
 | |
| - 			compatible = "qcom,i2c-qup-v2.2.1";
 | |
| - 			#address-cells = <1>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0004-v5.16-arm64-dts-qcom-msm8996-Move-clock-cells-to-QMP-PHY-c.patch b/target/linux/ipq807x/patches-5.15/0004-v5.16-arm64-dts-qcom-msm8996-Move-clock-cells-to-QMP-PHY-c.patch
 | |
| deleted file mode 100644
 | |
| index 94fc27750c..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0004-v5.16-arm64-dts-qcom-msm8996-Move-clock-cells-to-QMP-PHY-c.patch
 | |
| +++ /dev/null
 | |
| @@ -1,53 +0,0 @@
 | |
| -From 1a82d7080001d395563ad8266d120d4cf63ad0a5 Mon Sep 17 00:00:00 2001
 | |
| -From: Shawn Guo <shawn.guo@linaro.org>
 | |
| -Date: Wed, 29 Sep 2021 11:42:46 +0800
 | |
| -Subject: [PATCH] arm64: dts: qcom: msm8996: Move '#clock-cells' to QMP PHY
 | |
| - child node
 | |
| -
 | |
| -'#clock-cells' is a required property of QMP PHY child node, not itself.
 | |
| -Move it to fix the dtbs_check warnings.
 | |
| -
 | |
| -There are only '#clock-cells' removal from SM8350 QMP PHY nodes, because
 | |
| -child nodes already have the property.
 | |
| -
 | |
| -Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20210929034253.24570-4-shawn.guo@linaro.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++--
 | |
| - 1 file changed, 2 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -91,7 +91,6 @@
 | |
| - 		ssphy_1: phy@58000 {
 | |
| - 			compatible = "qcom,ipq8074-qmp-usb3-phy";
 | |
| - 			reg = <0x00058000 0x1c4>;
 | |
| --			#clock-cells = <1>;
 | |
| - 			#address-cells = <1>;
 | |
| - 			#size-cells = <1>;
 | |
| - 			ranges;
 | |
| -@@ -112,6 +111,7 @@
 | |
| - 				      <0x00058800 0x1f8>,     /* PCS  */
 | |
| - 				      <0x00058600 0x044>;     /* PCS misc*/
 | |
| - 				#phy-cells = <0>;
 | |
| -+				#clock-cells = <1>;
 | |
| - 				clocks = <&gcc GCC_USB1_PIPE_CLK>;
 | |
| - 				clock-names = "pipe0";
 | |
| - 				clock-output-names = "usb3phy_1_cc_pipe_clk";
 | |
| -@@ -134,7 +134,6 @@
 | |
| - 		ssphy_0: phy@78000 {
 | |
| - 			compatible = "qcom,ipq8074-qmp-usb3-phy";
 | |
| - 			reg = <0x00078000 0x1c4>;
 | |
| --			#clock-cells = <1>;
 | |
| - 			#address-cells = <1>;
 | |
| - 			#size-cells = <1>;
 | |
| - 			ranges;
 | |
| -@@ -155,6 +154,7 @@
 | |
| - 				      <0x00078800 0x1f8>,     /* PCS  */
 | |
| - 				      <0x00078600 0x044>;     /* PCS misc*/
 | |
| - 				#phy-cells = <0>;
 | |
| -+				#clock-cells = <1>;
 | |
| - 				clocks = <&gcc GCC_USB0_PIPE_CLK>;
 | |
| - 				clock-names = "pipe0";
 | |
| - 				clock-output-names = "usb3phy_0_cc_pipe_clk";
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0007-v5.17-arm64-dts-qcom-ipq8074-add-MDIO-bus.patch b/target/linux/ipq807x/patches-5.15/0007-v5.17-arm64-dts-qcom-ipq8074-add-MDIO-bus.patch
 | |
| deleted file mode 100644
 | |
| index b31c06cb58..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0007-v5.17-arm64-dts-qcom-ipq8074-add-MDIO-bus.patch
 | |
| +++ /dev/null
 | |
| @@ -1,36 +0,0 @@
 | |
| -From 036e332e29ee24396ad877cc6a1275d86a1c4b3d Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Thu, 7 Oct 2021 13:58:46 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add MDIO bus
 | |
| -
 | |
| -IPQ8074 uses an IPQ4019 compatible MDIO controller that is already
 | |
| -supported in the kernel, so add the DT node in order to use it.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20211007115846.26255-1-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 12 ++++++++++++
 | |
| - 1 file changed, 12 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -231,6 +231,18 @@
 | |
| - 			};
 | |
| - 		};
 | |
| - 
 | |
| -+		mdio: mdio@90000 {
 | |
| -+			compatible = "qcom,ipq4019-mdio";
 | |
| -+			reg = <0x00090000 0x64>;
 | |
| -+			#address-cells = <1>;
 | |
| -+			#size-cells = <0>;
 | |
| -+
 | |
| -+			clocks = <&gcc GCC_MDIO_AHB_CLK>;
 | |
| -+			clock-names = "gcc_mdio_ahb_clk";
 | |
| -+
 | |
| -+			status = "disabled";
 | |
| -+		};
 | |
| -+
 | |
| - 		prng: rng@e3000 {
 | |
| - 			compatible = "qcom,prng-ee";
 | |
| - 			reg = <0x000e3000 0x1000>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0008-v5.18-arm64-dts-qcom-ipq8074-add-SMEM-support.patch b/target/linux/ipq807x/patches-5.15/0008-v5.18-arm64-dts-qcom-ipq8074-add-SMEM-support.patch
 | |
| deleted file mode 100644
 | |
| index afaa2bae82..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0008-v5.18-arm64-dts-qcom-ipq8074-add-SMEM-support.patch
 | |
| +++ /dev/null
 | |
| @@ -1,51 +0,0 @@
 | |
| -From 29e135cf87900ac1da457bb27e98e30ca7f723ea Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Thu, 6 Jan 2022 22:25:12 +0100
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add SMEM support
 | |
| -
 | |
| -IPQ8074 uses SMEM like other modern QCA SoC-s, so since its already
 | |
| -supported by the kernel add the required DT nodes.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220106212512.1970828-1-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 20 ++++++++++++++++++++
 | |
| - 1 file changed, 20 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -76,6 +76,20 @@
 | |
| - 		method = "smc";
 | |
| - 	};
 | |
| - 
 | |
| -+	reserved-memory {
 | |
| -+		#address-cells = <2>;
 | |
| -+		#size-cells = <2>;
 | |
| -+		ranges;
 | |
| -+
 | |
| -+		smem@4ab00000 {
 | |
| -+			compatible = "qcom,smem";
 | |
| -+			reg = <0x0 0x4ab00000 0x0 0x00100000>;
 | |
| -+			no-map;
 | |
| -+
 | |
| -+			hwlocks = <&tcsr_mutex 0>;
 | |
| -+		};
 | |
| -+	};
 | |
| -+
 | |
| - 	firmware {
 | |
| - 		scm {
 | |
| - 			compatible = "qcom,scm-ipq8074", "qcom,scm";
 | |
| -@@ -332,6 +346,12 @@
 | |
| - 			#reset-cells = <0x1>;
 | |
| - 		};
 | |
| - 
 | |
| -+		tcsr_mutex: hwlock@1905000 {
 | |
| -+			compatible = "qcom,tcsr-mutex";
 | |
| -+			reg = <0x01905000 0x20000>;
 | |
| -+			#hwlock-cells = <1>;
 | |
| -+		};
 | |
| -+
 | |
| - 		spmi_bus: spmi@200f000 {
 | |
| - 			compatible = "qcom,spmi-pmic-arb";
 | |
| - 			reg = <0x0200f000 0x001000>,
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0009-v5.18-arm64-dts-qcom-ipq8074-add-the-reserved-memory-node.patch b/target/linux/ipq807x/patches-5.15/0009-v5.18-arm64-dts-qcom-ipq8074-add-the-reserved-memory-node.patch
 | |
| deleted file mode 100644
 | |
| index 6b0db7092d..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0009-v5.18-arm64-dts-qcom-ipq8074-add-the-reserved-memory-node.patch
 | |
| +++ /dev/null
 | |
| @@ -1,30 +0,0 @@
 | |
| -From 0f1cdeea7f237de21f244c06f2c102f93dbd9c4e Mon Sep 17 00:00:00 2001
 | |
| -From: Kathiravan T <quic_kathirav@quicinc.com>
 | |
| -Date: Fri, 7 Jan 2022 18:24:38 +0530
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add the reserved-memory node
 | |
| -
 | |
| -On IPQ8074, 4MB of memory is needed for TZ. So mark that region
 | |
| -as reserved.
 | |
| -
 | |
| -Signed-off-by: Kathiravan T <quic_kathirav@quicinc.com>
 | |
| -[bjorn: Squash with existing reserved-memory node]
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/1641560078-860-1-git-send-email-quic_kathirav@quicinc.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 5 +++++
 | |
| - 1 file changed, 5 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -88,6 +88,11 @@
 | |
| - 
 | |
| - 			hwlocks = <&tcsr_mutex 0>;
 | |
| - 		};
 | |
| -+
 | |
| -+		memory@4ac00000 {
 | |
| -+			no-map;
 | |
| -+			reg = <0x0 0x4ac00000 0x0 0x00400000>;
 | |
| -+		};
 | |
| - 	};
 | |
| - 
 | |
| - 	firmware {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0010-v5.18-arm64-dts-qcom-ipq8074-enable-the-GICv2m-support.patch b/target/linux/ipq807x/patches-5.15/0010-v5.18-arm64-dts-qcom-ipq8074-enable-the-GICv2m-support.patch
 | |
| deleted file mode 100644
 | |
| index 3d5372a6e6..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0010-v5.18-arm64-dts-qcom-ipq8074-enable-the-GICv2m-support.patch
 | |
| +++ /dev/null
 | |
| @@ -1,36 +0,0 @@
 | |
| -From a505f23abf0c31f40a2c3070d82e961b7c045664 Mon Sep 17 00:00:00 2001
 | |
| -From: Kathiravan T <quic_kathirav@quicinc.com>
 | |
| -Date: Tue, 8 Feb 2022 21:05:24 +0530
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: enable the GICv2m support
 | |
| -
 | |
| -GIC used in the IPQ8074 SoCs has one instance of the GICv2m extension,
 | |
| -which supports upto 32 MSI interrupts. Lets add support for the same.
 | |
| -
 | |
| -Signed-off-by: Kathiravan T <quic_kathirav@quicinc.com>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/1644334525-11577-2-git-send-email-quic_kathirav@quicinc.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 9 +++++++++
 | |
| - 1 file changed, 9 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -635,9 +635,18 @@
 | |
| - 
 | |
| - 		intc: interrupt-controller@b000000 {
 | |
| - 			compatible = "qcom,msm-qgic2";
 | |
| -+			#address-cells = <1>;
 | |
| -+			#size-cells = <1>;
 | |
| - 			interrupt-controller;
 | |
| - 			#interrupt-cells = <0x3>;
 | |
| - 			reg = <0x0b000000 0x1000>, <0x0b002000 0x1000>;
 | |
| -+			ranges = <0 0xb00a000 0xffd>;
 | |
| -+
 | |
| -+			v2m@0 {
 | |
| -+				compatible = "arm,gic-v2m-frame";
 | |
| -+				msi-controller;
 | |
| -+				reg = <0x0 0xffd>;
 | |
| -+			};
 | |
| - 		};
 | |
| - 
 | |
| - 		timer {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0011-v5.18-arm64-dts-qcom-ipq8074-drop-the-clock-frequency-prop.patch b/target/linux/ipq807x/patches-5.15/0011-v5.18-arm64-dts-qcom-ipq8074-drop-the-clock-frequency-prop.patch
 | |
| deleted file mode 100644
 | |
| index 9018087e40..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0011-v5.18-arm64-dts-qcom-ipq8074-drop-the-clock-frequency-prop.patch
 | |
| +++ /dev/null
 | |
| @@ -1,25 +0,0 @@
 | |
| -From 2a73fa24be1d5a263062696f55dcc90725f9159c Mon Sep 17 00:00:00 2001
 | |
| -From: Kathiravan T <quic_kathirav@quicinc.com>
 | |
| -Date: Wed, 2 Feb 2022 22:05:08 +0530
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: drop the clock-frequency property
 | |
| -
 | |
| -Drop the clock-frequency property from the MMIO timer node, since it
 | |
| -is already configured by the bootloader.
 | |
| -
 | |
| -Signed-off-by: Kathiravan T <quic_kathirav@quicinc.com>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/1643819709-5410-2-git-send-email-quic_kathirav@quicinc.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 1 -
 | |
| - 1 file changed, 1 deletion(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -671,7 +671,6 @@
 | |
| - 			ranges;
 | |
| - 			compatible = "arm,armv7-timer-mem";
 | |
| - 			reg = <0x0b120000 0x1000>;
 | |
| --			clock-frequency = <19200000>;
 | |
| - 
 | |
| - 			frame@b120000 {
 | |
| - 				frame-number = <0>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0012-v5.19-arm64-dts-qcom-align-dmas-in-I2C-SPI-UART-with-DT-sc.patch b/target/linux/ipq807x/patches-5.15/0012-v5.19-arm64-dts-qcom-align-dmas-in-I2C-SPI-UART-with-DT-sc.patch
 | |
| deleted file mode 100644
 | |
| index 19be9bd861..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0012-v5.19-arm64-dts-qcom-align-dmas-in-I2C-SPI-UART-with-DT-sc.patch
 | |
| +++ /dev/null
 | |
| @@ -1,61 +0,0 @@
 | |
| -From 6f39b05b13e7be39919fd8d235bb0e63ecabf190 Mon Sep 17 00:00:00 2001
 | |
| -From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Date: Tue, 5 Apr 2022 08:34:43 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: align dmas in I2C/SPI/UART with DT schema
 | |
| -
 | |
| -The DT schema expects dma channels in tx-rx order.  No functional
 | |
| -change.
 | |
| -
 | |
| -Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220405063451.12011-2-krzysztof.kozlowski@linaro.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 16 ++++++++--------
 | |
| - 1 file changed, 8 insertions(+), 8 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -472,8 +472,8 @@
 | |
| - 				<&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>;
 | |
| - 			clock-names = "iface", "core";
 | |
| - 			clock-frequency = <400000>;
 | |
| --			dmas = <&blsp_dma 15>, <&blsp_dma 14>;
 | |
| --			dma-names = "rx", "tx";
 | |
| -+			dmas = <&blsp_dma 14>, <&blsp_dma 15>;
 | |
| -+			dma-names = "tx", "rx";
 | |
| - 			pinctrl-0 = <&i2c_0_pins>;
 | |
| - 			pinctrl-names = "default";
 | |
| - 			status = "disabled";
 | |
| -@@ -489,8 +489,8 @@
 | |
| - 				<&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>;
 | |
| - 			clock-names = "iface", "core";
 | |
| - 			clock-frequency = <100000>;
 | |
| --			dmas = <&blsp_dma 17>, <&blsp_dma 16>;
 | |
| --			dma-names = "rx", "tx";
 | |
| -+			dmas = <&blsp_dma 16>, <&blsp_dma 17>;
 | |
| -+			dma-names = "tx", "rx";
 | |
| - 			status = "disabled";
 | |
| - 		};
 | |
| - 
 | |
| -@@ -504,8 +504,8 @@
 | |
| - 				 <&gcc GCC_BLSP1_QUP5_I2C_APPS_CLK>;
 | |
| - 			clock-names = "iface", "core";
 | |
| - 			clock-frequency = <400000>;
 | |
| --			dmas = <&blsp_dma 21>, <&blsp_dma 20>;
 | |
| --			dma-names = "rx", "tx";
 | |
| -+			dmas = <&blsp_dma 20>, <&blsp_dma 21>;
 | |
| -+			dma-names = "tx", "rx";
 | |
| - 			status = "disabled";
 | |
| - 		};
 | |
| - 
 | |
| -@@ -519,8 +519,8 @@
 | |
| - 				 <&gcc GCC_BLSP1_QUP6_I2C_APPS_CLK>;
 | |
| - 			clock-names = "iface", "core";
 | |
| - 			clock-frequency = <100000>;
 | |
| --			dmas = <&blsp_dma 23>, <&blsp_dma 22>;
 | |
| --			dma-names = "rx", "tx";
 | |
| -+			dmas = <&blsp_dma 22>, <&blsp_dma 23>;
 | |
| -+			dma-names = "tx", "rx";
 | |
| - 			status = "disabled";
 | |
| - 		};
 | |
| - 
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0013-v5.19-arm64-dts-qcom-align-clocks-in-I2C-SPI-with-DT-schem.patch b/target/linux/ipq807x/patches-5.15/0013-v5.19-arm64-dts-qcom-align-clocks-in-I2C-SPI-with-DT-schem.patch
 | |
| deleted file mode 100644
 | |
| index d1c214c2c7..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0013-v5.19-arm64-dts-qcom-align-clocks-in-I2C-SPI-with-DT-schem.patch
 | |
| +++ /dev/null
 | |
| @@ -1,68 +0,0 @@
 | |
| -From 61d4a1751cfe5a22e5f18478fe16ffb1ee12607d Mon Sep 17 00:00:00 2001
 | |
| -From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Date: Tue, 5 Apr 2022 08:34:44 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: align clocks in I2C/SPI with DT schema
 | |
| -
 | |
| -The DT schema expects clocks core-iface order.  No functional change.
 | |
| -
 | |
| -Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220405063451.12011-3-krzysztof.kozlowski@linaro.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 24 ++++++++++++------------
 | |
| - 1 file changed, 12 insertions(+), 12 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -468,9 +468,9 @@
 | |
| - 			#size-cells = <0>;
 | |
| - 			reg = <0x078b6000 0x600>;
 | |
| - 			interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
 | |
| --			clocks = <&gcc GCC_BLSP1_AHB_CLK>,
 | |
| --				<&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>;
 | |
| --			clock-names = "iface", "core";
 | |
| -+			clocks = <&gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>,
 | |
| -+				 <&gcc GCC_BLSP1_AHB_CLK>;
 | |
| -+			clock-names = "core", "iface";
 | |
| - 			clock-frequency = <400000>;
 | |
| - 			dmas = <&blsp_dma 14>, <&blsp_dma 15>;
 | |
| - 			dma-names = "tx", "rx";
 | |
| -@@ -485,9 +485,9 @@
 | |
| - 			#size-cells = <0>;
 | |
| - 			reg = <0x078b7000 0x600>;
 | |
| - 			interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
 | |
| --			clocks = <&gcc GCC_BLSP1_AHB_CLK>,
 | |
| --				<&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>;
 | |
| --			clock-names = "iface", "core";
 | |
| -+			clocks = <&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>,
 | |
| -+				 <&gcc GCC_BLSP1_AHB_CLK>;
 | |
| -+			clock-names = "core", "iface";
 | |
| - 			clock-frequency = <100000>;
 | |
| - 			dmas = <&blsp_dma 16>, <&blsp_dma 17>;
 | |
| - 			dma-names = "tx", "rx";
 | |
| -@@ -500,9 +500,9 @@
 | |
| - 			#size-cells = <0>;
 | |
| - 			reg = <0x78b9000 0x600>;
 | |
| - 			interrupts = <GIC_SPI 299 IRQ_TYPE_LEVEL_HIGH>;
 | |
| --			clocks = <&gcc GCC_BLSP1_AHB_CLK>,
 | |
| --				 <&gcc GCC_BLSP1_QUP5_I2C_APPS_CLK>;
 | |
| --			clock-names = "iface", "core";
 | |
| -+			clocks = <&gcc GCC_BLSP1_QUP5_I2C_APPS_CLK>,
 | |
| -+				 <&gcc GCC_BLSP1_AHB_CLK>;
 | |
| -+			clock-names = "core", "iface";
 | |
| - 			clock-frequency = <400000>;
 | |
| - 			dmas = <&blsp_dma 20>, <&blsp_dma 21>;
 | |
| - 			dma-names = "tx", "rx";
 | |
| -@@ -515,9 +515,9 @@
 | |
| - 			#size-cells = <0>;
 | |
| - 			reg = <0x078ba000 0x600>;
 | |
| - 			interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
 | |
| --			clocks = <&gcc GCC_BLSP1_AHB_CLK>,
 | |
| --				 <&gcc GCC_BLSP1_QUP6_I2C_APPS_CLK>;
 | |
| --			clock-names = "iface", "core";
 | |
| -+			clocks = <&gcc GCC_BLSP1_QUP6_I2C_APPS_CLK>,
 | |
| -+				 <&gcc GCC_BLSP1_AHB_CLK>;
 | |
| -+			clock-names = "core", "iface";
 | |
| - 			clock-frequency = <100000>;
 | |
| - 			dmas = <&blsp_dma 22>, <&blsp_dma 23>;
 | |
| - 			dma-names = "tx", "rx";
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0014-v5.19-arm64-dts-qcom-correct-DWC3-node-names-and-unit-addr.patch b/target/linux/ipq807x/patches-5.15/0014-v5.19-arm64-dts-qcom-correct-DWC3-node-names-and-unit-addr.patch
 | |
| deleted file mode 100644
 | |
| index 1b41f97002..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0014-v5.19-arm64-dts-qcom-correct-DWC3-node-names-and-unit-addr.patch
 | |
| +++ /dev/null
 | |
| @@ -1,36 +0,0 @@
 | |
| -From ee9002a825695b5dca76f758a9365ca7f7d18265 Mon Sep 17 00:00:00 2001
 | |
| -From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Date: Wed, 4 May 2022 15:19:16 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: correct DWC3 node names and unit addresses
 | |
| -
 | |
| -Align DWC3 USB node names with DT schema ("usb" is expected) and correct
 | |
| -the unit addresses to match the "reg" property.  This also implies
 | |
| -overriding nodes by label, instead of full path.
 | |
| -
 | |
| -Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220504131923.214367-7-krzysztof.kozlowski@linaro.org
 | |
| -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++--
 | |
| - 1 file changed, 2 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -579,7 +579,7 @@
 | |
| - 			resets = <&gcc GCC_USB0_BCR>;
 | |
| - 			status = "disabled";
 | |
| - 
 | |
| --			dwc_0: dwc3@8a00000 {
 | |
| -+			dwc_0: usb@8a00000 {
 | |
| - 				compatible = "snps,dwc3";
 | |
| - 				reg = <0x8a00000 0xcd00>;
 | |
| - 				interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
 | |
| -@@ -619,7 +619,7 @@
 | |
| - 			resets = <&gcc GCC_USB1_BCR>;
 | |
| - 			status = "disabled";
 | |
| - 
 | |
| --			dwc_1: dwc3@8c00000 {
 | |
| -+			dwc_1: usb@8c00000 {
 | |
| - 				compatible = "snps,dwc3";
 | |
| - 				reg = <0x8c00000 0xcd00>;
 | |
| - 				interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0015-v5.19-arm64-dts-qcom-ipq8074-add-dedicated-qcom-ipq8074-dw.patch b/target/linux/ipq807x/patches-5.15/0015-v5.19-arm64-dts-qcom-ipq8074-add-dedicated-qcom-ipq8074-dw.patch
 | |
| deleted file mode 100644
 | |
| index 68173e81d2..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0015-v5.19-arm64-dts-qcom-ipq8074-add-dedicated-qcom-ipq8074-dw.patch
 | |
| +++ /dev/null
 | |
| @@ -1,36 +0,0 @@
 | |
| -From 71061acf1a9343317e4d34a2c4578ed9301112cc Mon Sep 17 00:00:00 2001
 | |
| -From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Date: Wed, 4 May 2022 15:19:17 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add dedicated qcom,ipq8074-dwc3
 | |
| - compatible
 | |
| -
 | |
| -Add dedicated compatible for DWC3 USB node name to allow more accurate
 | |
| -DT schema matching.
 | |
| -
 | |
| -Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220504131923.214367-8-krzysztof.kozlowski@linaro.org
 | |
| -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++--
 | |
| - 1 file changed, 2 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -554,7 +554,7 @@
 | |
| - 		};
 | |
| - 
 | |
| - 		usb_0: usb@8af8800 {
 | |
| --			compatible = "qcom,dwc3";
 | |
| -+			compatible = "qcom,ipq8074-dwc3", "qcom,dwc3";
 | |
| - 			reg = <0x08af8800 0x400>;
 | |
| - 			#address-cells = <1>;
 | |
| - 			#size-cells = <1>;
 | |
| -@@ -594,7 +594,7 @@
 | |
| - 		};
 | |
| - 
 | |
| - 		usb_1: usb@8cf8800 {
 | |
| --			compatible = "qcom,dwc3";
 | |
| -+			compatible = "qcom,ipq8074-dwc3", "qcom,dwc3";
 | |
| - 			reg = <0x08cf8800 0x400>;
 | |
| - 			#address-cells = <1>;
 | |
| - 			#size-cells = <1>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0016-v5.19-arm64-dts-qcom-align-DWC3-USB-clocks-with-DT-schema.patch b/target/linux/ipq807x/patches-5.15/0016-v5.19-arm64-dts-qcom-align-DWC3-USB-clocks-with-DT-schema.patch
 | |
| deleted file mode 100644
 | |
| index de7c3eaffc..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0016-v5.19-arm64-dts-qcom-align-DWC3-USB-clocks-with-DT-schema.patch
 | |
| +++ /dev/null
 | |
| @@ -1,39 +0,0 @@
 | |
| -From 159cbe595c1018a0172c637374ec69af643fa9f5 Mon Sep 17 00:00:00 2001
 | |
| -From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Date: Wed, 4 May 2022 15:19:22 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: align DWC3 USB clocks with DT schema
 | |
| -
 | |
| -Align order of clocks and their names with Qualcomm DWC3 USB DT schema.
 | |
| -No functional impact expected.
 | |
| -
 | |
| -Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220504131923.214367-13-krzysztof.kozlowski@linaro.org
 | |
| -Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 8 ++++----
 | |
| - 1 file changed, 4 insertions(+), 4 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -564,8 +564,8 @@
 | |
| - 				<&gcc GCC_USB0_MASTER_CLK>,
 | |
| - 				<&gcc GCC_USB0_SLEEP_CLK>,
 | |
| - 				<&gcc GCC_USB0_MOCK_UTMI_CLK>;
 | |
| --			clock-names = "sys_noc_axi",
 | |
| --				"master",
 | |
| -+			clock-names = "cfg_noc",
 | |
| -+				"core",
 | |
| - 				"sleep",
 | |
| - 				"mock_utmi";
 | |
| - 
 | |
| -@@ -604,8 +604,8 @@
 | |
| - 				<&gcc GCC_USB1_MASTER_CLK>,
 | |
| - 				<&gcc GCC_USB1_SLEEP_CLK>,
 | |
| - 				<&gcc GCC_USB1_MOCK_UTMI_CLK>;
 | |
| --			clock-names = "sys_noc_axi",
 | |
| --				"master",
 | |
| -+			clock-names = "cfg_noc",
 | |
| -+				"core",
 | |
| - 				"sleep",
 | |
| - 				"mock_utmi";
 | |
| - 
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0017-v6.0-arm64-dts-qcom-adjust-whitespace-around.patch b/target/linux/ipq807x/patches-5.15/0017-v6.0-arm64-dts-qcom-adjust-whitespace-around.patch
 | |
| deleted file mode 100644
 | |
| index 515582da5c..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0017-v6.0-arm64-dts-qcom-adjust-whitespace-around.patch
 | |
| +++ /dev/null
 | |
| @@ -1,36 +0,0 @@
 | |
| -From a9f7dc27469ca9588d7aa572bdfdfd5f0f1aab6a Mon Sep 17 00:00:00 2001
 | |
| -From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Date: Thu, 26 May 2022 22:42:47 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: adjust whitespace around '='
 | |
| -
 | |
| -Fix whitespace coding style: use single space instead of tabs or
 | |
| -multiple spaces around '=' sign in property assignment.  No functional
 | |
| -changes (same DTB).
 | |
| -
 | |
| -Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220526204248.832139-1-krzysztof.kozlowski@linaro.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++--
 | |
| - 1 file changed, 2 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -119,7 +119,7 @@
 | |
| - 				<&xo>;
 | |
| - 			clock-names = "aux", "cfg_ahb", "ref";
 | |
| - 
 | |
| --			resets =  <&gcc GCC_USB1_PHY_BCR>,
 | |
| -+			resets = <&gcc GCC_USB1_PHY_BCR>,
 | |
| - 				<&gcc GCC_USB3PHY_1_PHY_BCR>;
 | |
| - 			reset-names = "phy","common";
 | |
| - 			status = "disabled";
 | |
| -@@ -162,7 +162,7 @@
 | |
| - 				<&xo>;
 | |
| - 			clock-names = "aux", "cfg_ahb", "ref";
 | |
| - 
 | |
| --			resets =  <&gcc GCC_USB0_PHY_BCR>,
 | |
| -+			resets = <&gcc GCC_USB0_PHY_BCR>,
 | |
| - 				<&gcc GCC_USB3PHY_0_PHY_BCR>;
 | |
| - 			reset-names = "phy","common";
 | |
| - 			status = "disabled";
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0018-v6.0-arm64-dts-qcom-Fix-sdhci-node-names-use-mmc.patch b/target/linux/ipq807x/patches-5.15/0018-v6.0-arm64-dts-qcom-Fix-sdhci-node-names-use-mmc.patch
 | |
| deleted file mode 100644
 | |
| index 20f7dc926d..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0018-v6.0-arm64-dts-qcom-Fix-sdhci-node-names-use-mmc.patch
 | |
| +++ /dev/null
 | |
| @@ -1,34 +0,0 @@
 | |
| -From 2e9703ffe97a1c447c0d00c061526fbeeade6107 Mon Sep 17 00:00:00 2001
 | |
| -From: Bhupesh Sharma <bhupesh.sharma@linaro.org>
 | |
| -Date: Sun, 15 May 2022 03:24:19 +0530
 | |
| -Subject: [PATCH] arm64: dts: qcom: Fix sdhci node names - use 'mmc@'
 | |
| -
 | |
| -Since the Qualcomm sdhci-msm device-tree binding has been converted
 | |
| -to yaml format, 'make dtbs_check' reports issues with
 | |
| -inconsistent 'sdhci@' convention used for specifying the
 | |
| -sdhci nodes. The generic mmc bindings expect 'mmc@' format
 | |
| -instead.
 | |
| -
 | |
| -Fix the same.
 | |
| -
 | |
| -Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Cc: Rob Herring <robh@kernel.org>
 | |
| -Signed-off-by: Bhupesh Sharma <bhupesh.sharma@linaro.org>
 | |
| -[bjorn: Moved non-arm64 changes to separate commit]
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220514215424.1007718-2-bhupesh.sharma@linaro.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +-
 | |
| - 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -376,7 +376,7 @@
 | |
| - 			cell-index = <0>;
 | |
| - 		};
 | |
| - 
 | |
| --		sdhc_1: sdhci@7824900 {
 | |
| -+		sdhc_1: mmc@7824900 {
 | |
| - 			compatible = "qcom,sdhci-msm-v4";
 | |
| - 			reg = <0x7824900 0x500>, <0x7824000 0x800>;
 | |
| - 			reg-names = "hc_mem", "core_mem";
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0019-v6.0-arm64-dts-qcom-Fix-ordering-of-clocks-clock-names-fo.patch b/target/linux/ipq807x/patches-5.15/0019-v6.0-arm64-dts-qcom-Fix-ordering-of-clocks-clock-names-fo.patch
 | |
| deleted file mode 100644
 | |
| index 24fd7fc9f7..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0019-v6.0-arm64-dts-qcom-Fix-ordering-of-clocks-clock-names-fo.patch
 | |
| +++ /dev/null
 | |
| @@ -1,47 +0,0 @@
 | |
| -From 18363f691e931abf0e9bdc9b5169fb15aa10224d Mon Sep 17 00:00:00 2001
 | |
| -From: Bhupesh Sharma <bhupesh.sharma@linaro.org>
 | |
| -Date: Sun, 15 May 2022 03:24:22 +0530
 | |
| -Subject: [PATCH] arm64: dts: qcom: Fix ordering of 'clocks' & 'clock-names'
 | |
| - for sdhci nodes
 | |
| -
 | |
| -Since the Qualcomm sdhci-msm device-tree binding has been converted
 | |
| -to yaml format, 'make dtbs_check' reports a number of issues with
 | |
| -ordering of 'clocks' & 'clock-names' for sdhci nodes:
 | |
| -
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk10-c2.dtb: sdhci@7824900:
 | |
| -  clock-names:0: 'iface' was expected
 | |
| -
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk10-c2.dtb: sdhci@7824900:
 | |
| -  clock-names:1: 'core' was expected
 | |
| -
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk10-c2.dtb: sdhci@7824900:
 | |
| -  clock-names:2: 'xo' was expected
 | |
| -
 | |
| -Fix the same by updating the offending 'dts' files.
 | |
| -
 | |
| -Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Cc: Rob Herring <robh@kernel.org>
 | |
| -Signed-off-by: Bhupesh Sharma <bhupesh.sharma@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220514215424.1007718-5-bhupesh.sharma@linaro.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 8 ++++----
 | |
| - 1 file changed, 4 insertions(+), 4 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -385,10 +385,10 @@
 | |
| - 				     <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
 | |
| - 			interrupt-names = "hc_irq", "pwr_irq";
 | |
| - 
 | |
| --			clocks = <&xo>,
 | |
| --				 <&gcc GCC_SDCC1_AHB_CLK>,
 | |
| --				 <&gcc GCC_SDCC1_APPS_CLK>;
 | |
| --			clock-names = "xo", "iface", "core";
 | |
| -+			clocks = <&gcc GCC_SDCC1_AHB_CLK>,
 | |
| -+				 <&gcc GCC_SDCC1_APPS_CLK>,
 | |
| -+				 <&xo>;
 | |
| -+			clock-names = "iface", "core", "xo";
 | |
| - 			max-frequency = <384000000>;
 | |
| - 			mmc-ddr-1_8v;
 | |
| - 			mmc-hs200-1_8v;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0020-v6.0-dt-bindings-clock-qcom-ipq8074-add-PPE-crypto-clock.patch b/target/linux/ipq807x/patches-5.15/0020-v6.0-dt-bindings-clock-qcom-ipq8074-add-PPE-crypto-clock.patch
 | |
| deleted file mode 100644
 | |
| index f2055d94b1..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0020-v6.0-dt-bindings-clock-qcom-ipq8074-add-PPE-crypto-clock.patch
 | |
| +++ /dev/null
 | |
| @@ -1,25 +0,0 @@
 | |
| -From aa14b0c11f6442cd489d33c2855941055a3d4fa6 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sun, 15 May 2022 23:00:41 +0200
 | |
| -Subject: [PATCH] dt-bindings: clock: qcom: ipq8074: add PPE crypto clock
 | |
| -
 | |
| -Add binding for the PPE crypto clock in IPQ8074.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220515210048.483898-4-robimarko@gmail.com
 | |
| ----
 | |
| - include/dt-bindings/clock/qcom,gcc-ipq8074.h | 1 +
 | |
| - 1 file changed, 1 insertion(+)
 | |
| -
 | |
| ---- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
 | |
| -+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
 | |
| -@@ -233,6 +233,7 @@
 | |
| - #define GCC_PCIE0_AXI_S_BRIDGE_CLK		224
 | |
| - #define GCC_PCIE0_RCHNG_CLK_SRC			225
 | |
| - #define GCC_PCIE0_RCHNG_CLK			226
 | |
| -+#define GCC_CRYPTO_PPE_CLK			227
 | |
| - 
 | |
| - #define GCC_BLSP1_BCR				0
 | |
| - #define GCC_BLSP1_QUP1_BCR			1
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0021-v6.0-clk-qcom-ipq8074-add-PPE-crypto-clock.patch b/target/linux/ipq807x/patches-5.15/0021-v6.0-clk-qcom-ipq8074-add-PPE-crypto-clock.patch
 | |
| deleted file mode 100644
 | |
| index 71fd33331d..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0021-v6.0-clk-qcom-ipq8074-add-PPE-crypto-clock.patch
 | |
| +++ /dev/null
 | |
| @@ -1,52 +0,0 @@
 | |
| -From f91d0e8bd6c1f812bc2589050c05a90ee886c749 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sun, 15 May 2022 23:00:42 +0200
 | |
| -Subject: [PATCH] clk: qcom: ipq8074: add PPE crypto clock
 | |
| -
 | |
| -The built-in PPE engine has a dedicated clock for the EIP-197 crypto
 | |
| -engine.
 | |
| -
 | |
| -So, since the required clock currently missing add support for it.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220515210048.483898-5-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/clk/qcom/gcc-ipq8074.c | 19 +++++++++++++++++++
 | |
| - 1 file changed, 19 insertions(+)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -+++ b/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -@@ -3183,6 +3183,24 @@ static struct clk_branch gcc_nss_ptp_ref
 | |
| - 	},
 | |
| - };
 | |
| - 
 | |
| -+static struct clk_branch gcc_crypto_ppe_clk = {
 | |
| -+	.halt_reg = 0x68310,
 | |
| -+	.halt_bit = 31,
 | |
| -+	.clkr = {
 | |
| -+		.enable_reg = 0x68310,
 | |
| -+		.enable_mask = BIT(0),
 | |
| -+		.hw.init = &(struct clk_init_data){
 | |
| -+			.name = "gcc_crypto_ppe_clk",
 | |
| -+			.parent_names = (const char *[]){
 | |
| -+				"nss_ppe_clk_src"
 | |
| -+			},
 | |
| -+			.num_parents = 1,
 | |
| -+			.flags = CLK_SET_RATE_PARENT,
 | |
| -+			.ops = &clk_branch2_ops,
 | |
| -+		},
 | |
| -+	},
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_branch gcc_nssnoc_ce_apb_clk = {
 | |
| - 	.halt_reg = 0x6830c,
 | |
| - 	.clkr = {
 | |
| -@@ -4655,6 +4673,7 @@ static struct clk_regmap *gcc_ipq8074_cl
 | |
| - 	[GCC_PCIE0_RCHNG_CLK_SRC] = &pcie0_rchng_clk_src.clkr,
 | |
| - 	[GCC_PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr,
 | |
| - 	[GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr,
 | |
| -+	[GCC_CRYPTO_PPE_CLK] = &gcc_crypto_ppe_clk.clkr,
 | |
| - };
 | |
| - 
 | |
| - static const struct qcom_reset_map gcc_ipq8074_resets[] = {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0022-v6.0-dt-bindings-clock-qcom-ipq8074-add-USB-GDSCs.patch b/target/linux/ipq807x/patches-5.15/0022-v6.0-dt-bindings-clock-qcom-ipq8074-add-USB-GDSCs.patch
 | |
| deleted file mode 100644
 | |
| index 908ed233b2..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0022-v6.0-dt-bindings-clock-qcom-ipq8074-add-USB-GDSCs.patch
 | |
| +++ /dev/null
 | |
| @@ -1,25 +0,0 @@
 | |
| -From f5441c669d5442d247c69bab3eb27c074c0dd19a Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sun, 15 May 2022 23:00:45 +0200
 | |
| -Subject: [PATCH] dt-bindings: clock: qcom: ipq8074: add USB GDSCs
 | |
| -
 | |
| -Add bindings for the USB GDSCs found in IPQ8074 GCC.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220515210048.483898-8-robimarko@gmail.com
 | |
| ----
 | |
| - include/dt-bindings/clock/qcom,gcc-ipq8074.h | 3 +++
 | |
| - 1 file changed, 3 insertions(+)
 | |
| -
 | |
| ---- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
 | |
| -+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
 | |
| -@@ -368,4 +368,7 @@
 | |
| - #define GCC_PCIE1_AXI_MASTER_STICKY_ARES	130
 | |
| - #define GCC_PCIE0_AXI_SLAVE_STICKY_ARES		131
 | |
| - 
 | |
| -+#define USB0_GDSC				0
 | |
| -+#define USB1_GDSC				1
 | |
| -+
 | |
| - #endif
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0023-v6.0-clk-qcom-ipq8074-add-USB-GDSCs.patch b/target/linux/ipq807x/patches-5.15/0023-v6.0-clk-qcom-ipq8074-add-USB-GDSCs.patch
 | |
| deleted file mode 100644
 | |
| index 7fcb190578..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0023-v6.0-clk-qcom-ipq8074-add-USB-GDSCs.patch
 | |
| +++ /dev/null
 | |
| @@ -1,79 +0,0 @@
 | |
| -From ff35d239b7b64f71d7dd9d0ce887647de2cacfcc Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sun, 15 May 2022 23:00:46 +0200
 | |
| -Subject: [PATCH] clk: qcom: ipq8074: add USB GDSCs
 | |
| -
 | |
| -Add GDSC-s for each of the two USB controllers built-in the IPQ8074.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220515210048.483898-9-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/clk/qcom/Kconfig       |  1 +
 | |
| - drivers/clk/qcom/gcc-ipq8074.c | 24 ++++++++++++++++++++++++
 | |
| - 2 files changed, 25 insertions(+)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/Kconfig
 | |
| -+++ b/drivers/clk/qcom/Kconfig
 | |
| -@@ -166,6 +166,7 @@ config IPQ_LCC_806X
 | |
| - 
 | |
| - config IPQ_GCC_8074
 | |
| - 	tristate "IPQ8074 Global Clock Controller"
 | |
| -+	select QCOM_GDSC
 | |
| - 	help
 | |
| - 	  Support for global clock controller on ipq8074 devices.
 | |
| - 	  Say Y if you want to use peripheral devices such as UART, SPI,
 | |
| ---- a/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -+++ b/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -@@ -22,6 +22,7 @@
 | |
| - #include "clk-alpha-pll.h"
 | |
| - #include "clk-regmap-divider.h"
 | |
| - #include "clk-regmap-mux.h"
 | |
| -+#include "gdsc.h"
 | |
| - #include "reset.h"
 | |
| - 
 | |
| - enum {
 | |
| -@@ -4408,6 +4409,22 @@ static struct clk_branch gcc_pcie0_axi_s
 | |
| - 	},
 | |
| - };
 | |
| - 
 | |
| -+static struct gdsc usb0_gdsc = {
 | |
| -+	.gdscr = 0x3e078,
 | |
| -+	.pd = {
 | |
| -+		.name = "usb0_gdsc",
 | |
| -+	},
 | |
| -+	.pwrsts = PWRSTS_OFF_ON,
 | |
| -+};
 | |
| -+
 | |
| -+static struct gdsc usb1_gdsc = {
 | |
| -+	.gdscr = 0x3f078,
 | |
| -+	.pd = {
 | |
| -+		.name = "usb1_gdsc",
 | |
| -+	},
 | |
| -+	.pwrsts = PWRSTS_OFF_ON,
 | |
| -+};
 | |
| -+
 | |
| - static const struct alpha_pll_config ubi32_pll_config = {
 | |
| - 	.l = 0x4e,
 | |
| - 	.config_ctl_val = 0x200d4aa8,
 | |
| -@@ -4811,6 +4828,11 @@ static const struct qcom_reset_map gcc_i
 | |
| - 	[GCC_PCIE1_AXI_MASTER_STICKY_ARES] = { 0x76040, 6 },
 | |
| - };
 | |
| - 
 | |
| -+static struct gdsc *gcc_ipq8074_gdscs[] = {
 | |
| -+	[USB0_GDSC] = &usb0_gdsc,
 | |
| -+	[USB1_GDSC] = &usb1_gdsc,
 | |
| -+};
 | |
| -+
 | |
| - static const struct of_device_id gcc_ipq8074_match_table[] = {
 | |
| - 	{ .compatible = "qcom,gcc-ipq8074" },
 | |
| - 	{ }
 | |
| -@@ -4833,6 +4855,8 @@ static const struct qcom_cc_desc gcc_ipq
 | |
| - 	.num_resets = ARRAY_SIZE(gcc_ipq8074_resets),
 | |
| - 	.clk_hws = gcc_ipq8074_hws,
 | |
| - 	.num_clk_hws = ARRAY_SIZE(gcc_ipq8074_hws),
 | |
| -+	.gdscs = gcc_ipq8074_gdscs,
 | |
| -+	.num_gdscs = ARRAY_SIZE(gcc_ipq8074_gdscs),
 | |
| - };
 | |
| - 
 | |
| - static int gcc_ipq8074_probe(struct platform_device *pdev)
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0024-v6.0-arm64-dts-qcom-ipq8074-add-USB-power-domains.patch b/target/linux/ipq807x/patches-5.15/0024-v6.0-arm64-dts-qcom-ipq8074-add-USB-power-domains.patch
 | |
| deleted file mode 100644
 | |
| index d515ec9076..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0024-v6.0-arm64-dts-qcom-ipq8074-add-USB-power-domains.patch
 | |
| +++ /dev/null
 | |
| @@ -1,43 +0,0 @@
 | |
| -From 53211e85006ebb9bf7fb4482288639612f3146e7 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sun, 15 May 2022 23:00:48 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add USB power domains
 | |
| -
 | |
| -Add USB power domains provided by GCC GDSCs.
 | |
| -Add the required #power-domain-cells to the GCC as well.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220515210048.483898-11-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 5 +++++
 | |
| - 1 file changed, 5 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -348,6 +348,7 @@
 | |
| - 			compatible = "qcom,gcc-ipq8074";
 | |
| - 			reg = <0x01800000 0x80000>;
 | |
| - 			#clock-cells = <0x1>;
 | |
| -+			#power-domain-cells = <1>;
 | |
| - 			#reset-cells = <0x1>;
 | |
| - 		};
 | |
| - 
 | |
| -@@ -576,6 +577,8 @@
 | |
| - 						<133330000>,
 | |
| - 						<19200000>;
 | |
| - 
 | |
| -+			power-domains = <&gcc USB0_GDSC>;
 | |
| -+
 | |
| - 			resets = <&gcc GCC_USB0_BCR>;
 | |
| - 			status = "disabled";
 | |
| - 
 | |
| -@@ -616,6 +619,8 @@
 | |
| - 						<133330000>,
 | |
| - 						<19200000>;
 | |
| - 
 | |
| -+			power-domains = <&gcc USB1_GDSC>;
 | |
| -+
 | |
| - 			resets = <&gcc GCC_USB1_BCR>;
 | |
| - 			status = "disabled";
 | |
| - 
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0025-v6.0-arm64-dts-qcom-ipq8074-move-ARMv8-timer-out-of-SoC-n.patch b/target/linux/ipq807x/patches-5.15/0025-v6.0-arm64-dts-qcom-ipq8074-move-ARMv8-timer-out-of-SoC-n.patch
 | |
| deleted file mode 100644
 | |
| index 57fe73ae92..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0025-v6.0-arm64-dts-qcom-ipq8074-move-ARMv8-timer-out-of-SoC-n.patch
 | |
| +++ /dev/null
 | |
| @@ -1,50 +0,0 @@
 | |
| -From 85a9cab9b9bb471eae016cdbfabd928585c23cce Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Mon, 4 Jul 2022 13:33:18 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: move ARMv8 timer out of SoC node
 | |
| -
 | |
| -The ARM timer is usually considered not part of SoC node, just like
 | |
| -other ARM designed blocks (PMU, PSCI).  This fixes dtbs_check warning:
 | |
| -
 | |
| -arch/arm64/boot/dts/qcom/ipq8072-ax9000.dtb: soc: timer: {'compatible': ['arm,armv8-timer'], 'interrupts': [[1, 2, 3848], [1, 3, 3848], [1, 4, 3848], [1, 1, 3848]]} should not be valid under {'type': 'object'}
 | |
| -	From schema: dtschema/schemas/simple-bus.yaml
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -[bjorn: Moved node after "soc" for alphabetical ordering]
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220704113318.623102-1-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 16 ++++++++--------
 | |
| - 1 file changed, 8 insertions(+), 8 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -654,14 +654,6 @@
 | |
| - 			};
 | |
| - 		};
 | |
| - 
 | |
| --		timer {
 | |
| --			compatible = "arm,armv8-timer";
 | |
| --			interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 | |
| --				     <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 | |
| --				     <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 | |
| --				     <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 | |
| --		};
 | |
| --
 | |
| - 		watchdog: watchdog@b017000 {
 | |
| - 			compatible = "qcom,kpss-wdt";
 | |
| - 			reg = <0xb017000 0x1000>;
 | |
| -@@ -853,4 +845,12 @@
 | |
| - 			status = "disabled";
 | |
| - 		};
 | |
| - 	};
 | |
| -+
 | |
| -+	timer {
 | |
| -+		compatible = "arm,armv8-timer";
 | |
| -+		interrupts = <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 | |
| -+			     <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 | |
| -+			     <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 | |
| -+			     <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 | |
| -+	};
 | |
| - };
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0026-v6.0-arm64-dts-qcom-ipq8074-add-reset-to-SDHCI.patch b/target/linux/ipq807x/patches-5.15/0026-v6.0-arm64-dts-qcom-ipq8074-add-reset-to-SDHCI.patch
 | |
| deleted file mode 100644
 | |
| index b262a804b3..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0026-v6.0-arm64-dts-qcom-ipq8074-add-reset-to-SDHCI.patch
 | |
| +++ /dev/null
 | |
| @@ -1,27 +0,0 @@
 | |
| -From 8e6af077ced3931ac18e37f0eb3fc6f1a20b0e4a Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Mon, 4 Jul 2022 16:35:54 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add reset to SDHCI
 | |
| -
 | |
| -Add reset to SDHCI controller so it can be reset to avoid timeout issues
 | |
| -after software reset due to bootloader set configuration.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
 | |
| -Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220704143554.1180927-2-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 1 +
 | |
| - 1 file changed, 1 insertion(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -390,6 +390,7 @@
 | |
| - 				 <&gcc GCC_SDCC1_APPS_CLK>,
 | |
| - 				 <&xo>;
 | |
| - 			clock-names = "iface", "core", "xo";
 | |
| -+			resets = <&gcc GCC_SDCC1_BCR>;
 | |
| - 			max-frequency = <384000000>;
 | |
| - 			mmc-ddr-1_8v;
 | |
| - 			mmc-hs200-1_8v;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0027-v6.0-arm64-dts-qcom-ipq8074-drop-USB-PHY-clock-index.patch b/target/linux/ipq807x/patches-5.15/0027-v6.0-arm64-dts-qcom-ipq8074-drop-USB-PHY-clock-index.patch
 | |
| deleted file mode 100644
 | |
| index c058c5abe4..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0027-v6.0-arm64-dts-qcom-ipq8074-drop-USB-PHY-clock-index.patch
 | |
| +++ /dev/null
 | |
| @@ -1,36 +0,0 @@
 | |
| -From 0171978734227bdd7813bc6d805f609126e3849e Mon Sep 17 00:00:00 2001
 | |
| -From: Johan Hovold <johan+linaro@kernel.org>
 | |
| -Date: Tue, 5 Jul 2022 13:40:22 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: drop USB PHY clock index
 | |
| -
 | |
| -The QMP USB PHY provides a single clock so drop the redundant clock
 | |
| -index.
 | |
| -
 | |
| -Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
 | |
| -Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220705114032.22787-5-johan+linaro@kernel.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++--
 | |
| - 1 file changed, 2 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -130,7 +130,7 @@
 | |
| - 				      <0x00058800 0x1f8>,     /* PCS  */
 | |
| - 				      <0x00058600 0x044>;     /* PCS misc*/
 | |
| - 				#phy-cells = <0>;
 | |
| --				#clock-cells = <1>;
 | |
| -+				#clock-cells = <0>;
 | |
| - 				clocks = <&gcc GCC_USB1_PIPE_CLK>;
 | |
| - 				clock-names = "pipe0";
 | |
| - 				clock-output-names = "usb3phy_1_cc_pipe_clk";
 | |
| -@@ -173,7 +173,7 @@
 | |
| - 				      <0x00078800 0x1f8>,     /* PCS  */
 | |
| - 				      <0x00078600 0x044>;     /* PCS misc*/
 | |
| - 				#phy-cells = <0>;
 | |
| --				#clock-cells = <1>;
 | |
| -+				#clock-cells = <0>;
 | |
| - 				clocks = <&gcc GCC_USB0_PIPE_CLK>;
 | |
| - 				clock-names = "pipe0";
 | |
| - 				clock-output-names = "usb3phy_0_cc_pipe_clk";
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0028-v5.16-mailbox-qcom-apcs-ipc-Consolidate-msm8994-type-apcs_.patch b/target/linux/ipq807x/patches-5.15/0028-v5.16-mailbox-qcom-apcs-ipc-Consolidate-msm8994-type-apcs_.patch
 | |
| deleted file mode 100644
 | |
| index e50c66f531..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0028-v5.16-mailbox-qcom-apcs-ipc-Consolidate-msm8994-type-apcs_.patch
 | |
| +++ /dev/null
 | |
| @@ -1,74 +0,0 @@
 | |
| -From a6e1d17fbfd41113bf47345e65953873e717ca63 Mon Sep 17 00:00:00 2001
 | |
| -From: Shawn Guo <shawn.guo@linaro.org>
 | |
| -Date: Tue, 14 Sep 2021 09:40:48 +0800
 | |
| -Subject: [PATCH] mailbox: qcom-apcs-ipc: Consolidate msm8994 type apcs_data
 | |
| -
 | |
| -The msm8994 type of apcs_data is defined multiple times with different
 | |
| -SoC name encoded.  Consolidate them on msm8994 and remove the data
 | |
| -duplication.
 | |
| -
 | |
| -Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
 | |
| -Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
 | |
| ----
 | |
| - drivers/mailbox/qcom-apcs-ipc-mailbox.c | 26 +++++--------------------
 | |
| - 1 file changed, 5 insertions(+), 21 deletions(-)
 | |
| -
 | |
| ---- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c
 | |
| -+++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
 | |
| -@@ -33,10 +33,6 @@ static const struct qcom_apcs_ipc_data i
 | |
| - 	.offset = 8, .clk_name = "qcom,apss-ipq6018-clk"
 | |
| - };
 | |
| - 
 | |
| --static const struct qcom_apcs_ipc_data ipq8074_apcs_data = {
 | |
| --	.offset = 8, .clk_name = NULL
 | |
| --};
 | |
| --
 | |
| - static const struct qcom_apcs_ipc_data msm8916_apcs_data = {
 | |
| - 	.offset = 8, .clk_name = "qcom-apcs-msm8916-clk"
 | |
| - };
 | |
| -@@ -49,18 +45,6 @@ static const struct qcom_apcs_ipc_data m
 | |
| - 	.offset = 16, .clk_name = NULL
 | |
| - };
 | |
| - 
 | |
| --static const struct qcom_apcs_ipc_data msm8998_apcs_data = {
 | |
| --	.offset = 8, .clk_name = NULL
 | |
| --};
 | |
| --
 | |
| --static const struct qcom_apcs_ipc_data sdm660_apcs_data = {
 | |
| --	.offset = 8, .clk_name = NULL
 | |
| --};
 | |
| --
 | |
| --static const struct qcom_apcs_ipc_data sm6125_apcs_data = {
 | |
| --	.offset = 8, .clk_name = NULL
 | |
| --};
 | |
| --
 | |
| - static const struct qcom_apcs_ipc_data apps_shared_apcs_data = {
 | |
| - 	.offset = 12, .clk_name = NULL
 | |
| - };
 | |
| -@@ -160,21 +144,21 @@ static int qcom_apcs_ipc_remove(struct p
 | |
| - /* .data is the offset of the ipc register within the global block */
 | |
| - static const struct of_device_id qcom_apcs_ipc_of_match[] = {
 | |
| - 	{ .compatible = "qcom,ipq6018-apcs-apps-global", .data = &ipq6018_apcs_data },
 | |
| --	{ .compatible = "qcom,ipq8074-apcs-apps-global", .data = &ipq8074_apcs_data },
 | |
| -+	{ .compatible = "qcom,ipq8074-apcs-apps-global", .data = &msm8994_apcs_data },
 | |
| - 	{ .compatible = "qcom,msm8916-apcs-kpss-global", .data = &msm8916_apcs_data },
 | |
| - 	{ .compatible = "qcom,msm8939-apcs-kpss-global", .data = &msm8916_apcs_data },
 | |
| - 	{ .compatible = "qcom,msm8953-apcs-kpss-global", .data = &msm8994_apcs_data },
 | |
| - 	{ .compatible = "qcom,msm8994-apcs-kpss-global", .data = &msm8994_apcs_data },
 | |
| - 	{ .compatible = "qcom,msm8996-apcs-hmss-global", .data = &msm8996_apcs_data },
 | |
| --	{ .compatible = "qcom,msm8998-apcs-hmss-global", .data = &msm8998_apcs_data },
 | |
| -+	{ .compatible = "qcom,msm8998-apcs-hmss-global", .data = &msm8994_apcs_data },
 | |
| - 	{ .compatible = "qcom,qcs404-apcs-apps-global", .data = &msm8916_apcs_data },
 | |
| - 	{ .compatible = "qcom,sc7180-apss-shared", .data = &apps_shared_apcs_data },
 | |
| - 	{ .compatible = "qcom,sc8180x-apss-shared", .data = &apps_shared_apcs_data },
 | |
| --	{ .compatible = "qcom,sdm660-apcs-hmss-global", .data = &sdm660_apcs_data },
 | |
| -+	{ .compatible = "qcom,sdm660-apcs-hmss-global", .data = &msm8994_apcs_data },
 | |
| - 	{ .compatible = "qcom,sdm845-apss-shared", .data = &apps_shared_apcs_data },
 | |
| --	{ .compatible = "qcom,sm6125-apcs-hmss-global", .data = &sm6125_apcs_data },
 | |
| -+	{ .compatible = "qcom,sm6125-apcs-hmss-global", .data = &msm8994_apcs_data },
 | |
| - 	{ .compatible = "qcom,sm8150-apss-shared", .data = &apps_shared_apcs_data },
 | |
| --	{ .compatible = "qcom,sm6115-apcs-hmss-global", .data = &sdm660_apcs_data },
 | |
| -+	{ .compatible = "qcom,sm6115-apcs-hmss-global", .data = &msm8994_apcs_data },
 | |
| - 	{ .compatible = "qcom,sdx55-apcs-gcc", .data = &sdx55_apcs_data },
 | |
| - 	{}
 | |
| - };
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0029-v6.1-mailbox-qcom-apcs-ipc-add-IPQ8074-APSS-clock-support.patch b/target/linux/ipq807x/patches-5.15/0029-v6.1-mailbox-qcom-apcs-ipc-add-IPQ8074-APSS-clock-support.patch
 | |
| deleted file mode 100644
 | |
| index cd1dcf2ba2..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0029-v6.1-mailbox-qcom-apcs-ipc-add-IPQ8074-APSS-clock-support.patch
 | |
| +++ /dev/null
 | |
| @@ -1,30 +0,0 @@
 | |
| -From 28e239ecd69a99748181bfdf5d2238ff1a8d0646 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:08:48 +0200
 | |
| -Subject: [PATCH] mailbox: qcom-apcs-ipc: add IPQ8074 APSS clock support
 | |
| -
 | |
| -IPQ8074 has the APSS clock controller utilizing the same register space as
 | |
| -the APCS, so provide access to the APSS utilizing a child device like
 | |
| -IPQ6018.
 | |
| -
 | |
| -IPQ6018 and IPQ8074 use the same controller and driver, so just utilize
 | |
| -IPQ6018 match data for IPQ8074.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
 | |
| ----
 | |
| - drivers/mailbox/qcom-apcs-ipc-mailbox.c | 2 +-
 | |
| - 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| -
 | |
| ---- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c
 | |
| -+++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c
 | |
| -@@ -144,7 +144,7 @@ static int qcom_apcs_ipc_remove(struct p
 | |
| - /* .data is the offset of the ipc register within the global block */
 | |
| - static const struct of_device_id qcom_apcs_ipc_of_match[] = {
 | |
| - 	{ .compatible = "qcom,ipq6018-apcs-apps-global", .data = &ipq6018_apcs_data },
 | |
| --	{ .compatible = "qcom,ipq8074-apcs-apps-global", .data = &msm8994_apcs_data },
 | |
| -+	{ .compatible = "qcom,ipq8074-apcs-apps-global", .data = &ipq6018_apcs_data },
 | |
| - 	{ .compatible = "qcom,msm8916-apcs-kpss-global", .data = &msm8916_apcs_data },
 | |
| - 	{ .compatible = "qcom,msm8939-apcs-kpss-global", .data = &msm8916_apcs_data },
 | |
| - 	{ .compatible = "qcom,msm8953-apcs-kpss-global", .data = &msm8994_apcs_data },
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0030-v6.0-arm64-dts-qcom-ipq8074-add-APCS-node.patch b/target/linux/ipq807x/patches-5.15/0030-v6.0-arm64-dts-qcom-ipq8074-add-APCS-node.patch
 | |
| deleted file mode 100644
 | |
| index 87a1fe82e7..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0030-v6.0-arm64-dts-qcom-ipq8074-add-APCS-node.patch
 | |
| +++ /dev/null
 | |
| @@ -1,37 +0,0 @@
 | |
| -From aea90e172420a062197849d7914b2fa032de0228 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Thu, 7 Jul 2022 19:37:33 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add APCS node
 | |
| -
 | |
| -APCS now has support for providing the APSS clocks as the child device
 | |
| -for IPQ8074.
 | |
| -
 | |
| -So, add the required DT node for it as it will later be used as the CPU
 | |
| -clocksource.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -[bjorn: Sorted node based on address]
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220707173733.404947-4-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 8 ++++++++
 | |
| - 1 file changed, 8 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -663,6 +663,14 @@
 | |
| - 			timeout-sec = <30>;
 | |
| - 		};
 | |
| - 
 | |
| -+		apcs_glb: mailbox@b111000 {
 | |
| -+			compatible = "qcom,ipq8074-apcs-apps-global";
 | |
| -+			reg = <0x0b111000 0x6000>;
 | |
| -+
 | |
| -+			#clock-cells = <1>;
 | |
| -+			#mbox-cells = <1>;
 | |
| -+		};
 | |
| -+
 | |
| - 		timer@b120000 {
 | |
| - 			#address-cells = <1>;
 | |
| - 			#size-cells = <1>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0031-v6.0-arm64-dts-qcom-ipq8074-add-size-address-cells-to-DTS.patch b/target/linux/ipq807x/patches-5.15/0031-v6.0-arm64-dts-qcom-ipq8074-add-size-address-cells-to-DTS.patch
 | |
| deleted file mode 100644
 | |
| index 8fae8ade75..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0031-v6.0-arm64-dts-qcom-ipq8074-add-size-address-cells-to-DTS.patch
 | |
| +++ /dev/null
 | |
| @@ -1,54 +0,0 @@
 | |
| -From a3f36600fd758173c1ec315684e4ae72c6e85654 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 8 Jul 2022 15:38:45 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add #size/address-cells to DTSI
 | |
| -
 | |
| -Add #size-cells and #address-cells to the SoC DTSI to avoid duplicating
 | |
| -the same properties in board DTS files.
 | |
| -
 | |
| -Remove the mentioned properties from current board DTS files.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220708133846.599735-1-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk01.dts  | 2 --
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi | 3 ---
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi      | 3 +++
 | |
| - 3 files changed, 3 insertions(+), 5 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -@@ -5,8 +5,6 @@
 | |
| - #include "ipq8074.dtsi"
 | |
| - 
 | |
| - / {
 | |
| --	#address-cells = <0x2>;
 | |
| --	#size-cells = <0x2>;
 | |
| - 	model = "Qualcomm Technologies, Inc. IPQ8074-HK01";
 | |
| - 	compatible = "qcom,ipq8074-hk01", "qcom,ipq8074";
 | |
| - 	interrupt-parent = <&intc>;
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
 | |
| -@@ -7,9 +7,6 @@
 | |
| - #include "ipq8074.dtsi"
 | |
| - 
 | |
| - / {
 | |
| --	#address-cells = <0x2>;
 | |
| --	#size-cells = <0x2>;
 | |
| --
 | |
| - 	interrupt-parent = <&intc>;
 | |
| - 
 | |
| - 	aliases {
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -7,6 +7,9 @@
 | |
| - #include <dt-bindings/clock/qcom,gcc-ipq8074.h>
 | |
| - 
 | |
| - / {
 | |
| -+	#address-cells = <2>;
 | |
| -+	#size-cells = <2>;
 | |
| -+
 | |
| - 	model = "Qualcomm Technologies, Inc. IPQ8074";
 | |
| - 	compatible = "qcom,ipq8074";
 | |
| - 
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0032-v6.0-arm64-dts-qcom-ipq8074-add-interrupt-parent-to-DTSI.patch b/target/linux/ipq807x/patches-5.15/0032-v6.0-arm64-dts-qcom-ipq8074-add-interrupt-parent-to-DTSI.patch
 | |
| deleted file mode 100644
 | |
| index 27a43c43ea..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0032-v6.0-arm64-dts-qcom-ipq8074-add-interrupt-parent-to-DTSI.patch
 | |
| +++ /dev/null
 | |
| @@ -1,50 +0,0 @@
 | |
| -From 7d57ca4d56856b7f7b97adda6e97cf5db4dcce93 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 8 Jul 2022 15:38:46 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add interrupt-parent to DTSI
 | |
| -
 | |
| -Add interrupt-parent to the SoC DTSI to avoid duplicating it in each board
 | |
| -DTS file.
 | |
| -
 | |
| -Remove interrupt-parent from existing board DTS files.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220708133846.599735-2-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk01.dts  | 1 -
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi | 2 --
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi      | 1 +
 | |
| - 3 files changed, 1 insertion(+), 3 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -@@ -7,7 +7,6 @@
 | |
| - / {
 | |
| - 	model = "Qualcomm Technologies, Inc. IPQ8074-HK01";
 | |
| - 	compatible = "qcom,ipq8074-hk01", "qcom,ipq8074";
 | |
| --	interrupt-parent = <&intc>;
 | |
| - 
 | |
| - 	aliases {
 | |
| - 		serial0 = &blsp1_uart5;
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
 | |
| -@@ -7,8 +7,6 @@
 | |
| - #include "ipq8074.dtsi"
 | |
| - 
 | |
| - / {
 | |
| --	interrupt-parent = <&intc>;
 | |
| --
 | |
| - 	aliases {
 | |
| - 		serial0 = &blsp1_uart5;
 | |
| - 	};
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -12,6 +12,7 @@
 | |
| - 
 | |
| - 	model = "Qualcomm Technologies, Inc. IPQ8074";
 | |
| - 	compatible = "qcom,ipq8074";
 | |
| -+	interrupt-parent = <&intc>;
 | |
| - 
 | |
| - 	clocks {
 | |
| - 		sleep_clk: sleep_clk {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0033-v6.1-arm64-dts-qcom-align-SDHCI-reg-names-with-DT-schema.patch b/target/linux/ipq807x/patches-5.15/0033-v6.1-arm64-dts-qcom-align-SDHCI-reg-names-with-DT-schema.patch
 | |
| deleted file mode 100644
 | |
| index f2fce43e5e..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0033-v6.1-arm64-dts-qcom-align-SDHCI-reg-names-with-DT-schema.patch
 | |
| +++ /dev/null
 | |
| @@ -1,28 +0,0 @@
 | |
| -From a19df563230af392f2e84e57d69367f96b4a8c56 Mon Sep 17 00:00:00 2001
 | |
| -From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Date: Tue, 12 Jul 2022 16:42:43 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: align SDHCI reg-names with DT schema
 | |
| -
 | |
| -DT schema requires SDHCI reg names to be hc/core without "_mem" suffix,
 | |
| -just like TXT bindings were expecting before the conversion.
 | |
| -
 | |
| -Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Reviewed-by: Douglas Anderson <dianders@chromium.org>
 | |
| -Reviewed-by: Konrad Dybcio <konrad.dybcio@somainline.org>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220712144245.17417-4-krzysztof.kozlowski@linaro.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +-
 | |
| - 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -384,7 +384,7 @@
 | |
| - 		sdhc_1: mmc@7824900 {
 | |
| - 			compatible = "qcom,sdhci-msm-v4";
 | |
| - 			reg = <0x7824900 0x500>, <0x7824000 0x800>;
 | |
| --			reg-names = "hc_mem", "core_mem";
 | |
| -+			reg-names = "hc", "core";
 | |
| - 
 | |
| - 			interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
 | |
| - 				     <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0035-v6.1-clk-qcom-apss-ipq-pll-use-OF-match-data-for-Alpha-PL.patch b/target/linux/ipq807x/patches-5.15/0035-v6.1-clk-qcom-apss-ipq-pll-use-OF-match-data-for-Alpha-PL.patch
 | |
| deleted file mode 100644
 | |
| index 2faf82baeb..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0035-v6.1-clk-qcom-apss-ipq-pll-use-OF-match-data-for-Alpha-PL.patch
 | |
| +++ /dev/null
 | |
| @@ -1,70 +0,0 @@
 | |
| -From 7bd608426c407a79debea54b2b243950f330c5b8 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:06:24 +0200
 | |
| -Subject: [PATCH] clk: qcom: apss-ipq-pll: use OF match data for Alpha PLL
 | |
| - config
 | |
| -
 | |
| -Convert the driver to use OF match data for providing the Alpha PLL config
 | |
| -per compatible.
 | |
| -This is required for IPQ8074 support since it uses a different Alpha PLL
 | |
| -config.
 | |
| -
 | |
| -While we are here rename "ipq_pll_config" to "ipq6018_pll_config" to make
 | |
| -it clear that it is for IPQ6018 only.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220628.339366-5-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/clk/qcom/apss-ipq-pll.c | 12 +++++++++---
 | |
| - 1 file changed, 9 insertions(+), 3 deletions(-)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/apss-ipq-pll.c
 | |
| -+++ b/drivers/clk/qcom/apss-ipq-pll.c
 | |
| -@@ -2,6 +2,7 @@
 | |
| - // Copyright (c) 2018, The Linux Foundation. All rights reserved.
 | |
| - #include <linux/clk-provider.h>
 | |
| - #include <linux/module.h>
 | |
| -+#include <linux/of_device.h>
 | |
| - #include <linux/platform_device.h>
 | |
| - #include <linux/regmap.h>
 | |
| - 
 | |
| -@@ -36,7 +37,7 @@ static struct clk_alpha_pll ipq_pll = {
 | |
| - 	},
 | |
| - };
 | |
| - 
 | |
| --static const struct alpha_pll_config ipq_pll_config = {
 | |
| -+static const struct alpha_pll_config ipq6018_pll_config = {
 | |
| - 	.l = 0x37,
 | |
| - 	.config_ctl_val = 0x04141200,
 | |
| - 	.config_ctl_hi_val = 0x0,
 | |
| -@@ -54,6 +55,7 @@ static const struct regmap_config ipq_pl
 | |
| - 
 | |
| - static int apss_ipq_pll_probe(struct platform_device *pdev)
 | |
| - {
 | |
| -+	const struct alpha_pll_config *ipq_pll_config;
 | |
| - 	struct device *dev = &pdev->dev;
 | |
| - 	struct regmap *regmap;
 | |
| - 	void __iomem *base;
 | |
| -@@ -67,7 +69,11 @@ static int apss_ipq_pll_probe(struct pla
 | |
| - 	if (IS_ERR(regmap))
 | |
| - 		return PTR_ERR(regmap);
 | |
| - 
 | |
| --	clk_alpha_pll_configure(&ipq_pll, regmap, &ipq_pll_config);
 | |
| -+	ipq_pll_config = of_device_get_match_data(&pdev->dev);
 | |
| -+	if (!ipq_pll_config)
 | |
| -+		return -ENODEV;
 | |
| -+
 | |
| -+	clk_alpha_pll_configure(&ipq_pll, regmap, ipq_pll_config);
 | |
| - 
 | |
| - 	ret = devm_clk_register_regmap(dev, &ipq_pll.clkr);
 | |
| - 	if (ret)
 | |
| -@@ -78,7 +84,7 @@ static int apss_ipq_pll_probe(struct pla
 | |
| - }
 | |
| - 
 | |
| - static const struct of_device_id apss_ipq_pll_match_table[] = {
 | |
| --	{ .compatible = "qcom,ipq6018-a53pll" },
 | |
| -+	{ .compatible = "qcom,ipq6018-a53pll", .data = &ipq6018_pll_config },
 | |
| - 	{ }
 | |
| - };
 | |
| - MODULE_DEVICE_TABLE(of, apss_ipq_pll_match_table);
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0036-v6.1-clk-qcom-apss-ipq-pll-update-IPQ6018-Alpha-PLL-confi.patch b/target/linux/ipq807x/patches-5.15/0036-v6.1-clk-qcom-apss-ipq-pll-update-IPQ6018-Alpha-PLL-confi.patch
 | |
| deleted file mode 100644
 | |
| index 4e1bb8aff2..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0036-v6.1-clk-qcom-apss-ipq-pll-update-IPQ6018-Alpha-PLL-confi.patch
 | |
| +++ /dev/null
 | |
| @@ -1,40 +0,0 @@
 | |
| -From d22c8f1bd94602d1bf2b377c3befe54e749b963d Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:06:25 +0200
 | |
| -Subject: [PATCH] clk: qcom: apss-ipq-pll: update IPQ6018 Alpha PLL config
 | |
| -
 | |
| -Update the IPQ6018 Alpha PLL config to the latest one from the downstream
 | |
| -5.4 kernel[1].
 | |
| -
 | |
| -This one should match the production SoC-s.
 | |
| -
 | |
| -Tested on IPQ6018 CP01-C1 reference board.
 | |
| -
 | |
| -[1] https://git.codelinaro.org/clo/qsdk/oss/kernel/linux-ipq-5.4/-/blob/NHSS.QSDK.12.1.r4/drivers/clk/qcom/apss-ipq-pll.c#L41
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220628.339366-6-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/clk/qcom/apss-ipq-pll.c | 8 ++++++--
 | |
| - 1 file changed, 6 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/apss-ipq-pll.c
 | |
| -+++ b/drivers/clk/qcom/apss-ipq-pll.c
 | |
| -@@ -39,10 +39,14 @@ static struct clk_alpha_pll ipq_pll = {
 | |
| - 
 | |
| - static const struct alpha_pll_config ipq6018_pll_config = {
 | |
| - 	.l = 0x37,
 | |
| --	.config_ctl_val = 0x04141200,
 | |
| --	.config_ctl_hi_val = 0x0,
 | |
| -+	.config_ctl_val = 0x240d4828,
 | |
| -+	.config_ctl_hi_val = 0x6,
 | |
| - 	.early_output_mask = BIT(3),
 | |
| -+	.aux2_output_mask = BIT(2),
 | |
| -+	.aux_output_mask = BIT(1),
 | |
| - 	.main_output_mask = BIT(0),
 | |
| -+	.test_ctl_val = 0x1c0000C0,
 | |
| -+	.test_ctl_hi_val = 0x4000,
 | |
| - };
 | |
| - 
 | |
| - static const struct regmap_config ipq_pll_regmap_config = {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0037-v6.1-clk-qcom-apss-ipq-pll-add-support-for-IPQ8074.patch b/target/linux/ipq807x/patches-5.15/0037-v6.1-clk-qcom-apss-ipq-pll-add-support-for-IPQ8074.patch
 | |
| deleted file mode 100644
 | |
| index f5f18acb1b..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0037-v6.1-clk-qcom-apss-ipq-pll-add-support-for-IPQ8074.patch
 | |
| +++ /dev/null
 | |
| @@ -1,47 +0,0 @@
 | |
| -From e0a711bd88ba98f6ab5118d248ec84fcf495d313 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:06:26 +0200
 | |
| -Subject: [PATCH] clk: qcom: apss-ipq-pll: add support for IPQ8074
 | |
| -
 | |
| -Add support for IPQ8074 since it uses the same PLL setup, however it uses
 | |
| -slightly different Alpha PLL config.
 | |
| -
 | |
| -Alpha PLL config was obtained by dumping PLL registers from a running
 | |
| -device.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220628.339366-7-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/clk/qcom/apss-ipq-pll.c | 13 +++++++++++++
 | |
| - 1 file changed, 13 insertions(+)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/apss-ipq-pll.c
 | |
| -+++ b/drivers/clk/qcom/apss-ipq-pll.c
 | |
| -@@ -49,6 +49,18 @@ static const struct alpha_pll_config ipq
 | |
| - 	.test_ctl_hi_val = 0x4000,
 | |
| - };
 | |
| - 
 | |
| -+static const struct alpha_pll_config ipq8074_pll_config = {
 | |
| -+	.l = 0x48,
 | |
| -+	.config_ctl_val = 0x200d4828,
 | |
| -+	.config_ctl_hi_val = 0x6,
 | |
| -+	.early_output_mask = BIT(3),
 | |
| -+	.aux2_output_mask = BIT(2),
 | |
| -+	.aux_output_mask = BIT(1),
 | |
| -+	.main_output_mask = BIT(0),
 | |
| -+	.test_ctl_val = 0x1c000000,
 | |
| -+	.test_ctl_hi_val = 0x4000,
 | |
| -+};
 | |
| -+
 | |
| - static const struct regmap_config ipq_pll_regmap_config = {
 | |
| - 	.reg_bits		= 32,
 | |
| - 	.reg_stride		= 4,
 | |
| -@@ -89,6 +101,7 @@ static int apss_ipq_pll_probe(struct pla
 | |
| - 
 | |
| - static const struct of_device_id apss_ipq_pll_match_table[] = {
 | |
| - 	{ .compatible = "qcom,ipq6018-a53pll", .data = &ipq6018_pll_config },
 | |
| -+	{ .compatible = "qcom,ipq8074-a53pll", .data = &ipq8074_pll_config },
 | |
| - 	{ }
 | |
| - };
 | |
| - MODULE_DEVICE_TABLE(of, apss_ipq_pll_match_table);
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0038-v6.1-clk-qcom-clk-rcg2-add-rcg2-mux-ops.patch b/target/linux/ipq807x/patches-5.15/0038-v6.1-clk-qcom-clk-rcg2-add-rcg2-mux-ops.patch
 | |
| deleted file mode 100644
 | |
| index 451066099d..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0038-v6.1-clk-qcom-clk-rcg2-add-rcg2-mux-ops.patch
 | |
| +++ /dev/null
 | |
| @@ -1,51 +0,0 @@
 | |
| -From f7fb35d540240889a8f45f3fd42363cbc1a448e2 Mon Sep 17 00:00:00 2001
 | |
| -From: Christian Marangi <ansuelsmth@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:06:20 +0200
 | |
| -Subject: [PATCH] clk: qcom: clk-rcg2: add rcg2 mux ops
 | |
| -
 | |
| -An RCG may act as a mux that switch between 2 parents.
 | |
| -This is the case on IPQ6018 and IPQ8074 where the APCS core clk that feeds
 | |
| -the CPU cluster clock just switches between XO and the PLL that feeds it.
 | |
| -
 | |
| -Add the required ops to add support for this special configuration and use
 | |
| -the generic mux function to determine the rate.
 | |
| -
 | |
| -This way we dont have to keep a essentially dummy frequency table to use
 | |
| -RCG2 as a mux.
 | |
| -
 | |
| -Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220628.339366-1-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/clk/qcom/clk-rcg.h  | 1 +
 | |
| - drivers/clk/qcom/clk-rcg2.c | 7 +++++++
 | |
| - 2 files changed, 8 insertions(+)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/clk-rcg.h
 | |
| -+++ b/drivers/clk/qcom/clk-rcg.h
 | |
| -@@ -164,6 +164,7 @@ struct clk_rcg2_gfx3d {
 | |
| - 
 | |
| - extern const struct clk_ops clk_rcg2_ops;
 | |
| - extern const struct clk_ops clk_rcg2_floor_ops;
 | |
| -+extern const struct clk_ops clk_rcg2_mux_closest_ops;
 | |
| - extern const struct clk_ops clk_edp_pixel_ops;
 | |
| - extern const struct clk_ops clk_byte_ops;
 | |
| - extern const struct clk_ops clk_byte2_ops;
 | |
| ---- a/drivers/clk/qcom/clk-rcg2.c
 | |
| -+++ b/drivers/clk/qcom/clk-rcg2.c
 | |
| -@@ -477,6 +477,13 @@ const struct clk_ops clk_rcg2_floor_ops
 | |
| - };
 | |
| - EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops);
 | |
| - 
 | |
| -+const struct clk_ops clk_rcg2_mux_closest_ops = {
 | |
| -+	.determine_rate = __clk_mux_determine_rate_closest,
 | |
| -+	.get_parent = clk_rcg2_get_parent,
 | |
| -+	.set_parent = clk_rcg2_set_parent,
 | |
| -+};
 | |
| -+EXPORT_SYMBOL_GPL(clk_rcg2_mux_closest_ops);
 | |
| -+
 | |
| - struct frac_entry {
 | |
| - 	int num;
 | |
| - 	int den;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0039-v6.1-clk-qcom-apss-ipq6018-fix-apcs_alias0_clk_src.patch b/target/linux/ipq807x/patches-5.15/0039-v6.1-clk-qcom-apss-ipq6018-fix-apcs_alias0_clk_src.patch
 | |
| deleted file mode 100644
 | |
| index c279e2804e..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0039-v6.1-clk-qcom-apss-ipq6018-fix-apcs_alias0_clk_src.patch
 | |
| +++ /dev/null
 | |
| @@ -1,63 +0,0 @@
 | |
| -From 6b9d5ecd2913758780a0529f9b95392f330b721b Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:06:21 +0200
 | |
| -Subject: [PATCH] clk: qcom: apss-ipq6018: fix apcs_alias0_clk_src
 | |
| -
 | |
| -While working on IPQ8074 APSS driver it was discovered that IPQ6018 and
 | |
| -IPQ8074 use almost the same PLL and APSS clocks, however APSS driver is
 | |
| -currently broken.
 | |
| -
 | |
| -More precisely apcs_alias0_clk_src is broken, it was added as regmap_mux
 | |
| -clock.
 | |
| -However after debugging why it was always stuck at 800Mhz, it was figured
 | |
| -out that its not regmap_mux compatible at all.
 | |
| -It is a simple mux but it uses RCG2 register layout and control bits, so
 | |
| -utilize the new clk_rcg2_mux_closest_ops to correctly drive it while not
 | |
| -having to provide a dummy frequency table.
 | |
| -
 | |
| -While we are here, use ARRAY_SIZE for number of parents.
 | |
| -
 | |
| -Tested on IPQ6018-CP01-C1 reference board and multiple IPQ8074 boards.
 | |
| -
 | |
| -Fixes: 5e77b4ef1b19 ("clk: qcom: Add ipq6018 apss clock controller")
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220628.339366-2-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/clk/qcom/apss-ipq6018.c | 13 ++++++-------
 | |
| - 1 file changed, 6 insertions(+), 7 deletions(-)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/apss-ipq6018.c
 | |
| -+++ b/drivers/clk/qcom/apss-ipq6018.c
 | |
| -@@ -16,7 +16,7 @@
 | |
| - #include "clk-regmap.h"
 | |
| - #include "clk-branch.h"
 | |
| - #include "clk-alpha-pll.h"
 | |
| --#include "clk-regmap-mux.h"
 | |
| -+#include "clk-rcg.h"
 | |
| - 
 | |
| - enum {
 | |
| - 	P_XO,
 | |
| -@@ -33,16 +33,15 @@ static const struct parent_map parents_a
 | |
| - 	{ P_APSS_PLL_EARLY, 5 },
 | |
| - };
 | |
| - 
 | |
| --static struct clk_regmap_mux apcs_alias0_clk_src = {
 | |
| --	.reg = 0x0050,
 | |
| --	.width = 3,
 | |
| --	.shift = 7,
 | |
| -+static struct clk_rcg2 apcs_alias0_clk_src = {
 | |
| -+	.cmd_rcgr = 0x0050,
 | |
| -+	.hid_width = 5,
 | |
| - 	.parent_map = parents_apcs_alias0_clk_src_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "apcs_alias0_clk_src",
 | |
| - 		.parent_data = parents_apcs_alias0_clk_src,
 | |
| --		.num_parents = 2,
 | |
| --		.ops = &clk_regmap_mux_closest_ops,
 | |
| -+		.num_parents = ARRAY_SIZE(parents_apcs_alias0_clk_src),
 | |
| -+		.ops = &clk_rcg2_mux_closest_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| - 	},
 | |
| - };
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0040-v6.2-arm64-dts-qcom-ipq8074-add-A53-PLL-node.patch b/target/linux/ipq807x/patches-5.15/0040-v6.2-arm64-dts-qcom-ipq8074-add-A53-PLL-node.patch
 | |
| deleted file mode 100644
 | |
| index dd57eae360..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0040-v6.2-arm64-dts-qcom-ipq8074-add-A53-PLL-node.patch
 | |
| +++ /dev/null
 | |
| @@ -1,32 +0,0 @@
 | |
| -From 6463c10bfdbd684ec7ecfd408ea541283215a088 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:06:28 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add A53 PLL node
 | |
| -
 | |
| -Add the required node for A53 PLL which will be used to provide the CPU
 | |
| -clock via APCS for APSS scaling.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220628.339366-9-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 8 ++++++++
 | |
| - 1 file changed, 8 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -675,6 +675,14 @@
 | |
| - 			#mbox-cells = <1>;
 | |
| - 		};
 | |
| - 
 | |
| -+		a53pll: clock@b116000 {
 | |
| -+			compatible = "qcom,ipq8074-a53pll";
 | |
| -+			reg = <0x0b116000 0x40>;
 | |
| -+			#clock-cells = <0>;
 | |
| -+			clocks = <&xo>;
 | |
| -+			clock-names = "xo";
 | |
| -+		};
 | |
| -+
 | |
| - 		timer@b120000 {
 | |
| - 			#address-cells = <1>;
 | |
| - 			#size-cells = <1>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0041-v6.1-arm64-dts-qcom-ipq8074-correct-APCS-register-space-s.patch b/target/linux/ipq807x/patches-5.15/0041-v6.1-arm64-dts-qcom-ipq8074-correct-APCS-register-space-s.patch
 | |
| deleted file mode 100644
 | |
| index 5c8ca8c547..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0041-v6.1-arm64-dts-qcom-ipq8074-correct-APCS-register-space-s.patch
 | |
| +++ /dev/null
 | |
| @@ -1,32 +0,0 @@
 | |
| -From 23c5ff3143ce43a76eebdf60a93436de9db39a7a Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:06:27 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: correct APCS register space size
 | |
| -
 | |
| -APCS DTS addition that was merged, was not supposed to get merged as it
 | |
| -was part of patch series that was superseded by 2 more patch series
 | |
| -that resolved issues with this one and greatly simplified things.
 | |
| -
 | |
| -Since it already got merged, start by correcting the register space
 | |
| -size as APCS will not be providing regmap for PLL and it will conflict
 | |
| -with the standalone A53 PLL node.
 | |
| -
 | |
| -Fixes: 50ed9fffec3a ("arm64: dts: qcom: ipq8074: add APCS node")
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220628.339366-8-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +-
 | |
| - 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -669,7 +669,7 @@
 | |
| - 
 | |
| - 		apcs_glb: mailbox@b111000 {
 | |
| - 			compatible = "qcom,ipq8074-apcs-apps-global";
 | |
| --			reg = <0x0b111000 0x6000>;
 | |
| -+			reg = <0x0b111000 0x1000>;
 | |
| - 
 | |
| - 			#clock-cells = <1>;
 | |
| - 			#mbox-cells = <1>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0042-v6.2-thermal-drivers-tsens-Add-support-for-combined-inter.patch b/target/linux/ipq807x/patches-5.15/0042-v6.2-thermal-drivers-tsens-Add-support-for-combined-inter.patch
 | |
| deleted file mode 100644
 | |
| index 2c6e70b14d..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0042-v6.2-thermal-drivers-tsens-Add-support-for-combined-inter.patch
 | |
| +++ /dev/null
 | |
| @@ -1,134 +0,0 @@
 | |
| -From e593e834fe8ba9bf314d8215ac05d8787f81efda Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:02:42 +0200
 | |
| -Subject: [PATCH] thermal/drivers/tsens: Add support for combined interrupt
 | |
| -
 | |
| -Despite using tsens v2.3 IP, IPQ8074 and IPQ6018 only have one IRQ for
 | |
| -signaling both up/low and critical trips.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220245.338396-2-robimarko@gmail.com
 | |
| -Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
 | |
| ----
 | |
| - drivers/thermal/qcom/tsens-8960.c |  1 +
 | |
| - drivers/thermal/qcom/tsens-v0_1.c |  1 +
 | |
| - drivers/thermal/qcom/tsens-v1.c   |  1 +
 | |
| - drivers/thermal/qcom/tsens-v2.c   |  1 +
 | |
| - drivers/thermal/qcom/tsens.c      | 38 ++++++++++++++++++++++++++-----
 | |
| - drivers/thermal/qcom/tsens.h      |  2 ++
 | |
| - 6 files changed, 38 insertions(+), 6 deletions(-)
 | |
| -
 | |
| ---- a/drivers/thermal/qcom/tsens-8960.c
 | |
| -+++ b/drivers/thermal/qcom/tsens-8960.c
 | |
| -@@ -269,6 +269,7 @@ static const struct tsens_ops ops_8960 =
 | |
| - static struct tsens_features tsens_8960_feat = {
 | |
| - 	.ver_major	= VER_0,
 | |
| - 	.crit_int	= 0,
 | |
| -+	.combo_int	= 0,
 | |
| - 	.adc		= 1,
 | |
| - 	.srot_split	= 0,
 | |
| - 	.max_sensors	= 11,
 | |
| ---- a/drivers/thermal/qcom/tsens-v0_1.c
 | |
| -+++ b/drivers/thermal/qcom/tsens-v0_1.c
 | |
| -@@ -549,6 +549,7 @@ static int __init init_8939(struct tsens
 | |
| - static struct tsens_features tsens_v0_1_feat = {
 | |
| - 	.ver_major	= VER_0_1,
 | |
| - 	.crit_int	= 0,
 | |
| -+	.combo_int	= 0,
 | |
| - 	.adc		= 1,
 | |
| - 	.srot_split	= 1,
 | |
| - 	.max_sensors	= 11,
 | |
| ---- a/drivers/thermal/qcom/tsens-v1.c
 | |
| -+++ b/drivers/thermal/qcom/tsens-v1.c
 | |
| -@@ -273,6 +273,7 @@ static int calibrate_8976(struct tsens_p
 | |
| - static struct tsens_features tsens_v1_feat = {
 | |
| - 	.ver_major	= VER_1_X,
 | |
| - 	.crit_int	= 0,
 | |
| -+	.combo_int	= 0,
 | |
| - 	.adc		= 1,
 | |
| - 	.srot_split	= 1,
 | |
| - 	.max_sensors	= 11,
 | |
| ---- a/drivers/thermal/qcom/tsens-v2.c
 | |
| -+++ b/drivers/thermal/qcom/tsens-v2.c
 | |
| -@@ -31,6 +31,7 @@
 | |
| - static struct tsens_features tsens_v2_feat = {
 | |
| - 	.ver_major	= VER_2_X,
 | |
| - 	.crit_int	= 1,
 | |
| -+	.combo_int	= 0,
 | |
| - 	.adc		= 0,
 | |
| - 	.srot_split	= 1,
 | |
| - 	.max_sensors	= 16,
 | |
| ---- a/drivers/thermal/qcom/tsens.c
 | |
| -+++ b/drivers/thermal/qcom/tsens.c
 | |
| -@@ -531,6 +531,27 @@ static irqreturn_t tsens_irq_thread(int
 | |
| - 	return IRQ_HANDLED;
 | |
| - }
 | |
| - 
 | |
| -+/**
 | |
| -+ * tsens_combined_irq_thread() - Threaded interrupt handler for combined interrupts
 | |
| -+ * @irq: irq number
 | |
| -+ * @data: tsens controller private data
 | |
| -+ *
 | |
| -+ * Handle the combined interrupt as if it were 2 separate interrupts, so call the
 | |
| -+ * critical handler first and then the up/low one.
 | |
| -+ *
 | |
| -+ * Return: IRQ_HANDLED
 | |
| -+ */
 | |
| -+static irqreturn_t tsens_combined_irq_thread(int irq, void *data)
 | |
| -+{
 | |
| -+	irqreturn_t ret;
 | |
| -+
 | |
| -+	ret = tsens_critical_irq_thread(irq, data);
 | |
| -+	if (ret != IRQ_HANDLED)
 | |
| -+		return ret;
 | |
| -+
 | |
| -+	return tsens_irq_thread(irq, data);
 | |
| -+}
 | |
| -+
 | |
| - static int tsens_set_trips(void *_sensor, int low, int high)
 | |
| - {
 | |
| - 	struct tsens_sensor *s = _sensor;
 | |
| -@@ -1081,13 +1102,18 @@ static int tsens_register(struct tsens_p
 | |
| - 				   tsens_mC_to_hw(priv->sensor, 0));
 | |
| - 	}
 | |
| - 
 | |
| --	ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
 | |
| --	if (ret < 0)
 | |
| --		return ret;
 | |
| -+	if (priv->feat->combo_int) {
 | |
| -+		ret = tsens_register_irq(priv, "combined",
 | |
| -+					 tsens_combined_irq_thread);
 | |
| -+	} else {
 | |
| -+		ret = tsens_register_irq(priv, "uplow", tsens_irq_thread);
 | |
| -+		if (ret < 0)
 | |
| -+			return ret;
 | |
| - 
 | |
| --	if (priv->feat->crit_int)
 | |
| --		ret = tsens_register_irq(priv, "critical",
 | |
| --					 tsens_critical_irq_thread);
 | |
| -+		if (priv->feat->crit_int)
 | |
| -+			ret = tsens_register_irq(priv, "critical",
 | |
| -+						 tsens_critical_irq_thread);
 | |
| -+	}
 | |
| - 
 | |
| - 	return ret;
 | |
| - }
 | |
| ---- a/drivers/thermal/qcom/tsens.h
 | |
| -+++ b/drivers/thermal/qcom/tsens.h
 | |
| -@@ -495,6 +495,7 @@ enum regfield_ids {
 | |
| -  * struct tsens_features - Features supported by the IP
 | |
| -  * @ver_major: Major number of IP version
 | |
| -  * @crit_int: does the IP support critical interrupts?
 | |
| -+ * @combo_int: does the IP use one IRQ for up, low and critical thresholds?
 | |
| -  * @adc:      do the sensors only output adc code (instead of temperature)?
 | |
| -  * @srot_split: does the IP neatly splits the register space into SROT and TM,
 | |
| -  *              with SROT only being available to secure boot firmware?
 | |
| -@@ -504,6 +505,7 @@ enum regfield_ids {
 | |
| - struct tsens_features {
 | |
| - 	unsigned int ver_major;
 | |
| - 	unsigned int crit_int:1;
 | |
| -+	unsigned int combo_int:1;
 | |
| - 	unsigned int adc:1;
 | |
| - 	unsigned int srot_split:1;
 | |
| - 	unsigned int has_watchdog:1;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0043-v6.2-thermal-drivers-tsens-Allow-configuring-min-and-max-.patch b/target/linux/ipq807x/patches-5.15/0043-v6.2-thermal-drivers-tsens-Allow-configuring-min-and-max-.patch
 | |
| deleted file mode 100644
 | |
| index 5a571a36b6..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0043-v6.2-thermal-drivers-tsens-Allow-configuring-min-and-max-.patch
 | |
| +++ /dev/null
 | |
| @@ -1,101 +0,0 @@
 | |
| -From 7805365fee582056b32c69cf35aafbb94b14a8ca Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:02:43 +0200
 | |
| -Subject: [PATCH] thermal/drivers/tsens: Allow configuring min and max trips
 | |
| -
 | |
| -IPQ8074 and IPQ6018 dont support negative trip temperatures and support
 | |
| -up to 204 degrees C as the max trip temperature.
 | |
| -
 | |
| -So, instead of always setting the -40 as min and 120 degrees C as max
 | |
| -allow it to be configured as part of the features.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220245.338396-3-robimarko@gmail.com
 | |
| -Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
 | |
| ----
 | |
| - drivers/thermal/qcom/tsens-8960.c | 2 ++
 | |
| - drivers/thermal/qcom/tsens-v0_1.c | 2 ++
 | |
| - drivers/thermal/qcom/tsens-v1.c   | 2 ++
 | |
| - drivers/thermal/qcom/tsens-v2.c   | 2 ++
 | |
| - drivers/thermal/qcom/tsens.c      | 4 ++--
 | |
| - drivers/thermal/qcom/tsens.h      | 4 ++++
 | |
| - 6 files changed, 14 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/drivers/thermal/qcom/tsens-8960.c
 | |
| -+++ b/drivers/thermal/qcom/tsens-8960.c
 | |
| -@@ -273,6 +273,8 @@ static struct tsens_features tsens_8960_
 | |
| - 	.adc		= 1,
 | |
| - 	.srot_split	= 0,
 | |
| - 	.max_sensors	= 11,
 | |
| -+	.trip_min_temp	= -40000,
 | |
| -+	.trip_max_temp	= 120000,
 | |
| - };
 | |
| - 
 | |
| - struct tsens_plat_data data_8960 = {
 | |
| ---- a/drivers/thermal/qcom/tsens-v0_1.c
 | |
| -+++ b/drivers/thermal/qcom/tsens-v0_1.c
 | |
| -@@ -553,6 +553,8 @@ static struct tsens_features tsens_v0_1_
 | |
| - 	.adc		= 1,
 | |
| - 	.srot_split	= 1,
 | |
| - 	.max_sensors	= 11,
 | |
| -+	.trip_min_temp	= -40000,
 | |
| -+	.trip_max_temp	= 120000,
 | |
| - };
 | |
| - 
 | |
| - static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = {
 | |
| ---- a/drivers/thermal/qcom/tsens-v1.c
 | |
| -+++ b/drivers/thermal/qcom/tsens-v1.c
 | |
| -@@ -277,6 +277,8 @@ static struct tsens_features tsens_v1_fe
 | |
| - 	.adc		= 1,
 | |
| - 	.srot_split	= 1,
 | |
| - 	.max_sensors	= 11,
 | |
| -+	.trip_min_temp	= -40000,
 | |
| -+	.trip_max_temp	= 120000,
 | |
| - };
 | |
| - 
 | |
| - static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
 | |
| ---- a/drivers/thermal/qcom/tsens-v2.c
 | |
| -+++ b/drivers/thermal/qcom/tsens-v2.c
 | |
| -@@ -35,6 +35,8 @@ static struct tsens_features tsens_v2_fe
 | |
| - 	.adc		= 0,
 | |
| - 	.srot_split	= 1,
 | |
| - 	.max_sensors	= 16,
 | |
| -+	.trip_min_temp	= -40000,
 | |
| -+	.trip_max_temp	= 120000,
 | |
| - };
 | |
| - 
 | |
| - static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
 | |
| ---- a/drivers/thermal/qcom/tsens.c
 | |
| -+++ b/drivers/thermal/qcom/tsens.c
 | |
| -@@ -572,8 +572,8 @@ static int tsens_set_trips(void *_sensor
 | |
| - 	dev_dbg(dev, "[%u] %s: proposed thresholds: (%d:%d)\n",
 | |
| - 		hw_id, __func__, low, high);
 | |
| - 
 | |
| --	cl_high = clamp_val(high, -40000, 120000);
 | |
| --	cl_low  = clamp_val(low, -40000, 120000);
 | |
| -+	cl_high = clamp_val(high, priv->feat->trip_min_temp, priv->feat->trip_max_temp);
 | |
| -+	cl_low  = clamp_val(low, priv->feat->trip_min_temp, priv->feat->trip_max_temp);
 | |
| - 
 | |
| - 	high_val = tsens_mC_to_hw(s, cl_high);
 | |
| - 	low_val  = tsens_mC_to_hw(s, cl_low);
 | |
| ---- a/drivers/thermal/qcom/tsens.h
 | |
| -+++ b/drivers/thermal/qcom/tsens.h
 | |
| -@@ -501,6 +501,8 @@ enum regfield_ids {
 | |
| -  *              with SROT only being available to secure boot firmware?
 | |
| -  * @has_watchdog: does this IP support watchdog functionality?
 | |
| -  * @max_sensors: maximum sensors supported by this version of the IP
 | |
| -+ * @trip_min_temp: minimum trip temperature supported by this version of the IP
 | |
| -+ * @trip_max_temp: maximum trip temperature supported by this version of the IP
 | |
| -  */
 | |
| - struct tsens_features {
 | |
| - 	unsigned int ver_major;
 | |
| -@@ -510,6 +512,8 @@ struct tsens_features {
 | |
| - 	unsigned int srot_split:1;
 | |
| - 	unsigned int has_watchdog:1;
 | |
| - 	unsigned int max_sensors;
 | |
| -+	int trip_min_temp;
 | |
| -+	int trip_max_temp;
 | |
| - };
 | |
| - 
 | |
| - /**
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0044-v6.2-thermal-drivers-tsens-Add-IPQ8074-support.patch b/target/linux/ipq807x/patches-5.15/0044-v6.2-thermal-drivers-tsens-Add-IPQ8074-support.patch
 | |
| deleted file mode 100644
 | |
| index 3e3e77a0a8..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0044-v6.2-thermal-drivers-tsens-Add-IPQ8074-support.patch
 | |
| +++ /dev/null
 | |
| @@ -1,74 +0,0 @@
 | |
| -From 0164d794cbc58488a7321272e95958d10cf103a4 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:02:44 +0200
 | |
| -Subject: [PATCH] thermal/drivers/tsens: Add IPQ8074 support
 | |
| -
 | |
| -Qualcomm IPQ8074 uses tsens v2.3 IP, however unlike other tsens v2 IP
 | |
| -it only has one IRQ, that is used for up/low as well as critical.
 | |
| -It also does not support negative trip temperatures.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220245.338396-4-robimarko@gmail.com
 | |
| -Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
 | |
| ----
 | |
| - drivers/thermal/qcom/tsens-v2.c | 17 +++++++++++++++++
 | |
| - drivers/thermal/qcom/tsens.c    |  3 +++
 | |
| - drivers/thermal/qcom/tsens.h    |  2 +-
 | |
| - 3 files changed, 21 insertions(+), 1 deletion(-)
 | |
| -
 | |
| ---- a/drivers/thermal/qcom/tsens-v2.c
 | |
| -+++ b/drivers/thermal/qcom/tsens-v2.c
 | |
| -@@ -39,6 +39,17 @@ static struct tsens_features tsens_v2_fe
 | |
| - 	.trip_max_temp	= 120000,
 | |
| - };
 | |
| - 
 | |
| -+static struct tsens_features ipq8074_feat = {
 | |
| -+	.ver_major	= VER_2_X,
 | |
| -+	.crit_int	= 1,
 | |
| -+	.combo_int	= 1,
 | |
| -+	.adc		= 0,
 | |
| -+	.srot_split	= 1,
 | |
| -+	.max_sensors	= 16,
 | |
| -+	.trip_min_temp	= 0,
 | |
| -+	.trip_max_temp	= 204000,
 | |
| -+};
 | |
| -+
 | |
| - static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
 | |
| - 	/* ----- SROT ------ */
 | |
| - 	/* VERSION */
 | |
| -@@ -104,6 +115,12 @@ struct tsens_plat_data data_tsens_v2 = {
 | |
| - 	.fields	= tsens_v2_regfields,
 | |
| - };
 | |
| - 
 | |
| -+struct tsens_plat_data data_ipq8074 = {
 | |
| -+	.ops		= &ops_generic_v2,
 | |
| -+	.feat		= &ipq8074_feat,
 | |
| -+	.fields	= tsens_v2_regfields,
 | |
| -+};
 | |
| -+
 | |
| - /* Kept around for backward compatibility with old msm8996.dtsi */
 | |
| - struct tsens_plat_data data_8996 = {
 | |
| - 	.num_sensors	= 13,
 | |
| ---- a/drivers/thermal/qcom/tsens.c
 | |
| -+++ b/drivers/thermal/qcom/tsens.c
 | |
| -@@ -991,6 +991,9 @@ static const struct of_device_id tsens_t
 | |
| - 		.compatible = "qcom,ipq8064-tsens",
 | |
| - 		.data = &data_8960,
 | |
| - 	}, {
 | |
| -+		.compatible = "qcom,ipq8074-tsens",
 | |
| -+		.data = &data_ipq8074,
 | |
| -+	}, {
 | |
| - 		.compatible = "qcom,mdm9607-tsens",
 | |
| - 		.data = &data_9607,
 | |
| - 	}, {
 | |
| ---- a/drivers/thermal/qcom/tsens.h
 | |
| -+++ b/drivers/thermal/qcom/tsens.h
 | |
| -@@ -599,6 +599,6 @@ extern struct tsens_plat_data data_8916,
 | |
| - extern struct tsens_plat_data data_tsens_v1, data_8976, data_8956;
 | |
| - 
 | |
| - /* TSENS v2 targets */
 | |
| --extern struct tsens_plat_data data_8996, data_tsens_v2;
 | |
| -+extern struct tsens_plat_data data_8996, data_ipq8074, data_tsens_v2;
 | |
| - 
 | |
| - #endif /* __QCOM_TSENS_H__ */
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0045-v6.2-arm64-dts-qcom-ipq8074-add-thermal-nodes.patch b/target/linux/ipq807x/patches-5.15/0045-v6.2-arm64-dts-qcom-ipq8074-add-thermal-nodes.patch
 | |
| deleted file mode 100644
 | |
| index bad75e4597..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0045-v6.2-arm64-dts-qcom-ipq8074-add-thermal-nodes.patch
 | |
| +++ /dev/null
 | |
| @@ -1,130 +0,0 @@
 | |
| -From c3cc0c2a17f552be2426200e47a9e2c62cf449ce Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:02:45 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add thermal nodes
 | |
| -
 | |
| -IPQ8074 has a tsens v2.3.0 peripheral which monitors
 | |
| -temperatures around the various subsystems on the
 | |
| -die.
 | |
| -
 | |
| -So lets add the tsens and thermal zone nodes, passive
 | |
| -CPU cooling will come in later patches after CPU frequency
 | |
| -scaling is supported.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220245.338396-5-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 96 +++++++++++++++++++++++++++
 | |
| - 1 file changed, 96 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -274,6 +274,16 @@
 | |
| - 			status = "disabled";
 | |
| - 		};
 | |
| - 
 | |
| -+		tsens: thermal-sensor@4a9000 {
 | |
| -+			compatible = "qcom,ipq8074-tsens";
 | |
| -+			reg = <0x4a9000 0x1000>, /* TM */
 | |
| -+			      <0x4a8000 0x1000>; /* SROT */
 | |
| -+			interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
 | |
| -+			interrupt-names = "combined";
 | |
| -+			#qcom,sensors = <16>;
 | |
| -+			#thermal-sensor-cells = <1>;
 | |
| -+		};
 | |
| -+
 | |
| - 		cryptobam: dma-controller@704000 {
 | |
| - 			compatible = "qcom,bam-v1.7.0";
 | |
| - 			reg = <0x00704000 0x20000>;
 | |
| -@@ -874,4 +884,90 @@
 | |
| - 			     <GIC_PPI 4 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
 | |
| - 			     <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
 | |
| - 	};
 | |
| -+
 | |
| -+	thermal-zones {
 | |
| -+		nss-top-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 4>;
 | |
| -+		};
 | |
| -+
 | |
| -+		nss0-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 5>;
 | |
| -+		};
 | |
| -+
 | |
| -+		nss1-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 6>;
 | |
| -+		};
 | |
| -+
 | |
| -+		wcss-phya0-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 7>;
 | |
| -+		};
 | |
| -+
 | |
| -+		wcss-phya1-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 8>;
 | |
| -+		};
 | |
| -+
 | |
| -+		cpu0_thermal: cpu0-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 9>;
 | |
| -+		};
 | |
| -+
 | |
| -+		cpu1_thermal: cpu1-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 10>;
 | |
| -+		};
 | |
| -+
 | |
| -+		cpu2_thermal: cpu2-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 11>;
 | |
| -+		};
 | |
| -+
 | |
| -+		cpu3_thermal: cpu3-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 12>;
 | |
| -+		};
 | |
| -+
 | |
| -+		cluster_thermal: cluster-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 13>;
 | |
| -+		};
 | |
| -+
 | |
| -+		wcss-phyb0-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 14>;
 | |
| -+		};
 | |
| -+
 | |
| -+		wcss-phyb1-thermal {
 | |
| -+			polling-delay-passive = <250>;
 | |
| -+			polling-delay = <1000>;
 | |
| -+
 | |
| -+			thermal-sensors = <&tsens 15>;
 | |
| -+		};
 | |
| -+	};
 | |
| - };
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0046-v6.2-arm64-dts-qcom-ipq8074-add-clocks-to-APCS.patch b/target/linux/ipq807x/patches-5.15/0046-v6.2-arm64-dts-qcom-ipq8074-add-clocks-to-APCS.patch
 | |
| deleted file mode 100644
 | |
| index e229851649..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0046-v6.2-arm64-dts-qcom-ipq8074-add-clocks-to-APCS.patch
 | |
| +++ /dev/null
 | |
| @@ -1,29 +0,0 @@
 | |
| -From 0df592a0a1a3fff9133977192677aa915afc174f Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:08:49 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add clocks to APCS
 | |
| -
 | |
| -APCS now has support for providing the APSS clocks as the child device
 | |
| -for IPQ8074.
 | |
| -
 | |
| -So, add the A53 PLL and XO clocks in order to use APCS as the CPU
 | |
| -clocksource for APSS scaling.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818220849.339732-4-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 ++
 | |
| - 1 file changed, 2 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -680,6 +680,8 @@
 | |
| - 		apcs_glb: mailbox@b111000 {
 | |
| - 			compatible = "qcom,ipq8074-apcs-apps-global";
 | |
| - 			reg = <0x0b111000 0x1000>;
 | |
| -+			clocks = <&a53pll>, <&xo>;
 | |
| -+			clock-names = "pll", "xo";
 | |
| - 
 | |
| - 			#clock-cells = <1>;
 | |
| - 			#mbox-cells = <1>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0047-v6.2-clk-qcom-ipq8074-convert-to-parent-data.patch b/target/linux/ipq807x/patches-5.15/0047-v6.2-clk-qcom-ipq8074-convert-to-parent-data.patch
 | |
| deleted file mode 100644
 | |
| index 9162ea538d..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0047-v6.2-clk-qcom-ipq8074-convert-to-parent-data.patch
 | |
| +++ /dev/null
 | |
| @@ -1,3601 +0,0 @@
 | |
| -From e6c5115d6845f25eda7e162dcd783a2044215867 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sun, 30 Oct 2022 18:57:01 +0100
 | |
| -Subject: [PATCH] clk: qcom: ipq8074: convert to parent data
 | |
| -
 | |
| -Convert the IPQ8074 GCC driver to use parent data instead of global
 | |
| -name matching.
 | |
| -
 | |
| -Utilize ARRAY_SIZE for num_parents instead of hardcoding the value.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20221030175703.1103224-1-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/clk/qcom/gcc-ipq8074.c | 1781 +++++++++++++++-----------------
 | |
| - 1 file changed, 813 insertions(+), 968 deletions(-)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -+++ b/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -@@ -49,349 +49,6 @@ enum {
 | |
| - 	P_UNIPHY2_TX,
 | |
| - };
 | |
| - 
 | |
| --static const char * const gcc_xo_gpll0_gpll0_out_main_div2[] = {
 | |
| --	"xo",
 | |
| --	"gpll0",
 | |
| --	"gpll0_out_main_div2",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_gpll0_gpll0_out_main_div2_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_GPLL0, 1 },
 | |
| --	{ P_GPLL0_DIV2, 4 },
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_gpll0_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_GPLL0, 1 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_gpll0_gpll2_gpll0_out_main_div2[] = {
 | |
| --	"xo",
 | |
| --	"gpll0",
 | |
| --	"gpll2",
 | |
| --	"gpll0_out_main_div2",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_gpll0_gpll2_gpll0_out_main_div2_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_GPLL0, 1 },
 | |
| --	{ P_GPLL2, 2 },
 | |
| --	{ P_GPLL0_DIV2, 4 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_gpll0_sleep_clk[] = {
 | |
| --	"xo",
 | |
| --	"gpll0",
 | |
| --	"sleep_clk",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_gpll0_sleep_clk_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_GPLL0, 2 },
 | |
| --	{ P_SLEEP_CLK, 6 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_gpll6_gpll0_gpll0_out_main_div2[] = {
 | |
| --	"xo",
 | |
| --	"gpll6",
 | |
| --	"gpll0",
 | |
| --	"gpll0_out_main_div2",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_GPLL6, 1 },
 | |
| --	{ P_GPLL0, 3 },
 | |
| --	{ P_GPLL0_DIV2, 4 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_gpll0_out_main_div2_gpll0[] = {
 | |
| --	"xo",
 | |
| --	"gpll0_out_main_div2",
 | |
| --	"gpll0",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_gpll0_out_main_div2_gpll0_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_GPLL0_DIV2, 2 },
 | |
| --	{ P_GPLL0, 1 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_usb3phy_0_cc_pipe_clk_xo[] = {
 | |
| --	"usb3phy_0_cc_pipe_clk",
 | |
| --	"xo",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_usb3phy_0_cc_pipe_clk_xo_map[] = {
 | |
| --	{ P_USB3PHY_0_PIPE, 0 },
 | |
| --	{ P_XO, 2 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_usb3phy_1_cc_pipe_clk_xo[] = {
 | |
| --	"usb3phy_1_cc_pipe_clk",
 | |
| --	"xo",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_usb3phy_1_cc_pipe_clk_xo_map[] = {
 | |
| --	{ P_USB3PHY_1_PIPE, 0 },
 | |
| --	{ P_XO, 2 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_pcie20_phy0_pipe_clk_xo[] = {
 | |
| --	"pcie20_phy0_pipe_clk",
 | |
| --	"xo",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_pcie20_phy0_pipe_clk_xo_map[] = {
 | |
| --	{ P_PCIE20_PHY0_PIPE, 0 },
 | |
| --	{ P_XO, 2 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_pcie20_phy1_pipe_clk_xo[] = {
 | |
| --	"pcie20_phy1_pipe_clk",
 | |
| --	"xo",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_pcie20_phy1_pipe_clk_xo_map[] = {
 | |
| --	{ P_PCIE20_PHY1_PIPE, 0 },
 | |
| --	{ P_XO, 2 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_gpll0_gpll6_gpll0_div2[] = {
 | |
| --	"xo",
 | |
| --	"gpll0",
 | |
| --	"gpll6",
 | |
| --	"gpll0_out_main_div2",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_div2_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_GPLL0, 1 },
 | |
| --	{ P_GPLL6, 2 },
 | |
| --	{ P_GPLL0_DIV2, 4 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_gpll0_gpll6_gpll0_out_main_div2[] = {
 | |
| --	"xo",
 | |
| --	"gpll0",
 | |
| --	"gpll6",
 | |
| --	"gpll0_out_main_div2",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_out_main_div2_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_GPLL0, 1 },
 | |
| --	{ P_GPLL6, 2 },
 | |
| --	{ P_GPLL0_DIV2, 3 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_bias_pll_nss_noc_clk_gpll0_gpll2[] = {
 | |
| --	"xo",
 | |
| --	"bias_pll_nss_noc_clk",
 | |
| --	"gpll0",
 | |
| --	"gpll2",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_bias_pll_nss_noc_clk_gpll0_gpll2_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_BIAS_PLL_NSS_NOC, 1 },
 | |
| --	{ P_GPLL0, 2 },
 | |
| --	{ P_GPLL2, 3 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_nss_crypto_pll_gpll0[] = {
 | |
| --	"xo",
 | |
| --	"nss_crypto_pll",
 | |
| --	"gpll0",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_nss_crypto_pll_gpll0_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_NSS_CRYPTO_PLL, 1 },
 | |
| --	{ P_GPLL0, 2 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6[] = {
 | |
| --	"xo",
 | |
| --	"ubi32_pll",
 | |
| --	"gpll0",
 | |
| --	"gpll2",
 | |
| --	"gpll4",
 | |
| --	"gpll6",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_ubi32_gpll0_gpll2_gpll4_gpll6_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_UBI32_PLL, 1 },
 | |
| --	{ P_GPLL0, 2 },
 | |
| --	{ P_GPLL2, 3 },
 | |
| --	{ P_GPLL4, 4 },
 | |
| --	{ P_GPLL6, 5 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_gpll0_out_main_div2[] = {
 | |
| --	"xo",
 | |
| --	"gpll0_out_main_div2",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_gpll0_out_main_div2_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_GPLL0_DIV2, 1 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_bias_gpll0_gpll4_nss_ubi32[] = {
 | |
| --	"xo",
 | |
| --	"bias_pll_cc_clk",
 | |
| --	"gpll0",
 | |
| --	"gpll4",
 | |
| --	"nss_crypto_pll",
 | |
| --	"ubi32_pll",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_bias_gpll0_gpll4_nss_ubi32_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_BIAS_PLL, 1 },
 | |
| --	{ P_GPLL0, 2 },
 | |
| --	{ P_GPLL4, 3 },
 | |
| --	{ P_NSS_CRYPTO_PLL, 4 },
 | |
| --	{ P_UBI32_PLL, 5 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_gpll0_gpll4[] = {
 | |
| --	"xo",
 | |
| --	"gpll0",
 | |
| --	"gpll4",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_GPLL0, 1 },
 | |
| --	{ P_GPLL4, 2 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_uniphy0_rx_tx_ubi32_bias[] = {
 | |
| --	"xo",
 | |
| --	"uniphy0_gcc_rx_clk",
 | |
| --	"uniphy0_gcc_tx_clk",
 | |
| --	"ubi32_pll",
 | |
| --	"bias_pll_cc_clk",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_uniphy0_rx_tx_ubi32_bias_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_UNIPHY0_RX, 1 },
 | |
| --	{ P_UNIPHY0_TX, 2 },
 | |
| --	{ P_UBI32_PLL, 5 },
 | |
| --	{ P_BIAS_PLL, 6 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_uniphy0_tx_rx_ubi32_bias[] = {
 | |
| --	"xo",
 | |
| --	"uniphy0_gcc_tx_clk",
 | |
| --	"uniphy0_gcc_rx_clk",
 | |
| --	"ubi32_pll",
 | |
| --	"bias_pll_cc_clk",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_uniphy0_tx_rx_ubi32_bias_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_UNIPHY0_TX, 1 },
 | |
| --	{ P_UNIPHY0_RX, 2 },
 | |
| --	{ P_UBI32_PLL, 5 },
 | |
| --	{ P_BIAS_PLL, 6 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias[] = {
 | |
| --	"xo",
 | |
| --	"uniphy0_gcc_rx_clk",
 | |
| --	"uniphy0_gcc_tx_clk",
 | |
| --	"uniphy1_gcc_rx_clk",
 | |
| --	"uniphy1_gcc_tx_clk",
 | |
| --	"ubi32_pll",
 | |
| --	"bias_pll_cc_clk",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map
 | |
| --gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_UNIPHY0_RX, 1 },
 | |
| --	{ P_UNIPHY0_TX, 2 },
 | |
| --	{ P_UNIPHY1_RX, 3 },
 | |
| --	{ P_UNIPHY1_TX, 4 },
 | |
| --	{ P_UBI32_PLL, 5 },
 | |
| --	{ P_BIAS_PLL, 6 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias[] = {
 | |
| --	"xo",
 | |
| --	"uniphy0_gcc_tx_clk",
 | |
| --	"uniphy0_gcc_rx_clk",
 | |
| --	"uniphy1_gcc_tx_clk",
 | |
| --	"uniphy1_gcc_rx_clk",
 | |
| --	"ubi32_pll",
 | |
| --	"bias_pll_cc_clk",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map
 | |
| --gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_UNIPHY0_TX, 1 },
 | |
| --	{ P_UNIPHY0_RX, 2 },
 | |
| --	{ P_UNIPHY1_TX, 3 },
 | |
| --	{ P_UNIPHY1_RX, 4 },
 | |
| --	{ P_UBI32_PLL, 5 },
 | |
| --	{ P_BIAS_PLL, 6 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_uniphy2_rx_tx_ubi32_bias[] = {
 | |
| --	"xo",
 | |
| --	"uniphy2_gcc_rx_clk",
 | |
| --	"uniphy2_gcc_tx_clk",
 | |
| --	"ubi32_pll",
 | |
| --	"bias_pll_cc_clk",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_uniphy2_rx_tx_ubi32_bias_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_UNIPHY2_RX, 1 },
 | |
| --	{ P_UNIPHY2_TX, 2 },
 | |
| --	{ P_UBI32_PLL, 5 },
 | |
| --	{ P_BIAS_PLL, 6 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_uniphy2_tx_rx_ubi32_bias[] = {
 | |
| --	"xo",
 | |
| --	"uniphy2_gcc_tx_clk",
 | |
| --	"uniphy2_gcc_rx_clk",
 | |
| --	"ubi32_pll",
 | |
| --	"bias_pll_cc_clk",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_uniphy2_tx_rx_ubi32_bias_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_UNIPHY2_TX, 1 },
 | |
| --	{ P_UNIPHY2_RX, 2 },
 | |
| --	{ P_UBI32_PLL, 5 },
 | |
| --	{ P_BIAS_PLL, 6 },
 | |
| --};
 | |
| --
 | |
| --static const char * const gcc_xo_gpll0_gpll6_gpll0_sleep_clk[] = {
 | |
| --	"xo",
 | |
| --	"gpll0",
 | |
| --	"gpll6",
 | |
| --	"gpll0_out_main_div2",
 | |
| --	"sleep_clk",
 | |
| --};
 | |
| --
 | |
| --static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map[] = {
 | |
| --	{ P_XO, 0 },
 | |
| --	{ P_GPLL0, 1 },
 | |
| --	{ P_GPLL6, 2 },
 | |
| --	{ P_GPLL0_DIV2, 4 },
 | |
| --	{ P_SLEEP_CLK, 6 },
 | |
| --};
 | |
| --
 | |
| - static struct clk_alpha_pll gpll0_main = {
 | |
| - 	.offset = 0x21000,
 | |
| - 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
 | |
| -@@ -400,8 +57,9 @@ static struct clk_alpha_pll gpll0_main =
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gpll0_main",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"xo"
 | |
| -+			.parent_data = &(const struct clk_parent_data){
 | |
| -+				.fw_name = "xo",
 | |
| -+				.name = "xo",
 | |
| - 			},
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_alpha_pll_ops,
 | |
| -@@ -414,9 +72,8 @@ static struct clk_fixed_factor gpll0_out
 | |
| - 	.div = 2,
 | |
| - 	.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "gpll0_out_main_div2",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"gpll0_main"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gpll0_main.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_fixed_factor_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -429,9 +86,8 @@ static struct clk_alpha_pll_postdiv gpll
 | |
| - 	.width = 4,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "gpll0",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"gpll0_main"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gpll0_main.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_alpha_pll_postdiv_ro_ops,
 | |
| - 	},
 | |
| -@@ -445,8 +101,9 @@ static struct clk_alpha_pll gpll2_main =
 | |
| - 		.enable_mask = BIT(2),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gpll2_main",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"xo"
 | |
| -+			.parent_data = &(const struct clk_parent_data){
 | |
| -+				.fw_name = "xo",
 | |
| -+				.name = "xo",
 | |
| - 			},
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_alpha_pll_ops,
 | |
| -@@ -461,9 +118,8 @@ static struct clk_alpha_pll_postdiv gpll
 | |
| - 	.width = 4,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "gpll2",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"gpll2_main"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gpll2_main.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_alpha_pll_postdiv_ro_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -478,8 +134,9 @@ static struct clk_alpha_pll gpll4_main =
 | |
| - 		.enable_mask = BIT(5),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gpll4_main",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"xo"
 | |
| -+			.parent_data = &(const struct clk_parent_data){
 | |
| -+				.fw_name = "xo",
 | |
| -+				.name = "xo",
 | |
| - 			},
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_alpha_pll_ops,
 | |
| -@@ -494,9 +151,8 @@ static struct clk_alpha_pll_postdiv gpll
 | |
| - 	.width = 4,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "gpll4",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"gpll4_main"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gpll4_main.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_alpha_pll_postdiv_ro_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -512,8 +168,9 @@ static struct clk_alpha_pll gpll6_main =
 | |
| - 		.enable_mask = BIT(7),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gpll6_main",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"xo"
 | |
| -+			.parent_data = &(const struct clk_parent_data){
 | |
| -+				.fw_name = "xo",
 | |
| -+				.name = "xo",
 | |
| - 			},
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_alpha_pll_ops,
 | |
| -@@ -528,9 +185,8 @@ static struct clk_alpha_pll_postdiv gpll
 | |
| - 	.width = 2,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "gpll6",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"gpll6_main"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gpll6_main.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_alpha_pll_postdiv_ro_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -542,9 +198,8 @@ static struct clk_fixed_factor gpll6_out
 | |
| - 	.div = 2,
 | |
| - 	.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "gpll6_out_main_div2",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"gpll6_main"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gpll6_main.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_fixed_factor_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -560,8 +215,9 @@ static struct clk_alpha_pll ubi32_pll_ma
 | |
| - 		.enable_mask = BIT(6),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "ubi32_pll_main",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"xo"
 | |
| -+			.parent_data = &(const struct clk_parent_data){
 | |
| -+				.fw_name = "xo",
 | |
| -+				.name = "xo",
 | |
| - 			},
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_alpha_pll_huayra_ops,
 | |
| -@@ -575,9 +231,8 @@ static struct clk_alpha_pll_postdiv ubi3
 | |
| - 	.width = 2,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "ubi32_pll",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"ubi32_pll_main"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&ubi32_pll_main.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_alpha_pll_postdiv_ro_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -592,8 +247,9 @@ static struct clk_alpha_pll nss_crypto_p
 | |
| - 		.enable_mask = BIT(4),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_crypto_pll_main",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"xo"
 | |
| -+			.parent_data = &(const struct clk_parent_data){
 | |
| -+				.fw_name = "xo",
 | |
| -+				.name = "xo",
 | |
| - 			},
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_alpha_pll_ops,
 | |
| -@@ -607,9 +263,8 @@ static struct clk_alpha_pll_postdiv nss_
 | |
| - 	.width = 4,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_crypto_pll",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"nss_crypto_pll_main"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_crypto_pll_main.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_alpha_pll_postdiv_ro_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -623,6 +278,18 @@ static const struct freq_tbl ftbl_pcnoc_
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_gpll0_gpll0_out_main_div2[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &gpll0.clkr.hw},
 | |
| -+	{ .hw = &gpll0_out_main_div2.hw},
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_gpll0_gpll0_out_main_div2_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_GPLL0, 1 },
 | |
| -+	{ P_GPLL0_DIV2, 4 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 pcnoc_bfdcd_clk_src = {
 | |
| - 	.cmd_rcgr = 0x27000,
 | |
| - 	.freq_tbl = ftbl_pcnoc_bfdcd_clk_src,
 | |
| -@@ -630,8 +297,8 @@ static struct clk_rcg2 pcnoc_bfdcd_clk_s
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "pcnoc_bfdcd_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 		.flags = CLK_IS_CRITICAL,
 | |
| - 	},
 | |
| -@@ -642,9 +309,8 @@ static struct clk_fixed_factor pcnoc_clk
 | |
| - 	.div = 1,
 | |
| - 	.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "pcnoc_clk_src",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"pcnoc_bfdcd_clk_src"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_bfdcd_clk_src.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_fixed_factor_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -658,8 +324,9 @@ static struct clk_branch gcc_sleep_clk_s
 | |
| - 		.enable_mask = BIT(1),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_sleep_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"sleep_clk"
 | |
| -+			.parent_data = &(const struct clk_parent_data){
 | |
| -+				.fw_name = "sleep_clk",
 | |
| -+				.name = "sleep_clk",
 | |
| - 			},
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -682,8 +349,8 @@ static struct clk_rcg2 blsp1_qup1_i2c_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup1_i2c_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -708,8 +375,8 @@ static struct clk_rcg2 blsp1_qup1_spi_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup1_spi_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -721,8 +388,8 @@ static struct clk_rcg2 blsp1_qup2_i2c_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup2_i2c_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -735,8 +402,8 @@ static struct clk_rcg2 blsp1_qup2_spi_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup2_spi_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -748,8 +415,8 @@ static struct clk_rcg2 blsp1_qup3_i2c_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup3_i2c_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -762,8 +429,8 @@ static struct clk_rcg2 blsp1_qup3_spi_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup3_spi_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -775,8 +442,8 @@ static struct clk_rcg2 blsp1_qup4_i2c_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup4_i2c_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -789,8 +456,8 @@ static struct clk_rcg2 blsp1_qup4_spi_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup4_spi_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -802,8 +469,8 @@ static struct clk_rcg2 blsp1_qup5_i2c_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup5_i2c_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -816,8 +483,8 @@ static struct clk_rcg2 blsp1_qup5_spi_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup5_spi_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -829,8 +496,8 @@ static struct clk_rcg2 blsp1_qup6_i2c_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup6_i2c_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -843,8 +510,8 @@ static struct clk_rcg2 blsp1_qup6_spi_ap
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_qup6_spi_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -877,8 +544,8 @@ static struct clk_rcg2 blsp1_uart1_apps_
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_uart1_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -891,8 +558,8 @@ static struct clk_rcg2 blsp1_uart2_apps_
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_uart2_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -905,8 +572,8 @@ static struct clk_rcg2 blsp1_uart3_apps_
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_uart3_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -919,8 +586,8 @@ static struct clk_rcg2 blsp1_uart4_apps_
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_uart4_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -933,8 +600,8 @@ static struct clk_rcg2 blsp1_uart5_apps_
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_uart5_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -947,8 +614,8 @@ static struct clk_rcg2 blsp1_uart6_apps_
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "blsp1_uart6_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -958,6 +625,11 @@ static const struct clk_parent_data gcc_
 | |
| - 	{ .hw = &gpll0.clkr.hw },
 | |
| - };
 | |
| - 
 | |
| -+static const struct parent_map gcc_xo_gpll0_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_GPLL0, 1 },
 | |
| -+};
 | |
| -+
 | |
| - static const struct freq_tbl ftbl_pcie_axi_clk_src[] = {
 | |
| - 	F(19200000, P_XO, 1, 0, 0),
 | |
| - 	F(200000000, P_GPLL0, 4, 0, 0),
 | |
| -@@ -972,7 +644,7 @@ static struct clk_rcg2 pcie0_axi_clk_src
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "pcie0_axi_clk_src",
 | |
| - 		.parent_data = gcc_xo_gpll0,
 | |
| --		.num_parents = 2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -981,6 +653,18 @@ static const struct freq_tbl ftbl_pcie_a
 | |
| - 	F(19200000, P_XO, 1, 0, 0),
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_gpll0_sleep_clk[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+	{ .fw_name = "sleep_clk", .name = "sleep_clk" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_gpll0_sleep_clk_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_GPLL0, 2 },
 | |
| -+	{ P_SLEEP_CLK, 6 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 pcie0_aux_clk_src = {
 | |
| - 	.cmd_rcgr = 0x75024,
 | |
| - 	.freq_tbl = ftbl_pcie_aux_clk_src,
 | |
| -@@ -989,12 +673,22 @@ static struct clk_rcg2 pcie0_aux_clk_src
 | |
| - 	.parent_map = gcc_xo_gpll0_sleep_clk_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "pcie0_aux_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_sleep_clk,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_sleep_clk,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_sleep_clk),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_pcie20_phy0_pipe_clk_xo[] = {
 | |
| -+	{ .name = "pcie20_phy0_pipe_clk" },
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_pcie20_phy0_pipe_clk_xo_map[] = {
 | |
| -+	{ P_PCIE20_PHY0_PIPE, 0 },
 | |
| -+	{ P_XO, 2 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_regmap_mux pcie0_pipe_clk_src = {
 | |
| - 	.reg = 0x7501c,
 | |
| - 	.shift = 8,
 | |
| -@@ -1003,8 +697,8 @@ static struct clk_regmap_mux pcie0_pipe_
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "pcie0_pipe_clk_src",
 | |
| --			.parent_names = gcc_pcie20_phy0_pipe_clk_xo,
 | |
| --			.num_parents = 2,
 | |
| -+			.parent_data = gcc_pcie20_phy0_pipe_clk_xo,
 | |
| -+			.num_parents = ARRAY_SIZE(gcc_pcie20_phy0_pipe_clk_xo),
 | |
| - 			.ops = &clk_regmap_mux_closest_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 		},
 | |
| -@@ -1019,7 +713,7 @@ static struct clk_rcg2 pcie1_axi_clk_src
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "pcie1_axi_clk_src",
 | |
| - 		.parent_data = gcc_xo_gpll0,
 | |
| --		.num_parents = 2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1032,12 +726,22 @@ static struct clk_rcg2 pcie1_aux_clk_src
 | |
| - 	.parent_map = gcc_xo_gpll0_sleep_clk_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "pcie1_aux_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_sleep_clk,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_sleep_clk,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_sleep_clk),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_pcie20_phy1_pipe_clk_xo[] = {
 | |
| -+	{ .name = "pcie20_phy1_pipe_clk" },
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_pcie20_phy1_pipe_clk_xo_map[] = {
 | |
| -+	{ P_PCIE20_PHY1_PIPE, 0 },
 | |
| -+	{ P_XO, 2 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_regmap_mux pcie1_pipe_clk_src = {
 | |
| - 	.reg = 0x7601c,
 | |
| - 	.shift = 8,
 | |
| -@@ -1046,8 +750,8 @@ static struct clk_regmap_mux pcie1_pipe_
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "pcie1_pipe_clk_src",
 | |
| --			.parent_names = gcc_pcie20_phy1_pipe_clk_xo,
 | |
| --			.num_parents = 2,
 | |
| -+			.parent_data = gcc_pcie20_phy1_pipe_clk_xo,
 | |
| -+			.num_parents = ARRAY_SIZE(gcc_pcie20_phy1_pipe_clk_xo),
 | |
| - 			.ops = &clk_regmap_mux_closest_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 		},
 | |
| -@@ -1066,6 +770,20 @@ static const struct freq_tbl ftbl_sdcc_a
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_gpll0_gpll2_gpll0_out_main_div2[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+	{ .hw = &gpll2.clkr.hw },
 | |
| -+	{ .hw = &gpll0_out_main_div2.hw },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_gpll0_gpll2_gpll0_out_main_div2_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_GPLL0, 1 },
 | |
| -+	{ P_GPLL2, 2 },
 | |
| -+	{ P_GPLL0_DIV2, 4 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 sdcc1_apps_clk_src = {
 | |
| - 	.cmd_rcgr = 0x42004,
 | |
| - 	.freq_tbl = ftbl_sdcc_apps_clk_src,
 | |
| -@@ -1074,8 +792,8 @@ static struct clk_rcg2 sdcc1_apps_clk_sr
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll2_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "sdcc1_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll2_gpll0_out_main_div2,
 | |
| --		.num_parents = 4,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll2_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_floor_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1086,6 +804,20 @@ static const struct freq_tbl ftbl_sdcc_i
 | |
| - 	F(308570000, P_GPLL6, 3.5, 0, 0),
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_div2[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+	{ .hw = &gpll6.clkr.hw },
 | |
| -+	{ .hw = &gpll0_out_main_div2.hw },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_div2_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_GPLL0, 1 },
 | |
| -+	{ P_GPLL6, 2 },
 | |
| -+	{ P_GPLL0_DIV2, 4 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 sdcc1_ice_core_clk_src = {
 | |
| - 	.cmd_rcgr = 0x5d000,
 | |
| - 	.freq_tbl = ftbl_sdcc_ice_core_clk_src,
 | |
| -@@ -1094,8 +826,8 @@ static struct clk_rcg2 sdcc1_ice_core_cl
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll6_gpll0_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "sdcc1_ice_core_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll6_gpll0_div2,
 | |
| --		.num_parents = 4,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll6_gpll0_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_gpll0_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1108,8 +840,8 @@ static struct clk_rcg2 sdcc2_apps_clk_sr
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll2_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "sdcc2_apps_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll2_gpll0_out_main_div2,
 | |
| --		.num_parents = 4,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll2_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_floor_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1121,6 +853,18 @@ static const struct freq_tbl ftbl_usb_ma
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_gpll0_out_main_div2_gpll0[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &gpll0_out_main_div2.hw },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_gpll0_out_main_div2_gpll0_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_GPLL0_DIV2, 2 },
 | |
| -+	{ P_GPLL0, 1 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 usb0_master_clk_src = {
 | |
| - 	.cmd_rcgr = 0x3e00c,
 | |
| - 	.freq_tbl = ftbl_usb_master_clk_src,
 | |
| -@@ -1129,8 +873,8 @@ static struct clk_rcg2 usb0_master_clk_s
 | |
| - 	.parent_map = gcc_xo_gpll0_out_main_div2_gpll0_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "usb0_master_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_out_main_div2_gpll0,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_out_main_div2_gpll0,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_out_main_div2_gpll0),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1148,8 +892,8 @@ static struct clk_rcg2 usb0_aux_clk_src
 | |
| - 	.parent_map = gcc_xo_gpll0_sleep_clk_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "usb0_aux_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_sleep_clk,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_sleep_clk,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_sleep_clk),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1161,6 +905,20 @@ static const struct freq_tbl ftbl_usb_mo
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_gpll6_gpll0_gpll0_out_main_div2[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &gpll6.clkr.hw },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+	{ .hw = &gpll0_out_main_div2.hw },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_GPLL6, 1 },
 | |
| -+	{ P_GPLL0, 3 },
 | |
| -+	{ P_GPLL0_DIV2, 4 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 usb0_mock_utmi_clk_src = {
 | |
| - 	.cmd_rcgr = 0x3e020,
 | |
| - 	.freq_tbl = ftbl_usb_mock_utmi_clk_src,
 | |
| -@@ -1169,12 +927,22 @@ static struct clk_rcg2 usb0_mock_utmi_cl
 | |
| - 	.parent_map = gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "usb0_mock_utmi_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll6_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 4,
 | |
| -+		.parent_data = gcc_xo_gpll6_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll6_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_usb3phy_0_cc_pipe_clk_xo[] = {
 | |
| -+	{ .name = "usb3phy_0_cc_pipe_clk" },
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_usb3phy_0_cc_pipe_clk_xo_map[] = {
 | |
| -+	{ P_USB3PHY_0_PIPE, 0 },
 | |
| -+	{ P_XO, 2 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_regmap_mux usb0_pipe_clk_src = {
 | |
| - 	.reg = 0x3e048,
 | |
| - 	.shift = 8,
 | |
| -@@ -1183,8 +951,8 @@ static struct clk_regmap_mux usb0_pipe_c
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "usb0_pipe_clk_src",
 | |
| --			.parent_names = gcc_usb3phy_0_cc_pipe_clk_xo,
 | |
| --			.num_parents = 2,
 | |
| -+			.parent_data = gcc_usb3phy_0_cc_pipe_clk_xo,
 | |
| -+			.num_parents = ARRAY_SIZE(gcc_usb3phy_0_cc_pipe_clk_xo),
 | |
| - 			.ops = &clk_regmap_mux_closest_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 		},
 | |
| -@@ -1199,8 +967,8 @@ static struct clk_rcg2 usb1_master_clk_s
 | |
| - 	.parent_map = gcc_xo_gpll0_out_main_div2_gpll0_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "usb1_master_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_out_main_div2_gpll0,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_out_main_div2_gpll0,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_out_main_div2_gpll0),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1213,8 +981,8 @@ static struct clk_rcg2 usb1_aux_clk_src
 | |
| - 	.parent_map = gcc_xo_gpll0_sleep_clk_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "usb1_aux_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_sleep_clk,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_sleep_clk,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_sleep_clk),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1227,12 +995,22 @@ static struct clk_rcg2 usb1_mock_utmi_cl
 | |
| - 	.parent_map = gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "usb1_mock_utmi_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll6_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 4,
 | |
| -+		.parent_data = gcc_xo_gpll6_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll6_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_usb3phy_1_cc_pipe_clk_xo[] = {
 | |
| -+	{ .name = "usb3phy_1_cc_pipe_clk" },
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_usb3phy_1_cc_pipe_clk_xo_map[] = {
 | |
| -+	{ P_USB3PHY_1_PIPE, 0 },
 | |
| -+	{ P_XO, 2 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_regmap_mux usb1_pipe_clk_src = {
 | |
| - 	.reg = 0x3f048,
 | |
| - 	.shift = 8,
 | |
| -@@ -1241,8 +1019,8 @@ static struct clk_regmap_mux usb1_pipe_c
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "usb1_pipe_clk_src",
 | |
| --			.parent_names = gcc_usb3phy_1_cc_pipe_clk_xo,
 | |
| --			.num_parents = 2,
 | |
| -+			.parent_data = gcc_usb3phy_1_cc_pipe_clk_xo,
 | |
| -+			.num_parents = ARRAY_SIZE(gcc_usb3phy_1_cc_pipe_clk_xo),
 | |
| - 			.ops = &clk_regmap_mux_closest_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 		},
 | |
| -@@ -1256,8 +1034,9 @@ static struct clk_branch gcc_xo_clk_src
 | |
| - 		.enable_mask = BIT(1),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_xo_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"xo"
 | |
| -+			.parent_data = &(const struct clk_parent_data){
 | |
| -+				.fw_name = "xo",
 | |
| -+				.name = "xo",
 | |
| - 			},
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
 | |
| -@@ -1271,9 +1050,8 @@ static struct clk_fixed_factor gcc_xo_di
 | |
| - 	.div = 4,
 | |
| - 	.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "gcc_xo_div4_clk_src",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"gcc_xo_clk_src"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gcc_xo_clk_src.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_fixed_factor_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1291,6 +1069,20 @@ static const struct freq_tbl ftbl_system
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_out_main_div2[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+	{ .hw = &gpll6.clkr.hw },
 | |
| -+	{ .hw = &gpll0_out_main_div2.hw },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_out_main_div2_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_GPLL0, 1 },
 | |
| -+	{ P_GPLL6, 2 },
 | |
| -+	{ P_GPLL0_DIV2, 3 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 system_noc_bfdcd_clk_src = {
 | |
| - 	.cmd_rcgr = 0x26004,
 | |
| - 	.freq_tbl = ftbl_system_noc_bfdcd_clk_src,
 | |
| -@@ -1298,8 +1090,8 @@ static struct clk_rcg2 system_noc_bfdcd_
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll6_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "system_noc_bfdcd_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll6_gpll0_out_main_div2,
 | |
| --		.num_parents = 4,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll6_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 		.flags = CLK_IS_CRITICAL,
 | |
| - 	},
 | |
| -@@ -1310,9 +1102,8 @@ static struct clk_fixed_factor system_no
 | |
| - 	.div = 1,
 | |
| - 	.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "system_noc_clk_src",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"system_noc_bfdcd_clk_src"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&system_noc_bfdcd_clk_src.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_fixed_factor_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1333,7 +1124,7 @@ static struct clk_rcg2 nss_ce_clk_src =
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_ce_clk_src",
 | |
| - 		.parent_data = gcc_xo_gpll0,
 | |
| --		.num_parents = 2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1344,6 +1135,20 @@ static const struct freq_tbl ftbl_nss_no
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_bias_pll_nss_noc_clk_gpll0_gpll2[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .name = "bias_pll_nss_noc_clk" },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+	{ .hw = &gpll2.clkr.hw },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_bias_pll_nss_noc_clk_gpll0_gpll2_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_BIAS_PLL_NSS_NOC, 1 },
 | |
| -+	{ P_GPLL0, 2 },
 | |
| -+	{ P_GPLL2, 3 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 nss_noc_bfdcd_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68088,
 | |
| - 	.freq_tbl = ftbl_nss_noc_bfdcd_clk_src,
 | |
| -@@ -1351,8 +1156,8 @@ static struct clk_rcg2 nss_noc_bfdcd_clk
 | |
| - 	.parent_map = gcc_xo_bias_pll_nss_noc_clk_gpll0_gpll2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_noc_bfdcd_clk_src",
 | |
| --		.parent_names = gcc_xo_bias_pll_nss_noc_clk_gpll0_gpll2,
 | |
| --		.num_parents = 4,
 | |
| -+		.parent_data = gcc_xo_bias_pll_nss_noc_clk_gpll0_gpll2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_bias_pll_nss_noc_clk_gpll0_gpll2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1362,9 +1167,8 @@ static struct clk_fixed_factor nss_noc_c
 | |
| - 	.div = 1,
 | |
| - 	.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_noc_clk_src",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"nss_noc_bfdcd_clk_src"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_noc_bfdcd_clk_src.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_fixed_factor_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1377,6 +1181,18 @@ static const struct freq_tbl ftbl_nss_cr
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_nss_crypto_pll_gpll0[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &nss_crypto_pll.clkr.hw },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_nss_crypto_pll_gpll0_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_NSS_CRYPTO_PLL, 1 },
 | |
| -+	{ P_GPLL0, 2 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 nss_crypto_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68144,
 | |
| - 	.freq_tbl = ftbl_nss_crypto_clk_src,
 | |
| -@@ -1385,8 +1201,8 @@ static struct clk_rcg2 nss_crypto_clk_sr
 | |
| - 	.parent_map = gcc_xo_nss_crypto_pll_gpll0_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_crypto_clk_src",
 | |
| --		.parent_names = gcc_xo_nss_crypto_pll_gpll0,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_nss_crypto_pll_gpll0,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_nss_crypto_pll_gpll0),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1400,6 +1216,24 @@ static const struct freq_tbl ftbl_nss_ub
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &ubi32_pll.clkr.hw },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+	{ .hw = &gpll2.clkr.hw },
 | |
| -+	{ .hw = &gpll4.clkr.hw },
 | |
| -+	{ .hw = &gpll6.clkr.hw },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_ubi32_gpll0_gpll2_gpll4_gpll6_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_UBI32_PLL, 1 },
 | |
| -+	{ P_GPLL0, 2 },
 | |
| -+	{ P_GPLL2, 3 },
 | |
| -+	{ P_GPLL4, 4 },
 | |
| -+	{ P_GPLL6, 5 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 nss_ubi0_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68104,
 | |
| - 	.freq_tbl = ftbl_nss_ubi_clk_src,
 | |
| -@@ -1407,8 +1241,8 @@ static struct clk_rcg2 nss_ubi0_clk_src
 | |
| - 	.parent_map = gcc_xo_ubi32_gpll0_gpll2_gpll4_gpll6_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_ubi0_clk_src",
 | |
| --		.parent_names = gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6,
 | |
| --		.num_parents = 6,
 | |
| -+		.parent_data = gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| - 	},
 | |
| -@@ -1421,9 +1255,8 @@ static struct clk_regmap_div nss_ubi0_di
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_ubi0_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ubi0_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ubi0_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ro_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1438,8 +1271,8 @@ static struct clk_rcg2 nss_ubi1_clk_src
 | |
| - 	.parent_map = gcc_xo_ubi32_gpll0_gpll2_gpll4_gpll6_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_ubi1_clk_src",
 | |
| --		.parent_names = gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6,
 | |
| --		.num_parents = 6,
 | |
| -+		.parent_data = gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| - 	},
 | |
| -@@ -1452,9 +1285,8 @@ static struct clk_regmap_div nss_ubi1_di
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_ubi1_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ubi1_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ubi1_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ro_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1468,6 +1300,16 @@ static const struct freq_tbl ftbl_ubi_mp
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_gpll0_out_main_div2[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &gpll0_out_main_div2.hw },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_gpll0_out_main_div2_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_GPLL0_DIV2, 1 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 ubi_mpt_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68090,
 | |
| - 	.freq_tbl = ftbl_ubi_mpt_clk_src,
 | |
| -@@ -1475,8 +1317,8 @@ static struct clk_rcg2 ubi_mpt_clk_src =
 | |
| - 	.parent_map = gcc_xo_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "ubi_mpt_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_out_main_div2,
 | |
| --		.num_parents = 2,
 | |
| -+		.parent_data = gcc_xo_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1487,6 +1329,18 @@ static const struct freq_tbl ftbl_nss_im
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_gpll0_gpll4[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+	{ .hw = &gpll4.clkr.hw },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_GPLL0, 1 },
 | |
| -+	{ P_GPLL4, 2 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 nss_imem_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68158,
 | |
| - 	.freq_tbl = ftbl_nss_imem_clk_src,
 | |
| -@@ -1494,8 +1348,8 @@ static struct clk_rcg2 nss_imem_clk_src
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll4_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_imem_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll4,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll4,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll4),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1506,6 +1360,24 @@ static const struct freq_tbl ftbl_nss_pp
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_bias_gpll0_gpll4_nss_ubi32[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .name = "bias_pll_cc_clk" },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+	{ .hw = &gpll4.clkr.hw },
 | |
| -+	{ .hw = &nss_crypto_pll.clkr.hw },
 | |
| -+	{ .hw = &ubi32_pll.clkr.hw },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_bias_gpll0_gpll4_nss_ubi32_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_BIAS_PLL, 1 },
 | |
| -+	{ P_GPLL0, 2 },
 | |
| -+	{ P_GPLL4, 3 },
 | |
| -+	{ P_NSS_CRYPTO_PLL, 4 },
 | |
| -+	{ P_UBI32_PLL, 5 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 nss_ppe_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68080,
 | |
| - 	.freq_tbl = ftbl_nss_ppe_clk_src,
 | |
| -@@ -1513,8 +1385,8 @@ static struct clk_rcg2 nss_ppe_clk_src =
 | |
| - 	.parent_map = gcc_xo_bias_gpll0_gpll4_nss_ubi32_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_ppe_clk_src",
 | |
| --		.parent_names = gcc_xo_bias_gpll0_gpll4_nss_ubi32,
 | |
| --		.num_parents = 6,
 | |
| -+		.parent_data = gcc_xo_bias_gpll0_gpll4_nss_ubi32,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_bias_gpll0_gpll4_nss_ubi32),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1524,9 +1396,8 @@ static struct clk_fixed_factor nss_ppe_c
 | |
| - 	.div = 4,
 | |
| - 	.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_ppe_cdiv_clk_src",
 | |
| --		.parent_names = (const char *[]){
 | |
| --			"nss_ppe_clk_src"
 | |
| --		},
 | |
| -+		.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 		.num_parents = 1,
 | |
| - 		.ops = &clk_fixed_factor_ops,
 | |
| - 		.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1540,6 +1411,22 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_uniphy0_rx_tx_ubi32_bias[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .name = "uniphy0_gcc_rx_clk" },
 | |
| -+	{ .name = "uniphy0_gcc_tx_clk" },
 | |
| -+	{ .hw = &ubi32_pll.clkr.hw },
 | |
| -+	{ .name = "bias_pll_cc_clk" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_uniphy0_rx_tx_ubi32_bias_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_UNIPHY0_RX, 1 },
 | |
| -+	{ P_UNIPHY0_TX, 2 },
 | |
| -+	{ P_UBI32_PLL, 5 },
 | |
| -+	{ P_BIAS_PLL, 6 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 nss_port1_rx_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68020,
 | |
| - 	.freq_tbl = ftbl_nss_port1_rx_clk_src,
 | |
| -@@ -1547,8 +1434,8 @@ static struct clk_rcg2 nss_port1_rx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port1_rx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy0_rx_tx_ubi32_bias,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy0_rx_tx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1560,9 +1447,8 @@ static struct clk_regmap_div nss_port1_r
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port1_rx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port1_rx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port1_rx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1577,6 +1463,22 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_uniphy0_tx_rx_ubi32_bias[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .name = "uniphy0_gcc_tx_clk" },
 | |
| -+	{ .name = "uniphy0_gcc_rx_clk" },
 | |
| -+	{ .hw = &ubi32_pll.clkr.hw },
 | |
| -+	{ .name = "bias_pll_cc_clk" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_uniphy0_tx_rx_ubi32_bias_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_UNIPHY0_TX, 1 },
 | |
| -+	{ P_UNIPHY0_RX, 2 },
 | |
| -+	{ P_UBI32_PLL, 5 },
 | |
| -+	{ P_BIAS_PLL, 6 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 nss_port1_tx_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68028,
 | |
| - 	.freq_tbl = ftbl_nss_port1_tx_clk_src,
 | |
| -@@ -1584,8 +1486,8 @@ static struct clk_rcg2 nss_port1_tx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port1_tx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy0_tx_rx_ubi32_bias,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy0_tx_rx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1597,9 +1499,8 @@ static struct clk_regmap_div nss_port1_t
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port1_tx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port1_tx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port1_tx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1614,8 +1515,8 @@ static struct clk_rcg2 nss_port2_rx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port2_rx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy0_rx_tx_ubi32_bias,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy0_rx_tx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1627,9 +1528,8 @@ static struct clk_regmap_div nss_port2_r
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port2_rx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port2_rx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port2_rx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1644,8 +1544,8 @@ static struct clk_rcg2 nss_port2_tx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port2_tx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy0_tx_rx_ubi32_bias,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy0_tx_rx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1657,9 +1557,8 @@ static struct clk_regmap_div nss_port2_t
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port2_tx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port2_tx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port2_tx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1674,8 +1573,8 @@ static struct clk_rcg2 nss_port3_rx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port3_rx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy0_rx_tx_ubi32_bias,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy0_rx_tx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1687,9 +1586,8 @@ static struct clk_regmap_div nss_port3_r
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port3_rx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port3_rx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port3_rx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1704,8 +1602,8 @@ static struct clk_rcg2 nss_port3_tx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port3_tx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy0_tx_rx_ubi32_bias,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy0_tx_rx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1717,9 +1615,8 @@ static struct clk_regmap_div nss_port3_t
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port3_tx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port3_tx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port3_tx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1734,8 +1631,8 @@ static struct clk_rcg2 nss_port4_rx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port4_rx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy0_rx_tx_ubi32_bias,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy0_rx_tx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1747,9 +1644,8 @@ static struct clk_regmap_div nss_port4_r
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port4_rx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port4_rx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port4_rx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1764,8 +1660,8 @@ static struct clk_rcg2 nss_port4_tx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port4_tx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy0_tx_rx_ubi32_bias,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy0_tx_rx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1777,9 +1673,8 @@ static struct clk_regmap_div nss_port4_t
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port4_tx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port4_tx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port4_tx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1799,6 +1694,27 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .name = "uniphy0_gcc_rx_clk" },
 | |
| -+	{ .name = "uniphy0_gcc_tx_clk" },
 | |
| -+	{ .name = "uniphy1_gcc_rx_clk" },
 | |
| -+	{ .name = "uniphy1_gcc_tx_clk" },
 | |
| -+	{ .hw = &ubi32_pll.clkr.hw },
 | |
| -+	{ .name = "bias_pll_cc_clk" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map
 | |
| -+gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_UNIPHY0_RX, 1 },
 | |
| -+	{ P_UNIPHY0_TX, 2 },
 | |
| -+	{ P_UNIPHY1_RX, 3 },
 | |
| -+	{ P_UNIPHY1_TX, 4 },
 | |
| -+	{ P_UBI32_PLL, 5 },
 | |
| -+	{ P_BIAS_PLL, 6 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 nss_port5_rx_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68060,
 | |
| - 	.freq_tbl = ftbl_nss_port5_rx_clk_src,
 | |
| -@@ -1806,8 +1722,8 @@ static struct clk_rcg2 nss_port5_rx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port5_rx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias,
 | |
| --		.num_parents = 7,
 | |
| -+		.parent_data = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1819,9 +1735,8 @@ static struct clk_regmap_div nss_port5_r
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port5_rx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port5_rx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port5_rx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1841,6 +1756,27 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .name = "uniphy0_gcc_tx_clk" },
 | |
| -+	{ .name = "uniphy0_gcc_rx_clk" },
 | |
| -+	{ .name = "uniphy1_gcc_tx_clk" },
 | |
| -+	{ .name = "uniphy1_gcc_rx_clk" },
 | |
| -+	{ .hw = &ubi32_pll.clkr.hw },
 | |
| -+	{ .name = "bias_pll_cc_clk" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map
 | |
| -+gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_UNIPHY0_TX, 1 },
 | |
| -+	{ P_UNIPHY0_RX, 2 },
 | |
| -+	{ P_UNIPHY1_TX, 3 },
 | |
| -+	{ P_UNIPHY1_RX, 4 },
 | |
| -+	{ P_UBI32_PLL, 5 },
 | |
| -+	{ P_BIAS_PLL, 6 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 nss_port5_tx_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68068,
 | |
| - 	.freq_tbl = ftbl_nss_port5_tx_clk_src,
 | |
| -@@ -1848,8 +1784,8 @@ static struct clk_rcg2 nss_port5_tx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port5_tx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias,
 | |
| --		.num_parents = 7,
 | |
| -+		.parent_data = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1861,9 +1797,8 @@ static struct clk_regmap_div nss_port5_t
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port5_tx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port5_tx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port5_tx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1883,6 +1818,22 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_uniphy2_rx_tx_ubi32_bias[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .name = "uniphy2_gcc_rx_clk" },
 | |
| -+	{ .name = "uniphy2_gcc_tx_clk" },
 | |
| -+	{ .hw = &ubi32_pll.clkr.hw },
 | |
| -+	{ .name = "bias_pll_cc_clk" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_uniphy2_rx_tx_ubi32_bias_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_UNIPHY2_RX, 1 },
 | |
| -+	{ P_UNIPHY2_TX, 2 },
 | |
| -+	{ P_UBI32_PLL, 5 },
 | |
| -+	{ P_BIAS_PLL, 6 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 nss_port6_rx_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68070,
 | |
| - 	.freq_tbl = ftbl_nss_port6_rx_clk_src,
 | |
| -@@ -1890,8 +1841,8 @@ static struct clk_rcg2 nss_port6_rx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy2_rx_tx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port6_rx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy2_rx_tx_ubi32_bias,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_uniphy2_rx_tx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy2_rx_tx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1903,9 +1854,8 @@ static struct clk_regmap_div nss_port6_r
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port6_rx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port6_rx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port6_rx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1925,6 +1875,22 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_uniphy2_tx_rx_ubi32_bias[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .name = "uniphy2_gcc_tx_clk" },
 | |
| -+	{ .name = "uniphy2_gcc_rx_clk" },
 | |
| -+	{ .hw = &ubi32_pll.clkr.hw },
 | |
| -+	{ .name = "bias_pll_cc_clk" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_uniphy2_tx_rx_ubi32_bias_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_UNIPHY2_TX, 1 },
 | |
| -+	{ P_UNIPHY2_RX, 2 },
 | |
| -+	{ P_UBI32_PLL, 5 },
 | |
| -+	{ P_BIAS_PLL, 6 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 nss_port6_tx_clk_src = {
 | |
| - 	.cmd_rcgr = 0x68078,
 | |
| - 	.freq_tbl = ftbl_nss_port6_tx_clk_src,
 | |
| -@@ -1932,8 +1898,8 @@ static struct clk_rcg2 nss_port6_tx_clk_
 | |
| - 	.parent_map = gcc_xo_uniphy2_tx_rx_ubi32_bias_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "nss_port6_tx_clk_src",
 | |
| --		.parent_names = gcc_xo_uniphy2_tx_rx_ubi32_bias,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_uniphy2_tx_rx_ubi32_bias,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_uniphy2_tx_rx_ubi32_bias),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1945,9 +1911,8 @@ static struct clk_regmap_div nss_port6_t
 | |
| - 	.clkr = {
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "nss_port6_tx_div_clk_src",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port6_tx_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port6_tx_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.ops = &clk_regmap_div_ops,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| -@@ -1970,8 +1935,8 @@ static struct clk_rcg2 crypto_clk_src =
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "crypto_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| --		.num_parents = 3,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_out_main_div2),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -1981,6 +1946,22 @@ static struct freq_tbl ftbl_gp_clk_src[]
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_sleep_clk[] = {
 | |
| -+	{ .fw_name = "xo", .name = "xo" },
 | |
| -+	{ .hw = &gpll0.clkr.hw },
 | |
| -+	{ .hw = &gpll6.clkr.hw },
 | |
| -+	{ .hw = &gpll0_out_main_div2.hw },
 | |
| -+	{ .fw_name = "sleep_clk", .name = "sleep_clk" },
 | |
| -+};
 | |
| -+
 | |
| -+static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map[] = {
 | |
| -+	{ P_XO, 0 },
 | |
| -+	{ P_GPLL0, 1 },
 | |
| -+	{ P_GPLL6, 2 },
 | |
| -+	{ P_GPLL0_DIV2, 4 },
 | |
| -+	{ P_SLEEP_CLK, 6 },
 | |
| -+};
 | |
| -+
 | |
| - static struct clk_rcg2 gp1_clk_src = {
 | |
| - 	.cmd_rcgr = 0x08004,
 | |
| - 	.freq_tbl = ftbl_gp_clk_src,
 | |
| -@@ -1989,8 +1970,8 @@ static struct clk_rcg2 gp1_clk_src = {
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "gp1_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll6_gpll0_sleep_clk,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll6_gpll0_sleep_clk,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_gpll0_sleep_clk),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -2003,8 +1984,8 @@ static struct clk_rcg2 gp2_clk_src = {
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "gp2_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll6_gpll0_sleep_clk,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll6_gpll0_sleep_clk,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_gpll0_sleep_clk),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -2017,8 +1998,8 @@ static struct clk_rcg2 gp3_clk_src = {
 | |
| - 	.parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map,
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "gp3_clk_src",
 | |
| --		.parent_names = gcc_xo_gpll0_gpll6_gpll0_sleep_clk,
 | |
| --		.num_parents = 5,
 | |
| -+		.parent_data = gcc_xo_gpll0_gpll6_gpll0_sleep_clk,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll6_gpll0_sleep_clk),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| -@@ -2030,9 +2011,8 @@ static struct clk_branch gcc_blsp1_ahb_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2047,9 +2027,8 @@ static struct clk_branch gcc_blsp1_qup1_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup1_i2c_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup1_i2c_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup1_i2c_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2064,9 +2043,8 @@ static struct clk_branch gcc_blsp1_qup1_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup1_spi_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup1_spi_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup1_spi_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2081,9 +2059,8 @@ static struct clk_branch gcc_blsp1_qup2_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup2_i2c_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup2_i2c_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup2_i2c_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2098,9 +2075,8 @@ static struct clk_branch gcc_blsp1_qup2_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup2_spi_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup2_spi_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup2_spi_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2115,9 +2091,8 @@ static struct clk_branch gcc_blsp1_qup3_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup3_i2c_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup3_i2c_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup3_i2c_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2132,9 +2107,8 @@ static struct clk_branch gcc_blsp1_qup3_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup3_spi_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup3_spi_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup3_spi_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2149,9 +2123,8 @@ static struct clk_branch gcc_blsp1_qup4_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup4_i2c_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup4_i2c_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup4_i2c_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2166,9 +2139,8 @@ static struct clk_branch gcc_blsp1_qup4_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup4_spi_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup4_spi_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup4_spi_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2183,9 +2155,8 @@ static struct clk_branch gcc_blsp1_qup5_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup5_i2c_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup5_i2c_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup5_i2c_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2200,9 +2171,8 @@ static struct clk_branch gcc_blsp1_qup5_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup5_spi_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup5_spi_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup5_spi_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2217,9 +2187,8 @@ static struct clk_branch gcc_blsp1_qup6_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup6_i2c_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup6_i2c_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup6_i2c_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2234,9 +2203,8 @@ static struct clk_branch gcc_blsp1_qup6_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_qup6_spi_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_qup6_spi_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_qup6_spi_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2251,9 +2219,8 @@ static struct clk_branch gcc_blsp1_uart1
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_uart1_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_uart1_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_uart1_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2268,9 +2235,8 @@ static struct clk_branch gcc_blsp1_uart2
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_uart2_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_uart2_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_uart2_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2285,9 +2251,8 @@ static struct clk_branch gcc_blsp1_uart3
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_uart3_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_uart3_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_uart3_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2302,9 +2267,8 @@ static struct clk_branch gcc_blsp1_uart4
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_uart4_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_uart4_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_uart4_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2319,9 +2283,8 @@ static struct clk_branch gcc_blsp1_uart5
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_uart5_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_uart5_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_uart5_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2336,9 +2299,8 @@ static struct clk_branch gcc_blsp1_uart6
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_blsp1_uart6_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"blsp1_uart6_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&blsp1_uart6_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2354,9 +2316,8 @@ static struct clk_branch gcc_prng_ahb_cl
 | |
| - 		.enable_mask = BIT(8),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_prng_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2371,9 +2332,8 @@ static struct clk_branch gcc_qpic_ahb_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_qpic_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2388,9 +2348,8 @@ static struct clk_branch gcc_qpic_clk =
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_qpic_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2405,9 +2364,8 @@ static struct clk_branch gcc_pcie0_ahb_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_pcie0_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2422,9 +2380,8 @@ static struct clk_branch gcc_pcie0_aux_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_pcie0_aux_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcie0_aux_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcie0_aux_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2439,9 +2396,8 @@ static struct clk_branch gcc_pcie0_axi_m
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_pcie0_axi_m_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcie0_axi_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcie0_axi_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2456,9 +2412,8 @@ static struct clk_branch gcc_pcie0_axi_s
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_pcie0_axi_s_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcie0_axi_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcie0_axi_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2474,9 +2429,8 @@ static struct clk_branch gcc_pcie0_pipe_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_pcie0_pipe_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcie0_pipe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcie0_pipe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2491,9 +2445,8 @@ static struct clk_branch gcc_sys_noc_pci
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_sys_noc_pcie0_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcie0_axi_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcie0_axi_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2508,9 +2461,8 @@ static struct clk_branch gcc_pcie1_ahb_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_pcie1_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2525,9 +2477,8 @@ static struct clk_branch gcc_pcie1_aux_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_pcie1_aux_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcie1_aux_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcie1_aux_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2542,9 +2493,8 @@ static struct clk_branch gcc_pcie1_axi_m
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_pcie1_axi_m_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcie1_axi_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcie1_axi_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2559,9 +2509,8 @@ static struct clk_branch gcc_pcie1_axi_s
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_pcie1_axi_s_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcie1_axi_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcie1_axi_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2577,9 +2526,8 @@ static struct clk_branch gcc_pcie1_pipe_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_pcie1_pipe_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcie1_pipe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcie1_pipe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2594,9 +2542,8 @@ static struct clk_branch gcc_sys_noc_pci
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_sys_noc_pcie1_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcie1_axi_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcie1_axi_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2611,9 +2558,8 @@ static struct clk_branch gcc_usb0_aux_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb0_aux_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"usb0_aux_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&usb0_aux_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2628,9 +2574,8 @@ static struct clk_branch gcc_sys_noc_usb
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_sys_noc_usb0_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"usb0_master_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&usb0_master_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2645,9 +2590,8 @@ static struct clk_branch gcc_usb0_master
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb0_master_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"usb0_master_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&usb0_master_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2662,9 +2606,8 @@ static struct clk_branch gcc_usb0_mock_u
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb0_mock_utmi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"usb0_mock_utmi_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&usb0_mock_utmi_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2679,9 +2622,8 @@ static struct clk_branch gcc_usb0_phy_cf
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb0_phy_cfg_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2697,9 +2639,8 @@ static struct clk_branch gcc_usb0_pipe_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb0_pipe_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"usb0_pipe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&usb0_pipe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2714,9 +2655,8 @@ static struct clk_branch gcc_usb0_sleep_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb0_sleep_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"gcc_sleep_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gcc_sleep_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2731,9 +2671,8 @@ static struct clk_branch gcc_usb1_aux_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb1_aux_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"usb1_aux_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&usb1_aux_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2748,9 +2687,8 @@ static struct clk_branch gcc_sys_noc_usb
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_sys_noc_usb1_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"usb1_master_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&usb1_master_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2765,9 +2703,8 @@ static struct clk_branch gcc_usb1_master
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb1_master_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"usb1_master_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&usb1_master_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2782,9 +2719,8 @@ static struct clk_branch gcc_usb1_mock_u
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb1_mock_utmi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"usb1_mock_utmi_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&usb1_mock_utmi_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2799,9 +2735,8 @@ static struct clk_branch gcc_usb1_phy_cf
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb1_phy_cfg_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2817,9 +2752,8 @@ static struct clk_branch gcc_usb1_pipe_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb1_pipe_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"usb1_pipe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&usb1_pipe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2834,9 +2768,8 @@ static struct clk_branch gcc_usb1_sleep_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_usb1_sleep_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"gcc_sleep_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gcc_sleep_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2851,9 +2784,8 @@ static struct clk_branch gcc_sdcc1_ahb_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_sdcc1_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2868,9 +2800,8 @@ static struct clk_branch gcc_sdcc1_apps_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_sdcc1_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"sdcc1_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&sdcc1_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2885,9 +2816,8 @@ static struct clk_branch gcc_sdcc1_ice_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_sdcc1_ice_core_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"sdcc1_ice_core_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&sdcc1_ice_core_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2902,9 +2832,8 @@ static struct clk_branch gcc_sdcc2_ahb_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_sdcc2_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2919,9 +2848,8 @@ static struct clk_branch gcc_sdcc2_apps_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_sdcc2_apps_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"sdcc2_apps_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&sdcc2_apps_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2936,9 +2864,8 @@ static struct clk_branch gcc_mem_noc_nss
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_mem_noc_nss_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_noc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_noc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2953,9 +2880,8 @@ static struct clk_branch gcc_nss_ce_apb_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_ce_apb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ce_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ce_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2970,9 +2896,8 @@ static struct clk_branch gcc_nss_ce_axi_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_ce_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ce_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ce_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -2987,9 +2912,8 @@ static struct clk_branch gcc_nss_cfg_clk
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_cfg_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3004,9 +2928,8 @@ static struct clk_branch gcc_nss_crypto_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_crypto_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_crypto_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_crypto_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3021,9 +2944,8 @@ static struct clk_branch gcc_nss_csr_clk
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_csr_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ce_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ce_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3038,9 +2960,8 @@ static struct clk_branch gcc_nss_edma_cf
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_edma_cfg_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3055,9 +2976,8 @@ static struct clk_branch gcc_nss_edma_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_edma_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3072,9 +2992,8 @@ static struct clk_branch gcc_nss_imem_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_imem_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_imem_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_imem_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3089,9 +3008,8 @@ static struct clk_branch gcc_nss_noc_clk
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_noc_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_noc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_noc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3106,9 +3024,8 @@ static struct clk_branch gcc_nss_ppe_btq
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_ppe_btq_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3123,9 +3040,8 @@ static struct clk_branch gcc_nss_ppe_cfg
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_ppe_cfg_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3140,9 +3056,8 @@ static struct clk_branch gcc_nss_ppe_clk
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_ppe_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3157,9 +3072,8 @@ static struct clk_branch gcc_nss_ppe_ipe
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_ppe_ipe_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3174,9 +3088,8 @@ static struct clk_branch gcc_nss_ptp_ref
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_ptp_ref_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_cdiv_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_cdiv_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3192,9 +3105,8 @@ static struct clk_branch gcc_crypto_ppe_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_crypto_ppe_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3209,9 +3121,8 @@ static struct clk_branch gcc_nssnoc_ce_a
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nssnoc_ce_apb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ce_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ce_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3226,9 +3137,8 @@ static struct clk_branch gcc_nssnoc_ce_a
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nssnoc_ce_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ce_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ce_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3243,9 +3153,8 @@ static struct clk_branch gcc_nssnoc_cryp
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nssnoc_crypto_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_crypto_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_crypto_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3260,9 +3169,8 @@ static struct clk_branch gcc_nssnoc_ppe_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nssnoc_ppe_cfg_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3277,9 +3185,8 @@ static struct clk_branch gcc_nssnoc_ppe_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nssnoc_ppe_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3294,9 +3201,8 @@ static struct clk_branch gcc_nssnoc_qosg
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nssnoc_qosgen_ref_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"gcc_xo_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gcc_xo_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3311,9 +3217,8 @@ static struct clk_branch gcc_nssnoc_snoc
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nssnoc_snoc_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"system_noc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&system_noc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3328,9 +3233,8 @@ static struct clk_branch gcc_nssnoc_time
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nssnoc_timeout_ref_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"gcc_xo_div4_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gcc_xo_div4_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3345,9 +3249,8 @@ static struct clk_branch gcc_nssnoc_ubi0
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nssnoc_ubi0_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ce_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ce_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3362,9 +3265,8 @@ static struct clk_branch gcc_nssnoc_ubi1
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nssnoc_ubi1_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ce_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ce_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3380,9 +3282,8 @@ static struct clk_branch gcc_ubi0_ahb_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_ubi0_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ce_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ce_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3398,9 +3299,8 @@ static struct clk_branch gcc_ubi0_axi_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_ubi0_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_noc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_noc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3416,9 +3316,8 @@ static struct clk_branch gcc_ubi0_nc_axi
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_ubi0_nc_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_noc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_noc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3434,9 +3333,8 @@ static struct clk_branch gcc_ubi0_core_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_ubi0_core_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ubi0_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ubi0_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3452,9 +3350,8 @@ static struct clk_branch gcc_ubi0_mpt_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_ubi0_mpt_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"ubi_mpt_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&ubi_mpt_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3470,9 +3367,8 @@ static struct clk_branch gcc_ubi1_ahb_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_ubi1_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ce_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ce_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3488,9 +3384,8 @@ static struct clk_branch gcc_ubi1_axi_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_ubi1_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_noc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_noc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3506,9 +3401,8 @@ static struct clk_branch gcc_ubi1_nc_axi
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_ubi1_nc_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_noc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_noc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3524,9 +3418,8 @@ static struct clk_branch gcc_ubi1_core_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_ubi1_core_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ubi1_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ubi1_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3542,9 +3435,8 @@ static struct clk_branch gcc_ubi1_mpt_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_ubi1_mpt_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"ubi_mpt_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&ubi_mpt_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3559,9 +3451,8 @@ static struct clk_branch gcc_cmn_12gpll_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_cmn_12gpll_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3576,9 +3467,8 @@ static struct clk_branch gcc_cmn_12gpll_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_cmn_12gpll_sys_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"gcc_xo_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gcc_xo_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3593,9 +3483,8 @@ static struct clk_branch gcc_mdio_ahb_cl
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_mdio_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3610,9 +3499,8 @@ static struct clk_branch gcc_uniphy0_ahb
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3627,9 +3515,8 @@ static struct clk_branch gcc_uniphy0_sys
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_sys_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"gcc_xo_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gcc_xo_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3644,9 +3531,8 @@ static struct clk_branch gcc_uniphy1_ahb
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy1_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3661,9 +3547,8 @@ static struct clk_branch gcc_uniphy1_sys
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy1_sys_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"gcc_xo_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gcc_xo_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3678,9 +3563,8 @@ static struct clk_branch gcc_uniphy2_ahb
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy2_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3695,9 +3579,8 @@ static struct clk_branch gcc_uniphy2_sys
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy2_sys_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"gcc_xo_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gcc_xo_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3712,9 +3595,8 @@ static struct clk_branch gcc_nss_port1_r
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port1_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port1_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port1_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3729,9 +3611,8 @@ static struct clk_branch gcc_nss_port1_t
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port1_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port1_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port1_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3746,9 +3627,8 @@ static struct clk_branch gcc_nss_port2_r
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port2_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port2_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port2_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3763,9 +3643,8 @@ static struct clk_branch gcc_nss_port2_t
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port2_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port2_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port2_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3780,9 +3659,8 @@ static struct clk_branch gcc_nss_port3_r
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port3_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port3_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port3_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3797,9 +3675,8 @@ static struct clk_branch gcc_nss_port3_t
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port3_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port3_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port3_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3814,9 +3691,8 @@ static struct clk_branch gcc_nss_port4_r
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port4_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port4_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port4_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3831,9 +3707,8 @@ static struct clk_branch gcc_nss_port4_t
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port4_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port4_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port4_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3848,9 +3723,8 @@ static struct clk_branch gcc_nss_port5_r
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port5_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port5_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port5_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3865,9 +3739,8 @@ static struct clk_branch gcc_nss_port5_t
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port5_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port5_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port5_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3882,9 +3755,8 @@ static struct clk_branch gcc_nss_port6_r
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port6_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port6_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port6_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3899,9 +3771,8 @@ static struct clk_branch gcc_nss_port6_t
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_nss_port6_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port6_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port6_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3916,9 +3787,8 @@ static struct clk_branch gcc_port1_mac_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_port1_mac_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3933,9 +3803,8 @@ static struct clk_branch gcc_port2_mac_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_port2_mac_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3950,9 +3819,8 @@ static struct clk_branch gcc_port3_mac_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_port3_mac_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3967,9 +3835,8 @@ static struct clk_branch gcc_port4_mac_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_port4_mac_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -3984,9 +3851,8 @@ static struct clk_branch gcc_port5_mac_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_port5_mac_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4001,9 +3867,8 @@ static struct clk_branch gcc_port6_mac_c
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_port6_mac_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_ppe_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_ppe_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4018,9 +3883,8 @@ static struct clk_branch gcc_uniphy0_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_port1_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port1_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port1_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4035,9 +3899,8 @@ static struct clk_branch gcc_uniphy0_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_port1_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port1_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port1_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4052,9 +3915,8 @@ static struct clk_branch gcc_uniphy0_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_port2_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port2_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port2_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4069,9 +3931,8 @@ static struct clk_branch gcc_uniphy0_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_port2_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port2_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port2_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4086,9 +3947,8 @@ static struct clk_branch gcc_uniphy0_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_port3_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port3_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port3_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4103,9 +3963,8 @@ static struct clk_branch gcc_uniphy0_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_port3_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port3_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port3_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4120,9 +3979,8 @@ static struct clk_branch gcc_uniphy0_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_port4_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port4_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port4_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4137,9 +3995,8 @@ static struct clk_branch gcc_uniphy0_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_port4_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port4_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port4_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4154,9 +4011,8 @@ static struct clk_branch gcc_uniphy0_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_port5_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port5_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port5_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4171,9 +4027,8 @@ static struct clk_branch gcc_uniphy0_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy0_port5_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port5_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port5_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4188,9 +4043,8 @@ static struct clk_branch gcc_uniphy1_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy1_port5_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port5_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port5_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4205,9 +4059,8 @@ static struct clk_branch gcc_uniphy1_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy1_port5_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port5_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port5_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4222,9 +4075,8 @@ static struct clk_branch gcc_uniphy2_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy2_port6_rx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port6_rx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port6_rx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4239,9 +4091,8 @@ static struct clk_branch gcc_uniphy2_por
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_uniphy2_port6_tx_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"nss_port6_tx_div_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&nss_port6_tx_div_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4257,9 +4108,8 @@ static struct clk_branch gcc_crypto_ahb_
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_crypto_ahb_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4275,9 +4125,8 @@ static struct clk_branch gcc_crypto_axi_
 | |
| - 		.enable_mask = BIT(1),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_crypto_axi_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"pcnoc_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&pcnoc_clk_src.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4293,9 +4142,8 @@ static struct clk_branch gcc_crypto_clk
 | |
| - 		.enable_mask = BIT(2),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_crypto_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"crypto_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&crypto_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4310,9 +4158,8 @@ static struct clk_branch gcc_gp1_clk = {
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_gp1_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"gp1_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gp1_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4327,9 +4174,8 @@ static struct clk_branch gcc_gp2_clk = {
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_gp2_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"gp2_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gp2_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4344,9 +4190,8 @@ static struct clk_branch gcc_gp3_clk = {
 | |
| - 		.enable_mask = BIT(0),
 | |
| - 		.hw.init = &(struct clk_init_data){
 | |
| - 			.name = "gcc_gp3_clk",
 | |
| --			.parent_names = (const char *[]){
 | |
| --				"gp3_clk_src"
 | |
| --			},
 | |
| -+			.parent_hws = (const struct clk_hw *[]){
 | |
| -+				&gp3_clk_src.clkr.hw },
 | |
| - 			.num_parents = 1,
 | |
| - 			.flags = CLK_SET_RATE_PARENT,
 | |
| - 			.ops = &clk_branch2_ops,
 | |
| -@@ -4368,7 +4213,7 @@ static struct clk_rcg2 pcie0_rchng_clk_s
 | |
| - 	.clkr.hw.init = &(struct clk_init_data){
 | |
| - 		.name = "pcie0_rchng_clk_src",
 | |
| - 		.parent_data = gcc_xo_gpll0,
 | |
| --		.num_parents = 2,
 | |
| -+		.num_parents = ARRAY_SIZE(gcc_xo_gpll0),
 | |
| - 		.ops = &clk_rcg2_ops,
 | |
| - 	},
 | |
| - };
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0050-v6.2-dt-bindings-clock-qcom-ipq8074-add-missing-networkin.patch b/target/linux/ipq807x/patches-5.15/0050-v6.2-dt-bindings-clock-qcom-ipq8074-add-missing-networkin.patch
 | |
| deleted file mode 100644
 | |
| index 75f16a1673..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0050-v6.2-dt-bindings-clock-qcom-ipq8074-add-missing-networkin.patch
 | |
| +++ /dev/null
 | |
| @@ -1,39 +0,0 @@
 | |
| -From e78a40eb24187a8b4f9b89e2181f674df39c2013 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Mon, 7 Nov 2022 14:29:00 +0100
 | |
| -Subject: [PATCH] dt-bindings: clock: qcom: ipq8074: add missing networking
 | |
| - resets
 | |
| -
 | |
| -Add bindings for the missing networking resets found in IPQ8074 GCC.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20221107132901.489240-2-robimarko@gmail.com
 | |
| ----
 | |
| - include/dt-bindings/clock/qcom,gcc-ipq8074.h | 14 ++++++++++++++
 | |
| - 1 file changed, 14 insertions(+)
 | |
| -
 | |
| ---- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
 | |
| -+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
 | |
| -@@ -367,6 +367,20 @@
 | |
| - #define GCC_PCIE1_AHB_ARES			129
 | |
| - #define GCC_PCIE1_AXI_MASTER_STICKY_ARES	130
 | |
| - #define GCC_PCIE0_AXI_SLAVE_STICKY_ARES		131
 | |
| -+#define GCC_PPE_FULL_RESET			132
 | |
| -+#define GCC_UNIPHY0_SOFT_RESET			133
 | |
| -+#define GCC_UNIPHY0_XPCS_RESET			134
 | |
| -+#define GCC_UNIPHY1_SOFT_RESET			135
 | |
| -+#define GCC_UNIPHY1_XPCS_RESET			136
 | |
| -+#define GCC_UNIPHY2_SOFT_RESET			137
 | |
| -+#define GCC_UNIPHY2_XPCS_RESET			138
 | |
| -+#define GCC_EDMA_HW_RESET			139
 | |
| -+#define GCC_NSSPORT1_RESET			140
 | |
| -+#define GCC_NSSPORT2_RESET			141
 | |
| -+#define GCC_NSSPORT3_RESET			142
 | |
| -+#define GCC_NSSPORT4_RESET			143
 | |
| -+#define GCC_NSSPORT5_RESET			144
 | |
| -+#define GCC_NSSPORT6_RESET			145
 | |
| - 
 | |
| - #define USB0_GDSC				0
 | |
| - #define USB1_GDSC				1
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0051-v6.2-clk-qcom-ipq8074-add-missing-networking-resets.patch b/target/linux/ipq807x/patches-5.15/0051-v6.2-clk-qcom-ipq8074-add-missing-networking-resets.patch
 | |
| deleted file mode 100644
 | |
| index 212fc84869..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0051-v6.2-clk-qcom-ipq8074-add-missing-networking-resets.patch
 | |
| +++ /dev/null
 | |
| @@ -1,41 +0,0 @@
 | |
| -From da76cb63d04dc22ed32123b8c1d084c006d67bfb Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Mon, 7 Nov 2022 14:29:01 +0100
 | |
| -Subject: [PATCH] clk: qcom: ipq8074: add missing networking resets
 | |
| -
 | |
| -Downstream QCA 5.4 kernel defines networking resets which are not present
 | |
| -in the mainline kernel but are required for the networking drivers.
 | |
| -
 | |
| -So, port the downstream resets and avoid using magic values for mask,
 | |
| -construct mask for resets which require multiple bits to be set/cleared.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20221107132901.489240-3-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/clk/qcom/gcc-ipq8074.c | 14 ++++++++++++++
 | |
| - 1 file changed, 14 insertions(+)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -+++ b/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -@@ -4671,6 +4671,20 @@ static const struct qcom_reset_map gcc_i
 | |
| - 	[GCC_PCIE1_AXI_SLAVE_ARES] = { 0x76040, 4 },
 | |
| - 	[GCC_PCIE1_AHB_ARES] = { 0x76040, 5 },
 | |
| - 	[GCC_PCIE1_AXI_MASTER_STICKY_ARES] = { 0x76040, 6 },
 | |
| -+	[GCC_PPE_FULL_RESET] = { .reg = 0x68014, .bitmask = GENMASK(19, 16) },
 | |
| -+	[GCC_UNIPHY0_SOFT_RESET] = { .reg = 0x56004, .bitmask = GENMASK(13, 4) | BIT(1) },
 | |
| -+	[GCC_UNIPHY0_XPCS_RESET] = { 0x56004, 2 },
 | |
| -+	[GCC_UNIPHY1_SOFT_RESET] = { .reg = 0x56104, .bitmask = GENMASK(5, 4) | BIT(1) },
 | |
| -+	[GCC_UNIPHY1_XPCS_RESET] = { 0x56104, 2 },
 | |
| -+	[GCC_UNIPHY2_SOFT_RESET] = { .reg = 0x56204, .bitmask = GENMASK(5, 4) | BIT(1) },
 | |
| -+	[GCC_UNIPHY2_XPCS_RESET] = { 0x56204, 2 },
 | |
| -+	[GCC_EDMA_HW_RESET] = { .reg = 0x68014, .bitmask = GENMASK(21, 20) },
 | |
| -+	[GCC_NSSPORT1_RESET] = { .reg = 0x68014, .bitmask = BIT(24) | GENMASK(1, 0) },
 | |
| -+	[GCC_NSSPORT2_RESET] = { .reg = 0x68014, .bitmask = BIT(25) | GENMASK(3, 2) },
 | |
| -+	[GCC_NSSPORT3_RESET] = { .reg = 0x68014, .bitmask = BIT(26) | GENMASK(5, 4) },
 | |
| -+	[GCC_NSSPORT4_RESET] = { .reg = 0x68014, .bitmask = BIT(27) | GENMASK(9, 8) },
 | |
| -+	[GCC_NSSPORT5_RESET] = { .reg = 0x68014, .bitmask = BIT(28) | GENMASK(11, 10) },
 | |
| -+	[GCC_NSSPORT6_RESET] = { .reg = 0x68014, .bitmask = BIT(29) | GENMASK(13, 12) },
 | |
| - };
 | |
| - 
 | |
| - static struct gdsc *gcc_ipq8074_gdscs[] = {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0052-v6.2-clk-qcom-ipq8074-populate-fw_name-for-all-parents.patch b/target/linux/ipq807x/patches-5.15/0052-v6.2-clk-qcom-ipq8074-populate-fw_name-for-all-parents.patch
 | |
| deleted file mode 100644
 | |
| index 7372b1da8e..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0052-v6.2-clk-qcom-ipq8074-populate-fw_name-for-all-parents.patch
 | |
| +++ /dev/null
 | |
| @@ -1,152 +0,0 @@
 | |
| -From 78936d46470938caa9a7ea529deeb36777b4f98e Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Wed, 16 Nov 2022 22:46:55 +0100
 | |
| -Subject: [PATCH] clk: qcom: ipq8074: populate fw_name for all parents
 | |
| -
 | |
| -It appears that having only .name populated in parent_data for clocks
 | |
| -which are only globally searchable currently will not work as the clk core
 | |
| -won't copy that name if there is no .fw_name present as well.
 | |
| -
 | |
| -So, populate .fw_name for all parent clocks in parent_data.
 | |
| -
 | |
| -Fixes: ae55ad32e273 ("clk: qcom: ipq8074: convert to parent data")
 | |
| -
 | |
| -Co-developed-by: Christian Marangi <ansuelsmth@gmail.com>
 | |
| -Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20221116214655.1116467-1-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/clk/qcom/gcc-ipq8074.c | 52 +++++++++++++++++-----------------
 | |
| - 1 file changed, 26 insertions(+), 26 deletions(-)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -+++ b/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -@@ -680,7 +680,7 @@ static struct clk_rcg2 pcie0_aux_clk_src
 | |
| - };
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_pcie20_phy0_pipe_clk_xo[] = {
 | |
| --	{ .name = "pcie20_phy0_pipe_clk" },
 | |
| -+	{ .fw_name = "pcie0_pipe", .name = "pcie20_phy0_pipe_clk" },
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| - };
 | |
| - 
 | |
| -@@ -733,7 +733,7 @@ static struct clk_rcg2 pcie1_aux_clk_src
 | |
| - };
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_pcie20_phy1_pipe_clk_xo[] = {
 | |
| --	{ .name = "pcie20_phy1_pipe_clk" },
 | |
| -+	{ .fw_name = "pcie1_pipe", .name = "pcie20_phy1_pipe_clk" },
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| - };
 | |
| - 
 | |
| -@@ -1137,7 +1137,7 @@ static const struct freq_tbl ftbl_nss_no
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_xo_bias_pll_nss_noc_clk_gpll0_gpll2[] = {
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| --	{ .name = "bias_pll_nss_noc_clk" },
 | |
| -+	{ .fw_name = "bias_pll_nss_noc_clk", .name = "bias_pll_nss_noc_clk" },
 | |
| - 	{ .hw = &gpll0.clkr.hw },
 | |
| - 	{ .hw = &gpll2.clkr.hw },
 | |
| - };
 | |
| -@@ -1362,7 +1362,7 @@ static const struct freq_tbl ftbl_nss_pp
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_xo_bias_gpll0_gpll4_nss_ubi32[] = {
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| --	{ .name = "bias_pll_cc_clk" },
 | |
| -+	{ .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" },
 | |
| - 	{ .hw = &gpll0.clkr.hw },
 | |
| - 	{ .hw = &gpll4.clkr.hw },
 | |
| - 	{ .hw = &nss_crypto_pll.clkr.hw },
 | |
| -@@ -1413,10 +1413,10 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_xo_uniphy0_rx_tx_ubi32_bias[] = {
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| --	{ .name = "uniphy0_gcc_rx_clk" },
 | |
| --	{ .name = "uniphy0_gcc_tx_clk" },
 | |
| -+	{ .fw_name = "uniphy0_gcc_rx_clk", .name = "uniphy0_gcc_rx_clk" },
 | |
| -+	{ .fw_name = "uniphy0_gcc_tx_clk", .name = "uniphy0_gcc_tx_clk" },
 | |
| - 	{ .hw = &ubi32_pll.clkr.hw },
 | |
| --	{ .name = "bias_pll_cc_clk" },
 | |
| -+	{ .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" },
 | |
| - };
 | |
| - 
 | |
| - static const struct parent_map gcc_xo_uniphy0_rx_tx_ubi32_bias_map[] = {
 | |
| -@@ -1465,10 +1465,10 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_xo_uniphy0_tx_rx_ubi32_bias[] = {
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| --	{ .name = "uniphy0_gcc_tx_clk" },
 | |
| --	{ .name = "uniphy0_gcc_rx_clk" },
 | |
| -+	{ .fw_name = "uniphy0_gcc_tx_clk", .name = "uniphy0_gcc_tx_clk" },
 | |
| -+	{ .fw_name = "uniphy0_gcc_rx_clk", .name = "uniphy0_gcc_rx_clk" },
 | |
| - 	{ .hw = &ubi32_pll.clkr.hw },
 | |
| --	{ .name = "bias_pll_cc_clk" },
 | |
| -+	{ .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" },
 | |
| - };
 | |
| - 
 | |
| - static const struct parent_map gcc_xo_uniphy0_tx_rx_ubi32_bias_map[] = {
 | |
| -@@ -1696,12 +1696,12 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias[] = {
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| --	{ .name = "uniphy0_gcc_rx_clk" },
 | |
| --	{ .name = "uniphy0_gcc_tx_clk" },
 | |
| --	{ .name = "uniphy1_gcc_rx_clk" },
 | |
| --	{ .name = "uniphy1_gcc_tx_clk" },
 | |
| -+	{ .fw_name = "uniphy0_gcc_rx_clk", .name = "uniphy0_gcc_rx_clk" },
 | |
| -+	{ .fw_name = "uniphy0_gcc_tx_clk", .name = "uniphy0_gcc_tx_clk" },
 | |
| -+	{ .fw_name = "uniphy1_gcc_rx_clk", .name = "uniphy1_gcc_rx_clk" },
 | |
| -+	{ .fw_name = "uniphy1_gcc_tx_clk", .name = "uniphy1_gcc_tx_clk" },
 | |
| - 	{ .hw = &ubi32_pll.clkr.hw },
 | |
| --	{ .name = "bias_pll_cc_clk" },
 | |
| -+	{ .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" },
 | |
| - };
 | |
| - 
 | |
| - static const struct parent_map
 | |
| -@@ -1758,12 +1758,12 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias[] = {
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| --	{ .name = "uniphy0_gcc_tx_clk" },
 | |
| --	{ .name = "uniphy0_gcc_rx_clk" },
 | |
| --	{ .name = "uniphy1_gcc_tx_clk" },
 | |
| --	{ .name = "uniphy1_gcc_rx_clk" },
 | |
| -+	{ .fw_name = "uniphy0_gcc_tx_clk", .name = "uniphy0_gcc_tx_clk" },
 | |
| -+	{ .fw_name = "uniphy0_gcc_rx_clk", .name = "uniphy0_gcc_rx_clk" },
 | |
| -+	{ .fw_name = "uniphy1_gcc_tx_clk", .name = "uniphy1_gcc_tx_clk" },
 | |
| -+	{ .fw_name = "uniphy1_gcc_rx_clk", .name = "uniphy1_gcc_rx_clk" },
 | |
| - 	{ .hw = &ubi32_pll.clkr.hw },
 | |
| --	{ .name = "bias_pll_cc_clk" },
 | |
| -+	{ .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" },
 | |
| - };
 | |
| - 
 | |
| - static const struct parent_map
 | |
| -@@ -1820,10 +1820,10 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_xo_uniphy2_rx_tx_ubi32_bias[] = {
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| --	{ .name = "uniphy2_gcc_rx_clk" },
 | |
| --	{ .name = "uniphy2_gcc_tx_clk" },
 | |
| -+	{ .fw_name = "uniphy2_gcc_rx_clk", .name = "uniphy2_gcc_rx_clk" },
 | |
| -+	{ .fw_name = "uniphy2_gcc_tx_clk", .name = "uniphy2_gcc_tx_clk" },
 | |
| - 	{ .hw = &ubi32_pll.clkr.hw },
 | |
| --	{ .name = "bias_pll_cc_clk" },
 | |
| -+	{ .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" },
 | |
| - };
 | |
| - 
 | |
| - static const struct parent_map gcc_xo_uniphy2_rx_tx_ubi32_bias_map[] = {
 | |
| -@@ -1877,10 +1877,10 @@ static const struct freq_tbl ftbl_nss_po
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_xo_uniphy2_tx_rx_ubi32_bias[] = {
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| --	{ .name = "uniphy2_gcc_tx_clk" },
 | |
| --	{ .name = "uniphy2_gcc_rx_clk" },
 | |
| -+	{ .fw_name = "uniphy2_gcc_tx_clk", .name = "uniphy2_gcc_tx_clk" },
 | |
| -+	{ .fw_name = "uniphy2_gcc_rx_clk", .name = "uniphy2_gcc_rx_clk" },
 | |
| - 	{ .hw = &ubi32_pll.clkr.hw },
 | |
| --	{ .name = "bias_pll_cc_clk" },
 | |
| -+	{ .fw_name = "bias_pll_cc_clk", .name = "bias_pll_cc_clk" },
 | |
| - };
 | |
| - 
 | |
| - static const struct parent_map gcc_xo_uniphy2_tx_rx_ubi32_bias_map[] = {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0053-v6.2-arm64-dts-qcom-ipq8074-pass-XO-and-sleep-clocks-to-G.patch b/target/linux/ipq807x/patches-5.15/0053-v6.2-arm64-dts-qcom-ipq8074-pass-XO-and-sleep-clocks-to-G.patch
 | |
| deleted file mode 100644
 | |
| index 1f99de002b..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0053-v6.2-arm64-dts-qcom-ipq8074-pass-XO-and-sleep-clocks-to-G.patch
 | |
| +++ /dev/null
 | |
| @@ -1,36 +0,0 @@
 | |
| -From 9033c3c86ea0dd35bd2ab957317573b755967298 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sun, 30 Oct 2022 18:57:03 +0100
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: pass XO and sleep clocks to GCC
 | |
| -
 | |
| -Pass XO and sleep clocks to the GCC controller so it does not have to
 | |
| -find them by matching globaly by name.
 | |
| -
 | |
| -If not passed directly, driver maintains backwards compatibility by then
 | |
| -falling back to global lookup.
 | |
| -
 | |
| -Since we are here, set cell numbers in decimal instead of hex.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20221030175703.1103224-3-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 6 ++++--
 | |
| - 1 file changed, 4 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -361,9 +361,11 @@
 | |
| - 		gcc: gcc@1800000 {
 | |
| - 			compatible = "qcom,gcc-ipq8074";
 | |
| - 			reg = <0x01800000 0x80000>;
 | |
| --			#clock-cells = <0x1>;
 | |
| -+			clocks = <&xo>, <&sleep_clk>;
 | |
| -+			clock-names = "xo", "sleep_clk";
 | |
| -+			#clock-cells = <1>;
 | |
| - 			#power-domain-cells = <1>;
 | |
| --			#reset-cells = <0x1>;
 | |
| -+			#reset-cells = <1>;
 | |
| - 		};
 | |
| - 
 | |
| - 		tcsr_mutex: hwlock@1905000 {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0054-v6.1-arm64-dts-qcom-replace-deprecated-perst-gpio-with-pe.patch b/target/linux/ipq807x/patches-5.15/0054-v6.1-arm64-dts-qcom-replace-deprecated-perst-gpio-with-pe.patch
 | |
| deleted file mode 100644
 | |
| index 35f4676a15..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0054-v6.1-arm64-dts-qcom-replace-deprecated-perst-gpio-with-pe.patch
 | |
| +++ /dev/null
 | |
| @@ -1,52 +0,0 @@
 | |
| -From 0afa47c1b57ba645225b38654869a6e5d2939da5 Mon Sep 17 00:00:00 2001
 | |
| -From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Date: Fri, 6 May 2022 18:21:07 +0300
 | |
| -Subject: [PATCH] arm64: dts: qcom: replace deprecated perst-gpio with
 | |
| - perst-gpios
 | |
| -
 | |
| -Replace deprecated perst-gpio and wake-gpio properties with up-to-date
 | |
| -perst-gpios and wake-gpios in the Qualcomm device trees.
 | |
| -
 | |
| -Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220506152107.1527552-9-dmitry.baryshkov@linaro.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk01.dts  | 4 ++--
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi | 4 ++--
 | |
| - 2 files changed, 4 insertions(+), 4 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -@@ -49,12 +49,12 @@
 | |
| - 
 | |
| - &pcie0 {
 | |
| - 	status = "okay";
 | |
| --	perst-gpio = <&tlmm 61 0x1>;
 | |
| -+	perst-gpios = <&tlmm 61 0x1>;
 | |
| - };
 | |
| - 
 | |
| - &pcie1 {
 | |
| - 	status = "okay";
 | |
| --	perst-gpio = <&tlmm 58 0x1>;
 | |
| -+	perst-gpios = <&tlmm 58 0x1>;
 | |
| - };
 | |
| - 
 | |
| - &pcie_qmp0 {
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk10.dtsi
 | |
| -@@ -39,12 +39,12 @@
 | |
| - 
 | |
| - &pcie0 {
 | |
| - 	status = "ok";
 | |
| --	perst-gpio = <&tlmm 58 0x1>;
 | |
| -+	perst-gpios = <&tlmm 58 0x1>;
 | |
| - };
 | |
| - 
 | |
| - &pcie1 {
 | |
| - 	status = "ok";
 | |
| --	perst-gpio = <&tlmm 61 0x1>;
 | |
| -+	perst-gpios = <&tlmm 61 0x1>;
 | |
| - };
 | |
| - 
 | |
| - &pcie_phy0 {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0055-v6.0-spmi-add-a-helper-to-look-up-an-SPMI-device-from-a-d.patch b/target/linux/ipq807x/patches-5.15/0055-v6.0-spmi-add-a-helper-to-look-up-an-SPMI-device-from-a-d.patch
 | |
| deleted file mode 100644
 | |
| index 61aeb0b029..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0055-v6.0-spmi-add-a-helper-to-look-up-an-SPMI-device-from-a-d.patch
 | |
| +++ /dev/null
 | |
| @@ -1,57 +0,0 @@
 | |
| -From 0eda4c5c7704363f665f4ccf0327349faad245a4 Mon Sep 17 00:00:00 2001
 | |
| -From: Caleb Connolly <caleb.connolly@linaro.org>
 | |
| -Date: Fri, 29 Apr 2022 23:08:56 +0100
 | |
| -Subject: [PATCH] spmi: add a helper to look up an SPMI device from a device
 | |
| - node
 | |
| -
 | |
| -The helper function spmi_device_from_of() takes a device node and
 | |
| -returns the SPMI device associated with it.
 | |
| -This is like of_find_device_by_node but for SPMI devices.
 | |
| -
 | |
| -Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
 | |
| -Acked-by: Stephen Boyd <sboyd@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220429220904.137297-2-caleb.connolly@linaro.org
 | |
| -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
 | |
| ----
 | |
| - drivers/spmi/spmi.c  | 17 +++++++++++++++++
 | |
| - include/linux/spmi.h |  3 +++
 | |
| - 2 files changed, 20 insertions(+)
 | |
| -
 | |
| ---- a/drivers/spmi/spmi.c
 | |
| -+++ b/drivers/spmi/spmi.c
 | |
| -@@ -388,6 +388,23 @@ static struct bus_type spmi_bus_type = {
 | |
| - };
 | |
| - 
 | |
| - /**
 | |
| -+ * spmi_device_from_of() - get the associated SPMI device from a device node
 | |
| -+ *
 | |
| -+ * @np:		device node
 | |
| -+ *
 | |
| -+ * Returns the struct spmi_device associated with a device node or NULL.
 | |
| -+ */
 | |
| -+struct spmi_device *spmi_device_from_of(struct device_node *np)
 | |
| -+{
 | |
| -+	struct device *dev = bus_find_device_by_of_node(&spmi_bus_type, np);
 | |
| -+
 | |
| -+	if (dev)
 | |
| -+		return to_spmi_device(dev);
 | |
| -+	return NULL;
 | |
| -+}
 | |
| -+EXPORT_SYMBOL_GPL(spmi_device_from_of);
 | |
| -+
 | |
| -+/**
 | |
| -  * spmi_controller_alloc() - Allocate a new SPMI device
 | |
| -  * @ctrl:	associated controller
 | |
| -  *
 | |
| ---- a/include/linux/spmi.h
 | |
| -+++ b/include/linux/spmi.h
 | |
| -@@ -164,6 +164,9 @@ static inline void spmi_driver_unregiste
 | |
| - 	module_driver(__spmi_driver, spmi_driver_register, \
 | |
| - 			spmi_driver_unregister)
 | |
| - 
 | |
| -+struct device_node;
 | |
| -+
 | |
| -+struct spmi_device *spmi_device_from_of(struct device_node *np);
 | |
| - int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf);
 | |
| - int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf,
 | |
| - 			   size_t len);
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0056-v5.16-mfd-qcom-spmi-pmic-Sort-compatibles-in-the-driver.patch b/target/linux/ipq807x/patches-5.15/0056-v5.16-mfd-qcom-spmi-pmic-Sort-compatibles-in-the-driver.patch
 | |
| deleted file mode 100644
 | |
| index 02a37aa376..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0056-v5.16-mfd-qcom-spmi-pmic-Sort-compatibles-in-the-driver.patch
 | |
| +++ /dev/null
 | |
| @@ -1,60 +0,0 @@
 | |
| -From 60df90d6829d16338e2971420220395cfc289247 Mon Sep 17 00:00:00 2001
 | |
| -From: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Date: Sun, 17 Oct 2021 09:12:16 -0700
 | |
| -Subject: [PATCH] mfd: qcom-spmi-pmic: Sort compatibles in the driver
 | |
| -
 | |
| -Sort the compatibles in the driver, to make it easier to validate that
 | |
| -the DT binding and driver are in sync.
 | |
| -
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Signed-off-by: Lee Jones <lee.jones@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20211017161218.2378176-2-bjorn.andersson@linaro.org
 | |
| ----
 | |
| - drivers/mfd/qcom-spmi-pmic.c | 30 +++++++++++++++---------------
 | |
| - 1 file changed, 15 insertions(+), 15 deletions(-)
 | |
| -
 | |
| ---- a/drivers/mfd/qcom-spmi-pmic.c
 | |
| -+++ b/drivers/mfd/qcom-spmi-pmic.c
 | |
| -@@ -40,27 +40,27 @@
 | |
| - #define PM660_SUBTYPE		0x1B
 | |
| - 
 | |
| - static const struct of_device_id pmic_spmi_id_table[] = {
 | |
| --	{ .compatible = "qcom,spmi-pmic", .data = (void *)COMMON_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8941",    .data = (void *)PM8941_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8841",    .data = (void *)PM8841_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm660",     .data = (void *)PM660_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm660l",    .data = (void *)PM660L_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8004",    .data = (void *)PM8004_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8005",    .data = (void *)PM8005_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8019",    .data = (void *)PM8019_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8226",    .data = (void *)PM8226_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8110",    .data = (void *)PM8110_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pma8084",   .data = (void *)PMA8084_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pmi8962",   .data = (void *)PMI8962_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pmd9635",   .data = (void *)PMD9635_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8994",    .data = (void *)PM8994_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pmi8994",   .data = (void *)PMI8994_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8916",    .data = (void *)PM8916_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8004",    .data = (void *)PM8004_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8226",    .data = (void *)PM8226_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8841",    .data = (void *)PM8841_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8909",    .data = (void *)PM8909_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8916",    .data = (void *)PM8916_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8941",    .data = (void *)PM8941_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8950",    .data = (void *)PM8950_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pmi8950",   .data = (void *)PMI8950_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8994",    .data = (void *)PM8994_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8998",    .data = (void *)PM8998_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pma8084",   .data = (void *)PMA8084_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pmd9635",   .data = (void *)PMD9635_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pmi8950",   .data = (void *)PMI8950_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pmi8962",   .data = (void *)PMI8962_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pmi8994",   .data = (void *)PMI8994_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pmi8998",   .data = (void *)PMI8998_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8005",    .data = (void *)PM8005_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm660l",    .data = (void *)PM660L_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm660",     .data = (void *)PM660_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,spmi-pmic", .data = (void *)COMMON_SUBTYPE },
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0057-v5.16-mfd-qcom-spmi-pmic-Add-missing-PMICs-supported-by-so.patch b/target/linux/ipq807x/patches-5.15/0057-v5.16-mfd-qcom-spmi-pmic-Add-missing-PMICs-supported-by-so.patch
 | |
| deleted file mode 100644
 | |
| index c2b3e8304d..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0057-v5.16-mfd-qcom-spmi-pmic-Add-missing-PMICs-supported-by-so.patch
 | |
| +++ /dev/null
 | |
| @@ -1,65 +0,0 @@
 | |
| -From 18921bfd81c88fb85a19683467f680897672f062 Mon Sep 17 00:00:00 2001
 | |
| -From: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Date: Sun, 17 Oct 2021 09:12:18 -0700
 | |
| -Subject: [PATCH] mfd: qcom-spmi-pmic: Add missing PMICs supported by socinfo
 | |
| -
 | |
| -The Qualcomm socinfo driver has eight more PMICs described, add these to
 | |
| -the SPMI PMIC driver as well.
 | |
| -
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Signed-off-by: Lee Jones <lee.jones@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20211017161218.2378176-4-bjorn.andersson@linaro.org
 | |
| ----
 | |
| - drivers/mfd/qcom-spmi-pmic.c | 17 +++++++++++++++++
 | |
| - 1 file changed, 17 insertions(+)
 | |
| -
 | |
| ---- a/drivers/mfd/qcom-spmi-pmic.c
 | |
| -+++ b/drivers/mfd/qcom-spmi-pmic.c
 | |
| -@@ -31,6 +31,8 @@
 | |
| - #define PM8916_SUBTYPE		0x0b
 | |
| - #define PM8004_SUBTYPE		0x0c
 | |
| - #define PM8909_SUBTYPE		0x0d
 | |
| -+#define PM8028_SUBTYPE		0x0e
 | |
| -+#define PM8901_SUBTYPE		0x0f
 | |
| - #define PM8950_SUBTYPE		0x10
 | |
| - #define PMI8950_SUBTYPE		0x11
 | |
| - #define PM8998_SUBTYPE		0x14
 | |
| -@@ -38,6 +40,13 @@
 | |
| - #define PM8005_SUBTYPE		0x18
 | |
| - #define PM660L_SUBTYPE		0x1A
 | |
| - #define PM660_SUBTYPE		0x1B
 | |
| -+#define PM8150_SUBTYPE		0x1E
 | |
| -+#define PM8150L_SUBTYPE		0x1f
 | |
| -+#define PM8150B_SUBTYPE		0x20
 | |
| -+#define PMK8002_SUBTYPE		0x21
 | |
| -+#define PM8009_SUBTYPE		0x24
 | |
| -+#define PM8150C_SUBTYPE		0x26
 | |
| -+#define SMB2351_SUBTYPE		0x29
 | |
| - 
 | |
| - static const struct of_device_id pmic_spmi_id_table[] = {
 | |
| - 	{ .compatible = "qcom,pm660",     .data = (void *)PM660_SUBTYPE },
 | |
| -@@ -45,9 +54,15 @@ static const struct of_device_id pmic_sp
 | |
| - 	{ .compatible = "qcom,pm8004",    .data = (void *)PM8004_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8005",    .data = (void *)PM8005_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8019",    .data = (void *)PM8019_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8028",    .data = (void *)PM8028_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8110",    .data = (void *)PM8110_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8150",    .data = (void *)PM8150_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8150b",   .data = (void *)PM8150B_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8150c",   .data = (void *)PM8150C_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8150l",   .data = (void *)PM8150L_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8226",    .data = (void *)PM8226_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8841",    .data = (void *)PM8841_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm8901",    .data = (void *)PM8901_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8909",    .data = (void *)PM8909_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8916",    .data = (void *)PM8916_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pm8941",    .data = (void *)PM8941_SUBTYPE },
 | |
| -@@ -60,6 +75,8 @@ static const struct of_device_id pmic_sp
 | |
| - 	{ .compatible = "qcom,pmi8962",   .data = (void *)PMI8962_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pmi8994",   .data = (void *)PMI8994_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,pmi8998",   .data = (void *)PMI8998_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pmk8002",   .data = (void *)PMK8002_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,smb2351",   .data = (void *)SMB2351_SUBTYPE },
 | |
| - 	{ .compatible = "qcom,spmi-pmic", .data = (void *)COMMON_SUBTYPE },
 | |
| - 	{ }
 | |
| - };
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0058-v6.0-mfd-qcom-spmi-pmic-expose-the-PMIC-revid-information.patch b/target/linux/ipq807x/patches-5.15/0058-v6.0-mfd-qcom-spmi-pmic-expose-the-PMIC-revid-information.patch
 | |
| deleted file mode 100644
 | |
| index 35e0cc6725..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0058-v6.0-mfd-qcom-spmi-pmic-expose-the-PMIC-revid-information.patch
 | |
| +++ /dev/null
 | |
| @@ -1,417 +0,0 @@
 | |
| -From 231f6a9f24a5e9b6e7af801ca2377970474cdf59 Mon Sep 17 00:00:00 2001
 | |
| -From: Caleb Connolly <caleb.connolly@linaro.org>
 | |
| -Date: Fri, 29 Apr 2022 23:08:57 +0100
 | |
| -Subject: [PATCH] mfd: qcom-spmi-pmic: expose the PMIC revid information to
 | |
| - clients
 | |
| -
 | |
| -Some PMIC functions such as the RRADC need to be aware of the PMIC
 | |
| -chip revision information to implement errata or otherwise adjust
 | |
| -behaviour, export the PMIC information to enable this.
 | |
| -
 | |
| -This is specifically required to enable the RRADC to adjust
 | |
| -coefficients based on which chip fab the PMIC was produced in,
 | |
| -this can vary per unique device and therefore has to be read at
 | |
| -runtime.
 | |
| -
 | |
| -Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
 | |
| -Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Tested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Acked-by: Lee Jones <lee.jones@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220429220904.137297-3-caleb.connolly@linaro.org
 | |
| -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
 | |
| ----
 | |
| - drivers/mfd/qcom-spmi-pmic.c      | 265 ++++++++++++++++++++----------
 | |
| - include/soc/qcom/qcom-spmi-pmic.h |  60 +++++++
 | |
| - 2 files changed, 235 insertions(+), 90 deletions(-)
 | |
| - create mode 100644 include/soc/qcom/qcom-spmi-pmic.h
 | |
| -
 | |
| ---- a/drivers/mfd/qcom-spmi-pmic.c
 | |
| -+++ b/drivers/mfd/qcom-spmi-pmic.c
 | |
| -@@ -3,11 +3,16 @@
 | |
| -  * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 | |
| -  */
 | |
| - 
 | |
| -+#include <linux/device.h>
 | |
| -+#include <linux/errno.h>
 | |
| -+#include <linux/gfp.h>
 | |
| - #include <linux/kernel.h>
 | |
| - #include <linux/module.h>
 | |
| - #include <linux/spmi.h>
 | |
| -+#include <linux/types.h>
 | |
| - #include <linux/regmap.h>
 | |
| - #include <linux/of_platform.h>
 | |
| -+#include <soc/qcom/qcom-spmi-pmic.h>
 | |
| - 
 | |
| - #define PMIC_REV2		0x101
 | |
| - #define PMIC_REV3		0x102
 | |
| -@@ -17,106 +22,140 @@
 | |
| - 
 | |
| - #define PMIC_TYPE_VALUE		0x51
 | |
| - 
 | |
| --#define COMMON_SUBTYPE		0x00
 | |
| --#define PM8941_SUBTYPE		0x01
 | |
| --#define PM8841_SUBTYPE		0x02
 | |
| --#define PM8019_SUBTYPE		0x03
 | |
| --#define PM8226_SUBTYPE		0x04
 | |
| --#define PM8110_SUBTYPE		0x05
 | |
| --#define PMA8084_SUBTYPE		0x06
 | |
| --#define PMI8962_SUBTYPE		0x07
 | |
| --#define PMD9635_SUBTYPE		0x08
 | |
| --#define PM8994_SUBTYPE		0x09
 | |
| --#define PMI8994_SUBTYPE		0x0a
 | |
| --#define PM8916_SUBTYPE		0x0b
 | |
| --#define PM8004_SUBTYPE		0x0c
 | |
| --#define PM8909_SUBTYPE		0x0d
 | |
| --#define PM8028_SUBTYPE		0x0e
 | |
| --#define PM8901_SUBTYPE		0x0f
 | |
| --#define PM8950_SUBTYPE		0x10
 | |
| --#define PMI8950_SUBTYPE		0x11
 | |
| --#define PM8998_SUBTYPE		0x14
 | |
| --#define PMI8998_SUBTYPE		0x15
 | |
| --#define PM8005_SUBTYPE		0x18
 | |
| --#define PM660L_SUBTYPE		0x1A
 | |
| --#define PM660_SUBTYPE		0x1B
 | |
| --#define PM8150_SUBTYPE		0x1E
 | |
| --#define PM8150L_SUBTYPE		0x1f
 | |
| --#define PM8150B_SUBTYPE		0x20
 | |
| --#define PMK8002_SUBTYPE		0x21
 | |
| --#define PM8009_SUBTYPE		0x24
 | |
| --#define PM8150C_SUBTYPE		0x26
 | |
| --#define SMB2351_SUBTYPE		0x29
 | |
| -+#define PMIC_REV4_V2		0x02
 | |
| -+
 | |
| -+struct qcom_spmi_dev {
 | |
| -+	int num_usids;
 | |
| -+	struct qcom_spmi_pmic pmic;
 | |
| -+};
 | |
| -+
 | |
| -+#define N_USIDS(n)		((void *)n)
 | |
| - 
 | |
| - static const struct of_device_id pmic_spmi_id_table[] = {
 | |
| --	{ .compatible = "qcom,pm660",     .data = (void *)PM660_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm660l",    .data = (void *)PM660L_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8004",    .data = (void *)PM8004_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8005",    .data = (void *)PM8005_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8019",    .data = (void *)PM8019_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8028",    .data = (void *)PM8028_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8110",    .data = (void *)PM8110_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8150",    .data = (void *)PM8150_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8150b",   .data = (void *)PM8150B_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8150c",   .data = (void *)PM8150C_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8150l",   .data = (void *)PM8150L_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8226",    .data = (void *)PM8226_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8841",    .data = (void *)PM8841_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8901",    .data = (void *)PM8901_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8909",    .data = (void *)PM8909_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8916",    .data = (void *)PM8916_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8941",    .data = (void *)PM8941_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8950",    .data = (void *)PM8950_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8994",    .data = (void *)PM8994_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pm8998",    .data = (void *)PM8998_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pma8084",   .data = (void *)PMA8084_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pmd9635",   .data = (void *)PMD9635_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pmi8950",   .data = (void *)PMI8950_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pmi8962",   .data = (void *)PMI8962_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pmi8994",   .data = (void *)PMI8994_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pmi8998",   .data = (void *)PMI8998_SUBTYPE },
 | |
| --	{ .compatible = "qcom,pmk8002",   .data = (void *)PMK8002_SUBTYPE },
 | |
| --	{ .compatible = "qcom,smb2351",   .data = (void *)SMB2351_SUBTYPE },
 | |
| --	{ .compatible = "qcom,spmi-pmic", .data = (void *)COMMON_SUBTYPE },
 | |
| -+	{ .compatible = "qcom,pm660", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm660l", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8004", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8005", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8019", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8028", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8110", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8150", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8150b", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8150c", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8150l", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8226", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8841", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8901", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8909", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8916", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8941", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8950", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8994", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pm8998", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pma8084", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pmd9635", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pmi8950", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pmi8962", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pmi8994", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pmi8998", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pmk8002", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,smb2351", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,spmi-pmic", .data = N_USIDS(1) },
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| --static void pmic_spmi_show_revid(struct regmap *map, struct device *dev)
 | |
| -+/*
 | |
| -+ * A PMIC can be represented by multiple SPMI devices, but
 | |
| -+ * only the base PMIC device will contain a reference to
 | |
| -+ * the revision information.
 | |
| -+ *
 | |
| -+ * This function takes a pointer to a pmic device and
 | |
| -+ * returns a pointer to the base PMIC device.
 | |
| -+ *
 | |
| -+ * This only supports PMICs with 1 or 2 USIDs.
 | |
| -+ */
 | |
| -+static struct spmi_device *qcom_pmic_get_base_usid(struct device *dev)
 | |
| - {
 | |
| --	unsigned int rev2, minor, major, type, subtype;
 | |
| --	const char *name = "unknown";
 | |
| --	int ret, i;
 | |
| -+	struct spmi_device *sdev;
 | |
| -+	struct qcom_spmi_dev *ctx;
 | |
| -+	struct device_node *spmi_bus;
 | |
| -+	struct device_node *other_usid = NULL;
 | |
| -+	int function_parent_usid, ret;
 | |
| -+	u32 pmic_addr;
 | |
| - 
 | |
| --	ret = regmap_read(map, PMIC_TYPE, &type);
 | |
| --	if (ret < 0)
 | |
| --		return;
 | |
| -+	sdev = to_spmi_device(dev);
 | |
| -+	ctx = dev_get_drvdata(&sdev->dev);
 | |
| - 
 | |
| --	if (type != PMIC_TYPE_VALUE)
 | |
| --		return;
 | |
| -+	/*
 | |
| -+	 * Quick return if the function device is already in the base
 | |
| -+	 * USID. This will always be hit for PMICs with only 1 USID.
 | |
| -+	 */
 | |
| -+	if (sdev->usid % ctx->num_usids == 0)
 | |
| -+		return sdev;
 | |
| - 
 | |
| --	ret = regmap_read(map, PMIC_SUBTYPE, &subtype);
 | |
| -+	function_parent_usid = sdev->usid;
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Walk through the list of PMICs until we find the sibling USID.
 | |
| -+	 * The goal is to find the first USID which is less than the
 | |
| -+	 * number of USIDs in the PMIC array, e.g. for a PMIC with 2 USIDs
 | |
| -+	 * where the function device is under USID 3, we want to find the
 | |
| -+	 * device for USID 2.
 | |
| -+	 */
 | |
| -+	spmi_bus = of_get_parent(sdev->dev.of_node);
 | |
| -+	do {
 | |
| -+		other_usid = of_get_next_child(spmi_bus, other_usid);
 | |
| -+
 | |
| -+		ret = of_property_read_u32_index(other_usid, "reg", 0, &pmic_addr);
 | |
| -+		if (ret)
 | |
| -+			return ERR_PTR(ret);
 | |
| -+
 | |
| -+		sdev = spmi_device_from_of(other_usid);
 | |
| -+		if (pmic_addr == function_parent_usid - (ctx->num_usids - 1)) {
 | |
| -+			if (!sdev)
 | |
| -+				/*
 | |
| -+				 * If the base USID for this PMIC hasn't probed yet
 | |
| -+				 * but the secondary USID has, then we need to defer
 | |
| -+				 * the function driver so that it will attempt to
 | |
| -+				 * probe again when the base USID is ready.
 | |
| -+				 */
 | |
| -+				return ERR_PTR(-EPROBE_DEFER);
 | |
| -+			return sdev;
 | |
| -+		}
 | |
| -+	} while (other_usid->sibling);
 | |
| -+
 | |
| -+	return ERR_PTR(-ENODATA);
 | |
| -+}
 | |
| -+
 | |
| -+static int pmic_spmi_load_revid(struct regmap *map, struct device *dev,
 | |
| -+				 struct qcom_spmi_pmic *pmic)
 | |
| -+{
 | |
| -+	int ret;
 | |
| -+
 | |
| -+	ret = regmap_read(map, PMIC_TYPE, &pmic->type);
 | |
| - 	if (ret < 0)
 | |
| --		return;
 | |
| -+		return ret;
 | |
| - 
 | |
| --	for (i = 0; i < ARRAY_SIZE(pmic_spmi_id_table); i++) {
 | |
| --		if (subtype == (unsigned long)pmic_spmi_id_table[i].data)
 | |
| --			break;
 | |
| --	}
 | |
| -+	if (pmic->type != PMIC_TYPE_VALUE)
 | |
| -+		return ret;
 | |
| - 
 | |
| --	if (i != ARRAY_SIZE(pmic_spmi_id_table))
 | |
| --		name = pmic_spmi_id_table[i].compatible;
 | |
| -+	ret = regmap_read(map, PMIC_SUBTYPE, &pmic->subtype);
 | |
| -+	if (ret < 0)
 | |
| -+		return ret;
 | |
| - 
 | |
| --	ret = regmap_read(map, PMIC_REV2, &rev2);
 | |
| -+	pmic->name = of_match_device(pmic_spmi_id_table, dev)->compatible;
 | |
| -+
 | |
| -+	ret = regmap_read(map, PMIC_REV2, &pmic->rev2);
 | |
| - 	if (ret < 0)
 | |
| --		return;
 | |
| -+		return ret;
 | |
| - 
 | |
| --	ret = regmap_read(map, PMIC_REV3, &minor);
 | |
| -+	ret = regmap_read(map, PMIC_REV3, &pmic->minor);
 | |
| - 	if (ret < 0)
 | |
| --		return;
 | |
| -+		return ret;
 | |
| - 
 | |
| --	ret = regmap_read(map, PMIC_REV4, &major);
 | |
| -+	ret = regmap_read(map, PMIC_REV4, &pmic->major);
 | |
| - 	if (ret < 0)
 | |
| --		return;
 | |
| -+		return ret;
 | |
| - 
 | |
| - 	/*
 | |
| - 	 * In early versions of PM8941 and PM8226, the major revision number
 | |
| -@@ -124,15 +163,49 @@ static void pmic_spmi_show_revid(struct
 | |
| - 	 * Increment the major revision number here if the chip is an early
 | |
| - 	 * version of PM8941 or PM8226.
 | |
| - 	 */
 | |
| --	if ((subtype == PM8941_SUBTYPE || subtype == PM8226_SUBTYPE) &&
 | |
| --	    major < 0x02)
 | |
| --		major++;
 | |
| -+	if ((pmic->subtype == PM8941_SUBTYPE || pmic->subtype == PM8226_SUBTYPE) &&
 | |
| -+	    pmic->major < PMIC_REV4_V2)
 | |
| -+		pmic->major++;
 | |
| -+
 | |
| -+	if (pmic->subtype == PM8110_SUBTYPE)
 | |
| -+		pmic->minor = pmic->rev2;
 | |
| -+
 | |
| -+	dev_dbg(dev, "%x: %s v%d.%d\n",
 | |
| -+		pmic->subtype, pmic->name, pmic->major, pmic->minor);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * qcom_pmic_get() - Get a pointer to the base PMIC device
 | |
| -+ *
 | |
| -+ * This function takes a struct device for a driver which is a child of a PMIC.
 | |
| -+ * And locates the PMIC revision information for it.
 | |
| -+ *
 | |
| -+ * @dev: the pmic function device
 | |
| -+ * @return: the struct qcom_spmi_pmic* pointer associated with the function device
 | |
| -+ */
 | |
| -+const struct qcom_spmi_pmic *qcom_pmic_get(struct device *dev)
 | |
| -+{
 | |
| -+	struct spmi_device *sdev;
 | |
| -+	struct qcom_spmi_dev *spmi;
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Make sure the device is actually a child of a PMIC
 | |
| -+	 */
 | |
| -+	if (!of_match_device(pmic_spmi_id_table, dev->parent))
 | |
| -+		return ERR_PTR(-EINVAL);
 | |
| -+
 | |
| -+	sdev = qcom_pmic_get_base_usid(dev->parent);
 | |
| - 
 | |
| --	if (subtype == PM8110_SUBTYPE)
 | |
| --		minor = rev2;
 | |
| -+	if (IS_ERR(sdev))
 | |
| -+		return ERR_CAST(sdev);
 | |
| - 
 | |
| --	dev_dbg(dev, "%x: %s v%d.%d\n", subtype, name, major, minor);
 | |
| -+	spmi = dev_get_drvdata(&sdev->dev);
 | |
| -+
 | |
| -+	return &spmi->pmic;
 | |
| - }
 | |
| -+EXPORT_SYMBOL(qcom_pmic_get);
 | |
| - 
 | |
| - static const struct regmap_config spmi_regmap_config = {
 | |
| - 	.reg_bits	= 16,
 | |
| -@@ -144,14 +217,26 @@ static const struct regmap_config spmi_r
 | |
| - static int pmic_spmi_probe(struct spmi_device *sdev)
 | |
| - {
 | |
| - 	struct regmap *regmap;
 | |
| -+	struct qcom_spmi_dev *ctx;
 | |
| -+	int ret;
 | |
| - 
 | |
| - 	regmap = devm_regmap_init_spmi_ext(sdev, &spmi_regmap_config);
 | |
| - 	if (IS_ERR(regmap))
 | |
| - 		return PTR_ERR(regmap);
 | |
| - 
 | |
| -+	ctx = devm_kzalloc(&sdev->dev, sizeof(*ctx), GFP_KERNEL);
 | |
| -+	if (!ctx)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	ctx->num_usids = (uintptr_t)of_device_get_match_data(&sdev->dev);
 | |
| -+
 | |
| - 	/* Only the first slave id for a PMIC contains this information */
 | |
| --	if (sdev->usid % 2 == 0)
 | |
| --		pmic_spmi_show_revid(regmap, &sdev->dev);
 | |
| -+	if (sdev->usid % ctx->num_usids == 0) {
 | |
| -+		ret = pmic_spmi_load_revid(regmap, &sdev->dev, &ctx->pmic);
 | |
| -+		if (ret < 0)
 | |
| -+			return ret;
 | |
| -+	}
 | |
| -+	spmi_device_set_drvdata(sdev, ctx);
 | |
| - 
 | |
| - 	return devm_of_platform_populate(&sdev->dev);
 | |
| - }
 | |
| ---- /dev/null
 | |
| -+++ b/include/soc/qcom/qcom-spmi-pmic.h
 | |
| -@@ -0,0 +1,60 @@
 | |
| -+/* SPDX-License-Identifier: GPL-2.0-only */
 | |
| -+/* Copyright (c) 2022 Linaro. All rights reserved.
 | |
| -+ * Author: Caleb Connolly <caleb.connolly@linaro.org>
 | |
| -+ */
 | |
| -+
 | |
| -+#ifndef __QCOM_SPMI_PMIC_H__
 | |
| -+#define __QCOM_SPMI_PMIC_H__
 | |
| -+
 | |
| -+#include <linux/device.h>
 | |
| -+
 | |
| -+#define COMMON_SUBTYPE		0x00
 | |
| -+#define PM8941_SUBTYPE		0x01
 | |
| -+#define PM8841_SUBTYPE		0x02
 | |
| -+#define PM8019_SUBTYPE		0x03
 | |
| -+#define PM8226_SUBTYPE		0x04
 | |
| -+#define PM8110_SUBTYPE		0x05
 | |
| -+#define PMA8084_SUBTYPE		0x06
 | |
| -+#define PMI8962_SUBTYPE		0x07
 | |
| -+#define PMD9635_SUBTYPE		0x08
 | |
| -+#define PM8994_SUBTYPE		0x09
 | |
| -+#define PMI8994_SUBTYPE		0x0a
 | |
| -+#define PM8916_SUBTYPE		0x0b
 | |
| -+#define PM8004_SUBTYPE		0x0c
 | |
| -+#define PM8909_SUBTYPE		0x0d
 | |
| -+#define PM8028_SUBTYPE		0x0e
 | |
| -+#define PM8901_SUBTYPE		0x0f
 | |
| -+#define PM8950_SUBTYPE		0x10
 | |
| -+#define PMI8950_SUBTYPE		0x11
 | |
| -+#define PM8998_SUBTYPE		0x14
 | |
| -+#define PMI8998_SUBTYPE		0x15
 | |
| -+#define PM8005_SUBTYPE		0x18
 | |
| -+#define PM660L_SUBTYPE		0x1A
 | |
| -+#define PM660_SUBTYPE		0x1B
 | |
| -+#define PM8150_SUBTYPE		0x1E
 | |
| -+#define PM8150L_SUBTYPE		0x1f
 | |
| -+#define PM8150B_SUBTYPE		0x20
 | |
| -+#define PMK8002_SUBTYPE		0x21
 | |
| -+#define PM8009_SUBTYPE		0x24
 | |
| -+#define PM8150C_SUBTYPE		0x26
 | |
| -+#define SMB2351_SUBTYPE		0x29
 | |
| -+
 | |
| -+#define PMI8998_FAB_ID_SMIC	0x11
 | |
| -+#define PMI8998_FAB_ID_GF	0x30
 | |
| -+
 | |
| -+#define PM660_FAB_ID_GF		0x0
 | |
| -+#define PM660_FAB_ID_TSMC	0x2
 | |
| -+#define PM660_FAB_ID_MX		0x3
 | |
| -+
 | |
| -+struct qcom_spmi_pmic {
 | |
| -+	unsigned int type;
 | |
| -+	unsigned int subtype;
 | |
| -+	unsigned int major;
 | |
| -+	unsigned int minor;
 | |
| -+	unsigned int rev2;
 | |
| -+	const char *name;
 | |
| -+};
 | |
| -+
 | |
| -+const struct qcom_spmi_pmic *qcom_pmic_get(struct device *dev);
 | |
| -+
 | |
| -+#endif /* __QCOM_SPMI_PMIC_H__ */
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0059-v6.0-mfd-qcom-spmi-pmic-read-fab-id-on-supported-PMICs.patch b/target/linux/ipq807x/patches-5.15/0059-v6.0-mfd-qcom-spmi-pmic-read-fab-id-on-supported-PMICs.patch
 | |
| deleted file mode 100644
 | |
| index ecf8772bfd..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0059-v6.0-mfd-qcom-spmi-pmic-read-fab-id-on-supported-PMICs.patch
 | |
| +++ /dev/null
 | |
| @@ -1,52 +0,0 @@
 | |
| -From 0c309f4e86c827cd5fd2eb0e36d5d1f19927380d Mon Sep 17 00:00:00 2001
 | |
| -From: Caleb Connolly <caleb.connolly@linaro.org>
 | |
| -Date: Fri, 29 Apr 2022 23:08:58 +0100
 | |
| -Subject: [PATCH] mfd: qcom-spmi-pmic: read fab id on supported PMICs
 | |
| -
 | |
| -The PMI8998 and PM660 expose the fab_id, this is needed by drivers like
 | |
| -the RRADC to calibrate ADC values.
 | |
| -
 | |
| -Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
 | |
| -Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Tested-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Acked-by: Lee Jones <lee.jones@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220429220904.137297-4-caleb.connolly@linaro.org
 | |
| -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
 | |
| ----
 | |
| - drivers/mfd/qcom-spmi-pmic.c      | 7 +++++++
 | |
| - include/soc/qcom/qcom-spmi-pmic.h | 1 +
 | |
| - 2 files changed, 8 insertions(+)
 | |
| -
 | |
| ---- a/drivers/mfd/qcom-spmi-pmic.c
 | |
| -+++ b/drivers/mfd/qcom-spmi-pmic.c
 | |
| -@@ -19,6 +19,7 @@
 | |
| - #define PMIC_REV4		0x103
 | |
| - #define PMIC_TYPE		0x104
 | |
| - #define PMIC_SUBTYPE		0x105
 | |
| -+#define PMIC_FAB_ID		0x1f2
 | |
| - 
 | |
| - #define PMIC_TYPE_VALUE		0x51
 | |
| - 
 | |
| -@@ -157,6 +158,12 @@ static int pmic_spmi_load_revid(struct r
 | |
| - 	if (ret < 0)
 | |
| - 		return ret;
 | |
| - 
 | |
| -+	if (pmic->subtype == PMI8998_SUBTYPE || pmic->subtype == PM660_SUBTYPE) {
 | |
| -+		ret = regmap_read(map, PMIC_FAB_ID, &pmic->fab_id);
 | |
| -+		if (ret < 0)
 | |
| -+			return ret;
 | |
| -+	}
 | |
| -+
 | |
| - 	/*
 | |
| - 	 * In early versions of PM8941 and PM8226, the major revision number
 | |
| - 	 * started incrementing from 0 (eg 0 = v1.0, 1 = v2.0).
 | |
| ---- a/include/soc/qcom/qcom-spmi-pmic.h
 | |
| -+++ b/include/soc/qcom/qcom-spmi-pmic.h
 | |
| -@@ -52,6 +52,7 @@ struct qcom_spmi_pmic {
 | |
| - 	unsigned int major;
 | |
| - 	unsigned int minor;
 | |
| - 	unsigned int rev2;
 | |
| -+	unsigned int fab_id;
 | |
| - 	const char *name;
 | |
| - };
 | |
| - 
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0060-v6.1-mfd-qcom-spmi-pmic-Add-support-for-PMP8074.patch b/target/linux/ipq807x/patches-5.15/0060-v6.1-mfd-qcom-spmi-pmic-Add-support-for-PMP8074.patch
 | |
| deleted file mode 100644
 | |
| index 109a08aea3..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0060-v6.1-mfd-qcom-spmi-pmic-Add-support-for-PMP8074.patch
 | |
| +++ /dev/null
 | |
| @@ -1,27 +0,0 @@
 | |
| -From 46878413ba10170aaa9b7c797816e928a11923e3 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:18:12 +0200
 | |
| -Subject: [PATCH] mfd: qcom-spmi-pmic: Add support for PMP8074
 | |
| -
 | |
| -Add support for PMP8074 PMIC which is a companion PMIC for the Qualcomm
 | |
| -IPQ8074 SoC-s.
 | |
| -
 | |
| -It shares the same subtype identifier as PM8901.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Lee Jones <lee@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818221815.346233-2-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/mfd/qcom-spmi-pmic.c | 1 +
 | |
| - 1 file changed, 1 insertion(+)
 | |
| -
 | |
| ---- a/drivers/mfd/qcom-spmi-pmic.c
 | |
| -+++ b/drivers/mfd/qcom-spmi-pmic.c
 | |
| -@@ -60,6 +60,7 @@ static const struct of_device_id pmic_sp
 | |
| - 	{ .compatible = "qcom,pmi8994", .data = N_USIDS(2) },
 | |
| - 	{ .compatible = "qcom,pmi8998", .data = N_USIDS(2) },
 | |
| - 	{ .compatible = "qcom,pmk8002", .data = N_USIDS(2) },
 | |
| -+	{ .compatible = "qcom,pmp8074", .data = N_USIDS(2) },
 | |
| - 	{ .compatible = "qcom,smb2351", .data = N_USIDS(2) },
 | |
| - 	{ .compatible = "qcom,spmi-pmic", .data = N_USIDS(1) },
 | |
| - 	{ }
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0061-v6.0-regulator-qcom_spmi-add-support-for-HT_P150.patch b/target/linux/ipq807x/patches-5.15/0061-v6.0-regulator-qcom_spmi-add-support-for-HT_P150.patch
 | |
| deleted file mode 100644
 | |
| index b0dbe7d088..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0061-v6.0-regulator-qcom_spmi-add-support-for-HT_P150.patch
 | |
| +++ /dev/null
 | |
| @@ -1,58 +0,0 @@
 | |
| -From dedc087d43013ab6043dd1da4cd585dd4242a6bb Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Mon, 4 Jul 2022 23:23:54 +0200
 | |
| -Subject: [PATCH] regulator: qcom_spmi: add support for HT_P150
 | |
| -
 | |
| -HT_P150 is a LDO PMOS regulator based on LV P150 using HFS430 layout
 | |
| -found in PMP8074 and PMS405 PMIC-s.
 | |
| -
 | |
| -Both PMP8074 and PMS405 define the programmable range as 1.616V to 3.304V
 | |
| -but the actual MAX output voltage depends on the exact LDO in each of
 | |
| -the PMIC-s.
 | |
| -
 | |
| -It has a max current of 150mA, voltage step of 8mV.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Link: https://lore.kernel.org/r/20220704212402.1715182-4-robimarko@gmail.com
 | |
| -Signed-off-by: Mark Brown <broonie@kernel.org>
 | |
| ----
 | |
| - drivers/regulator/qcom_spmi-regulator.c | 7 +++++++
 | |
| - 1 file changed, 7 insertions(+)
 | |
| -
 | |
| ---- a/drivers/regulator/qcom_spmi-regulator.c
 | |
| -+++ b/drivers/regulator/qcom_spmi-regulator.c
 | |
| -@@ -164,6 +164,7 @@ enum spmi_regulator_subtype {
 | |
| - 	SPMI_REGULATOR_SUBTYPE_ULT_HF_CTL3	= 0x0f,
 | |
| - 	SPMI_REGULATOR_SUBTYPE_ULT_HF_CTL4	= 0x10,
 | |
| - 	SPMI_REGULATOR_SUBTYPE_HFS430		= 0x0a,
 | |
| -+	SPMI_REGULATOR_SUBTYPE_HT_P150		= 0x35,
 | |
| - };
 | |
| - 
 | |
| - enum spmi_common_regulator_registers {
 | |
| -@@ -544,6 +545,10 @@ static struct spmi_voltage_range hfs430_
 | |
| - 	SPMI_VOLTAGE_RANGE(0, 320000, 320000, 2040000, 2040000, 8000),
 | |
| - };
 | |
| - 
 | |
| -+static struct spmi_voltage_range ht_p150_ranges[] = {
 | |
| -+	SPMI_VOLTAGE_RANGE(0, 1616000, 1616000, 3304000, 3304000, 8000),
 | |
| -+};
 | |
| -+
 | |
| - static DEFINE_SPMI_SET_POINTS(pldo);
 | |
| - static DEFINE_SPMI_SET_POINTS(nldo1);
 | |
| - static DEFINE_SPMI_SET_POINTS(nldo2);
 | |
| -@@ -564,6 +569,7 @@ static DEFINE_SPMI_SET_POINTS(nldo660);
 | |
| - static DEFINE_SPMI_SET_POINTS(ht_lvpldo);
 | |
| - static DEFINE_SPMI_SET_POINTS(ht_nldo);
 | |
| - static DEFINE_SPMI_SET_POINTS(hfs430);
 | |
| -+static DEFINE_SPMI_SET_POINTS(ht_p150);
 | |
| - 
 | |
| - static inline int spmi_vreg_read(struct spmi_regulator *vreg, u16 addr, u8 *buf,
 | |
| - 				 int len)
 | |
| -@@ -1458,6 +1464,7 @@ static const struct regulator_ops spmi_h
 | |
| - 
 | |
| - static const struct spmi_regulator_mapping supported_regulators[] = {
 | |
| - 	/*           type subtype dig_min dig_max ltype ops setpoints hpm_min */
 | |
| -+	SPMI_VREG(LDO,   HT_P150,  0, INF, HFS430, hfs430, ht_p150, 10000),
 | |
| - 	SPMI_VREG(BUCK,  GP_CTL,   0, INF, SMPS,   smps,   smps,   100000),
 | |
| - 	SPMI_VREG(BUCK,  HFS430,   0, INF, HFS430, hfs430, hfs430,  10000),
 | |
| - 	SPMI_VREG(LDO,   N300,     0, INF, LDO,    ldo,    nldo1,   10000),
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0062-v6.0-regulator-qcom_spmi-add-support-for-HT_P600.patch b/target/linux/ipq807x/patches-5.15/0062-v6.0-regulator-qcom_spmi-add-support-for-HT_P600.patch
 | |
| deleted file mode 100644
 | |
| index 6b76f2c3fc..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0062-v6.0-regulator-qcom_spmi-add-support-for-HT_P600.patch
 | |
| +++ /dev/null
 | |
| @@ -1,59 +0,0 @@
 | |
| -From 14789f38e03c42857613b69ff0f032e03653b246 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Mon, 4 Jul 2022 23:23:55 +0200
 | |
| -Subject: [PATCH] regulator: qcom_spmi: add support for HT_P600
 | |
| -
 | |
| -HT_P600 is a LDO PMOS regulator based on LV P600 using HFS430 layout
 | |
| -found in PMP8074 and PMS405 PMIC-s.
 | |
| -
 | |
| -Both PMP8074 and PMS405 define the programmable range as 1.704 to 1.896V
 | |
| -but the actual MAX output voltage depends on the exact LDO in each of
 | |
| -the PMIC-s.
 | |
| -Their usual voltage that they are used is 1.8V.
 | |
| -
 | |
| -It has a max current of 600mA, voltage step of 8mV.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Link: https://lore.kernel.org/r/20220704212402.1715182-5-robimarko@gmail.com
 | |
| -Signed-off-by: Mark Brown <broonie@kernel.org>
 | |
| ----
 | |
| - drivers/regulator/qcom_spmi-regulator.c | 7 +++++++
 | |
| - 1 file changed, 7 insertions(+)
 | |
| -
 | |
| ---- a/drivers/regulator/qcom_spmi-regulator.c
 | |
| -+++ b/drivers/regulator/qcom_spmi-regulator.c
 | |
| -@@ -165,6 +165,7 @@ enum spmi_regulator_subtype {
 | |
| - 	SPMI_REGULATOR_SUBTYPE_ULT_HF_CTL4	= 0x10,
 | |
| - 	SPMI_REGULATOR_SUBTYPE_HFS430		= 0x0a,
 | |
| - 	SPMI_REGULATOR_SUBTYPE_HT_P150		= 0x35,
 | |
| -+	SPMI_REGULATOR_SUBTYPE_HT_P600		= 0x3d,
 | |
| - };
 | |
| - 
 | |
| - enum spmi_common_regulator_registers {
 | |
| -@@ -549,6 +550,10 @@ static struct spmi_voltage_range ht_p150
 | |
| - 	SPMI_VOLTAGE_RANGE(0, 1616000, 1616000, 3304000, 3304000, 8000),
 | |
| - };
 | |
| - 
 | |
| -+static struct spmi_voltage_range ht_p600_ranges[] = {
 | |
| -+	SPMI_VOLTAGE_RANGE(0, 1704000, 1704000, 1896000, 1896000, 8000),
 | |
| -+};
 | |
| -+
 | |
| - static DEFINE_SPMI_SET_POINTS(pldo);
 | |
| - static DEFINE_SPMI_SET_POINTS(nldo1);
 | |
| - static DEFINE_SPMI_SET_POINTS(nldo2);
 | |
| -@@ -570,6 +575,7 @@ static DEFINE_SPMI_SET_POINTS(ht_lvpldo)
 | |
| - static DEFINE_SPMI_SET_POINTS(ht_nldo);
 | |
| - static DEFINE_SPMI_SET_POINTS(hfs430);
 | |
| - static DEFINE_SPMI_SET_POINTS(ht_p150);
 | |
| -+static DEFINE_SPMI_SET_POINTS(ht_p600);
 | |
| - 
 | |
| - static inline int spmi_vreg_read(struct spmi_regulator *vreg, u16 addr, u8 *buf,
 | |
| - 				 int len)
 | |
| -@@ -1464,6 +1470,7 @@ static const struct regulator_ops spmi_h
 | |
| - 
 | |
| - static const struct spmi_regulator_mapping supported_regulators[] = {
 | |
| - 	/*           type subtype dig_min dig_max ltype ops setpoints hpm_min */
 | |
| -+	SPMI_VREG(LDO,   HT_P600,  0, INF, HFS430, hfs430, ht_p600, 10000),
 | |
| - 	SPMI_VREG(LDO,   HT_P150,  0, INF, HFS430, hfs430, ht_p150, 10000),
 | |
| - 	SPMI_VREG(BUCK,  GP_CTL,   0, INF, SMPS,   smps,   smps,   100000),
 | |
| - 	SPMI_VREG(BUCK,  HFS430,   0, INF, HFS430, hfs430, hfs430,  10000),
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0063-v6.0-regulator-qcom_spmi-add-support-for-PMP8074-regulato.patch b/target/linux/ipq807x/patches-5.15/0063-v6.0-regulator-qcom_spmi-add-support-for-PMP8074-regulato.patch
 | |
| deleted file mode 100644
 | |
| index ce6985b13b..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0063-v6.0-regulator-qcom_spmi-add-support-for-PMP8074-regulato.patch
 | |
| +++ /dev/null
 | |
| @@ -1,68 +0,0 @@
 | |
| -From 3e3da8da25f81fa3f0f3a37f60d10b17d1166864 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Mon, 4 Jul 2022 23:23:57 +0200
 | |
| -Subject: [PATCH] regulator: qcom_spmi: add support for PMP8074 regulators
 | |
| -
 | |
| -PMP8074 is a companion PMIC for the Qualcomm IPQ8074 WiSoC-s.
 | |
| -
 | |
| -It features 5 HF-SMPS and 13 LDO regulators.
 | |
| -
 | |
| -HF-SMPS regulators are Buck HFS430 regulators.
 | |
| -L1, L2 and L3 are HT_N1200_ST subtype LDO regulators.
 | |
| -L4 is HT_N300_ST subtype LDO regulator.
 | |
| -L5 and L6 are HT_P600 subtype LDO regulators.
 | |
| -L7, L11, L12 and L13 are HT_P150 subtype LDO regulators.
 | |
| -L10 is HT_P50 subtype LDO regulator.
 | |
| -
 | |
| -This commit adds support for all of the buck regulators and LDO-s except
 | |
| -for L10 as I dont have documentation on its output voltage range.
 | |
| -
 | |
| -S3 is the CPU cluster voltage supply, S4 supplies the UBI32 NPU cores
 | |
| -and L11 is the SDIO/eMMC I/O voltage regulator required for high speeds.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Link: https://lore.kernel.org/r/20220704212402.1715182-7-robimarko@gmail.com
 | |
| -Signed-off-by: Mark Brown <broonie@kernel.org>
 | |
| ----
 | |
| - drivers/regulator/qcom_spmi-regulator.c | 23 +++++++++++++++++++++++
 | |
| - 1 file changed, 23 insertions(+)
 | |
| -
 | |
| ---- a/drivers/regulator/qcom_spmi-regulator.c
 | |
| -+++ b/drivers/regulator/qcom_spmi-regulator.c
 | |
| -@@ -2101,6 +2101,28 @@ static const struct spmi_regulator_data
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| -+static const struct spmi_regulator_data pmp8074_regulators[] = {
 | |
| -+	{ "s1", 0x1400, "vdd_s1"},
 | |
| -+	{ "s2", 0x1700, "vdd_s2"},
 | |
| -+	{ "s3", 0x1a00, "vdd_s3"},
 | |
| -+	{ "s4", 0x1d00, "vdd_s4"},
 | |
| -+	{ "s5", 0x2000, "vdd_s5"},
 | |
| -+	{ "l1", 0x4000, "vdd_l1_l2"},
 | |
| -+	{ "l2", 0x4100, "vdd_l1_l2"},
 | |
| -+	{ "l3", 0x4200, "vdd_l3_l8"},
 | |
| -+	{ "l4", 0x4300, "vdd_l4"},
 | |
| -+	{ "l5", 0x4400, "vdd_l5_l6_l15"},
 | |
| -+	{ "l6", 0x4500, "vdd_l5_l6_l15"},
 | |
| -+	{ "l7", 0x4600, "vdd_l7"},
 | |
| -+	{ "l8", 0x4700, "vdd_l3_l8"},
 | |
| -+	{ "l9", 0x4800, "vdd_l9"},
 | |
| -+	/* l10 is currently unsupported HT_P50 */
 | |
| -+	{ "l11", 0x4a00, "vdd_l10_l11_l12_l13"},
 | |
| -+	{ "l12", 0x4b00, "vdd_l10_l11_l12_l13"},
 | |
| -+	{ "l13", 0x4c00, "vdd_l10_l11_l12_l13"},
 | |
| -+	{ }
 | |
| -+};
 | |
| -+
 | |
| - static const struct spmi_regulator_data pms405_regulators[] = {
 | |
| - 	{ "s3", 0x1a00, "vdd_s3"},
 | |
| - 	{ }
 | |
| -@@ -2117,6 +2139,7 @@ static const struct of_device_id qcom_sp
 | |
| - 	{ .compatible = "qcom,pmi8994-regulators", .data = &pmi8994_regulators },
 | |
| - 	{ .compatible = "qcom,pm660-regulators", .data = &pm660_regulators },
 | |
| - 	{ .compatible = "qcom,pm660l-regulators", .data = &pm660l_regulators },
 | |
| -+	{ .compatible = "qcom,pmp8074-regulators", .data = &pmp8074_regulators },
 | |
| - 	{ .compatible = "qcom,pms405-regulators", .data = &pms405_regulators },
 | |
| - 	{ }
 | |
| - };
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0064-v6.0-pinctrl-qcom-pmic-gpio-add-support-for-PMP8074.patch b/target/linux/ipq807x/patches-5.15/0064-v6.0-pinctrl-qcom-pmic-gpio-add-support-for-PMP8074.patch
 | |
| deleted file mode 100644
 | |
| index ba3d1750e1..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0064-v6.0-pinctrl-qcom-pmic-gpio-add-support-for-PMP8074.patch
 | |
| +++ /dev/null
 | |
| @@ -1,25 +0,0 @@
 | |
| -From 204cd3516f59eb7040b814429187e674f49ba065 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Mon, 11 Jul 2022 22:34:05 +0200
 | |
| -Subject: [PATCH] pinctrl: qcom-pmic-gpio: add support for PMP8074
 | |
| -
 | |
| -PMP8074 has 12 GPIO-s with holes on GPIO1 and GPIO12.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Link: https://lore.kernel.org/r/20220711203408.2949888-4-robimarko@gmail.com
 | |
| -Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
 | |
| ----
 | |
| - drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 2 ++
 | |
| - 1 file changed, 2 insertions(+)
 | |
| -
 | |
| ---- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
 | |
| -+++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
 | |
| -@@ -1167,6 +1167,8 @@ static const struct of_device_id pmic_gp
 | |
| - 	{ .compatible = "qcom,pmi8998-gpio", .data = (void *) 14 },
 | |
| - 	{ .compatible = "qcom,pmk8350-gpio", .data = (void *) 4 },
 | |
| - 	{ .compatible = "qcom,pmm8155au-gpio", .data = (void *) 10 },
 | |
| -+	/* pmp8074 has 12 GPIOs with holes on 1 and 12 */
 | |
| -+	{ .compatible = "qcom,pmp8074-gpio", .data = (void *) 12 },
 | |
| - 	{ .compatible = "qcom,pmr735a-gpio", .data = (void *) 4 },
 | |
| - 	{ .compatible = "qcom,pmr735b-gpio", .data = (void *) 4 },
 | |
| - 	/* pms405 has 12 GPIOs with holes on 1, 9, and 10 */
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0065-v6.1-iio-adc-qcom-spmi-adc5-add-ADC5_VREF_VADC-to-rev2-AD.patch b/target/linux/ipq807x/patches-5.15/0065-v6.1-iio-adc-qcom-spmi-adc5-add-ADC5_VREF_VADC-to-rev2-AD.patch
 | |
| deleted file mode 100644
 | |
| index 306f0dd253..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0065-v6.1-iio-adc-qcom-spmi-adc5-add-ADC5_VREF_VADC-to-rev2-AD.patch
 | |
| +++ /dev/null
 | |
| @@ -1,26 +0,0 @@
 | |
| -From 41a02abb863edca0de0373bc3deaf0639b18c589 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:18:13 +0200
 | |
| -Subject: [PATCH] iio: adc: qcom-spmi-adc5: add ADC5_VREF_VADC to rev2 ADC5
 | |
| -
 | |
| -Add support for ADC5_VREF_VADC channel to rev2 ADC5 channel list.
 | |
| -This channel measures the VADC reference LDO output.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Link: https://lore.kernel.org/r/20220818221815.346233-3-robimarko@gmail.com
 | |
| -Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
 | |
| ----
 | |
| - drivers/iio/adc/qcom-spmi-adc5.c | 2 ++
 | |
| - 1 file changed, 2 insertions(+)
 | |
| -
 | |
| ---- a/drivers/iio/adc/qcom-spmi-adc5.c
 | |
| -+++ b/drivers/iio/adc/qcom-spmi-adc5.c
 | |
| -@@ -589,6 +589,8 @@ static const struct adc5_channels adc5_c
 | |
| - 					SCALE_HW_CALIB_DEFAULT)
 | |
| - 	[ADC5_1P25VREF]		= ADC5_CHAN_VOLT("vref_1p25", 0,
 | |
| - 					SCALE_HW_CALIB_DEFAULT)
 | |
| -+	[ADC5_VREF_VADC]	= ADC5_CHAN_VOLT("vref_vadc", 0,
 | |
| -+					SCALE_HW_CALIB_DEFAULT)
 | |
| - 	[ADC5_VPH_PWR]		= ADC5_CHAN_VOLT("vph_pwr", 1,
 | |
| - 					SCALE_HW_CALIB_DEFAULT)
 | |
| - 	[ADC5_VBAT_SNS]		= ADC5_CHAN_VOLT("vbat_sns", 1,
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0066-v6.2-arm64-dts-qcom-add-PMP8074-DTSI.patch b/target/linux/ipq807x/patches-5.15/0066-v6.2-arm64-dts-qcom-add-PMP8074-DTSI.patch
 | |
| deleted file mode 100644
 | |
| index cd146420cf..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0066-v6.2-arm64-dts-qcom-add-PMP8074-DTSI.patch
 | |
| +++ /dev/null
 | |
| @@ -1,149 +0,0 @@
 | |
| -From fb76b808f8628215afebaf0f8af0bde635302590 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:18:14 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: add PMP8074 DTSI
 | |
| -
 | |
| -PMP8074 is a companion PMIC to the Qualcomm IPQ8074 series that is
 | |
| -controlled via SPMI.
 | |
| -
 | |
| -Add DTSI for it providing GPIO, regulator, RTC and VADC support.
 | |
| -
 | |
| -RTC is disabled by default as there is no built-in battery so it will
 | |
| -loose time unless board vendor added a battery, so make it optional.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818221815.346233-4-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/pmp8074.dtsi | 125 ++++++++++++++++++++++++++
 | |
| - 1 file changed, 125 insertions(+)
 | |
| - create mode 100644 arch/arm64/boot/dts/qcom/pmp8074.dtsi
 | |
| -
 | |
| ---- /dev/null
 | |
| -+++ b/arch/arm64/boot/dts/qcom/pmp8074.dtsi
 | |
| -@@ -0,0 +1,125 @@
 | |
| -+// SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
 | |
| -+
 | |
| -+#include <dt-bindings/spmi/spmi.h>
 | |
| -+#include <dt-bindings/iio/qcom,spmi-vadc.h>
 | |
| -+
 | |
| -+&spmi_bus {
 | |
| -+	pmic@0 {
 | |
| -+		compatible = "qcom,pmp8074", "qcom,spmi-pmic";
 | |
| -+		reg = <0x0 SPMI_USID>;
 | |
| -+		#address-cells = <1>;
 | |
| -+		#size-cells = <0>;
 | |
| -+
 | |
| -+		pmp8074_adc: adc@3100 {
 | |
| -+			compatible = "qcom,spmi-adc-rev2";
 | |
| -+			reg = <0x3100>;
 | |
| -+			interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
 | |
| -+			#address-cells = <1>;
 | |
| -+			#size-cells = <0>;
 | |
| -+			#io-channel-cells = <1>;
 | |
| -+
 | |
| -+			ref-gnd@0 {
 | |
| -+				reg = <ADC5_REF_GND>;
 | |
| -+				qcom,pre-scaling = <1 1>;
 | |
| -+			};
 | |
| -+
 | |
| -+			vref-1p25@1 {
 | |
| -+				reg = <ADC5_1P25VREF>;
 | |
| -+				qcom,pre-scaling = <1 1>;
 | |
| -+			};
 | |
| -+
 | |
| -+			vref-vadc@2 {
 | |
| -+				reg = <ADC5_VREF_VADC>;
 | |
| -+				qcom,pre-scaling = <1 1>;
 | |
| -+			};
 | |
| -+
 | |
| -+			pmic_die: die-temp@6 {
 | |
| -+				reg = <ADC5_DIE_TEMP>;
 | |
| -+				qcom,pre-scaling = <1 1>;
 | |
| -+			};
 | |
| -+
 | |
| -+			xo_therm: xo-temp@76 {
 | |
| -+				reg = <ADC5_XO_THERM_100K_PU>;
 | |
| -+				qcom,ratiometric;
 | |
| -+				qcom,hw-settle-time = <200>;
 | |
| -+				qcom,pre-scaling = <1 1>;
 | |
| -+			};
 | |
| -+
 | |
| -+			pa_therm1: thermistor1@77 {
 | |
| -+				reg = <ADC5_AMUX_THM1_100K_PU>;
 | |
| -+				qcom,ratiometric;
 | |
| -+				qcom,hw-settle-time = <200>;
 | |
| -+				qcom,pre-scaling = <1 1>;
 | |
| -+			};
 | |
| -+
 | |
| -+			pa_therm2: thermistor2@78 {
 | |
| -+				reg = <ADC5_AMUX_THM2_100K_PU>;
 | |
| -+				qcom,ratiometric;
 | |
| -+				qcom,hw-settle-time = <200>;
 | |
| -+				qcom,pre-scaling = <1 1>;
 | |
| -+			};
 | |
| -+
 | |
| -+			pa_therm3: thermistor3@79 {
 | |
| -+				reg = <ADC5_AMUX_THM3_100K_PU>;
 | |
| -+				qcom,ratiometric;
 | |
| -+				qcom,hw-settle-time = <200>;
 | |
| -+				qcom,pre-scaling = <1 1>;
 | |
| -+			};
 | |
| -+
 | |
| -+			vph-pwr@131 {
 | |
| -+				reg = <ADC5_VPH_PWR>;
 | |
| -+				qcom,pre-scaling = <1 3>;
 | |
| -+			};
 | |
| -+		};
 | |
| -+
 | |
| -+		pmp8074_rtc: rtc@6000 {
 | |
| -+			compatible = "qcom,pm8941-rtc";
 | |
| -+			reg = <0x6000>;
 | |
| -+			reg-names = "rtc", "alarm";
 | |
| -+			interrupts = <0x0 0x61 0x1 IRQ_TYPE_NONE>;
 | |
| -+			allow-set-time;
 | |
| -+			status = "disabled";
 | |
| -+		};
 | |
| -+
 | |
| -+		pmp8074_gpios: gpio@c000 {
 | |
| -+			compatible = "qcom,pmp8074-gpio", "qcom,spmi-gpio";
 | |
| -+			reg = <0xc000>;
 | |
| -+			gpio-controller;
 | |
| -+			#gpio-cells = <2>;
 | |
| -+			gpio-ranges = <&pmp8074_gpios 0 0 12>;
 | |
| -+			interrupt-controller;
 | |
| -+			#interrupt-cells = <2>;
 | |
| -+		};
 | |
| -+	};
 | |
| -+
 | |
| -+	pmic@1 {
 | |
| -+		compatible = "qcom,pmp8074", "qcom,spmi-pmic";
 | |
| -+		reg = <0x1 SPMI_USID>;
 | |
| -+
 | |
| -+		regulators {
 | |
| -+			compatible = "qcom,pmp8074-regulators";
 | |
| -+
 | |
| -+			s3: s3 {
 | |
| -+				regulator-name = "vdd_s3";
 | |
| -+				regulator-min-microvolt = <592000>;
 | |
| -+				regulator-max-microvolt = <1064000>;
 | |
| -+				regulator-always-on;
 | |
| -+				regulator-boot-on;
 | |
| -+			};
 | |
| -+
 | |
| -+			s4: s4 {
 | |
| -+				regulator-name = "vdd_s4";
 | |
| -+				regulator-min-microvolt = <712000>;
 | |
| -+				regulator-max-microvolt = <992000>;
 | |
| -+				regulator-always-on;
 | |
| -+				regulator-boot-on;
 | |
| -+			};
 | |
| -+
 | |
| -+			l11: l11 {
 | |
| -+				regulator-name = "l11";
 | |
| -+				regulator-min-microvolt = <1800000>;
 | |
| -+				regulator-max-microvolt = <3300000>;
 | |
| -+			};
 | |
| -+		};
 | |
| -+	};
 | |
| -+};
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0067-v6.2-arm64-dts-qcom-ipq8074-hk01-add-VQMMC-supply.patch b/target/linux/ipq807x/patches-5.15/0067-v6.2-arm64-dts-qcom-ipq8074-hk01-add-VQMMC-supply.patch
 | |
| deleted file mode 100644
 | |
| index af65c0c979..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0067-v6.2-arm64-dts-qcom-ipq8074-hk01-add-VQMMC-supply.patch
 | |
| +++ /dev/null
 | |
| @@ -1,37 +0,0 @@
 | |
| -From 2c394cfc1779886048feca7dc7f4075da5f6328c Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 19 Aug 2022 00:18:15 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074-hk01: add VQMMC supply
 | |
| -
 | |
| -Since now we have control over the PMP8074 PMIC providing various system
 | |
| -voltages including L11 which provides the SDIO/eMMC I/O voltage set it as
 | |
| -the SDHCI VQMMC supply.
 | |
| -
 | |
| -This allows SDHCI controller to switch to 1.8V I/O mode and support high
 | |
| -speed modes like HS200 and HS400.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220818221815.346233-5-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk01.dts | 2 ++
 | |
| - 1 file changed, 2 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -@@ -3,6 +3,7 @@
 | |
| - /* Copyright (c) 2017, The Linux Foundation. All rights reserved.
 | |
| -  */
 | |
| - #include "ipq8074.dtsi"
 | |
| -+#include "pmp8074.dtsi"
 | |
| - 
 | |
| - / {
 | |
| - 	model = "Qualcomm Technologies, Inc. IPQ8074-HK01";
 | |
| -@@ -82,6 +83,7 @@
 | |
| - 
 | |
| - &sdhc_1 {
 | |
| - 	status = "okay";
 | |
| -+	vqmmc-supply = <&l11>;
 | |
| - };
 | |
| - 
 | |
| - &qusb_phy_0 {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0068-v6.2-arm64-dts-qcom-hk01-use-GPIO-flags-for-tlmm.patch b/target/linux/ipq807x/patches-5.15/0068-v6.2-arm64-dts-qcom-hk01-use-GPIO-flags-for-tlmm.patch
 | |
| deleted file mode 100644
 | |
| index 93c57d9ea9..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0068-v6.2-arm64-dts-qcom-hk01-use-GPIO-flags-for-tlmm.patch
 | |
| +++ /dev/null
 | |
| @@ -1,42 +0,0 @@
 | |
| -From 82ceb86227b1fc15c76d5fc691b2bf425f1a63b3 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Mon, 7 Nov 2022 10:29:30 +0100
 | |
| -Subject: [PATCH] arm64: dts: qcom: hk01: use GPIO flags for tlmm
 | |
| -
 | |
| -Use respective GPIO_ACTIVE_LOW/HIGH flags for tlmm GPIOs instead of
 | |
| -harcoding the cell value.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20221107092930.33325-3-robimarko@gmail.com
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk01.dts | 5 +++--
 | |
| - 1 file changed, 3 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -@@ -4,6 +4,7 @@
 | |
| -  */
 | |
| - #include "ipq8074.dtsi"
 | |
| - #include "pmp8074.dtsi"
 | |
| -+#include <dt-bindings/gpio/gpio.h>
 | |
| - 
 | |
| - / {
 | |
| - 	model = "Qualcomm Technologies, Inc. IPQ8074-HK01";
 | |
| -@@ -50,12 +51,12 @@
 | |
| - 
 | |
| - &pcie0 {
 | |
| - 	status = "okay";
 | |
| --	perst-gpios = <&tlmm 61 0x1>;
 | |
| -+	perst-gpios = <&tlmm 61 GPIO_ACTIVE_LOW>;
 | |
| - };
 | |
| - 
 | |
| - &pcie1 {
 | |
| - 	status = "okay";
 | |
| --	perst-gpios = <&tlmm 58 0x1>;
 | |
| -+	perst-gpios = <&tlmm 58 GPIO_ACTIVE_LOW>;
 | |
| - };
 | |
| - 
 | |
| - &pcie_qmp0 {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0069-v6.2-arm64-dts-qcom-ipq8074-Fix-up-comments.patch b/target/linux/ipq807x/patches-5.15/0069-v6.2-arm64-dts-qcom-ipq8074-Fix-up-comments.patch
 | |
| deleted file mode 100644
 | |
| index a8bf2492f4..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0069-v6.2-arm64-dts-qcom-ipq8074-Fix-up-comments.patch
 | |
| +++ /dev/null
 | |
| @@ -1,82 +0,0 @@
 | |
| -From 1b1c1423ca3e740984aa883512a72c4ea08fbe28 Mon Sep 17 00:00:00 2001
 | |
| -From: Konrad Dybcio <konrad.dybcio@linaro.org>
 | |
| -Date: Mon, 7 Nov 2022 15:55:17 +0100
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074-*: Fix up comments
 | |
| -
 | |
| -Make sure all multiline C-style commends begin with just '/*' with
 | |
| -the comment text starting on a new line.
 | |
| -
 | |
| -Also, fix up some whitespace within comments.
 | |
| -
 | |
| -Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20221107145522.6706-8-konrad.dybcio@linaro.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk01.dts    |  3 ++-
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk10-c1.dts |  3 ++-
 | |
| - arch/arm64/boot/dts/qcom/ipq8074-hk10-c2.dts |  3 ++-
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi        | 12 ++++++------
 | |
| - 4 files changed, 12 insertions(+), 9 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts
 | |
| -@@ -1,6 +1,7 @@
 | |
| - // SPDX-License-Identifier: GPL-2.0-only
 | |
| - /dts-v1/;
 | |
| --/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
 | |
| -+/*
 | |
| -+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 | |
| -  */
 | |
| - #include "ipq8074.dtsi"
 | |
| - #include "pmp8074.dtsi"
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074-hk10-c1.dts
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk10-c1.dts
 | |
| -@@ -1,5 +1,6 @@
 | |
| - // SPDX-License-Identifier: GPL-2.0-only
 | |
| --/* Copyright (c) 2020 The Linux Foundation. All rights reserved.
 | |
| -+/*
 | |
| -+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
 | |
| -  */
 | |
| - /dts-v1/;
 | |
| - 
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074-hk10-c2.dts
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074-hk10-c2.dts
 | |
| -@@ -1,6 +1,7 @@
 | |
| - // SPDX-License-Identifier: GPL-2.0-only
 | |
| - /dts-v1/;
 | |
| --/* Copyright (c) 2020 The Linux Foundation. All rights reserved.
 | |
| -+/*
 | |
| -+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
 | |
| -  */
 | |
| - #include "ipq8074-hk10.dtsi"
 | |
| - 
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -129,10 +129,10 @@
 | |
| - 			status = "disabled";
 | |
| - 
 | |
| - 			usb1_ssphy: phy@58200 {
 | |
| --				reg = <0x00058200 0x130>,       /* Tx */
 | |
| -+				reg = <0x00058200 0x130>,     /* Tx */
 | |
| - 				      <0x00058400 0x200>,     /* Rx */
 | |
| --				      <0x00058800 0x1f8>,     /* PCS  */
 | |
| --				      <0x00058600 0x044>;     /* PCS misc*/
 | |
| -+				      <0x00058800 0x1f8>,     /* PCS */
 | |
| -+				      <0x00058600 0x044>;     /* PCS misc */
 | |
| - 				#phy-cells = <0>;
 | |
| - 				#clock-cells = <0>;
 | |
| - 				clocks = <&gcc GCC_USB1_PIPE_CLK>;
 | |
| -@@ -172,10 +172,10 @@
 | |
| - 			status = "disabled";
 | |
| - 
 | |
| - 			usb0_ssphy: phy@78200 {
 | |
| --				reg = <0x00078200 0x130>,       /* Tx */
 | |
| -+				reg = <0x00078200 0x130>,     /* Tx */
 | |
| - 				      <0x00078400 0x200>,     /* Rx */
 | |
| --				      <0x00078800 0x1f8>,     /* PCS  */
 | |
| --				      <0x00078600 0x044>;     /* PCS misc*/
 | |
| -+				      <0x00078800 0x1f8>,     /* PCS */
 | |
| -+				      <0x00078600 0x044>;     /* PCS misc */
 | |
| - 				#phy-cells = <0>;
 | |
| - 				#clock-cells = <0>;
 | |
| - 				clocks = <&gcc GCC_USB0_PIPE_CLK>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0070-v6.2-arm64-dts-qcom-ipq8074-align-TLMM-pin-configuration-.patch b/target/linux/ipq807x/patches-5.15/0070-v6.2-arm64-dts-qcom-ipq8074-align-TLMM-pin-configuration-.patch
 | |
| deleted file mode 100644
 | |
| index 1ce1140682..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0070-v6.2-arm64-dts-qcom-ipq8074-align-TLMM-pin-configuration-.patch
 | |
| +++ /dev/null
 | |
| @@ -1,60 +0,0 @@
 | |
| -From 5f20690f77878b1ba24ec88df01b92d5131a6780 Mon Sep 17 00:00:00 2001
 | |
| -From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Date: Tue, 8 Nov 2022 15:23:57 +0100
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: align TLMM pin configuration with
 | |
| - DT schema
 | |
| -
 | |
| -DT schema expects TLMM pin configuration nodes to be named with
 | |
| -'-state' suffix and their optional children with '-pins' suffix.
 | |
| -
 | |
| -Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20221108142357.67202-2-krzysztof.kozlowski@linaro.org
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 10 +++++-----
 | |
| - 1 file changed, 5 insertions(+), 5 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -318,35 +318,35 @@
 | |
| - 			interrupt-controller;
 | |
| - 			#interrupt-cells = <0x2>;
 | |
| - 
 | |
| --			serial_4_pins: serial4-pinmux {
 | |
| -+			serial_4_pins: serial4-state {
 | |
| - 				pins = "gpio23", "gpio24";
 | |
| - 				function = "blsp4_uart1";
 | |
| - 				drive-strength = <8>;
 | |
| - 				bias-disable;
 | |
| - 			};
 | |
| - 
 | |
| --			i2c_0_pins: i2c-0-pinmux {
 | |
| -+			i2c_0_pins: i2c-0-state {
 | |
| - 				pins = "gpio42", "gpio43";
 | |
| - 				function = "blsp1_i2c";
 | |
| - 				drive-strength = <8>;
 | |
| - 				bias-disable;
 | |
| - 			};
 | |
| - 
 | |
| --			spi_0_pins: spi-0-pins {
 | |
| -+			spi_0_pins: spi-0-state {
 | |
| - 				pins = "gpio38", "gpio39", "gpio40", "gpio41";
 | |
| - 				function = "blsp0_spi";
 | |
| - 				drive-strength = <8>;
 | |
| - 				bias-disable;
 | |
| - 			};
 | |
| - 
 | |
| --			hsuart_pins: hsuart-pins {
 | |
| -+			hsuart_pins: hsuart-state {
 | |
| - 				pins = "gpio46", "gpio47", "gpio48", "gpio49";
 | |
| - 				function = "blsp2_uart";
 | |
| - 				drive-strength = <8>;
 | |
| - 				bias-disable;
 | |
| - 			};
 | |
| - 
 | |
| --			qpic_pins: qpic-pins {
 | |
| -+			qpic_pins: qpic-state {
 | |
| - 				pins = "gpio1", "gpio3", "gpio4",
 | |
| - 				       "gpio5", "gpio6", "gpio7",
 | |
| - 				       "gpio8", "gpio10", "gpio11",
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0071-v5.16-soc-qcom-socinfo-Add-IPQ8074-family-ID-s.patch b/target/linux/ipq807x/patches-5.15/0071-v5.16-soc-qcom-socinfo-Add-IPQ8074-family-ID-s.patch
 | |
| deleted file mode 100644
 | |
| index ed1b063972..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0071-v5.16-soc-qcom-socinfo-Add-IPQ8074-family-ID-s.patch
 | |
| +++ /dev/null
 | |
| @@ -1,50 +0,0 @@
 | |
| -From a212eb94fc9f72a126df651c5d7898feaea29526 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sun, 5 Sep 2021 19:11:31 +0200
 | |
| -Subject: [PATCH] soc: qcom: socinfo: Add IPQ8074 family ID-s
 | |
| -
 | |
| -IPQ8074 family SoC ID-s are missing, so lets add them based on
 | |
| -the downstream driver.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Kathiravan T <kathirav@codeaurora.org>
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20210905171131.660885-1-robimarko@gmail.com
 | |
| ----
 | |
| - drivers/soc/qcom/socinfo.c | 12 ++++++++++++
 | |
| - 1 file changed, 12 insertions(+)
 | |
| -
 | |
| ---- a/drivers/soc/qcom/socinfo.c
 | |
| -+++ b/drivers/soc/qcom/socinfo.c
 | |
| -@@ -281,19 +281,31 @@ static const struct soc_id soc_id[] = {
 | |
| - 	{ 319, "APQ8098" },
 | |
| - 	{ 321, "SDM845" },
 | |
| - 	{ 322, "MDM9206" },
 | |
| -+	{ 323, "IPQ8074" },
 | |
| - 	{ 324, "SDA660" },
 | |
| - 	{ 325, "SDM658" },
 | |
| - 	{ 326, "SDA658" },
 | |
| - 	{ 327, "SDA630" },
 | |
| - 	{ 338, "SDM450" },
 | |
| - 	{ 341, "SDA845" },
 | |
| -+	{ 342, "IPQ8072" },
 | |
| -+	{ 343, "IPQ8076" },
 | |
| -+	{ 344, "IPQ8078" },
 | |
| - 	{ 345, "SDM636" },
 | |
| - 	{ 346, "SDA636" },
 | |
| - 	{ 349, "SDM632" },
 | |
| - 	{ 350, "SDA632" },
 | |
| - 	{ 351, "SDA450" },
 | |
| - 	{ 356, "SM8250" },
 | |
| -+	{ 375, "IPQ8070" },
 | |
| -+	{ 376, "IPQ8071" },
 | |
| -+	{ 389, "IPQ8072A" },
 | |
| -+	{ 390, "IPQ8074A" },
 | |
| -+	{ 391, "IPQ8076A" },
 | |
| -+	{ 392, "IPQ8078A" },
 | |
| - 	{ 394, "SM6125" },
 | |
| -+	{ 395, "IPQ8070A" },
 | |
| -+	{ 396, "IPQ8071A" },
 | |
| - 	{ 402, "IPQ6018" },
 | |
| - 	{ 403, "IPQ6028" },
 | |
| - 	{ 421, "IPQ6000" },
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0072-v6.0-phy-qcom-qmp-pcie-make-pipe-clock-rate-configurable.patch b/target/linux/ipq807x/patches-5.15/0072-v6.0-phy-qcom-qmp-pcie-make-pipe-clock-rate-configurable.patch
 | |
| deleted file mode 100644
 | |
| index 667c0cf7c7..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0072-v6.0-phy-qcom-qmp-pcie-make-pipe-clock-rate-configurable.patch
 | |
| +++ /dev/null
 | |
| @@ -1,47 +0,0 @@
 | |
| -From 2b0fe9137aa32d7fc367bf3a1cef4fa97ece6d58 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Tue, 23 Aug 2022 22:43:51 +0200
 | |
| -Subject: [PATCH] phy: qcom-qmp-pcie: make pipe clock rate configurable
 | |
| -
 | |
| -IPQ8074 Gen3 PCIe PHY uses 250MHz as the pipe clock rate instead of 125MHz
 | |
| -like every other PCIe QMP PHY does, so make it configurable as part of the
 | |
| -qmp_phy_cfg.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220621195512.1760362-1-robimarko@gmail.com
 | |
| -Signed-off-by: Vinod Koul <vkoul@kernel.org>
 | |
| ----
 | |
| - drivers/phy/qualcomm/phy-qcom-qmp.c | 14 ++++++++++++--
 | |
| - 1 file changed, 12 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/drivers/phy/qualcomm/phy-qcom-qmp.c
 | |
| -+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
 | |
| -@@ -2842,6 +2842,9 @@ struct qmp_phy_cfg {
 | |
| - 	/* true, if PHY has secondary tx/rx lanes to be configured */
 | |
| - 	bool is_dual_lane_phy;
 | |
| - 
 | |
| -+	/* QMP PHY pipe clock interface rate */
 | |
| -+	unsigned long pipe_clock_rate;
 | |
| -+
 | |
| - 	/* true, if PCS block has no separate SW_RESET register */
 | |
| - 	bool no_pcs_sw_reset;
 | |
| - };
 | |
| -@@ -5139,8 +5142,15 @@ static int phy_pipe_clk_register(struct
 | |
| - 
 | |
| - 	init.ops = &clk_fixed_rate_ops;
 | |
| - 
 | |
| --	/* controllers using QMP phys use 125MHz pipe clock interface */
 | |
| --	fixed->fixed_rate = 125000000;
 | |
| -+	/*
 | |
| -+	 * Controllers using QMP PHY-s use 125MHz pipe clock interface
 | |
| -+	 * unless other frequency is specified in the PHY config.
 | |
| -+	 */
 | |
| -+	if (qmp->phys[0]->cfg->pipe_clock_rate)
 | |
| -+		fixed->fixed_rate = qmp->phys[0]->cfg->pipe_clock_rate;
 | |
| -+	else
 | |
| -+		fixed->fixed_rate = 125000000;
 | |
| -+
 | |
| - 	fixed->hw.init = &init;
 | |
| - 
 | |
| - 	ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0073-v6.0-phy-qcom-qmp-pcie-add-IPQ8074-PCIe-Gen3-QMP-PHY-supp.patch b/target/linux/ipq807x/patches-5.15/0073-v6.0-phy-qcom-qmp-pcie-add-IPQ8074-PCIe-Gen3-QMP-PHY-supp.patch
 | |
| deleted file mode 100644
 | |
| index 72aeef974e..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0073-v6.0-phy-qcom-qmp-pcie-add-IPQ8074-PCIe-Gen3-QMP-PHY-supp.patch
 | |
| +++ /dev/null
 | |
| @@ -1,200 +0,0 @@
 | |
| -From 23bd21d8c05109b57aa9508e88fbdbc2b6d33de7 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Tue, 23 Aug 2022 22:47:40 +0200
 | |
| -Subject: [PATCH] phy: qcom-qmp-pcie: add IPQ8074 PCIe Gen3 QMP PHY support
 | |
| -
 | |
| -IPQ8074 has 2 different single lane PCIe PHY-s, one Gen2 and one Gen3.
 | |
| -Gen2 one is already supported, so add the support for the Gen3 one.
 | |
| -It uses the same register layout as IPQ6018.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| -Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Link: https://lore.kernel.org/r/20220621195512.1760362-3-robimarko@gmail.com
 | |
| -Signed-off-by: Vinod Koul <vkoul@kernel.org>
 | |
| ----
 | |
| - drivers/phy/qualcomm/phy-qcom-qmp.c | 160 ++++++++++++++++++++++++++++
 | |
| - 1 file changed, 160 insertions(+)
 | |
| -
 | |
| ---- a/drivers/phy/qualcomm/phy-qcom-qmp.c
 | |
| -+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
 | |
| -@@ -812,6 +812,133 @@ static const struct qmp_phy_init_tbl ipq
 | |
| - 	QMP_PHY_INIT_CFG_L(QPHY_START_CTRL, 0x3),
 | |
| - };
 | |
| - 
 | |
| -+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_serdes_tbl[] = {
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x31),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_IVCO, 0x0f),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TRIM, 0x0f),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CMN_CONFIG, 0x06),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP_EN, 0x42),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_RESETSM_CNTRL, 0x20),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x01),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_MAP, 0x04),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER1, 0xff),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE_TIMER2, 0x3f),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x30),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x21),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE0, 0x82),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x03),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE0, 0x355),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE0, 0x35555),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE0, 0x1a),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE0, 0x1a0a),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE0, 0xb),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE0, 0x16),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE0, 0x28),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x0),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0x40),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE0, 0x02),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE0, 0x24),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x20),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV, 0xa),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_SELECT, 0x32),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_SYS_CLK_CTRL, 0x02),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_SYSCLK_EN_SEL, 0x08),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_BG_TIMER, 0xa),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_HSCLK_SEL, 0x1),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_DEC_START_MODE1, 0x68),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x2),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x2aa),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x2aaab),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP2_MODE1, 0x34),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_LOCK_CMP1_MODE1, 0x3414),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CP_CTRL_MODE1, 0x0b),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_RCTRL_MODE1, 0x16),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_PLL_CCTRL_MODE1, 0x28),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x0),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0x40),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE2_MODE1, 0x03),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_VCO_TUNE1_MODE1, 0xb4),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CORE_CLK_EN, 0x0),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CORECLK_DIV_MODE1, 0x08),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE0, 0x19),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_EP_DIV_MODE1, 0x28),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_PLL_CLK_ENABLE1, 0x90),
 | |
| -+};
 | |
| -+
 | |
| -+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_tx_tbl[] = {
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x02),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_TX0_RCV_DETECT_LVL_2, 0x12),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_TX0_HIGHZ_DRVR_EN, 0x10),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_TX0_LANE_MODE_1, 0x06),
 | |
| -+};
 | |
| -+
 | |
| -+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_rx_tbl[] = {
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_CNTRL, 0x03),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_ENABLES, 0x1c),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x14),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0xe),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x4),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_DFE_EN_TIMER, 0x04),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x7f),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_PI_CONTROLS, 0x70),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_LOW, 0x00),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH, 0x02),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH2, 0xc8),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH3, 0x09),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_10_HIGH4, 0xb1),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_LOW, 0x01),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH, 0x02),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH2, 0xc8),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH3, 0x09),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_01_HIGH4, 0xb1),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_LOW, 0xf0),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH, 0x2),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH2, 0x2f),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH3, 0xd3),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_MODE_00_HIGH4, 0x40),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0xc0),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_FO_GAIN, 0x0c),
 | |
| -+	QMP_PHY_INIT_CFG(QSERDES_RX0_UCDR_SO_GAIN, 0x02),
 | |
| -+};
 | |
| -+
 | |
| -+static const struct qmp_phy_init_tbl ipq8074_pcie_gen3_pcs_tbl[] = {
 | |
| -+	QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL2, 0x83),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_COM_FLL_CNT_VAL_L, 0x9),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_COM_FLL_CNT_VAL_H_TOL, 0x42),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_COM_FLL_MAN_CODE, 0x40),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_COM_FLL_CNTRL1, 0x01),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_H, 0x0),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x1),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_ACTIONS, 0x0),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H, 0x00),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG1, 0x11),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_EQ_CONFIG2, 0xb),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_CONFIG2, 0x52),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_MODE2_CONFIG2, 0x50),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_MODE2_CONFIG4, 0x1a),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x6),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_COM_G12S1_TXDEEMPH_M3P5DB, 0x10),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_COM_RX_DCC_CAL_CONFIG, 0x01),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_COM_RX_SIGDET_LVL, 0xaa),
 | |
| -+	QMP_PHY_INIT_CFG(PCS_COM_REFGEN_REQ_CONFIG1, 0x0d),
 | |
| -+};
 | |
| -+
 | |
| - static const struct qmp_phy_init_tbl sdm845_qmp_pcie_serdes_tbl[] = {
 | |
| - 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
 | |
| - 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
 | |
| -@@ -3168,6 +3295,36 @@ static const struct qmp_phy_cfg ipq8074_
 | |
| - 	.pwrdn_delay_max	= 1005,		/* us */
 | |
| - };
 | |
| - 
 | |
| -+static const struct qmp_phy_cfg ipq8074_pciephy_gen3_cfg = {
 | |
| -+	.type			= PHY_TYPE_PCIE,
 | |
| -+	.nlanes			= 1,
 | |
| -+
 | |
| -+	.serdes_tbl		= ipq8074_pcie_gen3_serdes_tbl,
 | |
| -+	.serdes_tbl_num		= ARRAY_SIZE(ipq8074_pcie_gen3_serdes_tbl),
 | |
| -+	.tx_tbl			= ipq8074_pcie_gen3_tx_tbl,
 | |
| -+	.tx_tbl_num		= ARRAY_SIZE(ipq8074_pcie_gen3_tx_tbl),
 | |
| -+	.rx_tbl			= ipq8074_pcie_gen3_rx_tbl,
 | |
| -+	.rx_tbl_num		= ARRAY_SIZE(ipq8074_pcie_gen3_rx_tbl),
 | |
| -+	.pcs_tbl		= ipq8074_pcie_gen3_pcs_tbl,
 | |
| -+	.pcs_tbl_num		= ARRAY_SIZE(ipq8074_pcie_gen3_pcs_tbl),
 | |
| -+	.clk_list		= ipq8074_pciephy_clk_l,
 | |
| -+	.num_clks		= ARRAY_SIZE(ipq8074_pciephy_clk_l),
 | |
| -+	.reset_list		= ipq8074_pciephy_reset_l,
 | |
| -+	.num_resets		= ARRAY_SIZE(ipq8074_pciephy_reset_l),
 | |
| -+	.vreg_list		= NULL,
 | |
| -+	.num_vregs		= 0,
 | |
| -+	.regs			= ipq_pciephy_gen3_regs_layout,
 | |
| -+
 | |
| -+	.start_ctrl		= SERDES_START | PCS_START,
 | |
| -+	.pwrdn_ctrl		= SW_PWRDN | REFCLK_DRV_DSBL,
 | |
| -+
 | |
| -+	.has_pwrdn_delay	= true,
 | |
| -+	.pwrdn_delay_min	= 995,		/* us */
 | |
| -+	.pwrdn_delay_max	= 1005,		/* us */
 | |
| -+
 | |
| -+	.pipe_clock_rate	= 250000000,
 | |
| -+};
 | |
| -+
 | |
| - static const struct qmp_phy_cfg ipq6018_pciephy_cfg = {
 | |
| - 	.type			= PHY_TYPE_PCIE,
 | |
| - 	.nlanes			= 1,
 | |
| -@@ -5571,6 +5728,9 @@ static const struct of_device_id qcom_qm
 | |
| - 		.compatible = "qcom,ipq8074-qmp-pcie-phy",
 | |
| - 		.data = &ipq8074_pciephy_cfg,
 | |
| - 	}, {
 | |
| -+		.compatible = "qcom,ipq8074-qmp-gen3-pcie-phy",
 | |
| -+		.data = &ipq8074_pciephy_gen3_cfg,
 | |
| -+	}, {
 | |
| - 		.compatible = "qcom,ipq6018-qmp-pcie-phy",
 | |
| - 		.data = &ipq6018_pciephy_cfg,
 | |
| - 	}, {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0074-v6.0-PCI-dwc-Move-GEN3_RELATED-DBI-definitions-to-common-.patch b/target/linux/ipq807x/patches-5.15/0074-v6.0-PCI-dwc-Move-GEN3_RELATED-DBI-definitions-to-common-.patch
 | |
| deleted file mode 100644
 | |
| index 626507abb2..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0074-v6.0-PCI-dwc-Move-GEN3_RELATED-DBI-definitions-to-common-.patch
 | |
| +++ /dev/null
 | |
| @@ -1,46 +0,0 @@
 | |
| -From 8df9fefd1d04f6f97f6015d7347104f69e6ea580 Mon Sep 17 00:00:00 2001
 | |
| -From: Baruch Siach <baruch.siach@siklu.com>
 | |
| -Date: Tue, 21 Jun 2022 11:54:52 +0300
 | |
| -Subject: [PATCH] PCI: dwc: Move GEN3_RELATED DBI definitions to common header
 | |
| -
 | |
| -These are common dwc macros that will be used for other platforms.
 | |
| -
 | |
| -Link: https://lore.kernel.org/r/1c2d5a7a139be81fa15f356b2380163dbdebdc09.1655799816.git.baruch@tkos.co.il
 | |
| -Signed-off-by: Baruch Siach <baruch.siach@siklu.com>
 | |
| -Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
 | |
| -Reviewed-by: Rob Herring <robh@kernel.org>
 | |
| ----
 | |
| - drivers/pci/controller/dwc/pcie-designware.h | 6 ++++++
 | |
| - drivers/pci/controller/dwc/pcie-tegra194.c   | 6 ------
 | |
| - 2 files changed, 6 insertions(+), 6 deletions(-)
 | |
| -
 | |
| ---- a/drivers/pci/controller/dwc/pcie-designware.h
 | |
| -+++ b/drivers/pci/controller/dwc/pcie-designware.h
 | |
| -@@ -74,6 +74,12 @@
 | |
| - #define PCIE_MSI_INTR0_MASK		0x82C
 | |
| - #define PCIE_MSI_INTR0_STATUS		0x830
 | |
| - 
 | |
| -+#define GEN3_RELATED_OFF			0x890
 | |
| -+#define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
 | |
| -+#define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
 | |
| -+#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
 | |
| -+#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
 | |
| -+
 | |
| - #define PCIE_PORT_MULTI_LANE_CTRL	0x8C0
 | |
| - #define PORT_MLTI_UPCFG_SUPPORT		BIT(7)
 | |
| - 
 | |
| ---- a/drivers/pci/controller/dwc/pcie-tegra194.c
 | |
| -+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
 | |
| -@@ -193,12 +193,6 @@
 | |
| - #define GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC_MASK	GENMASK(23, 8)
 | |
| - #define GEN3_EQ_CONTROL_OFF_FB_MODE_MASK	GENMASK(3, 0)
 | |
| - 
 | |
| --#define GEN3_RELATED_OFF			0x890
 | |
| --#define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
 | |
| --#define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
 | |
| --#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
 | |
| --#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
 | |
| --
 | |
| - #define PORT_LOGIC_AMBA_ERROR_RESPONSE_DEFAULT	0x8D0
 | |
| - #define AMBA_ERROR_RESPONSE_CRS_SHIFT		3
 | |
| - #define AMBA_ERROR_RESPONSE_CRS_MASK		GENMASK(1, 0)
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0075-v6.0-PCI-qcom-Define-slot-capabilities-using-PCI_EXP_SLTC.patch b/target/linux/ipq807x/patches-5.15/0075-v6.0-PCI-qcom-Define-slot-capabilities-using-PCI_EXP_SLTC.patch
 | |
| deleted file mode 100644
 | |
| index bc1464b126..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0075-v6.0-PCI-qcom-Define-slot-capabilities-using-PCI_EXP_SLTC.patch
 | |
| +++ /dev/null
 | |
| @@ -1,51 +0,0 @@
 | |
| -From d568739f1c21e1768a887ff85611769f782eb64f Mon Sep 17 00:00:00 2001
 | |
| -From: Baruch Siach <baruch.siach@siklu.com>
 | |
| -Date: Tue, 21 Jun 2022 11:54:53 +0300
 | |
| -Subject: [PATCH] PCI: qcom: Define slot capabilities using PCI_EXP_SLTCAP_*
 | |
| -
 | |
| -The PCIE_CAP_LINK1_VAL macro actually defines slot capabilities. Use
 | |
| -PCI_EXP_SLTCAP_* macros to spell its value, and rename it to better
 | |
| -describe its meaning.
 | |
| -
 | |
| -Link: https://lore.kernel.org/r/3025d5e1d8da64798db6958f9780c4763fbcac47.1655799816.git.baruch@tkos.co.il
 | |
| -Signed-off-by: Baruch Siach <baruch.siach@siklu.com>
 | |
| -Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
 | |
| -Reviewed-by: Rob Herring <robh@kernel.org>
 | |
| -Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com>
 | |
| ----
 | |
| - drivers/pci/controller/dwc/pcie-qcom.c | 17 +++++++++++++++--
 | |
| - 1 file changed, 15 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/drivers/pci/controller/dwc/pcie-qcom.c
 | |
| -+++ b/drivers/pci/controller/dwc/pcie-qcom.c
 | |
| -@@ -69,7 +69,20 @@
 | |
| - #define PCIE20_AXI_MSTR_RESP_COMP_CTRL1		0x81c
 | |
| - #define CFG_BRIDGE_SB_INIT			BIT(0)
 | |
| - 
 | |
| --#define PCIE_CAP_LINK1_VAL			0x2FD7F
 | |
| -+#define PCIE_CAP_SLOT_POWER_LIMIT_VAL		FIELD_PREP(PCI_EXP_SLTCAP_SPLV, \
 | |
| -+						250)
 | |
| -+#define PCIE_CAP_SLOT_POWER_LIMIT_SCALE		FIELD_PREP(PCI_EXP_SLTCAP_SPLS, \
 | |
| -+						1)
 | |
| -+#define PCIE_CAP_SLOT_VAL			(PCI_EXP_SLTCAP_ABP | \
 | |
| -+						PCI_EXP_SLTCAP_PCP | \
 | |
| -+						PCI_EXP_SLTCAP_MRLSP | \
 | |
| -+						PCI_EXP_SLTCAP_AIP | \
 | |
| -+						PCI_EXP_SLTCAP_PIP | \
 | |
| -+						PCI_EXP_SLTCAP_HPS | \
 | |
| -+						PCI_EXP_SLTCAP_HPC | \
 | |
| -+						PCI_EXP_SLTCAP_EIP | \
 | |
| -+						PCIE_CAP_SLOT_POWER_LIMIT_VAL | \
 | |
| -+						PCIE_CAP_SLOT_POWER_LIMIT_SCALE)
 | |
| - 
 | |
| - #define PCIE20_PARF_Q2A_FLUSH			0x1AC
 | |
| - 
 | |
| -@@ -1125,7 +1138,7 @@ static int qcom_pcie_post_init_2_3_3(str
 | |
| - 
 | |
| - 	writel(PCI_COMMAND_MASTER, pci->dbi_base + PCI_COMMAND);
 | |
| - 	writel(DBI_RO_WR_EN, pci->dbi_base + PCIE20_MISC_CONTROL_1_REG);
 | |
| --	writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
 | |
| -+	writel(PCIE_CAP_SLOT_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
 | |
| - 
 | |
| - 	val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
 | |
| - 	val &= ~PCI_EXP_LNKCAP_ASPMS;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0076-v5.16-PCI-qcom-Replace-ops-with-struct-pcie_cfg-in-pcie-ma.patch b/target/linux/ipq807x/patches-5.15/0076-v5.16-PCI-qcom-Replace-ops-with-struct-pcie_cfg-in-pcie-ma.patch
 | |
| deleted file mode 100644
 | |
| index 817a3c64c9..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0076-v5.16-PCI-qcom-Replace-ops-with-struct-pcie_cfg-in-pcie-ma.patch
 | |
| +++ /dev/null
 | |
| @@ -1,122 +0,0 @@
 | |
| -From 180ce25d5c3ccff206f084b7ab350778641d1b1c Mon Sep 17 00:00:00 2001
 | |
| -From: Prasad Malisetty <pmaliset@codeaurora.org>
 | |
| -Date: Thu, 7 Oct 2021 23:18:42 +0530
 | |
| -Subject: [PATCH] PCI: qcom: Replace ops with struct pcie_cfg in pcie match
 | |
| - data
 | |
| -
 | |
| -Add struct qcom_pcie_cfg as match data for all platforms.  Assign
 | |
| -appropriate platform ops into struct qcom_pcie_cfg and read using
 | |
| -of_device_get_match_data() in qcom_pcie_probe().
 | |
| -
 | |
| -Link: https://lore.kernel.org/r/1633628923-25047-5-git-send-email-pmaliset@codeaurora.org
 | |
| -Signed-off-by: Prasad Malisetty <pmaliset@codeaurora.org>
 | |
| -Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
 | |
| -Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
 | |
| -Reviewed-by: Stephen Boyd <swboyd@chromium.org>
 | |
| ----
 | |
| - drivers/pci/controller/dwc/pcie-qcom.c | 66 +++++++++++++++++++++-----
 | |
| - 1 file changed, 55 insertions(+), 11 deletions(-)
 | |
| -
 | |
| ---- a/drivers/pci/controller/dwc/pcie-qcom.c
 | |
| -+++ b/drivers/pci/controller/dwc/pcie-qcom.c
 | |
| -@@ -202,6 +202,10 @@ struct qcom_pcie_ops {
 | |
| - 	int (*config_sid)(struct qcom_pcie *pcie);
 | |
| - };
 | |
| - 
 | |
| -+struct qcom_pcie_cfg {
 | |
| -+	const struct qcom_pcie_ops *ops;
 | |
| -+};
 | |
| -+
 | |
| - struct qcom_pcie {
 | |
| - 	struct dw_pcie *pci;
 | |
| - 	void __iomem *parf;			/* DT parf */
 | |
| -@@ -1469,6 +1473,38 @@ static const struct qcom_pcie_ops ops_1_
 | |
| - 	.config_sid = qcom_pcie_config_sid_sm8250,
 | |
| - };
 | |
| - 
 | |
| -+static const struct qcom_pcie_cfg apq8084_cfg = {
 | |
| -+	.ops = &ops_1_0_0,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct qcom_pcie_cfg ipq8064_cfg = {
 | |
| -+	.ops = &ops_2_1_0,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct qcom_pcie_cfg msm8996_cfg = {
 | |
| -+	.ops = &ops_2_3_2,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct qcom_pcie_cfg ipq8074_cfg = {
 | |
| -+	.ops = &ops_2_3_3,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct qcom_pcie_cfg ipq4019_cfg = {
 | |
| -+	.ops = &ops_2_4_0,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct qcom_pcie_cfg sdm845_cfg = {
 | |
| -+	.ops = &ops_2_7_0,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct qcom_pcie_cfg sm8250_cfg = {
 | |
| -+	.ops = &ops_1_9_0,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct qcom_pcie_cfg sc7280_cfg = {
 | |
| -+	.ops = &ops_1_9_0,
 | |
| -+};
 | |
| -+
 | |
| - static const struct dw_pcie_ops dw_pcie_ops = {
 | |
| - 	.link_up = qcom_pcie_link_up,
 | |
| - 	.start_link = qcom_pcie_start_link,
 | |
| -@@ -1480,6 +1516,7 @@ static int qcom_pcie_probe(struct platfo
 | |
| - 	struct pcie_port *pp;
 | |
| - 	struct dw_pcie *pci;
 | |
| - 	struct qcom_pcie *pcie;
 | |
| -+	const struct qcom_pcie_cfg *pcie_cfg;
 | |
| - 	int ret;
 | |
| - 
 | |
| - 	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
 | |
| -@@ -1501,7 +1538,13 @@ static int qcom_pcie_probe(struct platfo
 | |
| - 
 | |
| - 	pcie->pci = pci;
 | |
| - 
 | |
| --	pcie->ops = of_device_get_match_data(dev);
 | |
| -+	pcie_cfg = of_device_get_match_data(dev);
 | |
| -+	if (!pcie_cfg || !pcie_cfg->ops) {
 | |
| -+		dev_err(dev, "Invalid platform data\n");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	pcie->ops = pcie_cfg->ops;
 | |
| - 
 | |
| - 	pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_HIGH);
 | |
| - 	if (IS_ERR(pcie->reset)) {
 | |
| -@@ -1557,16 +1600,17 @@ err_pm_runtime_put:
 | |
| - }
 | |
| - 
 | |
| - static const struct of_device_id qcom_pcie_match[] = {
 | |
| --	{ .compatible = "qcom,pcie-apq8084", .data = &ops_1_0_0 },
 | |
| --	{ .compatible = "qcom,pcie-ipq8064", .data = &ops_2_1_0 },
 | |
| --	{ .compatible = "qcom,pcie-ipq8064-v2", .data = &ops_2_1_0 },
 | |
| --	{ .compatible = "qcom,pcie-apq8064", .data = &ops_2_1_0 },
 | |
| --	{ .compatible = "qcom,pcie-msm8996", .data = &ops_2_3_2 },
 | |
| --	{ .compatible = "qcom,pcie-ipq8074", .data = &ops_2_3_3 },
 | |
| --	{ .compatible = "qcom,pcie-ipq4019", .data = &ops_2_4_0 },
 | |
| --	{ .compatible = "qcom,pcie-qcs404", .data = &ops_2_4_0 },
 | |
| --	{ .compatible = "qcom,pcie-sdm845", .data = &ops_2_7_0 },
 | |
| --	{ .compatible = "qcom,pcie-sm8250", .data = &ops_1_9_0 },
 | |
| -+	{ .compatible = "qcom,pcie-apq8084", .data = &apq8084_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-ipq8064", .data = &ipq8064_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-ipq8064-v2", .data = &ipq8064_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-apq8064", .data = &ipq8064_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-msm8996", .data = &msm8996_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-ipq8074", .data = &ipq8074_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-ipq4019", .data = &ipq4019_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-qcs404", .data = &ipq4019_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-sdm845", .data = &sdm845_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0077-v6.0-PCI-qcom-Add-IPQ60xx-support.patch b/target/linux/ipq807x/patches-5.15/0077-v6.0-PCI-qcom-Add-IPQ60xx-support.patch
 | |
| deleted file mode 100644
 | |
| index 6881ed6d25..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0077-v6.0-PCI-qcom-Add-IPQ60xx-support.patch
 | |
| +++ /dev/null
 | |
| @@ -1,220 +0,0 @@
 | |
| -From a7d96ca20847ade9f29cff4521f43b8ae968b3df Mon Sep 17 00:00:00 2001
 | |
| -From: Selvam Sathappan Periakaruppan <quic_speriaka@quicinc.com>
 | |
| -Date: Tue, 21 Jun 2022 11:54:54 +0300
 | |
| -Subject: [PATCH] PCI: qcom: Add IPQ60xx support
 | |
| -
 | |
| -IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
 | |
| -platform.
 | |
| -
 | |
| -The code is based on downstream[1] Codeaurora kernel v5.4 (branch
 | |
| -win.linuxopenwrt.2.0).
 | |
| -
 | |
| -Split out the DBI registers access part from .init into .post_init. DBI
 | |
| -registers are only accessible after phy_power_on().
 | |
| -
 | |
| -[1] https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-ipq-5.4/
 | |
| -
 | |
| -Link: https://lore.kernel.org/r/f7f848653c99abbf9a0f877949a44e52329543ae.1655799816.git.baruch@tkos.co.il
 | |
| -Tested-by: Robert Marko <robert.marko@sartura.hr>
 | |
| -Signed-off-by: Selvam Sathappan Periakaruppan <quic_speriaka@quicinc.com>
 | |
| -Signed-off-by: Baruch Siach <baruch.siach@siklu.com>
 | |
| -Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
 | |
| -Reviewed-by: Rob Herring <robh@kernel.org>
 | |
| -Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
 | |
| -Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com>
 | |
| ----
 | |
| - drivers/pci/controller/dwc/pcie-designware.h |   1 +
 | |
| - drivers/pci/controller/dwc/pcie-qcom.c       | 130 +++++++++++++++++++
 | |
| - 2 files changed, 131 insertions(+)
 | |
| -
 | |
| ---- a/drivers/pci/controller/dwc/pcie-designware.h
 | |
| -+++ b/drivers/pci/controller/dwc/pcie-designware.h
 | |
| -@@ -76,6 +76,7 @@
 | |
| - 
 | |
| - #define GEN3_RELATED_OFF			0x890
 | |
| - #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
 | |
| -+#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS	BIT(13)
 | |
| - #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
 | |
| - #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
 | |
| - #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
 | |
| ---- a/drivers/pci/controller/dwc/pcie-qcom.c
 | |
| -+++ b/drivers/pci/controller/dwc/pcie-qcom.c
 | |
| -@@ -52,6 +52,10 @@
 | |
| - #define PCIE20_PARF_DBI_BASE_ADDR		0x168
 | |
| - #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE		0x16C
 | |
| - #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL	0x174
 | |
| -+#define AHB_CLK_EN				BIT(0)
 | |
| -+#define MSTR_AXI_CLK_EN				BIT(1)
 | |
| -+#define BYPASS					BIT(4)
 | |
| -+
 | |
| - #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT	0x178
 | |
| - #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2	0x1A8
 | |
| - #define PCIE20_PARF_LTSSM			0x1B0
 | |
| -@@ -181,6 +185,11 @@ struct qcom_pcie_resources_2_7_0 {
 | |
| - 	struct clk *pipe_clk;
 | |
| - };
 | |
| - 
 | |
| -+struct qcom_pcie_resources_2_9_0 {
 | |
| -+	struct clk_bulk_data clks[5];
 | |
| -+	struct reset_control *rst;
 | |
| -+};
 | |
| -+
 | |
| - union qcom_pcie_resources {
 | |
| - 	struct qcom_pcie_resources_1_0_0 v1_0_0;
 | |
| - 	struct qcom_pcie_resources_2_1_0 v2_1_0;
 | |
| -@@ -188,6 +197,7 @@ union qcom_pcie_resources {
 | |
| - 	struct qcom_pcie_resources_2_3_3 v2_3_3;
 | |
| - 	struct qcom_pcie_resources_2_4_0 v2_4_0;
 | |
| - 	struct qcom_pcie_resources_2_7_0 v2_7_0;
 | |
| -+	struct qcom_pcie_resources_2_9_0 v2_9_0;
 | |
| - };
 | |
| - 
 | |
| - struct qcom_pcie;
 | |
| -@@ -1282,6 +1292,112 @@ static void qcom_pcie_post_deinit_2_7_0(
 | |
| - 	clk_disable_unprepare(res->pipe_clk);
 | |
| - }
 | |
| - 
 | |
| -+static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
 | |
| -+{
 | |
| -+	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
 | |
| -+	struct dw_pcie *pci = pcie->pci;
 | |
| -+	struct device *dev = pci->dev;
 | |
| -+	int ret;
 | |
| -+
 | |
| -+	res->clks[0].id = "iface";
 | |
| -+	res->clks[1].id = "axi_m";
 | |
| -+	res->clks[2].id = "axi_s";
 | |
| -+	res->clks[3].id = "axi_bridge";
 | |
| -+	res->clks[4].id = "rchng";
 | |
| -+
 | |
| -+	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
 | |
| -+	if (ret < 0)
 | |
| -+		return ret;
 | |
| -+
 | |
| -+	res->rst = devm_reset_control_array_get_exclusive(dev);
 | |
| -+	if (IS_ERR(res->rst))
 | |
| -+		return PTR_ERR(res->rst);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
 | |
| -+{
 | |
| -+	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
 | |
| -+
 | |
| -+	clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
 | |
| -+}
 | |
| -+
 | |
| -+static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
 | |
| -+{
 | |
| -+	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
 | |
| -+	struct device *dev = pcie->pci->dev;
 | |
| -+	int ret;
 | |
| -+
 | |
| -+	ret = reset_control_assert(res->rst);
 | |
| -+	if (ret) {
 | |
| -+		dev_err(dev, "reset assert failed (%d)\n", ret);
 | |
| -+		return ret;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Delay periods before and after reset deassert are working values
 | |
| -+	 * from downstream Codeaurora kernel
 | |
| -+	 */
 | |
| -+	usleep_range(2000, 2500);
 | |
| -+
 | |
| -+	ret = reset_control_deassert(res->rst);
 | |
| -+	if (ret) {
 | |
| -+		dev_err(dev, "reset deassert failed (%d)\n", ret);
 | |
| -+		return ret;
 | |
| -+	}
 | |
| -+
 | |
| -+	usleep_range(2000, 2500);
 | |
| -+
 | |
| -+	return clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
 | |
| -+}
 | |
| -+
 | |
| -+static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
 | |
| -+{
 | |
| -+	struct dw_pcie *pci = pcie->pci;
 | |
| -+	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
 | |
| -+	u32 val;
 | |
| -+	int i;
 | |
| -+
 | |
| -+	writel(SLV_ADDR_SPACE_SZ,
 | |
| -+		pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
 | |
| -+
 | |
| -+	val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
 | |
| -+	val &= ~BIT(0);
 | |
| -+	writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
 | |
| -+
 | |
| -+	writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
 | |
| -+
 | |
| -+	writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
 | |
| -+	writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
 | |
| -+		pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
 | |
| -+	writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS |
 | |
| -+		GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
 | |
| -+		pci->dbi_base + GEN3_RELATED_OFF);
 | |
| -+
 | |
| -+	writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS |
 | |
| -+		SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
 | |
| -+		AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
 | |
| -+		pcie->parf + PCIE20_PARF_SYS_CTRL);
 | |
| -+
 | |
| -+	writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
 | |
| -+
 | |
| -+	dw_pcie_dbi_ro_wr_en(pci);
 | |
| -+	writel(PCIE_CAP_SLOT_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
 | |
| -+
 | |
| -+	val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
 | |
| -+	val &= ~PCI_EXP_LNKCAP_ASPMS;
 | |
| -+	writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
 | |
| -+
 | |
| -+	writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
 | |
| -+			PCI_EXP_DEVCTL2);
 | |
| -+
 | |
| -+	for (i = 0; i < 256; i++)
 | |
| -+		writel(0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N + (4 * i));
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| - static int qcom_pcie_link_up(struct dw_pcie *pci)
 | |
| - {
 | |
| - 	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
 | |
| -@@ -1473,6 +1589,15 @@ static const struct qcom_pcie_ops ops_1_
 | |
| - 	.config_sid = qcom_pcie_config_sid_sm8250,
 | |
| - };
 | |
| - 
 | |
| -+/* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
 | |
| -+static const struct qcom_pcie_ops ops_2_9_0 = {
 | |
| -+	.get_resources = qcom_pcie_get_resources_2_9_0,
 | |
| -+	.init = qcom_pcie_init_2_9_0,
 | |
| -+	.post_init = qcom_pcie_post_init_2_9_0,
 | |
| -+	.deinit = qcom_pcie_deinit_2_9_0,
 | |
| -+	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
 | |
| -+};
 | |
| -+
 | |
| - static const struct qcom_pcie_cfg apq8084_cfg = {
 | |
| - 	.ops = &ops_1_0_0,
 | |
| - };
 | |
| -@@ -1505,6 +1630,10 @@ static const struct qcom_pcie_cfg sc7280
 | |
| - 	.ops = &ops_1_9_0,
 | |
| - };
 | |
| - 
 | |
| -+static const struct qcom_pcie_cfg ipq6018_cfg = {
 | |
| -+	.ops = &ops_2_9_0,
 | |
| -+};
 | |
| -+
 | |
| - static const struct dw_pcie_ops dw_pcie_ops = {
 | |
| - 	.link_up = qcom_pcie_link_up,
 | |
| - 	.start_link = qcom_pcie_start_link,
 | |
| -@@ -1611,6 +1740,7 @@ static const struct of_device_id qcom_pc
 | |
| - 	{ .compatible = "qcom,pcie-sdm845", .data = &sdm845_cfg },
 | |
| - 	{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
 | |
| - 	{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-ipq6018", .data = &ipq6018_cfg },
 | |
| - 	{ }
 | |
| - };
 | |
| - 
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0078-v5.19-clk-qcom-rcg2-Cache-CFG-register-updates-for-parked-.patch b/target/linux/ipq807x/patches-5.15/0078-v5.19-clk-qcom-rcg2-Cache-CFG-register-updates-for-parked-.patch
 | |
| deleted file mode 100644
 | |
| index 5300c36dce..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0078-v5.19-clk-qcom-rcg2-Cache-CFG-register-updates-for-parked-.patch
 | |
| +++ /dev/null
 | |
| @@ -1,288 +0,0 @@
 | |
| -From e8e7ce92a49dc87f0d006cfbfe419b8e0b25476d Mon Sep 17 00:00:00 2001
 | |
| -From: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Date: Tue, 26 Apr 2022 14:21:36 -0700
 | |
| -Subject: [PATCH] clk: qcom: rcg2: Cache CFG register updates for parked RCGs
 | |
| -
 | |
| -As GDSCs are turned on and off some associated clocks are momentarily
 | |
| -enabled for house keeping purposes. For this, and similar, purposes the
 | |
| -"shared RCGs" will park the RCG on a source clock which is known to be
 | |
| -available.
 | |
| -When the RCG is parked, a safe clock source will be selected and
 | |
| -committed, then the original source would be written back and upon enable
 | |
| -the change back to the unparked source would be committed.
 | |
| -
 | |
| -But starting with SM8350 this fails, as the value in CFG is committed by
 | |
| -the GDSC handshake and without a ticking parent the GDSC enablement will
 | |
| -time out.
 | |
| -
 | |
| -This becomes a concrete problem if the runtime supended state of a
 | |
| -device includes disabling such rcg's parent clock. As the device
 | |
| -attempts to power up the domain again the rcg will fail to enable and
 | |
| -hence the GDSC enablement will fail, preventing the device from
 | |
| -returning from the suspended state.
 | |
| -
 | |
| -This can be seen in e.g. the display stack during probe on SM8350.
 | |
| -
 | |
| -To avoid this problem, the software needs to ensure that the RCG is
 | |
| -configured to a active parent clock while it is disabled. This is done
 | |
| -by caching the CFG register content while the shared RCG is parked on
 | |
| -this safe source.
 | |
| -
 | |
| -Writes to M, N and D registers are committed as they are requested. New
 | |
| -helpers for get_parent() and recalc_rate() are extracted from their
 | |
| -previous implementations and __clk_rcg2_configure() is modified to allow
 | |
| -it to operate on the cached value.
 | |
| -
 | |
| -Fixes: 7ef6f11887bd ("clk: qcom: Configure the RCGs to a safe source as needed")
 | |
| -Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
 | |
| -Reviewed-by: Stephen Boyd <sboyd@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220426212136.1543984-1-bjorn.andersson@linaro.org
 | |
| ----
 | |
| - drivers/clk/qcom/clk-rcg.h  |   2 +
 | |
| - drivers/clk/qcom/clk-rcg2.c | 126 ++++++++++++++++++++++++++++--------
 | |
| - 2 files changed, 101 insertions(+), 27 deletions(-)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/clk-rcg.h
 | |
| -+++ b/drivers/clk/qcom/clk-rcg.h
 | |
| -@@ -139,6 +139,7 @@ extern const struct clk_ops clk_dyn_rcg_
 | |
| -  * @freq_tbl: frequency table
 | |
| -  * @clkr: regmap clock handle
 | |
| -  * @cfg_off: defines the cfg register offset from the CMD_RCGR + CFG_REG
 | |
| -+ * @parked_cfg: cached value of the CFG register for parked RCGs
 | |
| -  */
 | |
| - struct clk_rcg2 {
 | |
| - 	u32			cmd_rcgr;
 | |
| -@@ -149,6 +150,7 @@ struct clk_rcg2 {
 | |
| - 	const struct freq_tbl	*freq_tbl;
 | |
| - 	struct clk_regmap	clkr;
 | |
| - 	u8			cfg_off;
 | |
| -+	u32			parked_cfg;
 | |
| - };
 | |
| - 
 | |
| - #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr)
 | |
| ---- a/drivers/clk/qcom/clk-rcg2.c
 | |
| -+++ b/drivers/clk/qcom/clk-rcg2.c
 | |
| -@@ -74,16 +74,11 @@ static int clk_rcg2_is_enabled(struct cl
 | |
| - 	return (cmd & CMD_ROOT_OFF) == 0;
 | |
| - }
 | |
| - 
 | |
| --static u8 clk_rcg2_get_parent(struct clk_hw *hw)
 | |
| -+static u8 __clk_rcg2_get_parent(struct clk_hw *hw, u32 cfg)
 | |
| - {
 | |
| - 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 | |
| - 	int num_parents = clk_hw_get_num_parents(hw);
 | |
| --	u32 cfg;
 | |
| --	int i, ret;
 | |
| --
 | |
| --	ret = regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
 | |
| --	if (ret)
 | |
| --		goto err;
 | |
| -+	int i;
 | |
| - 
 | |
| - 	cfg &= CFG_SRC_SEL_MASK;
 | |
| - 	cfg >>= CFG_SRC_SEL_SHIFT;
 | |
| -@@ -92,12 +87,27 @@ static u8 clk_rcg2_get_parent(struct clk
 | |
| - 		if (cfg == rcg->parent_map[i].cfg)
 | |
| - 			return i;
 | |
| - 
 | |
| --err:
 | |
| - 	pr_debug("%s: Clock %s has invalid parent, using default.\n",
 | |
| - 		 __func__, clk_hw_get_name(hw));
 | |
| - 	return 0;
 | |
| - }
 | |
| - 
 | |
| -+static u8 clk_rcg2_get_parent(struct clk_hw *hw)
 | |
| -+{
 | |
| -+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 | |
| -+	u32 cfg;
 | |
| -+	int ret;
 | |
| -+
 | |
| -+	ret = regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
 | |
| -+	if (ret) {
 | |
| -+		pr_debug("%s: Unable to read CFG register for %s\n",
 | |
| -+			 __func__, clk_hw_get_name(hw));
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	return __clk_rcg2_get_parent(hw, cfg);
 | |
| -+}
 | |
| -+
 | |
| - static int update_config(struct clk_rcg2 *rcg)
 | |
| - {
 | |
| - 	int count, ret;
 | |
| -@@ -164,12 +174,10 @@ calc_rate(unsigned long rate, u32 m, u32
 | |
| - }
 | |
| - 
 | |
| - static unsigned long
 | |
| --clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 | |
| -+__clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate, u32 cfg)
 | |
| - {
 | |
| - 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 | |
| --	u32 cfg, hid_div, m = 0, n = 0, mode = 0, mask;
 | |
| --
 | |
| --	regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
 | |
| -+	u32 hid_div, m = 0, n = 0, mode = 0, mask;
 | |
| - 
 | |
| - 	if (rcg->mnd_width) {
 | |
| - 		mask = BIT(rcg->mnd_width) - 1;
 | |
| -@@ -190,6 +198,17 @@ clk_rcg2_recalc_rate(struct clk_hw *hw,
 | |
| - 	return calc_rate(parent_rate, m, n, mode, hid_div);
 | |
| - }
 | |
| - 
 | |
| -+static unsigned long
 | |
| -+clk_rcg2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 | |
| -+{
 | |
| -+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 | |
| -+	u32 cfg;
 | |
| -+
 | |
| -+	regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
 | |
| -+
 | |
| -+	return __clk_rcg2_recalc_rate(hw, parent_rate, cfg);
 | |
| -+}
 | |
| -+
 | |
| - static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f,
 | |
| - 				    struct clk_rate_request *req,
 | |
| - 				    enum freq_policy policy)
 | |
| -@@ -263,7 +282,8 @@ static int clk_rcg2_determine_floor_rate
 | |
| - 	return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, FLOOR);
 | |
| - }
 | |
| - 
 | |
| --static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
 | |
| -+static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f,
 | |
| -+				u32 *_cfg)
 | |
| - {
 | |
| - 	u32 cfg, mask, d_val, not2d_val, n_minus_m;
 | |
| - 	struct clk_hw *hw = &rcg->clkr.hw;
 | |
| -@@ -305,15 +325,27 @@ static int __clk_rcg2_configure(struct c
 | |
| - 	cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
 | |
| - 	if (rcg->mnd_width && f->n && (f->m != f->n))
 | |
| - 		cfg |= CFG_MODE_DUAL_EDGE;
 | |
| --	return regmap_update_bits(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg),
 | |
| --					mask, cfg);
 | |
| -+
 | |
| -+	*_cfg &= ~mask;
 | |
| -+	*_cfg |= cfg;
 | |
| -+
 | |
| -+	return 0;
 | |
| - }
 | |
| - 
 | |
| - static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
 | |
| - {
 | |
| -+	u32 cfg;
 | |
| - 	int ret;
 | |
| - 
 | |
| --	ret = __clk_rcg2_configure(rcg, f);
 | |
| -+	ret = regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
 | |
| -+	if (ret)
 | |
| -+		return ret;
 | |
| -+
 | |
| -+	ret = __clk_rcg2_configure(rcg, f, &cfg);
 | |
| -+	if (ret)
 | |
| -+		return ret;
 | |
| -+
 | |
| -+	ret = regmap_write(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), cfg);
 | |
| - 	if (ret)
 | |
| - 		return ret;
 | |
| - 
 | |
| -@@ -994,11 +1026,12 @@ static int clk_rcg2_shared_set_rate(stru
 | |
| - 		return -EINVAL;
 | |
| - 
 | |
| - 	/*
 | |
| --	 * In case clock is disabled, update the CFG, M, N and D registers
 | |
| --	 * and don't hit the update bit of CMD register.
 | |
| -+	 * In case clock is disabled, update the M, N and D registers, cache
 | |
| -+	 * the CFG value in parked_cfg and don't hit the update bit of CMD
 | |
| -+	 * register.
 | |
| - 	 */
 | |
| --	if (!__clk_is_enabled(hw->clk))
 | |
| --		return __clk_rcg2_configure(rcg, f);
 | |
| -+	if (!clk_hw_is_enabled(hw))
 | |
| -+		return __clk_rcg2_configure(rcg, f, &rcg->parked_cfg);
 | |
| - 
 | |
| - 	return clk_rcg2_shared_force_enable_clear(hw, f);
 | |
| - }
 | |
| -@@ -1022,6 +1055,11 @@ static int clk_rcg2_shared_enable(struct
 | |
| - 	if (ret)
 | |
| - 		return ret;
 | |
| - 
 | |
| -+	/* Write back the stored configuration corresponding to current rate */
 | |
| -+	ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, rcg->parked_cfg);
 | |
| -+	if (ret)
 | |
| -+		return ret;
 | |
| -+
 | |
| - 	ret = update_config(rcg);
 | |
| - 	if (ret)
 | |
| - 		return ret;
 | |
| -@@ -1032,13 +1070,12 @@ static int clk_rcg2_shared_enable(struct
 | |
| - static void clk_rcg2_shared_disable(struct clk_hw *hw)
 | |
| - {
 | |
| - 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 | |
| --	u32 cfg;
 | |
| - 
 | |
| - 	/*
 | |
| - 	 * Store current configuration as switching to safe source would clear
 | |
| - 	 * the SRC and DIV of CFG register
 | |
| - 	 */
 | |
| --	regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
 | |
| -+	regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &rcg->parked_cfg);
 | |
| - 
 | |
| - 	/*
 | |
| - 	 * Park the RCG at a safe configuration - sourced off of safe source.
 | |
| -@@ -1056,17 +1093,52 @@ static void clk_rcg2_shared_disable(stru
 | |
| - 	update_config(rcg);
 | |
| - 
 | |
| - 	clk_rcg2_clear_force_enable(hw);
 | |
| -+}
 | |
| - 
 | |
| --	/* Write back the stored configuration corresponding to current rate */
 | |
| --	regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
 | |
| -+static u8 clk_rcg2_shared_get_parent(struct clk_hw *hw)
 | |
| -+{
 | |
| -+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 | |
| -+
 | |
| -+	/* If the shared rcg is parked use the cached cfg instead */
 | |
| -+	if (!clk_hw_is_enabled(hw))
 | |
| -+		return __clk_rcg2_get_parent(hw, rcg->parked_cfg);
 | |
| -+
 | |
| -+	return clk_rcg2_get_parent(hw);
 | |
| -+}
 | |
| -+
 | |
| -+static int clk_rcg2_shared_set_parent(struct clk_hw *hw, u8 index)
 | |
| -+{
 | |
| -+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 | |
| -+
 | |
| -+	/* If the shared rcg is parked only update the cached cfg */
 | |
| -+	if (!clk_hw_is_enabled(hw)) {
 | |
| -+		rcg->parked_cfg &= ~CFG_SRC_SEL_MASK;
 | |
| -+		rcg->parked_cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
 | |
| -+
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	return clk_rcg2_set_parent(hw, index);
 | |
| -+}
 | |
| -+
 | |
| -+static unsigned long
 | |
| -+clk_rcg2_shared_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 | |
| -+{
 | |
| -+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 | |
| -+
 | |
| -+	/* If the shared rcg is parked use the cached cfg instead */
 | |
| -+	if (!clk_hw_is_enabled(hw))
 | |
| -+		return __clk_rcg2_recalc_rate(hw, parent_rate, rcg->parked_cfg);
 | |
| -+
 | |
| -+	return clk_rcg2_recalc_rate(hw, parent_rate);
 | |
| - }
 | |
| - 
 | |
| - const struct clk_ops clk_rcg2_shared_ops = {
 | |
| - 	.enable = clk_rcg2_shared_enable,
 | |
| - 	.disable = clk_rcg2_shared_disable,
 | |
| --	.get_parent = clk_rcg2_get_parent,
 | |
| --	.set_parent = clk_rcg2_set_parent,
 | |
| --	.recalc_rate = clk_rcg2_recalc_rate,
 | |
| -+	.get_parent = clk_rcg2_shared_get_parent,
 | |
| -+	.set_parent = clk_rcg2_shared_set_parent,
 | |
| -+	.recalc_rate = clk_rcg2_shared_recalc_rate,
 | |
| - 	.determine_rate = clk_rcg2_determine_rate,
 | |
| - 	.set_rate = clk_rcg2_shared_set_rate,
 | |
| - 	.set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent,
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0079-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch b/target/linux/ipq807x/patches-5.15/0079-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch
 | |
| deleted file mode 100644
 | |
| index 3319f431ba..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0079-v6.2-dt-bindings-arm-qcom-document-qcom-msm-id-and-qcom-b.patch
 | |
| +++ /dev/null
 | |
| @@ -1,207 +0,0 @@
 | |
| -From 77faa07c185c969e742cbb3e6aa487a11b0b616c Mon Sep 17 00:00:00 2001
 | |
| -From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Date: Tue, 30 Aug 2022 09:57:42 +0300
 | |
| -Subject: [PATCH] dt-bindings: arm: qcom: document qcom,msm-id and
 | |
| - qcom,board-id
 | |
| -
 | |
| -The top level qcom,msm-id and qcom,board-id properties are utilized by
 | |
| -bootloaders on Qualcomm MSM platforms to determine which device tree
 | |
| -should be used and passed to the kernel.
 | |
| -
 | |
| -The commit b32e592d3c28 ("devicetree: bindings: Document qcom board
 | |
| -compatible format") from 2015 was a consensus during discussion about
 | |
| -upstreaming qcom,msm-id and qcom,board-id fields.  There are however still
 | |
| -problems with that consensus:
 | |
| -1. It was reached 7 years ago but it turned out its implementation did
 | |
| -   not reach all possible products.
 | |
| -
 | |
| -2. Initially additional tool (dtbTool) was needed for parsing these
 | |
| -   fields to create a QCDT image consisting of multiple DTBs, later the
 | |
| -   bootloaders were improved and they use these qcom,msm-id and
 | |
| -   qcom,board-id properties directly.
 | |
| -
 | |
| -3. Extracting relevant information from the board compatible requires
 | |
| -   this additional tool (dtbTool), which makes the build process more
 | |
| -   complicated and not easily reproducible (DTBs are modified after the
 | |
| -   kernel build).
 | |
| -
 | |
| -4. Some versions of Qualcomm bootloaders expect these properties even
 | |
| -   when booting with a single DTB.  The community is stuck with these
 | |
| -   bootloaders thus they require properties in the DTBs.
 | |
| -
 | |
| -Since several upstreamed Qualcomm SoC-based boards require these
 | |
| -properties to properly boot and the properties are reportedly used by
 | |
| -bootloaders, document them along with the bindings header with constants
 | |
| -used by: bootloader, some DTS and socinfo driver.
 | |
| -
 | |
| -Link: https://lore.kernel.org/r/a3c932d1-a102-ce18-deea-18cbbd05ecab@linaro.org/
 | |
| -Co-developed-by: Kumar Gala <galak@codeaurora.org>
 | |
| -Signed-off-by: Kumar Gala <galak@codeaurora.org>
 | |
| -Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
 | |
| -Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
 | |
| -Reviewed-by: Rob Herring <robh@kernel.org>
 | |
| -Signed-off-by: Bjorn Andersson <andersson@kernel.org>
 | |
| -Link: https://lore.kernel.org/r/20220830065744.161163-2-krzysztof.kozlowski@linaro.org
 | |
| ----
 | |
| - include/dt-bindings/arm/qcom,ids.h | 155 +++++++++++++++++++++++++++++
 | |
| - 1 file changed, 155 insertions(+)
 | |
| - create mode 100644 include/dt-bindings/arm/qcom,ids.h
 | |
| -
 | |
| ---- /dev/null
 | |
| -+++ b/include/dt-bindings/arm/qcom,ids.h
 | |
| -@@ -0,0 +1,155 @@
 | |
| -+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
 | |
| -+/*
 | |
| -+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
 | |
| -+ * Copyright (c) 2022 Linaro Ltd
 | |
| -+ * Author: Krzysztof Kozlowski <krzk@kernel.org> based on previous work of Kumar Gala.
 | |
| -+ */
 | |
| -+#ifndef _DT_BINDINGS_ARM_QCOM_IDS_H
 | |
| -+#define _DT_BINDINGS_ARM_QCOM_IDS_H
 | |
| -+
 | |
| -+/*
 | |
| -+ * The MSM chipset and hardware revision used by Qualcomm bootloaders, DTS for
 | |
| -+ * older chipsets (qcom,msm-id) and in socinfo driver:
 | |
| -+ */
 | |
| -+#define QCOM_ID_MSM8960			87
 | |
| -+#define QCOM_ID_APQ8064			109
 | |
| -+#define QCOM_ID_MSM8660A		122
 | |
| -+#define QCOM_ID_MSM8260A		123
 | |
| -+#define QCOM_ID_APQ8060A		124
 | |
| -+#define QCOM_ID_MSM8974			126
 | |
| -+#define QCOM_ID_MPQ8064			130
 | |
| -+#define QCOM_ID_MSM8960AB		138
 | |
| -+#define QCOM_ID_APQ8060AB		139
 | |
| -+#define QCOM_ID_MSM8260AB		140
 | |
| -+#define QCOM_ID_MSM8660AB		141
 | |
| -+#define QCOM_ID_MSM8626			145
 | |
| -+#define QCOM_ID_MSM8610			147
 | |
| -+#define QCOM_ID_APQ8064AB		153
 | |
| -+#define QCOM_ID_MSM8226			158
 | |
| -+#define QCOM_ID_MSM8526			159
 | |
| -+#define QCOM_ID_MSM8110			161
 | |
| -+#define QCOM_ID_MSM8210			162
 | |
| -+#define QCOM_ID_MSM8810			163
 | |
| -+#define QCOM_ID_MSM8212			164
 | |
| -+#define QCOM_ID_MSM8612			165
 | |
| -+#define QCOM_ID_MSM8112			166
 | |
| -+#define QCOM_ID_MSM8225Q		168
 | |
| -+#define QCOM_ID_MSM8625Q		169
 | |
| -+#define QCOM_ID_MSM8125Q		170
 | |
| -+#define QCOM_ID_APQ8064AA		172
 | |
| -+#define QCOM_ID_APQ8084			178
 | |
| -+#define QCOM_ID_APQ8074			184
 | |
| -+#define QCOM_ID_MSM8274			185
 | |
| -+#define QCOM_ID_MSM8674			186
 | |
| -+#define QCOM_ID_MSM8974PRO_AC		194
 | |
| -+#define QCOM_ID_MSM8126			198
 | |
| -+#define QCOM_ID_APQ8026			199
 | |
| -+#define QCOM_ID_MSM8926			200
 | |
| -+#define QCOM_ID_MSM8326			205
 | |
| -+#define QCOM_ID_MSM8916			206
 | |
| -+#define QCOM_ID_MSM8994			207
 | |
| -+#define QCOM_ID_APQ8074PRO_AA		208
 | |
| -+#define QCOM_ID_APQ8074PRO_AB		209
 | |
| -+#define QCOM_ID_APQ8074PRO_AC		210
 | |
| -+#define QCOM_ID_MSM8274PRO_AA		211
 | |
| -+#define QCOM_ID_MSM8274PRO_AB		212
 | |
| -+#define QCOM_ID_MSM8274PRO_AC		213
 | |
| -+#define QCOM_ID_MSM8674PRO_AA		214
 | |
| -+#define QCOM_ID_MSM8674PRO_AB		215
 | |
| -+#define QCOM_ID_MSM8674PRO_AC		216
 | |
| -+#define QCOM_ID_MSM8974PRO_AA		217
 | |
| -+#define QCOM_ID_MSM8974PRO_AB		218
 | |
| -+#define QCOM_ID_APQ8028			219
 | |
| -+#define QCOM_ID_MSM8128			220
 | |
| -+#define QCOM_ID_MSM8228			221
 | |
| -+#define QCOM_ID_MSM8528			222
 | |
| -+#define QCOM_ID_MSM8628			223
 | |
| -+#define QCOM_ID_MSM8928			224
 | |
| -+#define QCOM_ID_MSM8510			225
 | |
| -+#define QCOM_ID_MSM8512			226
 | |
| -+#define QCOM_ID_MSM8936			233
 | |
| -+#define QCOM_ID_MSM8939			239
 | |
| -+#define QCOM_ID_APQ8036			240
 | |
| -+#define QCOM_ID_APQ8039			241
 | |
| -+#define QCOM_ID_MSM8996			246
 | |
| -+#define QCOM_ID_APQ8016			247
 | |
| -+#define QCOM_ID_MSM8216			248
 | |
| -+#define QCOM_ID_MSM8116			249
 | |
| -+#define QCOM_ID_MSM8616			250
 | |
| -+#define QCOM_ID_MSM8992			251
 | |
| -+#define QCOM_ID_APQ8094			253
 | |
| -+#define QCOM_ID_MDM9607			290
 | |
| -+#define QCOM_ID_APQ8096			291
 | |
| -+#define QCOM_ID_MSM8998			292
 | |
| -+#define QCOM_ID_MSM8953			293
 | |
| -+#define QCOM_ID_MDM8207			296
 | |
| -+#define QCOM_ID_MDM9207			297
 | |
| -+#define QCOM_ID_MDM9307			298
 | |
| -+#define QCOM_ID_MDM9628			299
 | |
| -+#define QCOM_ID_APQ8053			304
 | |
| -+#define QCOM_ID_MSM8996SG		305
 | |
| -+#define QCOM_ID_MSM8996AU		310
 | |
| -+#define QCOM_ID_APQ8096AU		311
 | |
| -+#define QCOM_ID_APQ8096SG		312
 | |
| -+#define QCOM_ID_SDM660			317
 | |
| -+#define QCOM_ID_SDM630			318
 | |
| -+#define QCOM_ID_APQ8098			319
 | |
| -+#define QCOM_ID_SDM845			321
 | |
| -+#define QCOM_ID_MDM9206			322
 | |
| -+#define QCOM_ID_IPQ8074			323
 | |
| -+#define QCOM_ID_SDA660			324
 | |
| -+#define QCOM_ID_SDM658			325
 | |
| -+#define QCOM_ID_SDA658			326
 | |
| -+#define QCOM_ID_SDA630			327
 | |
| -+#define QCOM_ID_SDM450			338
 | |
| -+#define QCOM_ID_SDA845			341
 | |
| -+#define QCOM_ID_IPQ8072			342
 | |
| -+#define QCOM_ID_IPQ8076			343
 | |
| -+#define QCOM_ID_IPQ8078			344
 | |
| -+#define QCOM_ID_SDM636			345
 | |
| -+#define QCOM_ID_SDA636			346
 | |
| -+#define QCOM_ID_SDM632			349
 | |
| -+#define QCOM_ID_SDA632			350
 | |
| -+#define QCOM_ID_SDA450			351
 | |
| -+#define QCOM_ID_SM8250			356
 | |
| -+#define QCOM_ID_IPQ8070			375
 | |
| -+#define QCOM_ID_IPQ8071			376
 | |
| -+#define QCOM_ID_IPQ8072A		389
 | |
| -+#define QCOM_ID_IPQ8074A		390
 | |
| -+#define QCOM_ID_IPQ8076A		391
 | |
| -+#define QCOM_ID_IPQ8078A		392
 | |
| -+#define QCOM_ID_SM6125			394
 | |
| -+#define QCOM_ID_IPQ8070A		395
 | |
| -+#define QCOM_ID_IPQ8071A		396
 | |
| -+#define QCOM_ID_IPQ6018			402
 | |
| -+#define QCOM_ID_IPQ6028			403
 | |
| -+#define QCOM_ID_IPQ6000			421
 | |
| -+#define QCOM_ID_IPQ6010			422
 | |
| -+#define QCOM_ID_SC7180			425
 | |
| -+#define QCOM_ID_SM6350			434
 | |
| -+#define QCOM_ID_SM8350			439
 | |
| -+#define QCOM_ID_SC8280XP		449
 | |
| -+#define QCOM_ID_IPQ6005			453
 | |
| -+#define QCOM_ID_QRB5165			455
 | |
| -+#define QCOM_ID_SM8450			457
 | |
| -+#define QCOM_ID_SM7225			459
 | |
| -+#define QCOM_ID_SA8295P			460
 | |
| -+#define QCOM_ID_SA8540P			461
 | |
| -+#define QCOM_ID_SM8450_2		480
 | |
| -+#define QCOM_ID_SM8450_3		482
 | |
| -+#define QCOM_ID_SC7280			487
 | |
| -+#define QCOM_ID_SC7180P			495
 | |
| -+#define QCOM_ID_SM6375			507
 | |
| -+
 | |
| -+/*
 | |
| -+ * The board type and revision information, used by Qualcomm bootloaders and
 | |
| -+ * DTS for older chipsets (qcom,board-id):
 | |
| -+ */
 | |
| -+#define QCOM_BOARD_ID(a, major, minor) \
 | |
| -+	(((major & 0xff) << 16) | ((minor & 0xff) << 8) | QCOM_BOARD_ID_##a)
 | |
| -+
 | |
| -+#define QCOM_BOARD_ID_MTP			8
 | |
| -+#define QCOM_BOARD_ID_DRAGONBOARD		10
 | |
| -+#define QCOM_BOARD_ID_SBC			24
 | |
| -+
 | |
| -+#endif /* _DT_BINDINGS_ARM_QCOM_IDS_H */
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0100-clk-qcom-clk-rcg2-introduce-support-for-multiple-con.patch b/target/linux/ipq807x/patches-5.15/0100-clk-qcom-clk-rcg2-introduce-support-for-multiple-con.patch
 | |
| deleted file mode 100644
 | |
| index 5713775948..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0100-clk-qcom-clk-rcg2-introduce-support-for-multiple-con.patch
 | |
| +++ /dev/null
 | |
| @@ -1,203 +0,0 @@
 | |
| -From 032be4f49dda786fea9e1501212f6cd09a7ded96 Mon Sep 17 00:00:00 2001
 | |
| -From: Christian Marangi <ansuelsmth@gmail.com>
 | |
| -Date: Thu, 3 Nov 2022 14:49:43 +0100
 | |
| -Subject: [PATCH] clk: qcom: clk-rcg2: introduce support for multiple conf for
 | |
| - same freq
 | |
| -
 | |
| -Some RCG frequency can be reached by multiple configuration.
 | |
| -
 | |
| -We currently declare multiple configuration for the same frequency but
 | |
| -that is not supported and always the first configuration will be taken.
 | |
| -
 | |
| -These multiple configuration are needed as based on the current parent
 | |
| -configuration, it may be needed to use a different configuration to
 | |
| -reach the same frequency.
 | |
| -
 | |
| -To handle this introduce 2 new macro, FM and C.
 | |
| -
 | |
| -- FM is used to declare an empty freq_tbl with just the frequency and an
 | |
| -  array of confs to insert all the config for the provided frequency.
 | |
| -
 | |
| -- C is used to declare a fre_conf where src, pre_div, m and n are
 | |
| -  provided.
 | |
| -
 | |
| -The driver is changed to handle this special freq_tbl and select the
 | |
| -correct config by calculating the final rate and deciding based on the
 | |
| -one that is less different than the requested one.
 | |
| -
 | |
| -Tested-by: Robert Marko <robimarko@gmail.com>
 | |
| -Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 | |
| ----
 | |
| - drivers/clk/qcom/clk-rcg.h  | 14 ++++++-
 | |
| - drivers/clk/qcom/clk-rcg2.c | 84 +++++++++++++++++++++++++++++++++----
 | |
| - 2 files changed, 88 insertions(+), 10 deletions(-)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/clk-rcg.h
 | |
| -+++ b/drivers/clk/qcom/clk-rcg.h
 | |
| -@@ -7,7 +7,17 @@
 | |
| - #include <linux/clk-provider.h>
 | |
| - #include "clk-regmap.h"
 | |
| - 
 | |
| --#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
 | |
| -+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n), 0, NULL }
 | |
| -+
 | |
| -+#define FM(_f, _confs) { .freq = (_f), .confs_num = ARRAY_SIZE(_confs), .confs = (_confs) }
 | |
| -+#define C(s, h, m, n) { (s), (2 * (h) - 1), (m), (n) }
 | |
| -+
 | |
| -+struct freq_conf {
 | |
| -+	u8 src;
 | |
| -+	u8 pre_div;
 | |
| -+	u16 m;
 | |
| -+	u16 n;
 | |
| -+};
 | |
| - 
 | |
| - struct freq_tbl {
 | |
| - 	unsigned long freq;
 | |
| -@@ -15,6 +25,8 @@ struct freq_tbl {
 | |
| - 	u8 pre_div;
 | |
| - 	u16 m;
 | |
| - 	u16 n;
 | |
| -+	int confs_num;
 | |
| -+	const struct freq_conf *confs;
 | |
| - };
 | |
| - 
 | |
| - /**
 | |
| ---- a/drivers/clk/qcom/clk-rcg2.c
 | |
| -+++ b/drivers/clk/qcom/clk-rcg2.c
 | |
| -@@ -209,11 +209,60 @@ clk_rcg2_recalc_rate(struct clk_hw *hw,
 | |
| - 	return __clk_rcg2_recalc_rate(hw, parent_rate, cfg);
 | |
| - }
 | |
| - 
 | |
| -+static void
 | |
| -+clk_rcg2_select_conf(struct clk_hw *hw, struct freq_tbl *f_tbl,
 | |
| -+		     const struct freq_tbl *f, unsigned long req_rate)
 | |
| -+{
 | |
| -+	unsigned long best_rate = 0, parent_rate, rate;
 | |
| -+	const struct freq_conf *conf, *best_conf;
 | |
| -+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 | |
| -+	struct clk_hw *p;
 | |
| -+	int index, i;
 | |
| -+
 | |
| -+	/* Search in each provided config the one that is near the wanted rate */
 | |
| -+	for (i = 0, conf = f->confs; i < f->confs_num; i++, conf++) {
 | |
| -+		index = qcom_find_src_index(hw, rcg->parent_map, conf->src);
 | |
| -+		if (index < 0)
 | |
| -+			continue;
 | |
| -+
 | |
| -+		p = clk_hw_get_parent_by_index(hw, index);
 | |
| -+		if (!p)
 | |
| -+			continue;
 | |
| -+
 | |
| -+		parent_rate =  clk_hw_get_rate(p);
 | |
| -+		rate = calc_rate(parent_rate, conf->n, conf->m, conf->n, conf->pre_div);
 | |
| -+
 | |
| -+		if (rate == req_rate) {
 | |
| -+			best_conf = conf;
 | |
| -+			break;
 | |
| -+		}
 | |
| -+
 | |
| -+		if (abs(req_rate - rate) < abs(best_rate - rate)) {
 | |
| -+			best_rate = rate;
 | |
| -+			best_conf = conf;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Very unlikely.
 | |
| -+	 * Force the first conf if we can't find a correct config.
 | |
| -+	 */
 | |
| -+	if (unlikely(i == f->confs_num))
 | |
| -+		best_conf = f->confs;
 | |
| -+
 | |
| -+	/* Apply the config */
 | |
| -+	f_tbl->src = best_conf->src;
 | |
| -+	f_tbl->pre_div = best_conf->pre_div;
 | |
| -+	f_tbl->m = best_conf->m;
 | |
| -+	f_tbl->n = best_conf->n;
 | |
| -+}
 | |
| -+
 | |
| - static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f,
 | |
| - 				    struct clk_rate_request *req,
 | |
| - 				    enum freq_policy policy)
 | |
| - {
 | |
| - 	unsigned long clk_flags, rate = req->rate;
 | |
| -+	struct freq_tbl f_tbl;
 | |
| - 	struct clk_hw *p;
 | |
| - 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 | |
| - 	int index;
 | |
| -@@ -232,7 +281,15 @@ static int _freq_tbl_determine_rate(stru
 | |
| - 	if (!f)
 | |
| - 		return -EINVAL;
 | |
| - 
 | |
| --	index = qcom_find_src_index(hw, rcg->parent_map, f->src);
 | |
| -+	f_tbl = *f;
 | |
| -+	/*
 | |
| -+	 * A single freq may be reached by multiple configuration.
 | |
| -+	 * Try to find the bast one if we have this kind of freq_table.
 | |
| -+	 */
 | |
| -+	if (f->confs)
 | |
| -+		clk_rcg2_select_conf(hw, &f_tbl, f, rate);
 | |
| -+
 | |
| -+	index = qcom_find_src_index(hw, rcg->parent_map, f_tbl.src);
 | |
| - 	if (index < 0)
 | |
| - 		return index;
 | |
| - 
 | |
| -@@ -242,18 +299,18 @@ static int _freq_tbl_determine_rate(stru
 | |
| - 		return -EINVAL;
 | |
| - 
 | |
| - 	if (clk_flags & CLK_SET_RATE_PARENT) {
 | |
| --		rate = f->freq;
 | |
| --		if (f->pre_div) {
 | |
| -+		rate = f_tbl.freq;
 | |
| -+		if (f_tbl.pre_div) {
 | |
| - 			if (!rate)
 | |
| - 				rate = req->rate;
 | |
| - 			rate /= 2;
 | |
| --			rate *= f->pre_div + 1;
 | |
| -+			rate *= f_tbl.pre_div + 1;
 | |
| - 		}
 | |
| - 
 | |
| --		if (f->n) {
 | |
| -+		if (f_tbl.n) {
 | |
| - 			u64 tmp = rate;
 | |
| --			tmp = tmp * f->n;
 | |
| --			do_div(tmp, f->m);
 | |
| -+			tmp = tmp * f_tbl.n;
 | |
| -+			do_div(tmp, f_tbl.m);
 | |
| - 			rate = tmp;
 | |
| - 		}
 | |
| - 	} else {
 | |
| -@@ -261,7 +318,7 @@ static int _freq_tbl_determine_rate(stru
 | |
| - 	}
 | |
| - 	req->best_parent_hw = p;
 | |
| - 	req->best_parent_rate = rate;
 | |
| --	req->rate = f->freq;
 | |
| -+	req->rate = f_tbl.freq;
 | |
| - 
 | |
| - 	return 0;
 | |
| - }
 | |
| -@@ -357,6 +414,7 @@ static int __clk_rcg2_set_rate(struct cl
 | |
| - {
 | |
| - 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 | |
| - 	const struct freq_tbl *f;
 | |
| -+	struct freq_tbl f_tbl;
 | |
| - 
 | |
| - 	switch (policy) {
 | |
| - 	case FLOOR:
 | |
| -@@ -372,7 +430,15 @@ static int __clk_rcg2_set_rate(struct cl
 | |
| - 	if (!f)
 | |
| - 		return -EINVAL;
 | |
| - 
 | |
| --	return clk_rcg2_configure(rcg, f);
 | |
| -+	f_tbl = *f;
 | |
| -+	/*
 | |
| -+	 * A single freq may be reached by multiple configuration.
 | |
| -+	 * Try to find the best one if we have this kind of freq_table.
 | |
| -+	 */
 | |
| -+	if (f->confs)
 | |
| -+		clk_rcg2_select_conf(hw, &f_tbl, f, rate);
 | |
| -+
 | |
| -+	return clk_rcg2_configure(rcg, &f_tbl);
 | |
| - }
 | |
| - 
 | |
| - static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0101-clk-qcom-gcc-ipq8074-rework-nss_port5-6-clock-to-mul.patch b/target/linux/ipq807x/patches-5.15/0101-clk-qcom-gcc-ipq8074-rework-nss_port5-6-clock-to-mul.patch
 | |
| deleted file mode 100644
 | |
| index 32fb2d9d87..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0101-clk-qcom-gcc-ipq8074-rework-nss_port5-6-clock-to-mul.patch
 | |
| +++ /dev/null
 | |
| @@ -1,129 +0,0 @@
 | |
| -From f778553f296792f4d1e8b3552603ad6116ea3eb3 Mon Sep 17 00:00:00 2001
 | |
| -From: Christian Marangi <ansuelsmth@gmail.com>
 | |
| -Date: Thu, 3 Nov 2022 14:49:44 +0100
 | |
| -Subject: [PATCH] clk: qcom: gcc-ipq8074: rework nss_port5/6 clock to multiple
 | |
| - conf
 | |
| -
 | |
| -Rework nss_port5/6 to use the new multiple configuration implementation
 | |
| -and correctly fix the clocks for these port under some corner case.
 | |
| -
 | |
| -This is particularly relevant for device that have 2.5G or 10G port
 | |
| -connected to port5 or port 6 on ipq8074. As the parent are shared
 | |
| -across multiple port it may be required to select the correct
 | |
| -configuration to accomplish the desired clock. Without this patch such
 | |
| -port doesn't work in some specific ethernet speed as the clock will be
 | |
| -set to the wrong frequency as we just select the first configuration for
 | |
| -the related frequency instead of selecting the best one.
 | |
| -
 | |
| -Tested-by: Robert Marko <robimarko@gmail.com> # ipq8074 Qnap QHora-301W
 | |
| -Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
 | |
| ----
 | |
| - drivers/clk/qcom/gcc-ipq8074.c | 64 +++++++++++++++++++++++++---------
 | |
| - 1 file changed, 48 insertions(+), 16 deletions(-)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -+++ b/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -@@ -1682,13 +1682,21 @@ static struct clk_regmap_div nss_port4_t
 | |
| - 	},
 | |
| - };
 | |
| - 
 | |
| -+static const struct freq_conf ftbl_nss_port5_rx_clk_src_25[] = {
 | |
| -+	C(P_UNIPHY1_RX, 12.5, 0, 0),
 | |
| -+	C(P_UNIPHY0_RX, 5, 0, 0),
 | |
| -+};
 | |
| -+
 | |
| -+static const struct freq_conf ftbl_nss_port5_rx_clk_src_125[] = {
 | |
| -+	C(P_UNIPHY1_RX, 2.5, 0, 0),
 | |
| -+	C(P_UNIPHY0_RX, 1, 0, 0),
 | |
| -+};
 | |
| -+
 | |
| - static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = {
 | |
| - 	F(19200000, P_XO, 1, 0, 0),
 | |
| --	F(25000000, P_UNIPHY1_RX, 12.5, 0, 0),
 | |
| --	F(25000000, P_UNIPHY0_RX, 5, 0, 0),
 | |
| -+	FM(25000000, ftbl_nss_port5_rx_clk_src_25),
 | |
| - 	F(78125000, P_UNIPHY1_RX, 4, 0, 0),
 | |
| --	F(125000000, P_UNIPHY1_RX, 2.5, 0, 0),
 | |
| --	F(125000000, P_UNIPHY0_RX, 1, 0, 0),
 | |
| -+	FM(125000000, ftbl_nss_port5_rx_clk_src_125),
 | |
| - 	F(156250000, P_UNIPHY1_RX, 2, 0, 0),
 | |
| - 	F(312500000, P_UNIPHY1_RX, 1, 0, 0),
 | |
| - 	{ }
 | |
| -@@ -1744,13 +1752,21 @@ static struct clk_regmap_div nss_port5_r
 | |
| - 	},
 | |
| - };
 | |
| - 
 | |
| -+static struct freq_conf ftbl_nss_port5_tx_clk_src_25[] = {
 | |
| -+	C(P_UNIPHY1_TX, 12.5, 0, 0),
 | |
| -+	C(P_UNIPHY0_TX, 5, 0, 0),
 | |
| -+};
 | |
| -+
 | |
| -+static struct freq_conf ftbl_nss_port5_tx_clk_src_125[] = {
 | |
| -+	C(P_UNIPHY1_TX, 2.5, 0, 0),
 | |
| -+	C(P_UNIPHY0_TX, 1, 0, 0),
 | |
| -+};
 | |
| -+
 | |
| - static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = {
 | |
| - 	F(19200000, P_XO, 1, 0, 0),
 | |
| --	F(25000000, P_UNIPHY1_TX, 12.5, 0, 0),
 | |
| --	F(25000000, P_UNIPHY0_TX, 5, 0, 0),
 | |
| -+	FM(25000000, ftbl_nss_port5_tx_clk_src_25),
 | |
| - 	F(78125000, P_UNIPHY1_TX, 4, 0, 0),
 | |
| --	F(125000000, P_UNIPHY1_TX, 2.5, 0, 0),
 | |
| --	F(125000000, P_UNIPHY0_TX, 1, 0, 0),
 | |
| -+	FM(125000000, ftbl_nss_port5_tx_clk_src_125),
 | |
| - 	F(156250000, P_UNIPHY1_TX, 2, 0, 0),
 | |
| - 	F(312500000, P_UNIPHY1_TX, 1, 0, 0),
 | |
| - 	{ }
 | |
| -@@ -1806,13 +1822,21 @@ static struct clk_regmap_div nss_port5_t
 | |
| - 	},
 | |
| - };
 | |
| - 
 | |
| -+static struct freq_conf ftbl_nss_port6_rx_clk_src_25[] = {
 | |
| -+	C(P_UNIPHY2_RX, 5, 0, 0),
 | |
| -+	C(P_UNIPHY2_RX, 12.5, 0, 0),
 | |
| -+};
 | |
| -+
 | |
| -+static struct freq_conf ftbl_nss_port6_rx_clk_src_125[] = {
 | |
| -+	C(P_UNIPHY2_RX, 1, 0, 0),
 | |
| -+	C(P_UNIPHY2_RX, 2.5, 0, 0),
 | |
| -+};
 | |
| -+
 | |
| - static const struct freq_tbl ftbl_nss_port6_rx_clk_src[] = {
 | |
| - 	F(19200000, P_XO, 1, 0, 0),
 | |
| --	F(25000000, P_UNIPHY2_RX, 5, 0, 0),
 | |
| --	F(25000000, P_UNIPHY2_RX, 12.5, 0, 0),
 | |
| -+	FM(25000000, ftbl_nss_port6_rx_clk_src_25),
 | |
| - 	F(78125000, P_UNIPHY2_RX, 4, 0, 0),
 | |
| --	F(125000000, P_UNIPHY2_RX, 1, 0, 0),
 | |
| --	F(125000000, P_UNIPHY2_RX, 2.5, 0, 0),
 | |
| -+	FM(125000000, ftbl_nss_port6_rx_clk_src_125),
 | |
| - 	F(156250000, P_UNIPHY2_RX, 2, 0, 0),
 | |
| - 	F(312500000, P_UNIPHY2_RX, 1, 0, 0),
 | |
| - 	{ }
 | |
| -@@ -1863,13 +1887,21 @@ static struct clk_regmap_div nss_port6_r
 | |
| - 	},
 | |
| - };
 | |
| - 
 | |
| -+static struct freq_conf ftbl_nss_port6_tx_clk_src_25[] = {
 | |
| -+	C(P_UNIPHY2_TX, 5, 0, 0),
 | |
| -+	C(P_UNIPHY2_TX, 12.5, 0, 0),
 | |
| -+};
 | |
| -+
 | |
| -+static struct freq_conf ftbl_nss_port6_tx_clk_src_125[] = {
 | |
| -+	C(P_UNIPHY2_TX, 1, 0, 0),
 | |
| -+	C(P_UNIPHY2_TX, 2.5, 0, 0),
 | |
| -+};
 | |
| -+
 | |
| - static const struct freq_tbl ftbl_nss_port6_tx_clk_src[] = {
 | |
| - 	F(19200000, P_XO, 1, 0, 0),
 | |
| --	F(25000000, P_UNIPHY2_TX, 5, 0, 0),
 | |
| --	F(25000000, P_UNIPHY2_TX, 12.5, 0, 0),
 | |
| -+	FM(25000000, ftbl_nss_port6_tx_clk_src_25),
 | |
| - 	F(78125000, P_UNIPHY2_TX, 4, 0, 0),
 | |
| --	F(125000000, P_UNIPHY2_TX, 1, 0, 0),
 | |
| --	F(125000000, P_UNIPHY2_TX, 2.5, 0, 0),
 | |
| -+	FM(125000000, ftbl_nss_port6_tx_clk_src_125),
 | |
| - 	F(156250000, P_UNIPHY2_TX, 2, 0, 0),
 | |
| - 	F(312500000, P_UNIPHY2_TX, 1, 0, 0),
 | |
| - 	{ }
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch b/target/linux/ipq807x/patches-5.15/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch
 | |
| deleted file mode 100644
 | |
| index af53c077ff..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0102-arm64-dts-ipq8074-add-reserved-memory-nodes.patch
 | |
| +++ /dev/null
 | |
| @@ -1,70 +0,0 @@
 | |
| -From ad2d07f71739351eeea1d8a120c0918e2c4b265f Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Wed, 22 Dec 2021 12:23:34 +0100
 | |
| -Subject: [PATCH] arm64: dts: ipq8074: add reserved memory nodes
 | |
| -
 | |
| -IPQ8074 has multiple reserved memory ranges, if they are not defined
 | |
| -then weird things tend to happen, board hangs and resets when PCI or
 | |
| -WLAN is used etc.
 | |
| -
 | |
| -So, to avoid all of that add the reserved memory nodes from the downstream
 | |
| -5.4 kernel from QCA.
 | |
| -This is their default layout meant for devices with 1GB of RAM, but
 | |
| -devices with lower ammounts can override the Q6 node.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 35 +++++++++++++++++++++++++++
 | |
| - 1 file changed, 35 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -85,6 +85,26 @@
 | |
| - 		#size-cells = <2>;
 | |
| - 		ranges;
 | |
| - 
 | |
| -+		nss@40000000 {
 | |
| -+			no-map;
 | |
| -+			reg = <0x0 0x40000000 0x0 0x01000000>;
 | |
| -+		};
 | |
| -+
 | |
| -+		tzapp_region: tzapp@4a400000 {
 | |
| -+			no-map;
 | |
| -+			reg = <0x0 0x4a400000 0x0 0x00200000>;
 | |
| -+		};
 | |
| -+
 | |
| -+		uboot@4a600000 {
 | |
| -+			no-map;
 | |
| -+			reg = <0x0 0x4a600000 0x0 0x00400000>;
 | |
| -+		};
 | |
| -+
 | |
| -+		sbl@4aa00000 {
 | |
| -+			no-map;
 | |
| -+			reg = <0x0 0x4aa00000 0x0 0x00100000>;
 | |
| -+		};
 | |
| -+
 | |
| - 		smem@4ab00000 {
 | |
| - 			compatible = "qcom,smem";
 | |
| - 			reg = <0x0 0x4ab00000 0x0 0x00100000>;
 | |
| -@@ -97,6 +117,21 @@
 | |
| - 			no-map;
 | |
| - 			reg = <0x0 0x4ac00000 0x0 0x00400000>;
 | |
| - 		};
 | |
| -+
 | |
| -+		q6_region: wcnss@4b000000 {
 | |
| -+			no-map;
 | |
| -+			reg = <0x0 0x4b000000 0x0 0x05f00000>;
 | |
| -+		};
 | |
| -+
 | |
| -+		q6_etr_region: q6_etr_dump@50f00000 {
 | |
| -+			no-map;
 | |
| -+			reg = <0x0 0x50f00000 0x0 0x00100000>;
 | |
| -+		};
 | |
| -+
 | |
| -+		m3_dump_region: m3_dump@51000000 {
 | |
| -+			no-map;
 | |
| -+			reg = <0x0 0x51000000 0x0 0x100000>;
 | |
| -+		};
 | |
| - 	};
 | |
| - 
 | |
| - 	firmware {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0106-arm64-dts-qcom-ipq8074-set-Gen2-PCIe-pcie-max-link-s.patch b/target/linux/ipq807x/patches-5.15/0106-arm64-dts-qcom-ipq8074-set-Gen2-PCIe-pcie-max-link-s.patch
 | |
| deleted file mode 100644
 | |
| index 0fa38394b9..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0106-arm64-dts-qcom-ipq8074-set-Gen2-PCIe-pcie-max-link-s.patch
 | |
| +++ /dev/null
 | |
| @@ -1,24 +0,0 @@
 | |
| -From a4748d2850783d36f77ccf2b5fcc86ccf1800ef1 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Wed, 16 Nov 2022 22:48:36 +0100
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: set Gen2 PCIe pcie max-link-speed
 | |
| -
 | |
| -Add the generic 'max-link-speed' property to describe the Gen2 PCIe link
 | |
| -generation limit.
 | |
| -This allows the generic DWC code to configure the link speed correctly.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 1 +
 | |
| - 1 file changed, 1 insertion(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -801,6 +801,7 @@
 | |
| - 			linux,pci-domain = <1>;
 | |
| - 			bus-range = <0x00 0xff>;
 | |
| - 			num-lanes = <1>;
 | |
| -+			max-link-speed = <2>;
 | |
| - 			#address-cells = <3>;
 | |
| - 			#size-cells = <2>;
 | |
| - 
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0107-PCI-qcom-Add-support-for-IPQ8074-Gen3-port.patch b/target/linux/ipq807x/patches-5.15/0107-PCI-qcom-Add-support-for-IPQ8074-Gen3-port.patch
 | |
| deleted file mode 100644
 | |
| index ae6b148210..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0107-PCI-qcom-Add-support-for-IPQ8074-Gen3-port.patch
 | |
| +++ /dev/null
 | |
| @@ -1,23 +0,0 @@
 | |
| -From 76893579a74e7e5c79f0c717d95d13f4cbbb5f4d Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sat, 24 Dec 2022 17:11:16 +0100
 | |
| -Subject: [PATCH] PCI: qcom: Add support for IPQ8074 Gen3 port
 | |
| -
 | |
| -IPQ8074 has one Gen2 and one Gen3 port, with Gen2 port already supported.
 | |
| -Add compatible for Gen3 port which uses the same controller as IPQ6018.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - drivers/pci/controller/dwc/pcie-qcom.c | 1 +
 | |
| - 1 file changed, 1 insertion(+)
 | |
| -
 | |
| ---- a/drivers/pci/controller/dwc/pcie-qcom.c
 | |
| -+++ b/drivers/pci/controller/dwc/pcie-qcom.c
 | |
| -@@ -1735,6 +1735,7 @@ static const struct of_device_id qcom_pc
 | |
| - 	{ .compatible = "qcom,pcie-apq8064", .data = &ipq8064_cfg },
 | |
| - 	{ .compatible = "qcom,pcie-msm8996", .data = &msm8996_cfg },
 | |
| - 	{ .compatible = "qcom,pcie-ipq8074", .data = &ipq8074_cfg },
 | |
| -+	{ .compatible = "qcom,pcie-ipq8074-gen3", .data = &ipq6018_cfg },
 | |
| - 	{ .compatible = "qcom,pcie-ipq4019", .data = &ipq4019_cfg },
 | |
| - 	{ .compatible = "qcom,pcie-qcs404", .data = &ipq4019_cfg },
 | |
| - 	{ .compatible = "qcom,pcie-sdm845", .data = &sdm845_cfg },
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0110-arm64-dts-qcom-ipq8074-pass-QMP-PCI-PHY-PIPE-clocks-.patch b/target/linux/ipq807x/patches-5.15/0110-arm64-dts-qcom-ipq8074-pass-QMP-PCI-PHY-PIPE-clocks-.patch
 | |
| deleted file mode 100644
 | |
| index 69d4126f76..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0110-arm64-dts-qcom-ipq8074-pass-QMP-PCI-PHY-PIPE-clocks-.patch
 | |
| +++ /dev/null
 | |
| @@ -1,30 +0,0 @@
 | |
| -From 8a576b5bc9f0555d1d970cacabcaa24a3b74fa57 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Wed, 16 Nov 2022 22:15:01 +0100
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: pass QMP PCI PHY PIPE clocks to
 | |
| - GCC
 | |
| -
 | |
| -Pass QMP PCI PHY PIPE clocks to the GCC controller so it does not have to
 | |
| -find them by matching globaly by name.
 | |
| -
 | |
| -If not passed directly, driver maintains backwards compatibility by then
 | |
| -falling back to global lookup.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++--
 | |
| - 1 file changed, 2 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -396,8 +396,8 @@
 | |
| - 		gcc: gcc@1800000 {
 | |
| - 			compatible = "qcom,gcc-ipq8074";
 | |
| - 			reg = <0x01800000 0x80000>;
 | |
| --			clocks = <&xo>, <&sleep_clk>;
 | |
| --			clock-names = "xo", "sleep_clk";
 | |
| -+			clocks = <&xo>, <&sleep_clk>, <&pcie_phy0>, <&pcie_phy1>;
 | |
| -+			clock-names = "xo", "sleep_clk", "pcie0_pipe", "pcie1_pipe";
 | |
| - 			#clock-cells = <1>;
 | |
| - 			#power-domain-cells = <1>;
 | |
| - 			#reset-cells = <1>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch b/target/linux/ipq807x/patches-5.15/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch
 | |
| deleted file mode 100644
 | |
| index 9fefd8852a..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0111-arm64-dts-qcom-ipq8074-use-msi-parent-for-PCIe.patch
 | |
| +++ /dev/null
 | |
| @@ -1,43 +0,0 @@
 | |
| -From fb1f6850be00d8dd8a54017be4c1336e224069ac Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Wed, 16 Nov 2022 22:26:25 +0100
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: use msi-parent for PCIe
 | |
| -
 | |
| -Instead of hardcoding the IRQ, simply use msi-parent instead.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 8 +++-----
 | |
| - 1 file changed, 3 insertions(+), 5 deletions(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -699,7 +699,7 @@
 | |
| - 			reg = <0x0b000000 0x1000>, <0x0b002000 0x1000>;
 | |
| - 			ranges = <0 0xb00a000 0xffd>;
 | |
| - 
 | |
| --			v2m@0 {
 | |
| -+			gic_v2m0: v2m@0 {
 | |
| - 				compatible = "arm,gic-v2m-frame";
 | |
| - 				msi-controller;
 | |
| - 				reg = <0x0 0xffd>;
 | |
| -@@ -811,8 +811,7 @@
 | |
| - 			ranges = <0x81000000 0x0 0x00000000 0x10200000 0x0 0x10000>,   /* I/O */
 | |
| - 				 <0x82000000 0x0 0x10220000 0x10220000 0x0 0xfde0000>; /* MEM */
 | |
| - 
 | |
| --			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
 | |
| --			interrupt-names = "msi";
 | |
| -+			msi-parent = <&gic_v2m0>;
 | |
| - 			#interrupt-cells = <1>;
 | |
| - 			interrupt-map-mask = <0 0 0 0x7>;
 | |
| - 			interrupt-map = <0 0 0 1 &intc 0 142
 | |
| -@@ -873,8 +872,7 @@
 | |
| - 			ranges = <0x81000000 0x0 0x00000000 0x20200000 0x0 0x10000>,   /* I/O */
 | |
| - 				 <0x82000000 0x0 0x20220000 0x20220000 0x0 0xfde0000>; /* MEM */
 | |
| - 
 | |
| --			interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
 | |
| --			interrupt-names = "msi";
 | |
| -+			msi-parent = <&gic_v2m0>;
 | |
| - 			#interrupt-cells = <1>;
 | |
| - 			interrupt-map-mask = <0 0 0 0x7>;
 | |
| - 			interrupt-map = <0 0 0 1 &intc 0 75
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0112-remoteproc-qcom-Add-PRNG-proxy-clock.patch b/target/linux/ipq807x/patches-5.15/0112-remoteproc-qcom-Add-PRNG-proxy-clock.patch
 | |
| deleted file mode 100644
 | |
| index 2124bfa3f1..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0112-remoteproc-qcom-Add-PRNG-proxy-clock.patch
 | |
| +++ /dev/null
 | |
| @@ -1,155 +0,0 @@
 | |
| -From 125681433c8e526356947acf572fe8ca8ad32291 Mon Sep 17 00:00:00 2001
 | |
| -From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Date: Sat, 30 Jan 2021 10:50:05 +0530
 | |
| -Subject: [PATCH] remoteproc: qcom: Add PRNG proxy clock
 | |
| -
 | |
| -PRNG clock is needed by the secure PIL, support for the same
 | |
| -is added in subsequent patches.
 | |
| -
 | |
| -Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Signed-off-by: Sricharan R <sricharan@codeaurora.org>
 | |
| -Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
 | |
| ----
 | |
| - drivers/remoteproc/qcom_q6v5_wcss.c | 65 +++++++++++++++++++++--------
 | |
| - 1 file changed, 47 insertions(+), 18 deletions(-)
 | |
| -
 | |
| ---- a/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -@@ -91,19 +91,6 @@ enum {
 | |
| - 	WCSS_QCS404,
 | |
| - };
 | |
| - 
 | |
| --struct wcss_data {
 | |
| --	const char *firmware_name;
 | |
| --	unsigned int crash_reason_smem;
 | |
| --	u32 version;
 | |
| --	bool aon_reset_required;
 | |
| --	bool wcss_q6_reset_required;
 | |
| --	const char *ssr_name;
 | |
| --	const char *sysmon_name;
 | |
| --	int ssctl_id;
 | |
| --	const struct rproc_ops *ops;
 | |
| --	bool requires_force_stop;
 | |
| --};
 | |
| --
 | |
| - struct q6v5_wcss {
 | |
| - 	struct device *dev;
 | |
| - 
 | |
| -@@ -128,6 +115,7 @@ struct q6v5_wcss {
 | |
| - 	struct clk *qdsp6ss_xo_cbcr;
 | |
| - 	struct clk *qdsp6ss_core_gfmux;
 | |
| - 	struct clk *lcc_bcr_sleep;
 | |
| -+	struct clk *prng_clk;
 | |
| - 	struct regulator *cx_supply;
 | |
| - 	struct qcom_sysmon *sysmon;
 | |
| - 
 | |
| -@@ -151,6 +139,21 @@ struct q6v5_wcss {
 | |
| - 	struct qcom_rproc_ssr ssr_subdev;
 | |
| - };
 | |
| - 
 | |
| -+struct wcss_data {
 | |
| -+	int (*init_clock)(struct q6v5_wcss *wcss);
 | |
| -+	int (*init_regulator)(struct q6v5_wcss *wcss);
 | |
| -+	const char *firmware_name;
 | |
| -+	unsigned int crash_reason_smem;
 | |
| -+	u32 version;
 | |
| -+	bool aon_reset_required;
 | |
| -+	bool wcss_q6_reset_required;
 | |
| -+	const char *ssr_name;
 | |
| -+	const char *sysmon_name;
 | |
| -+	int ssctl_id;
 | |
| -+	const struct rproc_ops *ops;
 | |
| -+	bool requires_force_stop;
 | |
| -+};
 | |
| -+
 | |
| - static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
 | |
| - {
 | |
| - 	int ret;
 | |
| -@@ -240,6 +243,12 @@ static int q6v5_wcss_start(struct rproc
 | |
| - 	struct q6v5_wcss *wcss = rproc->priv;
 | |
| - 	int ret;
 | |
| - 
 | |
| -+	ret = clk_prepare_enable(wcss->prng_clk);
 | |
| -+	if (ret) {
 | |
| -+		dev_err(wcss->dev, "prng clock enable failed\n");
 | |
| -+		return ret;
 | |
| -+	}
 | |
| -+
 | |
| - 	qcom_q6v5_prepare(&wcss->q6v5);
 | |
| - 
 | |
| - 	/* Release Q6 and WCSS reset */
 | |
| -@@ -733,6 +742,7 @@ static int q6v5_wcss_stop(struct rproc *
 | |
| - 			return ret;
 | |
| - 	}
 | |
| - 
 | |
| -+	clk_disable_unprepare(wcss->prng_clk);
 | |
| - 	qcom_q6v5_unprepare(&wcss->q6v5);
 | |
| - 
 | |
| - 	return 0;
 | |
| -@@ -900,7 +910,21 @@ static int q6v5_alloc_memory_region(stru
 | |
| - 	return 0;
 | |
| - }
 | |
| - 
 | |
| --static int q6v5_wcss_init_clock(struct q6v5_wcss *wcss)
 | |
| -+static int ipq8074_init_clock(struct q6v5_wcss *wcss)
 | |
| -+{
 | |
| -+	int ret;
 | |
| -+
 | |
| -+	wcss->prng_clk = devm_clk_get(wcss->dev, "prng");
 | |
| -+	if (IS_ERR(wcss->prng_clk)) {
 | |
| -+		ret = PTR_ERR(wcss->prng_clk);
 | |
| -+		if (ret != -EPROBE_DEFER)
 | |
| -+			dev_err(wcss->dev, "Failed to get prng clock\n");
 | |
| -+		return ret;
 | |
| -+	}
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static int qcs404_init_clock(struct q6v5_wcss *wcss)
 | |
| - {
 | |
| - 	int ret;
 | |
| - 
 | |
| -@@ -990,7 +1014,7 @@ static int q6v5_wcss_init_clock(struct q
 | |
| - 	return 0;
 | |
| - }
 | |
| - 
 | |
| --static int q6v5_wcss_init_regulator(struct q6v5_wcss *wcss)
 | |
| -+static int qcs404_init_regulator(struct q6v5_wcss *wcss)
 | |
| - {
 | |
| - 	wcss->cx_supply = devm_regulator_get(wcss->dev, "cx");
 | |
| - 	if (IS_ERR(wcss->cx_supply))
 | |
| -@@ -1034,12 +1058,14 @@ static int q6v5_wcss_probe(struct platfo
 | |
| - 	if (ret)
 | |
| - 		goto free_rproc;
 | |
| - 
 | |
| --	if (wcss->version == WCSS_QCS404) {
 | |
| --		ret = q6v5_wcss_init_clock(wcss);
 | |
| -+	if (desc->init_clock) {
 | |
| -+		ret = desc->init_clock(wcss);
 | |
| - 		if (ret)
 | |
| - 			goto free_rproc;
 | |
| -+	}
 | |
| - 
 | |
| --		ret = q6v5_wcss_init_regulator(wcss);
 | |
| -+	if (desc->init_regulator) {
 | |
| -+		ret = desc->init_regulator(wcss);
 | |
| - 		if (ret)
 | |
| - 			goto free_rproc;
 | |
| - 	}
 | |
| -@@ -1086,6 +1112,7 @@ static int q6v5_wcss_remove(struct platf
 | |
| - }
 | |
| - 
 | |
| - static const struct wcss_data wcss_ipq8074_res_init = {
 | |
| -+	.init_clock = ipq8074_init_clock,
 | |
| - 	.firmware_name = "IPQ8074/q6_fw.mdt",
 | |
| - 	.crash_reason_smem = WCSS_CRASH_REASON,
 | |
| - 	.aon_reset_required = true,
 | |
| -@@ -1095,6 +1122,8 @@ static const struct wcss_data wcss_ipq80
 | |
| - };
 | |
| - 
 | |
| - static const struct wcss_data wcss_qcs404_res_init = {
 | |
| -+	.init_clock = qcs404_init_clock,
 | |
| -+	.init_regulator = qcs404_init_regulator,
 | |
| - 	.crash_reason_smem = WCSS_CRASH_REASON,
 | |
| - 	.firmware_name = "wcnss.mdt",
 | |
| - 	.version = WCSS_QCS404,
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0113-remoteproc-qcom-Add-secure-PIL-support.patch b/target/linux/ipq807x/patches-5.15/0113-remoteproc-qcom-Add-secure-PIL-support.patch
 | |
| deleted file mode 100644
 | |
| index 1d415942e0..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0113-remoteproc-qcom-Add-secure-PIL-support.patch
 | |
| +++ /dev/null
 | |
| @@ -1,143 +0,0 @@
 | |
| -From 7358d42dfbdfdb5d4f1d0d4c2e5c2bb4143a29b0 Mon Sep 17 00:00:00 2001
 | |
| -From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Date: Sat, 30 Jan 2021 10:50:06 +0530
 | |
| -Subject: [PATCH] remoteproc: qcom: Add secure PIL support
 | |
| -
 | |
| -IPQ8074 uses secure PIL. Hence, adding the support for the same.
 | |
| -
 | |
| -Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Signed-off-by: Sricharan R <sricharan@codeaurora.org>
 | |
| -Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
 | |
| ----
 | |
| - drivers/remoteproc/qcom_q6v5_wcss.c | 43 +++++++++++++++++++++++++++--
 | |
| - 1 file changed, 40 insertions(+), 3 deletions(-)
 | |
| -
 | |
| ---- a/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -@@ -18,6 +18,7 @@
 | |
| - #include <linux/regulator/consumer.h>
 | |
| - #include <linux/reset.h>
 | |
| - #include <linux/soc/qcom/mdt_loader.h>
 | |
| -+#include <linux/qcom_scm.h>
 | |
| - #include "qcom_common.h"
 | |
| - #include "qcom_pil_info.h"
 | |
| - #include "qcom_q6v5.h"
 | |
| -@@ -86,6 +87,9 @@
 | |
| - #define TCSR_WCSS_CLK_ENABLE	0x14
 | |
| - 
 | |
| - #define MAX_HALT_REG		3
 | |
| -+
 | |
| -+#define WCNSS_PAS_ID		6
 | |
| -+
 | |
| - enum {
 | |
| - 	WCSS_IPQ8074,
 | |
| - 	WCSS_QCS404,
 | |
| -@@ -134,6 +138,7 @@ struct q6v5_wcss {
 | |
| - 	unsigned int crash_reason_smem;
 | |
| - 	u32 version;
 | |
| - 	bool requires_force_stop;
 | |
| -+	bool need_mem_protection;
 | |
| - 
 | |
| - 	struct qcom_rproc_glink glink_subdev;
 | |
| - 	struct qcom_rproc_ssr ssr_subdev;
 | |
| -@@ -152,6 +157,7 @@ struct wcss_data {
 | |
| - 	int ssctl_id;
 | |
| - 	const struct rproc_ops *ops;
 | |
| - 	bool requires_force_stop;
 | |
| -+	bool need_mem_protection;
 | |
| - };
 | |
| - 
 | |
| - static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
 | |
| -@@ -251,6 +257,15 @@ static int q6v5_wcss_start(struct rproc
 | |
| - 
 | |
| - 	qcom_q6v5_prepare(&wcss->q6v5);
 | |
| - 
 | |
| -+	if (wcss->need_mem_protection) {
 | |
| -+		ret = qcom_scm_pas_auth_and_reset(WCNSS_PAS_ID);
 | |
| -+		if (ret) {
 | |
| -+			dev_err(wcss->dev, "wcss_reset failed\n");
 | |
| -+			return ret;
 | |
| -+		}
 | |
| -+		goto wait_for_reset;
 | |
| -+	}
 | |
| -+
 | |
| - 	/* Release Q6 and WCSS reset */
 | |
| - 	ret = reset_control_deassert(wcss->wcss_reset);
 | |
| - 	if (ret) {
 | |
| -@@ -285,6 +300,7 @@ static int q6v5_wcss_start(struct rproc
 | |
| - 	if (ret)
 | |
| - 		goto wcss_q6_reset;
 | |
| - 
 | |
| -+wait_for_reset:
 | |
| - 	ret = qcom_q6v5_wait_for_start(&wcss->q6v5, 5 * HZ);
 | |
| - 	if (ret == -ETIMEDOUT)
 | |
| - 		dev_err(wcss->dev, "start timed out\n");
 | |
| -@@ -718,6 +734,15 @@ static int q6v5_wcss_stop(struct rproc *
 | |
| - 	struct q6v5_wcss *wcss = rproc->priv;
 | |
| - 	int ret;
 | |
| - 
 | |
| -+	if (wcss->need_mem_protection) {
 | |
| -+		ret = qcom_scm_pas_shutdown(WCNSS_PAS_ID);
 | |
| -+		if (ret) {
 | |
| -+			dev_err(wcss->dev, "not able to shutdown\n");
 | |
| -+			return ret;
 | |
| -+		}
 | |
| -+		goto pas_done;
 | |
| -+	}
 | |
| -+
 | |
| - 	/* WCSS powerdown */
 | |
| - 	if (wcss->requires_force_stop) {
 | |
| - 		ret = qcom_q6v5_request_stop(&wcss->q6v5, NULL);
 | |
| -@@ -742,6 +767,7 @@ static int q6v5_wcss_stop(struct rproc *
 | |
| - 			return ret;
 | |
| - 	}
 | |
| - 
 | |
| -+pas_done:
 | |
| - 	clk_disable_unprepare(wcss->prng_clk);
 | |
| - 	qcom_q6v5_unprepare(&wcss->q6v5);
 | |
| - 
 | |
| -@@ -765,9 +791,15 @@ static int q6v5_wcss_load(struct rproc *
 | |
| - 	struct q6v5_wcss *wcss = rproc->priv;
 | |
| - 	int ret;
 | |
| - 
 | |
| --	ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
 | |
| --				    0, wcss->mem_region, wcss->mem_phys,
 | |
| --				    wcss->mem_size, &wcss->mem_reloc);
 | |
| -+	if (wcss->need_mem_protection)
 | |
| -+		ret = qcom_mdt_load(wcss->dev, fw, rproc->firmware,
 | |
| -+				    WCNSS_PAS_ID, wcss->mem_region,
 | |
| -+				    wcss->mem_phys, wcss->mem_size,
 | |
| -+				    &wcss->mem_reloc);
 | |
| -+	else
 | |
| -+		ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
 | |
| -+					    0, wcss->mem_region, wcss->mem_phys,
 | |
| -+					    wcss->mem_size, &wcss->mem_reloc);
 | |
| - 	if (ret)
 | |
| - 		return ret;
 | |
| - 
 | |
| -@@ -1036,6 +1068,9 @@ static int q6v5_wcss_probe(struct platfo
 | |
| - 	if (!desc)
 | |
| - 		return -EINVAL;
 | |
| - 
 | |
| -+	if (desc->need_mem_protection && !qcom_scm_is_available())
 | |
| -+		return -EPROBE_DEFER;
 | |
| -+
 | |
| - 	rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
 | |
| - 			    desc->firmware_name, sizeof(*wcss));
 | |
| - 	if (!rproc) {
 | |
| -@@ -1049,6 +1084,7 @@ static int q6v5_wcss_probe(struct platfo
 | |
| - 
 | |
| - 	wcss->version = desc->version;
 | |
| - 	wcss->requires_force_stop = desc->requires_force_stop;
 | |
| -+	wcss->need_mem_protection = desc->need_mem_protection;
 | |
| - 
 | |
| - 	ret = q6v5_wcss_init_mmio(wcss, pdev);
 | |
| - 	if (ret)
 | |
| -@@ -1119,6 +1155,7 @@ static const struct wcss_data wcss_ipq80
 | |
| - 	.wcss_q6_reset_required = true,
 | |
| - 	.ops = &q6v5_wcss_ipq8074_ops,
 | |
| - 	.requires_force_stop = true,
 | |
| -+	.need_mem_protection = true,
 | |
| - };
 | |
| - 
 | |
| - static const struct wcss_data wcss_qcs404_res_init = {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0114-remoteproc-qcom-Add-support-for-split-q6-m3-wlan-fir.patch b/target/linux/ipq807x/patches-5.15/0114-remoteproc-qcom-Add-support-for-split-q6-m3-wlan-fir.patch
 | |
| deleted file mode 100644
 | |
| index 1231824af0..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0114-remoteproc-qcom-Add-support-for-split-q6-m3-wlan-fir.patch
 | |
| +++ /dev/null
 | |
| @@ -1,103 +0,0 @@
 | |
| -From b422c9d4f048b086ce83f44a7cfcddcce162897f Mon Sep 17 00:00:00 2001
 | |
| -From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Date: Sat, 30 Jan 2021 10:50:07 +0530
 | |
| -Subject: [PATCH] remoteproc: qcom: Add support for split q6 + m3 wlan firmware
 | |
| -
 | |
| -IPQ8074 supports split firmware for q6 and m3 as well.
 | |
| -So add support for loading the m3 firmware before q6.
 | |
| -Now the drivers works fine for both split and unified
 | |
| -firmwares.
 | |
| -
 | |
| -Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Signed-off-by: Sricharan R <sricharan@codeaurora.org>
 | |
| -Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
 | |
| ----
 | |
| - drivers/remoteproc/qcom_q6v5_wcss.c | 33 +++++++++++++++++++++++++----
 | |
| - 1 file changed, 29 insertions(+), 4 deletions(-)
 | |
| -
 | |
| ---- a/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -@@ -139,6 +139,7 @@ struct q6v5_wcss {
 | |
| - 	u32 version;
 | |
| - 	bool requires_force_stop;
 | |
| - 	bool need_mem_protection;
 | |
| -+	const char *m3_firmware_name;
 | |
| - 
 | |
| - 	struct qcom_rproc_glink glink_subdev;
 | |
| - 	struct qcom_rproc_ssr ssr_subdev;
 | |
| -@@ -147,7 +148,8 @@ struct q6v5_wcss {
 | |
| - struct wcss_data {
 | |
| - 	int (*init_clock)(struct q6v5_wcss *wcss);
 | |
| - 	int (*init_regulator)(struct q6v5_wcss *wcss);
 | |
| --	const char *firmware_name;
 | |
| -+	const char *q6_firmware_name;
 | |
| -+	const char *m3_firmware_name;
 | |
| - 	unsigned int crash_reason_smem;
 | |
| - 	u32 version;
 | |
| - 	bool aon_reset_required;
 | |
| -@@ -789,8 +791,29 @@ static void *q6v5_wcss_da_to_va(struct r
 | |
| - static int q6v5_wcss_load(struct rproc *rproc, const struct firmware *fw)
 | |
| - {
 | |
| - 	struct q6v5_wcss *wcss = rproc->priv;
 | |
| -+	const struct firmware *m3_fw;
 | |
| - 	int ret;
 | |
| - 
 | |
| -+	if (wcss->m3_firmware_name) {
 | |
| -+		ret = request_firmware(&m3_fw, wcss->m3_firmware_name,
 | |
| -+				       wcss->dev);
 | |
| -+		if (ret)
 | |
| -+			goto skip_m3;
 | |
| -+
 | |
| -+		ret = qcom_mdt_load_no_init(wcss->dev, m3_fw,
 | |
| -+					    wcss->m3_firmware_name, 0,
 | |
| -+					    wcss->mem_region, wcss->mem_phys,
 | |
| -+					    wcss->mem_size, &wcss->mem_reloc);
 | |
| -+
 | |
| -+		release_firmware(m3_fw);
 | |
| -+
 | |
| -+		if (ret) {
 | |
| -+			dev_err(wcss->dev, "can't load m3_fw.bXX\n");
 | |
| -+			return ret;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+skip_m3:
 | |
| - 	if (wcss->need_mem_protection)
 | |
| - 		ret = qcom_mdt_load(wcss->dev, fw, rproc->firmware,
 | |
| - 				    WCNSS_PAS_ID, wcss->mem_region,
 | |
| -@@ -1072,7 +1095,7 @@ static int q6v5_wcss_probe(struct platfo
 | |
| - 		return -EPROBE_DEFER;
 | |
| - 
 | |
| - 	rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
 | |
| --			    desc->firmware_name, sizeof(*wcss));
 | |
| -+			    desc->q6_firmware_name, sizeof(*wcss));
 | |
| - 	if (!rproc) {
 | |
| - 		dev_err(&pdev->dev, "failed to allocate rproc\n");
 | |
| - 		return -ENOMEM;
 | |
| -@@ -1085,6 +1108,7 @@ static int q6v5_wcss_probe(struct platfo
 | |
| - 	wcss->version = desc->version;
 | |
| - 	wcss->requires_force_stop = desc->requires_force_stop;
 | |
| - 	wcss->need_mem_protection = desc->need_mem_protection;
 | |
| -+	wcss->m3_firmware_name = desc->m3_firmware_name;
 | |
| - 
 | |
| - 	ret = q6v5_wcss_init_mmio(wcss, pdev);
 | |
| - 	if (ret)
 | |
| -@@ -1149,7 +1173,8 @@ static int q6v5_wcss_remove(struct platf
 | |
| - 
 | |
| - static const struct wcss_data wcss_ipq8074_res_init = {
 | |
| - 	.init_clock = ipq8074_init_clock,
 | |
| --	.firmware_name = "IPQ8074/q6_fw.mdt",
 | |
| -+	.q6_firmware_name = "IPQ8074/q6_fw.mdt",
 | |
| -+	.m3_firmware_name = "IPQ8074/m3_fw.mdt",
 | |
| - 	.crash_reason_smem = WCSS_CRASH_REASON,
 | |
| - 	.aon_reset_required = true,
 | |
| - 	.wcss_q6_reset_required = true,
 | |
| -@@ -1162,7 +1187,7 @@ static const struct wcss_data wcss_qcs40
 | |
| - 	.init_clock = qcs404_init_clock,
 | |
| - 	.init_regulator = qcs404_init_regulator,
 | |
| - 	.crash_reason_smem = WCSS_CRASH_REASON,
 | |
| --	.firmware_name = "wcnss.mdt",
 | |
| -+	.q6_firmware_name = "wcnss.mdt",
 | |
| - 	.version = WCSS_QCS404,
 | |
| - 	.aon_reset_required = false,
 | |
| - 	.wcss_q6_reset_required = false,
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0115-remoteproc-qcom-Add-ssr-subdevice-identifier.patch b/target/linux/ipq807x/patches-5.15/0115-remoteproc-qcom-Add-ssr-subdevice-identifier.patch
 | |
| deleted file mode 100644
 | |
| index 0ff2d0358b..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0115-remoteproc-qcom-Add-ssr-subdevice-identifier.patch
 | |
| +++ /dev/null
 | |
| @@ -1,24 +0,0 @@
 | |
| -From 3a8f67b4770c817b04794c9a02e3f88f85d86280 Mon Sep 17 00:00:00 2001
 | |
| -From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Date: Sat, 30 Jan 2021 10:50:08 +0530
 | |
| -Subject: [PATCH] remoteproc: qcom: Add ssr subdevice identifier
 | |
| -
 | |
| -Add name for ssr subdevice on IPQ8074 SoC.
 | |
| -
 | |
| -Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Signed-off-by: Sricharan R <sricharan@codeaurora.org>
 | |
| -Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
 | |
| ----
 | |
| - drivers/remoteproc/qcom_q6v5_wcss.c | 1 +
 | |
| - 1 file changed, 1 insertion(+)
 | |
| -
 | |
| ---- a/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -@@ -1178,6 +1178,7 @@ static const struct wcss_data wcss_ipq80
 | |
| - 	.crash_reason_smem = WCSS_CRASH_REASON,
 | |
| - 	.aon_reset_required = true,
 | |
| - 	.wcss_q6_reset_required = true,
 | |
| -+	.ssr_name = "q6wcss",
 | |
| - 	.ops = &q6v5_wcss_ipq8074_ops,
 | |
| - 	.requires_force_stop = true,
 | |
| - 	.need_mem_protection = true,
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0116-remoteproc-qcom-Update-regmap-offsets-for-halt-regis.patch b/target/linux/ipq807x/patches-5.15/0116-remoteproc-qcom-Update-regmap-offsets-for-halt-regis.patch
 | |
| deleted file mode 100644
 | |
| index c8e5aceefc..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0116-remoteproc-qcom-Update-regmap-offsets-for-halt-regis.patch
 | |
| +++ /dev/null
 | |
| @@ -1,79 +0,0 @@
 | |
| -From 8c73af6e8d78c66cfef0f551b00d375ec0b67ff3 Mon Sep 17 00:00:00 2001
 | |
| -From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Date: Sat, 30 Jan 2021 10:50:09 +0530
 | |
| -Subject: [PATCH] remoteproc: qcom: Update regmap offsets for halt register
 | |
| -
 | |
| -Fixed issue in reading halt-regs parameter from device-tree.
 | |
| -
 | |
| -Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Signed-off-by: Sricharan R <sricharan@codeaurora.org>
 | |
| ----
 | |
| - drivers/remoteproc/qcom_q6v5_wcss.c | 22 ++++++++++++++--------
 | |
| - 1 file changed, 14 insertions(+), 8 deletions(-)
 | |
| -
 | |
| ---- a/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -@@ -86,7 +86,7 @@
 | |
| - #define TCSR_WCSS_CLK_MASK	0x1F
 | |
| - #define TCSR_WCSS_CLK_ENABLE	0x14
 | |
| - 
 | |
| --#define MAX_HALT_REG		3
 | |
| -+#define MAX_HALT_REG		4
 | |
| - 
 | |
| - #define WCNSS_PAS_ID		6
 | |
| - 
 | |
| -@@ -154,6 +154,7 @@ struct wcss_data {
 | |
| - 	u32 version;
 | |
| - 	bool aon_reset_required;
 | |
| - 	bool wcss_q6_reset_required;
 | |
| -+	bool bcr_reset_required;
 | |
| - 	const char *ssr_name;
 | |
| - 	const char *sysmon_name;
 | |
| - 	int ssctl_id;
 | |
| -@@ -875,10 +876,13 @@ static int q6v5_wcss_init_reset(struct q
 | |
| - 		}
 | |
| - 	}
 | |
| - 
 | |
| --	wcss->wcss_q6_bcr_reset = devm_reset_control_get_exclusive(dev, "wcss_q6_bcr_reset");
 | |
| --	if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
 | |
| --		dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
 | |
| --		return PTR_ERR(wcss->wcss_q6_bcr_reset);
 | |
| -+	if (desc->bcr_reset_required) {
 | |
| -+		wcss->wcss_q6_bcr_reset = devm_reset_control_get_exclusive(dev,
 | |
| -+									   "wcss_q6_bcr_reset");
 | |
| -+		if (IS_ERR(wcss->wcss_q6_bcr_reset)) {
 | |
| -+			dev_err(wcss->dev, "unable to acquire wcss_q6_bcr_reset\n");
 | |
| -+			return PTR_ERR(wcss->wcss_q6_bcr_reset);
 | |
| -+		}
 | |
| - 	}
 | |
| - 
 | |
| - 	return 0;
 | |
| -@@ -929,9 +933,9 @@ static int q6v5_wcss_init_mmio(struct q6
 | |
| - 		return -EINVAL;
 | |
| - 	}
 | |
| - 
 | |
| --	wcss->halt_q6 = halt_reg[0];
 | |
| --	wcss->halt_wcss = halt_reg[1];
 | |
| --	wcss->halt_nc = halt_reg[2];
 | |
| -+	wcss->halt_q6 = halt_reg[1];
 | |
| -+	wcss->halt_wcss = halt_reg[2];
 | |
| -+	wcss->halt_nc = halt_reg[3];
 | |
| - 
 | |
| - 	return 0;
 | |
| - }
 | |
| -@@ -1178,6 +1182,7 @@ static const struct wcss_data wcss_ipq80
 | |
| - 	.crash_reason_smem = WCSS_CRASH_REASON,
 | |
| - 	.aon_reset_required = true,
 | |
| - 	.wcss_q6_reset_required = true,
 | |
| -+	.bcr_reset_required = false,
 | |
| - 	.ssr_name = "q6wcss",
 | |
| - 	.ops = &q6v5_wcss_ipq8074_ops,
 | |
| - 	.requires_force_stop = true,
 | |
| -@@ -1192,6 +1197,7 @@ static const struct wcss_data wcss_qcs40
 | |
| - 	.version = WCSS_QCS404,
 | |
| - 	.aon_reset_required = false,
 | |
| - 	.wcss_q6_reset_required = false,
 | |
| -+	.bcr_reset_required = true,
 | |
| - 	.ssr_name = "mpss",
 | |
| - 	.sysmon_name = "wcnss",
 | |
| - 	.ssctl_id = 0x12,
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0117-dt-bindings-clock-qcom-Add-reset-for-WCSSAON.patch b/target/linux/ipq807x/patches-5.15/0117-dt-bindings-clock-qcom-Add-reset-for-WCSSAON.patch
 | |
| deleted file mode 100644
 | |
| index fe0e0f9e0b..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0117-dt-bindings-clock-qcom-Add-reset-for-WCSSAON.patch
 | |
| +++ /dev/null
 | |
| @@ -1,26 +0,0 @@
 | |
| -From ff7c6533ed8c4de58ed6c8aab03ea59c03eb4f31 Mon Sep 17 00:00:00 2001
 | |
| -From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Date: Sat, 30 Jan 2021 10:50:10 +0530
 | |
| -Subject: [PATCH] dt-bindings: clock: qcom: Add reset for WCSSAON
 | |
| -
 | |
| -Add binding for WCSSAON reset required for Q6v5 reset on IPQ8074 SoC.
 | |
| -
 | |
| -Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Signed-off-by: Sricharan R <sricharan@codeaurora.org>
 | |
| -Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
 | |
| -Acked-by: Rob Herring <robh@kernel.org>
 | |
| -Acked-by: Stephen Boyd <sboyd@kernel.org>
 | |
| ----
 | |
| - include/dt-bindings/clock/qcom,gcc-ipq8074.h | 1 +
 | |
| - 1 file changed, 1 insertion(+)
 | |
| -
 | |
| ---- a/include/dt-bindings/clock/qcom,gcc-ipq8074.h
 | |
| -+++ b/include/dt-bindings/clock/qcom,gcc-ipq8074.h
 | |
| -@@ -381,6 +381,7 @@
 | |
| - #define GCC_NSSPORT4_RESET			143
 | |
| - #define GCC_NSSPORT5_RESET			144
 | |
| - #define GCC_NSSPORT6_RESET			145
 | |
| -+#define GCC_WCSSAON_RESET			146
 | |
| - 
 | |
| - #define USB0_GDSC				0
 | |
| - #define USB1_GDSC				1
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0118-clk-qcom-Add-WCSSAON-reset.patch b/target/linux/ipq807x/patches-5.15/0118-clk-qcom-Add-WCSSAON-reset.patch
 | |
| deleted file mode 100644
 | |
| index 791531775e..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0118-clk-qcom-Add-WCSSAON-reset.patch
 | |
| +++ /dev/null
 | |
| @@ -1,25 +0,0 @@
 | |
| -From 43d9788f546d24df22d8ba3fcc2497d7ccc198f3 Mon Sep 17 00:00:00 2001
 | |
| -From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Date: Sat, 30 Jan 2021 10:50:11 +0530
 | |
| -Subject: [PATCH] clk: qcom: Add WCSSAON reset
 | |
| -
 | |
| -Add WCSSAON reset required for Q6v5 on IPQ8074 SoC.
 | |
| -
 | |
| -Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Signed-off-by: Sricharan R <sricharan@codeaurora.org>
 | |
| -Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
 | |
| -Acked-by: Stephen Boyd <sboyd@kernel.org>
 | |
| ----
 | |
| - drivers/clk/qcom/gcc-ipq8074.c | 1 +
 | |
| - 1 file changed, 1 insertion(+)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -+++ b/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -@@ -4717,6 +4717,7 @@ static const struct qcom_reset_map gcc_i
 | |
| - 	[GCC_NSSPORT4_RESET] = { .reg = 0x68014, .bitmask = BIT(27) | GENMASK(9, 8) },
 | |
| - 	[GCC_NSSPORT5_RESET] = { .reg = 0x68014, .bitmask = BIT(28) | GENMASK(11, 10) },
 | |
| - 	[GCC_NSSPORT6_RESET] = { .reg = 0x68014, .bitmask = BIT(29) | GENMASK(13, 12) },
 | |
| -+	[GCC_WCSSAON_RESET] = { 0x59010, 0 },
 | |
| - };
 | |
| - 
 | |
| - static struct gdsc *gcc_ipq8074_gdscs[] = {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0119-remoteproc-wcss-disable-auto-boot-for-IPQ8074.patch b/target/linux/ipq807x/patches-5.15/0119-remoteproc-wcss-disable-auto-boot-for-IPQ8074.patch
 | |
| deleted file mode 100644
 | |
| index a562f7864e..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0119-remoteproc-wcss-disable-auto-boot-for-IPQ8074.patch
 | |
| +++ /dev/null
 | |
| @@ -1,48 +0,0 @@
 | |
| -From 406a332fd1bcc4e18d73cce390f56272fe9111d7 Mon Sep 17 00:00:00 2001
 | |
| -From: Sivaprakash Murugesan <sivaprak@codeaurora.org>
 | |
| -Date: Fri, 17 Apr 2020 16:37:10 +0530
 | |
| -Subject: [PATCH] remoteproc: wcss: disable auto boot for IPQ8074
 | |
| -
 | |
| -There is no need for remoteproc to boot automatically, ath11k will trigger
 | |
| -booting when its probing.
 | |
| -
 | |
| -Signed-off-by: Sivaprakash Murugesan <sivaprak@codeaurora.org>
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - drivers/remoteproc/qcom_q6v5_wcss.c | 4 ++++
 | |
| - 1 file changed, 4 insertions(+)
 | |
| -
 | |
| ---- a/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
 | |
| -@@ -161,6 +161,7 @@ struct wcss_data {
 | |
| - 	const struct rproc_ops *ops;
 | |
| - 	bool requires_force_stop;
 | |
| - 	bool need_mem_protection;
 | |
| -+	bool need_auto_boot;
 | |
| - };
 | |
| - 
 | |
| - static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
 | |
| -@@ -1151,6 +1152,7 @@ static int q6v5_wcss_probe(struct platfo
 | |
| - 						      desc->sysmon_name,
 | |
| - 						      desc->ssctl_id);
 | |
| - 
 | |
| -+	rproc->auto_boot = desc->need_auto_boot;
 | |
| - 	ret = rproc_add(rproc);
 | |
| - 	if (ret)
 | |
| - 		goto free_rproc;
 | |
| -@@ -1187,6 +1189,7 @@ static const struct wcss_data wcss_ipq80
 | |
| - 	.ops = &q6v5_wcss_ipq8074_ops,
 | |
| - 	.requires_force_stop = true,
 | |
| - 	.need_mem_protection = true,
 | |
| -+	.need_auto_boot = false,
 | |
| - };
 | |
| - 
 | |
| - static const struct wcss_data wcss_qcs404_res_init = {
 | |
| -@@ -1203,6 +1206,7 @@ static const struct wcss_data wcss_qcs40
 | |
| - 	.ssctl_id = 0x12,
 | |
| - 	.ops = &q6v5_wcss_qcs404_ops,
 | |
| - 	.requires_force_stop = false,
 | |
| -+	.need_auto_boot = true,
 | |
| - };
 | |
| - 
 | |
| - static const struct of_device_id q6v5_wcss_of_match[] = {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch b/target/linux/ipq807x/patches-5.15/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch
 | |
| deleted file mode 100644
 | |
| index e37ba37e96..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0120-arm64-dts-qcom-Enable-Q6v5-WCSS-for-ipq8074-SoC.patch
 | |
| +++ /dev/null
 | |
| @@ -1,120 +0,0 @@
 | |
| -From 7388400b8bd42f71d040dbf2fdbdcb834fcc0ede Mon Sep 17 00:00:00 2001
 | |
| -From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Date: Sat, 30 Jan 2021 10:50:13 +0530
 | |
| -Subject: [PATCH] arm64: dts: qcom: Enable Q6v5 WCSS for ipq8074 SoC
 | |
| -
 | |
| -Enable remoteproc WCSS PIL driver with glink and ssr subdevices.
 | |
| -Also enables smp2p and mailboxes required for IPC.
 | |
| -
 | |
| -Signed-off-by: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
 | |
| -Signed-off-by: Sricharan R <sricharan@codeaurora.org>
 | |
| -Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 81 +++++++++++++++++++++++++++
 | |
| - 1 file changed, 81 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -140,6 +140,32 @@
 | |
| - 		};
 | |
| - 	};
 | |
| - 
 | |
| -+	wcss: smp2p-wcss {
 | |
| -+		compatible = "qcom,smp2p";
 | |
| -+		qcom,smem = <435>, <428>;
 | |
| -+
 | |
| -+		interrupt-parent = <&intc>;
 | |
| -+		interrupts = <0 322 1>;
 | |
| -+
 | |
| -+		mboxes = <&apcs_glb 9>;
 | |
| -+
 | |
| -+		qcom,local-pid = <0>;
 | |
| -+		qcom,remote-pid = <1>;
 | |
| -+
 | |
| -+		wcss_smp2p_out: master-kernel {
 | |
| -+			qcom,entry-name = "master-kernel";
 | |
| -+			qcom,smp2p-feature-ssr-ack;
 | |
| -+			#qcom,smem-state-cells = <1>;
 | |
| -+		};
 | |
| -+
 | |
| -+		wcss_smp2p_in: slave-kernel {
 | |
| -+			qcom,entry-name = "slave-kernel";
 | |
| -+
 | |
| -+			interrupt-controller;
 | |
| -+			#interrupt-cells = <2>;
 | |
| -+		};
 | |
| -+	};
 | |
| -+
 | |
| - 	soc: soc {
 | |
| - 		#address-cells = <0x1>;
 | |
| - 		#size-cells = <0x1>;
 | |
| -@@ -409,6 +435,11 @@
 | |
| - 			#hwlock-cells = <1>;
 | |
| - 		};
 | |
| - 
 | |
| -+		tcsr_q6: syscon@1945000 {
 | |
| -+			compatible = "syscon";
 | |
| -+			reg = <0x01945000 0xe000>;
 | |
| -+		};
 | |
| -+
 | |
| - 		spmi_bus: spmi@200f000 {
 | |
| - 			compatible = "qcom,spmi-pmic-arb";
 | |
| - 			reg = <0x0200f000 0x001000>,
 | |
| -@@ -913,6 +944,56 @@
 | |
| - 				      "axi_s_sticky";
 | |
| - 			status = "disabled";
 | |
| - 		};
 | |
| -+
 | |
| -+		q6v5_wcss: q6v5_wcss@cd00000 {
 | |
| -+			compatible = "qcom,ipq8074-wcss-pil";
 | |
| -+			reg = <0x0cd00000 0x4040>,
 | |
| -+			      <0x004ab000 0x20>;
 | |
| -+			reg-names = "qdsp6",
 | |
| -+				    "rmb";
 | |
| -+			qca,auto-restart;
 | |
| -+			qca,extended-intc;
 | |
| -+			interrupts-extended = <&intc 0 325 1>,
 | |
| -+					      <&wcss_smp2p_in 0 0>,
 | |
| -+					      <&wcss_smp2p_in 1 0>,
 | |
| -+					      <&wcss_smp2p_in 2 0>,
 | |
| -+					      <&wcss_smp2p_in 3 0>;
 | |
| -+			interrupt-names = "wdog",
 | |
| -+					  "fatal",
 | |
| -+					  "ready",
 | |
| -+					  "handover",
 | |
| -+					  "stop-ack";
 | |
| -+
 | |
| -+			resets = <&gcc GCC_WCSSAON_RESET>,
 | |
| -+				 <&gcc GCC_WCSS_BCR>,
 | |
| -+				 <&gcc GCC_WCSS_Q6_BCR>;
 | |
| -+
 | |
| -+			reset-names = "wcss_aon_reset",
 | |
| -+				      "wcss_reset",
 | |
| -+				      "wcss_q6_reset";
 | |
| -+
 | |
| -+			clocks = <&gcc GCC_PRNG_AHB_CLK>;
 | |
| -+			clock-names = "prng";
 | |
| -+
 | |
| -+			qcom,halt-regs = <&tcsr_q6 0xa000 0xd000 0x0>;
 | |
| -+
 | |
| -+			qcom,smem-states = <&wcss_smp2p_out 0>,
 | |
| -+					   <&wcss_smp2p_out 1>;
 | |
| -+			qcom,smem-state-names = "shutdown",
 | |
| -+						"stop";
 | |
| -+
 | |
| -+			memory-region = <&q6_region>;
 | |
| -+
 | |
| -+			glink-edge {
 | |
| -+				interrupts = <GIC_SPI 321 IRQ_TYPE_EDGE_RISING>;
 | |
| -+				qcom,remote-pid = <1>;
 | |
| -+				mboxes = <&apcs_glb 8>;
 | |
| -+
 | |
| -+				rpm_requests {
 | |
| -+					qcom,glink-channels = "IPCRTR";
 | |
| -+				};
 | |
| -+			};
 | |
| -+		};
 | |
| - 	};
 | |
| - 
 | |
| - 	timer {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0121-arm64-dts-ipq8074-Add-WLAN-node.patch b/target/linux/ipq807x/patches-5.15/0121-arm64-dts-ipq8074-Add-WLAN-node.patch
 | |
| deleted file mode 100644
 | |
| index bd5410c934..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0121-arm64-dts-ipq8074-Add-WLAN-node.patch
 | |
| +++ /dev/null
 | |
| @@ -1,135 +0,0 @@
 | |
| -From a67d1901741c162645eda0dbdc3a2c0c2aff5cf4 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Tue, 21 Dec 2021 14:49:36 +0100
 | |
| -Subject: [PATCH] arm64: dts: ipq8074: Add WLAN node
 | |
| -
 | |
| -IPQ8074 has a AHB based Q6v5 802.11ax radios that are supported
 | |
| -by the ath11k.
 | |
| -
 | |
| -Add the required DT node to enable the built-in radios.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 111 ++++++++++++++++++++++++++
 | |
| - 1 file changed, 111 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -994,6 +994,117 @@
 | |
| - 				};
 | |
| - 			};
 | |
| - 		};
 | |
| -+
 | |
| -+		wifi: wifi@c0000000 {
 | |
| -+			compatible = "qcom,ipq8074-wifi";
 | |
| -+			reg = <0xc000000 0x2000000>;
 | |
| -+
 | |
| -+			interrupts = <GIC_SPI 320 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 319 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 318 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 316 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 315 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 314 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 311 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 310 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 411 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 410 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 40 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 302 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 301 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 296 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 295 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 294 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 293 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 292 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 291 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 290 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 289 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 288 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 239 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 236 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 235 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 234 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 233 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 232 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 231 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 230 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 229 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 228 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 224 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 223 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 203 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 183 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 180 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 179 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 177 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 176 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 163 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 160 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 159 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 158 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 157 IRQ_TYPE_EDGE_RISING>,
 | |
| -+				     <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
 | |
| -+
 | |
| -+			interrupt-names = "misc-pulse1",
 | |
| -+					  "misc-latch",
 | |
| -+					  "sw-exception",
 | |
| -+					  "ce0",
 | |
| -+					  "ce1",
 | |
| -+					  "ce2",
 | |
| -+					  "ce3",
 | |
| -+					  "ce4",
 | |
| -+					  "ce5",
 | |
| -+					  "ce6",
 | |
| -+					  "ce7",
 | |
| -+					  "ce8",
 | |
| -+					  "ce9",
 | |
| -+					  "ce10",
 | |
| -+					  "ce11",
 | |
| -+					  "host2wbm-desc-feed",
 | |
| -+					  "host2reo-re-injection",
 | |
| -+					  "host2reo-command",
 | |
| -+					  "host2rxdma-monitor-ring3",
 | |
| -+					  "host2rxdma-monitor-ring2",
 | |
| -+					  "host2rxdma-monitor-ring1",
 | |
| -+					  "reo2ost-exception",
 | |
| -+					  "wbm2host-rx-release",
 | |
| -+					  "reo2host-status",
 | |
| -+					  "reo2host-destination-ring4",
 | |
| -+					  "reo2host-destination-ring3",
 | |
| -+					  "reo2host-destination-ring2",
 | |
| -+					  "reo2host-destination-ring1",
 | |
| -+					  "rxdma2host-monitor-destination-mac3",
 | |
| -+					  "rxdma2host-monitor-destination-mac2",
 | |
| -+					  "rxdma2host-monitor-destination-mac1",
 | |
| -+					  "ppdu-end-interrupts-mac3",
 | |
| -+					  "ppdu-end-interrupts-mac2",
 | |
| -+					  "ppdu-end-interrupts-mac1",
 | |
| -+					  "rxdma2host-monitor-status-ring-mac3",
 | |
| -+					  "rxdma2host-monitor-status-ring-mac2",
 | |
| -+					  "rxdma2host-monitor-status-ring-mac1",
 | |
| -+					  "host2rxdma-host-buf-ring-mac3",
 | |
| -+					  "host2rxdma-host-buf-ring-mac2",
 | |
| -+					  "host2rxdma-host-buf-ring-mac1",
 | |
| -+					  "rxdma2host-destination-ring-mac3",
 | |
| -+					  "rxdma2host-destination-ring-mac2",
 | |
| -+					  "rxdma2host-destination-ring-mac1",
 | |
| -+					  "host2tcl-input-ring4",
 | |
| -+					  "host2tcl-input-ring3",
 | |
| -+					  "host2tcl-input-ring2",
 | |
| -+					  "host2tcl-input-ring1",
 | |
| -+					  "wbm2host-tx-completions-ring3",
 | |
| -+					  "wbm2host-tx-completions-ring2",
 | |
| -+					  "wbm2host-tx-completions-ring1",
 | |
| -+					  "tcl2host-status-ring";
 | |
| -+			qcom,rproc = <&q6v5_wcss>;
 | |
| -+			status = "disabled";
 | |
| -+		};
 | |
| - 	};
 | |
| - 
 | |
| - 	timer {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0122-arm64-dts-ipq8074-add-CPU-clock.patch b/target/linux/ipq807x/patches-5.15/0122-arm64-dts-ipq8074-add-CPU-clock.patch
 | |
| deleted file mode 100644
 | |
| index a3c5f344ab..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0122-arm64-dts-ipq8074-add-CPU-clock.patch
 | |
| +++ /dev/null
 | |
| @@ -1,59 +0,0 @@
 | |
| -From cb3ef99c1553565e1dc0301ccd5c1c0fa2d15c15 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 31 Dec 2021 17:56:14 +0100
 | |
| -Subject: [PATCH] arm64: dts: ipq8074: add CPU clock
 | |
| -
 | |
| -Now that CPU clock is exposed and can be controlled, add the necessary
 | |
| -properties to the CPU nodes.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 9 +++++++++
 | |
| - 1 file changed, 9 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -5,6 +5,7 @@
 | |
| - 
 | |
| - #include <dt-bindings/interrupt-controller/arm-gic.h>
 | |
| - #include <dt-bindings/clock/qcom,gcc-ipq8074.h>
 | |
| -+#include <dt-bindings/clock/qcom,apss-ipq.h>
 | |
| - 
 | |
| - / {
 | |
| - 	#address-cells = <2>;
 | |
| -@@ -38,6 +39,8 @@
 | |
| - 			reg = <0x0>;
 | |
| - 			next-level-cache = <&L2_0>;
 | |
| - 			enable-method = "psci";
 | |
| -+			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| -+			clock-names = "cpu";
 | |
| - 		};
 | |
| - 
 | |
| - 		CPU1: cpu@1 {
 | |
| -@@ -46,6 +49,8 @@
 | |
| - 			enable-method = "psci";
 | |
| - 			reg = <0x1>;
 | |
| - 			next-level-cache = <&L2_0>;
 | |
| -+			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| -+			clock-names = "cpu";
 | |
| - 		};
 | |
| - 
 | |
| - 		CPU2: cpu@2 {
 | |
| -@@ -54,6 +59,8 @@
 | |
| - 			enable-method = "psci";
 | |
| - 			reg = <0x2>;
 | |
| - 			next-level-cache = <&L2_0>;
 | |
| -+			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| -+			clock-names = "cpu";
 | |
| - 		};
 | |
| - 
 | |
| - 		CPU3: cpu@3 {
 | |
| -@@ -62,6 +69,8 @@
 | |
| - 			enable-method = "psci";
 | |
| - 			reg = <0x3>;
 | |
| - 			next-level-cache = <&L2_0>;
 | |
| -+			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| -+			clock-names = "cpu";
 | |
| - 		};
 | |
| - 
 | |
| - 		L2_0: l2-cache {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0123-arm64-dts-ipq8074-add-cooling-cells-to-CPU-nodes.patch b/target/linux/ipq807x/patches-5.15/0123-arm64-dts-ipq8074-add-cooling-cells-to-CPU-nodes.patch
 | |
| deleted file mode 100644
 | |
| index 3520b38134..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0123-arm64-dts-ipq8074-add-cooling-cells-to-CPU-nodes.patch
 | |
| +++ /dev/null
 | |
| @@ -1,48 +0,0 @@
 | |
| -From 347ca56e86c99021fad059b9a8ef101245b8507e Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 31 Dec 2021 20:38:06 +0100
 | |
| -Subject: [PATCH] arm64: dts: ipq8074: add cooling cells to CPU nodes
 | |
| -
 | |
| -Since there is CPU Freq support as well as thermal sensor support
 | |
| -now for the IPQ8074, add cooling cells to CPU nodes so that they can
 | |
| -be used as cooling devices using CPU Freq.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 4 ++++
 | |
| - 1 file changed, 4 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -41,6 +41,7 @@
 | |
| - 			enable-method = "psci";
 | |
| - 			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| - 			clock-names = "cpu";
 | |
| -+			#cooling-cells = <2>;
 | |
| - 		};
 | |
| - 
 | |
| - 		CPU1: cpu@1 {
 | |
| -@@ -51,6 +52,7 @@
 | |
| - 			next-level-cache = <&L2_0>;
 | |
| - 			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| - 			clock-names = "cpu";
 | |
| -+			#cooling-cells = <2>;
 | |
| - 		};
 | |
| - 
 | |
| - 		CPU2: cpu@2 {
 | |
| -@@ -61,6 +63,7 @@
 | |
| - 			next-level-cache = <&L2_0>;
 | |
| - 			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| - 			clock-names = "cpu";
 | |
| -+			#cooling-cells = <2>;
 | |
| - 		};
 | |
| - 
 | |
| - 		CPU3: cpu@3 {
 | |
| -@@ -71,6 +74,7 @@
 | |
| - 			next-level-cache = <&L2_0>;
 | |
| - 			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| - 			clock-names = "cpu";
 | |
| -+			#cooling-cells = <2>;
 | |
| - 		};
 | |
| - 
 | |
| - 		L2_0: l2-cache {
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0124-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch b/target/linux/ipq807x/patches-5.15/0124-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch
 | |
| deleted file mode 100644
 | |
| index 30f6e988aa..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0124-soc-qcom-socinfo-move-SMEM-item-struct-and-defines-t.patch
 | |
| +++ /dev/null
 | |
| @@ -1,168 +0,0 @@
 | |
| -From 97505f4c049fa2e8c86a53411a9e599033898533 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sat, 31 Dec 2022 00:27:42 +0100
 | |
| -Subject: [PATCH] soc: qcom: socinfo: move SMEM item struct and defines to a
 | |
| - header
 | |
| -
 | |
| -Move SMEM item struct and related defines to a header in order to be able
 | |
| -to reuse them in the Qualcomm NVMEM CPUFreq driver instead of duplicating
 | |
| -them.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - drivers/soc/qcom/socinfo.c       | 58 +--------------------------
 | |
| - include/linux/soc/qcom/socinfo.h | 67 ++++++++++++++++++++++++++++++++
 | |
| - 2 files changed, 68 insertions(+), 57 deletions(-)
 | |
| - create mode 100644 include/linux/soc/qcom/socinfo.h
 | |
| -
 | |
| ---- a/drivers/soc/qcom/socinfo.c
 | |
| -+++ b/drivers/soc/qcom/socinfo.c
 | |
| -@@ -11,6 +11,7 @@
 | |
| - #include <linux/random.h>
 | |
| - #include <linux/slab.h>
 | |
| - #include <linux/soc/qcom/smem.h>
 | |
| -+#include <linux/soc/qcom/socinfo.h>
 | |
| - #include <linux/string.h>
 | |
| - #include <linux/sys_soc.h>
 | |
| - #include <linux/types.h>
 | |
| -@@ -25,15 +26,6 @@
 | |
| - #define SOCINFO_MINOR(ver) ((ver) & 0xffff)
 | |
| - #define SOCINFO_VERSION(maj, min)  ((((maj) & 0xffff) << 16)|((min) & 0xffff))
 | |
| - 
 | |
| --#define SMEM_SOCINFO_BUILD_ID_LENGTH           32
 | |
| --#define SMEM_SOCINFO_CHIP_ID_LENGTH            32
 | |
| --
 | |
| --/*
 | |
| -- * SMEM item id, used to acquire handles to respective
 | |
| -- * SMEM region.
 | |
| -- */
 | |
| --#define SMEM_HW_SW_BUILD_ID            137
 | |
| --
 | |
| - #ifdef CONFIG_DEBUG_FS
 | |
| - #define SMEM_IMAGE_VERSION_BLOCKS_COUNT        32
 | |
| - #define SMEM_IMAGE_VERSION_SIZE                4096
 | |
| -@@ -105,54 +97,6 @@ static const char *const pmic_models[] =
 | |
| - };
 | |
| - #endif /* CONFIG_DEBUG_FS */
 | |
| - 
 | |
| --/* Socinfo SMEM item structure */
 | |
| --struct socinfo {
 | |
| --	__le32 fmt;
 | |
| --	__le32 id;
 | |
| --	__le32 ver;
 | |
| --	char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH];
 | |
| --	/* Version 2 */
 | |
| --	__le32 raw_id;
 | |
| --	__le32 raw_ver;
 | |
| --	/* Version 3 */
 | |
| --	__le32 hw_plat;
 | |
| --	/* Version 4 */
 | |
| --	__le32 plat_ver;
 | |
| --	/* Version 5 */
 | |
| --	__le32 accessory_chip;
 | |
| --	/* Version 6 */
 | |
| --	__le32 hw_plat_subtype;
 | |
| --	/* Version 7 */
 | |
| --	__le32 pmic_model;
 | |
| --	__le32 pmic_die_rev;
 | |
| --	/* Version 8 */
 | |
| --	__le32 pmic_model_1;
 | |
| --	__le32 pmic_die_rev_1;
 | |
| --	__le32 pmic_model_2;
 | |
| --	__le32 pmic_die_rev_2;
 | |
| --	/* Version 9 */
 | |
| --	__le32 foundry_id;
 | |
| --	/* Version 10 */
 | |
| --	__le32 serial_num;
 | |
| --	/* Version 11 */
 | |
| --	__le32 num_pmics;
 | |
| --	__le32 pmic_array_offset;
 | |
| --	/* Version 12 */
 | |
| --	__le32 chip_family;
 | |
| --	__le32 raw_device_family;
 | |
| --	__le32 raw_device_num;
 | |
| --	/* Version 13 */
 | |
| --	__le32 nproduct_id;
 | |
| --	char chip_id[SMEM_SOCINFO_CHIP_ID_LENGTH];
 | |
| --	/* Version 14 */
 | |
| --	__le32 num_clusters;
 | |
| --	__le32 ncluster_array_offset;
 | |
| --	__le32 num_defective_parts;
 | |
| --	__le32 ndefective_parts_array_offset;
 | |
| --	/* Version 15 */
 | |
| --	__le32 nmodem_supported;
 | |
| --};
 | |
| --
 | |
| - #ifdef CONFIG_DEBUG_FS
 | |
| - struct socinfo_params {
 | |
| - 	u32 raw_device_family;
 | |
| ---- /dev/null
 | |
| -+++ b/include/linux/soc/qcom/socinfo.h
 | |
| -@@ -0,0 +1,67 @@
 | |
| -+// SPDX-License-Identifier: GPL-2.0
 | |
| -+/*
 | |
| -+ * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
 | |
| -+ * Copyright (c) 2017-2019, Linaro Ltd.
 | |
| -+ */
 | |
| -+
 | |
| -+#ifndef __QCOM_SOCINFO_H__
 | |
| -+#define __QCOM_SOCINFO_H__
 | |
| -+
 | |
| -+/*
 | |
| -+ * SMEM item id, used to acquire handles to respective
 | |
| -+ * SMEM region.
 | |
| -+ */
 | |
| -+#define SMEM_HW_SW_BUILD_ID		137
 | |
| -+
 | |
| -+#define SMEM_SOCINFO_BUILD_ID_LENGTH	32
 | |
| -+#define SMEM_SOCINFO_CHIP_ID_LENGTH	32
 | |
| -+
 | |
| -+/* Socinfo SMEM item structure */
 | |
| -+struct socinfo {
 | |
| -+	__le32 fmt;
 | |
| -+	__le32 id;
 | |
| -+	__le32 ver;
 | |
| -+	char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH];
 | |
| -+	/* Version 2 */
 | |
| -+	__le32 raw_id;
 | |
| -+	__le32 raw_ver;
 | |
| -+	/* Version 3 */
 | |
| -+	__le32 hw_plat;
 | |
| -+	/* Version 4 */
 | |
| -+	__le32 plat_ver;
 | |
| -+	/* Version 5 */
 | |
| -+	__le32 accessory_chip;
 | |
| -+	/* Version 6 */
 | |
| -+	__le32 hw_plat_subtype;
 | |
| -+	/* Version 7 */
 | |
| -+	__le32 pmic_model;
 | |
| -+	__le32 pmic_die_rev;
 | |
| -+	/* Version 8 */
 | |
| -+	__le32 pmic_model_1;
 | |
| -+	__le32 pmic_die_rev_1;
 | |
| -+	__le32 pmic_model_2;
 | |
| -+	__le32 pmic_die_rev_2;
 | |
| -+	/* Version 9 */
 | |
| -+	__le32 foundry_id;
 | |
| -+	/* Version 10 */
 | |
| -+	__le32 serial_num;
 | |
| -+	/* Version 11 */
 | |
| -+	__le32 num_pmics;
 | |
| -+	__le32 pmic_array_offset;
 | |
| -+	/* Version 12 */
 | |
| -+	__le32 chip_family;
 | |
| -+	__le32 raw_device_family;
 | |
| -+	__le32 raw_device_num;
 | |
| -+	/* Version 13 */
 | |
| -+	__le32 nproduct_id;
 | |
| -+	char chip_id[SMEM_SOCINFO_CHIP_ID_LENGTH];
 | |
| -+	/* Version 14 */
 | |
| -+	__le32 num_clusters;
 | |
| -+	__le32 ncluster_array_offset;
 | |
| -+	__le32 num_defective_parts;
 | |
| -+	__le32 ndefective_parts_array_offset;
 | |
| -+	/* Version 15 */
 | |
| -+	__le32 nmodem_supported;
 | |
| -+};
 | |
| -+
 | |
| -+#endif
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0125-cpufreq-qcom-nvmem-reuse-socinfo-SMEM-item-struct.patch b/target/linux/ipq807x/patches-5.15/0125-cpufreq-qcom-nvmem-reuse-socinfo-SMEM-item-struct.patch
 | |
| deleted file mode 100644
 | |
| index aa7fe5a868..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0125-cpufreq-qcom-nvmem-reuse-socinfo-SMEM-item-struct.patch
 | |
| +++ /dev/null
 | |
| @@ -1,50 +0,0 @@
 | |
| -From b7b7ea3a0cab42d4f1d4c9ae9eb7c7a3d03e7982 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 30 Dec 2022 22:51:47 +0100
 | |
| -Subject: [PATCH] cpufreq: qcom-nvmem: reuse socinfo SMEM item struct
 | |
| -
 | |
| -Now that socinfo SMEM item struct and defines have been moved to a header
 | |
| -so we can utilize that instead.
 | |
| -
 | |
| -Now the SMEM value can be accesed directly, there is no need for defining
 | |
| -the ID for the SMEM request as well.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - drivers/cpufreq/qcom-cpufreq-nvmem.c | 14 +++++---------
 | |
| - 1 file changed, 5 insertions(+), 9 deletions(-)
 | |
| -
 | |
| ---- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
 | |
| -+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
 | |
| -@@ -28,8 +28,7 @@
 | |
| - #include <linux/pm_opp.h>
 | |
| - #include <linux/slab.h>
 | |
| - #include <linux/soc/qcom/smem.h>
 | |
| --
 | |
| --#define MSM_ID_SMEM	137
 | |
| -+#include <linux/soc/qcom/socinfo.h>
 | |
| - 
 | |
| - enum _msm_id {
 | |
| - 	MSM8996V3 = 0xF6ul,
 | |
| -@@ -145,17 +144,14 @@ static void get_krait_bin_format_b(struc
 | |
| - static enum _msm8996_version qcom_cpufreq_get_msm_id(void)
 | |
| - {
 | |
| - 	size_t len;
 | |
| --	u32 *msm_id;
 | |
| -+	struct socinfo *info;
 | |
| - 	enum _msm8996_version version;
 | |
| - 
 | |
| --	msm_id = qcom_smem_get(QCOM_SMEM_HOST_ANY, MSM_ID_SMEM, &len);
 | |
| --	if (IS_ERR(msm_id))
 | |
| -+	info = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_HW_SW_BUILD_ID, &len);
 | |
| -+	if (IS_ERR(info))
 | |
| - 		return NUM_OF_MSM8996_VERSIONS;
 | |
| - 
 | |
| --	/* The first 4 bytes are format, next to them is the actual msm-id */
 | |
| --	msm_id++;
 | |
| --
 | |
| --	switch ((enum _msm_id)*msm_id) {
 | |
| -+	switch (info->id) {
 | |
| - 	case MSM8996V3:
 | |
| - 	case APQ8096V3:
 | |
| - 		version = MSM8996_V3;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0126-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch b/target/linux/ipq807x/patches-5.15/0126-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch
 | |
| deleted file mode 100644
 | |
| index 3303b40277..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0126-cpufreq-qcom-nvmem-use-SoC-ID-s-from-bindings.patch
 | |
| +++ /dev/null
 | |
| @@ -1,46 +0,0 @@
 | |
| -From 132b2f15b8ae3f848b3e6f2962f409cfab0ca759 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 30 Dec 2022 23:33:47 +0100
 | |
| -Subject: [PATCH] cpufreq: qcom-nvmem: use SoC ID-s from bindings
 | |
| -
 | |
| -SMEM SoC ID-s are now stored in DT bindings so lets use those instead of
 | |
| -defining them in the driver again.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - drivers/cpufreq/qcom-cpufreq-nvmem.c | 15 +++++----------
 | |
| - 1 file changed, 5 insertions(+), 10 deletions(-)
 | |
| -
 | |
| ---- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
 | |
| -+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
 | |
| -@@ -30,12 +30,7 @@
 | |
| - #include <linux/soc/qcom/smem.h>
 | |
| - #include <linux/soc/qcom/socinfo.h>
 | |
| - 
 | |
| --enum _msm_id {
 | |
| --	MSM8996V3 = 0xF6ul,
 | |
| --	APQ8096V3 = 0x123ul,
 | |
| --	MSM8996SG = 0x131ul,
 | |
| --	APQ8096SG = 0x138ul,
 | |
| --};
 | |
| -+#include <dt-bindings/arm/qcom,ids.h>
 | |
| - 
 | |
| - enum _msm8996_version {
 | |
| - 	MSM8996_V3,
 | |
| -@@ -152,12 +147,12 @@ static enum _msm8996_version qcom_cpufre
 | |
| - 		return NUM_OF_MSM8996_VERSIONS;
 | |
| - 
 | |
| - 	switch (info->id) {
 | |
| --	case MSM8996V3:
 | |
| --	case APQ8096V3:
 | |
| -+	case QCOM_ID_MSM8996:
 | |
| -+	case QCOM_ID_APQ8096:
 | |
| - 		version = MSM8996_V3;
 | |
| - 		break;
 | |
| --	case MSM8996SG:
 | |
| --	case APQ8096SG:
 | |
| -+	case QCOM_ID_MSM8996SG:
 | |
| -+	case QCOM_ID_APQ8096SG:
 | |
| - 		version = MSM8996_SG;
 | |
| - 		break;
 | |
| - 	default:
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0127-cpufreq-qcom-nvmem-make-qcom_cpufreq_get_msm_id-retu.patch b/target/linux/ipq807x/patches-5.15/0127-cpufreq-qcom-nvmem-make-qcom_cpufreq_get_msm_id-retu.patch
 | |
| deleted file mode 100644
 | |
| index 768866b1b2..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0127-cpufreq-qcom-nvmem-make-qcom_cpufreq_get_msm_id-retu.patch
 | |
| +++ /dev/null
 | |
| @@ -1,106 +0,0 @@
 | |
| -From 85bf71b130ab0e939f53ec9cf1131d67d148bc9a Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sat, 31 Dec 2022 12:45:31 +0100
 | |
| -Subject: [PATCH] cpufreq: qcom-nvmem: make qcom_cpufreq_get_msm_id() return
 | |
| - the SoC ID
 | |
| -
 | |
| -Currently, qcom_cpufreq_get_msm_id() does not simply return the SoC ID
 | |
| -after getting it via SMEM call but instead uses an enum to encode the
 | |
| -matched SMEM ID to 2 variants of MSM8996 which are then used in
 | |
| -qcom_cpufreq_kryo_name_version() to set the supported version.
 | |
| -
 | |
| -This prevents qcom_cpufreq_get_msm_id() from being universal and its doing
 | |
| -more than its name suggests, so lets make it just return the SoC ID
 | |
| -directly which allows matching directly on the SoC ID and removes the need
 | |
| -for msm8996_version enum which simplifies the driver.
 | |
| -It also allows reusing the qcom_cpufreq_get_msm_id() for new SoC-s.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - drivers/cpufreq/qcom-cpufreq-nvmem.c | 44 ++++++++--------------------
 | |
| - 1 file changed, 12 insertions(+), 32 deletions(-)
 | |
| -
 | |
| ---- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
 | |
| -+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
 | |
| -@@ -32,12 +32,6 @@
 | |
| - 
 | |
| - #include <dt-bindings/arm/qcom,ids.h>
 | |
| - 
 | |
| --enum _msm8996_version {
 | |
| --	MSM8996_V3,
 | |
| --	MSM8996_SG,
 | |
| --	NUM_OF_MSM8996_VERSIONS,
 | |
| --};
 | |
| --
 | |
| - struct qcom_cpufreq_drv;
 | |
| - 
 | |
| - struct qcom_cpufreq_match_data {
 | |
| -@@ -136,30 +130,16 @@ static void get_krait_bin_format_b(struc
 | |
| - 	dev_dbg(cpu_dev, "PVS version: %d\n", *pvs_ver);
 | |
| - }
 | |
| - 
 | |
| --static enum _msm8996_version qcom_cpufreq_get_msm_id(void)
 | |
| -+static int qcom_cpufreq_get_msm_id(void)
 | |
| - {
 | |
| - 	size_t len;
 | |
| - 	struct socinfo *info;
 | |
| --	enum _msm8996_version version;
 | |
| - 
 | |
| - 	info = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_HW_SW_BUILD_ID, &len);
 | |
| - 	if (IS_ERR(info))
 | |
| --		return NUM_OF_MSM8996_VERSIONS;
 | |
| --
 | |
| --	switch (info->id) {
 | |
| --	case QCOM_ID_MSM8996:
 | |
| --	case QCOM_ID_APQ8096:
 | |
| --		version = MSM8996_V3;
 | |
| --		break;
 | |
| --	case QCOM_ID_MSM8996SG:
 | |
| --	case QCOM_ID_APQ8096SG:
 | |
| --		version = MSM8996_SG;
 | |
| --		break;
 | |
| --	default:
 | |
| --		version = NUM_OF_MSM8996_VERSIONS;
 | |
| --	}
 | |
| -+		return PTR_ERR(info);
 | |
| - 
 | |
| --	return version;
 | |
| -+	return info->id;
 | |
| - }
 | |
| - 
 | |
| - static int qcom_cpufreq_kryo_name_version(struct device *cpu_dev,
 | |
| -@@ -168,25 +148,25 @@ static int qcom_cpufreq_kryo_name_versio
 | |
| - 					  struct qcom_cpufreq_drv *drv)
 | |
| - {
 | |
| - 	size_t len;
 | |
| -+	int msm_id;
 | |
| - 	u8 *speedbin;
 | |
| --	enum _msm8996_version msm8996_version;
 | |
| - 	*pvs_name = NULL;
 | |
| - 
 | |
| --	msm8996_version = qcom_cpufreq_get_msm_id();
 | |
| --	if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
 | |
| --		dev_err(cpu_dev, "Not Snapdragon 820/821!");
 | |
| --		return -ENODEV;
 | |
| --	}
 | |
| -+	msm_id = qcom_cpufreq_get_msm_id();
 | |
| -+	if (msm_id < 0)
 | |
| -+		return msm_id;
 | |
| - 
 | |
| - 	speedbin = nvmem_cell_read(speedbin_nvmem, &len);
 | |
| - 	if (IS_ERR(speedbin))
 | |
| - 		return PTR_ERR(speedbin);
 | |
| - 
 | |
| --	switch (msm8996_version) {
 | |
| --	case MSM8996_V3:
 | |
| -+	switch (msm_id) {
 | |
| -+	case QCOM_ID_MSM8996:
 | |
| -+	case QCOM_ID_APQ8096:
 | |
| - 		drv->versions = 1 << (unsigned int)(*speedbin);
 | |
| - 		break;
 | |
| --	case MSM8996_SG:
 | |
| -+	case QCOM_ID_MSM8996SG:
 | |
| -+	case QCOM_ID_APQ8096SG:
 | |
| - 		drv->versions = 1 << ((unsigned int)(*speedbin) + 4);
 | |
| - 		break;
 | |
| - 	default:
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0128-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch b/target/linux/ipq807x/patches-5.15/0128-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch
 | |
| deleted file mode 100644
 | |
| index 49fd4e4cc0..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0128-cpufreq-qcom-nvmem-add-support-for-IPQ8074.patch
 | |
| +++ /dev/null
 | |
| @@ -1,100 +0,0 @@
 | |
| -From 813f2b5ad002e691b92154037f154b4444eedd54 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sat, 31 Dec 2022 13:03:41 +0100
 | |
| -Subject: [PATCH] cpufreq: qcom-nvmem: add support for IPQ8074
 | |
| -
 | |
| -IPQ8074 comes in 2 families:
 | |
| -* IPQ8070A/IPQ8071A (Acorn) up to 1.4GHz
 | |
| -* IPQ8072A/IPQ8074A/IPQ8076A/IPQ8078A (Hawkeye) up to 2.2GHz
 | |
| -
 | |
| -So, in order to be able to share one OPP table lets add support for IPQ8074
 | |
| -family based of SMEM SoC ID-s as speedbin fuse is always 0 on IPQ8074.
 | |
| -
 | |
| -IPQ8074 compatible is blacklisted from DT platdev as the cpufreq device
 | |
| -will get created by NVMEM CPUFreq driver.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - drivers/cpufreq/cpufreq-dt-platdev.c |  1 +
 | |
| - drivers/cpufreq/qcom-cpufreq-nvmem.c | 39 ++++++++++++++++++++++++++++
 | |
| - 2 files changed, 40 insertions(+)
 | |
| -
 | |
| ---- a/drivers/cpufreq/cpufreq-dt-platdev.c
 | |
| -+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
 | |
| -@@ -159,6 +159,7 @@ static const struct of_device_id blockli
 | |
| - 	{ .compatible = "ti,omap3", },
 | |
| - 
 | |
| - 	{ .compatible = "qcom,ipq8064", },
 | |
| -+	{ .compatible = "qcom,ipq8074", },
 | |
| - 	{ .compatible = "qcom,apq8064", },
 | |
| - 	{ .compatible = "qcom,msm8974", },
 | |
| - 	{ .compatible = "qcom,msm8960", },
 | |
| ---- a/drivers/cpufreq/qcom-cpufreq-nvmem.c
 | |
| -+++ b/drivers/cpufreq/qcom-cpufreq-nvmem.c
 | |
| -@@ -32,6 +32,9 @@
 | |
| - 
 | |
| - #include <dt-bindings/arm/qcom,ids.h>
 | |
| - 
 | |
| -+#define IPQ8074_HAWKEYE_VERSION		BIT(0)
 | |
| -+#define IPQ8074_ACORN_VERSION		BIT(1)
 | |
| -+
 | |
| - struct qcom_cpufreq_drv;
 | |
| - 
 | |
| - struct qcom_cpufreq_match_data {
 | |
| -@@ -218,6 +221,37 @@ len_error:
 | |
| - 	return ret;
 | |
| - }
 | |
| - 
 | |
| -+static int qcom_cpufreq_ipq8074_name_version(struct device *cpu_dev,
 | |
| -+					     struct nvmem_cell *speedbin_nvmem,
 | |
| -+					     char **pvs_name,
 | |
| -+					     struct qcom_cpufreq_drv *drv)
 | |
| -+{
 | |
| -+	int msm_id;
 | |
| -+	*pvs_name = NULL;
 | |
| -+
 | |
| -+	msm_id = qcom_cpufreq_get_msm_id();
 | |
| -+	if (msm_id < 0)
 | |
| -+		return msm_id;
 | |
| -+
 | |
| -+	switch (msm_id) {
 | |
| -+	case QCOM_ID_IPQ8070A:
 | |
| -+	case QCOM_ID_IPQ8071A:
 | |
| -+		drv->versions = IPQ8074_ACORN_VERSION;
 | |
| -+		break;
 | |
| -+	case QCOM_ID_IPQ8072A:
 | |
| -+	case QCOM_ID_IPQ8074A:
 | |
| -+	case QCOM_ID_IPQ8076A:
 | |
| -+	case QCOM_ID_IPQ8078A:
 | |
| -+		drv->versions = IPQ8074_HAWKEYE_VERSION;
 | |
| -+		break;
 | |
| -+	default:
 | |
| -+		BUG();
 | |
| -+		break;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| - static const struct qcom_cpufreq_match_data match_data_kryo = {
 | |
| - 	.get_version = qcom_cpufreq_kryo_name_version,
 | |
| - };
 | |
| -@@ -232,6 +266,10 @@ static const struct qcom_cpufreq_match_d
 | |
| - 	.genpd_names = qcs404_genpd_names,
 | |
| - };
 | |
| - 
 | |
| -+static const struct qcom_cpufreq_match_data match_data_ipq8074 = {
 | |
| -+	.get_version = qcom_cpufreq_ipq8074_name_version,
 | |
| -+};
 | |
| -+
 | |
| - static int qcom_cpufreq_probe(struct platform_device *pdev)
 | |
| - {
 | |
| - 	struct qcom_cpufreq_drv *drv;
 | |
| -@@ -431,6 +469,7 @@ static const struct of_device_id qcom_cp
 | |
| - 	{ .compatible = "qcom,msm8996", .data = &match_data_kryo },
 | |
| - 	{ .compatible = "qcom,qcs404", .data = &match_data_qcs404 },
 | |
| - 	{ .compatible = "qcom,ipq8064", .data = &match_data_krait },
 | |
| -+	{ .compatible = "qcom,ipq8074", .data = &match_data_ipq8074 },
 | |
| - 	{ .compatible = "qcom,apq8064", .data = &match_data_krait },
 | |
| - 	{ .compatible = "qcom,msm8974", .data = &match_data_krait },
 | |
| - 	{ .compatible = "qcom,msm8960", .data = &match_data_krait },
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0129-arm64-dts-qcom-ipq8074-add-QFPROM-fuses.patch b/target/linux/ipq807x/patches-5.15/0129-arm64-dts-qcom-ipq8074-add-QFPROM-fuses.patch
 | |
| deleted file mode 100644
 | |
| index 3a6f4e9c87..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0129-arm64-dts-qcom-ipq8074-add-QFPROM-fuses.patch
 | |
| +++ /dev/null
 | |
| @@ -1,128 +0,0 @@
 | |
| -From 04d2fc6a551bbd972a6428059b45ce79cb9de9d7 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Fri, 6 May 2022 22:38:24 +0200
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add QFPROM fuses
 | |
| -
 | |
| -Add the QFPROM node and CPR fuses.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 107 ++++++++++++++++++++++++++
 | |
| - 1 file changed, 107 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -340,6 +340,113 @@
 | |
| - 			status = "disabled";
 | |
| - 		};
 | |
| - 
 | |
| -+		qfprom: efuse@a4000 {
 | |
| -+			compatible = "qcom,ipq8074-qfprom", "qcom,qfprom";
 | |
| -+			reg = <0x000a4000 0x1000>;
 | |
| -+			#address-cells = <1>;
 | |
| -+			#size-cells = <1>;
 | |
| -+
 | |
| -+			cpr_efuse_speedbin: speedbin@125 {
 | |
| -+				reg = <0x125 0x1>;
 | |
| -+				bits = <0 3>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_boost_cfg: boost_cfg@125 {
 | |
| -+				reg = <0x125 0x1>;
 | |
| -+				bits = <3 3>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_misc_volt_adj: misc_volt_adj@125 {
 | |
| -+				reg = <0x125 0x1>;
 | |
| -+				bits = <3 3>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_boost_volt: boost_volt@126 {
 | |
| -+				reg = <0x126 0x1>;
 | |
| -+				bits = <6 1>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_revision: revision@23e {
 | |
| -+				reg = <0x23e 0x1>;
 | |
| -+				bits = <5 3>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_ro_sel0: rosel0@249 {
 | |
| -+				reg = <0x249 0x1>;
 | |
| -+				bits = <0 4>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_ro_sel1: rosel1@248 {
 | |
| -+				reg = <0x248 0x1>;
 | |
| -+				bits = <4 4>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_ro_sel2: rosel2@248 {
 | |
| -+				reg = <0x248 0x2>;
 | |
| -+				bits = <0 4>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_ro_sel3: rosel3@249 {
 | |
| -+				reg = <0x249 0x1>;
 | |
| -+				bits = <4 4>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_init_voltage0: ivoltage0@23a {
 | |
| -+				reg = <0x23a 0x1>;
 | |
| -+				bits = <2 6>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_init_voltage1: ivoltage1@239 {
 | |
| -+				reg = <0x239 0x2>;
 | |
| -+				bits = <4 6>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_init_voltage2: ivoltage2@238 {
 | |
| -+				reg = <0x238 0x2>;
 | |
| -+				bits = <6 6>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_init_voltage3: ivoltage3@238 {
 | |
| -+				reg = <0x238 0x1>;
 | |
| -+				bits = <0 6>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_quot0: quot0@244 {
 | |
| -+				reg = <0x244 0x2>;
 | |
| -+				bits = <0 12>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_quot1: quot1@242 {
 | |
| -+				reg = <0x242 0x2>;
 | |
| -+				bits = <4 12>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_quot2: quot2@241 {
 | |
| -+				reg = <0x241 0x2>;
 | |
| -+				bits = <0 12>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_quot3: quot3@245 {
 | |
| -+				reg = <0x245 0x2>;
 | |
| -+				bits = <4 12>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_quot0_offset: quot0_offset@23d {
 | |
| -+				reg = <0x23d 0x2>;
 | |
| -+				bits = <6 7>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_quot1_offset: quot1_offset@23c {
 | |
| -+				reg = <0x23c 0x2>;
 | |
| -+				bits = <7 7>;
 | |
| -+			};
 | |
| -+
 | |
| -+			cpr_efuse_quot2_offset: quot2_offset@23c {
 | |
| -+				reg = <0x23c 0x1>;
 | |
| -+				bits = <0 7>;
 | |
| -+			};
 | |
| -+		};
 | |
| -+
 | |
| - 		prng: rng@e3000 {
 | |
| - 			compatible = "qcom,prng-ee";
 | |
| - 			reg = <0x000e3000 0x1000>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0130-arm64-dts-qcom-ipq8074-add-CPU-OPP-table.patch b/target/linux/ipq807x/patches-5.15/0130-arm64-dts-qcom-ipq8074-add-CPU-OPP-table.patch
 | |
| deleted file mode 100644
 | |
| index 9c1e7b9d29..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0130-arm64-dts-qcom-ipq8074-add-CPU-OPP-table.patch
 | |
| +++ /dev/null
 | |
| @@ -1,102 +0,0 @@
 | |
| -From a20c4e8738a00087aa5d53fe5148ed484e23d229 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sat, 31 Dec 2022 13:56:26 +0100
 | |
| -Subject: [PATCH] arm64: dts: qcom: ipq8074: add CPU OPP table
 | |
| -
 | |
| -Now that there is NVMEM CPUFreq support for IPQ8074, we can add the OPP
 | |
| -table for SoC.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 52 +++++++++++++++++++++++++++
 | |
| - 1 file changed, 52 insertions(+)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -42,6 +42,7 @@
 | |
| - 			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| - 			clock-names = "cpu";
 | |
| - 			#cooling-cells = <2>;
 | |
| -+			operating-points-v2 = <&cpu_opp_table>;
 | |
| - 		};
 | |
| - 
 | |
| - 		CPU1: cpu@1 {
 | |
| -@@ -53,6 +54,7 @@
 | |
| - 			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| - 			clock-names = "cpu";
 | |
| - 			#cooling-cells = <2>;
 | |
| -+			operating-points-v2 = <&cpu_opp_table>;
 | |
| - 		};
 | |
| - 
 | |
| - 		CPU2: cpu@2 {
 | |
| -@@ -64,6 +66,7 @@
 | |
| - 			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| - 			clock-names = "cpu";
 | |
| - 			#cooling-cells = <2>;
 | |
| -+			operating-points-v2 = <&cpu_opp_table>;
 | |
| - 		};
 | |
| - 
 | |
| - 		CPU3: cpu@3 {
 | |
| -@@ -75,6 +78,7 @@
 | |
| - 			clocks = <&apcs_glb APCS_ALIAS0_CORE_CLK>;
 | |
| - 			clock-names = "cpu";
 | |
| - 			#cooling-cells = <2>;
 | |
| -+			operating-points-v2 = <&cpu_opp_table>;
 | |
| - 		};
 | |
| - 
 | |
| - 		L2_0: l2-cache {
 | |
| -@@ -83,6 +87,54 @@
 | |
| - 		};
 | |
| - 	};
 | |
| - 
 | |
| -+	cpu_opp_table: opp-table {
 | |
| -+		compatible = "operating-points-v2-kryo-cpu";
 | |
| -+		nvmem-cells = <&cpr_efuse_speedbin>;
 | |
| -+		opp-shared;
 | |
| -+
 | |
| -+		opp-1017600000 {
 | |
| -+			opp-hz = /bits/ 64 <1017600000>;
 | |
| -+			opp-microvolt = <1>;
 | |
| -+			opp-supported-hw = <0xf>;
 | |
| -+			clock-latency-ns = <200000>;
 | |
| -+		};
 | |
| -+
 | |
| -+		opp-1382400000 {
 | |
| -+			opp-hz = /bits/ 64 <1382400000>;
 | |
| -+			opp-microvolt = <2>;
 | |
| -+			opp-supported-hw = <0xf>;
 | |
| -+			clock-latency-ns = <200000>;
 | |
| -+		};
 | |
| -+
 | |
| -+		opp-1651200000 {
 | |
| -+			opp-hz = /bits/ 64 <1651200000>;
 | |
| -+			opp-microvolt = <3>;
 | |
| -+			opp-supported-hw = <0x1>;
 | |
| -+			clock-latency-ns = <200000>;
 | |
| -+		};
 | |
| -+
 | |
| -+		opp-1843200000 {
 | |
| -+			opp-hz = /bits/ 64 <1843200000>;
 | |
| -+			opp-microvolt = <4>;
 | |
| -+			opp-supported-hw = <0x1>;
 | |
| -+			clock-latency-ns = <200000>;
 | |
| -+		};
 | |
| -+
 | |
| -+		opp-1920000000 {
 | |
| -+			opp-hz = /bits/ 64 <1920000000>;
 | |
| -+			opp-microvolt = <5>;
 | |
| -+			opp-supported-hw = <0x1>;
 | |
| -+			clock-latency-ns = <200000>;
 | |
| -+		};
 | |
| -+
 | |
| -+		opp-2208000000 {
 | |
| -+			opp-hz = /bits/ 64 <2208000000>;
 | |
| -+			opp-microvolt = <6>;
 | |
| -+			opp-supported-hw = <0x1>;
 | |
| -+			clock-latency-ns = <200000>;
 | |
| -+		};
 | |
| -+	};
 | |
| -+
 | |
| - 	pmu {
 | |
| - 		compatible = "arm,cortex-a53-pmu";
 | |
| - 		interrupts = <GIC_PPI 7 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0131-clk-qcom-ipq8074-populate-fw_name-for-usb3phy-s.patch b/target/linux/ipq807x/patches-5.15/0131-clk-qcom-ipq8074-populate-fw_name-for-usb3phy-s.patch
 | |
| deleted file mode 100644
 | |
| index eb772be4ce..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0131-clk-qcom-ipq8074-populate-fw_name-for-usb3phy-s.patch
 | |
| +++ /dev/null
 | |
| @@ -1,38 +0,0 @@
 | |
| -From 614d31c231c7707322b643f409eeb7e28adc7f8c Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Sun, 8 Jan 2023 13:36:28 +0100
 | |
| -Subject: [PATCH] clk: qcom: ipq8074: populate fw_name for usb3phy-s
 | |
| -
 | |
| -Having only .name populated in parent_data for clocks which are only
 | |
| -globally searchable currently will not work as the clk core won't copy
 | |
| -that name if there is no .fw_name present as well.
 | |
| -
 | |
| -So, populate .fw_name for usb3phy clocks in parent_data as they were
 | |
| -missed by me in ("clk: qcom: ipq8074: populate fw_name for all parents").
 | |
| -
 | |
| -Fixes: ae55ad32e273 ("clk: qcom: ipq8074: convert to parent data")
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - drivers/clk/qcom/gcc-ipq8074.c | 4 ++--
 | |
| - 1 file changed, 2 insertions(+), 2 deletions(-)
 | |
| -
 | |
| ---- a/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -+++ b/drivers/clk/qcom/gcc-ipq8074.c
 | |
| -@@ -934,7 +934,7 @@ static struct clk_rcg2 usb0_mock_utmi_cl
 | |
| - };
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_usb3phy_0_cc_pipe_clk_xo[] = {
 | |
| --	{ .name = "usb3phy_0_cc_pipe_clk" },
 | |
| -+	{ .fw_name = "usb3phy_0_cc_pipe_clk", .name = "usb3phy_0_cc_pipe_clk" },
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| - };
 | |
| - 
 | |
| -@@ -1002,7 +1002,7 @@ static struct clk_rcg2 usb1_mock_utmi_cl
 | |
| - };
 | |
| - 
 | |
| - static const struct clk_parent_data gcc_usb3phy_1_cc_pipe_clk_xo[] = {
 | |
| --	{ .name = "usb3phy_1_cc_pipe_clk" },
 | |
| -+	{ .fw_name = "usb3phy_1_cc_pipe_clk", .name = "usb3phy_1_cc_pipe_clk" },
 | |
| - 	{ .fw_name = "xo", .name = "xo" },
 | |
| - };
 | |
| - 
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0900-power-Add-Qualcomm-APM.patch b/target/linux/ipq807x/patches-5.15/0900-power-Add-Qualcomm-APM.patch
 | |
| deleted file mode 100644
 | |
| index 2e5c72b7d1..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0900-power-Add-Qualcomm-APM.patch
 | |
| +++ /dev/null
 | |
| @@ -1,1047 +0,0 @@
 | |
| -From 6c98adf98236b8644b8f5e1aa7af9f1a88ea2766 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Mon, 11 Apr 2022 14:38:08 +0200
 | |
| -Subject: [PATCH] power: Add Qualcomm APM
 | |
| -
 | |
| -Add Qualcomm APM driver, which allows scaling cache and memory fabrics.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - drivers/power/Kconfig          |   1 +
 | |
| - drivers/power/Makefile         |   1 +
 | |
| - drivers/power/qcom/Kconfig     |   7 +
 | |
| - drivers/power/qcom/Makefile    |   1 +
 | |
| - drivers/power/qcom/apm.c       | 944 +++++++++++++++++++++++++++++++++
 | |
| - include/linux/power/qcom/apm.h |  48 ++
 | |
| - 6 files changed, 1002 insertions(+)
 | |
| - create mode 100644 drivers/power/qcom/Kconfig
 | |
| - create mode 100644 drivers/power/qcom/Makefile
 | |
| - create mode 100644 drivers/power/qcom/apm.c
 | |
| - create mode 100644 include/linux/power/qcom/apm.h
 | |
| -
 | |
| ---- a/drivers/power/Kconfig
 | |
| -+++ b/drivers/power/Kconfig
 | |
| -@@ -1,3 +1,4 @@
 | |
| - # SPDX-License-Identifier: GPL-2.0-only
 | |
| - source "drivers/power/reset/Kconfig"
 | |
| - source "drivers/power/supply/Kconfig"
 | |
| -+source "drivers/power/qcom/Kconfig"
 | |
| ---- a/drivers/power/Makefile
 | |
| -+++ b/drivers/power/Makefile
 | |
| -@@ -1,3 +1,4 @@
 | |
| - # SPDX-License-Identifier: GPL-2.0-only
 | |
| - obj-$(CONFIG_POWER_RESET)	+= reset/
 | |
| - obj-$(CONFIG_POWER_SUPPLY)	+= supply/
 | |
| -+obj-$(CONFIG_QCOM_APM)		+= qcom/
 | |
| ---- /dev/null
 | |
| -+++ b/drivers/power/qcom/Kconfig
 | |
| -@@ -0,0 +1,7 @@
 | |
| -+config QCOM_APM
 | |
| -+       bool "Qualcomm Technologies Inc platform specific APM driver"
 | |
| -+       help
 | |
| -+	Platform specific driver to manage the power source of
 | |
| -+	memory arrays. Interfaces with regulator drivers to ensure
 | |
| -+	SRAM Vmin requirements are met across different performance
 | |
| -+	levels.
 | |
| ---- /dev/null
 | |
| -+++ b/drivers/power/qcom/Makefile
 | |
| -@@ -0,0 +1 @@
 | |
| -+obj-$(CONFIG_QCOM_APM)		+= apm.o
 | |
| ---- /dev/null
 | |
| -+++ b/drivers/power/qcom/apm.c
 | |
| -@@ -0,0 +1,944 @@
 | |
| -+/*
 | |
| -+ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
 | |
| -+ *
 | |
| -+ * This program is free software; you can redistribute it and/or modify
 | |
| -+ * it under the terms of the GNU General Public License version 2 and
 | |
| -+ * only version 2 as published by the Free Software Foundation.
 | |
| -+ *
 | |
| -+ * This program is distributed in the hope that it will be useful,
 | |
| -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| -+ * GNU General Public License for more details.
 | |
| -+ */
 | |
| -+
 | |
| -+#define pr_fmt(fmt) "%s: " fmt, __func__
 | |
| -+
 | |
| -+#include <linux/debugfs.h>
 | |
| -+#include <linux/delay.h>
 | |
| -+#include <linux/of_device.h>
 | |
| -+#include <linux/init.h>
 | |
| -+#include <linux/io.h>
 | |
| -+#include <linux/kernel.h>
 | |
| -+#include <linux/list.h>
 | |
| -+#include <linux/module.h>
 | |
| -+#include <linux/of.h>
 | |
| -+#include <linux/platform_device.h>
 | |
| -+#include <linux/slab.h>
 | |
| -+#include <linux/string.h>
 | |
| -+#include <linux/power/qcom/apm.h>
 | |
| -+
 | |
| -+/*
 | |
| -+ *        VDD_APCC
 | |
| -+ * =============================================================
 | |
| -+ *       |      VDD_MX                  |                    |
 | |
| -+ *       |    ==========================|=============       |
 | |
| -+ *    ___|___   ___|___    ___|___   ___|___    ___|___   ___|___
 | |
| -+ *   |       | |       |  |       | |       |  |       | |       |
 | |
| -+ *   | APCC  | | MX HS |  | MX HS | | APCC  |  | MX HS | | APCC  |
 | |
| -+ *   |  HS   | |       |  |       | |  HS   |  |       | |  HS   |
 | |
| -+ *   |_______| |_______|  |_______| |_______|  |_______| |_______|
 | |
| -+ *       |_________|          |_________|         |__________|
 | |
| -+ *            |                    |                    |
 | |
| -+ *      ______|_____         ______|_____        _______|_____
 | |
| -+ *     |            |       |            |      |             |
 | |
| -+ *     |            |       |            |      |             |
 | |
| -+ *     |  CPU MEM   |       |   L2 MEM   |      |    L3 MEM   |
 | |
| -+ *     |   Arrays   |       |   Arrays   |      |    Arrays   |
 | |
| -+ *     |            |       |            |      |             |
 | |
| -+ *     |____________|       |____________|      |_____________|
 | |
| -+ *
 | |
| -+ */
 | |
| -+
 | |
| -+/* Register value definitions */
 | |
| -+#define APCS_GFMUXA_SEL_VAL            0x13
 | |
| -+#define APCS_GFMUXA_DESEL_VAL          0x03
 | |
| -+#define MSM_APM_MX_MODE_VAL            0x00
 | |
| -+#define MSM_APM_APCC_MODE_VAL          0x10
 | |
| -+#define MSM_APM_MX_DONE_VAL            0x00
 | |
| -+#define MSM_APM_APCC_DONE_VAL          0x03
 | |
| -+#define MSM_APM_OVERRIDE_SEL_VAL       0xb0
 | |
| -+#define MSM_APM_SEC_CLK_SEL_VAL        0x30
 | |
| -+#define SPM_EVENT_SET_VAL              0x01
 | |
| -+#define SPM_EVENT_CLEAR_VAL            0x00
 | |
| -+
 | |
| -+/* Register bit mask definitions */
 | |
| -+#define MSM_APM_CTL_STS_MASK            0x0f
 | |
| -+
 | |
| -+/* Register offset definitions */
 | |
| -+#define APCC_APM_MODE              0x00000098
 | |
| -+#define APCC_APM_CTL_STS           0x000000a8
 | |
| -+#define APCS_SPARE                 0x00000068
 | |
| -+#define APCS_VERSION               0x00000fd0
 | |
| -+
 | |
| -+#define HMSS_VERSION_1P2           0x10020000
 | |
| -+
 | |
| -+#define MSM_APM_SWITCH_TIMEOUT_US  10
 | |
| -+#define SPM_WAKEUP_DELAY_US        2
 | |
| -+#define SPM_EVENT_NUM              6
 | |
| -+
 | |
| -+#define MSM_APM_DRIVER_NAME        "qcom,msm-apm"
 | |
| -+
 | |
| -+enum {
 | |
| -+	MSM8996_ID,
 | |
| -+	MSM8953_ID,
 | |
| -+	IPQ807x_ID,
 | |
| -+};
 | |
| -+
 | |
| -+struct msm_apm_ctrl_dev {
 | |
| -+	struct list_head	list;
 | |
| -+	struct device		*dev;
 | |
| -+	enum msm_apm_supply	supply;
 | |
| -+	spinlock_t		lock;
 | |
| -+	void __iomem		*reg_base;
 | |
| -+	void __iomem		*apcs_csr_base;
 | |
| -+	void __iomem		**apcs_spm_events_addr;
 | |
| -+	void __iomem		*apc0_pll_ctl_addr;
 | |
| -+	void __iomem		*apc1_pll_ctl_addr;
 | |
| -+	u32			version;
 | |
| -+	struct dentry		*debugfs;
 | |
| -+	u32			msm_id;
 | |
| -+};
 | |
| -+
 | |
| -+#if defined(CONFIG_DEBUG_FS)
 | |
| -+static struct dentry *apm_debugfs_base;
 | |
| -+#endif
 | |
| -+
 | |
| -+static DEFINE_MUTEX(apm_ctrl_list_mutex);
 | |
| -+static LIST_HEAD(apm_ctrl_list);
 | |
| -+
 | |
| -+/*
 | |
| -+ * Get the resources associated with the APM controller from device tree
 | |
| -+ * and remap all I/O addresses that are relevant to this HW revision.
 | |
| -+ */
 | |
| -+static int msm_apm_ctrl_devm_ioremap(struct platform_device *pdev,
 | |
| -+				     struct msm_apm_ctrl_dev *ctrl)
 | |
| -+{
 | |
| -+	struct device *dev = &pdev->dev;
 | |
| -+	struct resource *res;
 | |
| -+	static const char *res_name[SPM_EVENT_NUM] = {
 | |
| -+		"apc0-l2-spm",
 | |
| -+		"apc1-l2-spm",
 | |
| -+		"apc0-cpu0-spm",
 | |
| -+		"apc0-cpu1-spm",
 | |
| -+		"apc1-cpu0-spm",
 | |
| -+		"apc1-cpu1-spm"
 | |
| -+	};
 | |
| -+	int i, ret = 0;
 | |
| -+
 | |
| -+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pm-apcc-glb");
 | |
| -+	if (!res) {
 | |
| -+		dev_err(dev, "Missing PM APCC Global register physical address");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+	ctrl->reg_base = devm_ioremap(dev, res->start, resource_size(res));
 | |
| -+	if (!ctrl->reg_base) {
 | |
| -+		dev_err(dev, "Failed to map PM APCC Global registers\n");
 | |
| -+		return -ENOMEM;
 | |
| -+	}
 | |
| -+
 | |
| -+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apcs-csr");
 | |
| -+	if (!res) {
 | |
| -+		dev_err(dev, "Missing APCS CSR physical base address");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+	ctrl->apcs_csr_base = devm_ioremap(dev, res->start, resource_size(res));
 | |
| -+	if (!ctrl->apcs_csr_base) {
 | |
| -+		dev_err(dev, "Failed to map APCS CSR registers\n");
 | |
| -+		return -ENOMEM;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->version = readl_relaxed(ctrl->apcs_csr_base + APCS_VERSION);
 | |
| -+
 | |
| -+	if (ctrl->version >= HMSS_VERSION_1P2)
 | |
| -+		return ret;
 | |
| -+
 | |
| -+	ctrl->apcs_spm_events_addr = devm_kzalloc(&pdev->dev,
 | |
| -+						  SPM_EVENT_NUM
 | |
| -+						  * sizeof(void __iomem *),
 | |
| -+						  GFP_KERNEL);
 | |
| -+	if (!ctrl->apcs_spm_events_addr) {
 | |
| -+		dev_err(dev, "Failed to allocate memory for APCS SPM event registers\n");
 | |
| -+		return -ENOMEM;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < SPM_EVENT_NUM; i++) {
 | |
| -+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 | |
| -+						   res_name[i]);
 | |
| -+		if (!res) {
 | |
| -+			dev_err(dev, "Missing address for %s\n", res_name[i]);
 | |
| -+			ret = -EINVAL;
 | |
| -+			goto free_events;
 | |
| -+		}
 | |
| -+
 | |
| -+		ctrl->apcs_spm_events_addr[i] = devm_ioremap(dev, res->start,
 | |
| -+						resource_size(res));
 | |
| -+		if (!ctrl->apcs_spm_events_addr[i]) {
 | |
| -+			dev_err(dev, "Failed to map %s\n", res_name[i]);
 | |
| -+			ret = -ENOMEM;
 | |
| -+			goto free_events;
 | |
| -+		}
 | |
| -+
 | |
| -+		dev_dbg(dev, "%s event phys: %pa virt:0x%p\n", res_name[i],
 | |
| -+			&res->start, ctrl->apcs_spm_events_addr[i]);
 | |
| -+	}
 | |
| -+
 | |
| -+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 | |
| -+					   "apc0-pll-ctl");
 | |
| -+	if (!res) {
 | |
| -+		dev_err(dev, "Missing APC0 PLL CTL physical address\n");
 | |
| -+		ret = -EINVAL;
 | |
| -+		goto free_events;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->apc0_pll_ctl_addr = devm_ioremap(dev,
 | |
| -+					   res->start,
 | |
| -+					   resource_size(res));
 | |
| -+	if (!ctrl->apc0_pll_ctl_addr) {
 | |
| -+		dev_err(dev, "Failed to map APC0 PLL CTL register\n");
 | |
| -+		ret = -ENOMEM;
 | |
| -+		goto free_events;
 | |
| -+	}
 | |
| -+
 | |
| -+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 | |
| -+					   "apc1-pll-ctl");
 | |
| -+	if (!res) {
 | |
| -+		dev_err(dev, "Missing APC1 PLL CTL physical address\n");
 | |
| -+		ret = -EINVAL;
 | |
| -+		goto free_events;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->apc1_pll_ctl_addr = devm_ioremap(dev,
 | |
| -+					   res->start,
 | |
| -+					   resource_size(res));
 | |
| -+	if (!ctrl->apc1_pll_ctl_addr) {
 | |
| -+		dev_err(dev, "Failed to map APC1 PLL CTL register\n");
 | |
| -+		ret = -ENOMEM;
 | |
| -+		goto free_events;
 | |
| -+	}
 | |
| -+
 | |
| -+	return ret;
 | |
| -+
 | |
| -+free_events:
 | |
| -+	devm_kfree(dev, ctrl->apcs_spm_events_addr);
 | |
| -+	return ret;
 | |
| -+}
 | |
| -+
 | |
| -+/* 8953 register offset definition */
 | |
| -+#define MSM8953_APM_DLY_CNTR	0x2ac
 | |
| -+
 | |
| -+/* Register field shift definitions */
 | |
| -+#define APM_CTL_SEL_SWITCH_DLY_SHIFT	0
 | |
| -+#define APM_CTL_RESUME_CLK_DLY_SHIFT	8
 | |
| -+#define APM_CTL_HALT_CLK_DLY_SHIFT	16
 | |
| -+#define APM_CTL_POST_HALT_DLY_SHIFT	24
 | |
| -+
 | |
| -+/* Register field mask definitions */
 | |
| -+#define APM_CTL_SEL_SWITCH_DLY_MASK	GENMASK(7, 0)
 | |
| -+#define APM_CTL_RESUME_CLK_DLY_MASK	GENMASK(15, 8)
 | |
| -+#define APM_CTL_HALT_CLK_DLY_MASK	GENMASK(23, 16)
 | |
| -+#define APM_CTL_POST_HALT_DLY_MASK	GENMASK(31, 24)
 | |
| -+
 | |
| -+/*
 | |
| -+ * Get the resources associated with the msm8953 APM controller from
 | |
| -+ * device tree, remap all I/O addresses, and program the initial
 | |
| -+ * register configuration required for the 8953 APM controller device.
 | |
| -+ */
 | |
| -+static int msm8953_apm_ctrl_init(struct platform_device *pdev,
 | |
| -+				     struct msm_apm_ctrl_dev *ctrl)
 | |
| -+{
 | |
| -+	struct device *dev = &pdev->dev;
 | |
| -+	struct resource *res;
 | |
| -+	u32 delay_counter, val = 0, regval = 0;
 | |
| -+	int rc = 0;
 | |
| -+
 | |
| -+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pm-apcc-glb");
 | |
| -+	if (!res) {
 | |
| -+		dev_err(dev, "Missing PM APCC Global register physical address\n");
 | |
| -+		return -ENODEV;
 | |
| -+	}
 | |
| -+	ctrl->reg_base = devm_ioremap(dev, res->start, resource_size(res));
 | |
| -+	if (!ctrl->reg_base) {
 | |
| -+		dev_err(dev, "Failed to map PM APCC Global registers\n");
 | |
| -+		return -ENOMEM;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Initial APM register configuration required before starting
 | |
| -+	 * APM HW controller.
 | |
| -+	 */
 | |
| -+	regval = readl_relaxed(ctrl->reg_base + MSM8953_APM_DLY_CNTR);
 | |
| -+	val = regval;
 | |
| -+
 | |
| -+	if (of_find_property(dev->of_node, "qcom,apm-post-halt-delay", NULL)) {
 | |
| -+		rc = of_property_read_u32(dev->of_node,
 | |
| -+				"qcom,apm-post-halt-delay", &delay_counter);
 | |
| -+		if (rc < 0) {
 | |
| -+			dev_err(dev, "apm-post-halt-delay read failed, rc = %d",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		val &= ~APM_CTL_POST_HALT_DLY_MASK;
 | |
| -+		val |= (delay_counter << APM_CTL_POST_HALT_DLY_SHIFT)
 | |
| -+			& APM_CTL_POST_HALT_DLY_MASK;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (of_find_property(dev->of_node, "qcom,apm-halt-clk-delay", NULL)) {
 | |
| -+		rc = of_property_read_u32(dev->of_node,
 | |
| -+				"qcom,apm-halt-clk-delay", &delay_counter);
 | |
| -+		if (rc < 0) {
 | |
| -+			dev_err(dev, "apm-halt-clk-delay read failed, rc = %d",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		val &= ~APM_CTL_HALT_CLK_DLY_MASK;
 | |
| -+		val |= (delay_counter << APM_CTL_HALT_CLK_DLY_SHIFT)
 | |
| -+			& APM_CTL_HALT_CLK_DLY_MASK;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (of_find_property(dev->of_node, "qcom,apm-resume-clk-delay", NULL)) {
 | |
| -+		rc = of_property_read_u32(dev->of_node,
 | |
| -+				"qcom,apm-resume-clk-delay", &delay_counter);
 | |
| -+		if (rc < 0) {
 | |
| -+			dev_err(dev, "apm-resume-clk-delay read failed, rc = %d",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		val &= ~APM_CTL_RESUME_CLK_DLY_MASK;
 | |
| -+		val |= (delay_counter << APM_CTL_RESUME_CLK_DLY_SHIFT)
 | |
| -+			& APM_CTL_RESUME_CLK_DLY_MASK;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (of_find_property(dev->of_node, "qcom,apm-sel-switch-delay", NULL)) {
 | |
| -+		rc = of_property_read_u32(dev->of_node,
 | |
| -+				"qcom,apm-sel-switch-delay", &delay_counter);
 | |
| -+		if (rc < 0) {
 | |
| -+			dev_err(dev, "apm-sel-switch-delay read failed, rc = %d",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		val &= ~APM_CTL_SEL_SWITCH_DLY_MASK;
 | |
| -+		val |= (delay_counter << APM_CTL_SEL_SWITCH_DLY_SHIFT)
 | |
| -+			& APM_CTL_SEL_SWITCH_DLY_MASK;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (val != regval) {
 | |
| -+		writel_relaxed(val, ctrl->reg_base + MSM8953_APM_DLY_CNTR);
 | |
| -+		/* make sure write completes before return */
 | |
| -+		mb();
 | |
| -+	}
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+static int msm8996_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{
 | |
| -+	int i, timeout = MSM_APM_SWITCH_TIMEOUT_US;
 | |
| -+	u32 regval;
 | |
| -+	int ret = 0;
 | |
| -+	unsigned long flags;
 | |
| -+
 | |
| -+	spin_lock_irqsave(&ctrl_dev->lock, flags);
 | |
| -+
 | |
| -+	/* Perform revision-specific programming steps */
 | |
| -+	if (ctrl_dev->version < HMSS_VERSION_1P2) {
 | |
| -+		/* Clear SPM events */
 | |
| -+		for (i = 0; i < SPM_EVENT_NUM; i++)
 | |
| -+			writel_relaxed(SPM_EVENT_CLEAR_VAL,
 | |
| -+				       ctrl_dev->apcs_spm_events_addr[i]);
 | |
| -+
 | |
| -+		udelay(SPM_WAKEUP_DELAY_US);
 | |
| -+
 | |
| -+		/* Switch APC/CBF to GPLL0 clock */
 | |
| -+		writel_relaxed(APCS_GFMUXA_SEL_VAL,
 | |
| -+			       ctrl_dev->apcs_csr_base + APCS_SPARE);
 | |
| -+		ndelay(200);
 | |
| -+		writel_relaxed(MSM_APM_OVERRIDE_SEL_VAL,
 | |
| -+			       ctrl_dev->apc0_pll_ctl_addr);
 | |
| -+		ndelay(200);
 | |
| -+		writel_relaxed(MSM_APM_OVERRIDE_SEL_VAL,
 | |
| -+			       ctrl_dev->apc1_pll_ctl_addr);
 | |
| -+
 | |
| -+		/* Ensure writes complete before proceeding */
 | |
| -+		mb();
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Switch arrays to MX supply and wait for its completion */
 | |
| -+	writel_relaxed(MSM_APM_MX_MODE_VAL, ctrl_dev->reg_base +
 | |
| -+		       APCC_APM_MODE);
 | |
| -+
 | |
| -+	/* Ensure write above completes before delaying */
 | |
| -+	mb();
 | |
| -+
 | |
| -+	while (timeout > 0) {
 | |
| -+		regval = readl_relaxed(ctrl_dev->reg_base + APCC_APM_CTL_STS);
 | |
| -+		if ((regval & MSM_APM_CTL_STS_MASK) ==
 | |
| -+		    MSM_APM_MX_DONE_VAL)
 | |
| -+			break;
 | |
| -+
 | |
| -+		udelay(1);
 | |
| -+		timeout--;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (timeout == 0) {
 | |
| -+		ret = -ETIMEDOUT;
 | |
| -+		dev_err(ctrl_dev->dev, "APCC to MX APM switch timed out. APCC_APM_CTL_STS=0x%x\n",
 | |
| -+			regval);
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Perform revision-specific programming steps */
 | |
| -+	if (ctrl_dev->version < HMSS_VERSION_1P2) {
 | |
| -+		/* Switch APC/CBF clocks to original source */
 | |
| -+		writel_relaxed(APCS_GFMUXA_DESEL_VAL,
 | |
| -+			       ctrl_dev->apcs_csr_base + APCS_SPARE);
 | |
| -+		ndelay(200);
 | |
| -+		writel_relaxed(MSM_APM_SEC_CLK_SEL_VAL,
 | |
| -+			       ctrl_dev->apc0_pll_ctl_addr);
 | |
| -+		ndelay(200);
 | |
| -+		writel_relaxed(MSM_APM_SEC_CLK_SEL_VAL,
 | |
| -+			       ctrl_dev->apc1_pll_ctl_addr);
 | |
| -+
 | |
| -+		/* Complete clock source switch before SPM event sequence */
 | |
| -+		mb();
 | |
| -+
 | |
| -+		/* Set SPM events */
 | |
| -+		for (i = 0; i < SPM_EVENT_NUM; i++)
 | |
| -+			writel_relaxed(SPM_EVENT_SET_VAL,
 | |
| -+				       ctrl_dev->apcs_spm_events_addr[i]);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!ret) {
 | |
| -+		ctrl_dev->supply = MSM_APM_SUPPLY_MX;
 | |
| -+		dev_dbg(ctrl_dev->dev, "APM supply switched to MX\n");
 | |
| -+	}
 | |
| -+
 | |
| -+	spin_unlock_irqrestore(&ctrl_dev->lock, flags);
 | |
| -+
 | |
| -+	return ret;
 | |
| -+}
 | |
| -+
 | |
| -+static int msm8996_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{
 | |
| -+	int i, timeout = MSM_APM_SWITCH_TIMEOUT_US;
 | |
| -+	u32 regval;
 | |
| -+	int ret = 0;
 | |
| -+	unsigned long flags;
 | |
| -+
 | |
| -+	spin_lock_irqsave(&ctrl_dev->lock, flags);
 | |
| -+
 | |
| -+	/* Perform revision-specific programming steps */
 | |
| -+	if (ctrl_dev->version < HMSS_VERSION_1P2) {
 | |
| -+		/* Clear SPM events */
 | |
| -+		for (i = 0; i < SPM_EVENT_NUM; i++)
 | |
| -+			writel_relaxed(SPM_EVENT_CLEAR_VAL,
 | |
| -+				       ctrl_dev->apcs_spm_events_addr[i]);
 | |
| -+
 | |
| -+		udelay(SPM_WAKEUP_DELAY_US);
 | |
| -+
 | |
| -+		/* Switch APC/CBF to GPLL0 clock */
 | |
| -+		writel_relaxed(APCS_GFMUXA_SEL_VAL,
 | |
| -+			       ctrl_dev->apcs_csr_base + APCS_SPARE);
 | |
| -+		ndelay(200);
 | |
| -+		writel_relaxed(MSM_APM_OVERRIDE_SEL_VAL,
 | |
| -+			       ctrl_dev->apc0_pll_ctl_addr);
 | |
| -+		ndelay(200);
 | |
| -+		writel_relaxed(MSM_APM_OVERRIDE_SEL_VAL,
 | |
| -+			       ctrl_dev->apc1_pll_ctl_addr);
 | |
| -+
 | |
| -+		/* Ensure previous writes complete before proceeding */
 | |
| -+		mb();
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Switch arrays to APCC supply and wait for its completion */
 | |
| -+	writel_relaxed(MSM_APM_APCC_MODE_VAL, ctrl_dev->reg_base +
 | |
| -+		       APCC_APM_MODE);
 | |
| -+
 | |
| -+	/* Ensure write above completes before delaying */
 | |
| -+	mb();
 | |
| -+
 | |
| -+	while (timeout > 0) {
 | |
| -+		regval = readl_relaxed(ctrl_dev->reg_base + APCC_APM_CTL_STS);
 | |
| -+		if ((regval & MSM_APM_CTL_STS_MASK) ==
 | |
| -+		    MSM_APM_APCC_DONE_VAL)
 | |
| -+			break;
 | |
| -+
 | |
| -+		udelay(1);
 | |
| -+		timeout--;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (timeout == 0) {
 | |
| -+		ret = -ETIMEDOUT;
 | |
| -+		dev_err(ctrl_dev->dev, "MX to APCC APM switch timed out. APCC_APM_CTL_STS=0x%x\n",
 | |
| -+			regval);
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Perform revision-specific programming steps */
 | |
| -+	if (ctrl_dev->version < HMSS_VERSION_1P2) {
 | |
| -+		/* Set SPM events */
 | |
| -+		for (i = 0; i < SPM_EVENT_NUM; i++)
 | |
| -+			writel_relaxed(SPM_EVENT_SET_VAL,
 | |
| -+				       ctrl_dev->apcs_spm_events_addr[i]);
 | |
| -+
 | |
| -+		/* Complete SPM event sequence before clock source switch */
 | |
| -+		mb();
 | |
| -+
 | |
| -+		/* Switch APC/CBF clocks to original source */
 | |
| -+		writel_relaxed(APCS_GFMUXA_DESEL_VAL,
 | |
| -+			       ctrl_dev->apcs_csr_base + APCS_SPARE);
 | |
| -+		ndelay(200);
 | |
| -+		writel_relaxed(MSM_APM_SEC_CLK_SEL_VAL,
 | |
| -+			       ctrl_dev->apc0_pll_ctl_addr);
 | |
| -+		ndelay(200);
 | |
| -+		writel_relaxed(MSM_APM_SEC_CLK_SEL_VAL,
 | |
| -+			       ctrl_dev->apc1_pll_ctl_addr);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!ret) {
 | |
| -+		ctrl_dev->supply = MSM_APM_SUPPLY_APCC;
 | |
| -+		dev_dbg(ctrl_dev->dev, "APM supply switched to APCC\n");
 | |
| -+	}
 | |
| -+
 | |
| -+	spin_unlock_irqrestore(&ctrl_dev->lock, flags);
 | |
| -+
 | |
| -+	return ret;
 | |
| -+}
 | |
| -+
 | |
| -+/* 8953 register value definitions */
 | |
| -+#define MSM8953_APM_MX_MODE_VAL            0x00
 | |
| -+#define MSM8953_APM_APCC_MODE_VAL          0x02
 | |
| -+#define MSM8953_APM_MX_DONE_VAL            0x00
 | |
| -+#define MSM8953_APM_APCC_DONE_VAL          0x03
 | |
| -+
 | |
| -+/* 8953 register offset definitions */
 | |
| -+#define MSM8953_APCC_APM_MODE              0x000002a8
 | |
| -+#define MSM8953_APCC_APM_CTL_STS           0x000002b0
 | |
| -+
 | |
| -+/* 8953 constants */
 | |
| -+#define MSM8953_APM_SWITCH_TIMEOUT_US      500
 | |
| -+
 | |
| -+/* Register bit mask definitions */
 | |
| -+#define MSM8953_APM_CTL_STS_MASK           0x1f
 | |
| -+
 | |
| -+static int msm8953_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{
 | |
| -+	int timeout = MSM8953_APM_SWITCH_TIMEOUT_US;
 | |
| -+	u32 regval;
 | |
| -+	int ret = 0;
 | |
| -+	unsigned long flags;
 | |
| -+
 | |
| -+	spin_lock_irqsave(&ctrl_dev->lock, flags);
 | |
| -+
 | |
| -+	/* Switch arrays to MX supply and wait for its completion */
 | |
| -+	writel_relaxed(MSM8953_APM_MX_MODE_VAL, ctrl_dev->reg_base +
 | |
| -+		       MSM8953_APCC_APM_MODE);
 | |
| -+
 | |
| -+	/* Ensure write above completes before delaying */
 | |
| -+	mb();
 | |
| -+
 | |
| -+	while (timeout > 0) {
 | |
| -+		regval = readl_relaxed(ctrl_dev->reg_base +
 | |
| -+					MSM8953_APCC_APM_CTL_STS);
 | |
| -+		if ((regval & MSM8953_APM_CTL_STS_MASK) ==
 | |
| -+				MSM8953_APM_MX_DONE_VAL)
 | |
| -+			break;
 | |
| -+
 | |
| -+		udelay(1);
 | |
| -+		timeout--;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (timeout == 0) {
 | |
| -+		ret = -ETIMEDOUT;
 | |
| -+		dev_err(ctrl_dev->dev, "APCC to MX APM switch timed out. APCC_APM_CTL_STS=0x%x\n",
 | |
| -+			regval);
 | |
| -+	} else {
 | |
| -+		ctrl_dev->supply = MSM_APM_SUPPLY_MX;
 | |
| -+		dev_dbg(ctrl_dev->dev, "APM supply switched to MX\n");
 | |
| -+	}
 | |
| -+
 | |
| -+	spin_unlock_irqrestore(&ctrl_dev->lock, flags);
 | |
| -+
 | |
| -+	return ret;
 | |
| -+}
 | |
| -+
 | |
| -+static int msm8953_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{
 | |
| -+	int timeout = MSM8953_APM_SWITCH_TIMEOUT_US;
 | |
| -+	u32 regval;
 | |
| -+	int ret = 0;
 | |
| -+	unsigned long flags;
 | |
| -+
 | |
| -+	spin_lock_irqsave(&ctrl_dev->lock, flags);
 | |
| -+
 | |
| -+	/* Switch arrays to APCC supply and wait for its completion */
 | |
| -+	writel_relaxed(MSM8953_APM_APCC_MODE_VAL, ctrl_dev->reg_base +
 | |
| -+		       MSM8953_APCC_APM_MODE);
 | |
| -+
 | |
| -+	/* Ensure write above completes before delaying */
 | |
| -+	mb();
 | |
| -+
 | |
| -+	while (timeout > 0) {
 | |
| -+		regval = readl_relaxed(ctrl_dev->reg_base +
 | |
| -+					MSM8953_APCC_APM_CTL_STS);
 | |
| -+		if ((regval & MSM8953_APM_CTL_STS_MASK) ==
 | |
| -+				MSM8953_APM_APCC_DONE_VAL)
 | |
| -+			break;
 | |
| -+
 | |
| -+		udelay(1);
 | |
| -+		timeout--;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (timeout == 0) {
 | |
| -+		ret = -ETIMEDOUT;
 | |
| -+		dev_err(ctrl_dev->dev, "MX to APCC APM switch timed out. APCC_APM_CTL_STS=0x%x\n",
 | |
| -+			regval);
 | |
| -+	} else {
 | |
| -+		ctrl_dev->supply = MSM_APM_SUPPLY_APCC;
 | |
| -+		dev_dbg(ctrl_dev->dev, "APM supply switched to APCC\n");
 | |
| -+	}
 | |
| -+
 | |
| -+	spin_unlock_irqrestore(&ctrl_dev->lock, flags);
 | |
| -+
 | |
| -+	return ret;
 | |
| -+}
 | |
| -+
 | |
| -+static int msm_apm_switch_to_mx(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{
 | |
| -+	int ret = 0;
 | |
| -+
 | |
| -+	switch (ctrl_dev->msm_id) {
 | |
| -+	case MSM8996_ID:
 | |
| -+		ret = msm8996_apm_switch_to_mx(ctrl_dev);
 | |
| -+		break;
 | |
| -+	case MSM8953_ID:
 | |
| -+	case IPQ807x_ID:
 | |
| -+		ret = msm8953_apm_switch_to_mx(ctrl_dev);
 | |
| -+		break;
 | |
| -+	}
 | |
| -+
 | |
| -+	return ret;
 | |
| -+}
 | |
| -+
 | |
| -+static int msm_apm_switch_to_apcc(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{
 | |
| -+	int ret = 0;
 | |
| -+
 | |
| -+	switch (ctrl_dev->msm_id) {
 | |
| -+	case MSM8996_ID:
 | |
| -+		ret = msm8996_apm_switch_to_apcc(ctrl_dev);
 | |
| -+		break;
 | |
| -+	case MSM8953_ID:
 | |
| -+	case IPQ807x_ID:
 | |
| -+		ret = msm8953_apm_switch_to_apcc(ctrl_dev);
 | |
| -+		break;
 | |
| -+	}
 | |
| -+
 | |
| -+	return ret;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * msm_apm_get_supply() - Returns the supply that is currently
 | |
| -+ *			powering the memory arrays
 | |
| -+ * @ctrl_dev:                   Pointer to an MSM APM controller device
 | |
| -+ *
 | |
| -+ * Returns the supply currently selected by the APM.
 | |
| -+ */
 | |
| -+int msm_apm_get_supply(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{
 | |
| -+	return ctrl_dev->supply;
 | |
| -+}
 | |
| -+EXPORT_SYMBOL(msm_apm_get_supply);
 | |
| -+
 | |
| -+/**
 | |
| -+ * msm_apm_set_supply() - Perform the necessary steps to switch the voltage
 | |
| -+ *                        source of the memory arrays to a given supply
 | |
| -+ * @ctrl_dev:                   Pointer to an MSM APM controller device
 | |
| -+ * @supply:                     Power rail to use as supply for the memory
 | |
| -+ *                              arrays
 | |
| -+ *
 | |
| -+ * Returns 0 on success, -ETIMEDOUT on APM switch timeout, or -EPERM if
 | |
| -+ * the supply is not supported.
 | |
| -+ */
 | |
| -+int msm_apm_set_supply(struct msm_apm_ctrl_dev *ctrl_dev,
 | |
| -+		       enum msm_apm_supply supply)
 | |
| -+{
 | |
| -+	int ret;
 | |
| -+
 | |
| -+	switch (supply) {
 | |
| -+	case MSM_APM_SUPPLY_APCC:
 | |
| -+		ret = msm_apm_switch_to_apcc(ctrl_dev);
 | |
| -+		break;
 | |
| -+	case MSM_APM_SUPPLY_MX:
 | |
| -+		ret = msm_apm_switch_to_mx(ctrl_dev);
 | |
| -+		break;
 | |
| -+	default:
 | |
| -+		ret = -EPERM;
 | |
| -+		break;
 | |
| -+	}
 | |
| -+
 | |
| -+	return ret;
 | |
| -+}
 | |
| -+EXPORT_SYMBOL(msm_apm_set_supply);
 | |
| -+
 | |
| -+/**
 | |
| -+ * msm_apm_ctrl_dev_get() - get a handle to the MSM APM controller linked to
 | |
| -+ *                          the device in device tree
 | |
| -+ * @dev:                    Pointer to the device
 | |
| -+ *
 | |
| -+ * The device must specify "qcom,apm-ctrl" property in its device tree
 | |
| -+ * node which points to an MSM APM controller device node.
 | |
| -+ *
 | |
| -+ * Returns an MSM APM controller handle if successful or ERR_PTR on any error.
 | |
| -+ * If the APM controller device hasn't probed yet, ERR_PTR(-EPROBE_DEFER) is
 | |
| -+ * returned.
 | |
| -+ */
 | |
| -+struct msm_apm_ctrl_dev *msm_apm_ctrl_dev_get(struct device *dev)
 | |
| -+{
 | |
| -+	struct msm_apm_ctrl_dev *ctrl_dev = NULL;
 | |
| -+	struct msm_apm_ctrl_dev *dev_found = ERR_PTR(-EPROBE_DEFER);
 | |
| -+	struct device_node *ctrl_node;
 | |
| -+
 | |
| -+	if (!dev || !dev->of_node) {
 | |
| -+		pr_err("Invalid device node\n");
 | |
| -+		return ERR_PTR(-EINVAL);
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl_node = of_parse_phandle(dev->of_node, "qcom,apm-ctrl", 0);
 | |
| -+	if (!ctrl_node) {
 | |
| -+		pr_err("Could not find qcom,apm-ctrl property in %s\n",
 | |
| -+		       dev->of_node->full_name);
 | |
| -+		return ERR_PTR(-ENXIO);
 | |
| -+	}
 | |
| -+
 | |
| -+	mutex_lock(&apm_ctrl_list_mutex);
 | |
| -+	list_for_each_entry(ctrl_dev, &apm_ctrl_list, list) {
 | |
| -+		if (ctrl_dev->dev && ctrl_dev->dev->of_node == ctrl_node) {
 | |
| -+			dev_found = ctrl_dev;
 | |
| -+			break;
 | |
| -+		}
 | |
| -+	}
 | |
| -+	mutex_unlock(&apm_ctrl_list_mutex);
 | |
| -+
 | |
| -+	of_node_put(ctrl_node);
 | |
| -+	return dev_found;
 | |
| -+}
 | |
| -+EXPORT_SYMBOL(msm_apm_ctrl_dev_get);
 | |
| -+
 | |
| -+#if defined(CONFIG_DEBUG_FS)
 | |
| -+
 | |
| -+static int apm_supply_dbg_open(struct inode *inode, struct file *filep)
 | |
| -+{
 | |
| -+	filep->private_data = inode->i_private;
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static ssize_t apm_supply_dbg_read(struct file *filep, char __user *ubuf,
 | |
| -+				   size_t count, loff_t *ppos)
 | |
| -+{
 | |
| -+	struct msm_apm_ctrl_dev *ctrl_dev = filep->private_data;
 | |
| -+	char buf[10];
 | |
| -+	int len;
 | |
| -+
 | |
| -+	if (!ctrl_dev) {
 | |
| -+		pr_err("invalid apm ctrl handle\n");
 | |
| -+		return -ENODEV;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl_dev->supply == MSM_APM_SUPPLY_APCC)
 | |
| -+		len = snprintf(buf, sizeof(buf), "APCC\n");
 | |
| -+	else if (ctrl_dev->supply == MSM_APM_SUPPLY_MX)
 | |
| -+		len = snprintf(buf, sizeof(buf), "MX\n");
 | |
| -+	else
 | |
| -+		len = snprintf(buf, sizeof(buf), "ERR\n");
 | |
| -+
 | |
| -+	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
 | |
| -+}
 | |
| -+
 | |
| -+static const struct file_operations apm_supply_fops = {
 | |
| -+	.open = apm_supply_dbg_open,
 | |
| -+	.read = apm_supply_dbg_read,
 | |
| -+};
 | |
| -+
 | |
| -+static void apm_debugfs_base_init(void)
 | |
| -+{
 | |
| -+	apm_debugfs_base = debugfs_create_dir("msm-apm", NULL);
 | |
| -+
 | |
| -+	if (IS_ERR_OR_NULL(apm_debugfs_base))
 | |
| -+		pr_err("msm-apm debugfs base directory creation failed\n");
 | |
| -+}
 | |
| -+
 | |
| -+static void apm_debugfs_init(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{
 | |
| -+	struct dentry *temp;
 | |
| -+
 | |
| -+	if (IS_ERR_OR_NULL(apm_debugfs_base)) {
 | |
| -+		pr_err("Base directory missing, cannot create apm debugfs nodes\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl_dev->debugfs = debugfs_create_dir(dev_name(ctrl_dev->dev),
 | |
| -+					       apm_debugfs_base);
 | |
| -+	if (IS_ERR_OR_NULL(ctrl_dev->debugfs)) {
 | |
| -+		pr_err("%s debugfs directory creation failed\n",
 | |
| -+		       dev_name(ctrl_dev->dev));
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_file("supply", S_IRUGO, ctrl_dev->debugfs,
 | |
| -+				   ctrl_dev, &apm_supply_fops);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		pr_err("supply mode creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+}
 | |
| -+
 | |
| -+static void apm_debugfs_deinit(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{
 | |
| -+	if (!IS_ERR_OR_NULL(ctrl_dev->debugfs))
 | |
| -+		debugfs_remove_recursive(ctrl_dev->debugfs);
 | |
| -+}
 | |
| -+
 | |
| -+static void apm_debugfs_base_remove(void)
 | |
| -+{
 | |
| -+	debugfs_remove_recursive(apm_debugfs_base);
 | |
| -+}
 | |
| -+#else
 | |
| -+
 | |
| -+static void apm_debugfs_base_init(void)
 | |
| -+{}
 | |
| -+
 | |
| -+static void apm_debugfs_init(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{}
 | |
| -+
 | |
| -+static void apm_debugfs_deinit(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{}
 | |
| -+
 | |
| -+static void apm_debugfs_base_remove(void)
 | |
| -+{}
 | |
| -+
 | |
| -+#endif
 | |
| -+
 | |
| -+static struct of_device_id msm_apm_match_table[] = {
 | |
| -+	{
 | |
| -+		.compatible = "qcom,msm-apm",
 | |
| -+		.data = (void *)(uintptr_t)MSM8996_ID,
 | |
| -+	},
 | |
| -+	{
 | |
| -+		.compatible = "qcom,msm8953-apm",
 | |
| -+		.data = (void *)(uintptr_t)MSM8953_ID,
 | |
| -+	},
 | |
| -+	{
 | |
| -+		.compatible = "qcom,ipq807x-apm",
 | |
| -+		.data = (void *)(uintptr_t)IPQ807x_ID,
 | |
| -+	},
 | |
| -+	{}
 | |
| -+};
 | |
| -+
 | |
| -+static int msm_apm_probe(struct platform_device *pdev)
 | |
| -+{
 | |
| -+	struct device *dev = &pdev->dev;
 | |
| -+	struct msm_apm_ctrl_dev *ctrl;
 | |
| -+	const struct of_device_id *match;
 | |
| -+	int ret = 0;
 | |
| -+
 | |
| -+	dev_dbg(dev, "probing MSM Array Power Mux driver\n");
 | |
| -+
 | |
| -+	if (!dev->of_node) {
 | |
| -+		dev_err(dev, "Device tree node is missing\n");
 | |
| -+		return -ENODEV;
 | |
| -+	}
 | |
| -+
 | |
| -+	match = of_match_device(msm_apm_match_table, dev);
 | |
| -+	if (!match)
 | |
| -+		return -ENODEV;
 | |
| -+
 | |
| -+	ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
 | |
| -+	if (!ctrl) {
 | |
| -+		dev_err(dev, "MSM APM controller memory allocation failed\n");
 | |
| -+		return -ENOMEM;
 | |
| -+	}
 | |
| -+
 | |
| -+	INIT_LIST_HEAD(&ctrl->list);
 | |
| -+	spin_lock_init(&ctrl->lock);
 | |
| -+	ctrl->dev = dev;
 | |
| -+	ctrl->msm_id = (uintptr_t)match->data;
 | |
| -+	platform_set_drvdata(pdev, ctrl);
 | |
| -+
 | |
| -+	switch (ctrl->msm_id) {
 | |
| -+	case MSM8996_ID:
 | |
| -+		ret = msm_apm_ctrl_devm_ioremap(pdev, ctrl);
 | |
| -+		if (ret) {
 | |
| -+			dev_err(dev, "Failed to add APM controller device\n");
 | |
| -+			return ret;
 | |
| -+		}
 | |
| -+		break;
 | |
| -+	case MSM8953_ID:
 | |
| -+	case IPQ807x_ID:
 | |
| -+		ret = msm8953_apm_ctrl_init(pdev, ctrl);
 | |
| -+		if (ret) {
 | |
| -+			dev_err(dev, "Failed to initialize APM controller device: ret=%d\n",
 | |
| -+				ret);
 | |
| -+			return ret;
 | |
| -+		}
 | |
| -+		break;
 | |
| -+	default:
 | |
| -+		dev_err(dev, "unable to add APM controller device for msm_id:%d\n",
 | |
| -+			ctrl->msm_id);
 | |
| -+		return -ENODEV;
 | |
| -+	}
 | |
| -+
 | |
| -+	apm_debugfs_init(ctrl);
 | |
| -+	mutex_lock(&apm_ctrl_list_mutex);
 | |
| -+	list_add_tail(&ctrl->list, &apm_ctrl_list);
 | |
| -+	mutex_unlock(&apm_ctrl_list_mutex);
 | |
| -+
 | |
| -+	dev_dbg(dev, "MSM Array Power Mux driver probe successful");
 | |
| -+
 | |
| -+	return ret;
 | |
| -+}
 | |
| -+
 | |
| -+static int msm_apm_remove(struct platform_device *pdev)
 | |
| -+{
 | |
| -+	struct msm_apm_ctrl_dev *ctrl_dev;
 | |
| -+
 | |
| -+	ctrl_dev = platform_get_drvdata(pdev);
 | |
| -+	if (ctrl_dev) {
 | |
| -+		mutex_lock(&apm_ctrl_list_mutex);
 | |
| -+		list_del(&ctrl_dev->list);
 | |
| -+		mutex_unlock(&apm_ctrl_list_mutex);
 | |
| -+		apm_debugfs_deinit(ctrl_dev);
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static struct platform_driver msm_apm_driver = {
 | |
| -+	.driver		= {
 | |
| -+		.name		= MSM_APM_DRIVER_NAME,
 | |
| -+		.of_match_table	= msm_apm_match_table,
 | |
| -+		.owner		= THIS_MODULE,
 | |
| -+	},
 | |
| -+	.probe		= msm_apm_probe,
 | |
| -+	.remove		= msm_apm_remove,
 | |
| -+};
 | |
| -+
 | |
| -+static int __init msm_apm_init(void)
 | |
| -+{
 | |
| -+	apm_debugfs_base_init();
 | |
| -+	return platform_driver_register(&msm_apm_driver);
 | |
| -+}
 | |
| -+
 | |
| -+static void __exit msm_apm_exit(void)
 | |
| -+{
 | |
| -+	platform_driver_unregister(&msm_apm_driver);
 | |
| -+	apm_debugfs_base_remove();
 | |
| -+}
 | |
| -+
 | |
| -+arch_initcall(msm_apm_init);
 | |
| -+module_exit(msm_apm_exit);
 | |
| -+
 | |
| -+MODULE_DESCRIPTION("MSM Array Power Mux driver");
 | |
| -+MODULE_LICENSE("GPL v2");
 | |
| ---- /dev/null
 | |
| -+++ b/include/linux/power/qcom/apm.h
 | |
| -@@ -0,0 +1,48 @@
 | |
| -+/*
 | |
| -+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
 | |
| -+ *
 | |
| -+ * This program is free software; you can redistribute it and/or modify
 | |
| -+ * it under the terms of the GNU General Public License version 2 and
 | |
| -+ * only version 2 as published by the Free Software Foundation.
 | |
| -+ *
 | |
| -+ * This program is distributed in the hope that it will be useful,
 | |
| -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| -+ * GNU General Public License for more details.
 | |
| -+ */
 | |
| -+
 | |
| -+#ifndef __LINUX_POWER_QCOM_APM_H__
 | |
| -+#define __LINUX_POWER_QCOM_APM_H__
 | |
| -+
 | |
| -+#include <linux/device.h>
 | |
| -+#include <linux/err.h>
 | |
| -+
 | |
| -+/**
 | |
| -+ * enum msm_apm_supply - supported power rails to supply memory arrays
 | |
| -+ * %MSM_APM_SUPPLY_APCC:	to enable selection of VDD_APCC rail as supply
 | |
| -+ * %MSM_APM_SUPPLY_MX:		to enable selection of VDD_MX rail as supply
 | |
| -+ */
 | |
| -+enum msm_apm_supply {
 | |
| -+	MSM_APM_SUPPLY_APCC,
 | |
| -+	MSM_APM_SUPPLY_MX,
 | |
| -+};
 | |
| -+
 | |
| -+/* Handle used to identify an APM controller device  */
 | |
| -+struct msm_apm_ctrl_dev;
 | |
| -+
 | |
| -+#ifdef CONFIG_QCOM_APM
 | |
| -+struct msm_apm_ctrl_dev *msm_apm_ctrl_dev_get(struct device *dev);
 | |
| -+int msm_apm_set_supply(struct msm_apm_ctrl_dev *ctrl_dev,
 | |
| -+		       enum msm_apm_supply supply);
 | |
| -+int msm_apm_get_supply(struct msm_apm_ctrl_dev *ctrl_dev);
 | |
| -+
 | |
| -+#else
 | |
| -+static inline struct msm_apm_ctrl_dev *msm_apm_ctrl_dev_get(struct device *dev)
 | |
| -+{ return ERR_PTR(-EPERM); }
 | |
| -+static inline int msm_apm_set_supply(struct msm_apm_ctrl_dev *ctrl_dev,
 | |
| -+		       enum msm_apm_supply supply)
 | |
| -+{ return -EPERM; }
 | |
| -+static inline int msm_apm_get_supply(struct msm_apm_ctrl_dev *ctrl_dev)
 | |
| -+{ return -EPERM; }
 | |
| -+#endif
 | |
| -+#endif
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0901-regulator-add-Qualcomm-CPR-regulators.patch b/target/linux/ipq807x/patches-5.15/0901-regulator-add-Qualcomm-CPR-regulators.patch
 | |
| deleted file mode 100644
 | |
| index 3deadea139..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0901-regulator-add-Qualcomm-CPR-regulators.patch
 | |
| +++ /dev/null
 | |
| @@ -1,12147 +0,0 @@
 | |
| -From 303fb163bb86f04432c93325ff8b9638c9e50641 Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Mon, 11 Apr 2022 14:35:36 +0200
 | |
| -Subject: [PATCH] regulator: add Qualcomm CPR regulators
 | |
| -
 | |
| -Add Qualcomm CPR driver, which allows using the CPR HW to calculate the
 | |
| -correct OPP point voltage dynamically based on the system load.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - drivers/regulator/Kconfig               |   33 +
 | |
| - drivers/regulator/Makefile              |    3 +
 | |
| - drivers/regulator/cpr3-npu-regulator.c  |  695 +++
 | |
| - drivers/regulator/cpr3-regulator.c      | 5112 +++++++++++++++++++++++
 | |
| - drivers/regulator/cpr3-regulator.h      | 1211 ++++++
 | |
| - drivers/regulator/cpr3-util.c           | 2750 ++++++++++++
 | |
| - drivers/regulator/cpr4-apss-regulator.c | 1819 ++++++++
 | |
| - include/soc/qcom/socinfo.h              |  463 ++
 | |
| - 8 files changed, 12086 insertions(+)
 | |
| - create mode 100644 drivers/regulator/cpr3-npu-regulator.c
 | |
| - create mode 100644 drivers/regulator/cpr3-regulator.c
 | |
| - create mode 100644 drivers/regulator/cpr3-regulator.h
 | |
| - create mode 100644 drivers/regulator/cpr3-util.c
 | |
| - create mode 100644 drivers/regulator/cpr4-apss-regulator.c
 | |
| - create mode 100644 include/soc/qcom/socinfo.h
 | |
| -
 | |
| ---- a/drivers/regulator/Kconfig
 | |
| -+++ b/drivers/regulator/Kconfig
 | |
| -@@ -1423,5 +1423,38 @@ config REGULATOR_QCOM_LABIBB
 | |
| - 	  boost regulator and IBB can be used as a negative boost regulator
 | |
| - 	  for LCD display panel.
 | |
| - 
 | |
| -+config REGULATOR_CPR3
 | |
| -+	bool "QCOM CPR3 regulator core support"
 | |
| -+	help
 | |
| -+	  This driver supports Core Power Reduction (CPR) version 3 controllers
 | |
| -+	  which are used by some Qualcomm Technologies, Inc. SoCs to
 | |
| -+	  manage important voltage regulators.  CPR3 controllers are capable of
 | |
| -+	  monitoring several ring oscillator sensing loops simultaneously.  The
 | |
| -+	  CPR3 controller informs software when the silicon conditions require
 | |
| -+	  the supply voltage to be increased or decreased.  On certain supply
 | |
| -+	  rails, the CPR3 controller is able to propagate the voltage increase
 | |
| -+	  or decrease requests all the way to the PMIC without software
 | |
| -+	  involvement.
 | |
| -+
 | |
| -+config REGULATOR_CPR3_NPU
 | |
| -+	bool "QCOM CPR3 regulator for NPU"
 | |
| -+	depends on OF && REGULATOR_CPR3
 | |
| -+	help
 | |
| -+	  This driver supports Qualcomm Technologies, Inc. NPU CPR3
 | |
| -+	  regulator Which will always operate in open loop.
 | |
| -+
 | |
| -+config REGULATOR_CPR4_APSS
 | |
| -+	bool "QCOM CPR4 regulator for APSS"
 | |
| -+	depends on OF && REGULATOR_CPR3
 | |
| -+	help
 | |
| -+	  This driver supports Qualcomm Technologies, Inc. APSS application
 | |
| -+	  processor specific features including memory array power mux (APM)
 | |
| -+	  switching, one CPR4 thread which monitor the two APSS clusters that
 | |
| -+	  are both powered by a shared supply, hardware closed-loop auto
 | |
| -+	  voltage stepping, voltage adjustments based on online core count,
 | |
| -+	  voltage adjustments based on temperature readings, and voltage
 | |
| -+	  adjustments for performance boost mode. This driver reads both initial
 | |
| -+	  voltage and CPR target quotient values out of hardware fuses.
 | |
| -+
 | |
| - endif
 | |
| - 
 | |
| ---- a/drivers/regulator/Makefile
 | |
| -+++ b/drivers/regulator/Makefile
 | |
| -@@ -105,6 +105,9 @@ obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qco
 | |
| - obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
 | |
| - obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o
 | |
| - obj-$(CONFIG_REGULATOR_QCOM_USB_VBUS) += qcom_usb_vbus-regulator.o
 | |
| -+obj-$(CONFIG_REGULATOR_CPR3) += cpr3-regulator.o cpr3-util.o
 | |
| -+obj-$(CONFIG_REGULATOR_CPR3_NPU) += cpr3-npu-regulator.o
 | |
| -+obj-$(CONFIG_REGULATOR_CPR4_APSS) += cpr4-apss-regulator.o
 | |
| - obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
 | |
| - obj-$(CONFIG_REGULATOR_PCA9450) += pca9450-regulator.o
 | |
| - obj-$(CONFIG_REGULATOR_PF8X00) += pf8x00-regulator.o
 | |
| ---- /dev/null
 | |
| -+++ b/drivers/regulator/cpr3-npu-regulator.c
 | |
| -@@ -0,0 +1,695 @@
 | |
| -+/*
 | |
| -+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 | |
| -+ *
 | |
| -+ * Permission to use, copy, modify, and/or distribute this software for any
 | |
| -+ * purpose with or without fee is hereby granted, provided that the above
 | |
| -+ * copyright notice and this permission notice appear in all copies.
 | |
| -+ *
 | |
| -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | |
| -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | |
| -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | |
| -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | |
| -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | |
| -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | |
| -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | |
| -+ */
 | |
| -+
 | |
| -+#include <linux/err.h>
 | |
| -+#include <linux/platform_device.h>
 | |
| -+#include <linux/module.h>
 | |
| -+#include <linux/of.h>
 | |
| -+#include <linux/of_device.h>
 | |
| -+#include <linux/slab.h>
 | |
| -+#include <linux/thermal.h>
 | |
| -+
 | |
| -+#include "cpr3-regulator.h"
 | |
| -+
 | |
| -+#define IPQ807x_NPU_FUSE_CORNERS		2
 | |
| -+#define IPQ817x_NPU_FUSE_CORNERS		1
 | |
| -+#define IPQ807x_NPU_FUSE_STEP_VOLT		8000
 | |
| -+#define IPQ807x_NPU_VOLTAGE_FUSE_SIZE		6
 | |
| -+#define IPQ807x_NPU_CPR_CLOCK_RATE		19200000
 | |
| -+
 | |
| -+#define IPQ807x_NPU_CPR_TCSR_START		6
 | |
| -+#define IPQ807x_NPU_CPR_TCSR_END		7
 | |
| -+
 | |
| -+#define NPU_TSENS				5
 | |
| -+
 | |
| -+u32 g_valid_npu_fuse_count = IPQ807x_NPU_FUSE_CORNERS;
 | |
| -+/**
 | |
| -+ * struct cpr3_ipq807x_npu_fuses - NPU specific fuse data for IPQ807x
 | |
| -+ * @init_voltage:	Initial (i.e. open-loop) voltage fuse parameter value
 | |
| -+ *			for each fuse corner (raw, not converted to a voltage)
 | |
| -+ * This struct holds the values for all of the fuses read from memory.
 | |
| -+ */
 | |
| -+struct cpr3_ipq807x_npu_fuses {
 | |
| -+	u64	init_voltage[IPQ807x_NPU_FUSE_CORNERS];
 | |
| -+};
 | |
| -+
 | |
| -+/*
 | |
| -+ * Constants which define the name of each fuse corner.
 | |
| -+ */
 | |
| -+enum cpr3_ipq807x_npu_fuse_corner {
 | |
| -+	CPR3_IPQ807x_NPU_FUSE_CORNER_NOM	= 0,
 | |
| -+	CPR3_IPQ807x_NPU_FUSE_CORNER_TURBO	= 1,
 | |
| -+};
 | |
| -+
 | |
| -+static const char * const cpr3_ipq807x_npu_fuse_corner_name[] = {
 | |
| -+	[CPR3_IPQ807x_NPU_FUSE_CORNER_NOM]	= "NOM",
 | |
| -+	[CPR3_IPQ807x_NPU_FUSE_CORNER_TURBO]	= "TURBO",
 | |
| -+};
 | |
| -+
 | |
| -+/*
 | |
| -+ * IPQ807x NPU fuse parameter locations:
 | |
| -+ *
 | |
| -+ * Structs are organized with the following dimensions:
 | |
| -+ *	Outer: 0 to 1 for fuse corners from lowest to highest corner
 | |
| -+ *	Inner: large enough to hold the longest set of parameter segments which
 | |
| -+ *		fully defines a fuse parameter, +1 (for NULL termination).
 | |
| -+ *		Each segment corresponds to a contiguous group of bits from a
 | |
| -+ *		single fuse row.  These segments are concatentated together in
 | |
| -+ *		order to form the full fuse parameter value.  The segments for
 | |
| -+ *		a given parameter may correspond to different fuse rows.
 | |
| -+ */
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq807x_npu_init_voltage_param[IPQ807x_NPU_FUSE_CORNERS][2] = {
 | |
| -+	{{73, 22, 27}, {} },
 | |
| -+	{{73, 16, 21}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+/*
 | |
| -+ * Open loop voltage fuse reference voltages in microvolts for IPQ807x
 | |
| -+ */
 | |
| -+static int
 | |
| -+ipq807x_npu_fuse_ref_volt [IPQ807x_NPU_FUSE_CORNERS] = {
 | |
| -+	912000,
 | |
| -+	992000,
 | |
| -+};
 | |
| -+
 | |
| -+/*
 | |
| -+ * IPQ9574 (Few parameters are changed, remaining are same as IPQ807x)
 | |
| -+ */
 | |
| -+#define IPQ9574_NPU_FUSE_CORNERS		2
 | |
| -+#define IPQ9574_NPU_FUSE_STEP_VOLT		10000
 | |
| -+#define IPQ9574_NPU_CPR_CLOCK_RATE		24000000
 | |
| -+
 | |
| -+/*
 | |
| -+ * fues parameters for IPQ9574
 | |
| -+ */
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq9574_npu_init_voltage_param[IPQ9574_NPU_FUSE_CORNERS][2] = {
 | |
| -+	{{105, 12, 17}, {} },
 | |
| -+	{{105,  6, 11}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+/*
 | |
| -+ * Open loop voltage fuse reference voltages in microvolts for IPQ9574
 | |
| -+ */
 | |
| -+static int
 | |
| -+ipq9574_npu_fuse_ref_volt [IPQ9574_NPU_FUSE_CORNERS] = {
 | |
| -+	862500,
 | |
| -+	987500,
 | |
| -+};
 | |
| -+
 | |
| -+struct cpr3_controller *g_ctrl;
 | |
| -+
 | |
| -+void cpr3_npu_temp_notify(int sensor, int temp, int low_notif)
 | |
| -+{
 | |
| -+	u32 prev_sensor_state;
 | |
| -+
 | |
| -+	if (sensor != NPU_TSENS)
 | |
| -+		return;
 | |
| -+
 | |
| -+	prev_sensor_state = g_ctrl->cur_sensor_state;
 | |
| -+	if (low_notif)
 | |
| -+		g_ctrl->cur_sensor_state |= BIT(sensor);
 | |
| -+	else
 | |
| -+		g_ctrl->cur_sensor_state &= ~BIT(sensor);
 | |
| -+
 | |
| -+	if (!prev_sensor_state && g_ctrl->cur_sensor_state)
 | |
| -+		cpr3_handle_temp_open_loop_adjustment(g_ctrl, true);
 | |
| -+	else if (prev_sensor_state && !g_ctrl->cur_sensor_state)
 | |
| -+		cpr3_handle_temp_open_loop_adjustment(g_ctrl, false);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_ipq807x_npu_read_fuse_data() - load NPU specific fuse parameter values
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * This function allocates a cpr3_ipq807x_npu_fuses struct, fills it with
 | |
| -+ * values read out of hardware fuses, and finally copies common fuse values
 | |
| -+ * into the CPR3 regulator struct.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_ipq807x_npu_read_fuse_data(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	void __iomem *base = vreg->thread->ctrl->fuse_base;
 | |
| -+	struct cpr3_ipq807x_npu_fuses *fuse;
 | |
| -+	int i, rc;
 | |
| -+
 | |
| -+	fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL);
 | |
| -+	if (!fuse)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	for (i = 0; i < g_valid_npu_fuse_count; i++) {
 | |
| -+		rc = cpr3_read_fuse_param(base,
 | |
| -+					  vreg->cpr3_regulator_data->init_voltage_param[i],
 | |
| -+					  &fuse->init_voltage[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "Unable to read fuse-corner %d initial voltage fuse, rc=%d\n",
 | |
| -+				 i, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->fuse_corner_count	= g_valid_npu_fuse_count;
 | |
| -+	vreg->platform_fuses	= fuse;
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_npu_parse_corner_data() - parse NPU corner data from device tree
 | |
| -+ *		properties of the CPR3 regulator's device node
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_npu_parse_corner_data(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_common_corner_data(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "error reading corner data, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_ipq807x_npu_calculate_open_loop_voltages() - calculate the open-loop
 | |
| -+ *		voltage for each corner of a CPR3 regulator
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @temp_correction:    Temperature based correction
 | |
| -+ *
 | |
| -+ * If open-loop voltage interpolation is allowed in device tree, then
 | |
| -+ * this function calculates the open-loop voltage for a given corner using
 | |
| -+ * linear interpolation.  This interpolation is performed using the processor
 | |
| -+ * frequencies of the lower and higher Fmax corners along with their fused
 | |
| -+ * open-loop voltages.
 | |
| -+ *
 | |
| -+ * If open-loop voltage interpolation is not allowed, then this function uses
 | |
| -+ * the Fmax fused open-loop voltage for all of the corners associated with a
 | |
| -+ * given fuse corner.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_ipq807x_npu_calculate_open_loop_voltages(
 | |
| -+			struct cpr3_regulator *vreg, bool temp_correction)
 | |
| -+{
 | |
| -+	struct cpr3_ipq807x_npu_fuses *fuse = vreg->platform_fuses;
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	int i, j, rc = 0;
 | |
| -+	u64 freq_low, volt_low, freq_high, volt_high;
 | |
| -+	int *fuse_volt;
 | |
| -+	int *fmax_corner;
 | |
| -+
 | |
| -+	fuse_volt = kcalloc(vreg->fuse_corner_count, sizeof(*fuse_volt),
 | |
| -+			    GFP_KERNEL);
 | |
| -+	fmax_corner = kcalloc(vreg->fuse_corner_count, sizeof(*fmax_corner),
 | |
| -+			      GFP_KERNEL);
 | |
| -+	if (!fuse_volt || !fmax_corner) {
 | |
| -+		rc = -ENOMEM;
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->fuse_corner_count; i++) {
 | |
| -+		if (ctrl->cpr_global_setting == CPR_DISABLED)
 | |
| -+			fuse_volt[i] = vreg->cpr3_regulator_data->fuse_ref_volt[i];
 | |
| -+		else
 | |
| -+			fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse(
 | |
| -+				vreg->cpr3_regulator_data->fuse_ref_volt[i],
 | |
| -+				vreg->cpr3_regulator_data->fuse_step_volt,
 | |
| -+				fuse->init_voltage[i],
 | |
| -+				IPQ807x_NPU_VOLTAGE_FUSE_SIZE);
 | |
| -+
 | |
| -+		/* Log fused open-loop voltage values for debugging purposes. */
 | |
| -+		cpr3_info(vreg, "fused %8s: open-loop=%7d uV\n",
 | |
| -+			  cpr3_ipq807x_npu_fuse_corner_name[i],
 | |
| -+			  fuse_volt[i]);
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_determine_part_type(vreg,
 | |
| -+			fuse_volt[CPR3_IPQ807x_NPU_FUSE_CORNER_TURBO]);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg,
 | |
| -+			"fused part type detection failed failed, rc=%d\n", rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_adjust_fused_open_loop_voltages(vreg, fuse_volt);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg,
 | |
| -+			"fused open-loop voltage adjustment failed, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+	if (temp_correction) {
 | |
| -+		rc = cpr3_determine_temp_base_open_loop_correction(vreg,
 | |
| -+								fuse_volt);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg,
 | |
| -+				"temp open-loop voltage adj. failed, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 1; i < vreg->fuse_corner_count; i++) {
 | |
| -+		if (fuse_volt[i] < fuse_volt[i - 1]) {
 | |
| -+			cpr3_info(vreg,
 | |
| -+				"fuse corner %d voltage=%d uV < fuse corner %d \
 | |
| -+				voltage=%d uV; overriding: fuse corner %d \
 | |
| -+				voltage=%d\n",
 | |
| -+				  i, fuse_volt[i], i - 1, fuse_volt[i - 1],
 | |
| -+				  i, fuse_volt[i - 1]);
 | |
| -+			fuse_volt[i] = fuse_volt[i - 1];
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Determine highest corner mapped to each fuse corner */
 | |
| -+	j = vreg->fuse_corner_count - 1;
 | |
| -+	for (i = vreg->corner_count - 1; i >= 0; i--) {
 | |
| -+		if (vreg->corner[i].cpr_fuse_corner == j) {
 | |
| -+			fmax_corner[j] = i;
 | |
| -+			j--;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (j >= 0) {
 | |
| -+		cpr3_err(vreg, "invalid fuse corner mapping\n");
 | |
| -+		rc = -EINVAL;
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Interpolation is not possible for corners mapped to the lowest fuse
 | |
| -+	 * corner so use the fuse corner value directly.
 | |
| -+	 */
 | |
| -+	for (i = 0; i <= fmax_corner[0]; i++)
 | |
| -+		vreg->corner[i].open_loop_volt = fuse_volt[0];
 | |
| -+
 | |
| -+	/* Interpolate voltages for the higher fuse corners. */
 | |
| -+	for (i = 1; i < vreg->fuse_corner_count; i++) {
 | |
| -+		freq_low = vreg->corner[fmax_corner[i - 1]].proc_freq;
 | |
| -+		volt_low = fuse_volt[i - 1];
 | |
| -+		freq_high = vreg->corner[fmax_corner[i]].proc_freq;
 | |
| -+		volt_high = fuse_volt[i];
 | |
| -+
 | |
| -+		for (j = fmax_corner[i - 1] + 1; j <= fmax_corner[i]; j++)
 | |
| -+			vreg->corner[j].open_loop_volt = cpr3_interpolate(
 | |
| -+				freq_low, volt_low, freq_high, volt_high,
 | |
| -+				vreg->corner[j].proc_freq);
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	if (rc == 0) {
 | |
| -+		cpr3_debug(vreg, "unadjusted per-corner open-loop voltages:\n");
 | |
| -+		for (i = 0; i < vreg->corner_count; i++)
 | |
| -+			cpr3_debug(vreg, "open-loop[%2d] = %d uV\n", i,
 | |
| -+				   vreg->corner[i].open_loop_volt);
 | |
| -+
 | |
| -+		rc = cpr3_adjust_open_loop_voltages(vreg);
 | |
| -+		if (rc)
 | |
| -+			cpr3_err(vreg,
 | |
| -+				"open-loop voltage adjustment failed, rc=%d\n",
 | |
| -+				 rc);
 | |
| -+	}
 | |
| -+
 | |
| -+	kfree(fuse_volt);
 | |
| -+	kfree(fmax_corner);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_npu_print_settings() - print out NPU CPR configuration settings into
 | |
| -+ *		the kernel log for debugging purposes
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ */
 | |
| -+static void cpr3_npu_print_settings(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct cpr3_corner *corner;
 | |
| -+	int i;
 | |
| -+
 | |
| -+	cpr3_debug(vreg,
 | |
| -+		"Corner: Frequency (Hz), Fuse Corner, Floor (uV), \
 | |
| -+		Open-Loop (uV), Ceiling (uV)\n");
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		corner = &vreg->corner[i];
 | |
| -+		cpr3_debug(vreg, "%3d: %10u, %2d, %7d, %7d, %7d\n",
 | |
| -+			   i, corner->proc_freq, corner->cpr_fuse_corner,
 | |
| -+			   corner->floor_volt, corner->open_loop_volt,
 | |
| -+			   corner->ceiling_volt);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (vreg->thread->ctrl->apm)
 | |
| -+		cpr3_debug(vreg, "APM threshold = %d uV, APM adjust = %d uV\n",
 | |
| -+			   vreg->thread->ctrl->apm_threshold_volt,
 | |
| -+			   vreg->thread->ctrl->apm_adj_volt);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_ipq807x_npu_calc_temp_based_ol_voltages() - Calculate the open loop
 | |
| -+ * voltages based on temperature based correction margins
 | |
| -+ * @vreg:               Pointer to the CPR3 regulator
 | |
| -+ */
 | |
| -+
 | |
| -+static int
 | |
| -+cpr3_ipq807x_npu_calc_temp_based_ol_voltages(struct cpr3_regulator *vreg,
 | |
| -+						bool temp_correction)
 | |
| -+{
 | |
| -+	int rc, i;
 | |
| -+
 | |
| -+	rc = cpr3_ipq807x_npu_calculate_open_loop_voltages(vreg,
 | |
| -+							temp_correction);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg,
 | |
| -+			"unable to calculate open-loop voltages, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_limit_open_loop_voltages(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "unable to limit open-loop voltages, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_open_loop_voltage_as_ceiling(vreg);
 | |
| -+
 | |
| -+	rc = cpr3_limit_floor_voltages(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "unable to limit floor voltages, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		if (temp_correction)
 | |
| -+			vreg->corner[i].cold_temp_open_loop_volt =
 | |
| -+				vreg->corner[i].open_loop_volt;
 | |
| -+		else
 | |
| -+			vreg->corner[i].normal_temp_open_loop_volt =
 | |
| -+				vreg->corner[i].open_loop_volt;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_npu_print_settings(vreg);
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_npu_init_thread() - perform steps necessary to initialize the
 | |
| -+ *		configuration data for a CPR3 thread
 | |
| -+ * @thread:		Pointer to the CPR3 thread
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_npu_init_thread(struct cpr3_thread *thread)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_common_thread_data(thread);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(thread->ctrl,
 | |
| -+			"thread %u CPR thread data from DT- failed, rc=%d\n",
 | |
| -+			 thread->thread_id, rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_npu_init_regulator() - perform all steps necessary to initialize the
 | |
| -+ *		configuration data for a CPR3 regulator
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_npu_init_regulator(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct cpr3_ipq807x_npu_fuses *fuse;
 | |
| -+	int rc, cold_temp = 0;
 | |
| -+	bool can_adj_cold_temp = cpr3_can_adjust_cold_temp(vreg);
 | |
| -+
 | |
| -+	rc = cpr3_ipq807x_npu_read_fuse_data(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "unable to read CPR fuse data, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	fuse = vreg->platform_fuses;
 | |
| -+
 | |
| -+	rc = cpr3_npu_parse_corner_data(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg,
 | |
| -+			"Cannot read CPR corner data from DT, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_mem_acc_init(vreg);
 | |
| -+	if (rc) {
 | |
| -+		if (rc != -EPROBE_DEFER)
 | |
| -+			cpr3_err(vreg,
 | |
| -+			"Cannot initialize mem-acc regulator settings, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (can_adj_cold_temp) {
 | |
| -+		rc = cpr3_ipq807x_npu_calc_temp_based_ol_voltages(vreg, true);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg,
 | |
| -+			"unable to calculate open-loop voltages, rc=%d\n", rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_ipq807x_npu_calc_temp_based_ol_voltages(vreg, false);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg,
 | |
| -+			"unable to calculate open-loop voltages, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (can_adj_cold_temp) {
 | |
| -+		cpr3_info(vreg,
 | |
| -+		"Normal and Cold condition init done. Default to normal.\n");
 | |
| -+
 | |
| -+		rc = cpr3_get_cold_temp_threshold(vreg, &cold_temp);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg,
 | |
| -+			"Get cold temperature threshold failed, rc=%d\n", rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+		register_low_temp_notif(NPU_TSENS, cold_temp,
 | |
| -+							cpr3_npu_temp_notify);
 | |
| -+	}
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_npu_init_controller() - perform NPU CPR3 controller specific
 | |
| -+ *		initializations
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_npu_init_controller(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_open_loop_common_ctrl_data(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		if (rc != -EPROBE_DEFER)
 | |
| -+			cpr3_err(ctrl, "unable to parse common controller data, rc=%d\n",
 | |
| -+				 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->ctrl_type = CPR_CTRL_TYPE_CPR3;
 | |
| -+	ctrl->supports_hw_closed_loop = false;
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static const struct cpr3_reg_data ipq807x_cpr_npu = {
 | |
| -+	.cpr_valid_fuse_count = IPQ807x_NPU_FUSE_CORNERS,
 | |
| -+	.init_voltage_param = ipq807x_npu_init_voltage_param,
 | |
| -+	.fuse_ref_volt = ipq807x_npu_fuse_ref_volt,
 | |
| -+	.fuse_step_volt = IPQ807x_NPU_FUSE_STEP_VOLT,
 | |
| -+	.cpr_clk_rate = IPQ807x_NPU_CPR_CLOCK_RATE,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct cpr3_reg_data ipq817x_cpr_npu = {
 | |
| -+	.cpr_valid_fuse_count = IPQ817x_NPU_FUSE_CORNERS,
 | |
| -+	.init_voltage_param = ipq807x_npu_init_voltage_param,
 | |
| -+	.fuse_ref_volt = ipq807x_npu_fuse_ref_volt,
 | |
| -+	.fuse_step_volt = IPQ807x_NPU_FUSE_STEP_VOLT,
 | |
| -+	.cpr_clk_rate = IPQ807x_NPU_CPR_CLOCK_RATE,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct cpr3_reg_data ipq9574_cpr_npu = {
 | |
| -+	.cpr_valid_fuse_count = IPQ9574_NPU_FUSE_CORNERS,
 | |
| -+	.init_voltage_param = ipq9574_npu_init_voltage_param,
 | |
| -+	.fuse_ref_volt = ipq9574_npu_fuse_ref_volt,
 | |
| -+	.fuse_step_volt = IPQ9574_NPU_FUSE_STEP_VOLT,
 | |
| -+	.cpr_clk_rate = IPQ9574_NPU_CPR_CLOCK_RATE,
 | |
| -+};
 | |
| -+
 | |
| -+static struct of_device_id cpr3_regulator_match_table[] = {
 | |
| -+	{
 | |
| -+		.compatible = "qcom,cpr3-ipq807x-npu-regulator",
 | |
| -+		.data = &ipq807x_cpr_npu
 | |
| -+	},
 | |
| -+	{
 | |
| -+		.compatible = "qcom,cpr3-ipq817x-npu-regulator",
 | |
| -+		.data = &ipq817x_cpr_npu
 | |
| -+	},
 | |
| -+	{
 | |
| -+		.compatible = "qcom,cpr3-ipq9574-npu-regulator",
 | |
| -+		.data = &ipq9574_cpr_npu
 | |
| -+	},
 | |
| -+	{}
 | |
| -+};
 | |
| -+
 | |
| -+static int cpr3_npu_regulator_probe(struct platform_device *pdev)
 | |
| -+{
 | |
| -+	struct device *dev = &pdev->dev;
 | |
| -+	struct cpr3_controller *ctrl;
 | |
| -+	int i, rc;
 | |
| -+	const struct of_device_id *match;
 | |
| -+	struct cpr3_reg_data *cpr_data;
 | |
| -+
 | |
| -+	if (!dev->of_node) {
 | |
| -+		dev_err(dev, "Device tree node is missing\n");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
 | |
| -+	if (!ctrl)
 | |
| -+		return -ENOMEM;
 | |
| -+	g_ctrl = ctrl;
 | |
| -+
 | |
| -+	match = of_match_device(cpr3_regulator_match_table, &pdev->dev);
 | |
| -+	if (!match)
 | |
| -+		return -ENODEV;
 | |
| -+
 | |
| -+	cpr_data = (struct cpr3_reg_data *)match->data;
 | |
| -+	g_valid_npu_fuse_count = cpr_data->cpr_valid_fuse_count;
 | |
| -+	dev_info(dev, "NPU CPR valid fuse count: %d\n", g_valid_npu_fuse_count);
 | |
| -+	ctrl->cpr_clock_rate = cpr_data->cpr_clk_rate;
 | |
| -+
 | |
| -+	ctrl->dev = dev;
 | |
| -+	/* Set to false later if anything precludes CPR operation. */
 | |
| -+	ctrl->cpr_allowed_hw = true;
 | |
| -+
 | |
| -+	rc = of_property_read_string(dev->of_node, "qcom,cpr-ctrl-name",
 | |
| -+				     &ctrl->name);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "unable to read qcom,cpr-ctrl-name, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_map_fuse_base(ctrl, pdev);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "could not map fuse base address\n");
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_read_tcsr_setting(ctrl, pdev, IPQ807x_NPU_CPR_TCSR_START,
 | |
| -+				    IPQ807x_NPU_CPR_TCSR_END);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "could not read CPR tcsr rsetting\n");
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_allocate_threads(ctrl, 0, 0);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "failed to allocate CPR thread array, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->thread_count != 1) {
 | |
| -+		cpr3_err(ctrl, "expected 1 thread but found %d\n",
 | |
| -+			 ctrl->thread_count);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_npu_init_controller(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		if (rc != -EPROBE_DEFER)
 | |
| -+			cpr3_err(ctrl, "failed to initialize CPR controller parameters, rc=%d\n",
 | |
| -+				 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_npu_init_thread(&ctrl->thread[0]);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "thread initialization failed, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread[0].vreg_count; i++) {
 | |
| -+		ctrl->thread[0].vreg[i].cpr3_regulator_data = cpr_data;
 | |
| -+		rc = cpr3_npu_init_regulator(&ctrl->thread[0].vreg[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(&ctrl->thread[0].vreg[i], "regulator initialization failed, rc=%d\n",
 | |
| -+				 rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	platform_set_drvdata(pdev, ctrl);
 | |
| -+
 | |
| -+	return cpr3_open_loop_regulator_register(pdev, ctrl);
 | |
| -+}
 | |
| -+
 | |
| -+static int cpr3_npu_regulator_remove(struct platform_device *pdev)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = platform_get_drvdata(pdev);
 | |
| -+
 | |
| -+	return cpr3_open_loop_regulator_unregister(ctrl);
 | |
| -+}
 | |
| -+
 | |
| -+static struct platform_driver cpr3_npu_regulator_driver = {
 | |
| -+	.driver		= {
 | |
| -+		.name		= "qcom,cpr3-npu-regulator",
 | |
| -+		.of_match_table	= cpr3_regulator_match_table,
 | |
| -+		.owner		= THIS_MODULE,
 | |
| -+	},
 | |
| -+	.probe		= cpr3_npu_regulator_probe,
 | |
| -+	.remove		= cpr3_npu_regulator_remove,
 | |
| -+};
 | |
| -+
 | |
| -+static int cpr3_regulator_init(void)
 | |
| -+{
 | |
| -+	return platform_driver_register(&cpr3_npu_regulator_driver);
 | |
| -+}
 | |
| -+arch_initcall(cpr3_regulator_init);
 | |
| -+
 | |
| -+static void cpr3_regulator_exit(void)
 | |
| -+{
 | |
| -+	platform_driver_unregister(&cpr3_npu_regulator_driver);
 | |
| -+}
 | |
| -+module_exit(cpr3_regulator_exit);
 | |
| -+
 | |
| -+MODULE_DESCRIPTION("QCOM CPR3 NPU regulator driver");
 | |
| -+MODULE_LICENSE("Dual BSD/GPLv2");
 | |
| -+MODULE_ALIAS("platform:npu-ipq807x");
 | |
| ---- /dev/null
 | |
| -+++ b/drivers/regulator/cpr3-regulator.c
 | |
| -@@ -0,0 +1,5112 @@
 | |
| -+/*
 | |
| -+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 | |
| -+ *
 | |
| -+ * This program is free software; you can redistribute it and/or modify
 | |
| -+ * it under the terms of the GNU General Public License version 2 and
 | |
| -+ * only version 2 as published by the Free Software Foundation.
 | |
| -+ *
 | |
| -+ * This program is distributed in the hope that it will be useful,
 | |
| -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| -+ * GNU General Public License for more details.
 | |
| -+ */
 | |
| -+
 | |
| -+#define pr_fmt(fmt) "%s: " fmt, __func__
 | |
| -+
 | |
| -+#include <linux/bitops.h>
 | |
| -+#include <linux/debugfs.h>
 | |
| -+#include <linux/delay.h>
 | |
| -+#include <linux/err.h>
 | |
| -+#include <linux/init.h>
 | |
| -+#include <linux/interrupt.h>
 | |
| -+#include <linux/io.h>
 | |
| -+#include <linux/kernel.h>
 | |
| -+#include <linux/ktime.h>
 | |
| -+#include <linux/list.h>
 | |
| -+#include <linux/module.h>
 | |
| -+#include <linux/of.h>
 | |
| -+#include <linux/of_device.h>
 | |
| -+#include <linux/platform_device.h>
 | |
| -+#include <linux/pm_opp.h>
 | |
| -+#include <linux/slab.h>
 | |
| -+#include <linux/sort.h>
 | |
| -+#include <linux/string.h>
 | |
| -+#include <linux/uaccess.h>
 | |
| -+#include <linux/regulator/driver.h>
 | |
| -+#include <linux/regulator/machine.h>
 | |
| -+#include <linux/regulator/of_regulator.h>
 | |
| -+#include <linux/panic_notifier.h>
 | |
| -+
 | |
| -+#include "cpr3-regulator.h"
 | |
| -+
 | |
| -+#define CPR3_REGULATOR_CORNER_INVALID	(-1)
 | |
| -+#define CPR3_RO_MASK			GENMASK(CPR3_RO_COUNT - 1, 0)
 | |
| -+
 | |
| -+/* CPR3 registers */
 | |
| -+#define CPR3_REG_CPR_CTL			0x4
 | |
| -+#define CPR3_CPR_CTL_LOOP_EN_MASK		BIT(0)
 | |
| -+#define CPR3_CPR_CTL_LOOP_ENABLE		BIT(0)
 | |
| -+#define CPR3_CPR_CTL_LOOP_DISABLE		0
 | |
| -+#define CPR3_CPR_CTL_IDLE_CLOCKS_MASK		GENMASK(5, 1)
 | |
| -+#define CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT		1
 | |
| -+#define CPR3_CPR_CTL_COUNT_MODE_MASK		GENMASK(7, 6)
 | |
| -+#define CPR3_CPR_CTL_COUNT_MODE_SHIFT		6
 | |
| -+#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN	0
 | |
| -+#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MAX	1
 | |
| -+#define CPR3_CPR_CTL_COUNT_MODE_STAGGERED	2
 | |
| -+#define CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_AGE	3
 | |
| -+#define CPR3_CPR_CTL_COUNT_REPEAT_MASK		GENMASK(31, 9)
 | |
| -+#define CPR3_CPR_CTL_COUNT_REPEAT_SHIFT		9
 | |
| -+
 | |
| -+#define CPR3_REG_CPR_STATUS			0x8
 | |
| -+#define CPR3_CPR_STATUS_BUSY_MASK		BIT(0)
 | |
| -+#define CPR3_CPR_STATUS_AGING_MEASUREMENT_MASK	BIT(1)
 | |
| -+
 | |
| -+/*
 | |
| -+ * This register is not present on controllers that support HW closed-loop
 | |
| -+ * except CPR4 APSS controller.
 | |
| -+ */
 | |
| -+#define CPR3_REG_CPR_TIMER_AUTO_CONT		0xC
 | |
| -+
 | |
| -+#define CPR3_REG_CPR_STEP_QUOT			0x14
 | |
| -+#define CPR3_CPR_STEP_QUOT_MIN_MASK		GENMASK(5, 0)
 | |
| -+#define CPR3_CPR_STEP_QUOT_MIN_SHIFT		0
 | |
| -+#define CPR3_CPR_STEP_QUOT_MAX_MASK		GENMASK(11, 6)
 | |
| -+#define CPR3_CPR_STEP_QUOT_MAX_SHIFT		6
 | |
| -+
 | |
| -+#define CPR3_REG_GCNT(ro)			(0xA0 + 0x4 * (ro))
 | |
| -+
 | |
| -+#define CPR3_REG_SENSOR_BYPASS_WRITE(sensor)	(0xE0 + 0x4 * ((sensor) / 32))
 | |
| -+#define CPR3_REG_SENSOR_BYPASS_WRITE_BANK(bank)	(0xE0 + 0x4 * (bank))
 | |
| -+
 | |
| -+#define CPR3_REG_SENSOR_MASK_WRITE(sensor)	(0x120 + 0x4 * ((sensor) / 32))
 | |
| -+#define CPR3_REG_SENSOR_MASK_WRITE_BANK(bank)	(0x120 + 0x4 * (bank))
 | |
| -+#define CPR3_REG_SENSOR_MASK_READ(sensor)	(0x140 + 0x4 * ((sensor) / 32))
 | |
| -+
 | |
| -+#define CPR3_REG_SENSOR_OWNER(sensor)	(0x200 + 0x4 * (sensor))
 | |
| -+
 | |
| -+#define CPR3_REG_CONT_CMD		0x800
 | |
| -+#define CPR3_CONT_CMD_ACK		0x1
 | |
| -+#define CPR3_CONT_CMD_NACK		0x0
 | |
| -+
 | |
| -+#define CPR3_REG_THRESH(thread)		(0x808 + 0x440 * (thread))
 | |
| -+#define CPR3_THRESH_CONS_DOWN_MASK	GENMASK(3, 0)
 | |
| -+#define CPR3_THRESH_CONS_DOWN_SHIFT	0
 | |
| -+#define CPR3_THRESH_CONS_UP_MASK	GENMASK(7, 4)
 | |
| -+#define CPR3_THRESH_CONS_UP_SHIFT	4
 | |
| -+#define CPR3_THRESH_DOWN_THRESH_MASK	GENMASK(12, 8)
 | |
| -+#define CPR3_THRESH_DOWN_THRESH_SHIFT	8
 | |
| -+#define CPR3_THRESH_UP_THRESH_MASK	GENMASK(17, 13)
 | |
| -+#define CPR3_THRESH_UP_THRESH_SHIFT	13
 | |
| -+
 | |
| -+#define CPR3_REG_RO_MASK(thread)	(0x80C + 0x440 * (thread))
 | |
| -+
 | |
| -+#define CPR3_REG_RESULT0(thread)	(0x810 + 0x440 * (thread))
 | |
| -+#define CPR3_RESULT0_BUSY_MASK		BIT(0)
 | |
| -+#define CPR3_RESULT0_STEP_DN_MASK	BIT(1)
 | |
| -+#define CPR3_RESULT0_STEP_UP_MASK	BIT(2)
 | |
| -+#define CPR3_RESULT0_ERROR_STEPS_MASK	GENMASK(7, 3)
 | |
| -+#define CPR3_RESULT0_ERROR_STEPS_SHIFT	3
 | |
| -+#define CPR3_RESULT0_ERROR_MASK		GENMASK(19, 8)
 | |
| -+#define CPR3_RESULT0_ERROR_SHIFT	8
 | |
| -+#define CPR3_RESULT0_NEGATIVE_MASK	BIT(20)
 | |
| -+
 | |
| -+#define CPR3_REG_RESULT1(thread)	(0x814 + 0x440 * (thread))
 | |
| -+#define CPR3_RESULT1_QUOT_MIN_MASK	GENMASK(11, 0)
 | |
| -+#define CPR3_RESULT1_QUOT_MIN_SHIFT	0
 | |
| -+#define CPR3_RESULT1_QUOT_MAX_MASK	GENMASK(23, 12)
 | |
| -+#define CPR3_RESULT1_QUOT_MAX_SHIFT	12
 | |
| -+#define CPR3_RESULT1_RO_MIN_MASK	GENMASK(27, 24)
 | |
| -+#define CPR3_RESULT1_RO_MIN_SHIFT	24
 | |
| -+#define CPR3_RESULT1_RO_MAX_MASK	GENMASK(31, 28)
 | |
| -+#define CPR3_RESULT1_RO_MAX_SHIFT	28
 | |
| -+
 | |
| -+#define CPR3_REG_RESULT2(thread)		(0x818 + 0x440 * (thread))
 | |
| -+#define CPR3_RESULT2_STEP_QUOT_MIN_MASK		GENMASK(5, 0)
 | |
| -+#define CPR3_RESULT2_STEP_QUOT_MIN_SHIFT	0
 | |
| -+#define CPR3_RESULT2_STEP_QUOT_MAX_MASK		GENMASK(11, 6)
 | |
| -+#define CPR3_RESULT2_STEP_QUOT_MAX_SHIFT	6
 | |
| -+#define CPR3_RESULT2_SENSOR_MIN_MASK		GENMASK(23, 16)
 | |
| -+#define CPR3_RESULT2_SENSOR_MIN_SHIFT		16
 | |
| -+#define CPR3_RESULT2_SENSOR_MAX_MASK		GENMASK(31, 24)
 | |
| -+#define CPR3_RESULT2_SENSOR_MAX_SHIFT		24
 | |
| -+
 | |
| -+#define CPR3_REG_IRQ_EN			0x81C
 | |
| -+#define CPR3_REG_IRQ_CLEAR		0x820
 | |
| -+#define CPR3_REG_IRQ_STATUS		0x824
 | |
| -+#define CPR3_IRQ_UP			BIT(3)
 | |
| -+#define CPR3_IRQ_MID			BIT(2)
 | |
| -+#define CPR3_IRQ_DOWN			BIT(1)
 | |
| -+
 | |
| -+#define CPR3_REG_TARGET_QUOT(thread, ro) \
 | |
| -+					(0x840 + 0x440 * (thread) + 0x4 * (ro))
 | |
| -+
 | |
| -+/* Registers found only on controllers that support HW closed-loop. */
 | |
| -+#define CPR3_REG_PD_THROTTLE		0xE8
 | |
| -+#define CPR3_PD_THROTTLE_DISABLE	0x0
 | |
| -+
 | |
| -+#define CPR3_REG_HW_CLOSED_LOOP		0x3000
 | |
| -+#define CPR3_HW_CLOSED_LOOP_ENABLE	0x0
 | |
| -+#define CPR3_HW_CLOSED_LOOP_DISABLE	0x1
 | |
| -+
 | |
| -+#define CPR3_REG_CPR_TIMER_MID_CONT	0x3004
 | |
| -+#define CPR3_REG_CPR_TIMER_UP_DN_CONT	0x3008
 | |
| -+
 | |
| -+#define CPR3_REG_LAST_MEASUREMENT		0x7F8
 | |
| -+#define CPR3_LAST_MEASUREMENT_THREAD_DN_SHIFT	0
 | |
| -+#define CPR3_LAST_MEASUREMENT_THREAD_UP_SHIFT	4
 | |
| -+#define CPR3_LAST_MEASUREMENT_THREAD_DN(thread) \
 | |
| -+		(BIT(thread) << CPR3_LAST_MEASUREMENT_THREAD_DN_SHIFT)
 | |
| -+#define CPR3_LAST_MEASUREMENT_THREAD_UP(thread) \
 | |
| -+		(BIT(thread) << CPR3_LAST_MEASUREMENT_THREAD_UP_SHIFT)
 | |
| -+#define CPR3_LAST_MEASUREMENT_AGGR_DN		BIT(8)
 | |
| -+#define CPR3_LAST_MEASUREMENT_AGGR_MID		BIT(9)
 | |
| -+#define CPR3_LAST_MEASUREMENT_AGGR_UP		BIT(10)
 | |
| -+#define CPR3_LAST_MEASUREMENT_VALID		BIT(11)
 | |
| -+#define CPR3_LAST_MEASUREMENT_SAW_ERROR		BIT(12)
 | |
| -+#define CPR3_LAST_MEASUREMENT_PD_BYPASS_MASK	GENMASK(23, 16)
 | |
| -+#define CPR3_LAST_MEASUREMENT_PD_BYPASS_SHIFT	16
 | |
| -+
 | |
| -+/* CPR4 controller specific registers and bit definitions */
 | |
| -+#define CPR4_REG_CPR_TIMER_CLAMP			0x10
 | |
| -+#define CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN	BIT(27)
 | |
| -+
 | |
| -+#define CPR4_REG_MISC				0x700
 | |
| -+#define CPR4_MISC_MARGIN_TABLE_ROW_SELECT_MASK	GENMASK(23, 20)
 | |
| -+#define CPR4_MISC_MARGIN_TABLE_ROW_SELECT_SHIFT	20
 | |
| -+#define CPR4_MISC_TEMP_SENSOR_ID_START_MASK	GENMASK(27, 24)
 | |
| -+#define CPR4_MISC_TEMP_SENSOR_ID_START_SHIFT	24
 | |
| -+#define CPR4_MISC_TEMP_SENSOR_ID_END_MASK	GENMASK(31, 28)
 | |
| -+#define CPR4_MISC_TEMP_SENSOR_ID_END_SHIFT	28
 | |
| -+
 | |
| -+#define CPR4_REG_SAW_ERROR_STEP_LIMIT		0x7A4
 | |
| -+#define CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK	GENMASK(4, 0)
 | |
| -+#define CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT	0
 | |
| -+#define CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK	GENMASK(9, 5)
 | |
| -+#define CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT	5
 | |
| -+
 | |
| -+#define CPR4_REG_MARGIN_TEMP_CORE_TIMERS			0x7A8
 | |
| -+#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK	GENMASK(28, 18)
 | |
| -+#define CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHIFT	18
 | |
| -+
 | |
| -+#define CPR4_REG_MARGIN_TEMP_CORE(core)		(0x7AC + 0x4 * (core))
 | |
| -+#define CPR4_MARGIN_TEMP_CORE_ADJ_MASK		GENMASK(7, 0)
 | |
| -+#define CPR4_MARGIN_TEMP_CORE_ADJ_SHIFT		8
 | |
| -+
 | |
| -+#define CPR4_REG_MARGIN_TEMP_POINT0N1		0x7F0
 | |
| -+#define CPR4_MARGIN_TEMP_POINT0_MASK		GENMASK(11, 0)
 | |
| -+#define CPR4_MARGIN_TEMP_POINT0_SHIFT		0
 | |
| -+#define CPR4_MARGIN_TEMP_POINT1_MASK		GENMASK(23, 12)
 | |
| -+#define CPR4_MARGIN_TEMP_POINT1_SHIFT		12
 | |
| -+#define CPR4_REG_MARGIN_TEMP_POINT2		0x7F4
 | |
| -+#define CPR4_MARGIN_TEMP_POINT2_MASK		GENMASK(11, 0)
 | |
| -+#define CPR4_MARGIN_TEMP_POINT2_SHIFT		0
 | |
| -+
 | |
| -+#define CPR4_REG_MARGIN_ADJ_CTL					0x7F8
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_BOOST_EN				BIT(0)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_CORE_ADJ_EN				BIT(1)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_TEMP_ADJ_EN				BIT(2)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_TIMER_SETTLE_VOLTAGE_EN		BIT(3)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_EN_MASK		BIT(4)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_ENABLE		BIT(4)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_DISABLE		0
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_PER_RO_KV_MARGIN_EN			BIT(7)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_KV_MARGIN_ADJ_EN			BIT(8)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_PMIC_STEP_SIZE_MASK			GENMASK(16, 12)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_PMIC_STEP_SIZE_SHIFT		12
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_INITIAL_TEMP_BAND_MASK		GENMASK(21, 19)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_INITIAL_TEMP_BAND_SHIFT		19
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_MAX_NUM_CORES_MASK			GENMASK(25, 22)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_MAX_NUM_CORES_SHIFT			22
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_KV_MARGIN_ADJ_STEP_QUOT_MASK	GENMASK(31, 26)
 | |
| -+#define CPR4_MARGIN_ADJ_CTL_KV_MARGIN_ADJ_STEP_QUOT_SHIFT	26
 | |
| -+
 | |
| -+#define CPR4_REG_CPR_MASK_THREAD(thread)	(0x80C + 0x440 * (thread))
 | |
| -+#define CPR4_CPR_MASK_THREAD_DISABLE_THREAD		BIT(31)
 | |
| -+#define CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK	GENMASK(15, 0)
 | |
| -+
 | |
| -+/*
 | |
| -+ * The amount of time to wait for the CPR controller to become idle when
 | |
| -+ * performing an aging measurement.
 | |
| -+ */
 | |
| -+#define CPR3_AGING_MEASUREMENT_TIMEOUT_NS	5000000
 | |
| -+
 | |
| -+/*
 | |
| -+ * The number of individual aging measurements to perform which are then
 | |
| -+ * averaged together in order to determine the final aging adjustment value.
 | |
| -+ */
 | |
| -+#define CPR3_AGING_MEASUREMENT_ITERATIONS	16
 | |
| -+
 | |
| -+/*
 | |
| -+ * Aging measurements for the aged and unaged ring oscillators take place a few
 | |
| -+ * microseconds apart.  If the vdd-supply voltage fluctuates between the two
 | |
| -+ * measurements, then the difference between them will be incorrect.  The
 | |
| -+ * difference could end up too high or too low.  This constant defines the
 | |
| -+ * number of lowest and highest measurements to ignore when averaging.
 | |
| -+ */
 | |
| -+#define CPR3_AGING_MEASUREMENT_FILTER		3
 | |
| -+
 | |
| -+/*
 | |
| -+ * The number of times to attempt the full aging measurement sequence before
 | |
| -+ * declaring a measurement failure.
 | |
| -+ */
 | |
| -+#define CPR3_AGING_RETRY_COUNT			5
 | |
| -+
 | |
| -+/*
 | |
| -+ * The maximum time to wait in microseconds for a CPR register write to
 | |
| -+ * complete.
 | |
| -+ */
 | |
| -+#define CPR3_REGISTER_WRITE_DELAY_US		200
 | |
| -+
 | |
| -+static DEFINE_MUTEX(cpr3_controller_list_mutex);
 | |
| -+static LIST_HEAD(cpr3_controller_list);
 | |
| -+static struct dentry *cpr3_debugfs_base;
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_read() - read four bytes from the memory address specified
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @offset:		Offset in bytes from the CPR3 controller's base address
 | |
| -+ *
 | |
| -+ * Return: memory address value
 | |
| -+ */
 | |
| -+static inline u32 cpr3_read(struct cpr3_controller *ctrl, u32 offset)
 | |
| -+{
 | |
| -+	if (!ctrl->cpr_enabled) {
 | |
| -+		cpr3_err(ctrl, "CPR register reads are not possible when CPR clocks are disabled\n");
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	return readl_relaxed(ctrl->cpr_ctrl_base + offset);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_write() - write four bytes to the memory address specified
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @offset:		Offset in bytes from the CPR3 controller's base address
 | |
| -+ * @value:		Value to write to the memory address
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static inline void cpr3_write(struct cpr3_controller *ctrl, u32 offset,
 | |
| -+				u32 value)
 | |
| -+{
 | |
| -+	if (!ctrl->cpr_enabled) {
 | |
| -+		cpr3_err(ctrl, "CPR register writes are not possible when CPR clocks are disabled\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	writel_relaxed(value, ctrl->cpr_ctrl_base + offset);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_masked_write() - perform a read-modify-write sequence so that only
 | |
| -+ *		masked bits are modified
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @offset:		Offset in bytes from the CPR3 controller's base address
 | |
| -+ * @mask:		Mask identifying the bits that should be modified
 | |
| -+ * @value:		Value to write to the memory address
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static inline void cpr3_masked_write(struct cpr3_controller *ctrl, u32 offset,
 | |
| -+				u32 mask, u32 value)
 | |
| -+{
 | |
| -+	u32 reg_val, orig_val;
 | |
| -+
 | |
| -+	if (!ctrl->cpr_enabled) {
 | |
| -+		cpr3_err(ctrl, "CPR register writes are not possible when CPR clocks are disabled\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	reg_val = orig_val = readl_relaxed(ctrl->cpr_ctrl_base + offset);
 | |
| -+	reg_val &= ~mask;
 | |
| -+	reg_val |= value & mask;
 | |
| -+
 | |
| -+	if (reg_val != orig_val)
 | |
| -+		writel_relaxed(reg_val, ctrl->cpr_ctrl_base + offset);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_ctrl_loop_enable() - enable the CPR sensing loop for a given controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static inline void cpr3_ctrl_loop_enable(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	if (ctrl->cpr_enabled && !(ctrl->aggr_corner.sdelta
 | |
| -+		&& ctrl->aggr_corner.sdelta->allow_boost))
 | |
| -+		cpr3_masked_write(ctrl, CPR3_REG_CPR_CTL,
 | |
| -+			CPR3_CPR_CTL_LOOP_EN_MASK, CPR3_CPR_CTL_LOOP_ENABLE);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_ctrl_loop_disable() - disable the CPR sensing loop for a given
 | |
| -+ *		controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static inline void cpr3_ctrl_loop_disable(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	if (ctrl->cpr_enabled)
 | |
| -+		cpr3_masked_write(ctrl, CPR3_REG_CPR_CTL,
 | |
| -+			CPR3_CPR_CTL_LOOP_EN_MASK, CPR3_CPR_CTL_LOOP_DISABLE);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_clock_enable() - prepare and enable all clocks used by this CPR3
 | |
| -+ *		controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_clock_enable(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = clk_prepare_enable(ctrl->bus_clk);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "failed to enable bus clock, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = clk_prepare_enable(ctrl->iface_clk);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "failed to enable interface clock, rc=%d\n", rc);
 | |
| -+		clk_disable_unprepare(ctrl->bus_clk);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = clk_prepare_enable(ctrl->core_clk);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "failed to enable core clock, rc=%d\n", rc);
 | |
| -+		clk_disable_unprepare(ctrl->iface_clk);
 | |
| -+		clk_disable_unprepare(ctrl->bus_clk);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_clock_disable() - disable and unprepare all clocks used by this CPR3
 | |
| -+ *		controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static void cpr3_clock_disable(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	clk_disable_unprepare(ctrl->core_clk);
 | |
| -+	clk_disable_unprepare(ctrl->iface_clk);
 | |
| -+	clk_disable_unprepare(ctrl->bus_clk);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_ctrl_clear_cpr4_config() - clear the CPR4 register configuration
 | |
| -+ *		programmed for current aggregated corner of a given controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static inline int cpr3_ctrl_clear_cpr4_config(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct cpr4_sdelta *aggr_sdelta = ctrl->aggr_corner.sdelta;
 | |
| -+	bool cpr_enabled = ctrl->cpr_enabled;
 | |
| -+	int i, rc = 0;
 | |
| -+
 | |
| -+	if (!aggr_sdelta || !(aggr_sdelta->allow_core_count_adj
 | |
| -+		|| aggr_sdelta->allow_temp_adj || aggr_sdelta->allow_boost))
 | |
| -+		/* cpr4 features are not enabled */
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	/* Ensure that CPR clocks are enabled before writing to registers. */
 | |
| -+	if (!cpr_enabled) {
 | |
| -+		rc = cpr3_clock_enable(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "clock enable failed, rc=%d\n", rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+		ctrl->cpr_enabled = true;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Clear feature enable configuration made for current
 | |
| -+	 * aggregated corner.
 | |
| -+	 */
 | |
| -+	cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+		CPR4_MARGIN_ADJ_CTL_MAX_NUM_CORES_MASK
 | |
| -+		| CPR4_MARGIN_ADJ_CTL_CORE_ADJ_EN
 | |
| -+		| CPR4_MARGIN_ADJ_CTL_TEMP_ADJ_EN
 | |
| -+		| CPR4_MARGIN_ADJ_CTL_KV_MARGIN_ADJ_EN
 | |
| -+		| CPR4_MARGIN_ADJ_CTL_BOOST_EN
 | |
| -+		| CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_EN_MASK, 0);
 | |
| -+
 | |
| -+	cpr3_masked_write(ctrl, CPR4_REG_MISC,
 | |
| -+			CPR4_MISC_MARGIN_TABLE_ROW_SELECT_MASK,
 | |
| -+			0 << CPR4_MISC_MARGIN_TABLE_ROW_SELECT_SHIFT);
 | |
| -+
 | |
| -+	for (i = 0; i <= aggr_sdelta->max_core_count; i++) {
 | |
| -+		/* Clear voltage margin adjustments programmed in TEMP_COREi */
 | |
| -+		cpr3_write(ctrl, CPR4_REG_MARGIN_TEMP_CORE(i), 0);
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Turn off CPR clocks if they were off before this function call. */
 | |
| -+	if (!cpr_enabled) {
 | |
| -+		cpr3_clock_disable(ctrl);
 | |
| -+		ctrl->cpr_enabled = false;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_closed_loop_enable() - enable logical CPR closed-loop operation
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_closed_loop_enable(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	if (!ctrl->cpr_allowed_hw || !ctrl->cpr_allowed_sw) {
 | |
| -+		cpr3_err(ctrl, "cannot enable closed-loop CPR operation because it is disallowed\n");
 | |
| -+		return -EPERM;
 | |
| -+	} else if (ctrl->cpr_enabled) {
 | |
| -+		/* Already enabled */
 | |
| -+		return 0;
 | |
| -+	} else if (ctrl->cpr_suspended) {
 | |
| -+		/*
 | |
| -+		 * CPR must remain disabled as the system is entering suspend.
 | |
| -+		 */
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_clock_enable(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "unable to enable CPR clocks, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->cpr_enabled = true;
 | |
| -+	cpr3_debug(ctrl, "CPR closed-loop operation enabled\n");
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_closed_loop_disable() - disable logical CPR closed-loop operation
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static inline int cpr3_closed_loop_disable(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	if (!ctrl->cpr_enabled) {
 | |
| -+		/* Already disabled */
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_clock_disable(ctrl);
 | |
| -+	ctrl->cpr_enabled = false;
 | |
| -+	cpr3_debug(ctrl, "CPR closed-loop operation disabled\n");
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_get_gcnt() - returns the GCNT register value corresponding
 | |
| -+ *		to the clock rate and sensor time of the CPR3 controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: GCNT value
 | |
| -+ */
 | |
| -+static u32 cpr3_regulator_get_gcnt(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	u64 temp;
 | |
| -+	unsigned int remainder;
 | |
| -+	u32 gcnt;
 | |
| -+
 | |
| -+	temp = (u64)ctrl->cpr_clock_rate * (u64)ctrl->sensor_time;
 | |
| -+	remainder = do_div(temp, 1000000000);
 | |
| -+	if (remainder)
 | |
| -+		temp++;
 | |
| -+	/*
 | |
| -+	 * GCNT == 0 corresponds to a single ref clock measurement interval so
 | |
| -+	 * offset GCNT values by 1.
 | |
| -+	 */
 | |
| -+	gcnt = temp - 1;
 | |
| -+
 | |
| -+	return gcnt;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_init_thread() - performs hardware initialization of CPR
 | |
| -+ *		thread registers
 | |
| -+ * @thread:		Pointer to the CPR3 thread
 | |
| -+ *
 | |
| -+ * CPR interface/bus clocks must be enabled before calling this function.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_init_thread(struct cpr3_thread *thread)
 | |
| -+{
 | |
| -+	u32 reg;
 | |
| -+
 | |
| -+	reg = (thread->consecutive_up << CPR3_THRESH_CONS_UP_SHIFT)
 | |
| -+		& CPR3_THRESH_CONS_UP_MASK;
 | |
| -+	reg |= (thread->consecutive_down << CPR3_THRESH_CONS_DOWN_SHIFT)
 | |
| -+		& CPR3_THRESH_CONS_DOWN_MASK;
 | |
| -+	reg |= (thread->up_threshold << CPR3_THRESH_UP_THRESH_SHIFT)
 | |
| -+		& CPR3_THRESH_UP_THRESH_MASK;
 | |
| -+	reg |= (thread->down_threshold << CPR3_THRESH_DOWN_THRESH_SHIFT)
 | |
| -+		& CPR3_THRESH_DOWN_THRESH_MASK;
 | |
| -+
 | |
| -+	cpr3_write(thread->ctrl, CPR3_REG_THRESH(thread->thread_id), reg);
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Mask all RO's initially so that unused thread doesn't contribute
 | |
| -+	 * to closed-loop voltage.
 | |
| -+	 */
 | |
| -+	cpr3_write(thread->ctrl, CPR3_REG_RO_MASK(thread->thread_id),
 | |
| -+		CPR3_RO_MASK);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_regulator_init_temp_points() - performs hardware initialization of CPR4
 | |
| -+ *		registers to track tsen temperature data and also specify the
 | |
| -+ *		temperature band range values to apply different voltage margins
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * CPR interface/bus clocks must be enabled before calling this function.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_regulator_init_temp_points(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	if (!ctrl->allow_temp_adj)
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	cpr3_masked_write(ctrl, CPR4_REG_MISC,
 | |
| -+				CPR4_MISC_TEMP_SENSOR_ID_START_MASK,
 | |
| -+				ctrl->temp_sensor_id_start
 | |
| -+				<< CPR4_MISC_TEMP_SENSOR_ID_START_SHIFT);
 | |
| -+
 | |
| -+	cpr3_masked_write(ctrl, CPR4_REG_MISC,
 | |
| -+				CPR4_MISC_TEMP_SENSOR_ID_END_MASK,
 | |
| -+				ctrl->temp_sensor_id_end
 | |
| -+				<< CPR4_MISC_TEMP_SENSOR_ID_END_SHIFT);
 | |
| -+
 | |
| -+	cpr3_masked_write(ctrl, CPR4_REG_MARGIN_TEMP_POINT2,
 | |
| -+		CPR4_MARGIN_TEMP_POINT2_MASK,
 | |
| -+		(ctrl->temp_band_count == 4 ? ctrl->temp_points[2] : 0x7FF)
 | |
| -+		<< CPR4_MARGIN_TEMP_POINT2_SHIFT);
 | |
| -+
 | |
| -+	cpr3_masked_write(ctrl, CPR4_REG_MARGIN_TEMP_POINT0N1,
 | |
| -+		CPR4_MARGIN_TEMP_POINT1_MASK,
 | |
| -+		(ctrl->temp_band_count >= 3 ? ctrl->temp_points[1] : 0x7FF)
 | |
| -+		<< CPR4_MARGIN_TEMP_POINT1_SHIFT);
 | |
| -+
 | |
| -+	cpr3_masked_write(ctrl, CPR4_REG_MARGIN_TEMP_POINT0N1,
 | |
| -+		CPR4_MARGIN_TEMP_POINT0_MASK,
 | |
| -+		(ctrl->temp_band_count >= 2 ? ctrl->temp_points[0] : 0x7FF)
 | |
| -+		<< CPR4_MARGIN_TEMP_POINT0_SHIFT);
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_init_cpr4() - performs hardware initialization at the
 | |
| -+ *		controller and thread level required for CPR4 operation.
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * CPR interface/bus clocks must be enabled before calling this function.
 | |
| -+ * This function allocates sdelta structures and sdelta tables for aggregated
 | |
| -+ * corners of the controller and its threads.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_init_cpr4(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct cpr3_thread *thread;
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+	struct cpr4_sdelta *sdelta;
 | |
| -+	int i, j, ctrl_max_core_count, thread_max_core_count, rc = 0;
 | |
| -+	bool ctrl_valid_sdelta, thread_valid_sdelta;
 | |
| -+	u32 pmic_step_size = 1;
 | |
| -+	int thread_id = 0;
 | |
| -+	u64 temp;
 | |
| -+
 | |
| -+	if (ctrl->supports_hw_closed_loop) {
 | |
| -+		if (ctrl->saw_use_unit_mV)
 | |
| -+			pmic_step_size = ctrl->step_volt / 1000;
 | |
| -+		cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+				  CPR4_MARGIN_ADJ_CTL_PMIC_STEP_SIZE_MASK,
 | |
| -+				  (pmic_step_size
 | |
| -+				  << CPR4_MARGIN_ADJ_CTL_PMIC_STEP_SIZE_SHIFT));
 | |
| -+
 | |
| -+		cpr3_masked_write(ctrl, CPR4_REG_SAW_ERROR_STEP_LIMIT,
 | |
| -+				  CPR4_SAW_ERROR_STEP_LIMIT_DN_MASK,
 | |
| -+				  (ctrl->down_error_step_limit
 | |
| -+					<< CPR4_SAW_ERROR_STEP_LIMIT_DN_SHIFT));
 | |
| -+
 | |
| -+		cpr3_masked_write(ctrl, CPR4_REG_SAW_ERROR_STEP_LIMIT,
 | |
| -+				  CPR4_SAW_ERROR_STEP_LIMIT_UP_MASK,
 | |
| -+				  (ctrl->up_error_step_limit
 | |
| -+					<< CPR4_SAW_ERROR_STEP_LIMIT_UP_SHIFT));
 | |
| -+
 | |
| -+		/*
 | |
| -+		 * Enable thread aggregation regardless of which threads are
 | |
| -+		 * enabled or disabled.
 | |
| -+		 */
 | |
| -+		cpr3_masked_write(ctrl, CPR4_REG_CPR_TIMER_CLAMP,
 | |
| -+				  CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN,
 | |
| -+				  CPR4_CPR_TIMER_CLAMP_THREAD_AGGREGATION_EN);
 | |
| -+
 | |
| -+		switch (ctrl->thread_count) {
 | |
| -+		case 0:
 | |
| -+			/* Disable both threads */
 | |
| -+			cpr3_masked_write(ctrl, CPR4_REG_CPR_MASK_THREAD(0),
 | |
| -+				CPR4_CPR_MASK_THREAD_DISABLE_THREAD
 | |
| -+				    | CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK,
 | |
| -+				CPR4_CPR_MASK_THREAD_DISABLE_THREAD
 | |
| -+				    | CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK);
 | |
| -+
 | |
| -+			cpr3_masked_write(ctrl, CPR4_REG_CPR_MASK_THREAD(1),
 | |
| -+				CPR4_CPR_MASK_THREAD_DISABLE_THREAD
 | |
| -+				    | CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK,
 | |
| -+				CPR4_CPR_MASK_THREAD_DISABLE_THREAD
 | |
| -+				    | CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK);
 | |
| -+			break;
 | |
| -+		case 1:
 | |
| -+			/* Disable unused thread */
 | |
| -+			thread_id = ctrl->thread[0].thread_id ? 0 : 1;
 | |
| -+			cpr3_masked_write(ctrl,
 | |
| -+				CPR4_REG_CPR_MASK_THREAD(thread_id),
 | |
| -+				CPR4_CPR_MASK_THREAD_DISABLE_THREAD
 | |
| -+				    | CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK,
 | |
| -+				CPR4_CPR_MASK_THREAD_DISABLE_THREAD
 | |
| -+				    | CPR4_CPR_MASK_THREAD_RO_MASK4THREAD_MASK);
 | |
| -+			break;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!ctrl->allow_core_count_adj && !ctrl->allow_temp_adj
 | |
| -+		&& !ctrl->allow_boost) {
 | |
| -+		/*
 | |
| -+		 * Skip below configuration as none of the features
 | |
| -+		 * are enabled.
 | |
| -+		 */
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->supports_hw_closed_loop)
 | |
| -+		cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+				  CPR4_MARGIN_ADJ_CTL_TIMER_SETTLE_VOLTAGE_EN,
 | |
| -+				  CPR4_MARGIN_ADJ_CTL_TIMER_SETTLE_VOLTAGE_EN);
 | |
| -+
 | |
| -+	cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+			CPR4_MARGIN_ADJ_CTL_KV_MARGIN_ADJ_STEP_QUOT_MASK,
 | |
| -+			ctrl->step_quot_fixed
 | |
| -+			<< CPR4_MARGIN_ADJ_CTL_KV_MARGIN_ADJ_STEP_QUOT_SHIFT);
 | |
| -+
 | |
| -+	cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+			CPR4_MARGIN_ADJ_CTL_PER_RO_KV_MARGIN_EN,
 | |
| -+			(ctrl->use_dynamic_step_quot
 | |
| -+			? CPR4_MARGIN_ADJ_CTL_PER_RO_KV_MARGIN_EN : 0));
 | |
| -+
 | |
| -+	cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+			CPR4_MARGIN_ADJ_CTL_INITIAL_TEMP_BAND_MASK,
 | |
| -+			ctrl->initial_temp_band
 | |
| -+			<< CPR4_MARGIN_ADJ_CTL_INITIAL_TEMP_BAND_SHIFT);
 | |
| -+
 | |
| -+	rc = cpr4_regulator_init_temp_points(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "initialize temp points failed, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->voltage_settling_time) {
 | |
| -+		/*
 | |
| -+		 * Configure the settling timer used to account for
 | |
| -+		 * one VDD supply step.
 | |
| -+		 */
 | |
| -+		temp = (u64)ctrl->cpr_clock_rate
 | |
| -+				* (u64)ctrl->voltage_settling_time;
 | |
| -+		do_div(temp, 1000000000);
 | |
| -+		cpr3_masked_write(ctrl, CPR4_REG_MARGIN_TEMP_CORE_TIMERS,
 | |
| -+			CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_MASK,
 | |
| -+			temp
 | |
| -+		    << CPR4_MARGIN_TEMP_CORE_TIMERS_SETTLE_VOLTAGE_COUNT_SHIFT);
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Allocate memory for cpr4_sdelta structure and sdelta table for
 | |
| -+	 * controller aggregated corner by finding the maximum core count
 | |
| -+	 * used by any cpr3 regulators.
 | |
| -+	 */
 | |
| -+	ctrl_max_core_count = 1;
 | |
| -+	ctrl_valid_sdelta = false;
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		thread = &ctrl->thread[i];
 | |
| -+
 | |
| -+		/*
 | |
| -+		 * Allocate memory for cpr4_sdelta structure and sdelta table
 | |
| -+		 * for thread aggregated corner by finding the maximum core
 | |
| -+		 * count used by any cpr3 regulators of the thread.
 | |
| -+		 */
 | |
| -+		thread_max_core_count = 1;
 | |
| -+		thread_valid_sdelta = false;
 | |
| -+		for (j = 0; j < thread->vreg_count; j++) {
 | |
| -+			vreg = &thread->vreg[j];
 | |
| -+			thread_max_core_count = max(thread_max_core_count,
 | |
| -+							vreg->max_core_count);
 | |
| -+			thread_valid_sdelta |= (vreg->allow_core_count_adj
 | |
| -+							| vreg->allow_temp_adj
 | |
| -+							| vreg->allow_boost);
 | |
| -+		}
 | |
| -+		if (thread_valid_sdelta) {
 | |
| -+			sdelta = devm_kzalloc(ctrl->dev, sizeof(*sdelta),
 | |
| -+					GFP_KERNEL);
 | |
| -+			if (!sdelta)
 | |
| -+				return -ENOMEM;
 | |
| -+
 | |
| -+			sdelta->table = devm_kcalloc(ctrl->dev,
 | |
| -+						thread_max_core_count
 | |
| -+						* ctrl->temp_band_count,
 | |
| -+						sizeof(*sdelta->table),
 | |
| -+						GFP_KERNEL);
 | |
| -+			if (!sdelta->table)
 | |
| -+				return -ENOMEM;
 | |
| -+
 | |
| -+			sdelta->boost_table = devm_kcalloc(ctrl->dev,
 | |
| -+						ctrl->temp_band_count,
 | |
| -+						sizeof(*sdelta->boost_table),
 | |
| -+						GFP_KERNEL);
 | |
| -+			if (!sdelta->boost_table)
 | |
| -+				return -ENOMEM;
 | |
| -+
 | |
| -+			thread->aggr_corner.sdelta = sdelta;
 | |
| -+		}
 | |
| -+
 | |
| -+		ctrl_valid_sdelta |= thread_valid_sdelta;
 | |
| -+		ctrl_max_core_count = max(ctrl_max_core_count,
 | |
| -+						thread_max_core_count);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl_valid_sdelta) {
 | |
| -+		sdelta = devm_kzalloc(ctrl->dev, sizeof(*sdelta), GFP_KERNEL);
 | |
| -+		if (!sdelta)
 | |
| -+			return -ENOMEM;
 | |
| -+
 | |
| -+		sdelta->table = devm_kcalloc(ctrl->dev, ctrl_max_core_count
 | |
| -+					* ctrl->temp_band_count,
 | |
| -+					sizeof(*sdelta->table), GFP_KERNEL);
 | |
| -+		if (!sdelta->table)
 | |
| -+			return -ENOMEM;
 | |
| -+
 | |
| -+		sdelta->boost_table = devm_kcalloc(ctrl->dev,
 | |
| -+					ctrl->temp_band_count,
 | |
| -+					sizeof(*sdelta->boost_table),
 | |
| -+					GFP_KERNEL);
 | |
| -+		if (!sdelta->boost_table)
 | |
| -+			return -ENOMEM;
 | |
| -+
 | |
| -+		ctrl->aggr_corner.sdelta = sdelta;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_write_temp_core_margin() - programs hardware SDELTA registers with
 | |
| -+ *		the voltage margin adjustments that need to be applied for
 | |
| -+ *		different online core-count and temperature bands.
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @addr:		SDELTA register address
 | |
| -+ * @temp_core_adj:	Array of voltage margin values for different temperature
 | |
| -+ *			bands.
 | |
| -+ *
 | |
| -+ * CPR interface/bus clocks must be enabled before calling this function.
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static void cpr3_write_temp_core_margin(struct cpr3_controller *ctrl,
 | |
| -+				 int addr, int *temp_core_adj)
 | |
| -+{
 | |
| -+	int i, margin_steps;
 | |
| -+	u32 reg = 0;
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->temp_band_count; i++) {
 | |
| -+		margin_steps = max(min(temp_core_adj[i], 127), -128);
 | |
| -+		reg |= (margin_steps & CPR4_MARGIN_TEMP_CORE_ADJ_MASK) <<
 | |
| -+			(i * CPR4_MARGIN_TEMP_CORE_ADJ_SHIFT);
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_write(ctrl, addr, reg);
 | |
| -+	cpr3_debug(ctrl, "sdelta offset=0x%08x, val=0x%08x\n", addr, reg);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_controller_program_sdelta() - programs hardware SDELTA registers with
 | |
| -+ *		the voltage margin adjustments that need to be applied at
 | |
| -+ *		different online core-count and temperature bands. Also,
 | |
| -+ *		programs hardware register configuration for per-online-core
 | |
| -+ *		and per-temperature based adjustments.
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * CPR interface/bus clocks must be enabled before calling this function.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_controller_program_sdelta(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct cpr3_corner *corner = &ctrl->aggr_corner;
 | |
| -+	struct cpr4_sdelta *sdelta = corner->sdelta;
 | |
| -+	int i, index, max_core_count, rc = 0;
 | |
| -+	bool cpr_enabled = ctrl->cpr_enabled;
 | |
| -+
 | |
| -+	if (!sdelta)
 | |
| -+		/* cpr4_sdelta not defined for current aggregated corner */
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	if (ctrl->supports_hw_closed_loop && ctrl->cpr_enabled) {
 | |
| -+		cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+			CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_EN_MASK,
 | |
| -+			(ctrl->use_hw_closed_loop && !sdelta->allow_boost)
 | |
| -+			? CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_ENABLE : 0);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!sdelta->allow_core_count_adj && !sdelta->allow_temp_adj
 | |
| -+		&& !sdelta->allow_boost) {
 | |
| -+		/*
 | |
| -+		 * Per-online-core, per-temperature and voltage boost
 | |
| -+		 * adjustments are disabled for this aggregation corner.
 | |
| -+		 */
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Ensure that CPR clocks are enabled before writing to registers. */
 | |
| -+	if (!cpr_enabled) {
 | |
| -+		rc = cpr3_clock_enable(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "clock enable failed, rc=%d\n", rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+		ctrl->cpr_enabled = true;
 | |
| -+	}
 | |
| -+
 | |
| -+	max_core_count = sdelta->max_core_count;
 | |
| -+
 | |
| -+	if (sdelta->allow_core_count_adj || sdelta->allow_temp_adj) {
 | |
| -+		if (sdelta->allow_core_count_adj) {
 | |
| -+			/* Program TEMP_CORE0 to same margins as TEMP_CORE1 */
 | |
| -+			cpr3_write_temp_core_margin(ctrl,
 | |
| -+				CPR4_REG_MARGIN_TEMP_CORE(0),
 | |
| -+				&sdelta->table[0]);
 | |
| -+		}
 | |
| -+
 | |
| -+		for (i = 0; i < max_core_count; i++) {
 | |
| -+			index = i * sdelta->temp_band_count;
 | |
| -+			/*
 | |
| -+			 * Program TEMP_COREi with voltage margin adjustments
 | |
| -+			 * that need to be applied when the number of cores
 | |
| -+			 * becomes i.
 | |
| -+			 */
 | |
| -+			cpr3_write_temp_core_margin(ctrl,
 | |
| -+				CPR4_REG_MARGIN_TEMP_CORE(
 | |
| -+						sdelta->allow_core_count_adj
 | |
| -+						? i + 1 : max_core_count),
 | |
| -+						&sdelta->table[index]);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (sdelta->allow_boost) {
 | |
| -+		/* Program only boost_num_cores row of SDELTA */
 | |
| -+		cpr3_write_temp_core_margin(ctrl,
 | |
| -+			CPR4_REG_MARGIN_TEMP_CORE(sdelta->boost_num_cores),
 | |
| -+					&sdelta->boost_table[0]);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!sdelta->allow_core_count_adj && !sdelta->allow_boost) {
 | |
| -+		cpr3_masked_write(ctrl, CPR4_REG_MISC,
 | |
| -+			CPR4_MISC_MARGIN_TABLE_ROW_SELECT_MASK,
 | |
| -+			max_core_count
 | |
| -+			<< CPR4_MISC_MARGIN_TABLE_ROW_SELECT_SHIFT);
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+		CPR4_MARGIN_ADJ_CTL_MAX_NUM_CORES_MASK
 | |
| -+		| CPR4_MARGIN_ADJ_CTL_CORE_ADJ_EN
 | |
| -+		| CPR4_MARGIN_ADJ_CTL_TEMP_ADJ_EN
 | |
| -+		| CPR4_MARGIN_ADJ_CTL_KV_MARGIN_ADJ_EN
 | |
| -+		| CPR4_MARGIN_ADJ_CTL_BOOST_EN,
 | |
| -+		max_core_count << CPR4_MARGIN_ADJ_CTL_MAX_NUM_CORES_SHIFT
 | |
| -+		| ((sdelta->allow_core_count_adj || sdelta->allow_boost)
 | |
| -+			? CPR4_MARGIN_ADJ_CTL_CORE_ADJ_EN : 0)
 | |
| -+		| ((sdelta->allow_temp_adj && ctrl->supports_hw_closed_loop)
 | |
| -+			? CPR4_MARGIN_ADJ_CTL_TEMP_ADJ_EN : 0)
 | |
| -+		| (((ctrl->use_hw_closed_loop && !sdelta->allow_boost)
 | |
| -+		    || !ctrl->supports_hw_closed_loop)
 | |
| -+			? CPR4_MARGIN_ADJ_CTL_KV_MARGIN_ADJ_EN : 0)
 | |
| -+		| (sdelta->allow_boost
 | |
| -+			?  CPR4_MARGIN_ADJ_CTL_BOOST_EN : 0));
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Ensure that all previous CPR register writes have completed before
 | |
| -+	 * continuing.
 | |
| -+	 */
 | |
| -+	mb();
 | |
| -+
 | |
| -+	/* Turn off CPR clocks if they were off before this function call. */
 | |
| -+	if (!cpr_enabled) {
 | |
| -+		cpr3_clock_disable(ctrl);
 | |
| -+		ctrl->cpr_enabled = false;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_init_ctrl() - performs hardware initialization of CPR
 | |
| -+ *		controller registers
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_init_ctrl(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int i, j, k, m, rc;
 | |
| -+	u32 ro_used = 0;
 | |
| -+	u32 gcnt, cont_dly, up_down_dly, val;
 | |
| -+	u64 temp;
 | |
| -+	char *mode;
 | |
| -+
 | |
| -+	if (ctrl->core_clk) {
 | |
| -+		rc = clk_set_rate(ctrl->core_clk, ctrl->cpr_clock_rate);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "clk_set_rate(core_clk, %u) failed, rc=%d\n",
 | |
| -+				ctrl->cpr_clock_rate, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_clock_enable(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "clock enable failed, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+	ctrl->cpr_enabled = true;
 | |
| -+
 | |
| -+	/* Find all RO's used by any corner of any regulator. */
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++)
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++)
 | |
| -+			for (k = 0; k < ctrl->thread[i].vreg[j].corner_count;
 | |
| -+			     k++)
 | |
| -+				for (m = 0; m < CPR3_RO_COUNT; m++)
 | |
| -+					if (ctrl->thread[i].vreg[j].corner[k].
 | |
| -+					    target_quot[m])
 | |
| -+						ro_used |= BIT(m);
 | |
| -+
 | |
| -+	/* Configure the GCNT of the RO's that will be used */
 | |
| -+	gcnt = cpr3_regulator_get_gcnt(ctrl);
 | |
| -+	for (i = 0; i < CPR3_RO_COUNT; i++)
 | |
| -+		if (ro_used & BIT(i))
 | |
| -+			cpr3_write(ctrl, CPR3_REG_GCNT(i), gcnt);
 | |
| -+
 | |
| -+	/* Configure the loop delay time */
 | |
| -+	temp = (u64)ctrl->cpr_clock_rate * (u64)ctrl->loop_time;
 | |
| -+	do_div(temp, 1000000000);
 | |
| -+	cont_dly = temp;
 | |
| -+	if (ctrl->supports_hw_closed_loop
 | |
| -+		&& ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3)
 | |
| -+		cpr3_write(ctrl, CPR3_REG_CPR_TIMER_MID_CONT, cont_dly);
 | |
| -+	else
 | |
| -+		cpr3_write(ctrl, CPR3_REG_CPR_TIMER_AUTO_CONT, cont_dly);
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+		temp = (u64)ctrl->cpr_clock_rate *
 | |
| -+				(u64)ctrl->up_down_delay_time;
 | |
| -+		do_div(temp, 1000000000);
 | |
| -+		up_down_dly = temp;
 | |
| -+		if (ctrl->supports_hw_closed_loop)
 | |
| -+			cpr3_write(ctrl, CPR3_REG_CPR_TIMER_UP_DN_CONT,
 | |
| -+				up_down_dly);
 | |
| -+		cpr3_debug(ctrl, "up_down_dly=%u, up_down_delay_time=%u ns\n",
 | |
| -+			up_down_dly, ctrl->up_down_delay_time);
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_debug(ctrl, "cpr_clock_rate=%u HZ, sensor_time=%u ns, loop_time=%u ns, gcnt=%u, cont_dly=%u\n",
 | |
| -+		ctrl->cpr_clock_rate, ctrl->sensor_time, ctrl->loop_time,
 | |
| -+		gcnt, cont_dly);
 | |
| -+
 | |
| -+	/* Configure CPR sensor operation */
 | |
| -+	val = (ctrl->idle_clocks << CPR3_CPR_CTL_IDLE_CLOCKS_SHIFT)
 | |
| -+		& CPR3_CPR_CTL_IDLE_CLOCKS_MASK;
 | |
| -+	val |= (ctrl->count_mode << CPR3_CPR_CTL_COUNT_MODE_SHIFT)
 | |
| -+		& CPR3_CPR_CTL_COUNT_MODE_MASK;
 | |
| -+	val |= (ctrl->count_repeat << CPR3_CPR_CTL_COUNT_REPEAT_SHIFT)
 | |
| -+		& CPR3_CPR_CTL_COUNT_REPEAT_MASK;
 | |
| -+	cpr3_write(ctrl, CPR3_REG_CPR_CTL, val);
 | |
| -+
 | |
| -+	cpr3_debug(ctrl, "idle_clocks=%u, count_mode=%u, count_repeat=%u; CPR_CTL=0x%08X\n",
 | |
| -+		ctrl->idle_clocks, ctrl->count_mode, ctrl->count_repeat, val);
 | |
| -+
 | |
| -+	/* Configure CPR default step quotients */
 | |
| -+	val = (ctrl->step_quot_init_min << CPR3_CPR_STEP_QUOT_MIN_SHIFT)
 | |
| -+		& CPR3_CPR_STEP_QUOT_MIN_MASK;
 | |
| -+	val |= (ctrl->step_quot_init_max << CPR3_CPR_STEP_QUOT_MAX_SHIFT)
 | |
| -+		& CPR3_CPR_STEP_QUOT_MAX_MASK;
 | |
| -+	cpr3_write(ctrl, CPR3_REG_CPR_STEP_QUOT, val);
 | |
| -+
 | |
| -+	cpr3_debug(ctrl, "step_quot_min=%u, step_quot_max=%u; STEP_QUOT=0x%08X\n",
 | |
| -+		ctrl->step_quot_init_min, ctrl->step_quot_init_max, val);
 | |
| -+
 | |
| -+	/* Configure the CPR sensor ownership */
 | |
| -+	for (i = 0; i < ctrl->sensor_count; i++)
 | |
| -+		cpr3_write(ctrl, CPR3_REG_SENSOR_OWNER(i),
 | |
| -+			   ctrl->sensor_owner[i]);
 | |
| -+
 | |
| -+	/* Configure per-thread registers */
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		rc = cpr3_regulator_init_thread(&ctrl->thread[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "CPR thread register initialization failed, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->supports_hw_closed_loop) {
 | |
| -+		if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+			cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+				CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_EN_MASK,
 | |
| -+				ctrl->use_hw_closed_loop
 | |
| -+				? CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_ENABLE
 | |
| -+				: CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_DISABLE);
 | |
| -+		} else if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+			cpr3_write(ctrl, CPR3_REG_HW_CLOSED_LOOP,
 | |
| -+				ctrl->use_hw_closed_loop
 | |
| -+				? CPR3_HW_CLOSED_LOOP_ENABLE
 | |
| -+				: CPR3_HW_CLOSED_LOOP_DISABLE);
 | |
| -+
 | |
| -+			cpr3_debug(ctrl, "PD_THROTTLE=0x%08X\n",
 | |
| -+				ctrl->proc_clock_throttle);
 | |
| -+		}
 | |
| -+
 | |
| -+		if ((ctrl->use_hw_closed_loop ||
 | |
| -+		     ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) &&
 | |
| -+		    ctrl->vdd_limit_regulator) {
 | |
| -+			rc = regulator_enable(ctrl->vdd_limit_regulator);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(ctrl, "CPR limit regulator enable failed, rc=%d\n",
 | |
| -+					rc);
 | |
| -+				return rc;
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+		rc = cpr3_regulator_init_cpr4(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "CPR4-specific controller initialization failed, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Ensure that all register writes complete before disabling clocks. */
 | |
| -+	wmb();
 | |
| -+
 | |
| -+	cpr3_clock_disable(ctrl);
 | |
| -+	ctrl->cpr_enabled = false;
 | |
| -+
 | |
| -+	if (!ctrl->cpr_allowed_sw || !ctrl->cpr_allowed_hw)
 | |
| -+		mode = "open-loop";
 | |
| -+	else if (ctrl->supports_hw_closed_loop)
 | |
| -+		mode = ctrl->use_hw_closed_loop
 | |
| -+			? "HW closed-loop" : "SW closed-loop";
 | |
| -+	else
 | |
| -+		mode = "closed-loop";
 | |
| -+
 | |
| -+	cpr3_info(ctrl, "Default CPR mode = %s", mode);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_set_target_quot() - configure the target quotient for each
 | |
| -+ *		RO of the CPR3 thread and set the RO mask
 | |
| -+ * @thread:		Pointer to the CPR3 thread
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static void cpr3_regulator_set_target_quot(struct cpr3_thread *thread)
 | |
| -+{
 | |
| -+	u32 new_quot, last_quot;
 | |
| -+	int i;
 | |
| -+
 | |
| -+	if (thread->aggr_corner.ro_mask == CPR3_RO_MASK
 | |
| -+	    && thread->last_closed_loop_aggr_corner.ro_mask == CPR3_RO_MASK) {
 | |
| -+		/* Avoid writing target quotients since all RO's are masked. */
 | |
| -+		return;
 | |
| -+	} else if (thread->aggr_corner.ro_mask == CPR3_RO_MASK) {
 | |
| -+		cpr3_write(thread->ctrl, CPR3_REG_RO_MASK(thread->thread_id),
 | |
| -+			CPR3_RO_MASK);
 | |
| -+		thread->last_closed_loop_aggr_corner.ro_mask = CPR3_RO_MASK;
 | |
| -+		/*
 | |
| -+		 * Only the RO_MASK register needs to be written since all
 | |
| -+		 * RO's are masked.
 | |
| -+		 */
 | |
| -+		return;
 | |
| -+	} else if (thread->aggr_corner.ro_mask
 | |
| -+			!= thread->last_closed_loop_aggr_corner.ro_mask) {
 | |
| -+		cpr3_write(thread->ctrl, CPR3_REG_RO_MASK(thread->thread_id),
 | |
| -+			thread->aggr_corner.ro_mask);
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < CPR3_RO_COUNT; i++) {
 | |
| -+		new_quot = thread->aggr_corner.target_quot[i];
 | |
| -+		last_quot = thread->last_closed_loop_aggr_corner.target_quot[i];
 | |
| -+		if (new_quot != last_quot)
 | |
| -+			cpr3_write(thread->ctrl,
 | |
| -+				CPR3_REG_TARGET_QUOT(thread->thread_id, i),
 | |
| -+				new_quot);
 | |
| -+	}
 | |
| -+
 | |
| -+	thread->last_closed_loop_aggr_corner = thread->aggr_corner;
 | |
| -+
 | |
| -+	return;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_update_vreg_closed_loop_volt() - update the last known settled
 | |
| -+ *		closed loop voltage for a CPR3 regulator
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @vdd_volt:		Last known settled voltage in microvolts for the
 | |
| -+ *			VDD supply
 | |
| -+ * @reg_last_measurement: Value read from the LAST_MEASUREMENT register
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static void cpr3_update_vreg_closed_loop_volt(struct cpr3_regulator *vreg,
 | |
| -+				int vdd_volt, u32 reg_last_measurement)
 | |
| -+{
 | |
| -+	bool step_dn, step_up, aggr_step_up, aggr_step_dn, aggr_step_mid;
 | |
| -+	bool valid, pd_valid, saw_error;
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	struct cpr3_corner *corner;
 | |
| -+	u32 id;
 | |
| -+
 | |
| -+	if (vreg->last_closed_loop_corner == CPR3_REGULATOR_CORNER_INVALID)
 | |
| -+		return;
 | |
| -+	else
 | |
| -+		corner = &vreg->corner[vreg->last_closed_loop_corner];
 | |
| -+
 | |
| -+	if (vreg->thread->last_closed_loop_aggr_corner.ro_mask
 | |
| -+	    == CPR3_RO_MASK  || !vreg->aggregated) {
 | |
| -+		return;
 | |
| -+	} else if (!ctrl->cpr_enabled || !ctrl->last_corner_was_closed_loop) {
 | |
| -+		return;
 | |
| -+	} else if (ctrl->thread_count == 1
 | |
| -+		 && vdd_volt >= corner->floor_volt
 | |
| -+		 && vdd_volt <= corner->ceiling_volt) {
 | |
| -+		corner->last_volt = vdd_volt;
 | |
| -+		cpr3_debug(vreg, "last_volt updated: last_volt[%d]=%d, ceiling_volt[%d]=%d, floor_volt[%d]=%d\n",
 | |
| -+			   vreg->last_closed_loop_corner, corner->last_volt,
 | |
| -+			   vreg->last_closed_loop_corner,
 | |
| -+			   corner->ceiling_volt,
 | |
| -+			   vreg->last_closed_loop_corner,
 | |
| -+			   corner->floor_volt);
 | |
| -+		return;
 | |
| -+	} else if (!ctrl->supports_hw_closed_loop) {
 | |
| -+		return;
 | |
| -+	} else if (ctrl->ctrl_type != CPR_CTRL_TYPE_CPR3) {
 | |
| -+		corner->last_volt = vdd_volt;
 | |
| -+		cpr3_debug(vreg, "last_volt updated: last_volt[%d]=%d, ceiling_volt[%d]=%d, floor_volt[%d]=%d\n",
 | |
| -+			   vreg->last_closed_loop_corner, corner->last_volt,
 | |
| -+			   vreg->last_closed_loop_corner,
 | |
| -+			   corner->ceiling_volt,
 | |
| -+			   vreg->last_closed_loop_corner,
 | |
| -+			   corner->floor_volt);
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	/* CPR clocks are on and HW closed loop is supported */
 | |
| -+	valid = !!(reg_last_measurement & CPR3_LAST_MEASUREMENT_VALID);
 | |
| -+	if (!valid) {
 | |
| -+		cpr3_debug(vreg, "CPR_LAST_VALID_MEASUREMENT=0x%X valid bit not set\n",
 | |
| -+			   reg_last_measurement);
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	id = vreg->thread->thread_id;
 | |
| -+
 | |
| -+	step_dn
 | |
| -+	       = !!(reg_last_measurement & CPR3_LAST_MEASUREMENT_THREAD_DN(id));
 | |
| -+	step_up
 | |
| -+	       = !!(reg_last_measurement & CPR3_LAST_MEASUREMENT_THREAD_UP(id));
 | |
| -+	aggr_step_dn = !!(reg_last_measurement & CPR3_LAST_MEASUREMENT_AGGR_DN);
 | |
| -+	aggr_step_mid
 | |
| -+		= !!(reg_last_measurement & CPR3_LAST_MEASUREMENT_AGGR_MID);
 | |
| -+	aggr_step_up = !!(reg_last_measurement & CPR3_LAST_MEASUREMENT_AGGR_UP);
 | |
| -+	saw_error = !!(reg_last_measurement & CPR3_LAST_MEASUREMENT_SAW_ERROR);
 | |
| -+	pd_valid
 | |
| -+	     = !((((reg_last_measurement & CPR3_LAST_MEASUREMENT_PD_BYPASS_MASK)
 | |
| -+		       >> CPR3_LAST_MEASUREMENT_PD_BYPASS_SHIFT)
 | |
| -+		      & vreg->pd_bypass_mask) == vreg->pd_bypass_mask);
 | |
| -+
 | |
| -+	if (!pd_valid) {
 | |
| -+		cpr3_debug(vreg, "CPR_LAST_VALID_MEASUREMENT=0x%X, all power domains bypassed\n",
 | |
| -+			   reg_last_measurement);
 | |
| -+		return;
 | |
| -+	} else if (step_dn && step_up) {
 | |
| -+		cpr3_err(vreg, "both up and down status bits set, CPR_LAST_VALID_MEASUREMENT=0x%X\n",
 | |
| -+			 reg_last_measurement);
 | |
| -+		return;
 | |
| -+	} else if (aggr_step_dn && step_dn && vdd_volt < corner->last_volt
 | |
| -+		   && vdd_volt >= corner->floor_volt) {
 | |
| -+		corner->last_volt = vdd_volt;
 | |
| -+	} else if (aggr_step_up && step_up && vdd_volt > corner->last_volt
 | |
| -+		   && vdd_volt <= corner->ceiling_volt) {
 | |
| -+		corner->last_volt = vdd_volt;
 | |
| -+	} else if (aggr_step_mid
 | |
| -+		   && vdd_volt >= corner->floor_volt
 | |
| -+		   && vdd_volt <= corner->ceiling_volt) {
 | |
| -+		corner->last_volt = vdd_volt;
 | |
| -+	} else if (saw_error && (vdd_volt == corner->ceiling_volt
 | |
| -+				 || vdd_volt == corner->floor_volt)) {
 | |
| -+		corner->last_volt = vdd_volt;
 | |
| -+	} else {
 | |
| -+		cpr3_debug(vreg, "last_volt not updated: last_volt[%d]=%d, ceiling_volt[%d]=%d, floor_volt[%d]=%d, vdd_volt=%d, CPR_LAST_VALID_MEASUREMENT=0x%X\n",
 | |
| -+			   vreg->last_closed_loop_corner, corner->last_volt,
 | |
| -+			   vreg->last_closed_loop_corner,
 | |
| -+			   corner->ceiling_volt,
 | |
| -+			   vreg->last_closed_loop_corner, corner->floor_volt,
 | |
| -+			   vdd_volt, reg_last_measurement);
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_debug(vreg, "last_volt updated: last_volt[%d]=%d, ceiling_volt[%d]=%d, floor_volt[%d]=%d, CPR_LAST_VALID_MEASUREMENT=0x%X\n",
 | |
| -+		   vreg->last_closed_loop_corner, corner->last_volt,
 | |
| -+		   vreg->last_closed_loop_corner, corner->ceiling_volt,
 | |
| -+		   vreg->last_closed_loop_corner, corner->floor_volt,
 | |
| -+		   reg_last_measurement);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_mem_acc_bhs_used() - determines if mem-acc regulators powered
 | |
| -+ *		through a BHS are associated with the CPR3 controller or any of
 | |
| -+ *		the CPR3 regulators it controls.
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * This function determines if the CPR3 controller or any of its CPR3 regulators
 | |
| -+ * need to manage mem-acc regulators that are currently powered through a BHS
 | |
| -+ * and whose corner selection is based upon a particular voltage threshold.
 | |
| -+ *
 | |
| -+ * Return: true or false
 | |
| -+ */
 | |
| -+static bool cpr3_regulator_mem_acc_bhs_used(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+	int i, j;
 | |
| -+
 | |
| -+	if (!ctrl->mem_acc_threshold_volt)
 | |
| -+		return false;
 | |
| -+
 | |
| -+	if (ctrl->mem_acc_regulator)
 | |
| -+		return true;
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+			vreg = &ctrl->thread[i].vreg[j];
 | |
| -+
 | |
| -+			if (vreg->mem_acc_regulator)
 | |
| -+				return true;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return false;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_config_bhs_mem_acc() - configure the mem-acc regulator
 | |
| -+ *		settings for hardware blocks currently powered through the BHS.
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @new_volt:		New voltage in microvolts that VDD supply needs to
 | |
| -+ *			end up at
 | |
| -+ * @last_volt:		Pointer to the last known voltage in microvolts for the
 | |
| -+ *			VDD supply
 | |
| -+ * @aggr_corner:	Pointer to the CPR3 corner which corresponds to the max
 | |
| -+ *			corner aggregated from all CPR3 threads managed by the
 | |
| -+ *			CPR3 controller
 | |
| -+ *
 | |
| -+ * This function programs the mem-acc regulator corners for CPR3 regulators
 | |
| -+ * whose LDO regulators are in bypassed state. The function also handles
 | |
| -+ * CPR3 controllers which utilize mem-acc regulators that operate independently
 | |
| -+ * from the LDO hardware and that must be programmed when the VDD supply
 | |
| -+ * crosses a particular voltage threshold.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure. If the VDD supply voltage is
 | |
| -+ * modified, last_volt is updated to reflect the new voltage setpoint.
 | |
| -+ */
 | |
| -+static int cpr3_regulator_config_bhs_mem_acc(struct cpr3_controller *ctrl,
 | |
| -+				     int new_volt, int *last_volt,
 | |
| -+				     struct cpr3_corner *aggr_corner)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+	int i, j, rc, mem_acc_corn, safe_volt;
 | |
| -+	int mem_acc_volt = ctrl->mem_acc_threshold_volt;
 | |
| -+	int ref_volt;
 | |
| -+
 | |
| -+	if (!cpr3_regulator_mem_acc_bhs_used(ctrl))
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	ref_volt = ctrl->use_hw_closed_loop ? aggr_corner->floor_volt :
 | |
| -+		new_volt;
 | |
| -+
 | |
| -+	if (((*last_volt < mem_acc_volt && mem_acc_volt <= ref_volt) ||
 | |
| -+	     (*last_volt >= mem_acc_volt && mem_acc_volt > ref_volt))) {
 | |
| -+		if (ref_volt < *last_volt)
 | |
| -+			safe_volt = max(mem_acc_volt, aggr_corner->last_volt);
 | |
| -+		else
 | |
| -+			safe_volt = max(mem_acc_volt, *last_volt);
 | |
| -+
 | |
| -+		rc = regulator_set_voltage(ctrl->vdd_regulator, safe_volt,
 | |
| -+					   new_volt < *last_volt ?
 | |
| -+					   ctrl->aggr_corner.ceiling_volt :
 | |
| -+					   new_volt);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "regulator_set_voltage(vdd) == %d failed, rc=%d\n",
 | |
| -+				 safe_volt, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		*last_volt = safe_volt;
 | |
| -+
 | |
| -+		mem_acc_corn = ref_volt < mem_acc_volt ?
 | |
| -+			ctrl->mem_acc_corner_map[CPR3_MEM_ACC_LOW_CORNER] :
 | |
| -+			ctrl->mem_acc_corner_map[CPR3_MEM_ACC_HIGH_CORNER];
 | |
| -+
 | |
| -+		if (ctrl->mem_acc_regulator) {
 | |
| -+			rc = regulator_set_voltage(ctrl->mem_acc_regulator,
 | |
| -+						   mem_acc_corn, mem_acc_corn);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(ctrl, "regulator_set_voltage(mem_acc) == %d failed, rc=%d\n",
 | |
| -+					 mem_acc_corn, rc);
 | |
| -+				return rc;
 | |
| -+			}
 | |
| -+		}
 | |
| -+
 | |
| -+		for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+			for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+				vreg = &ctrl->thread[i].vreg[j];
 | |
| -+
 | |
| -+				if (!vreg->mem_acc_regulator)
 | |
| -+					continue;
 | |
| -+
 | |
| -+				rc = regulator_set_voltage(
 | |
| -+					vreg->mem_acc_regulator, mem_acc_corn,
 | |
| -+					mem_acc_corn);
 | |
| -+				if (rc) {
 | |
| -+					cpr3_err(vreg, "regulator_set_voltage(mem_acc) == %d failed, rc=%d\n",
 | |
| -+						 mem_acc_corn, rc);
 | |
| -+					return rc;
 | |
| -+				}
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_switch_apm_mode() - switch the mode of the APM controller
 | |
| -+ *		associated with a given CPR3 controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @new_volt:		New voltage in microvolts that VDD supply needs to
 | |
| -+ *			end up at
 | |
| -+ * @last_volt:		Pointer to the last known voltage in microvolts for the
 | |
| -+ *			VDD supply
 | |
| -+ * @aggr_corner:	Pointer to the CPR3 corner which corresponds to the max
 | |
| -+ *			corner aggregated from all CPR3 threads managed by the
 | |
| -+ *			CPR3 controller
 | |
| -+ *
 | |
| -+ * This function requests a switch of the APM mode while guaranteeing
 | |
| -+ * any LDO regulator hardware requirements are satisfied. The function must
 | |
| -+ * be called once it is known a new VDD supply setpoint crosses the APM
 | |
| -+ * voltage threshold.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure. If the VDD supply voltage is
 | |
| -+ * modified, last_volt is updated to reflect the new voltage setpoint.
 | |
| -+ */
 | |
| -+static int cpr3_regulator_switch_apm_mode(struct cpr3_controller *ctrl,
 | |
| -+					  int new_volt, int *last_volt,
 | |
| -+					  struct cpr3_corner *aggr_corner)
 | |
| -+{
 | |
| -+	struct regulator *vdd = ctrl->vdd_regulator;
 | |
| -+	int apm_volt = ctrl->apm_threshold_volt;
 | |
| -+	int orig_last_volt = *last_volt;
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = regulator_set_voltage(vdd, apm_volt, apm_volt);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "regulator_set_voltage(vdd) == %d failed, rc=%d\n",
 | |
| -+			 apm_volt, rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	*last_volt = apm_volt;
 | |
| -+
 | |
| -+	rc = msm_apm_set_supply(ctrl->apm, new_volt >= apm_volt
 | |
| -+				? ctrl->apm_high_supply : ctrl->apm_low_supply);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "APM switch failed, rc=%d\n", rc);
 | |
| -+		/* Roll back the voltage. */
 | |
| -+		regulator_set_voltage(vdd, orig_last_volt, INT_MAX);
 | |
| -+		*last_volt = orig_last_volt;
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_config_voltage_crossings() - configure APM and mem-acc
 | |
| -+ *		settings depending upon a new VDD supply setpoint
 | |
| -+ *
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @new_volt:		New voltage in microvolts that VDD supply needs to
 | |
| -+ *			end up at
 | |
| -+ * @last_volt:		Pointer to the last known voltage in microvolts for the
 | |
| -+ *			VDD supply
 | |
| -+ * @aggr_corner:	Pointer to the CPR3 corner which corresponds to the max
 | |
| -+ *			corner aggregated from all CPR3 threads managed by the
 | |
| -+ *			CPR3 controller
 | |
| -+ *
 | |
| -+ * This function handles the APM and mem-acc regulator reconfiguration if
 | |
| -+ * the new VDD supply voltage will result in crossing their respective voltage
 | |
| -+ * thresholds.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure. If the VDD supply voltage is
 | |
| -+ * modified, last_volt is updated to reflect the new voltage setpoint.
 | |
| -+ */
 | |
| -+static int cpr3_regulator_config_voltage_crossings(struct cpr3_controller *ctrl,
 | |
| -+				   int new_volt, int *last_volt,
 | |
| -+				   struct cpr3_corner *aggr_corner)
 | |
| -+{
 | |
| -+	bool apm_crossing = false, mem_acc_crossing = false;
 | |
| -+	bool mem_acc_bhs_used;
 | |
| -+	int apm_volt = ctrl->apm_threshold_volt;
 | |
| -+	int mem_acc_volt = ctrl->mem_acc_threshold_volt;
 | |
| -+	int ref_volt, rc;
 | |
| -+
 | |
| -+	if (ctrl->apm && apm_volt > 0
 | |
| -+	    && ((*last_volt < apm_volt && apm_volt <= new_volt)
 | |
| -+		|| (*last_volt >= apm_volt && apm_volt > new_volt)))
 | |
| -+		apm_crossing = true;
 | |
| -+
 | |
| -+	mem_acc_bhs_used = cpr3_regulator_mem_acc_bhs_used(ctrl);
 | |
| -+
 | |
| -+	ref_volt = ctrl->use_hw_closed_loop ? aggr_corner->floor_volt :
 | |
| -+		new_volt;
 | |
| -+
 | |
| -+	if (mem_acc_bhs_used &&
 | |
| -+	    (((*last_volt < mem_acc_volt && mem_acc_volt <= ref_volt) ||
 | |
| -+	      (*last_volt >= mem_acc_volt && mem_acc_volt > ref_volt))))
 | |
| -+		mem_acc_crossing = true;
 | |
| -+
 | |
| -+	if (apm_crossing && mem_acc_crossing) {
 | |
| -+		if ((new_volt < *last_volt && apm_volt >= mem_acc_volt) ||
 | |
| -+		    (new_volt >= *last_volt && apm_volt < mem_acc_volt)) {
 | |
| -+			rc = cpr3_regulator_switch_apm_mode(ctrl, new_volt,
 | |
| -+							    last_volt,
 | |
| -+							    aggr_corner);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(ctrl, "unable to switch APM mode\n");
 | |
| -+				return rc;
 | |
| -+			}
 | |
| -+
 | |
| -+			rc = cpr3_regulator_config_bhs_mem_acc(ctrl, new_volt,
 | |
| -+						       last_volt, aggr_corner);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(ctrl, "unable to configure BHS mem-acc settings\n");
 | |
| -+				return rc;
 | |
| -+			}
 | |
| -+		} else {
 | |
| -+			rc = cpr3_regulator_config_bhs_mem_acc(ctrl, new_volt,
 | |
| -+						       last_volt, aggr_corner);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(ctrl, "unable to configure BHS mem-acc settings\n");
 | |
| -+				return rc;
 | |
| -+			}
 | |
| -+
 | |
| -+			rc = cpr3_regulator_switch_apm_mode(ctrl, new_volt,
 | |
| -+							    last_volt,
 | |
| -+							    aggr_corner);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(ctrl, "unable to switch APM mode\n");
 | |
| -+				return rc;
 | |
| -+			}
 | |
| -+		}
 | |
| -+	} else if (apm_crossing) {
 | |
| -+		rc = cpr3_regulator_switch_apm_mode(ctrl, new_volt, last_volt,
 | |
| -+						    aggr_corner);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "unable to switch APM mode\n");
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	} else if (mem_acc_crossing) {
 | |
| -+		rc = cpr3_regulator_config_bhs_mem_acc(ctrl, new_volt,
 | |
| -+						       last_volt, aggr_corner);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "unable to configure BHS mem-acc settings\n");
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_config_mem_acc() - configure the corner of the mem-acc
 | |
| -+ *			regulator associated with the CPR3 controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @aggr_corner:	Pointer to the CPR3 corner which corresponds to the max
 | |
| -+ *			corner aggregated from all CPR3 threads managed by the
 | |
| -+ *			CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_config_mem_acc(struct cpr3_controller *ctrl,
 | |
| -+					 struct cpr3_corner *aggr_corner)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	if (ctrl->mem_acc_regulator && aggr_corner->mem_acc_volt) {
 | |
| -+		rc = regulator_set_voltage(ctrl->mem_acc_regulator,
 | |
| -+					   aggr_corner->mem_acc_volt,
 | |
| -+					   aggr_corner->mem_acc_volt);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "regulator_set_voltage(mem_acc) == %d failed, rc=%d\n",
 | |
| -+				 aggr_corner->mem_acc_volt, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_scale_vdd_voltage() - scale the CPR controlled VDD supply
 | |
| -+ *		voltage to the new level while satisfying any other hardware
 | |
| -+ *		requirements
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @new_volt:		New voltage in microvolts that VDD supply needs to end
 | |
| -+ *			up at
 | |
| -+ * @last_volt:		Last known voltage in microvolts for the VDD supply
 | |
| -+ * @aggr_corner:	Pointer to the CPR3 corner which corresponds to the max
 | |
| -+ *			corner aggregated from all CPR3 threads managed by the
 | |
| -+ *			CPR3 controller
 | |
| -+ *
 | |
| -+ * This function scales the CPR controlled VDD supply voltage from its
 | |
| -+ * current level to the new voltage that is specified.  If the supply is
 | |
| -+ * configured to use the APM and the APM threshold is crossed as a result of
 | |
| -+ * the voltage scaling, then this function also stops at the APM threshold,
 | |
| -+ * switches the APM source, and finally sets the final new voltage.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_scale_vdd_voltage(struct cpr3_controller *ctrl,
 | |
| -+				int new_volt, int last_volt,
 | |
| -+				struct cpr3_corner *aggr_corner)
 | |
| -+{
 | |
| -+	struct regulator *vdd = ctrl->vdd_regulator;
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	if (new_volt < last_volt) {
 | |
| -+			rc = cpr3_regulator_config_mem_acc(ctrl, aggr_corner);
 | |
| -+			if (rc)
 | |
| -+				return rc;
 | |
| -+	} else {
 | |
| -+		/* Increasing VDD voltage */
 | |
| -+		if (ctrl->system_regulator) {
 | |
| -+			rc = regulator_set_voltage(ctrl->system_regulator,
 | |
| -+				aggr_corner->system_volt, INT_MAX);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(ctrl, "regulator_set_voltage(system) == %d failed, rc=%d\n",
 | |
| -+					aggr_corner->system_volt, rc);
 | |
| -+				return rc;
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_regulator_config_voltage_crossings(ctrl, new_volt, &last_volt,
 | |
| -+						     aggr_corner);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "unable to handle voltage threshold crossing configurations, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Subtract a small amount from the min_uV parameter so that the
 | |
| -+	 * set voltage request is not dropped by the framework due to being
 | |
| -+	 * duplicate.  This is needed in order to switch from hardware
 | |
| -+	 * closed-loop to open-loop successfully.
 | |
| -+	 */
 | |
| -+	rc = regulator_set_voltage(vdd, new_volt - (ctrl->cpr_enabled ? 0 : 1),
 | |
| -+				   aggr_corner->ceiling_volt);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "regulator_set_voltage(vdd) == %d failed, rc=%d\n",
 | |
| -+			new_volt, rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (new_volt == last_volt && ctrl->supports_hw_closed_loop
 | |
| -+	    && ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+		/*
 | |
| -+		 * CPR4 features enforce voltage reprogramming when the last
 | |
| -+		 * set voltage and new set voltage are same. This way, we can
 | |
| -+		 * ensure that SAW PMIC STATUS register is updated with newly
 | |
| -+		 * programmed voltage.
 | |
| -+		 */
 | |
| -+		rc = regulator_sync_voltage(vdd);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "regulator_sync_voltage(vdd) == %d failed, rc=%d\n",
 | |
| -+				new_volt, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (new_volt >= last_volt) {
 | |
| -+		rc = cpr3_regulator_config_mem_acc(ctrl, aggr_corner);
 | |
| -+		if (rc)
 | |
| -+			return rc;
 | |
| -+	} else {
 | |
| -+		/* Decreasing VDD voltage */
 | |
| -+		if (ctrl->system_regulator) {
 | |
| -+			rc = regulator_set_voltage(ctrl->system_regulator,
 | |
| -+				aggr_corner->system_volt, INT_MAX);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(ctrl, "regulator_set_voltage(system) == %d failed, rc=%d\n",
 | |
| -+					aggr_corner->system_volt, rc);
 | |
| -+				return rc;
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_get_dynamic_floor_volt() - returns the current dynamic floor
 | |
| -+ *		voltage based upon static configurations and the state of all
 | |
| -+ *		power domains during the last CPR measurement
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @reg_last_measurement: Value read from the LAST_MEASUREMENT register
 | |
| -+ *
 | |
| -+ * When using HW closed-loop, the dynamic floor voltage is always returned
 | |
| -+ * regardless of the current state of the power domains.
 | |
| -+ *
 | |
| -+ * Return: dynamic floor voltage in microvolts or 0 if dynamic floor is not
 | |
| -+ *         currently required
 | |
| -+ */
 | |
| -+static int cpr3_regulator_get_dynamic_floor_volt(struct cpr3_controller *ctrl,
 | |
| -+		u32 reg_last_measurement)
 | |
| -+{
 | |
| -+	int dynamic_floor_volt = 0;
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+	bool valid, pd_valid;
 | |
| -+	u32 bypass_bits;
 | |
| -+	int i, j;
 | |
| -+
 | |
| -+	if (!ctrl->supports_hw_closed_loop)
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	if (likely(!ctrl->use_hw_closed_loop)) {
 | |
| -+		valid = !!(reg_last_measurement & CPR3_LAST_MEASUREMENT_VALID);
 | |
| -+		bypass_bits
 | |
| -+		 = (reg_last_measurement & CPR3_LAST_MEASUREMENT_PD_BYPASS_MASK)
 | |
| -+			>> CPR3_LAST_MEASUREMENT_PD_BYPASS_SHIFT;
 | |
| -+	} else {
 | |
| -+		/*
 | |
| -+		 * Ensure that the dynamic floor voltage is always used for
 | |
| -+		 * HW closed-loop since the conditions below cannot be evaluated
 | |
| -+		 * after each CPR measurement.
 | |
| -+		 */
 | |
| -+		valid = false;
 | |
| -+		bypass_bits = 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+			vreg = &ctrl->thread[i].vreg[j];
 | |
| -+
 | |
| -+			if (!vreg->uses_dynamic_floor)
 | |
| -+				continue;
 | |
| -+
 | |
| -+			pd_valid = !((bypass_bits & vreg->pd_bypass_mask)
 | |
| -+					== vreg->pd_bypass_mask);
 | |
| -+
 | |
| -+			if (!valid || !pd_valid)
 | |
| -+				dynamic_floor_volt = max(dynamic_floor_volt,
 | |
| -+					vreg->corner[
 | |
| -+					 vreg->dynamic_floor_corner].last_volt);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return dynamic_floor_volt;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_max_sdelta_diff() - returns the maximum voltage difference in
 | |
| -+ *		microvolts that can result from different operating conditions
 | |
| -+ *		for the specified sdelta struct
 | |
| -+ * @sdelta:		Pointer to the sdelta structure
 | |
| -+ * @step_volt:		Step size in microvolts between available set
 | |
| -+ *			points of the VDD supply.
 | |
| -+ *
 | |
| -+ * Return: voltage difference between the highest and lowest adjustments if
 | |
| -+ *	sdelta and sdelta->table are valid, else 0.
 | |
| -+ */
 | |
| -+static int cpr3_regulator_max_sdelta_diff(const struct cpr4_sdelta *sdelta,
 | |
| -+				int step_volt)
 | |
| -+{
 | |
| -+	int i, j, index, sdelta_min = INT_MAX, sdelta_max = INT_MIN;
 | |
| -+
 | |
| -+	if (!sdelta || !sdelta->table)
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	for (i = 0; i < sdelta->max_core_count; i++) {
 | |
| -+		for (j = 0; j < sdelta->temp_band_count; j++) {
 | |
| -+			index = i * sdelta->temp_band_count + j;
 | |
| -+			sdelta_min = min(sdelta_min, sdelta->table[index]);
 | |
| -+			sdelta_max = max(sdelta_max, sdelta->table[index]);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return (sdelta_max - sdelta_min) * step_volt;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_aggregate_sdelta() - check open-loop voltages of current
 | |
| -+ *		aggregated corner and current corner of a given regulator
 | |
| -+ *		and adjust the sdelta strucuture data of aggregate corner.
 | |
| -+ * @aggr_corner:	Pointer to accumulated aggregated corner which
 | |
| -+ *			is both an input and an output
 | |
| -+ * @corner:		Pointer to the corner to be aggregated with
 | |
| -+ *			aggr_corner
 | |
| -+ * @step_volt:		Step size in microvolts between available set
 | |
| -+ *			points of the VDD supply.
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static void cpr3_regulator_aggregate_sdelta(
 | |
| -+				struct cpr3_corner *aggr_corner,
 | |
| -+				const struct cpr3_corner *corner, int step_volt)
 | |
| -+{
 | |
| -+	struct cpr4_sdelta *aggr_sdelta, *sdelta;
 | |
| -+	int aggr_core_count, core_count, temp_band_count;
 | |
| -+	u32 aggr_index, index;
 | |
| -+	int i, j, sdelta_size, cap_steps, adjust_sdelta;
 | |
| -+
 | |
| -+	aggr_sdelta = aggr_corner->sdelta;
 | |
| -+	sdelta = corner->sdelta;
 | |
| -+
 | |
| -+	if (aggr_corner->open_loop_volt < corner->open_loop_volt) {
 | |
| -+		/*
 | |
| -+		 * Found the new dominant regulator as its open-loop requirement
 | |
| -+		 * is higher than previous dominant regulator. Calculate cap
 | |
| -+		 * voltage to limit the SDELTA values to make sure the runtime
 | |
| -+		 * (Core-count/temp) adjustments do not violate other
 | |
| -+		 * regulators' voltage requirements. Use cpr4_sdelta values of
 | |
| -+		 * new dominant regulator.
 | |
| -+		 */
 | |
| -+		aggr_sdelta->cap_volt = min(aggr_sdelta->cap_volt,
 | |
| -+						(corner->open_loop_volt -
 | |
| -+						aggr_corner->open_loop_volt));
 | |
| -+
 | |
| -+		/* Clear old data in the sdelta table */
 | |
| -+		sdelta_size = aggr_sdelta->max_core_count
 | |
| -+					* aggr_sdelta->temp_band_count;
 | |
| -+
 | |
| -+		if (aggr_sdelta->allow_core_count_adj
 | |
| -+			|| aggr_sdelta->allow_temp_adj)
 | |
| -+			memset(aggr_sdelta->table, 0, sdelta_size
 | |
| -+					* sizeof(*aggr_sdelta->table));
 | |
| -+
 | |
| -+		if (sdelta->allow_temp_adj || sdelta->allow_core_count_adj) {
 | |
| -+			/* Copy new data in sdelta table */
 | |
| -+			sdelta_size = sdelta->max_core_count
 | |
| -+						* sdelta->temp_band_count;
 | |
| -+			if (sdelta->table)
 | |
| -+				memcpy(aggr_sdelta->table, sdelta->table,
 | |
| -+					sdelta_size * sizeof(*sdelta->table));
 | |
| -+		}
 | |
| -+
 | |
| -+		if (sdelta->allow_boost) {
 | |
| -+			memcpy(aggr_sdelta->boost_table, sdelta->boost_table,
 | |
| -+				sdelta->temp_band_count
 | |
| -+				* sizeof(*sdelta->boost_table));
 | |
| -+			aggr_sdelta->boost_num_cores = sdelta->boost_num_cores;
 | |
| -+		} else if (aggr_sdelta->allow_boost) {
 | |
| -+			for (i = 0; i < aggr_sdelta->temp_band_count; i++) {
 | |
| -+				adjust_sdelta = (corner->open_loop_volt
 | |
| -+						- aggr_corner->open_loop_volt)
 | |
| -+						/ step_volt;
 | |
| -+				aggr_sdelta->boost_table[i] += adjust_sdelta;
 | |
| -+				aggr_sdelta->boost_table[i]
 | |
| -+					= min(aggr_sdelta->boost_table[i], 0);
 | |
| -+			}
 | |
| -+		}
 | |
| -+
 | |
| -+		aggr_corner->open_loop_volt = corner->open_loop_volt;
 | |
| -+		aggr_sdelta->allow_temp_adj = sdelta->allow_temp_adj;
 | |
| -+		aggr_sdelta->allow_core_count_adj
 | |
| -+					= sdelta->allow_core_count_adj;
 | |
| -+		aggr_sdelta->max_core_count = sdelta->max_core_count;
 | |
| -+		aggr_sdelta->temp_band_count = sdelta->temp_band_count;
 | |
| -+	} else if (aggr_corner->open_loop_volt > corner->open_loop_volt) {
 | |
| -+		/*
 | |
| -+		 * Adjust the cap voltage if the open-loop requirement of new
 | |
| -+		 * regulator is the next highest.
 | |
| -+		 */
 | |
| -+		aggr_sdelta->cap_volt = min(aggr_sdelta->cap_volt,
 | |
| -+						(aggr_corner->open_loop_volt
 | |
| -+						- corner->open_loop_volt));
 | |
| -+
 | |
| -+		if (sdelta->allow_boost) {
 | |
| -+			for (i = 0; i < aggr_sdelta->temp_band_count; i++) {
 | |
| -+				adjust_sdelta = (aggr_corner->open_loop_volt
 | |
| -+						- corner->open_loop_volt)
 | |
| -+						/ step_volt;
 | |
| -+				aggr_sdelta->boost_table[i] =
 | |
| -+					sdelta->boost_table[i] + adjust_sdelta;
 | |
| -+				aggr_sdelta->boost_table[i]
 | |
| -+					= min(aggr_sdelta->boost_table[i], 0);
 | |
| -+			}
 | |
| -+			aggr_sdelta->boost_num_cores = sdelta->boost_num_cores;
 | |
| -+		}
 | |
| -+	} else {
 | |
| -+		/*
 | |
| -+		 * Found another dominant regulator with same open-loop
 | |
| -+		 * requirement. Make cap voltage to '0'. Disable core-count
 | |
| -+		 * adjustments as we couldn't support for both regulators.
 | |
| -+		 * Keep enable temp based adjustments if enabled for both
 | |
| -+		 * regulators and choose mininum margin adjustment values
 | |
| -+		 * between them.
 | |
| -+		 */
 | |
| -+		aggr_sdelta->cap_volt = 0;
 | |
| -+		aggr_sdelta->allow_core_count_adj = false;
 | |
| -+
 | |
| -+		if (aggr_sdelta->allow_temp_adj
 | |
| -+					&& sdelta->allow_temp_adj) {
 | |
| -+			aggr_core_count = aggr_sdelta->max_core_count - 1;
 | |
| -+			core_count = sdelta->max_core_count - 1;
 | |
| -+			temp_band_count = sdelta->temp_band_count;
 | |
| -+			for (j = 0; j < temp_band_count; j++) {
 | |
| -+				aggr_index = aggr_core_count * temp_band_count
 | |
| -+						+ j;
 | |
| -+				index = core_count * temp_band_count + j;
 | |
| -+				aggr_sdelta->table[aggr_index] =
 | |
| -+					min(aggr_sdelta->table[aggr_index],
 | |
| -+						sdelta->table[index]);
 | |
| -+			}
 | |
| -+		} else {
 | |
| -+			aggr_sdelta->allow_temp_adj = false;
 | |
| -+		}
 | |
| -+
 | |
| -+		if (sdelta->allow_boost) {
 | |
| -+			memcpy(aggr_sdelta->boost_table, sdelta->boost_table,
 | |
| -+				sdelta->temp_band_count
 | |
| -+				* sizeof(*sdelta->boost_table));
 | |
| -+			aggr_sdelta->boost_num_cores = sdelta->boost_num_cores;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Keep non-dominant clients boost enable state */
 | |
| -+	aggr_sdelta->allow_boost |= sdelta->allow_boost;
 | |
| -+	if (aggr_sdelta->allow_boost)
 | |
| -+		aggr_sdelta->allow_core_count_adj = false;
 | |
| -+
 | |
| -+	if (aggr_sdelta->cap_volt && !(aggr_sdelta->cap_volt == INT_MAX)) {
 | |
| -+		core_count = aggr_sdelta->max_core_count;
 | |
| -+		temp_band_count = aggr_sdelta->temp_band_count;
 | |
| -+		/*
 | |
| -+		 * Convert cap voltage from uV to PMIC steps and use to limit
 | |
| -+		 * sdelta margin adjustments.
 | |
| -+		 */
 | |
| -+		cap_steps = aggr_sdelta->cap_volt / step_volt;
 | |
| -+		for (i = 0; i < core_count; i++)
 | |
| -+			for (j = 0; j < temp_band_count; j++) {
 | |
| -+				index = i * temp_band_count + j;
 | |
| -+				aggr_sdelta->table[index] =
 | |
| -+						min(aggr_sdelta->table[index],
 | |
| -+							cap_steps);
 | |
| -+		}
 | |
| -+	}
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_aggregate_corners() - aggregate two corners together
 | |
| -+ * @aggr_corner:		Pointer to accumulated aggregated corner which
 | |
| -+ *				is both an input and an output
 | |
| -+ * @corner:			Pointer to the corner to be aggregated with
 | |
| -+ *				aggr_corner
 | |
| -+ * @aggr_quot:			Flag indicating that target quotients should be
 | |
| -+ *				aggregated as well.
 | |
| -+ * @step_volt:			Step size in microvolts between available set
 | |
| -+ *				points of the VDD supply.
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static void cpr3_regulator_aggregate_corners(struct cpr3_corner *aggr_corner,
 | |
| -+			const struct cpr3_corner *corner, bool aggr_quot,
 | |
| -+			int step_volt)
 | |
| -+{
 | |
| -+	int i;
 | |
| -+
 | |
| -+	aggr_corner->ceiling_volt
 | |
| -+		= max(aggr_corner->ceiling_volt, corner->ceiling_volt);
 | |
| -+	aggr_corner->floor_volt
 | |
| -+		= max(aggr_corner->floor_volt, corner->floor_volt);
 | |
| -+	aggr_corner->last_volt
 | |
| -+		= max(aggr_corner->last_volt, corner->last_volt);
 | |
| -+	aggr_corner->system_volt
 | |
| -+		= max(aggr_corner->system_volt, corner->system_volt);
 | |
| -+	aggr_corner->mem_acc_volt
 | |
| -+		= max(aggr_corner->mem_acc_volt, corner->mem_acc_volt);
 | |
| -+	aggr_corner->irq_en |= corner->irq_en;
 | |
| -+	aggr_corner->use_open_loop |= corner->use_open_loop;
 | |
| -+
 | |
| -+	if (aggr_quot) {
 | |
| -+		aggr_corner->ro_mask &= corner->ro_mask;
 | |
| -+
 | |
| -+		for (i = 0; i < CPR3_RO_COUNT; i++)
 | |
| -+			aggr_corner->target_quot[i]
 | |
| -+				= max(aggr_corner->target_quot[i],
 | |
| -+				      corner->target_quot[i]);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (aggr_corner->sdelta && corner->sdelta
 | |
| -+		&& (aggr_corner->sdelta->table
 | |
| -+		|| aggr_corner->sdelta->boost_table)) {
 | |
| -+		cpr3_regulator_aggregate_sdelta(aggr_corner, corner, step_volt);
 | |
| -+	} else {
 | |
| -+		aggr_corner->open_loop_volt
 | |
| -+			= max(aggr_corner->open_loop_volt,
 | |
| -+				corner->open_loop_volt);
 | |
| -+	}
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_update_ctrl_state() - update the state of the CPR controller
 | |
| -+ *		to reflect the corners used by all CPR3 regulators as well as
 | |
| -+ *		the CPR operating mode
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * This function aggregates the CPR parameters for all CPR3 regulators
 | |
| -+ * associated with the VDD supply.  Upon success, it sets the aggregated last
 | |
| -+ * known good voltage.
 | |
| -+ *
 | |
| -+ * The VDD supply voltage will not be physically configured unless this
 | |
| -+ * condition is met by at least one of the regulators of the controller:
 | |
| -+ * regulator->vreg_enabled == true &&
 | |
| -+ * regulator->current_corner != CPR3_REGULATOR_CORNER_INVALID
 | |
| -+ *
 | |
| -+ * CPR registers for the controller and each thread are updated as long as
 | |
| -+ * ctrl->cpr_enabled == true.
 | |
| -+ *
 | |
| -+ * Note, CPR3 controller lock must be held by the caller.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int _cpr3_regulator_update_ctrl_state(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct cpr3_corner aggr_corner = {};
 | |
| -+	struct cpr3_thread *thread;
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+	struct cpr4_sdelta *sdelta;
 | |
| -+	bool valid = false;
 | |
| -+	bool thread_valid;
 | |
| -+	int i, j, rc, new_volt, vdd_volt, dynamic_floor_volt, last_corner_volt;
 | |
| -+	u32 reg_last_measurement = 0, sdelta_size;
 | |
| -+	int *sdelta_table, *boost_table;
 | |
| -+
 | |
| -+	last_corner_volt = 0;
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+		rc = cpr3_ctrl_clear_cpr4_config(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "failed to clear CPR4 configuration,rc=%d\n",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_ctrl_loop_disable(ctrl);
 | |
| -+
 | |
| -+	vdd_volt = regulator_get_voltage(ctrl->vdd_regulator);
 | |
| -+	if (vdd_volt < 0) {
 | |
| -+		cpr3_err(ctrl, "regulator_get_voltage(vdd) failed, rc=%d\n",
 | |
| -+			 vdd_volt);
 | |
| -+		return vdd_volt;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+		/*
 | |
| -+		 * Save aggregated corner open-loop voltage which was programmed
 | |
| -+		 * during last corner switch which is used when programming new
 | |
| -+		 * aggregated corner open-loop voltage.
 | |
| -+		 */
 | |
| -+		last_corner_volt = ctrl->aggr_corner.open_loop_volt;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->cpr_enabled && ctrl->use_hw_closed_loop &&
 | |
| -+		ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3)
 | |
| -+		reg_last_measurement
 | |
| -+			= cpr3_read(ctrl, CPR3_REG_LAST_MEASUREMENT);
 | |
| -+
 | |
| -+	aggr_corner.sdelta = ctrl->aggr_corner.sdelta;
 | |
| -+	if (aggr_corner.sdelta) {
 | |
| -+		sdelta = aggr_corner.sdelta;
 | |
| -+		sdelta_table = sdelta->table;
 | |
| -+		if (sdelta_table) {
 | |
| -+			sdelta_size = sdelta->max_core_count *
 | |
| -+					sdelta->temp_band_count;
 | |
| -+			memset(sdelta_table, 0, sdelta_size
 | |
| -+					* sizeof(*sdelta_table));
 | |
| -+		}
 | |
| -+
 | |
| -+		boost_table = sdelta->boost_table;
 | |
| -+		if (boost_table)
 | |
| -+			memset(boost_table, 0, sdelta->temp_band_count
 | |
| -+					* sizeof(*boost_table));
 | |
| -+
 | |
| -+		memset(sdelta, 0, sizeof(*sdelta));
 | |
| -+		sdelta->table = sdelta_table;
 | |
| -+		sdelta->cap_volt = INT_MAX;
 | |
| -+		sdelta->boost_table = boost_table;
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Aggregate the requests of all threads */
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		thread = &ctrl->thread[i];
 | |
| -+		thread_valid = false;
 | |
| -+
 | |
| -+		sdelta = thread->aggr_corner.sdelta;
 | |
| -+		if (sdelta) {
 | |
| -+			sdelta_table = sdelta->table;
 | |
| -+			if (sdelta_table) {
 | |
| -+				sdelta_size = sdelta->max_core_count *
 | |
| -+						sdelta->temp_band_count;
 | |
| -+				memset(sdelta_table, 0, sdelta_size
 | |
| -+						* sizeof(*sdelta_table));
 | |
| -+			}
 | |
| -+
 | |
| -+			boost_table = sdelta->boost_table;
 | |
| -+			if (boost_table)
 | |
| -+				memset(boost_table, 0, sdelta->temp_band_count
 | |
| -+						* sizeof(*boost_table));
 | |
| -+
 | |
| -+			memset(sdelta, 0, sizeof(*sdelta));
 | |
| -+			sdelta->table = sdelta_table;
 | |
| -+			sdelta->cap_volt = INT_MAX;
 | |
| -+			sdelta->boost_table = boost_table;
 | |
| -+		}
 | |
| -+
 | |
| -+		memset(&thread->aggr_corner, 0, sizeof(thread->aggr_corner));
 | |
| -+		thread->aggr_corner.sdelta = sdelta;
 | |
| -+		thread->aggr_corner.ro_mask = CPR3_RO_MASK;
 | |
| -+
 | |
| -+		for (j = 0; j < thread->vreg_count; j++) {
 | |
| -+			vreg = &thread->vreg[j];
 | |
| -+
 | |
| -+			if (ctrl->cpr_enabled && ctrl->use_hw_closed_loop)
 | |
| -+				cpr3_update_vreg_closed_loop_volt(vreg,
 | |
| -+						vdd_volt, reg_last_measurement);
 | |
| -+
 | |
| -+			if (!vreg->vreg_enabled
 | |
| -+			    || vreg->current_corner
 | |
| -+					    == CPR3_REGULATOR_CORNER_INVALID) {
 | |
| -+				/* Cannot participate in aggregation. */
 | |
| -+				vreg->aggregated = false;
 | |
| -+				continue;
 | |
| -+			} else {
 | |
| -+				vreg->aggregated = true;
 | |
| -+				thread_valid = true;
 | |
| -+			}
 | |
| -+
 | |
| -+			cpr3_regulator_aggregate_corners(&thread->aggr_corner,
 | |
| -+					&vreg->corner[vreg->current_corner],
 | |
| -+					true, ctrl->step_volt);
 | |
| -+		}
 | |
| -+
 | |
| -+		valid |= thread_valid;
 | |
| -+
 | |
| -+		if (thread_valid)
 | |
| -+			cpr3_regulator_aggregate_corners(&aggr_corner,
 | |
| -+					&thread->aggr_corner,
 | |
| -+					false, ctrl->step_volt);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (valid && ctrl->cpr_allowed_hw && ctrl->cpr_allowed_sw) {
 | |
| -+		rc = cpr3_closed_loop_enable(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "could not enable CPR, rc=%d\n", rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	} else {
 | |
| -+		rc = cpr3_closed_loop_disable(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "could not disable CPR, rc=%d\n", rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* No threads are enabled with a valid corner so exit. */
 | |
| -+	if (!valid)
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * When using CPR hardware closed-loop, the voltage may vary anywhere
 | |
| -+	 * between the floor and ceiling voltage without software notification.
 | |
| -+	 * Therefore, it is required that the floor to ceiling range for the
 | |
| -+	 * aggregated corner not intersect the APM threshold voltage.  Adjust
 | |
| -+	 * the floor to ceiling range if this requirement is violated.
 | |
| -+	 *
 | |
| -+	 * The following algorithm is applied in the case that
 | |
| -+	 * floor < threshold <= ceiling:
 | |
| -+	 *	if open_loop >= threshold - adj, then floor = threshold
 | |
| -+	 *	else ceiling = threshold - step
 | |
| -+	 * where adj = an adjustment factor to ensure sufficient voltage margin
 | |
| -+	 * and step = VDD output step size
 | |
| -+	 *
 | |
| -+	 * The open-loop and last known voltages are also bounded by the new
 | |
| -+	 * floor or ceiling value as needed.
 | |
| -+	 */
 | |
| -+	if (ctrl->use_hw_closed_loop
 | |
| -+	    && aggr_corner.ceiling_volt >= ctrl->apm_threshold_volt
 | |
| -+	    && aggr_corner.floor_volt < ctrl->apm_threshold_volt) {
 | |
| -+
 | |
| -+		if (aggr_corner.open_loop_volt
 | |
| -+		    >= ctrl->apm_threshold_volt - ctrl->apm_adj_volt)
 | |
| -+			aggr_corner.floor_volt = ctrl->apm_threshold_volt;
 | |
| -+		else
 | |
| -+			aggr_corner.ceiling_volt
 | |
| -+				= ctrl->apm_threshold_volt - ctrl->step_volt;
 | |
| -+
 | |
| -+		aggr_corner.last_volt
 | |
| -+		    = max(aggr_corner.last_volt, aggr_corner.floor_volt);
 | |
| -+		aggr_corner.last_volt
 | |
| -+		    = min(aggr_corner.last_volt, aggr_corner.ceiling_volt);
 | |
| -+		aggr_corner.open_loop_volt
 | |
| -+		    = max(aggr_corner.open_loop_volt, aggr_corner.floor_volt);
 | |
| -+		aggr_corner.open_loop_volt
 | |
| -+		    = min(aggr_corner.open_loop_volt, aggr_corner.ceiling_volt);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->use_hw_closed_loop
 | |
| -+	    && aggr_corner.ceiling_volt >= ctrl->mem_acc_threshold_volt
 | |
| -+	    && aggr_corner.floor_volt < ctrl->mem_acc_threshold_volt) {
 | |
| -+		aggr_corner.floor_volt = ctrl->mem_acc_threshold_volt;
 | |
| -+		aggr_corner.last_volt = max(aggr_corner.last_volt,
 | |
| -+					     aggr_corner.floor_volt);
 | |
| -+		aggr_corner.open_loop_volt = max(aggr_corner.open_loop_volt,
 | |
| -+						  aggr_corner.floor_volt);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->use_hw_closed_loop) {
 | |
| -+		dynamic_floor_volt
 | |
| -+			= cpr3_regulator_get_dynamic_floor_volt(ctrl,
 | |
| -+							reg_last_measurement);
 | |
| -+		if (aggr_corner.floor_volt < dynamic_floor_volt) {
 | |
| -+			aggr_corner.floor_volt = dynamic_floor_volt;
 | |
| -+			aggr_corner.last_volt = max(aggr_corner.last_volt,
 | |
| -+							aggr_corner.floor_volt);
 | |
| -+			aggr_corner.open_loop_volt
 | |
| -+				= max(aggr_corner.open_loop_volt,
 | |
| -+					aggr_corner.floor_volt);
 | |
| -+			aggr_corner.ceiling_volt = max(aggr_corner.ceiling_volt,
 | |
| -+							aggr_corner.floor_volt);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->cpr_enabled && ctrl->last_corner_was_closed_loop) {
 | |
| -+		/*
 | |
| -+		 * Always program open-loop voltage for CPR4 controllers which
 | |
| -+		 * support hardware closed-loop.  Storing the last closed loop
 | |
| -+		 * voltage in corner structure can still help with debugging.
 | |
| -+		 */
 | |
| -+		if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3)
 | |
| -+			new_volt = aggr_corner.last_volt;
 | |
| -+		else if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4
 | |
| -+			 && ctrl->supports_hw_closed_loop)
 | |
| -+			new_volt = aggr_corner.open_loop_volt;
 | |
| -+		else
 | |
| -+			new_volt = min(aggr_corner.last_volt +
 | |
| -+			      cpr3_regulator_max_sdelta_diff(aggr_corner.sdelta,
 | |
| -+							     ctrl->step_volt),
 | |
| -+				       aggr_corner.ceiling_volt);
 | |
| -+
 | |
| -+		aggr_corner.last_volt = new_volt;
 | |
| -+	} else {
 | |
| -+		new_volt = aggr_corner.open_loop_volt;
 | |
| -+		aggr_corner.last_volt = aggr_corner.open_loop_volt;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4
 | |
| -+	    && ctrl->supports_hw_closed_loop) {
 | |
| -+		/*
 | |
| -+		 * Store last aggregated corner open-loop voltage in vdd_volt
 | |
| -+		 * which is used when programming current aggregated corner
 | |
| -+		 * required voltage.
 | |
| -+		 */
 | |
| -+		vdd_volt = last_corner_volt;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_debug(ctrl, "setting new voltage=%d uV\n", new_volt);
 | |
| -+	rc = cpr3_regulator_scale_vdd_voltage(ctrl, new_volt,
 | |
| -+					      vdd_volt, &aggr_corner);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "vdd voltage scaling failed, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Only update registers if CPR is enabled. */
 | |
| -+	if (ctrl->cpr_enabled) {
 | |
| -+		if (ctrl->use_hw_closed_loop) {
 | |
| -+			/* Hardware closed-loop */
 | |
| -+
 | |
| -+			/* Set ceiling and floor limits in hardware */
 | |
| -+			rc = regulator_set_voltage(ctrl->vdd_limit_regulator,
 | |
| -+				aggr_corner.floor_volt,
 | |
| -+				aggr_corner.ceiling_volt);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(ctrl, "could not configure HW closed-loop voltage limits, rc=%d\n",
 | |
| -+					rc);
 | |
| -+				return rc;
 | |
| -+			}
 | |
| -+		} else {
 | |
| -+			/* Software closed-loop */
 | |
| -+
 | |
| -+			/*
 | |
| -+			 * Disable UP or DOWN interrupts when at ceiling or
 | |
| -+			 * floor respectively.
 | |
| -+			 */
 | |
| -+			if (new_volt == aggr_corner.floor_volt)
 | |
| -+				aggr_corner.irq_en &= ~CPR3_IRQ_DOWN;
 | |
| -+			if (new_volt == aggr_corner.ceiling_volt)
 | |
| -+				aggr_corner.irq_en &= ~CPR3_IRQ_UP;
 | |
| -+
 | |
| -+			cpr3_write(ctrl, CPR3_REG_IRQ_CLEAR,
 | |
| -+				CPR3_IRQ_UP | CPR3_IRQ_DOWN);
 | |
| -+			cpr3_write(ctrl, CPR3_REG_IRQ_EN, aggr_corner.irq_en);
 | |
| -+		}
 | |
| -+
 | |
| -+		for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+			cpr3_regulator_set_target_quot(&ctrl->thread[i]);
 | |
| -+
 | |
| -+			for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+				vreg = &ctrl->thread[i].vreg[j];
 | |
| -+
 | |
| -+				if (vreg->vreg_enabled)
 | |
| -+					vreg->last_closed_loop_corner
 | |
| -+						= vreg->current_corner;
 | |
| -+			}
 | |
| -+		}
 | |
| -+
 | |
| -+		if (ctrl->proc_clock_throttle) {
 | |
| -+			if (aggr_corner.ceiling_volt > aggr_corner.floor_volt
 | |
| -+			    && (ctrl->use_hw_closed_loop
 | |
| -+					|| new_volt < aggr_corner.ceiling_volt))
 | |
| -+				cpr3_write(ctrl, CPR3_REG_PD_THROTTLE,
 | |
| -+						ctrl->proc_clock_throttle);
 | |
| -+			else
 | |
| -+				cpr3_write(ctrl, CPR3_REG_PD_THROTTLE,
 | |
| -+						CPR3_PD_THROTTLE_DISABLE);
 | |
| -+		}
 | |
| -+
 | |
| -+		/*
 | |
| -+		 * Ensure that all CPR register writes complete before
 | |
| -+		 * re-enabling CPR loop operation.
 | |
| -+		 */
 | |
| -+		wmb();
 | |
| -+	} else if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4
 | |
| -+		   && ctrl->vdd_limit_regulator) {
 | |
| -+		/* Set ceiling and floor limits in hardware */
 | |
| -+		rc = regulator_set_voltage(ctrl->vdd_limit_regulator,
 | |
| -+			aggr_corner.floor_volt,
 | |
| -+			aggr_corner.ceiling_volt);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "could not configure HW closed-loop voltage limits, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->aggr_corner = aggr_corner;
 | |
| -+
 | |
| -+	if (ctrl->allow_core_count_adj || ctrl->allow_temp_adj
 | |
| -+		|| ctrl->allow_boost) {
 | |
| -+		rc = cpr3_controller_program_sdelta(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "failed to program sdelta, rc=%d\n", rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Only enable the CPR controller if it is possible to set more than
 | |
| -+	 * one vdd-supply voltage.
 | |
| -+	 */
 | |
| -+	if (aggr_corner.ceiling_volt > aggr_corner.floor_volt &&
 | |
| -+			!aggr_corner.use_open_loop)
 | |
| -+		cpr3_ctrl_loop_enable(ctrl);
 | |
| -+
 | |
| -+	ctrl->last_corner_was_closed_loop = ctrl->cpr_enabled;
 | |
| -+	cpr3_debug(ctrl, "CPR configuration updated\n");
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_wait_for_idle() - wait for the CPR controller to no longer be
 | |
| -+ *		busy
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @max_wait_ns:	Max wait time in nanoseconds
 | |
| -+ *
 | |
| -+ * Return: 0 on success or -ETIMEDOUT if the controller was still busy after
 | |
| -+ *	   the maximum delay time
 | |
| -+ */
 | |
| -+static int cpr3_regulator_wait_for_idle(struct cpr3_controller *ctrl,
 | |
| -+					s64 max_wait_ns)
 | |
| -+{
 | |
| -+	ktime_t start, end;
 | |
| -+	s64 time_ns;
 | |
| -+	u32 reg;
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Ensure that all previous CPR register writes have completed before
 | |
| -+	 * checking the status register.
 | |
| -+	 */
 | |
| -+	mb();
 | |
| -+
 | |
| -+	start = ktime_get();
 | |
| -+	do {
 | |
| -+		end = ktime_get();
 | |
| -+		time_ns = ktime_to_ns(ktime_sub(end, start));
 | |
| -+		if (time_ns > max_wait_ns) {
 | |
| -+			cpr3_err(ctrl, "CPR controller still busy after %lld us\n",
 | |
| -+				div_s64(time_ns, 1000));
 | |
| -+			return -ETIMEDOUT;
 | |
| -+		}
 | |
| -+		usleep_range(50, 100);
 | |
| -+		reg = cpr3_read(ctrl, CPR3_REG_CPR_STATUS);
 | |
| -+	} while (reg & CPR3_CPR_STATUS_BUSY_MASK);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cmp_int() - int comparison function to be passed into the sort() function
 | |
| -+ *		which leads to ascending sorting
 | |
| -+ * @a:			First int value
 | |
| -+ * @b:			Second int value
 | |
| -+ *
 | |
| -+ * Return: >0 if a > b, 0 if a == b, <0 if a < b
 | |
| -+ */
 | |
| -+static int cmp_int(const void *a, const void *b)
 | |
| -+{
 | |
| -+	return *(int *)a - *(int *)b;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_measure_aging() - measure the quotient difference for the
 | |
| -+ *		specified CPR aging sensor
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @aging_sensor:	Aging sensor to measure
 | |
| -+ *
 | |
| -+ * Note that vdd-supply must be configured to the aging reference voltage before
 | |
| -+ * calling this function.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_measure_aging(struct cpr3_controller *ctrl,
 | |
| -+				struct cpr3_aging_sensor_info *aging_sensor)
 | |
| -+{
 | |
| -+	u32 mask, reg, result, quot_min, quot_max, sel_min, sel_max;
 | |
| -+	u32 quot_min_scaled, quot_max_scaled;
 | |
| -+	u32 gcnt, gcnt_ref, gcnt0_restore, gcnt1_restore, irq_restore;
 | |
| -+	u32 ro_mask_restore, cont_dly_restore, up_down_dly_restore = 0;
 | |
| -+	int quot_delta, quot_delta_scaled, quot_delta_scaled_sum;
 | |
| -+	int *quot_delta_results;
 | |
| -+	int rc, rc2, i, aging_measurement_count, filtered_count;
 | |
| -+	bool is_aging_measurement;
 | |
| -+
 | |
| -+	quot_delta_results = kcalloc(CPR3_AGING_MEASUREMENT_ITERATIONS,
 | |
| -+			sizeof(*quot_delta_results), GFP_KERNEL);
 | |
| -+	if (!quot_delta_results)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+		rc = cpr3_ctrl_clear_cpr4_config(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "failed to clear CPR4 configuration,rc=%d\n",
 | |
| -+				rc);
 | |
| -+			kfree(quot_delta_results);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_ctrl_loop_disable(ctrl);
 | |
| -+
 | |
| -+	/* Enable up, down, and mid CPR interrupts */
 | |
| -+	irq_restore = cpr3_read(ctrl, CPR3_REG_IRQ_EN);
 | |
| -+	cpr3_write(ctrl, CPR3_REG_IRQ_EN,
 | |
| -+			CPR3_IRQ_UP | CPR3_IRQ_DOWN | CPR3_IRQ_MID);
 | |
| -+
 | |
| -+	/* Ensure that the aging sensor is assigned to CPR thread 0 */
 | |
| -+	cpr3_write(ctrl, CPR3_REG_SENSOR_OWNER(aging_sensor->sensor_id), 0);
 | |
| -+
 | |
| -+	/* Switch from HW to SW closed-loop if necessary */
 | |
| -+	if (ctrl->supports_hw_closed_loop) {
 | |
| -+		if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+			cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+				CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_EN_MASK,
 | |
| -+				CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_DISABLE);
 | |
| -+		} else if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+			cpr3_write(ctrl, CPR3_REG_HW_CLOSED_LOOP,
 | |
| -+				CPR3_HW_CLOSED_LOOP_DISABLE);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Configure the GCNT for RO0 and RO1 that are used for aging */
 | |
| -+	gcnt0_restore = cpr3_read(ctrl, CPR3_REG_GCNT(0));
 | |
| -+	gcnt1_restore = cpr3_read(ctrl, CPR3_REG_GCNT(1));
 | |
| -+	gcnt_ref = cpr3_regulator_get_gcnt(ctrl);
 | |
| -+	gcnt = gcnt_ref * 3 / 2;
 | |
| -+	cpr3_write(ctrl, CPR3_REG_GCNT(0), gcnt);
 | |
| -+	cpr3_write(ctrl, CPR3_REG_GCNT(1), gcnt);
 | |
| -+
 | |
| -+	/* Unmask all RO's */
 | |
| -+	ro_mask_restore = cpr3_read(ctrl, CPR3_REG_RO_MASK(0));
 | |
| -+	cpr3_write(ctrl, CPR3_REG_RO_MASK(0), 0);
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Mask all sensors except for the one to measure and bypass all
 | |
| -+	 * sensors in collapsible domains.
 | |
| -+	 */
 | |
| -+	for (i = 0; i <= ctrl->sensor_count / 32; i++) {
 | |
| -+		mask = GENMASK(min(31, ctrl->sensor_count - i * 32), 0);
 | |
| -+		if (aging_sensor->sensor_id / 32 >= i
 | |
| -+		    && aging_sensor->sensor_id / 32 < (i + 1))
 | |
| -+			mask &= ~BIT(aging_sensor->sensor_id % 32);
 | |
| -+		cpr3_write(ctrl, CPR3_REG_SENSOR_MASK_WRITE_BANK(i), mask);
 | |
| -+		cpr3_write(ctrl, CPR3_REG_SENSOR_BYPASS_WRITE_BANK(i),
 | |
| -+				aging_sensor->bypass_mask[i]);
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Set CPR loop delays to 0 us */
 | |
| -+	if (ctrl->supports_hw_closed_loop
 | |
| -+		&& ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+		cont_dly_restore = cpr3_read(ctrl, CPR3_REG_CPR_TIMER_MID_CONT);
 | |
| -+		up_down_dly_restore = cpr3_read(ctrl,
 | |
| -+						CPR3_REG_CPR_TIMER_UP_DN_CONT);
 | |
| -+		cpr3_write(ctrl, CPR3_REG_CPR_TIMER_MID_CONT, 0);
 | |
| -+		cpr3_write(ctrl, CPR3_REG_CPR_TIMER_UP_DN_CONT, 0);
 | |
| -+	} else {
 | |
| -+		cont_dly_restore = cpr3_read(ctrl,
 | |
| -+						CPR3_REG_CPR_TIMER_AUTO_CONT);
 | |
| -+		cpr3_write(ctrl, CPR3_REG_CPR_TIMER_AUTO_CONT, 0);
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Set count mode to all-at-once min with no repeat */
 | |
| -+	cpr3_masked_write(ctrl, CPR3_REG_CPR_CTL,
 | |
| -+		CPR3_CPR_CTL_COUNT_MODE_MASK | CPR3_CPR_CTL_COUNT_REPEAT_MASK,
 | |
| -+		CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_MIN
 | |
| -+			<< CPR3_CPR_CTL_COUNT_MODE_SHIFT);
 | |
| -+
 | |
| -+	cpr3_ctrl_loop_enable(ctrl);
 | |
| -+
 | |
| -+	rc = cpr3_regulator_wait_for_idle(ctrl,
 | |
| -+					CPR3_AGING_MEASUREMENT_TIMEOUT_NS);
 | |
| -+	if (rc)
 | |
| -+		goto cleanup;
 | |
| -+
 | |
| -+	/* Set count mode to all-at-once aging */
 | |
| -+	cpr3_masked_write(ctrl, CPR3_REG_CPR_CTL, CPR3_CPR_CTL_COUNT_MODE_MASK,
 | |
| -+			CPR3_CPR_CTL_COUNT_MODE_ALL_AT_ONCE_AGE
 | |
| -+				<< CPR3_CPR_CTL_COUNT_MODE_SHIFT);
 | |
| -+
 | |
| -+	aging_measurement_count = 0;
 | |
| -+	for (i = 0; i < CPR3_AGING_MEASUREMENT_ITERATIONS; i++) {
 | |
| -+		/* Send CONT_NACK */
 | |
| -+		cpr3_write(ctrl, CPR3_REG_CONT_CMD, CPR3_CONT_CMD_NACK);
 | |
| -+
 | |
| -+		rc = cpr3_regulator_wait_for_idle(ctrl,
 | |
| -+					CPR3_AGING_MEASUREMENT_TIMEOUT_NS);
 | |
| -+		if (rc)
 | |
| -+			goto cleanup;
 | |
| -+
 | |
| -+		/* Check for PAGE_IS_AGE flag in status register */
 | |
| -+		reg = cpr3_read(ctrl, CPR3_REG_CPR_STATUS);
 | |
| -+		is_aging_measurement
 | |
| -+			= reg & CPR3_CPR_STATUS_AGING_MEASUREMENT_MASK;
 | |
| -+
 | |
| -+		/* Read CPR measurement results */
 | |
| -+		result = cpr3_read(ctrl, CPR3_REG_RESULT1(0));
 | |
| -+		quot_min = (result & CPR3_RESULT1_QUOT_MIN_MASK)
 | |
| -+				>> CPR3_RESULT1_QUOT_MIN_SHIFT;
 | |
| -+		quot_max = (result & CPR3_RESULT1_QUOT_MAX_MASK)
 | |
| -+				>> CPR3_RESULT1_QUOT_MAX_SHIFT;
 | |
| -+		sel_min = (result & CPR3_RESULT1_RO_MIN_MASK)
 | |
| -+				>> CPR3_RESULT1_RO_MIN_SHIFT;
 | |
| -+		sel_max = (result & CPR3_RESULT1_RO_MAX_MASK)
 | |
| -+				>> CPR3_RESULT1_RO_MAX_SHIFT;
 | |
| -+
 | |
| -+		/*
 | |
| -+		 * Scale the quotients so that they are equivalent to the fused
 | |
| -+		 * values.  This accounts for the difference in measurement
 | |
| -+		 * interval times.
 | |
| -+		 */
 | |
| -+		quot_min_scaled = quot_min * (gcnt_ref + 1) / (gcnt + 1);
 | |
| -+		quot_max_scaled = quot_max * (gcnt_ref + 1) / (gcnt + 1);
 | |
| -+
 | |
| -+		if (sel_max == 1) {
 | |
| -+			quot_delta = quot_max - quot_min;
 | |
| -+			quot_delta_scaled = quot_max_scaled - quot_min_scaled;
 | |
| -+		} else {
 | |
| -+			quot_delta = quot_min - quot_max;
 | |
| -+			quot_delta_scaled = quot_min_scaled - quot_max_scaled;
 | |
| -+		}
 | |
| -+
 | |
| -+		if (is_aging_measurement)
 | |
| -+			quot_delta_results[aging_measurement_count++]
 | |
| -+				= quot_delta_scaled;
 | |
| -+
 | |
| -+		cpr3_debug(ctrl, "aging results: page_is_age=%u, sel_min=%u, sel_max=%u, quot_min=%u, quot_max=%u, quot_delta=%d, quot_min_scaled=%u, quot_max_scaled=%u, quot_delta_scaled=%d\n",
 | |
| -+			is_aging_measurement, sel_min, sel_max, quot_min,
 | |
| -+			quot_max, quot_delta, quot_min_scaled, quot_max_scaled,
 | |
| -+			quot_delta_scaled);
 | |
| -+	}
 | |
| -+
 | |
| -+	filtered_count
 | |
| -+		= aging_measurement_count - CPR3_AGING_MEASUREMENT_FILTER * 2;
 | |
| -+	if (filtered_count > 0) {
 | |
| -+		sort(quot_delta_results, aging_measurement_count,
 | |
| -+			sizeof(*quot_delta_results), cmp_int, NULL);
 | |
| -+
 | |
| -+		quot_delta_scaled_sum = 0;
 | |
| -+		for (i = 0; i < filtered_count; i++)
 | |
| -+			quot_delta_scaled_sum
 | |
| -+				+= quot_delta_results[i
 | |
| -+					+ CPR3_AGING_MEASUREMENT_FILTER];
 | |
| -+
 | |
| -+		aging_sensor->measured_quot_diff
 | |
| -+			= quot_delta_scaled_sum / filtered_count;
 | |
| -+		cpr3_info(ctrl, "average quotient delta=%d (count=%d)\n",
 | |
| -+			aging_sensor->measured_quot_diff,
 | |
| -+			filtered_count);
 | |
| -+	} else {
 | |
| -+		cpr3_err(ctrl, "%d aging measurements completed after %d iterations\n",
 | |
| -+			aging_measurement_count,
 | |
| -+			CPR3_AGING_MEASUREMENT_ITERATIONS);
 | |
| -+		rc = -EBUSY;
 | |
| -+	}
 | |
| -+
 | |
| -+cleanup:
 | |
| -+	kfree(quot_delta_results);
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+		rc2 = cpr3_ctrl_clear_cpr4_config(ctrl);
 | |
| -+		if (rc2) {
 | |
| -+			cpr3_err(ctrl, "failed to clear CPR4 configuration,rc=%d\n",
 | |
| -+				rc2);
 | |
| -+			rc = rc2;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_ctrl_loop_disable(ctrl);
 | |
| -+
 | |
| -+	cpr3_write(ctrl, CPR3_REG_IRQ_EN, irq_restore);
 | |
| -+
 | |
| -+	cpr3_write(ctrl, CPR3_REG_RO_MASK(0), ro_mask_restore);
 | |
| -+
 | |
| -+	cpr3_write(ctrl, CPR3_REG_GCNT(0), gcnt0_restore);
 | |
| -+	cpr3_write(ctrl, CPR3_REG_GCNT(1), gcnt1_restore);
 | |
| -+
 | |
| -+	if (ctrl->supports_hw_closed_loop
 | |
| -+		&& ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+		cpr3_write(ctrl, CPR3_REG_CPR_TIMER_MID_CONT, cont_dly_restore);
 | |
| -+		cpr3_write(ctrl, CPR3_REG_CPR_TIMER_UP_DN_CONT,
 | |
| -+				up_down_dly_restore);
 | |
| -+	} else {
 | |
| -+		cpr3_write(ctrl, CPR3_REG_CPR_TIMER_AUTO_CONT,
 | |
| -+				cont_dly_restore);
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i <= ctrl->sensor_count / 32; i++) {
 | |
| -+		cpr3_write(ctrl, CPR3_REG_SENSOR_MASK_WRITE_BANK(i), 0);
 | |
| -+		cpr3_write(ctrl, CPR3_REG_SENSOR_BYPASS_WRITE_BANK(i), 0);
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_masked_write(ctrl, CPR3_REG_CPR_CTL,
 | |
| -+		CPR3_CPR_CTL_COUNT_MODE_MASK | CPR3_CPR_CTL_COUNT_REPEAT_MASK,
 | |
| -+		(ctrl->count_mode << CPR3_CPR_CTL_COUNT_MODE_SHIFT)
 | |
| -+		| (ctrl->count_repeat << CPR3_CPR_CTL_COUNT_REPEAT_SHIFT));
 | |
| -+
 | |
| -+	cpr3_write(ctrl, CPR3_REG_SENSOR_OWNER(aging_sensor->sensor_id),
 | |
| -+			ctrl->sensor_owner[aging_sensor->sensor_id]);
 | |
| -+
 | |
| -+	cpr3_write(ctrl, CPR3_REG_IRQ_CLEAR,
 | |
| -+			CPR3_IRQ_UP | CPR3_IRQ_DOWN | CPR3_IRQ_MID);
 | |
| -+
 | |
| -+	if (ctrl->supports_hw_closed_loop) {
 | |
| -+		if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+			cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+				CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_EN_MASK,
 | |
| -+				ctrl->use_hw_closed_loop
 | |
| -+				? CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_ENABLE
 | |
| -+				: CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_DISABLE);
 | |
| -+		} else if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+			cpr3_write(ctrl, CPR3_REG_HW_CLOSED_LOOP,
 | |
| -+				ctrl->use_hw_closed_loop
 | |
| -+				? CPR3_HW_CLOSED_LOOP_ENABLE
 | |
| -+				: CPR3_HW_CLOSED_LOOP_DISABLE);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_readjust_volt_and_quot() - readjust the target quotients as
 | |
| -+ *		well as the floor, ceiling, and open-loop voltages for the
 | |
| -+ *		regulator by removing the old adjustment and adding the new one
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @old_adjust_volt:	Old aging adjustment voltage in microvolts
 | |
| -+ * @new_adjust_volt:	New aging adjustment voltage in microvolts
 | |
| -+ *
 | |
| -+ * Also reset the cached closed loop voltage (last_volt) to equal the open-loop
 | |
| -+ * voltage for each corner.
 | |
| -+ *
 | |
| -+ * Return: None
 | |
| -+ */
 | |
| -+static void cpr3_regulator_readjust_volt_and_quot(struct cpr3_regulator *vreg,
 | |
| -+		int old_adjust_volt, int new_adjust_volt)
 | |
| -+{
 | |
| -+	unsigned long long temp;
 | |
| -+	int i, j, old_volt, new_volt, rounded_volt;
 | |
| -+
 | |
| -+	if (!vreg->aging_allowed)
 | |
| -+		return;
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		temp = (unsigned long long)old_adjust_volt
 | |
| -+			* (unsigned long long)vreg->corner[i].aging_derate;
 | |
| -+		do_div(temp, 1000);
 | |
| -+		old_volt = temp;
 | |
| -+
 | |
| -+		temp = (unsigned long long)new_adjust_volt
 | |
| -+			* (unsigned long long)vreg->corner[i].aging_derate;
 | |
| -+		do_div(temp, 1000);
 | |
| -+		new_volt = temp;
 | |
| -+
 | |
| -+		old_volt = min(vreg->aging_max_adjust_volt, old_volt);
 | |
| -+		new_volt = min(vreg->aging_max_adjust_volt, new_volt);
 | |
| -+
 | |
| -+		for (j = 0; j < CPR3_RO_COUNT; j++) {
 | |
| -+			if (vreg->corner[i].target_quot[j] != 0) {
 | |
| -+				vreg->corner[i].target_quot[j]
 | |
| -+					+= cpr3_quot_adjustment(
 | |
| -+						vreg->corner[i].ro_scale[j],
 | |
| -+						new_volt)
 | |
| -+					   - cpr3_quot_adjustment(
 | |
| -+						vreg->corner[i].ro_scale[j],
 | |
| -+						old_volt);
 | |
| -+			}
 | |
| -+		}
 | |
| -+
 | |
| -+		rounded_volt = CPR3_ROUND(new_volt,
 | |
| -+					vreg->thread->ctrl->step_volt);
 | |
| -+
 | |
| -+		if (!vreg->aging_allow_open_loop_adj)
 | |
| -+			rounded_volt = 0;
 | |
| -+
 | |
| -+		vreg->corner[i].ceiling_volt
 | |
| -+			= vreg->corner[i].unaged_ceiling_volt + rounded_volt;
 | |
| -+		vreg->corner[i].ceiling_volt = min(vreg->corner[i].ceiling_volt,
 | |
| -+					      vreg->corner[i].abs_ceiling_volt);
 | |
| -+		vreg->corner[i].floor_volt
 | |
| -+			= vreg->corner[i].unaged_floor_volt + rounded_volt;
 | |
| -+		vreg->corner[i].floor_volt = min(vreg->corner[i].floor_volt,
 | |
| -+						vreg->corner[i].ceiling_volt);
 | |
| -+		vreg->corner[i].open_loop_volt
 | |
| -+			= vreg->corner[i].unaged_open_loop_volt + rounded_volt;
 | |
| -+		vreg->corner[i].open_loop_volt
 | |
| -+			= min(vreg->corner[i].open_loop_volt,
 | |
| -+				vreg->corner[i].ceiling_volt);
 | |
| -+
 | |
| -+		vreg->corner[i].last_volt = vreg->corner[i].open_loop_volt;
 | |
| -+
 | |
| -+		cpr3_debug(vreg, "corner %d: applying %d uV closed-loop and %d uV open-loop voltage margin adjustment\n",
 | |
| -+			i, new_volt, rounded_volt);
 | |
| -+	}
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_set_aging_ref_adjustment() - adjust target quotients for the
 | |
| -+ *		regulators managed by this CPR controller to account for aging
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @ref_adjust_volt:	New aging reference adjustment voltage in microvolts to
 | |
| -+ *			apply to all regulators managed by this CPR controller
 | |
| -+ *
 | |
| -+ * The existing aging adjustment as defined by ctrl->aging_ref_adjust_volt is
 | |
| -+ * first removed and then the adjustment is applied.  Lastly, the value of
 | |
| -+ * ctrl->aging_ref_adjust_volt is updated to ref_adjust_volt.
 | |
| -+ */
 | |
| -+static void cpr3_regulator_set_aging_ref_adjustment(
 | |
| -+		struct cpr3_controller *ctrl, int ref_adjust_volt)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+	int i, j;
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+			vreg = &ctrl->thread[i].vreg[j];
 | |
| -+			cpr3_regulator_readjust_volt_and_quot(vreg,
 | |
| -+				ctrl->aging_ref_adjust_volt, ref_adjust_volt);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->aging_ref_adjust_volt = ref_adjust_volt;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_aging_adjust() - adjust the target quotients for regulators
 | |
| -+ *		based on the output of CPR aging sensors
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_aging_adjust(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+	struct cpr3_corner restore_aging_corner;
 | |
| -+	struct cpr3_corner *corner;
 | |
| -+	int *restore_current_corner;
 | |
| -+	bool *restore_vreg_enabled;
 | |
| -+	int i, j, id, rc, rc2, vreg_count, aging_volt, max_aging_volt = 0;
 | |
| -+	u32 reg;
 | |
| -+
 | |
| -+	if (!ctrl->aging_required || !ctrl->cpr_enabled
 | |
| -+	    || ctrl->aggr_corner.ceiling_volt == 0
 | |
| -+	    || ctrl->aggr_corner.ceiling_volt > ctrl->aging_ref_volt)
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	for (i = 0, vreg_count = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+			vreg = &ctrl->thread[i].vreg[j];
 | |
| -+			vreg_count++;
 | |
| -+
 | |
| -+			if (vreg->aging_allowed && vreg->vreg_enabled
 | |
| -+			    && vreg->current_corner > vreg->aging_corner)
 | |
| -+				return 0;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Verify that none of the aging sensors are currently masked. */
 | |
| -+	for (i = 0; i < ctrl->aging_sensor_count; i++) {
 | |
| -+		id = ctrl->aging_sensor[i].sensor_id;
 | |
| -+		reg = cpr3_read(ctrl, CPR3_REG_SENSOR_MASK_READ(id));
 | |
| -+		if (reg & BIT(id % 32))
 | |
| -+			return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Verify that the aging possible register (if specified) has an
 | |
| -+	 * acceptable value.
 | |
| -+	 */
 | |
| -+	if (ctrl->aging_possible_reg) {
 | |
| -+		reg = readl_relaxed(ctrl->aging_possible_reg);
 | |
| -+		reg &= ctrl->aging_possible_mask;
 | |
| -+		if (reg != ctrl->aging_possible_val)
 | |
| -+			return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	restore_current_corner = kcalloc(vreg_count,
 | |
| -+				sizeof(*restore_current_corner), GFP_KERNEL);
 | |
| -+	restore_vreg_enabled = kcalloc(vreg_count,
 | |
| -+				sizeof(*restore_vreg_enabled), GFP_KERNEL);
 | |
| -+	if (!restore_current_corner || !restore_vreg_enabled) {
 | |
| -+		kfree(restore_current_corner);
 | |
| -+		kfree(restore_vreg_enabled);
 | |
| -+		return -ENOMEM;
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Force all regulators to the aging corner */
 | |
| -+	for (i = 0, vreg_count = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++, vreg_count++) {
 | |
| -+			vreg = &ctrl->thread[i].vreg[j];
 | |
| -+
 | |
| -+			restore_current_corner[vreg_count]
 | |
| -+				= vreg->current_corner;
 | |
| -+			restore_vreg_enabled[vreg_count]
 | |
| -+				= vreg->vreg_enabled;
 | |
| -+
 | |
| -+			vreg->current_corner = vreg->aging_corner;
 | |
| -+			vreg->vreg_enabled = true;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Force one of the regulators to require the aging reference voltage */
 | |
| -+	vreg = &ctrl->thread[0].vreg[0];
 | |
| -+	corner = &vreg->corner[vreg->current_corner];
 | |
| -+	restore_aging_corner = *corner;
 | |
| -+	corner->ceiling_volt = ctrl->aging_ref_volt;
 | |
| -+	corner->floor_volt = ctrl->aging_ref_volt;
 | |
| -+	corner->open_loop_volt = ctrl->aging_ref_volt;
 | |
| -+	corner->last_volt = ctrl->aging_ref_volt;
 | |
| -+
 | |
| -+	/* Skip last_volt caching */
 | |
| -+	ctrl->last_corner_was_closed_loop = false;
 | |
| -+
 | |
| -+	/* Set the vdd supply voltage to the aging reference voltage */
 | |
| -+	rc = _cpr3_regulator_update_ctrl_state(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "unable to force vdd-supply to the aging reference voltage=%d uV, rc=%d\n",
 | |
| -+			ctrl->aging_ref_volt, rc);
 | |
| -+		goto cleanup;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->aging_vdd_mode) {
 | |
| -+		rc = regulator_set_mode(ctrl->vdd_regulator,
 | |
| -+					ctrl->aging_vdd_mode);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "unable to configure vdd-supply for mode=%u, rc=%d\n",
 | |
| -+				ctrl->aging_vdd_mode, rc);
 | |
| -+			goto cleanup;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Perform aging measurement on all aging sensors */
 | |
| -+	for (i = 0; i < ctrl->aging_sensor_count; i++) {
 | |
| -+		for (j = 0; j < CPR3_AGING_RETRY_COUNT; j++) {
 | |
| -+			rc = cpr3_regulator_measure_aging(ctrl,
 | |
| -+					&ctrl->aging_sensor[i]);
 | |
| -+			if (!rc)
 | |
| -+				break;
 | |
| -+		}
 | |
| -+
 | |
| -+		if (!rc) {
 | |
| -+			aging_volt =
 | |
| -+				cpr3_voltage_adjustment(
 | |
| -+					ctrl->aging_sensor[i].ro_scale,
 | |
| -+					ctrl->aging_sensor[i].measured_quot_diff
 | |
| -+					- ctrl->aging_sensor[i].init_quot_diff);
 | |
| -+			max_aging_volt = max(max_aging_volt, aging_volt);
 | |
| -+		} else {
 | |
| -+			cpr3_err(ctrl, "CPR aging measurement failed after %d tries, rc=%d\n",
 | |
| -+				j, rc);
 | |
| -+			ctrl->aging_failed = true;
 | |
| -+			ctrl->aging_required = false;
 | |
| -+			goto cleanup;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+cleanup:
 | |
| -+	vreg = &ctrl->thread[0].vreg[0];
 | |
| -+	vreg->corner[vreg->current_corner] = restore_aging_corner;
 | |
| -+
 | |
| -+	for (i = 0, vreg_count = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++, vreg_count++) {
 | |
| -+			vreg = &ctrl->thread[i].vreg[j];
 | |
| -+			vreg->current_corner
 | |
| -+				= restore_current_corner[vreg_count];
 | |
| -+			vreg->vreg_enabled = restore_vreg_enabled[vreg_count];
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	kfree(restore_current_corner);
 | |
| -+	kfree(restore_vreg_enabled);
 | |
| -+
 | |
| -+	/* Adjust the CPR target quotients according to the aging measurement */
 | |
| -+	if (!rc) {
 | |
| -+		cpr3_regulator_set_aging_ref_adjustment(ctrl, max_aging_volt);
 | |
| -+
 | |
| -+		cpr3_info(ctrl, "aging measurement successful; aging reference adjustment voltage=%d uV\n",
 | |
| -+			ctrl->aging_ref_adjust_volt);
 | |
| -+		ctrl->aging_succeeded = true;
 | |
| -+		ctrl->aging_required = false;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->aging_complete_vdd_mode) {
 | |
| -+		rc = regulator_set_mode(ctrl->vdd_regulator,
 | |
| -+					ctrl->aging_complete_vdd_mode);
 | |
| -+		if (rc)
 | |
| -+			cpr3_err(ctrl, "unable to configure vdd-supply for mode=%u, rc=%d\n",
 | |
| -+				ctrl->aging_complete_vdd_mode, rc);
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Skip last_volt caching */
 | |
| -+	ctrl->last_corner_was_closed_loop = false;
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Restore vdd-supply to the voltage before the aging measurement and
 | |
| -+	 * restore the CPR3 controller hardware state.
 | |
| -+	 */
 | |
| -+	rc2 = _cpr3_regulator_update_ctrl_state(ctrl);
 | |
| -+
 | |
| -+	/* Stop last_volt caching on for the next request */
 | |
| -+	ctrl->last_corner_was_closed_loop = false;
 | |
| -+
 | |
| -+	return rc ? rc : rc2;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_update_ctrl_state() - update the state of the CPR controller
 | |
| -+ *		to reflect the corners used by all CPR3 regulators as well as
 | |
| -+ *		the CPR operating mode and perform aging adjustments if needed
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Note, CPR3 controller lock must be held by the caller.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_update_ctrl_state(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = _cpr3_regulator_update_ctrl_state(ctrl);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	return cpr3_regulator_aging_adjust(ctrl);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_set_voltage() - set the voltage corner for the CPR3 regulator
 | |
| -+ *			associated with the regulator device
 | |
| -+ * @rdev:		Regulator device pointer for the cpr3-regulator
 | |
| -+ * @corner:		New voltage corner to set (offset by CPR3_CORNER_OFFSET)
 | |
| -+ * @corner_max:		Maximum voltage corner allowed (offset by
 | |
| -+ *			CPR3_CORNER_OFFSET)
 | |
| -+ * @selector:		Pointer which is filled with the selector value for the
 | |
| -+ *			corner
 | |
| -+ *
 | |
| -+ * This function is passed as a callback function into the regulator ops that
 | |
| -+ * are registered for each cpr3-regulator device.  The VDD voltage will not be
 | |
| -+ * physically configured until both this function and cpr3_regulator_enable()
 | |
| -+ * are called.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_set_voltage(struct regulator_dev *rdev,
 | |
| -+		int corner, int corner_max, unsigned *selector)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg = rdev_get_drvdata(rdev);
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	int rc = 0;
 | |
| -+	int last_corner;
 | |
| -+
 | |
| -+	corner -= CPR3_CORNER_OFFSET;
 | |
| -+	corner_max -= CPR3_CORNER_OFFSET;
 | |
| -+	*selector = corner;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+
 | |
| -+	if (!vreg->vreg_enabled) {
 | |
| -+		vreg->current_corner = corner;
 | |
| -+		cpr3_debug(vreg, "stored corner=%d\n", corner);
 | |
| -+		goto done;
 | |
| -+	} else if (vreg->current_corner == corner) {
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	last_corner = vreg->current_corner;
 | |
| -+	vreg->current_corner = corner;
 | |
| -+
 | |
| -+	if (vreg->cpr4_regulator_data != NULL)
 | |
| -+		if (vreg->cpr4_regulator_data->mem_acc_funcs != NULL)
 | |
| -+			vreg->cpr4_regulator_data->mem_acc_funcs->set_mem_acc(rdev);
 | |
| -+
 | |
| -+	rc = cpr3_regulator_update_ctrl_state(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "could not update CPR state, rc=%d\n", rc);
 | |
| -+		vreg->current_corner = last_corner;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (vreg->cpr4_regulator_data != NULL)
 | |
| -+		if (vreg->cpr4_regulator_data->mem_acc_funcs != NULL)
 | |
| -+			vreg->cpr4_regulator_data->mem_acc_funcs->clear_mem_acc(rdev);
 | |
| -+
 | |
| -+	cpr3_debug(vreg, "set corner=%d\n", corner);
 | |
| -+done:
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_handle_temp_open_loop_adjustment() - voltage based cold temperature
 | |
| -+ *
 | |
| -+ * @rdev:		Regulator device pointer for the cpr3-regulator
 | |
| -+ * @is_cold:		Flag to denote enter/exit cold condition
 | |
| -+ *
 | |
| -+ * This function is adjusts voltage margin based on cold condition
 | |
| -+ *
 | |
| -+ * Return: 0 = success
 | |
| -+ */
 | |
| -+
 | |
| -+int cpr3_handle_temp_open_loop_adjustment(struct cpr3_controller *ctrl,
 | |
| -+								bool is_cold)
 | |
| -+{
 | |
| -+	int i ,j, k, rc;
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+			vreg = &ctrl->thread[i].vreg[j];
 | |
| -+			for (k = 0; k < vreg->corner_count; k++) {
 | |
| -+				vreg->corner[k].open_loop_volt = is_cold ?
 | |
| -+				    vreg->corner[k].cold_temp_open_loop_volt :
 | |
| -+				    vreg->corner[k].normal_temp_open_loop_volt;
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+	rc = cpr3_regulator_update_ctrl_state(ctrl);
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_get_voltage() - get the voltage corner for the CPR3 regulator
 | |
| -+ *			associated with the regulator device
 | |
| -+ * @rdev:		Regulator device pointer for the cpr3-regulator
 | |
| -+ *
 | |
| -+ * This function is passed as a callback function into the regulator ops that
 | |
| -+ * are registered for each cpr3-regulator device.
 | |
| -+ *
 | |
| -+ * Return: voltage corner value offset by CPR3_CORNER_OFFSET
 | |
| -+ */
 | |
| -+static int cpr3_regulator_get_voltage(struct regulator_dev *rdev)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg = rdev_get_drvdata(rdev);
 | |
| -+
 | |
| -+	if (vreg->current_corner == CPR3_REGULATOR_CORNER_INVALID)
 | |
| -+		return CPR3_CORNER_OFFSET;
 | |
| -+	else
 | |
| -+		return vreg->current_corner + CPR3_CORNER_OFFSET;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_list_voltage() - return the voltage corner mapped to the
 | |
| -+ *			specified selector
 | |
| -+ * @rdev:		Regulator device pointer for the cpr3-regulator
 | |
| -+ * @selector:		Regulator selector
 | |
| -+ *
 | |
| -+ * This function is passed as a callback function into the regulator ops that
 | |
| -+ * are registered for each cpr3-regulator device.
 | |
| -+ *
 | |
| -+ * Return: voltage corner value offset by CPR3_CORNER_OFFSET
 | |
| -+ */
 | |
| -+static int cpr3_regulator_list_voltage(struct regulator_dev *rdev,
 | |
| -+		unsigned selector)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg = rdev_get_drvdata(rdev);
 | |
| -+
 | |
| -+	if (selector < vreg->corner_count)
 | |
| -+		return selector + CPR3_CORNER_OFFSET;
 | |
| -+	else
 | |
| -+		return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_is_enabled() - return the enable state of the CPR3 regulator
 | |
| -+ * @rdev:		Regulator device pointer for the cpr3-regulator
 | |
| -+ *
 | |
| -+ * This function is passed as a callback function into the regulator ops that
 | |
| -+ * are registered for each cpr3-regulator device.
 | |
| -+ *
 | |
| -+ * Return: true if regulator is enabled, false if regulator is disabled
 | |
| -+ */
 | |
| -+static int cpr3_regulator_is_enabled(struct regulator_dev *rdev)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg = rdev_get_drvdata(rdev);
 | |
| -+
 | |
| -+	return vreg->vreg_enabled;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_enable() - enable the CPR3 regulator
 | |
| -+ * @rdev:		Regulator device pointer for the cpr3-regulator
 | |
| -+ *
 | |
| -+ * This function is passed as a callback function into the regulator ops that
 | |
| -+ * are registered for each cpr3-regulator device.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_enable(struct regulator_dev *rdev)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg = rdev_get_drvdata(rdev);
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	int rc = 0;
 | |
| -+
 | |
| -+	if (vreg->vreg_enabled == true)
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+
 | |
| -+	if (ctrl->system_regulator) {
 | |
| -+		rc = regulator_enable(ctrl->system_regulator);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "regulator_enable(system) failed, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = regulator_enable(ctrl->vdd_regulator);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "regulator_enable(vdd) failed, rc=%d\n", rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->vreg_enabled = true;
 | |
| -+	rc = cpr3_regulator_update_ctrl_state(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "could not update CPR state, rc=%d\n", rc);
 | |
| -+		regulator_disable(ctrl->vdd_regulator);
 | |
| -+		vreg->vreg_enabled = false;
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_debug(vreg, "Enabled\n");
 | |
| -+done:
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_disable() - disable the CPR3 regulator
 | |
| -+ * @rdev:		Regulator device pointer for the cpr3-regulator
 | |
| -+ *
 | |
| -+ * This function is passed as a callback function into the regulator ops that
 | |
| -+ * are registered for each cpr3-regulator device.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_disable(struct regulator_dev *rdev)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg = rdev_get_drvdata(rdev);
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	int rc, rc2;
 | |
| -+
 | |
| -+	if (vreg->vreg_enabled == false)
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+	rc = regulator_disable(ctrl->vdd_regulator);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "regulator_disable(vdd) failed, rc=%d\n", rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->vreg_enabled = false;
 | |
| -+	rc = cpr3_regulator_update_ctrl_state(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "could not update CPR state, rc=%d\n", rc);
 | |
| -+		rc2 = regulator_enable(ctrl->vdd_regulator);
 | |
| -+		vreg->vreg_enabled = true;
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->system_regulator) {
 | |
| -+		rc = regulator_disable(ctrl->system_regulator);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "regulator_disable(system) failed, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_debug(vreg, "Disabled\n");
 | |
| -+done:
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+static struct regulator_ops cpr3_regulator_ops = {
 | |
| -+	.enable			= cpr3_regulator_enable,
 | |
| -+	.disable		= cpr3_regulator_disable,
 | |
| -+	.is_enabled		= cpr3_regulator_is_enabled,
 | |
| -+	.set_voltage		= cpr3_regulator_set_voltage,
 | |
| -+	.get_voltage		= cpr3_regulator_get_voltage,
 | |
| -+	.list_voltage		= cpr3_regulator_list_voltage,
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_print_result() - print CPR measurement results to the kernel log for
 | |
| -+ *		debugging purposes
 | |
| -+ * @thread:		Pointer to the CPR3 thread
 | |
| -+ *
 | |
| -+ * Return: None
 | |
| -+ */
 | |
| -+static void cpr3_print_result(struct cpr3_thread *thread)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = thread->ctrl;
 | |
| -+	u32 result[3], busy, step_dn, step_up, error_steps, error, negative;
 | |
| -+	u32 quot_min, quot_max, ro_min, ro_max, step_quot_min, step_quot_max;
 | |
| -+	u32 sensor_min, sensor_max;
 | |
| -+	char *sign;
 | |
| -+
 | |
| -+	result[0] = cpr3_read(ctrl, CPR3_REG_RESULT0(thread->thread_id));
 | |
| -+	result[1] = cpr3_read(ctrl, CPR3_REG_RESULT1(thread->thread_id));
 | |
| -+	result[2] = cpr3_read(ctrl, CPR3_REG_RESULT2(thread->thread_id));
 | |
| -+
 | |
| -+	busy = !!(result[0] & CPR3_RESULT0_BUSY_MASK);
 | |
| -+	step_dn = !!(result[0] & CPR3_RESULT0_STEP_DN_MASK);
 | |
| -+	step_up = !!(result[0] & CPR3_RESULT0_STEP_UP_MASK);
 | |
| -+	error_steps = (result[0] & CPR3_RESULT0_ERROR_STEPS_MASK)
 | |
| -+			>> CPR3_RESULT0_ERROR_STEPS_SHIFT;
 | |
| -+	error = (result[0] & CPR3_RESULT0_ERROR_MASK)
 | |
| -+			>> CPR3_RESULT0_ERROR_SHIFT;
 | |
| -+	negative = !!(result[0] & CPR3_RESULT0_NEGATIVE_MASK);
 | |
| -+
 | |
| -+	quot_min = (result[1] & CPR3_RESULT1_QUOT_MIN_MASK)
 | |
| -+			>> CPR3_RESULT1_QUOT_MIN_SHIFT;
 | |
| -+	quot_max = (result[1] & CPR3_RESULT1_QUOT_MAX_MASK)
 | |
| -+			>> CPR3_RESULT1_QUOT_MAX_SHIFT;
 | |
| -+	ro_min = (result[1] & CPR3_RESULT1_RO_MIN_MASK)
 | |
| -+			>> CPR3_RESULT1_RO_MIN_SHIFT;
 | |
| -+	ro_max = (result[1] & CPR3_RESULT1_RO_MAX_MASK)
 | |
| -+			>> CPR3_RESULT1_RO_MAX_SHIFT;
 | |
| -+
 | |
| -+	step_quot_min = (result[2] & CPR3_RESULT2_STEP_QUOT_MIN_MASK)
 | |
| -+			>> CPR3_RESULT2_STEP_QUOT_MIN_SHIFT;
 | |
| -+	step_quot_max = (result[2] & CPR3_RESULT2_STEP_QUOT_MAX_MASK)
 | |
| -+			>> CPR3_RESULT2_STEP_QUOT_MAX_SHIFT;
 | |
| -+	sensor_min = (result[2] & CPR3_RESULT2_SENSOR_MIN_MASK)
 | |
| -+			>> CPR3_RESULT2_SENSOR_MIN_SHIFT;
 | |
| -+	sensor_max = (result[2] & CPR3_RESULT2_SENSOR_MAX_MASK)
 | |
| -+			>> CPR3_RESULT2_SENSOR_MAX_SHIFT;
 | |
| -+
 | |
| -+	sign = negative ? "-" : "";
 | |
| -+	cpr3_debug(ctrl, "thread %u: busy=%u, step_dn=%u, step_up=%u, error_steps=%s%u, error=%s%u\n",
 | |
| -+		thread->thread_id, busy, step_dn, step_up, sign, error_steps,
 | |
| -+		sign, error);
 | |
| -+	cpr3_debug(ctrl, "thread %u: quot_min=%u, quot_max=%u, ro_min=%u, ro_max=%u\n",
 | |
| -+		thread->thread_id, quot_min, quot_max, ro_min, ro_max);
 | |
| -+	cpr3_debug(ctrl, "thread %u: step_quot_min=%u, step_quot_max=%u, sensor_min=%u, sensor_max=%u\n",
 | |
| -+		thread->thread_id, step_quot_min, step_quot_max, sensor_min,
 | |
| -+		sensor_max);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_thread_busy() - returns if the specified CPR3 thread is busy taking
 | |
| -+ *		a measurement
 | |
| -+ * @thread:		Pointer to the CPR3 thread
 | |
| -+ *
 | |
| -+ * Return: CPR3 busy status
 | |
| -+ */
 | |
| -+static bool cpr3_thread_busy(struct cpr3_thread *thread)
 | |
| -+{
 | |
| -+	u32 result;
 | |
| -+
 | |
| -+	result = cpr3_read(thread->ctrl, CPR3_REG_RESULT0(thread->thread_id));
 | |
| -+
 | |
| -+	return !!(result & CPR3_RESULT0_BUSY_MASK);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_irq_handler() - CPR interrupt handler callback function used for
 | |
| -+ *		software closed-loop operation
 | |
| -+ * @irq:		CPR interrupt number
 | |
| -+ * @data:		Private data corresponding to the CPR3 controller
 | |
| -+ *			pointer
 | |
| -+ *
 | |
| -+ * This function increases or decreases the vdd supply voltage based upon the
 | |
| -+ * CPR controller recommendation.
 | |
| -+ *
 | |
| -+ * Return: IRQ_HANDLED
 | |
| -+ */
 | |
| -+static irqreturn_t cpr3_irq_handler(int irq, void *data)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = data;
 | |
| -+	struct cpr3_corner *aggr = &ctrl->aggr_corner;
 | |
| -+	u32 cont = CPR3_CONT_CMD_NACK;
 | |
| -+	u32 reg_last_measurement = 0;
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+	struct cpr3_corner *corner;
 | |
| -+	unsigned long flags;
 | |
| -+	int i, j, new_volt, last_volt, dynamic_floor_volt, rc;
 | |
| -+	u32 irq_en, status, cpr_status, ctl;
 | |
| -+	bool up, down;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+
 | |
| -+	if (!ctrl->cpr_enabled) {
 | |
| -+		cpr3_debug(ctrl, "CPR interrupt received but CPR is disabled\n");
 | |
| -+		mutex_unlock(&ctrl->lock);
 | |
| -+		return IRQ_HANDLED;
 | |
| -+	} else if (ctrl->use_hw_closed_loop) {
 | |
| -+		cpr3_debug(ctrl, "CPR interrupt received but CPR is using HW closed-loop\n");
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * CPR IRQ status checking and CPR controller disabling must happen
 | |
| -+	 * atomically and without invening delay in order to avoid an interrupt
 | |
| -+	 * storm caused by the handler racing with the CPR controller.
 | |
| -+	 */
 | |
| -+	local_irq_save(flags);
 | |
| -+	preempt_disable();
 | |
| -+
 | |
| -+	status = cpr3_read(ctrl, CPR3_REG_IRQ_STATUS);
 | |
| -+	up = status & CPR3_IRQ_UP;
 | |
| -+	down = status & CPR3_IRQ_DOWN;
 | |
| -+
 | |
| -+	if (!up && !down) {
 | |
| -+		/*
 | |
| -+		 * Toggle the CPR controller off and then back on since the
 | |
| -+		 * hardware and software states are out of sync.  This condition
 | |
| -+		 * occurs after an aging measurement completes as the CPR IRQ
 | |
| -+		 * physically triggers during the aging measurement but the
 | |
| -+		 * handler is stuck waiting on the mutex lock.
 | |
| -+		 */
 | |
| -+		cpr3_ctrl_loop_disable(ctrl);
 | |
| -+
 | |
| -+		local_irq_restore(flags);
 | |
| -+		preempt_enable();
 | |
| -+
 | |
| -+		/* Wait for the loop disable write to complete */
 | |
| -+		mb();
 | |
| -+
 | |
| -+		/* Wait for BUSY=1 and LOOP_EN=0 in CPR controller registers. */
 | |
| -+		for (i = 0; i < CPR3_REGISTER_WRITE_DELAY_US / 10; i++) {
 | |
| -+			cpr_status = cpr3_read(ctrl, CPR3_REG_CPR_STATUS);
 | |
| -+			ctl = cpr3_read(ctrl, CPR3_REG_CPR_CTL);
 | |
| -+			if (cpr_status & CPR3_CPR_STATUS_BUSY_MASK
 | |
| -+			    && (ctl & CPR3_CPR_CTL_LOOP_EN_MASK)
 | |
| -+					== CPR3_CPR_CTL_LOOP_DISABLE)
 | |
| -+				break;
 | |
| -+			udelay(10);
 | |
| -+		}
 | |
| -+		if (i == CPR3_REGISTER_WRITE_DELAY_US / 10)
 | |
| -+			cpr3_debug(ctrl, "CPR controller not disabled after %d us\n",
 | |
| -+				CPR3_REGISTER_WRITE_DELAY_US);
 | |
| -+
 | |
| -+		/* Clear interrupt status */
 | |
| -+		cpr3_write(ctrl, CPR3_REG_IRQ_CLEAR,
 | |
| -+			CPR3_IRQ_UP | CPR3_IRQ_DOWN);
 | |
| -+
 | |
| -+		/* Wait for the interrupt clearing write to complete */
 | |
| -+		mb();
 | |
| -+
 | |
| -+		/* Wait for IRQ_STATUS register to be cleared. */
 | |
| -+		for (i = 0; i < CPR3_REGISTER_WRITE_DELAY_US / 10; i++) {
 | |
| -+			status = cpr3_read(ctrl, CPR3_REG_IRQ_STATUS);
 | |
| -+			if (!(status & (CPR3_IRQ_UP | CPR3_IRQ_DOWN)))
 | |
| -+				break;
 | |
| -+			udelay(10);
 | |
| -+		}
 | |
| -+		if (i == CPR3_REGISTER_WRITE_DELAY_US / 10)
 | |
| -+			cpr3_debug(ctrl, "CPR interrupts not cleared after %d us\n",
 | |
| -+				CPR3_REGISTER_WRITE_DELAY_US);
 | |
| -+
 | |
| -+		cpr3_ctrl_loop_enable(ctrl);
 | |
| -+
 | |
| -+		cpr3_debug(ctrl, "CPR interrupt received but no up or down status bit is set\n");
 | |
| -+
 | |
| -+		mutex_unlock(&ctrl->lock);
 | |
| -+		return IRQ_HANDLED;
 | |
| -+	} else if (up && down) {
 | |
| -+		cpr3_debug(ctrl, "both up and down status bits set\n");
 | |
| -+		/* The up flag takes precedence over the down flag. */
 | |
| -+		down = false;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->supports_hw_closed_loop)
 | |
| -+		reg_last_measurement
 | |
| -+			= cpr3_read(ctrl, CPR3_REG_LAST_MEASUREMENT);
 | |
| -+	dynamic_floor_volt = cpr3_regulator_get_dynamic_floor_volt(ctrl,
 | |
| -+							reg_last_measurement);
 | |
| -+
 | |
| -+	local_irq_restore(flags);
 | |
| -+	preempt_enable();
 | |
| -+
 | |
| -+	irq_en = aggr->irq_en;
 | |
| -+	last_volt = aggr->last_volt;
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		if (cpr3_thread_busy(&ctrl->thread[i])) {
 | |
| -+			cpr3_debug(ctrl, "CPR thread %u busy when it should be waiting for SW cont\n",
 | |
| -+				ctrl->thread[i].thread_id);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	new_volt = up ? last_volt + ctrl->step_volt
 | |
| -+		      : last_volt - ctrl->step_volt;
 | |
| -+
 | |
| -+	/* Re-enable UP/DOWN interrupt when its opposite is received. */
 | |
| -+	irq_en |= up ? CPR3_IRQ_DOWN : CPR3_IRQ_UP;
 | |
| -+
 | |
| -+	if (new_volt > aggr->ceiling_volt) {
 | |
| -+		new_volt = aggr->ceiling_volt;
 | |
| -+		irq_en &= ~CPR3_IRQ_UP;
 | |
| -+		cpr3_debug(ctrl, "limiting to ceiling=%d uV\n",
 | |
| -+			aggr->ceiling_volt);
 | |
| -+	} else if (new_volt < aggr->floor_volt) {
 | |
| -+		new_volt = aggr->floor_volt;
 | |
| -+		irq_en &= ~CPR3_IRQ_DOWN;
 | |
| -+		cpr3_debug(ctrl, "limiting to floor=%d uV\n", aggr->floor_volt);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (down && new_volt < dynamic_floor_volt) {
 | |
| -+		/*
 | |
| -+		 * The vdd-supply voltage should not be decreased below the
 | |
| -+		 * dynamic floor voltage.  However, it is not necessary (and
 | |
| -+		 * counter productive) to force the voltage up to this level
 | |
| -+		 * if it happened to be below it since the closed-loop voltage
 | |
| -+		 * must have gotten there in a safe manner while the power
 | |
| -+		 * domains for the CPR3 regulator imposing the dynamic floor
 | |
| -+		 * were not bypassed.
 | |
| -+		 */
 | |
| -+		new_volt = last_volt;
 | |
| -+		irq_en &= ~CPR3_IRQ_DOWN;
 | |
| -+		cpr3_debug(ctrl, "limiting to dynamic floor=%d uV\n",
 | |
| -+			dynamic_floor_volt);
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++)
 | |
| -+		cpr3_print_result(&ctrl->thread[i]);
 | |
| -+
 | |
| -+	cpr3_debug(ctrl, "%s: new_volt=%d uV, last_volt=%d uV\n",
 | |
| -+		up ? "UP" : "DN", new_volt, last_volt);
 | |
| -+
 | |
| -+	if (ctrl->proc_clock_throttle && last_volt == aggr->ceiling_volt
 | |
| -+	    && new_volt < last_volt)
 | |
| -+		cpr3_write(ctrl, CPR3_REG_PD_THROTTLE,
 | |
| -+				ctrl->proc_clock_throttle);
 | |
| -+
 | |
| -+	if (new_volt != last_volt) {
 | |
| -+		rc = cpr3_regulator_scale_vdd_voltage(ctrl, new_volt,
 | |
| -+						      last_volt,
 | |
| -+						      aggr);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "scale_vdd() failed to set vdd=%d uV, rc=%d\n",
 | |
| -+				 new_volt, rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+		cont = CPR3_CONT_CMD_ACK;
 | |
| -+
 | |
| -+		/*
 | |
| -+		 * Update the closed-loop voltage for all regulators managed
 | |
| -+		 * by this CPR controller.
 | |
| -+		 */
 | |
| -+		for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+			for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+				vreg = &ctrl->thread[i].vreg[j];
 | |
| -+				cpr3_update_vreg_closed_loop_volt(vreg,
 | |
| -+					new_volt, reg_last_measurement);
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->proc_clock_throttle && new_volt == aggr->ceiling_volt)
 | |
| -+		cpr3_write(ctrl, CPR3_REG_PD_THROTTLE,
 | |
| -+				CPR3_PD_THROTTLE_DISABLE);
 | |
| -+
 | |
| -+	corner = &ctrl->thread[0].vreg[0].corner[
 | |
| -+			ctrl->thread[0].vreg[0].current_corner];
 | |
| -+
 | |
| -+	if (irq_en != aggr->irq_en) {
 | |
| -+		aggr->irq_en = irq_en;
 | |
| -+		cpr3_write(ctrl, CPR3_REG_IRQ_EN, irq_en);
 | |
| -+	}
 | |
| -+
 | |
| -+	aggr->last_volt = new_volt;
 | |
| -+
 | |
| -+done:
 | |
| -+	/* Clear interrupt status */
 | |
| -+	cpr3_write(ctrl, CPR3_REG_IRQ_CLEAR, CPR3_IRQ_UP | CPR3_IRQ_DOWN);
 | |
| -+
 | |
| -+	/* ACK or NACK the CPR controller */
 | |
| -+	cpr3_write(ctrl, CPR3_REG_CONT_CMD, cont);
 | |
| -+
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+	return IRQ_HANDLED;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_ceiling_irq_handler() - CPR ceiling reached interrupt handler callback
 | |
| -+ *		function used for hardware closed-loop operation
 | |
| -+ * @irq:		CPR ceiling interrupt number
 | |
| -+ * @data:		Private data corresponding to the CPR3 controller
 | |
| -+ *			pointer
 | |
| -+ *
 | |
| -+ * This function disables processor clock throttling and closed-loop operation
 | |
| -+ * when the ceiling voltage is reached.
 | |
| -+ *
 | |
| -+ * Return: IRQ_HANDLED
 | |
| -+ */
 | |
| -+static irqreturn_t cpr3_ceiling_irq_handler(int irq, void *data)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = data;
 | |
| -+	int volt;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+
 | |
| -+	if (!ctrl->cpr_enabled) {
 | |
| -+		cpr3_debug(ctrl, "CPR ceiling interrupt received but CPR is disabled\n");
 | |
| -+		goto done;
 | |
| -+	} else if (!ctrl->use_hw_closed_loop) {
 | |
| -+		cpr3_debug(ctrl, "CPR ceiling interrupt received but CPR is using SW closed-loop\n");
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	volt = regulator_get_voltage(ctrl->vdd_regulator);
 | |
| -+	if (volt < 0) {
 | |
| -+		cpr3_err(ctrl, "could not get vdd voltage, rc=%d\n", volt);
 | |
| -+		goto done;
 | |
| -+	} else if (volt != ctrl->aggr_corner.ceiling_volt) {
 | |
| -+		cpr3_debug(ctrl, "CPR ceiling interrupt received but vdd voltage: %d uV != ceiling voltage: %d uV\n",
 | |
| -+			volt, ctrl->aggr_corner.ceiling_volt);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+		/*
 | |
| -+		 * Since the ceiling voltage has been reached, disable processor
 | |
| -+		 * clock throttling as well as CPR closed-loop operation.
 | |
| -+		 */
 | |
| -+		cpr3_write(ctrl, CPR3_REG_PD_THROTTLE,
 | |
| -+				CPR3_PD_THROTTLE_DISABLE);
 | |
| -+		cpr3_ctrl_loop_disable(ctrl);
 | |
| -+		cpr3_debug(ctrl, "CPR closed-loop and throttling disabled\n");
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+	return IRQ_HANDLED;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_vreg_register() - register a regulator device for a CPR3
 | |
| -+ *		regulator
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * This function initializes all regulator framework related structures and then
 | |
| -+ * calls regulator_register() for the CPR3 regulator.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_vreg_register(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct regulator_config config = {};
 | |
| -+	struct regulator_desc *rdesc;
 | |
| -+	struct regulator_init_data *init_data;
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	init_data = of_get_regulator_init_data(vreg->thread->ctrl->dev,
 | |
| -+						vreg->of_node, &vreg->rdesc);
 | |
| -+	if (!init_data) {
 | |
| -+		cpr3_err(vreg, "regulator init data is missing\n");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	init_data->constraints.input_uV = init_data->constraints.max_uV;
 | |
| -+	rdesc			= &vreg->rdesc;
 | |
| -+	init_data->constraints.valid_ops_mask |=
 | |
| -+		REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS;
 | |
| -+	rdesc->ops = &cpr3_regulator_ops;
 | |
| -+
 | |
| -+	rdesc->n_voltages	= vreg->corner_count;
 | |
| -+	rdesc->name		= init_data->constraints.name;
 | |
| -+	rdesc->owner		= THIS_MODULE;
 | |
| -+	rdesc->type		= REGULATOR_VOLTAGE;
 | |
| -+
 | |
| -+	config.dev		= vreg->thread->ctrl->dev;
 | |
| -+	config.driver_data	= vreg;
 | |
| -+	config.init_data	= init_data;
 | |
| -+	config.of_node		= vreg->of_node;
 | |
| -+
 | |
| -+	vreg->rdev = regulator_register(rdesc, &config);
 | |
| -+	if (IS_ERR(vreg->rdev)) {
 | |
| -+		rc = PTR_ERR(vreg->rdev);
 | |
| -+		cpr3_err(vreg, "regulator_register failed, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static int debugfs_int_set(void *data, u64 val)
 | |
| -+{
 | |
| -+	*(int *)data = val;
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static int debugfs_int_get(void *data, u64 *val)
 | |
| -+{
 | |
| -+	*val = *(int *)data;
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+DEFINE_SIMPLE_ATTRIBUTE(fops_int, debugfs_int_get, debugfs_int_set, "%lld\n");
 | |
| -+DEFINE_SIMPLE_ATTRIBUTE(fops_int_ro, debugfs_int_get, NULL, "%lld\n");
 | |
| -+DEFINE_SIMPLE_ATTRIBUTE(fops_int_wo, NULL, debugfs_int_set, "%lld\n");
 | |
| -+
 | |
| -+/**
 | |
| -+ * debugfs_create_int - create a debugfs file that is used to read and write a
 | |
| -+ *		signed int value
 | |
| -+ * @name:		Pointer to a string containing the name of the file to
 | |
| -+ *			create
 | |
| -+ * @mode:		The permissions that the file should have
 | |
| -+ * @parent:		Pointer to the parent dentry for this file.  This should
 | |
| -+ *			be a directory dentry if set.  If this parameter is
 | |
| -+ *			%NULL, then the file will be created in the root of the
 | |
| -+ *			debugfs filesystem.
 | |
| -+ * @value:		Pointer to the variable that the file should read to and
 | |
| -+ *			write from
 | |
| -+ *
 | |
| -+ * This function creates a file in debugfs with the given name that
 | |
| -+ * contains the value of the variable @value.  If the @mode variable is so
 | |
| -+ * set, it can be read from, and written to.
 | |
| -+ *
 | |
| -+ * This function will return a pointer to a dentry if it succeeds.  This
 | |
| -+ * pointer must be passed to the debugfs_remove() function when the file is
 | |
| -+ * to be removed.  If an error occurs, %NULL will be returned.
 | |
| -+ */
 | |
| -+static struct dentry *debugfs_create_int(const char *name, umode_t mode,
 | |
| -+				struct dentry *parent, int *value)
 | |
| -+{
 | |
| -+	/* if there are no write bits set, make read only */
 | |
| -+	if (!(mode & S_IWUGO))
 | |
| -+		return debugfs_create_file(name, mode, parent, value,
 | |
| -+					   &fops_int_ro);
 | |
| -+	/* if there are no read bits set, make write only */
 | |
| -+	if (!(mode & S_IRUGO))
 | |
| -+		return debugfs_create_file(name, mode, parent, value,
 | |
| -+					   &fops_int_wo);
 | |
| -+
 | |
| -+	return debugfs_create_file(name, mode, parent, value, &fops_int);
 | |
| -+}
 | |
| -+
 | |
| -+static int debugfs_bool_get(void *data, u64 *val)
 | |
| -+{
 | |
| -+	*val = *(bool *)data;
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+DEFINE_SIMPLE_ATTRIBUTE(fops_bool_ro, debugfs_bool_get, NULL, "%lld\n");
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr3_debug_corner_info - data structure used by the
 | |
| -+ *		cpr3_debugfs_create_corner_int function
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @index:		Pointer to the corner array index
 | |
| -+ * @member_offset:	Offset in bytes from the beginning of struct cpr3_corner
 | |
| -+ *			to the beginning of the value to be read from
 | |
| -+ * @corner:		Pointer to the CPR3 corner array
 | |
| -+ */
 | |
| -+struct cpr3_debug_corner_info {
 | |
| -+	struct cpr3_regulator	*vreg;
 | |
| -+	int			*index;
 | |
| -+	size_t			member_offset;
 | |
| -+	struct cpr3_corner	*corner;
 | |
| -+};
 | |
| -+
 | |
| -+static int cpr3_debug_corner_int_get(void *data, u64 *val)
 | |
| -+{
 | |
| -+	struct cpr3_debug_corner_info *info = data;
 | |
| -+	struct cpr3_controller *ctrl = info->vreg->thread->ctrl;
 | |
| -+	int i;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+
 | |
| -+	i = *info->index;
 | |
| -+	if (i < 0)
 | |
| -+		i = 0;
 | |
| -+
 | |
| -+	*val = *(int *)((char *)&info->vreg->corner[i] + info->member_offset);
 | |
| -+
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+DEFINE_SIMPLE_ATTRIBUTE(cpr3_debug_corner_int_fops, cpr3_debug_corner_int_get,
 | |
| -+			NULL, "%lld\n");
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_debugfs_create_corner_int - create a debugfs file that is used to read
 | |
| -+ *		a signed int value out of a CPR3 regulator's corner array
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @name:		Pointer to a string containing the name of the file to
 | |
| -+ *			create
 | |
| -+ * @mode:		The permissions that the file should have
 | |
| -+ * @parent:		Pointer to the parent dentry for this file.  This should
 | |
| -+ *			be a directory dentry if set.  If this parameter is
 | |
| -+ *			%NULL, then the file will be created in the root of the
 | |
| -+ *			debugfs filesystem.
 | |
| -+ * @index:		Pointer to the corner array index
 | |
| -+ * @member_offset:	Offset in bytes from the beginning of struct cpr3_corner
 | |
| -+ *			to the beginning of the value to be read from
 | |
| -+ *
 | |
| -+ * This function creates a file in debugfs with the given name that
 | |
| -+ * contains the value of the int type variable vreg->corner[index].member
 | |
| -+ * where member_offset == offsetof(struct cpr3_corner, member).
 | |
| -+ */
 | |
| -+static struct dentry *cpr3_debugfs_create_corner_int(
 | |
| -+		struct cpr3_regulator *vreg, const char *name, umode_t mode,
 | |
| -+		struct dentry *parent, int *index, size_t member_offset)
 | |
| -+{
 | |
| -+	struct cpr3_debug_corner_info *info;
 | |
| -+
 | |
| -+	info = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*info), GFP_KERNEL);
 | |
| -+	if (!info)
 | |
| -+		return NULL;
 | |
| -+
 | |
| -+	info->vreg = vreg;
 | |
| -+	info->index = index;
 | |
| -+	info->member_offset = member_offset;
 | |
| -+
 | |
| -+	return debugfs_create_file(name, mode, parent, info,
 | |
| -+				   &cpr3_debug_corner_int_fops);
 | |
| -+}
 | |
| -+
 | |
| -+static int cpr3_debug_quot_open(struct inode *inode, struct file *file)
 | |
| -+{
 | |
| -+	struct cpr3_debug_corner_info *info = inode->i_private;
 | |
| -+	struct cpr3_thread *thread = info->vreg->thread;
 | |
| -+	int size, i, pos;
 | |
| -+	u32 *quot;
 | |
| -+	char *buf;
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Max size:
 | |
| -+	 *  - 10 digits + ' ' or '\n' = 11 bytes per number
 | |
| -+	 *  - terminating '\0'
 | |
| -+	 */
 | |
| -+	size = CPR3_RO_COUNT * 11;
 | |
| -+	buf = kzalloc(size + 1, GFP_KERNEL);
 | |
| -+	if (!buf)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	file->private_data = buf;
 | |
| -+
 | |
| -+	mutex_lock(&thread->ctrl->lock);
 | |
| -+
 | |
| -+	quot = info->corner[*info->index].target_quot;
 | |
| -+
 | |
| -+	for (i = 0, pos = 0; i < CPR3_RO_COUNT; i++)
 | |
| -+		pos += scnprintf(buf + pos, size - pos, "%u%c",
 | |
| -+			quot[i], i < CPR3_RO_COUNT - 1 ? ' ' : '\n');
 | |
| -+
 | |
| -+	mutex_unlock(&thread->ctrl->lock);
 | |
| -+
 | |
| -+	return nonseekable_open(inode, file);
 | |
| -+}
 | |
| -+
 | |
| -+static ssize_t cpr3_debug_quot_read(struct file *file, char __user *buf,
 | |
| -+		size_t len, loff_t *ppos)
 | |
| -+{
 | |
| -+	return simple_read_from_buffer(buf, len, ppos, file->private_data,
 | |
| -+					strlen(file->private_data));
 | |
| -+}
 | |
| -+
 | |
| -+static int cpr3_debug_quot_release(struct inode *inode, struct file *file)
 | |
| -+{
 | |
| -+	kfree(file->private_data);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static const struct file_operations cpr3_debug_quot_fops = {
 | |
| -+	.owner	 = THIS_MODULE,
 | |
| -+	.open	 = cpr3_debug_quot_open,
 | |
| -+	.release = cpr3_debug_quot_release,
 | |
| -+	.read	 = cpr3_debug_quot_read,
 | |
| -+	.llseek  = no_llseek,
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_debugfs_corner_add() - add debugfs files to expose
 | |
| -+ *		configuration data for the CPR corner
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @corner_dir:		Pointer to the parent corner dentry for the new files
 | |
| -+ * @index:		Pointer to the corner array index
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static void cpr3_regulator_debugfs_corner_add(struct cpr3_regulator *vreg,
 | |
| -+		struct dentry *corner_dir, int *index)
 | |
| -+{
 | |
| -+	struct cpr3_debug_corner_info *info;
 | |
| -+	struct dentry *temp;
 | |
| -+
 | |
| -+	temp = cpr3_debugfs_create_corner_int(vreg, "floor_volt", S_IRUGO,
 | |
| -+		corner_dir, index, offsetof(struct cpr3_corner, floor_volt));
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(vreg, "floor_volt debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = cpr3_debugfs_create_corner_int(vreg, "ceiling_volt", S_IRUGO,
 | |
| -+		corner_dir, index, offsetof(struct cpr3_corner, ceiling_volt));
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(vreg, "ceiling_volt debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = cpr3_debugfs_create_corner_int(vreg, "open_loop_volt", S_IRUGO,
 | |
| -+		corner_dir, index,
 | |
| -+		offsetof(struct cpr3_corner, open_loop_volt));
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(vreg, "open_loop_volt debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = cpr3_debugfs_create_corner_int(vreg, "last_volt", S_IRUGO,
 | |
| -+		corner_dir, index, offsetof(struct cpr3_corner, last_volt));
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(vreg, "last_volt debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	info = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*info), GFP_KERNEL);
 | |
| -+	if (!info)
 | |
| -+		return;
 | |
| -+
 | |
| -+	info->vreg = vreg;
 | |
| -+	info->index = index;
 | |
| -+	info->corner = vreg->corner;
 | |
| -+
 | |
| -+	temp = debugfs_create_file("target_quots", S_IRUGO, corner_dir,
 | |
| -+				info, &cpr3_debug_quot_fops);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(vreg, "target_quots debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_debug_corner_index_set() - debugfs callback used to change the
 | |
| -+ *		value of the CPR3 regulator debug_corner index
 | |
| -+ * @data:		Pointer to private data which is equal to the CPR3
 | |
| -+ *			regulator pointer
 | |
| -+ * @val:		New value for debug_corner
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_debug_corner_index_set(void *data, u64 val)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg = data;
 | |
| -+
 | |
| -+	if (val < CPR3_CORNER_OFFSET || val > vreg->corner_count) {
 | |
| -+		cpr3_err(vreg, "invalid corner index %llu; allowed values: %d-%d\n",
 | |
| -+			val, CPR3_CORNER_OFFSET, vreg->corner_count);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	mutex_lock(&vreg->thread->ctrl->lock);
 | |
| -+	vreg->debug_corner = val - CPR3_CORNER_OFFSET;
 | |
| -+	mutex_unlock(&vreg->thread->ctrl->lock);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_debug_corner_index_get() - debugfs callback used to retrieve
 | |
| -+ *		the value of the CPR3 regulator debug_corner index
 | |
| -+ * @data:		Pointer to private data which is equal to the CPR3
 | |
| -+ *			regulator pointer
 | |
| -+ * @val:		Output parameter written with the value of
 | |
| -+ *			debug_corner
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_debug_corner_index_get(void *data, u64 *val)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg = data;
 | |
| -+
 | |
| -+	*val = vreg->debug_corner + CPR3_CORNER_OFFSET;
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+DEFINE_SIMPLE_ATTRIBUTE(cpr3_debug_corner_index_fops,
 | |
| -+			cpr3_debug_corner_index_get,
 | |
| -+			cpr3_debug_corner_index_set,
 | |
| -+			"%llu\n");
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_debug_current_corner_index_get() - debugfs callback used to retrieve
 | |
| -+ *		the value of the CPR3 regulator current_corner index
 | |
| -+ * @data:		Pointer to private data which is equal to the CPR3
 | |
| -+ *			regulator pointer
 | |
| -+ * @val:		Output parameter written with the value of
 | |
| -+ *			current_corner
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_debug_current_corner_index_get(void *data, u64 *val)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg = data;
 | |
| -+
 | |
| -+	*val = vreg->current_corner + CPR3_CORNER_OFFSET;
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+DEFINE_SIMPLE_ATTRIBUTE(cpr3_debug_current_corner_index_fops,
 | |
| -+			cpr3_debug_current_corner_index_get,
 | |
| -+			NULL, "%llu\n");
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_debugfs_vreg_add() - add debugfs files to expose configuration
 | |
| -+ *		data for the CPR3 regulator
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @thread_dir		CPR3 thread debugfs directory handle
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static void cpr3_regulator_debugfs_vreg_add(struct cpr3_regulator *vreg,
 | |
| -+				struct dentry *thread_dir)
 | |
| -+{
 | |
| -+	struct dentry *temp, *corner_dir, *vreg_dir;
 | |
| -+
 | |
| -+	vreg_dir = debugfs_create_dir(vreg->name, thread_dir);
 | |
| -+	if (IS_ERR_OR_NULL(vreg_dir)) {
 | |
| -+		cpr3_err(vreg, "%s debugfs directory creation failed\n",
 | |
| -+			vreg->name);
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("speed_bin_fuse", S_IRUGO, vreg_dir,
 | |
| -+				  &vreg->speed_bin_fuse);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(vreg, "speed_bin_fuse debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("cpr_rev_fuse", S_IRUGO, vreg_dir,
 | |
| -+				  &vreg->cpr_rev_fuse);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(vreg, "cpr_rev_fuse debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("fuse_combo", S_IRUGO, vreg_dir,
 | |
| -+				  &vreg->fuse_combo);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(vreg, "fuse_combo debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("corner_count", S_IRUGO, vreg_dir,
 | |
| -+				  &vreg->corner_count);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(vreg, "corner_count debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	corner_dir = debugfs_create_dir("corner", vreg_dir);
 | |
| -+	if (IS_ERR_OR_NULL(corner_dir)) {
 | |
| -+		cpr3_err(vreg, "corner debugfs directory creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_file("index", S_IRUGO | S_IWUSR, corner_dir,
 | |
| -+				vreg, &cpr3_debug_corner_index_fops);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(vreg, "index debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_regulator_debugfs_corner_add(vreg, corner_dir,
 | |
| -+					&vreg->debug_corner);
 | |
| -+
 | |
| -+	corner_dir = debugfs_create_dir("current_corner", vreg_dir);
 | |
| -+	if (IS_ERR_OR_NULL(corner_dir)) {
 | |
| -+		cpr3_err(vreg, "current_corner debugfs directory creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_file("index", S_IRUGO, corner_dir,
 | |
| -+				vreg, &cpr3_debug_current_corner_index_fops);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(vreg, "index debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_regulator_debugfs_corner_add(vreg, corner_dir,
 | |
| -+					  &vreg->current_corner);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_debugfs_thread_add() - add debugfs files to expose
 | |
| -+ *		configuration data for the CPR thread
 | |
| -+ * @thread:		Pointer to the CPR3 thread
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static void cpr3_regulator_debugfs_thread_add(struct cpr3_thread *thread)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = thread->ctrl;
 | |
| -+	struct dentry *aggr_dir, *temp, *thread_dir;
 | |
| -+	struct cpr3_debug_corner_info *info;
 | |
| -+	char buf[20];
 | |
| -+	int *index;
 | |
| -+	int i;
 | |
| -+
 | |
| -+	scnprintf(buf, sizeof(buf), "thread%u", thread->thread_id);
 | |
| -+	thread_dir = debugfs_create_dir(buf, thread->ctrl->debugfs);
 | |
| -+	if (IS_ERR_OR_NULL(thread_dir)) {
 | |
| -+		cpr3_err(ctrl, "thread %u %s debugfs directory creation failed\n",
 | |
| -+			thread->thread_id, buf);
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	aggr_dir = debugfs_create_dir("max_aggregated_params", thread_dir);
 | |
| -+	if (IS_ERR_OR_NULL(aggr_dir)) {
 | |
| -+		cpr3_err(ctrl, "thread %u max_aggregated_params debugfs directory creation failed\n",
 | |
| -+			thread->thread_id);
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("floor_volt", S_IRUGO, aggr_dir,
 | |
| -+				  &thread->aggr_corner.floor_volt);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(ctrl, "thread %u aggr floor_volt debugfs file creation failed\n",
 | |
| -+			thread->thread_id);
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("ceiling_volt", S_IRUGO, aggr_dir,
 | |
| -+				  &thread->aggr_corner.ceiling_volt);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(ctrl, "thread %u aggr ceiling_volt debugfs file creation failed\n",
 | |
| -+			thread->thread_id);
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("open_loop_volt", S_IRUGO, aggr_dir,
 | |
| -+				  &thread->aggr_corner.open_loop_volt);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(ctrl, "thread %u aggr open_loop_volt debugfs file creation failed\n",
 | |
| -+			thread->thread_id);
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("last_volt", S_IRUGO, aggr_dir,
 | |
| -+				  &thread->aggr_corner.last_volt);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(ctrl, "thread %u aggr last_volt debugfs file creation failed\n",
 | |
| -+			thread->thread_id);
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	info = devm_kzalloc(thread->ctrl->dev, sizeof(*info), GFP_KERNEL);
 | |
| -+	index = devm_kzalloc(thread->ctrl->dev, sizeof(*index), GFP_KERNEL);
 | |
| -+	if (!info || !index)
 | |
| -+		return;
 | |
| -+	*index = 0;
 | |
| -+	info->vreg = &thread->vreg[0];
 | |
| -+	info->index = index;
 | |
| -+	info->corner = &thread->aggr_corner;
 | |
| -+
 | |
| -+	temp = debugfs_create_file("target_quots", S_IRUGO, aggr_dir,
 | |
| -+				info, &cpr3_debug_quot_fops);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(ctrl, "thread %u target_quots debugfs file creation failed\n",
 | |
| -+			thread->thread_id);
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < thread->vreg_count; i++)
 | |
| -+		cpr3_regulator_debugfs_vreg_add(&thread->vreg[i], thread_dir);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_debug_closed_loop_enable_set() - debugfs callback used to change the
 | |
| -+ *		value of the CPR controller cpr_allowed_sw flag which enables or
 | |
| -+ *		disables closed-loop operation
 | |
| -+ * @data:		Pointer to private data which is equal to the CPR
 | |
| -+ *			controller pointer
 | |
| -+ * @val:		New value for cpr_allowed_sw
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_debug_closed_loop_enable_set(void *data, u64 val)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = data;
 | |
| -+	bool enable = !!val;
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+
 | |
| -+	if (ctrl->cpr_allowed_sw == enable)
 | |
| -+		goto done;
 | |
| -+
 | |
| -+	if (enable && !ctrl->cpr_allowed_hw) {
 | |
| -+		cpr3_err(ctrl, "CPR closed-loop operation is not allowed\n");
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->cpr_allowed_sw = enable;
 | |
| -+
 | |
| -+	rc = cpr3_regulator_update_ctrl_state(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "could not change CPR enable state=%u, rc=%d\n",
 | |
| -+			 enable, rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->proc_clock_throttle && !ctrl->cpr_enabled) {
 | |
| -+		rc = cpr3_clock_enable(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "clock enable failed, rc=%d\n",
 | |
| -+				 rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+		ctrl->cpr_enabled = true;
 | |
| -+
 | |
| -+		cpr3_write(ctrl, CPR3_REG_PD_THROTTLE,
 | |
| -+			   CPR3_PD_THROTTLE_DISABLE);
 | |
| -+
 | |
| -+		cpr3_clock_disable(ctrl);
 | |
| -+		ctrl->cpr_enabled = false;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_debug(ctrl, "closed-loop=%s\n", enable ? "enabled" : "disabled");
 | |
| -+done:
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_debug_closed_loop_enable_get() - debugfs callback used to retrieve
 | |
| -+ *		the value of the CPR controller cpr_allowed_sw flag which
 | |
| -+ *		indicates if closed-loop operation is enabled
 | |
| -+ * @data:		Pointer to private data which is equal to the CPR
 | |
| -+ *			controller pointer
 | |
| -+ * @val:		Output parameter written with the value of
 | |
| -+ *			cpr_allowed_sw
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_debug_closed_loop_enable_get(void *data, u64 *val)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = data;
 | |
| -+
 | |
| -+	*val = ctrl->cpr_allowed_sw;
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+DEFINE_SIMPLE_ATTRIBUTE(cpr3_debug_closed_loop_enable_fops,
 | |
| -+			cpr3_debug_closed_loop_enable_get,
 | |
| -+			cpr3_debug_closed_loop_enable_set,
 | |
| -+			"%llu\n");
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_debug_hw_closed_loop_enable_set() - debugfs callback used to change the
 | |
| -+ *		value of the CPR controller use_hw_closed_loop flag which
 | |
| -+ *		switches between software closed-loop and hardware closed-loop
 | |
| -+ *		operation for CPR3 and CPR4 controllers and between open-loop
 | |
| -+ *		and full hardware closed-loop operation for CPRh controllers.
 | |
| -+ * @data:		Pointer to private data which is equal to the CPR
 | |
| -+ *			controller pointer
 | |
| -+ * @val:		New value for use_hw_closed_loop
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_debug_hw_closed_loop_enable_set(void *data, u64 val)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = data;
 | |
| -+	bool use_hw_closed_loop = !!val;
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+	bool cpr_enabled;
 | |
| -+	int i, j, k, rc;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+
 | |
| -+	if (ctrl->use_hw_closed_loop == use_hw_closed_loop)
 | |
| -+		goto done;
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+		rc = cpr3_ctrl_clear_cpr4_config(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "failed to clear CPR4 configuration,rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_ctrl_loop_disable(ctrl);
 | |
| -+
 | |
| -+	ctrl->use_hw_closed_loop = use_hw_closed_loop;
 | |
| -+
 | |
| -+	cpr_enabled = ctrl->cpr_enabled;
 | |
| -+
 | |
| -+	/* Ensure that CPR clocks are enabled before writing to registers. */
 | |
| -+	if (!cpr_enabled) {
 | |
| -+		rc = cpr3_clock_enable(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "clock enable failed, rc=%d\n", rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+		ctrl->cpr_enabled = true;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->use_hw_closed_loop)
 | |
| -+		cpr3_write(ctrl, CPR3_REG_IRQ_EN, 0);
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+		cpr3_masked_write(ctrl, CPR4_REG_MARGIN_ADJ_CTL,
 | |
| -+			CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_EN_MASK,
 | |
| -+			ctrl->use_hw_closed_loop
 | |
| -+			? CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_ENABLE
 | |
| -+			: CPR4_MARGIN_ADJ_CTL_HW_CLOSED_LOOP_DISABLE);
 | |
| -+	} else if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+		cpr3_write(ctrl, CPR3_REG_HW_CLOSED_LOOP,
 | |
| -+			ctrl->use_hw_closed_loop
 | |
| -+			? CPR3_HW_CLOSED_LOOP_ENABLE
 | |
| -+			: CPR3_HW_CLOSED_LOOP_DISABLE);
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Turn off CPR clocks if they were off before this function call. */
 | |
| -+	if (!cpr_enabled) {
 | |
| -+		cpr3_clock_disable(ctrl);
 | |
| -+		ctrl->cpr_enabled = false;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->use_hw_closed_loop && ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+		rc = regulator_enable(ctrl->vdd_limit_regulator);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "CPR limit regulator enable failed, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	} else if (!ctrl->use_hw_closed_loop
 | |
| -+			&& ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+		rc = regulator_disable(ctrl->vdd_limit_regulator);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "CPR limit regulator disable failed, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Due to APM and mem-acc floor restriction constraints,
 | |
| -+	 * the closed-loop voltage may be different when using
 | |
| -+	 * software closed-loop vs hardware closed-loop.  Therefore,
 | |
| -+	 * reset the cached closed-loop voltage for all corners to the
 | |
| -+	 * corresponding open-loop voltage when switching between
 | |
| -+	 * SW and HW closed-loop mode.
 | |
| -+	 */
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+			vreg = &ctrl->thread[i].vreg[j];
 | |
| -+			for (k = 0; k < vreg->corner_count; k++)
 | |
| -+				vreg->corner[k].last_volt
 | |
| -+				= vreg->corner[k].open_loop_volt;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Skip last_volt caching */
 | |
| -+	ctrl->last_corner_was_closed_loop = false;
 | |
| -+
 | |
| -+	rc = cpr3_regulator_update_ctrl_state(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "could not change CPR HW closed-loop enable state=%u, rc=%d\n",
 | |
| -+			 use_hw_closed_loop, rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_debug(ctrl, "CPR mode=%s\n",
 | |
| -+		   use_hw_closed_loop ?
 | |
| -+		   "HW closed-loop" : "SW closed-loop");
 | |
| -+done:
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_debug_hw_closed_loop_enable_get() - debugfs callback used to retrieve
 | |
| -+ *		the value of the CPR controller use_hw_closed_loop flag which
 | |
| -+ *		indicates if hardware closed-loop operation is being used in
 | |
| -+ *		place of software closed-loop operation
 | |
| -+ * @data:		Pointer to private data which is equal to the CPR
 | |
| -+ *			controller pointer
 | |
| -+ * @val:		Output parameter written with the value of
 | |
| -+ *			use_hw_closed_loop
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_debug_hw_closed_loop_enable_get(void *data, u64 *val)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = data;
 | |
| -+
 | |
| -+	*val = ctrl->use_hw_closed_loop;
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+DEFINE_SIMPLE_ATTRIBUTE(cpr3_debug_hw_closed_loop_enable_fops,
 | |
| -+			cpr3_debug_hw_closed_loop_enable_get,
 | |
| -+			cpr3_debug_hw_closed_loop_enable_set,
 | |
| -+			"%llu\n");
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_debug_trigger_aging_measurement_set() - debugfs callback used to trigger
 | |
| -+ *		another CPR measurement
 | |
| -+ * @data:		Pointer to private data which is equal to the CPR
 | |
| -+ *			controller pointer
 | |
| -+ * @val:		Unused
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_debug_trigger_aging_measurement_set(void *data, u64 val)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = data;
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+		rc = cpr3_ctrl_clear_cpr4_config(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "failed to clear CPR4 configuration,rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_ctrl_loop_disable(ctrl);
 | |
| -+
 | |
| -+	cpr3_regulator_set_aging_ref_adjustment(ctrl, INT_MAX);
 | |
| -+	ctrl->aging_required = true;
 | |
| -+	ctrl->aging_succeeded = false;
 | |
| -+	ctrl->aging_failed = false;
 | |
| -+
 | |
| -+	rc = cpr3_regulator_update_ctrl_state(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "could not update the CPR controller state, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+DEFINE_SIMPLE_ATTRIBUTE(cpr3_debug_trigger_aging_measurement_fops,
 | |
| -+			NULL,
 | |
| -+			cpr3_debug_trigger_aging_measurement_set,
 | |
| -+			"%llu\n");
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_debugfs_ctrl_add() - add debugfs files to expose configuration
 | |
| -+ *		data for the CPR controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static void cpr3_regulator_debugfs_ctrl_add(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct dentry *temp, *aggr_dir;
 | |
| -+	int i;
 | |
| -+
 | |
| -+	/* Add cpr3-regulator base directory if it isn't present already. */
 | |
| -+	if (cpr3_debugfs_base == NULL) {
 | |
| -+		cpr3_debugfs_base = debugfs_create_dir("cpr3-regulator", NULL);
 | |
| -+		if (IS_ERR_OR_NULL(cpr3_debugfs_base)) {
 | |
| -+			cpr3_err(ctrl, "cpr3-regulator debugfs base directory creation failed\n");
 | |
| -+			cpr3_debugfs_base = NULL;
 | |
| -+			return;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->debugfs = debugfs_create_dir(ctrl->name, cpr3_debugfs_base);
 | |
| -+	if (IS_ERR_OR_NULL(ctrl->debugfs)) {
 | |
| -+		cpr3_err(ctrl, "cpr3-regulator controller debugfs directory creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_file("cpr_closed_loop_enable", S_IRUGO | S_IWUSR,
 | |
| -+					ctrl->debugfs, ctrl,
 | |
| -+					&cpr3_debug_closed_loop_enable_fops);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(ctrl, "cpr_closed_loop_enable debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->supports_hw_closed_loop) {
 | |
| -+		temp = debugfs_create_file("use_hw_closed_loop",
 | |
| -+					S_IRUGO | S_IWUSR, ctrl->debugfs, ctrl,
 | |
| -+					&cpr3_debug_hw_closed_loop_enable_fops);
 | |
| -+		if (IS_ERR_OR_NULL(temp)) {
 | |
| -+			cpr3_err(ctrl, "use_hw_closed_loop debugfs file creation failed\n");
 | |
| -+			return;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("thread_count", S_IRUGO, ctrl->debugfs,
 | |
| -+				  &ctrl->thread_count);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(ctrl, "thread_count debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->apm) {
 | |
| -+		temp = debugfs_create_int("apm_threshold_volt", S_IRUGO,
 | |
| -+				ctrl->debugfs, &ctrl->apm_threshold_volt);
 | |
| -+		if (IS_ERR_OR_NULL(temp)) {
 | |
| -+			cpr3_err(ctrl, "apm_threshold_volt debugfs file creation failed\n");
 | |
| -+			return;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->aging_required || ctrl->aging_succeeded
 | |
| -+	    || ctrl->aging_failed) {
 | |
| -+		temp = debugfs_create_int("aging_adj_volt", S_IRUGO,
 | |
| -+				ctrl->debugfs, &ctrl->aging_ref_adjust_volt);
 | |
| -+		if (IS_ERR_OR_NULL(temp)) {
 | |
| -+			cpr3_err(ctrl, "aging_adj_volt debugfs file creation failed\n");
 | |
| -+			return;
 | |
| -+		}
 | |
| -+
 | |
| -+		temp = debugfs_create_file("aging_succeeded", S_IRUGO,
 | |
| -+			ctrl->debugfs, &ctrl->aging_succeeded, &fops_bool_ro);
 | |
| -+		if (IS_ERR_OR_NULL(temp)) {
 | |
| -+			cpr3_err(ctrl, "aging_succeeded debugfs file creation failed\n");
 | |
| -+			return;
 | |
| -+		}
 | |
| -+
 | |
| -+		temp = debugfs_create_file("aging_failed", S_IRUGO,
 | |
| -+			ctrl->debugfs, &ctrl->aging_failed, &fops_bool_ro);
 | |
| -+		if (IS_ERR_OR_NULL(temp)) {
 | |
| -+			cpr3_err(ctrl, "aging_failed debugfs file creation failed\n");
 | |
| -+			return;
 | |
| -+		}
 | |
| -+
 | |
| -+		temp = debugfs_create_file("aging_trigger", S_IWUSR,
 | |
| -+			ctrl->debugfs, ctrl,
 | |
| -+			&cpr3_debug_trigger_aging_measurement_fops);
 | |
| -+		if (IS_ERR_OR_NULL(temp)) {
 | |
| -+			cpr3_err(ctrl, "aging_trigger debugfs file creation failed\n");
 | |
| -+			return;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	aggr_dir = debugfs_create_dir("max_aggregated_voltages", ctrl->debugfs);
 | |
| -+	if (IS_ERR_OR_NULL(aggr_dir)) {
 | |
| -+		cpr3_err(ctrl, "max_aggregated_voltages debugfs directory creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("floor_volt", S_IRUGO, aggr_dir,
 | |
| -+				  &ctrl->aggr_corner.floor_volt);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(ctrl, "aggr floor_volt debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("ceiling_volt", S_IRUGO, aggr_dir,
 | |
| -+				  &ctrl->aggr_corner.ceiling_volt);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(ctrl, "aggr ceiling_volt debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("open_loop_volt", S_IRUGO, aggr_dir,
 | |
| -+				  &ctrl->aggr_corner.open_loop_volt);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(ctrl, "aggr open_loop_volt debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = debugfs_create_int("last_volt", S_IRUGO, aggr_dir,
 | |
| -+				  &ctrl->aggr_corner.last_volt);
 | |
| -+	if (IS_ERR_OR_NULL(temp)) {
 | |
| -+		cpr3_err(ctrl, "aggr last_volt debugfs file creation failed\n");
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++)
 | |
| -+		cpr3_regulator_debugfs_thread_add(&ctrl->thread[i]);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_debugfs_ctrl_remove() - remove debugfs files for the CPR
 | |
| -+ *		controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Note, this function must be called after the controller has been removed from
 | |
| -+ * cpr3_controller_list and while the cpr3_controller_list_mutex lock is held.
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+static void cpr3_regulator_debugfs_ctrl_remove(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	if (list_empty(&cpr3_controller_list)) {
 | |
| -+		debugfs_remove_recursive(cpr3_debugfs_base);
 | |
| -+		cpr3_debugfs_base = NULL;
 | |
| -+	} else {
 | |
| -+		debugfs_remove_recursive(ctrl->debugfs);
 | |
| -+	}
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_init_ctrl_data() - performs initialization of CPR controller
 | |
| -+ *					elements
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_init_ctrl_data(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	/* Read the initial vdd voltage from hardware. */
 | |
| -+	ctrl->aggr_corner.last_volt
 | |
| -+		= regulator_get_voltage(ctrl->vdd_regulator);
 | |
| -+	if (ctrl->aggr_corner.last_volt < 0) {
 | |
| -+		cpr3_err(ctrl, "regulator_get_voltage(vdd) failed, rc=%d\n",
 | |
| -+				ctrl->aggr_corner.last_volt);
 | |
| -+		return ctrl->aggr_corner.last_volt;
 | |
| -+	}
 | |
| -+	ctrl->aggr_corner.open_loop_volt = ctrl->aggr_corner.last_volt;
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_init_vreg_data() - performs initialization of common CPR3
 | |
| -+ *		regulator elements and validate aging configurations
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_init_vreg_data(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	int i, j;
 | |
| -+	bool init_aging;
 | |
| -+
 | |
| -+	vreg->current_corner = CPR3_REGULATOR_CORNER_INVALID;
 | |
| -+	vreg->last_closed_loop_corner = CPR3_REGULATOR_CORNER_INVALID;
 | |
| -+
 | |
| -+	init_aging = vreg->aging_allowed && vreg->thread->ctrl->aging_required;
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		vreg->corner[i].last_volt = vreg->corner[i].open_loop_volt;
 | |
| -+		vreg->corner[i].irq_en = CPR3_IRQ_UP | CPR3_IRQ_DOWN;
 | |
| -+
 | |
| -+		vreg->corner[i].ro_mask = 0;
 | |
| -+		for (j = 0; j < CPR3_RO_COUNT; j++) {
 | |
| -+			if (vreg->corner[i].target_quot[j] == 0)
 | |
| -+				vreg->corner[i].ro_mask |= BIT(j);
 | |
| -+		}
 | |
| -+
 | |
| -+		if (init_aging) {
 | |
| -+			vreg->corner[i].unaged_floor_volt
 | |
| -+				= vreg->corner[i].floor_volt;
 | |
| -+			vreg->corner[i].unaged_ceiling_volt
 | |
| -+				= vreg->corner[i].ceiling_volt;
 | |
| -+			vreg->corner[i].unaged_open_loop_volt
 | |
| -+				= vreg->corner[i].open_loop_volt;
 | |
| -+		}
 | |
| -+
 | |
| -+		if (vreg->aging_allowed) {
 | |
| -+			if (vreg->corner[i].unaged_floor_volt <= 0) {
 | |
| -+				cpr3_err(vreg, "invalid unaged_floor_volt[%d] = %d\n",
 | |
| -+					i, vreg->corner[i].unaged_floor_volt);
 | |
| -+				return -EINVAL;
 | |
| -+			}
 | |
| -+			if (vreg->corner[i].unaged_ceiling_volt <= 0) {
 | |
| -+				cpr3_err(vreg, "invalid unaged_ceiling_volt[%d] = %d\n",
 | |
| -+					i, vreg->corner[i].unaged_ceiling_volt);
 | |
| -+				return -EINVAL;
 | |
| -+			}
 | |
| -+			if (vreg->corner[i].unaged_open_loop_volt <= 0) {
 | |
| -+				cpr3_err(vreg, "invalid unaged_open_loop_volt[%d] = %d\n",
 | |
| -+				      i, vreg->corner[i].unaged_open_loop_volt);
 | |
| -+				return -EINVAL;
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (vreg->aging_allowed && vreg->corner[vreg->aging_corner].ceiling_volt
 | |
| -+	    > vreg->thread->ctrl->aging_ref_volt) {
 | |
| -+		cpr3_err(vreg, "aging corner %d ceiling voltage = %d > aging ref voltage = %d uV\n",
 | |
| -+			vreg->aging_corner,
 | |
| -+			vreg->corner[vreg->aging_corner].ceiling_volt,
 | |
| -+			vreg->thread->ctrl->aging_ref_volt);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_suspend() - perform common required CPR3 power down steps
 | |
| -+ *		before the system enters suspend
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_regulator_suspend(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+		rc = cpr3_ctrl_clear_cpr4_config(ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "failed to clear CPR4 configuration,rc=%d\n",
 | |
| -+				rc);
 | |
| -+			mutex_unlock(&ctrl->lock);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_ctrl_loop_disable(ctrl);
 | |
| -+
 | |
| -+	rc = cpr3_closed_loop_disable(ctrl);
 | |
| -+	if (rc)
 | |
| -+		cpr3_err(ctrl, "could not disable CPR, rc=%d\n", rc);
 | |
| -+
 | |
| -+	ctrl->cpr_suspended = true;
 | |
| -+
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_resume() - perform common required CPR3 power up steps after
 | |
| -+ *		the system resumes from suspend
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_regulator_resume(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	mutex_lock(&ctrl->lock);
 | |
| -+
 | |
| -+	ctrl->cpr_suspended = false;
 | |
| -+	rc = cpr3_regulator_update_ctrl_state(ctrl);
 | |
| -+	if (rc)
 | |
| -+		cpr3_err(ctrl, "could not enable CPR, rc=%d\n", rc);
 | |
| -+
 | |
| -+	mutex_unlock(&ctrl->lock);
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_validate_controller() - verify the data passed in via the
 | |
| -+ *		cpr3_controller data structure
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_regulator_validate_controller(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct cpr3_thread *thread;
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+	int i, j, allow_boost_vreg_count = 0;
 | |
| -+
 | |
| -+	if (!ctrl->vdd_regulator) {
 | |
| -+		cpr3_err(ctrl, "vdd regulator missing\n");
 | |
| -+		return -EINVAL;
 | |
| -+	} else if (ctrl->sensor_count <= 0
 | |
| -+		   || ctrl->sensor_count > CPR3_MAX_SENSOR_COUNT) {
 | |
| -+		cpr3_err(ctrl, "invalid CPR sensor count=%d\n",
 | |
| -+			ctrl->sensor_count);
 | |
| -+		return -EINVAL;
 | |
| -+	} else if (!ctrl->sensor_owner) {
 | |
| -+		cpr3_err(ctrl, "CPR sensor ownership table missing\n");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->aging_required) {
 | |
| -+		for (i = 0; i < ctrl->aging_sensor_count; i++) {
 | |
| -+			if (ctrl->aging_sensor[i].sensor_id
 | |
| -+			    >= ctrl->sensor_count) {
 | |
| -+				cpr3_err(ctrl, "aging_sensor[%d] id=%u is not in the value range 0-%d",
 | |
| -+					i, ctrl->aging_sensor[i].sensor_id,
 | |
| -+					ctrl->sensor_count - 1);
 | |
| -+				return -EINVAL;
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		thread = &ctrl->thread[i];
 | |
| -+		for (j = 0; j < thread->vreg_count; j++) {
 | |
| -+			vreg = &thread->vreg[j];
 | |
| -+			if (vreg->allow_boost)
 | |
| -+				allow_boost_vreg_count++;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (allow_boost_vreg_count > 1) {
 | |
| -+		/*
 | |
| -+		 * Boost feature is not allowed to be used for more
 | |
| -+		 * than one CPR3 regulator of a CPR3 controller.
 | |
| -+		 */
 | |
| -+		cpr3_err(ctrl, "Boost feature is enabled for more than one regulator\n");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_panic_callback() - panic notification callback function. This function
 | |
| -+ *		is invoked when a kernel panic occurs.
 | |
| -+ * @nfb:	Notifier block pointer of CPR3 controller
 | |
| -+ * @event:	Value passed unmodified to notifier function
 | |
| -+ * @data:	Pointer passed unmodified to notifier function
 | |
| -+ *
 | |
| -+ * Return: NOTIFY_OK
 | |
| -+ */
 | |
| -+static int cpr3_panic_callback(struct notifier_block *nfb,
 | |
| -+			unsigned long event, void *data)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = container_of(nfb,
 | |
| -+				struct cpr3_controller, panic_notifier);
 | |
| -+	struct cpr3_panic_regs_info *regs_info = ctrl->panic_regs_info;
 | |
| -+	struct cpr3_reg_info *reg;
 | |
| -+	int i = 0;
 | |
| -+
 | |
| -+	for (i = 0; i < regs_info->reg_count; i++) {
 | |
| -+		reg = &(regs_info->regs[i]);
 | |
| -+		reg->value = readl_relaxed(reg->virt_addr);
 | |
| -+		pr_err("%s[0x%08x] = 0x%08x\n", reg->name, reg->addr,
 | |
| -+			reg->value);
 | |
| -+	}
 | |
| -+	/*
 | |
| -+	 * Barrier to ensure that the information has been updated in the
 | |
| -+	 * structure.
 | |
| -+	 */
 | |
| -+	mb();
 | |
| -+
 | |
| -+	return NOTIFY_OK;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_register() - register the regulators for a CPR3 controller and
 | |
| -+ *		perform CPR hardware initialization
 | |
| -+ * @pdev:		Platform device pointer for the CPR3 controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_regulator_register(struct platform_device *pdev,
 | |
| -+			struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct device *dev = &pdev->dev;
 | |
| -+	struct resource *res;
 | |
| -+	int i, j, rc;
 | |
| -+
 | |
| -+	if (!dev->of_node) {
 | |
| -+		dev_err(dev, "%s: Device tree node is missing\n", __func__);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!ctrl || !ctrl->name) {
 | |
| -+		dev_err(dev, "%s: CPR controller data is missing\n", __func__);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_regulator_validate_controller(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "controller validation failed, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	mutex_init(&ctrl->lock);
 | |
| -+
 | |
| -+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cpr_ctrl");
 | |
| -+	if (!res || !res->start) {
 | |
| -+		cpr3_err(ctrl, "CPR controller address is missing\n");
 | |
| -+		return -ENXIO;
 | |
| -+	}
 | |
| -+	ctrl->cpr_ctrl_base = devm_ioremap(dev, res->start, resource_size(res));
 | |
| -+
 | |
| -+	if (ctrl->aging_possible_mask) {
 | |
| -+		/*
 | |
| -+		 * Aging possible register address is required if an aging
 | |
| -+		 * possible mask has been specified.
 | |
| -+		 */
 | |
| -+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 | |
| -+						"aging_allowed");
 | |
| -+		if (!res || !res->start) {
 | |
| -+			cpr3_err(ctrl, "CPR aging allowed address is missing\n");
 | |
| -+			return -ENXIO;
 | |
| -+		}
 | |
| -+		ctrl->aging_possible_reg = devm_ioremap(dev, res->start,
 | |
| -+							resource_size(res));
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->irq = platform_get_irq_byname(pdev, "cpr");
 | |
| -+	if (ctrl->irq < 0) {
 | |
| -+		cpr3_err(ctrl, "missing CPR interrupt\n");
 | |
| -+		return ctrl->irq;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->supports_hw_closed_loop) {
 | |
| -+		if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+			ctrl->ceiling_irq = platform_get_irq_byname(pdev,
 | |
| -+						"ceiling");
 | |
| -+			if (ctrl->ceiling_irq < 0) {
 | |
| -+				cpr3_err(ctrl, "missing ceiling interrupt\n");
 | |
| -+				return ctrl->ceiling_irq;
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_regulator_init_ctrl_data(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "CPR controller data initialization failed, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+			rc = cpr3_regulator_init_vreg_data(
 | |
| -+						&ctrl->thread[i].vreg[j]);
 | |
| -+			if (rc)
 | |
| -+				return rc;
 | |
| -+			cpr3_print_quots(&ctrl->thread[i].vreg[j]);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Add the maximum possible aging voltage margin until it is possible
 | |
| -+	 * to perform an aging measurement.
 | |
| -+	 */
 | |
| -+	if (ctrl->aging_required)
 | |
| -+		cpr3_regulator_set_aging_ref_adjustment(ctrl, INT_MAX);
 | |
| -+
 | |
| -+	rc = cpr3_regulator_init_ctrl(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "CPR controller initialization failed, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Register regulator devices for all threads. */
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+			rc = cpr3_regulator_vreg_register(
 | |
| -+					&ctrl->thread[i].vreg[j]);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(&ctrl->thread[i].vreg[j], "failed to register regulator, rc=%d\n",
 | |
| -+					rc);
 | |
| -+				goto free_regulators;
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = devm_request_threaded_irq(dev, ctrl->irq, NULL,
 | |
| -+				       cpr3_irq_handler,
 | |
| -+				       IRQF_ONESHOT |
 | |
| -+				       IRQF_TRIGGER_RISING,
 | |
| -+				       "cpr3", ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "could not request IRQ %d, rc=%d\n",
 | |
| -+			 ctrl->irq, rc);
 | |
| -+		goto free_regulators;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->supports_hw_closed_loop &&
 | |
| -+	    ctrl->ctrl_type == CPR_CTRL_TYPE_CPR3) {
 | |
| -+		rc = devm_request_threaded_irq(dev, ctrl->ceiling_irq, NULL,
 | |
| -+			cpr3_ceiling_irq_handler,
 | |
| -+			IRQF_ONESHOT | IRQF_TRIGGER_RISING,
 | |
| -+			"cpr3_ceiling", ctrl);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "could not request ceiling IRQ %d, rc=%d\n",
 | |
| -+				ctrl->ceiling_irq, rc);
 | |
| -+			goto free_regulators;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	mutex_lock(&cpr3_controller_list_mutex);
 | |
| -+	cpr3_regulator_debugfs_ctrl_add(ctrl);
 | |
| -+	list_add(&ctrl->list, &cpr3_controller_list);
 | |
| -+	mutex_unlock(&cpr3_controller_list_mutex);
 | |
| -+
 | |
| -+	if (ctrl->panic_regs_info) {
 | |
| -+		/* Register panic notification call back */
 | |
| -+		ctrl->panic_notifier.notifier_call = cpr3_panic_callback;
 | |
| -+		atomic_notifier_chain_register(&panic_notifier_list,
 | |
| -+			&ctrl->panic_notifier);
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+
 | |
| -+free_regulators:
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++)
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++)
 | |
| -+			if (!IS_ERR_OR_NULL(ctrl->thread[i].vreg[j].rdev))
 | |
| -+				regulator_unregister(
 | |
| -+					ctrl->thread[i].vreg[j].rdev);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_open_loop_regulator_register() - register the regulators for a CPR3
 | |
| -+ *			controller which will always work in Open loop and
 | |
| -+ *			won't support close loop.
 | |
| -+ * @pdev:		Platform device pointer for the CPR3 controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_open_loop_regulator_register(struct platform_device *pdev,
 | |
| -+				      struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct device *dev = &pdev->dev;
 | |
| -+	struct cpr3_regulator *vreg;
 | |
| -+	int i, j, rc;
 | |
| -+
 | |
| -+	if (!dev->of_node) {
 | |
| -+		dev_err(dev, "%s: Device tree node is missing\n", __func__);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!ctrl || !ctrl->name) {
 | |
| -+		dev_err(dev, "%s: CPR controller data is missing\n", __func__);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!ctrl->vdd_regulator) {
 | |
| -+		cpr3_err(ctrl, "vdd regulator missing\n");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	mutex_init(&ctrl->lock);
 | |
| -+
 | |
| -+	rc = cpr3_regulator_init_ctrl_data(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "CPR controller data initialization failed, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+			vreg = &ctrl->thread[i].vreg[j];
 | |
| -+			vreg->corner[i].last_volt =
 | |
| -+				vreg->corner[i].open_loop_volt;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Register regulator devices for all threads. */
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++) {
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++) {
 | |
| -+			rc = cpr3_regulator_vreg_register(
 | |
| -+					&ctrl->thread[i].vreg[j]);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(&ctrl->thread[i].vreg[j], "failed to register regulator, rc=%d\n",
 | |
| -+					 rc);
 | |
| -+				goto free_regulators;
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	mutex_lock(&cpr3_controller_list_mutex);
 | |
| -+	list_add(&ctrl->list, &cpr3_controller_list);
 | |
| -+	mutex_unlock(&cpr3_controller_list_mutex);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+
 | |
| -+free_regulators:
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++)
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++)
 | |
| -+			if (!IS_ERR_OR_NULL(ctrl->thread[i].vreg[j].rdev))
 | |
| -+				regulator_unregister(
 | |
| -+					ctrl->thread[i].vreg[j].rdev);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_regulator_unregister() - unregister the regulators for a CPR3 controller
 | |
| -+ *		and perform CPR hardware shutdown
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_regulator_unregister(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int i, j, rc = 0;
 | |
| -+
 | |
| -+	mutex_lock(&cpr3_controller_list_mutex);
 | |
| -+	list_del(&ctrl->list);
 | |
| -+	cpr3_regulator_debugfs_ctrl_remove(ctrl);
 | |
| -+	mutex_unlock(&cpr3_controller_list_mutex);
 | |
| -+
 | |
| -+	if (ctrl->ctrl_type == CPR_CTRL_TYPE_CPR4) {
 | |
| -+		rc = cpr3_ctrl_clear_cpr4_config(ctrl);
 | |
| -+		if (rc)
 | |
| -+			cpr3_err(ctrl, "failed to clear CPR4 configuration,rc=%d\n",
 | |
| -+				rc);
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_ctrl_loop_disable(ctrl);
 | |
| -+
 | |
| -+	cpr3_closed_loop_disable(ctrl);
 | |
| -+
 | |
| -+	if (ctrl->vdd_limit_regulator) {
 | |
| -+		regulator_disable(ctrl->vdd_limit_regulator);
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++)
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++)
 | |
| -+			regulator_unregister(ctrl->thread[i].vreg[j].rdev);
 | |
| -+
 | |
| -+	if (ctrl->panic_notifier.notifier_call)
 | |
| -+		atomic_notifier_chain_unregister(&panic_notifier_list,
 | |
| -+			&ctrl->panic_notifier);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_open_loop_regulator_unregister() - unregister the regulators for a CPR3
 | |
| -+ *			open loop controller and perform CPR hardware shutdown
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_open_loop_regulator_unregister(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int i, j;
 | |
| -+
 | |
| -+	mutex_lock(&cpr3_controller_list_mutex);
 | |
| -+	list_del(&ctrl->list);
 | |
| -+	mutex_unlock(&cpr3_controller_list_mutex);
 | |
| -+
 | |
| -+	if (ctrl->vdd_limit_regulator) {
 | |
| -+		regulator_disable(ctrl->vdd_limit_regulator);
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread_count; i++)
 | |
| -+		for (j = 0; j < ctrl->thread[i].vreg_count; j++)
 | |
| -+			regulator_unregister(ctrl->thread[i].vreg[j].rdev);
 | |
| -+
 | |
| -+	if (ctrl->panic_notifier.notifier_call)
 | |
| -+		atomic_notifier_chain_unregister(&panic_notifier_list,
 | |
| -+			&ctrl->panic_notifier);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| ---- /dev/null
 | |
| -+++ b/drivers/regulator/cpr3-regulator.h
 | |
| -@@ -0,0 +1,1211 @@
 | |
| -+/*
 | |
| -+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 | |
| -+ *
 | |
| -+ * This program is free software; you can redistribute it and/or modify
 | |
| -+ * it under the terms of the GNU General Public License version 2 and
 | |
| -+ * only version 2 as published by the Free Software Foundation.
 | |
| -+ *
 | |
| -+ * This program is distributed in the hope that it will be useful,
 | |
| -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| -+ * GNU General Public License for more details.
 | |
| -+ */
 | |
| -+
 | |
| -+#ifndef __REGULATOR_CPR3_REGULATOR_H__
 | |
| -+#define __REGULATOR_CPR3_REGULATOR_H__
 | |
| -+
 | |
| -+#include <linux/clk.h>
 | |
| -+#include <linux/mutex.h>
 | |
| -+#include <linux/of.h>
 | |
| -+#include <linux/platform_device.h>
 | |
| -+#include <linux/types.h>
 | |
| -+#include <linux/power/qcom/apm.h>
 | |
| -+#include <linux/regulator/driver.h>
 | |
| -+
 | |
| -+struct cpr3_controller;
 | |
| -+struct cpr3_thread;
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr3_fuse_param - defines one contiguous segment of a fuse parameter
 | |
| -+ *			    that is contained within a given row.
 | |
| -+ * @row:	Fuse row number
 | |
| -+ * @bit_start:	The first bit within the row of the fuse parameter segment
 | |
| -+ * @bit_end:	The last bit within the row of the fuse parameter segment
 | |
| -+ *
 | |
| -+ * Each fuse row is 64 bits in length.  bit_start and bit_end may take values
 | |
| -+ * from 0 to 63.  bit_start must be less than or equal to bit_end.
 | |
| -+ */
 | |
| -+struct cpr3_fuse_param {
 | |
| -+	unsigned		row;
 | |
| -+	unsigned		bit_start;
 | |
| -+	unsigned		bit_end;
 | |
| -+};
 | |
| -+
 | |
| -+/* Each CPR3 sensor has 16 ring oscillators */
 | |
| -+#define CPR3_RO_COUNT		16
 | |
| -+
 | |
| -+/* The maximum number of sensors that can be present on a single CPR loop. */
 | |
| -+#define CPR3_MAX_SENSOR_COUNT	256
 | |
| -+
 | |
| -+/* This constant is used when allocating array printing buffers. */
 | |
| -+#define MAX_CHARS_PER_INT	10
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr4_sdelta - CPR4 controller specific data structure for the sdelta
 | |
| -+ *			adjustment table which is used to adjust the VDD supply
 | |
| -+ *			voltage automatically based upon the temperature and/or
 | |
| -+ *			the number of online CPU cores.
 | |
| -+ * @allow_core_count_adj: Core count adjustments are allowed.
 | |
| -+ * @allow_temp_adj:	Temperature based adjustments are allowed.
 | |
| -+ * @max_core_count:	Maximum number of cores considered for core count
 | |
| -+ *			adjustment logic.
 | |
| -+ * @temp_band_count:	Number of temperature bands considered for temperature
 | |
| -+ *			based adjustment logic.
 | |
| -+ * @cap_volt:		CAP in uV to apply to SDELTA margins with multiple
 | |
| -+ *			cpr3-regulators defined for single controller.
 | |
| -+ * @table:		SDELTA table with per-online-core and temperature based
 | |
| -+ *			adjustments of size (max_core_count * temp_band_count)
 | |
| -+ *			Outer: core count
 | |
| -+ *			Inner: temperature band
 | |
| -+ *			Each element has units of VDD supply steps. Positive
 | |
| -+ *			values correspond to a reduction in voltage and negative
 | |
| -+ *			value correspond to an increase (this follows the SDELTA
 | |
| -+ *			register semantics).
 | |
| -+ * @allow_boost:	Voltage boost allowed.
 | |
| -+ * @boost_num_cores:	The number of online cores at which the boost voltage
 | |
| -+ *			adjustments will be applied
 | |
| -+ * @boost_table:	SDELTA table with boost voltage adjustments of size
 | |
| -+ *			temp_band_count. Each element has units of VDD supply
 | |
| -+ *			steps. Positive values correspond to a reduction in
 | |
| -+ *			voltage and negative value correspond to an increase
 | |
| -+ *			(this follows the SDELTA register semantics).
 | |
| -+ */
 | |
| -+struct cpr4_sdelta {
 | |
| -+	bool	allow_core_count_adj;
 | |
| -+	bool	allow_temp_adj;
 | |
| -+	int	max_core_count;
 | |
| -+	int	temp_band_count;
 | |
| -+	int	cap_volt;
 | |
| -+	int	*table;
 | |
| -+	bool	allow_boost;
 | |
| -+	int	boost_num_cores;
 | |
| -+	int	*boost_table;
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr3_corner - CPR3 virtual voltage corner data structure
 | |
| -+ * @floor_volt:		CPR closed-loop floor voltage in microvolts
 | |
| -+ * @ceiling_volt:	CPR closed-loop ceiling voltage in microvolts
 | |
| -+ * @open_loop_volt:	CPR open-loop voltage (i.e. initial voltage) in
 | |
| -+ *			microvolts
 | |
| -+ * @last_volt:		Last known settled CPR closed-loop voltage which is used
 | |
| -+ *			when switching to a new corner
 | |
| -+ * @abs_ceiling_volt:	The absolute CPR closed-loop ceiling voltage in
 | |
| -+ *			microvolts.  This is used to limit the ceiling_volt
 | |
| -+ *			value when it is increased as a result of aging
 | |
| -+ *			adjustment.
 | |
| -+ * @unaged_floor_volt:	The CPR closed-loop floor voltage in microvolts before
 | |
| -+ *			any aging adjustment is performed
 | |
| -+ * @unaged_ceiling_volt: The CPR closed-loop ceiling voltage in microvolts
 | |
| -+ *			before any aging adjustment is performed
 | |
| -+ * @unaged_open_loop_volt: The CPR open-loop voltage (i.e. initial voltage) in
 | |
| -+ *			microvolts before any aging adjusment is performed
 | |
| -+ * @system_volt:	The system-supply voltage in microvolts or corners or
 | |
| -+ *			levels
 | |
| -+ * @mem_acc_volt:	The mem-acc-supply voltage in corners
 | |
| -+ * @proc_freq:		Processor frequency in Hertz. For CPR rev. 3 and 4
 | |
| -+ *			conrollers, this field is only used by platform specific
 | |
| -+ *			CPR3 driver for interpolation. For CPRh-compliant
 | |
| -+ *			controllers, this frequency is also utilized by the
 | |
| -+ *			clock driver to determine the corner to CPU clock
 | |
| -+ *			frequency mappings.
 | |
| -+ * @cpr_fuse_corner:	Fused corner index associated with this virtual corner
 | |
| -+ *			(only used by platform specific CPR3 driver for
 | |
| -+ *			mapping purposes)
 | |
| -+ * @target_quot:	Array of target quotient values to use for each ring
 | |
| -+ *			oscillator (RO) for this corner.  A value of 0 should be
 | |
| -+ *			specified as the target quotient for each RO that is
 | |
| -+ *			unused by this corner.
 | |
| -+ * @ro_scale:		Array of CPR ring oscillator (RO) scaling factors.  The
 | |
| -+ *			scaling factor for each RO is defined from RO0 to RO15
 | |
| -+ *			with units of QUOT/V.  A value of 0 may be specified for
 | |
| -+ *			an RO that is unused.
 | |
| -+ * @ro_mask:		Bitmap where each of the 16 LSBs indicate if the
 | |
| -+ *			corresponding ROs should be masked for this corner
 | |
| -+ * @irq_en:		Bitmap of the CPR interrupts to enable for this corner
 | |
| -+ * @aging_derate:	The amount to derate the aging voltage adjustment
 | |
| -+ *			determined for the reference corner in units of uV/mV.
 | |
| -+ *			E.g. a value of 900 would imply that the adjustment for
 | |
| -+ *			this corner should be 90% (900/1000) of that for the
 | |
| -+ *			reference corner.
 | |
| -+ * @use_open_loop:	Boolean indicating that open-loop (i.e CPR disabled) as
 | |
| -+ *			opposed to closed-loop operation must be used for this
 | |
| -+ *			corner on CPRh controllers.
 | |
| -+ * @sdelta:		The CPR4 controller specific data for this corner. This
 | |
| -+ *			field is applicable for CPR4 controllers.
 | |
| -+ *
 | |
| -+ * The value of last_volt is initialized inside of the cpr3_regulator_register()
 | |
| -+ * call with the open_loop_volt value.  It can later be updated to the settled
 | |
| -+ * VDD supply voltage.  The values for unaged_floor_volt, unaged_ceiling_volt,
 | |
| -+ * and unaged_open_loop_volt are initialized inside of cpr3_regulator_register()
 | |
| -+ * if ctrl->aging_required == true.  These three values must be pre-initialized
 | |
| -+ * if cpr3_regulator_register() is called with ctrl->aging_required == false and
 | |
| -+ * ctrl->aging_succeeded == true.
 | |
| -+ *
 | |
| -+ * The values of ro_mask and irq_en are initialized inside of the
 | |
| -+ * cpr3_regulator_register() call.
 | |
| -+ */
 | |
| -+struct cpr3_corner {
 | |
| -+	int			floor_volt;
 | |
| -+	int			ceiling_volt;
 | |
| -+	int			cold_temp_open_loop_volt;
 | |
| -+	int			normal_temp_open_loop_volt;
 | |
| -+	int			open_loop_volt;
 | |
| -+	int			last_volt;
 | |
| -+	int			abs_ceiling_volt;
 | |
| -+	int			unaged_floor_volt;
 | |
| -+	int			unaged_ceiling_volt;
 | |
| -+	int			unaged_open_loop_volt;
 | |
| -+	int			system_volt;
 | |
| -+	int			mem_acc_volt;
 | |
| -+	u32			proc_freq;
 | |
| -+	int			cpr_fuse_corner;
 | |
| -+	u32			target_quot[CPR3_RO_COUNT];
 | |
| -+	u32			ro_scale[CPR3_RO_COUNT];
 | |
| -+	u32			ro_mask;
 | |
| -+	u32			irq_en;
 | |
| -+	int			aging_derate;
 | |
| -+	bool			use_open_loop;
 | |
| -+	struct cpr4_sdelta	*sdelta;
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cprh_corner_band - CPRh controller specific data structure which
 | |
| -+ *			encapsulates the range of corners and the SDELTA
 | |
| -+ *			adjustment table to be applied to the corners within
 | |
| -+ *			the min and max bounds of the corner band.
 | |
| -+ * @corner:		Corner number which defines the corner band boundary
 | |
| -+ * @sdelta:		The SDELTA adjustment table which contains core-count
 | |
| -+ *			and temp based margin adjustments that are applicable
 | |
| -+ *			to the corner band.
 | |
| -+ */
 | |
| -+struct cprh_corner_band {
 | |
| -+	int			corner;
 | |
| -+	struct cpr4_sdelta	*sdelta;
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr3_fuse_parameters - CPR4 fuse specific data structure which has
 | |
| -+ * 			the required fuse parameters need for Close Loop CPR
 | |
| -+ * @(*apss_ro_sel_param)[2]:       Pointer to RO select fuse details
 | |
| -+ * @(*apss_init_voltage_param)[2]: Pointer to Target voltage fuse details
 | |
| -+ * @(*apss_target_quot_param)[2]:  Pointer to Target quot fuse details
 | |
| -+ * @(*apss_quot_offset_param)[2]:  Pointer to quot offset fuse details
 | |
| -+ * @cpr_fusing_rev_param:          Pointer to CPR revision fuse details
 | |
| -+ * @apss_speed_bin_param:          Pointer to Speed bin fuse details
 | |
| -+ * @cpr_boost_fuse_cfg_param:      Pointer to Boost fuse cfg details
 | |
| -+ * @apss_boost_fuse_volt_param:    Pointer to Boost fuse volt details
 | |
| -+ * @misc_fuse_volt_adj_param:      Pointer to Misc fuse volt fuse details
 | |
| -+ */
 | |
| -+struct cpr3_fuse_parameters {
 | |
| -+	struct cpr3_fuse_param (*apss_ro_sel_param)[2];
 | |
| -+	struct cpr3_fuse_param (*apss_init_voltage_param)[2];
 | |
| -+	struct cpr3_fuse_param (*apss_target_quot_param)[2];
 | |
| -+	struct cpr3_fuse_param (*apss_quot_offset_param)[2];
 | |
| -+	struct cpr3_fuse_param *cpr_fusing_rev_param;
 | |
| -+	struct cpr3_fuse_param *apss_speed_bin_param;
 | |
| -+	struct cpr3_fuse_param *cpr_boost_fuse_cfg_param;
 | |
| -+	struct cpr3_fuse_param *apss_boost_fuse_volt_param;
 | |
| -+	struct cpr3_fuse_param *misc_fuse_volt_adj_param;
 | |
| -+};
 | |
| -+
 | |
| -+struct cpr4_mem_acc_func {
 | |
| -+	void (*set_mem_acc)(struct regulator_dev *);
 | |
| -+	void (*clear_mem_acc)(struct regulator_dev *);
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr4_reg_data - CPR4 regulator specific data structure which is
 | |
| -+ * target specific
 | |
| -+ * @cpr_valid_fuse_count: Number of valid fuse corners
 | |
| -+ * @fuse_ref_volt: 	  Pointer to fuse reference voltage
 | |
| -+ * @fuse_step_volt: 	  CPR step voltage available in fuse
 | |
| -+ * @cpr_clk_rate: 	  CPR clock rate
 | |
| -+ * @boost_fuse_ref_volt:  Boost fuse reference voltage
 | |
| -+ * @boost_ceiling_volt:   Boost ceiling voltage
 | |
| -+ * @boost_floor_volt: 	  Boost floor voltage
 | |
| -+ * @cpr3_fuse_params:     Pointer to CPR fuse parameters
 | |
| -+ * @mem_acc_funcs:        Pointer to MEM ACC set/clear functions
 | |
| -+ **/
 | |
| -+struct cpr4_reg_data {
 | |
| -+	u32 cpr_valid_fuse_count;
 | |
| -+	int *fuse_ref_volt;
 | |
| -+	u32 fuse_step_volt;
 | |
| -+	u32 cpr_clk_rate;
 | |
| -+	int boost_fuse_ref_volt;
 | |
| -+	int boost_ceiling_volt;
 | |
| -+	int boost_floor_volt;
 | |
| -+	struct cpr3_fuse_parameters *cpr3_fuse_params;
 | |
| -+	struct cpr4_mem_acc_func *mem_acc_funcs;
 | |
| -+};
 | |
| -+/**
 | |
| -+ * struct cpr3_reg_data - CPR3 regulator specific data structure which is
 | |
| -+ * target specific
 | |
| -+ * @cpr_valid_fuse_count: Number of valid fuse corners
 | |
| -+ * @(*init_voltage_param)[2]: Pointer to Target voltage fuse details
 | |
| -+ * @fuse_ref_volt: 	  Pointer to fuse reference voltage
 | |
| -+ * @fuse_step_volt: 	  CPR step voltage available in fuse
 | |
| -+ * @cpr_clk_rate: 	  CPR clock rate
 | |
| -+ * @cpr3_fuse_params:     Pointer to CPR fuse parameters
 | |
| -+ **/
 | |
| -+struct cpr3_reg_data {
 | |
| -+	u32 cpr_valid_fuse_count;
 | |
| -+	struct cpr3_fuse_param (*init_voltage_param)[2];
 | |
| -+	int *fuse_ref_volt;
 | |
| -+	u32 fuse_step_volt;
 | |
| -+	u32 cpr_clk_rate;
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr3_regulator - CPR3 logical regulator instance associated with a
 | |
| -+ *			given CPR3 hardware thread
 | |
| -+ * @of_node:		Device node associated with the device tree child node
 | |
| -+ *			of this CPR3 regulator
 | |
| -+ * @thread:		Pointer to the CPR3 thread which manages this CPR3
 | |
| -+ *			regulator
 | |
| -+ * @name:		Unique name for this CPR3 regulator which is filled
 | |
| -+ *			using the device tree regulator-name property
 | |
| -+ * @rdesc:		Regulator description for this CPR3 regulator
 | |
| -+ * @rdev:		Regulator device pointer for the regulator registered
 | |
| -+ *			for this CPR3 regulator
 | |
| -+ * @mem_acc_regulator:	Pointer to the optional mem-acc supply regulator used
 | |
| -+ *			to manage memory circuitry settings based upon CPR3
 | |
| -+ *			regulator output voltage.
 | |
| -+ * @corner:		Array of all corners supported by this CPR3 regulator
 | |
| -+ * @corner_count:	The number of elements in the corner array
 | |
| -+ * @corner_band:	Array of all corner bands supported by CPRh compatible
 | |
| -+ *			controllers
 | |
| -+ * @cpr4_regulator_data Target specific cpr4 regulator data
 | |
| -+ * @cpr3_regulator_data Target specific cpr3 regulator data
 | |
| -+ * @corner_band_count:	The number of elements in the corner band array
 | |
| -+ * @platform_fuses:	Pointer to platform specific CPR fuse data (only used by
 | |
| -+ *			platform specific CPR3 driver)
 | |
| -+ * @speed_bin_fuse:	Value read from the speed bin fuse parameter
 | |
| -+ * @speed_bins_supported: The number of speed bins supported by the device tree
 | |
| -+ *			configuration for this CPR3 regulator
 | |
| -+ * @cpr_rev_fuse:	Value read from the CPR fusing revision fuse parameter
 | |
| -+ * @fuse_combo:		Platform specific enum value identifying the specific
 | |
| -+ *			combination of fuse values found on a given chip
 | |
| -+ * @fuse_combos_supported: The number of fuse combinations supported by the
 | |
| -+ *			device tree configuration for this CPR3 regulator
 | |
| -+ * @fuse_corner_count:	Number of corners defined by fuse parameters
 | |
| -+ * @fuse_corner_map:	Array of length fuse_corner_count which specifies the
 | |
| -+ *			highest corner associated with each fuse corner.  Note
 | |
| -+ *			that each element must correspond to a valid corner
 | |
| -+ *			and that element values must be strictly increasing.
 | |
| -+ *			Also, it is acceptable for the lowest fuse corner to map
 | |
| -+ *			to a corner other than the lowest.  Likewise, it is
 | |
| -+ *			acceptable for the highest fuse corner to map to a
 | |
| -+ *			corner other than the highest.
 | |
| -+ * @fuse_combo_corner_sum: The sum of the corner counts across all fuse combos
 | |
| -+ * @fuse_combo_offset:	The device tree property array offset for the selected
 | |
| -+ *			fuse combo
 | |
| -+ * @speed_bin_corner_sum: The sum of the corner counts across all speed bins
 | |
| -+ *			This may be specified as 0 if per speed bin parsing
 | |
| -+ *			support is not required.
 | |
| -+ * @speed_bin_offset:	The device tree property array offset for the selected
 | |
| -+ *			speed bin
 | |
| -+ * @fuse_combo_corner_band_sum: The sum of the corner band counts across all
 | |
| -+ *			fuse combos
 | |
| -+ * @fuse_combo_corner_band_offset: The device tree property array offset for
 | |
| -+ *			the corner band count corresponding to the selected
 | |
| -+ *			fuse combo
 | |
| -+ * @speed_bin_corner_band_sum: The sum of the corner band counts across all
 | |
| -+ *			speed bins. This may be specified as 0 if per speed bin
 | |
| -+ *			parsing support is not required
 | |
| -+ * @speed_bin_corner_band_offset: The device tree property array offset for the
 | |
| -+ *			corner band count corresponding to the selected speed
 | |
| -+ *			bin
 | |
| -+ * @pd_bypass_mask:	Bit mask of power domains associated with this CPR3
 | |
| -+ *			regulator
 | |
| -+ * @dynamic_floor_corner: Index identifying the voltage corner for the CPR3
 | |
| -+ *			regulator whose last_volt value should be used as the
 | |
| -+ *			global CPR floor voltage if all of the power domains
 | |
| -+ *			associated with this CPR3 regulator are bypassed
 | |
| -+ * @uses_dynamic_floor: Boolean flag indicating that dynamic_floor_corner should
 | |
| -+ *			be utilized for the CPR3 regulator
 | |
| -+ * @current_corner:	Index identifying the currently selected voltage corner
 | |
| -+ *			for the CPR3 regulator or less than 0 if no corner has
 | |
| -+ *			been requested
 | |
| -+ * @last_closed_loop_corner: Index identifying the last voltage corner for the
 | |
| -+ *			CPR3 regulator which was configured when operating in
 | |
| -+ *			CPR closed-loop mode or less than 0 if no corner has
 | |
| -+ *			been requested.  CPR registers are only written to when
 | |
| -+ *			using closed-loop mode.
 | |
| -+ * @aggregated:		Boolean flag indicating that this CPR3 regulator
 | |
| -+ *			participated in the last aggregation event
 | |
| -+ * @debug_corner:	Index identifying voltage corner used for displaying
 | |
| -+ *			corner configuration values in debugfs
 | |
| -+ * @vreg_enabled:	Boolean defining the enable state of the CPR3
 | |
| -+ *			regulator's regulator within the regulator framework.
 | |
| -+ * @aging_allowed:	Boolean defining if CPR aging adjustments are allowed
 | |
| -+ *			for this CPR3 regulator given the fuse combo of the
 | |
| -+ *			device
 | |
| -+ * @aging_allow_open_loop_adj: Boolean defining if the open-loop voltage of each
 | |
| -+ *			corner of this regulator should be adjusted as a result
 | |
| -+ *			of an aging measurement.  This flag can be set to false
 | |
| -+ *			when the open-loop voltage adjustments have been
 | |
| -+ *			specified such that they include the maximum possible
 | |
| -+ *			aging adjustment.  This flag is only used if
 | |
| -+ *			aging_allowed == true.
 | |
| -+ * @aging_corner:	The corner that should be configured for this regulator
 | |
| -+ *			when an aging measurement is performed.
 | |
| -+ * @aging_max_adjust_volt: The maximum aging voltage margin in microvolts that
 | |
| -+ *			may be added to the target quotients of this regulator.
 | |
| -+ *			A value of 0 may be specified if this regulator does not
 | |
| -+ *			require any aging adjustment.
 | |
| -+ * @allow_core_count_adj: Core count adjustments are allowed for this regulator.
 | |
| -+ * @allow_temp_adj:	Temperature based adjustments are allowed for this
 | |
| -+ *			regulator.
 | |
| -+ * @max_core_count:	Maximum number of cores considered for core count
 | |
| -+ *			adjustment logic.
 | |
| -+ * @allow_boost:	Voltage boost allowed for this regulator.
 | |
| -+ *
 | |
| -+ * This structure contains both configuration and runtime state data.  The
 | |
| -+ * elements current_corner, last_closed_loop_corner, aggregated, debug_corner,
 | |
| -+ * and vreg_enabled are state variables.
 | |
| -+ */
 | |
| -+struct cpr3_regulator {
 | |
| -+	struct device_node	*of_node;
 | |
| -+	struct cpr3_thread	*thread;
 | |
| -+	const char		*name;
 | |
| -+	struct regulator_desc	rdesc;
 | |
| -+	struct regulator_dev	*rdev;
 | |
| -+	struct regulator	*mem_acc_regulator;
 | |
| -+	struct cpr3_corner	*corner;
 | |
| -+	int			corner_count;
 | |
| -+	struct cprh_corner_band *corner_band;
 | |
| -+	struct cpr4_reg_data    *cpr4_regulator_data;
 | |
| -+	struct cpr3_reg_data    *cpr3_regulator_data;
 | |
| -+	u32			corner_band_count;
 | |
| -+
 | |
| -+	void			*platform_fuses;
 | |
| -+	int			speed_bin_fuse;
 | |
| -+	int			speed_bins_supported;
 | |
| -+	int			cpr_rev_fuse;
 | |
| -+	int			part_type;
 | |
| -+	int			part_type_supported;
 | |
| -+	int			fuse_combo;
 | |
| -+	int			fuse_combos_supported;
 | |
| -+	int			fuse_corner_count;
 | |
| -+	int			*fuse_corner_map;
 | |
| -+	int			fuse_combo_corner_sum;
 | |
| -+	int			fuse_combo_offset;
 | |
| -+	int			speed_bin_corner_sum;
 | |
| -+	int			speed_bin_offset;
 | |
| -+	int			fuse_combo_corner_band_sum;
 | |
| -+	int			fuse_combo_corner_band_offset;
 | |
| -+	int			speed_bin_corner_band_sum;
 | |
| -+	int			speed_bin_corner_band_offset;
 | |
| -+	u32			pd_bypass_mask;
 | |
| -+	int			dynamic_floor_corner;
 | |
| -+	bool			uses_dynamic_floor;
 | |
| -+
 | |
| -+	int			current_corner;
 | |
| -+	int			last_closed_loop_corner;
 | |
| -+	bool			aggregated;
 | |
| -+	int			debug_corner;
 | |
| -+	bool			vreg_enabled;
 | |
| -+
 | |
| -+	bool			aging_allowed;
 | |
| -+	bool			aging_allow_open_loop_adj;
 | |
| -+	int			aging_corner;
 | |
| -+	int			aging_max_adjust_volt;
 | |
| -+
 | |
| -+	bool			allow_core_count_adj;
 | |
| -+	bool			allow_temp_adj;
 | |
| -+	int			max_core_count;
 | |
| -+	bool			allow_boost;
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr3_thread - CPR3 hardware thread data structure
 | |
| -+ * @thread_id:		Hardware thread ID
 | |
| -+ * @of_node:		Device node associated with the device tree child node
 | |
| -+ *			of this CPR3 thread
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller which manages this thread
 | |
| -+ * @vreg:		Array of CPR3 regulators handled by the CPR3 thread
 | |
| -+ * @vreg_count:		Number of elements in the vreg array
 | |
| -+ * @aggr_corner:	CPR corner containing the in process aggregated voltage
 | |
| -+ *			and target quotient configurations which will be applied
 | |
| -+ * @last_closed_loop_aggr_corner: CPR corner containing the most recent
 | |
| -+ *			configurations which were written into hardware
 | |
| -+ *			registers when operating in closed loop mode (i.e. with
 | |
| -+ *			CPR enabled)
 | |
| -+ * @consecutive_up:	The number of consecutive CPR step up events needed to
 | |
| -+ *			to trigger an up interrupt
 | |
| -+ * @consecutive_down:	The number of consecutive CPR step down events needed to
 | |
| -+ *			to trigger a down interrupt
 | |
| -+ * @up_threshold:	The number CPR error steps required to generate an up
 | |
| -+ *			event
 | |
| -+ * @down_threshold:	The number CPR error steps required to generate a down
 | |
| -+ *			event
 | |
| -+ *
 | |
| -+ * This structure contains both configuration and runtime state data.  The
 | |
| -+ * elements aggr_corner and last_closed_loop_aggr_corner are state variables.
 | |
| -+ */
 | |
| -+struct cpr3_thread {
 | |
| -+	u32			thread_id;
 | |
| -+	struct device_node	*of_node;
 | |
| -+	struct cpr3_controller	*ctrl;
 | |
| -+	struct cpr3_regulator	*vreg;
 | |
| -+	int			vreg_count;
 | |
| -+	struct cpr3_corner	aggr_corner;
 | |
| -+	struct cpr3_corner	last_closed_loop_aggr_corner;
 | |
| -+
 | |
| -+	u32			consecutive_up;
 | |
| -+	u32			consecutive_down;
 | |
| -+	u32			up_threshold;
 | |
| -+	u32			down_threshold;
 | |
| -+};
 | |
| -+
 | |
| -+/* Per CPR controller data */
 | |
| -+/**
 | |
| -+ * enum cpr3_mem_acc_corners - Constants which define the number of mem-acc
 | |
| -+ *		regulator corners available in the mem-acc corner map array.
 | |
| -+ * %CPR3_MEM_ACC_LOW_CORNER:	Index in mem-acc corner map array mapping to the
 | |
| -+ *				mem-acc regulator corner
 | |
| -+ *				to be used for low voltage vdd supply
 | |
| -+ * %CPR3_MEM_ACC_HIGH_CORNER:	Index in mem-acc corner map array mapping to the
 | |
| -+ *				mem-acc regulator corner to be used for high
 | |
| -+ *				voltage vdd supply
 | |
| -+ * %CPR3_MEM_ACC_CORNERS:	Number of elements in the mem-acc corner map
 | |
| -+ *				array
 | |
| -+ */
 | |
| -+enum cpr3_mem_acc_corners {
 | |
| -+	CPR3_MEM_ACC_LOW_CORNER		= 0,
 | |
| -+	CPR3_MEM_ACC_HIGH_CORNER	= 1,
 | |
| -+	CPR3_MEM_ACC_CORNERS		= 2,
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * enum cpr3_count_mode - CPR3 controller count mode which defines the
 | |
| -+ *		method that CPR sensor data is acquired
 | |
| -+ * %CPR3_COUNT_MODE_ALL_AT_ONCE_MIN:	Capture all CPR sensor readings
 | |
| -+ *					simultaneously and report the minimum
 | |
| -+ *					value seen in successive measurements
 | |
| -+ * %CPR3_COUNT_MODE_ALL_AT_ONCE_MAX:	Capture all CPR sensor readings
 | |
| -+ *					simultaneously and report the maximum
 | |
| -+ *					value seen in successive measurements
 | |
| -+ * %CPR3_COUNT_MODE_STAGGERED:		Read one sensor at a time in a
 | |
| -+ *					sequential fashion
 | |
| -+ * %CPR3_COUNT_MODE_ALL_AT_ONCE_AGE:	Capture all CPR aging sensor readings
 | |
| -+ *					simultaneously.
 | |
| -+ */
 | |
| -+enum cpr3_count_mode {
 | |
| -+	CPR3_COUNT_MODE_ALL_AT_ONCE_MIN	= 0,
 | |
| -+	CPR3_COUNT_MODE_ALL_AT_ONCE_MAX	= 1,
 | |
| -+	CPR3_COUNT_MODE_STAGGERED	= 2,
 | |
| -+	CPR3_COUNT_MODE_ALL_AT_ONCE_AGE	= 3,
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * enum cpr_controller_type - supported CPR controller hardware types
 | |
| -+ * %CPR_CTRL_TYPE_CPR3:	HW has CPR3 controller
 | |
| -+ * %CPR_CTRL_TYPE_CPR4:	HW has CPR4 controller
 | |
| -+ */
 | |
| -+enum cpr_controller_type {
 | |
| -+	CPR_CTRL_TYPE_CPR3,
 | |
| -+	CPR_CTRL_TYPE_CPR4,
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr_setting - supported CPR global settings
 | |
| -+ * %CPR_DEFAULT: default mode from dts will be used
 | |
| -+ * %CPR_DISABLED: ceiling voltage will be used for all the corners
 | |
| -+ * %CPR_OPEN_LOOP_EN: CPR will work in OL
 | |
| -+ * %CPR_CLOSED_LOOP_EN: CPR will work in CL, if supported
 | |
| -+ */
 | |
| -+enum cpr_setting {
 | |
| -+	CPR_DEFAULT		= 0,
 | |
| -+	CPR_DISABLED		= 1,
 | |
| -+	CPR_OPEN_LOOP_EN	= 2,
 | |
| -+	CPR_CLOSED_LOOP_EN	= 3,
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr3_aging_sensor_info - CPR3 aging sensor information
 | |
| -+ * @sensor_id		The index of the CPR3 sensor to be used in the aging
 | |
| -+ *			measurement.
 | |
| -+ * @ro_scale		The CPR ring oscillator (RO) scaling factor for the
 | |
| -+ *			aging sensor with units of QUOT/V.
 | |
| -+ * @init_quot_diff:	The fused quotient difference between aged and un-aged
 | |
| -+ *			paths that was measured at manufacturing time.
 | |
| -+ * @measured_quot_diff: The quotient difference measured at runtime.
 | |
| -+ * @bypass_mask:	Bit mask of the CPR sensors that must be bypassed during
 | |
| -+ *			the aging measurement for this sensor
 | |
| -+ *
 | |
| -+ * This structure contains both configuration and runtime state data.  The
 | |
| -+ * element measured_quot_diff is a state variable.
 | |
| -+ */
 | |
| -+struct cpr3_aging_sensor_info {
 | |
| -+	u32			sensor_id;
 | |
| -+	u32			ro_scale;
 | |
| -+	int			init_quot_diff;
 | |
| -+	int			measured_quot_diff;
 | |
| -+	u32			bypass_mask[CPR3_MAX_SENSOR_COUNT / 32];
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr3_reg_info - Register information data structure
 | |
| -+ * @name:	Register name
 | |
| -+ * @addr:	Register physical address
 | |
| -+ * @value:	Register content
 | |
| -+ * @virt_addr:	Register virtual address
 | |
| -+ *
 | |
| -+ * This data structure is used to dump some critical register contents
 | |
| -+ * when the device crashes due to a kernel panic.
 | |
| -+ */
 | |
| -+struct cpr3_reg_info {
 | |
| -+	const char	*name;
 | |
| -+	u32		addr;
 | |
| -+	u32		value;
 | |
| -+	void __iomem	*virt_addr;
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr3_panic_regs_info - Data structure to dump critical register
 | |
| -+ *		contents.
 | |
| -+ * @reg_count:		Number of elements in the regs array
 | |
| -+ * @regs:		Array of critical registers information
 | |
| -+ *
 | |
| -+ * This data structure is used to dump critical register contents when
 | |
| -+ * the device crashes due to a kernel panic.
 | |
| -+ */
 | |
| -+struct cpr3_panic_regs_info {
 | |
| -+	int			reg_count;
 | |
| -+	struct cpr3_reg_info	*regs;
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr3_controller - CPR3 controller data structure
 | |
| -+ * @dev:		Device pointer for the CPR3 controller device
 | |
| -+ * @name:		Unique name for the CPR3 controller
 | |
| -+ * @ctrl_id:		Controller ID corresponding to the VDD supply number
 | |
| -+ *			that this CPR3 controller manages.
 | |
| -+ * @cpr_ctrl_base:	Virtual address of the CPR3 controller base register
 | |
| -+ * @fuse_base:		Virtual address of fuse row 0
 | |
| -+ * @aging_possible_reg:	Virtual address of an optional platform-specific
 | |
| -+ *			register that must be ready to determine if it is
 | |
| -+ *			possible to perform an aging measurement.
 | |
| -+ * @list:		list head used in a global cpr3-regulator list so that
 | |
| -+ *			cpr3-regulator structs can be found easily in RAM dumps
 | |
| -+ * @thread:		Array of CPR3 threads managed by the CPR3 controller
 | |
| -+ * @thread_count:	Number of elements in the thread array
 | |
| -+ * @sensor_owner:	Array of thread IDs indicating which thread owns a given
 | |
| -+ *			CPR sensor
 | |
| -+ * @sensor_count:	The number of CPR sensors found on the CPR loop managed
 | |
| -+ *			by this CPR controller.  Must be equal to the number of
 | |
| -+ *			elements in the sensor_owner array
 | |
| -+ * @soc_revision:	Revision number of the SoC.  This may be unused by
 | |
| -+ *			platforms that do not have different behavior for
 | |
| -+ *			different SoC revisions.
 | |
| -+ * @lock:		Mutex lock used to ensure mutual exclusion between
 | |
| -+ *			all of the threads associated with the controller
 | |
| -+ * @vdd_regulator:	Pointer to the VDD supply regulator which this CPR3
 | |
| -+ *			controller manages
 | |
| -+ * @system_regulator:	Pointer to the optional system-supply regulator upon
 | |
| -+ *			which the VDD supply regulator depends.
 | |
| -+ * @mem_acc_regulator:	Pointer to the optional mem-acc supply regulator used
 | |
| -+ *			to manage memory circuitry settings based upon the
 | |
| -+ *			VDD supply output voltage.
 | |
| -+ * @vdd_limit_regulator: Pointer to the VDD supply limit regulator which is used
 | |
| -+ *			for hardware closed-loop in order specify ceiling and
 | |
| -+ *			floor voltage limits (platform specific)
 | |
| -+ * @system_supply_max_volt: Voltage in microvolts which corresponds to the
 | |
| -+ *			absolute ceiling voltage of the system-supply
 | |
| -+ * @mem_acc_threshold_volt: mem-acc threshold voltage in microvolts
 | |
| -+ * @mem_acc_corner_map: mem-acc regulator corners mapping to low and high
 | |
| -+ *			voltage mem-acc settings for the memories powered by
 | |
| -+ *			this CPR3 controller and its associated CPR3 regulators
 | |
| -+ * @mem_acc_crossover_volt: Voltage in microvolts corresponding to the voltage
 | |
| -+ *			that the VDD supply must be set to while a MEM ACC
 | |
| -+ *			switch is in progress. This element must be initialized
 | |
| -+ *			for CPRh controllers when a MEM ACC threshold voltage is
 | |
| -+ *			defined.
 | |
| -+ * @core_clk:		Pointer to the CPR3 controller core clock
 | |
| -+ * @iface_clk:		Pointer to the CPR3 interface clock (platform specific)
 | |
| -+ * @bus_clk:		Pointer to the CPR3 bus clock (platform specific)
 | |
| -+ * @irq:		CPR interrupt number
 | |
| -+ * @irq_affinity_mask:	The cpumask for the CPUs which the CPR interrupt should
 | |
| -+ *			have affinity for
 | |
| -+ * @cpu_hotplug_notifier: CPU hotplug notifier used to reset IRQ affinity when a
 | |
| -+ *			CPU is brought back online
 | |
| -+ * @ceiling_irq:	Interrupt number for the interrupt that is triggered
 | |
| -+ *			when hardware closed-loop attempts to exceed the ceiling
 | |
| -+ *			voltage
 | |
| -+ * @apm:		Handle to the array power mux (APM)
 | |
| -+ * @apm_threshold_volt:	Voltage in microvolts which defines the threshold
 | |
| -+ *			voltage to determine the APM supply selection for
 | |
| -+ *			each corner
 | |
| -+ * @apm_crossover_volt:	Voltage in microvolts corresponding to the voltage that
 | |
| -+ *			the VDD supply must be set to while an APM switch is in
 | |
| -+ *			progress. This element must be initialized for CPRh
 | |
| -+ *			controllers when an APM threshold voltage is defined
 | |
| -+ * @apm_adj_volt:	Minimum difference between APM threshold voltage and
 | |
| -+ *			open-loop voltage which allows the APM threshold voltage
 | |
| -+ *			to be used as a ceiling
 | |
| -+ * @apm_high_supply:	APM supply to configure if VDD voltage is greater than
 | |
| -+ *			or equal to the APM threshold voltage
 | |
| -+ * @apm_low_supply:	APM supply to configure if the VDD voltage is less than
 | |
| -+ *			the APM threshold voltage
 | |
| -+ * @base_volt:		Minimum voltage in microvolts supported by the VDD
 | |
| -+ *			supply managed by this CPR controller
 | |
| -+ * @corner_switch_delay_time: The delay time in nanoseconds used by the CPR
 | |
| -+ *			controller to wait for voltage settling before
 | |
| -+ *			acknowledging the OSM block after corner changes
 | |
| -+ * @cpr_clock_rate:	CPR reference clock frequency in Hz.
 | |
| -+ * @sensor_time:	The time in nanoseconds that each sensor takes to
 | |
| -+ *			perform a measurement.
 | |
| -+ * @loop_time:		The time in nanoseconds between consecutive CPR
 | |
| -+ *			measurements.
 | |
| -+ * @up_down_delay_time: The time to delay in nanoseconds between consecutive CPR
 | |
| -+ *			measurements when the last measurement recommended
 | |
| -+ *			increasing or decreasing the vdd-supply voltage.
 | |
| -+ *			(platform specific)
 | |
| -+ * @idle_clocks:	Number of CPR reference clock ticks that the CPR
 | |
| -+ *			controller waits in transitional states.
 | |
| -+ * @step_quot_init_min:	The default minimum CPR step quotient value.  The step
 | |
| -+ *			quotient is the number of additional ring oscillator
 | |
| -+ *			ticks observed when increasing one step in vdd-supply
 | |
| -+ *			output voltage.
 | |
| -+ * @step_quot_init_max:	The default maximum CPR step quotient value.
 | |
| -+ * @step_volt:		Step size in microvolts between available set points
 | |
| -+ *			of the VDD supply
 | |
| -+ * @down_error_step_limit: CPR4 hardware closed-loop down error step limit which
 | |
| -+ *			defines the maximum number of VDD supply regulator steps
 | |
| -+ *			that the voltage may be reduced as the result of a
 | |
| -+ *			single CPR measurement.
 | |
| -+ * @up_error_step_limit: CPR4 hardware closed-loop up error step limit which
 | |
| -+ *			defines the maximum number of VDD supply regulator steps
 | |
| -+ *			that the voltage may be increased as the result of a
 | |
| -+ *			single CPR measurement.
 | |
| -+ * @count_mode:		CPR controller count mode
 | |
| -+ * @count_repeat:	Number of times to perform consecutive sensor
 | |
| -+ *			measurements when using all-at-once count modes.
 | |
| -+ * @proc_clock_throttle: Defines the processor clock frequency throttling
 | |
| -+ *			register value to use.  This can be used to reduce the
 | |
| -+ *			clock frequency when a power domain exits a low power
 | |
| -+ *			mode until CPR settles at a new voltage.
 | |
| -+ *			(platform specific)
 | |
| -+ * @cpr_allowed_hw:	Boolean which indicates if closed-loop CPR operation is
 | |
| -+ *			permitted for a given chip based upon hardware fuse
 | |
| -+ *			values
 | |
| -+ * @cpr_allowed_sw:	Boolean which indicates if closed-loop CPR operation is
 | |
| -+ *			permitted based upon software policies
 | |
| -+ * @supports_hw_closed_loop: Boolean which indicates if this CPR3/4 controller
 | |
| -+ *			physically supports hardware closed-loop CPR operation
 | |
| -+ * @use_hw_closed_loop:	Boolean which indicates that this controller will be
 | |
| -+ *			using hardware closed-loop operation in place of
 | |
| -+ *			software closed-loop operation.
 | |
| -+ * @ctrl_type:		CPR controller type
 | |
| -+ * @saw_use_unit_mV:	Boolean which indicates the unit used in SAW PVC
 | |
| -+ *			interface is mV.
 | |
| -+ * @aggr_corner:	CPR corner containing the most recently aggregated
 | |
| -+ *			voltage configurations which are being used currently
 | |
| -+ * @cpr_enabled:	Boolean which indicates that the CPR controller is
 | |
| -+ *			enabled and operating in closed-loop mode.  CPR clocks
 | |
| -+ *			have been prepared and enabled whenever this flag is
 | |
| -+ *			true.
 | |
| -+ * @last_corner_was_closed_loop: Boolean indicating if the last known corners
 | |
| -+ *			were updated during closed loop operation.
 | |
| -+ * @cpr_suspended:	Boolean which indicates that CPR has been temporarily
 | |
| -+ *			disabled while enterring system suspend.
 | |
| -+ * @debugfs:		Pointer to the debugfs directory of this CPR3 controller
 | |
| -+ * @aging_ref_volt:	Reference voltage in microvolts to configure when
 | |
| -+ *			performing CPR aging measurements.
 | |
| -+ * @aging_vdd_mode:	vdd-supply regulator mode to configure before performing
 | |
| -+ *			a CPR aging measurement.  It should be one of
 | |
| -+ *			REGULATOR_MODE_*.
 | |
| -+ * @aging_complete_vdd_mode: vdd-supply regulator mode to configure after
 | |
| -+ *			performing a CPR aging measurement.  It should be one of
 | |
| -+ *			REGULATOR_MODE_*.
 | |
| -+ * @aging_ref_adjust_volt: The reference aging voltage margin in microvolts that
 | |
| -+ *			should be added to the target quotients of the
 | |
| -+ *			regulators managed by this controller after derating.
 | |
| -+ * @aging_required:	Flag which indicates that a CPR aging measurement still
 | |
| -+ *			needs to be performed for this CPR3 controller.
 | |
| -+ * @aging_succeeded:	Flag which indicates that a CPR aging measurement has
 | |
| -+ *			completed successfully.
 | |
| -+ * @aging_failed:	Flag which indicates that a CPR aging measurement has
 | |
| -+ *			failed to complete successfully.
 | |
| -+ * @aging_sensor:	Array of CPR3 aging sensors which are used to perform
 | |
| -+ *			aging measurements at a runtime.
 | |
| -+ * @aging_sensor_count:	Number of elements in the aging_sensor array
 | |
| -+ * @aging_possible_mask: Optional bitmask used to mask off the
 | |
| -+ *			aging_possible_reg register.
 | |
| -+ * @aging_possible_val:	Optional value that the masked aging_possible_reg
 | |
| -+ *			register must have in order for a CPR aging measurement
 | |
| -+ *			to be possible.
 | |
| -+ * @step_quot_fixed:	Fixed step quotient value used for target quotient
 | |
| -+ *			adjustment if use_dynamic_step_quot is not set.
 | |
| -+ *			This parameter is only relevant for CPR4 controllers
 | |
| -+ *			when using the per-online-core or per-temperature
 | |
| -+ *			adjustments.
 | |
| -+ * @initial_temp_band:	Temperature band used for calculation of base-line
 | |
| -+ *			target quotients (fused).
 | |
| -+ * @use_dynamic_step_quot: Boolean value which indicates that margin adjustment
 | |
| -+ *			of target quotient will be based on the step quotient
 | |
| -+ *			calculated dynamically in hardware for each RO.
 | |
| -+ * @allow_core_count_adj: Core count adjustments are allowed for this controller
 | |
| -+ * @allow_temp_adj:	Temperature based adjustments are allowed for
 | |
| -+ *			this controller
 | |
| -+ * @allow_boost:	Voltage boost allowed for this controller.
 | |
| -+ * @temp_band_count:	Number of temperature bands used for temperature based
 | |
| -+ *			adjustment logic
 | |
| -+ * @temp_points:	Array of temperature points in decidegrees Celsius used
 | |
| -+ *			to specify the ranges for selected temperature bands.
 | |
| -+ *			The array must have (temp_band_count - 1) elements
 | |
| -+ *			allocated.
 | |
| -+ * @temp_sensor_id_start: Start ID of temperature sensors used for temperature
 | |
| -+ *			based adjustments.
 | |
| -+ * @temp_sensor_id_end:	End ID of temperature sensors used for temperature
 | |
| -+ *			based adjustments.
 | |
| -+ * @voltage_settling_time: The time in nanoseconds that it takes for the
 | |
| -+ *			VDD supply voltage to settle after being increased or
 | |
| -+ *			decreased by step_volt microvolts which is used when
 | |
| -+ *			SDELTA voltage margin adjustments are applied.
 | |
| -+ * @cpr_global_setting:	Global setting for this CPR controller
 | |
| -+ * @panic_regs_info:	Array of panic registers information which provides the
 | |
| -+ *			list of registers to dump when the device crashes.
 | |
| -+ * @panic_notifier:	Notifier block registered to global panic notifier list.
 | |
| -+ *
 | |
| -+ * This structure contains both configuration and runtime state data.  The
 | |
| -+ * elements cpr_allowed_sw, use_hw_closed_loop, aggr_corner, cpr_enabled,
 | |
| -+ * last_corner_was_closed_loop, cpr_suspended, aging_ref_adjust_volt,
 | |
| -+ * aging_required, aging_succeeded, and aging_failed are state variables.
 | |
| -+ *
 | |
| -+ * The apm* elements do not need to be initialized if the VDD supply managed by
 | |
| -+ * the CPR3 controller does not utilize an APM.
 | |
| -+ *
 | |
| -+ * The elements step_quot_fixed, initial_temp_band, allow_core_count_adj,
 | |
| -+ * allow_temp_adj and temp* need to be initialized for CPR4 controllers which
 | |
| -+ * are using per-online-core or per-temperature adjustments.
 | |
| -+ */
 | |
| -+struct cpr3_controller {
 | |
| -+	struct device		*dev;
 | |
| -+	const char		*name;
 | |
| -+	int			ctrl_id;
 | |
| -+	void __iomem		*cpr_ctrl_base;
 | |
| -+	void __iomem		*fuse_base;
 | |
| -+	void __iomem		*aging_possible_reg;
 | |
| -+	struct list_head	list;
 | |
| -+	struct cpr3_thread	*thread;
 | |
| -+	int			thread_count;
 | |
| -+	u8			*sensor_owner;
 | |
| -+	int			sensor_count;
 | |
| -+	int			soc_revision;
 | |
| -+	struct mutex		lock;
 | |
| -+	struct regulator	*vdd_regulator;
 | |
| -+	struct regulator	*system_regulator;
 | |
| -+	struct regulator	*mem_acc_regulator;
 | |
| -+	struct regulator	*vdd_limit_regulator;
 | |
| -+	int			system_supply_max_volt;
 | |
| -+	int			mem_acc_threshold_volt;
 | |
| -+	int			mem_acc_corner_map[CPR3_MEM_ACC_CORNERS];
 | |
| -+	int			mem_acc_crossover_volt;
 | |
| -+	struct clk		*core_clk;
 | |
| -+	struct clk		*iface_clk;
 | |
| -+	struct clk		*bus_clk;
 | |
| -+	int			irq;
 | |
| -+	struct cpumask		irq_affinity_mask;
 | |
| -+	struct notifier_block	cpu_hotplug_notifier;
 | |
| -+	int			ceiling_irq;
 | |
| -+	struct msm_apm_ctrl_dev *apm;
 | |
| -+	int			apm_threshold_volt;
 | |
| -+	int			apm_crossover_volt;
 | |
| -+	int			apm_adj_volt;
 | |
| -+	enum msm_apm_supply	apm_high_supply;
 | |
| -+	enum msm_apm_supply	apm_low_supply;
 | |
| -+	int			base_volt;
 | |
| -+	u32			corner_switch_delay_time;
 | |
| -+	u32			cpr_clock_rate;
 | |
| -+	u32			sensor_time;
 | |
| -+	u32			loop_time;
 | |
| -+	u32			up_down_delay_time;
 | |
| -+	u32			idle_clocks;
 | |
| -+	u32			step_quot_init_min;
 | |
| -+	u32			step_quot_init_max;
 | |
| -+	int			step_volt;
 | |
| -+	u32			down_error_step_limit;
 | |
| -+	u32			up_error_step_limit;
 | |
| -+	enum cpr3_count_mode	count_mode;
 | |
| -+	u32			count_repeat;
 | |
| -+	u32			proc_clock_throttle;
 | |
| -+	bool			cpr_allowed_hw;
 | |
| -+	bool			cpr_allowed_sw;
 | |
| -+	bool			supports_hw_closed_loop;
 | |
| -+	bool			use_hw_closed_loop;
 | |
| -+	enum cpr_controller_type ctrl_type;
 | |
| -+	bool			saw_use_unit_mV;
 | |
| -+	struct cpr3_corner	aggr_corner;
 | |
| -+	bool			cpr_enabled;
 | |
| -+	bool			last_corner_was_closed_loop;
 | |
| -+	bool			cpr_suspended;
 | |
| -+	struct dentry		*debugfs;
 | |
| -+
 | |
| -+	int			aging_ref_volt;
 | |
| -+	unsigned int		aging_vdd_mode;
 | |
| -+	unsigned int		aging_complete_vdd_mode;
 | |
| -+	int			aging_ref_adjust_volt;
 | |
| -+	bool			aging_required;
 | |
| -+	bool			aging_succeeded;
 | |
| -+	bool			aging_failed;
 | |
| -+	struct cpr3_aging_sensor_info *aging_sensor;
 | |
| -+	int			aging_sensor_count;
 | |
| -+	u32			cur_sensor_state;
 | |
| -+	u32			aging_possible_mask;
 | |
| -+	u32			aging_possible_val;
 | |
| -+
 | |
| -+	u32			step_quot_fixed;
 | |
| -+	u32			initial_temp_band;
 | |
| -+	bool			use_dynamic_step_quot;
 | |
| -+	bool			allow_core_count_adj;
 | |
| -+	bool			allow_temp_adj;
 | |
| -+	bool			allow_boost;
 | |
| -+	int			temp_band_count;
 | |
| -+	int			*temp_points;
 | |
| -+	u32			temp_sensor_id_start;
 | |
| -+	u32			temp_sensor_id_end;
 | |
| -+	u32			voltage_settling_time;
 | |
| -+	enum cpr_setting	cpr_global_setting;
 | |
| -+	struct cpr3_panic_regs_info *panic_regs_info;
 | |
| -+	struct notifier_block	panic_notifier;
 | |
| -+};
 | |
| -+
 | |
| -+/* Used for rounding voltages to the closest physically available set point. */
 | |
| -+#define CPR3_ROUND(n, d) (DIV_ROUND_UP(n, d) * (d))
 | |
| -+
 | |
| -+#define cpr3_err(cpr3_thread, message, ...) \
 | |
| -+	pr_err("%s: " message, (cpr3_thread)->name, ##__VA_ARGS__)
 | |
| -+#define cpr3_info(cpr3_thread, message, ...) \
 | |
| -+	pr_info("%s: " message, (cpr3_thread)->name, ##__VA_ARGS__)
 | |
| -+#define cpr3_debug(cpr3_thread, message, ...) \
 | |
| -+	pr_debug("%s: " message, (cpr3_thread)->name, ##__VA_ARGS__)
 | |
| -+
 | |
| -+/*
 | |
| -+ * Offset subtracted from voltage corner values passed in from the regulator
 | |
| -+ * framework in order to get internal voltage corner values.  This is needed
 | |
| -+ * since the regulator framework treats 0 as an error value at regulator
 | |
| -+ * registration time.
 | |
| -+ */
 | |
| -+#define CPR3_CORNER_OFFSET	1
 | |
| -+
 | |
| -+#ifdef CONFIG_REGULATOR_CPR3
 | |
| -+
 | |
| -+int cpr3_regulator_register(struct platform_device *pdev,
 | |
| -+			struct cpr3_controller *ctrl);
 | |
| -+int cpr3_open_loop_regulator_register(struct platform_device *pdev,
 | |
| -+				      struct cpr3_controller *ctrl);
 | |
| -+int cpr3_regulator_unregister(struct cpr3_controller *ctrl);
 | |
| -+int cpr3_open_loop_regulator_unregister(struct cpr3_controller *ctrl);
 | |
| -+int cpr3_regulator_suspend(struct cpr3_controller *ctrl);
 | |
| -+int cpr3_regulator_resume(struct cpr3_controller *ctrl);
 | |
| -+
 | |
| -+int cpr3_allocate_threads(struct cpr3_controller *ctrl, u32 min_thread_id,
 | |
| -+			u32 max_thread_id);
 | |
| -+int cpr3_map_fuse_base(struct cpr3_controller *ctrl,
 | |
| -+			struct platform_device *pdev);
 | |
| -+int cpr3_read_tcsr_setting(struct cpr3_controller *ctrl,
 | |
| -+			   struct platform_device *pdev, u8 start, u8 end);
 | |
| -+int cpr3_read_fuse_param(void __iomem *fuse_base_addr,
 | |
| -+			const struct cpr3_fuse_param *param, u64 *param_value);
 | |
| -+int cpr3_convert_open_loop_voltage_fuse(int ref_volt, int step_volt, u32 fuse,
 | |
| -+			int fuse_len);
 | |
| -+u64 cpr3_interpolate(u64 x1, u64 y1, u64 x2, u64 y2, u64 x);
 | |
| -+int cpr3_parse_array_property(struct cpr3_regulator *vreg,
 | |
| -+			const char *prop_name, int tuple_size, u32 *out);
 | |
| -+int cpr3_parse_corner_array_property(struct cpr3_regulator *vreg,
 | |
| -+			const char *prop_name, int tuple_size, u32 *out);
 | |
| -+int cpr3_parse_corner_band_array_property(struct cpr3_regulator *vreg,
 | |
| -+			const char *prop_name, int tuple_size, u32 *out);
 | |
| -+int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg);
 | |
| -+int cpr3_parse_thread_u32(struct cpr3_thread *thread, const char *propname,
 | |
| -+			u32 *out_value, u32 value_min, u32 value_max);
 | |
| -+int cpr3_parse_ctrl_u32(struct cpr3_controller *ctrl, const char *propname,
 | |
| -+			u32 *out_value, u32 value_min, u32 value_max);
 | |
| -+int cpr3_parse_common_thread_data(struct cpr3_thread *thread);
 | |
| -+int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl);
 | |
| -+int cpr3_parse_open_loop_common_ctrl_data(struct cpr3_controller *ctrl);
 | |
| -+int cpr3_limit_open_loop_voltages(struct cpr3_regulator *vreg);
 | |
| -+void cpr3_open_loop_voltage_as_ceiling(struct cpr3_regulator *vreg);
 | |
| -+int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg);
 | |
| -+void cpr3_print_quots(struct cpr3_regulator *vreg);
 | |
| -+int cpr3_determine_part_type(struct cpr3_regulator *vreg, int fuse_volt);
 | |
| -+int cpr3_determine_temp_base_open_loop_correction(struct cpr3_regulator *vreg,
 | |
| -+			int *fuse_volt);
 | |
| -+int cpr3_adjust_fused_open_loop_voltages(struct cpr3_regulator *vreg,
 | |
| -+			int *fuse_volt);
 | |
| -+int cpr3_adjust_open_loop_voltages(struct cpr3_regulator *vreg);
 | |
| -+int cpr3_quot_adjustment(int ro_scale, int volt_adjust);
 | |
| -+int cpr3_voltage_adjustment(int ro_scale, int quot_adjust);
 | |
| -+int cpr3_parse_closed_loop_voltage_adjustments(struct cpr3_regulator *vreg,
 | |
| -+			u64 *ro_sel, int *volt_adjust,
 | |
| -+			int *volt_adjust_fuse, int *ro_scale);
 | |
| -+int cpr4_parse_core_count_temp_voltage_adj(struct cpr3_regulator *vreg,
 | |
| -+			bool use_corner_band);
 | |
| -+int cpr3_apm_init(struct cpr3_controller *ctrl);
 | |
| -+int cpr3_mem_acc_init(struct cpr3_regulator *vreg);
 | |
| -+void cprh_adjust_voltages_for_apm(struct cpr3_regulator *vreg);
 | |
| -+void cprh_adjust_voltages_for_mem_acc(struct cpr3_regulator *vreg);
 | |
| -+int cpr3_adjust_target_quotients(struct cpr3_regulator *vreg,
 | |
| -+			int *fuse_volt_adjust);
 | |
| -+int cpr3_handle_temp_open_loop_adjustment(struct cpr3_controller *ctrl,
 | |
| -+			bool is_cold);
 | |
| -+int cpr3_get_cold_temp_threshold(struct cpr3_regulator *vreg, int *cold_temp);
 | |
| -+bool cpr3_can_adjust_cold_temp(struct cpr3_regulator *vreg);
 | |
| -+
 | |
| -+#else
 | |
| -+
 | |
| -+static inline int cpr3_regulator_register(struct platform_device *pdev,
 | |
| -+			struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	return -ENXIO;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int
 | |
| -+cpr3_open_loop_regulator_register(struct platform_device *pdev,
 | |
| -+				  struct cpr3_controller *ctrl);
 | |
| -+{
 | |
| -+	return -ENXIO;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_regulator_unregister(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	return -ENXIO;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int
 | |
| -+cpr3_open_loop_regulator_unregister(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	return -ENXIO;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_regulator_suspend(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	return -ENXIO;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_regulator_resume(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	return -ENXIO;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_get_thread_name(struct cpr3_thread *thread,
 | |
| -+			struct device_node *thread_node)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_allocate_threads(struct cpr3_controller *ctrl,
 | |
| -+			u32 min_thread_id, u32 max_thread_id)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_map_fuse_base(struct cpr3_controller *ctrl,
 | |
| -+			struct platform_device *pdev)
 | |
| -+{
 | |
| -+	return -ENXIO;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_read_tcsr_setting(struct cpr3_controller *ctrl,
 | |
| -+			   struct platform_device *pdev, u8 start, u8 end)
 | |
| -+{
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_read_fuse_param(void __iomem *fuse_base_addr,
 | |
| -+			const struct cpr3_fuse_param *param, u64 *param_value)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_convert_open_loop_voltage_fuse(int ref_volt,
 | |
| -+			int step_volt, u32 fuse, int fuse_len)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline u64 cpr3_interpolate(u64 x1, u64 y1, u64 x2, u64 y2, u64 x)
 | |
| -+{
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_parse_array_property(struct cpr3_regulator *vreg,
 | |
| -+			const char *prop_name, int tuple_size, u32 *out)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_parse_corner_array_property(struct cpr3_regulator *vreg,
 | |
| -+			const char *prop_name, int tuple_size, u32 *out)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_parse_corner_band_array_property(
 | |
| -+			struct cpr3_regulator *vreg, const char *prop_name,
 | |
| -+			int tuple_size, u32 *out)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_parse_thread_u32(struct cpr3_thread *thread,
 | |
| -+			const char *propname, u32 *out_value, u32 value_min,
 | |
| -+			u32 value_max)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_parse_ctrl_u32(struct cpr3_controller *ctrl,
 | |
| -+			const char *propname, u32 *out_value, u32 value_min,
 | |
| -+			u32 value_max)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_parse_common_thread_data(struct cpr3_thread *thread)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int
 | |
| -+cpr3_parse_open_loop_common_ctrl_data(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_limit_open_loop_voltages(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline void cpr3_open_loop_voltage_as_ceiling(
 | |
| -+			struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	return;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline void cpr3_print_quots(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	return;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int
 | |
| -+cpr3_determine_part_type(struct cpr3_regulator *vreg, int fuse_volt)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int
 | |
| -+cpr3_determine_temp_base_open_loop_correction(struct cpr3_regulator *vreg,
 | |
| -+			int *fuse_volt)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_adjust_fused_open_loop_voltages(
 | |
| -+			struct cpr3_regulator *vreg, int *fuse_volt)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_adjust_open_loop_voltages(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	return -EPERM;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_quot_adjustment(int ro_scale, int volt_adjust)
 | |
| -+{
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_voltage_adjustment(int ro_scale, int quot_adjust)
 | |
| -+{
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_parse_closed_loop_voltage_adjustments(
 | |
| -+			struct cpr3_regulator *vreg, u64 *ro_sel,
 | |
| -+			int *volt_adjust, int *volt_adjust_fuse, int *ro_scale)
 | |
| -+{
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr4_parse_core_count_temp_voltage_adj(
 | |
| -+			struct cpr3_regulator *vreg, bool use_corner_band)
 | |
| -+{
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_apm_init(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_mem_acc_init(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static inline void cprh_adjust_voltages_for_apm(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+}
 | |
| -+
 | |
| -+static inline void cprh_adjust_voltages_for_mem_acc(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpr3_adjust_target_quotients(struct cpr3_regulator *vreg,
 | |
| -+			int *fuse_volt_adjust)
 | |
| -+{
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int
 | |
| -+cpr3_handle_temp_open_loop_adjustment(struct cpr3_controller *ctrl,
 | |
| -+			bool is_cold)
 | |
| -+{
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static inline bool
 | |
| -+cpr3_can_adjust_cold_temp(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	return false;
 | |
| -+}
 | |
| -+
 | |
| -+static inline int
 | |
| -+cpr3_get_cold_temp_threshold(struct cpr3_regulator *vreg, int *cold_temp)
 | |
| -+{
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+#endif /* CONFIG_REGULATOR_CPR3 */
 | |
| -+
 | |
| -+#endif /* __REGULATOR_CPR_REGULATOR_H__ */
 | |
| ---- /dev/null
 | |
| -+++ b/drivers/regulator/cpr3-util.c
 | |
| -@@ -0,0 +1,2750 @@
 | |
| -+/*
 | |
| -+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 | |
| -+ *
 | |
| -+ * This program is free software; you can redistribute it and/or modify
 | |
| -+ * it under the terms of the GNU General Public License version 2 and
 | |
| -+ * only version 2 as published by the Free Software Foundation.
 | |
| -+ *
 | |
| -+ * This program is distributed in the hope that it will be useful,
 | |
| -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| -+ * GNU General Public License for more details.
 | |
| -+ */
 | |
| -+
 | |
| -+/*
 | |
| -+ * This file contains utility functions to be used by platform specific CPR3
 | |
| -+ * regulator drivers.
 | |
| -+ */
 | |
| -+
 | |
| -+#define pr_fmt(fmt) "%s: " fmt, __func__
 | |
| -+
 | |
| -+#include <linux/cpumask.h>
 | |
| -+#include <linux/device.h>
 | |
| -+#include <linux/io.h>
 | |
| -+#include <linux/kernel.h>
 | |
| -+#include <linux/of.h>
 | |
| -+#include <linux/platform_device.h>
 | |
| -+#include <linux/slab.h>
 | |
| -+#include <linux/types.h>
 | |
| -+
 | |
| -+#include <soc/qcom/socinfo.h>
 | |
| -+
 | |
| -+#include "cpr3-regulator.h"
 | |
| -+
 | |
| -+#define BYTES_PER_FUSE_ROW		8
 | |
| -+#define MAX_FUSE_ROW_BIT		63
 | |
| -+
 | |
| -+#define CPR3_CONSECUTIVE_UP_DOWN_MIN	0
 | |
| -+#define CPR3_CONSECUTIVE_UP_DOWN_MAX	15
 | |
| -+#define CPR3_UP_DOWN_THRESHOLD_MIN	0
 | |
| -+#define CPR3_UP_DOWN_THRESHOLD_MAX	31
 | |
| -+#define CPR3_STEP_QUOT_MIN		0
 | |
| -+#define CPR3_STEP_QUOT_MAX		63
 | |
| -+#define CPR3_IDLE_CLOCKS_MIN		0
 | |
| -+#define CPR3_IDLE_CLOCKS_MAX		31
 | |
| -+
 | |
| -+/* This constant has units of uV/mV so 1000 corresponds to 100%. */
 | |
| -+#define CPR3_AGING_DERATE_UNITY		1000
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_allocate_regulators() - allocate and initialize CPR3 regulators for a
 | |
| -+ *		given thread based upon device tree data
 | |
| -+ * @thread:		Pointer to the CPR3 thread
 | |
| -+ *
 | |
| -+ * This function allocates the thread->vreg array based upon the number of
 | |
| -+ * device tree regulator subnodes.  It also initializes generic elements of each
 | |
| -+ * regulator struct such as name, of_node, and thread.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_allocate_regulators(struct cpr3_thread *thread)
 | |
| -+{
 | |
| -+	struct device_node *node;
 | |
| -+	int i, rc;
 | |
| -+
 | |
| -+	thread->vreg_count = 0;
 | |
| -+
 | |
| -+	for_each_available_child_of_node(thread->of_node, node) {
 | |
| -+		thread->vreg_count++;
 | |
| -+	}
 | |
| -+
 | |
| -+	thread->vreg = devm_kcalloc(thread->ctrl->dev, thread->vreg_count,
 | |
| -+			sizeof(*thread->vreg), GFP_KERNEL);
 | |
| -+	if (!thread->vreg)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	i = 0;
 | |
| -+	for_each_available_child_of_node(thread->of_node, node) {
 | |
| -+		thread->vreg[i].of_node = node;
 | |
| -+		thread->vreg[i].thread = thread;
 | |
| -+
 | |
| -+		rc = of_property_read_string(node, "regulator-name",
 | |
| -+						&thread->vreg[i].name);
 | |
| -+		if (rc) {
 | |
| -+			dev_err(thread->ctrl->dev, "could not find regulator name, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		i++;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_allocate_threads() - allocate and initialize CPR3 threads for a given
 | |
| -+ *			     controller based upon device tree data
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @min_thread_id:	Minimum allowed hardware thread ID for this controller
 | |
| -+ * @max_thread_id:	Maximum allowed hardware thread ID for this controller
 | |
| -+ *
 | |
| -+ * This function allocates the ctrl->thread array based upon the number of
 | |
| -+ * device tree thread subnodes.  It also initializes generic elements of each
 | |
| -+ * thread struct such as thread_id, of_node, ctrl, and vreg array.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_allocate_threads(struct cpr3_controller *ctrl, u32 min_thread_id,
 | |
| -+			u32 max_thread_id)
 | |
| -+{
 | |
| -+	struct device *dev = ctrl->dev;
 | |
| -+	struct device_node *thread_node;
 | |
| -+	int i, j, rc;
 | |
| -+
 | |
| -+	ctrl->thread_count = 0;
 | |
| -+
 | |
| -+	for_each_available_child_of_node(dev->of_node, thread_node) {
 | |
| -+		ctrl->thread_count++;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->thread = devm_kcalloc(dev, ctrl->thread_count,
 | |
| -+			sizeof(*ctrl->thread), GFP_KERNEL);
 | |
| -+	if (!ctrl->thread)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	i = 0;
 | |
| -+	for_each_available_child_of_node(dev->of_node, thread_node) {
 | |
| -+		ctrl->thread[i].of_node = thread_node;
 | |
| -+		ctrl->thread[i].ctrl = ctrl;
 | |
| -+
 | |
| -+		rc = of_property_read_u32(thread_node, "qcom,cpr-thread-id",
 | |
| -+					  &ctrl->thread[i].thread_id);
 | |
| -+		if (rc) {
 | |
| -+			dev_err(dev, "could not read DT property qcom,cpr-thread-id, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		if (ctrl->thread[i].thread_id < min_thread_id ||
 | |
| -+				ctrl->thread[i].thread_id > max_thread_id) {
 | |
| -+			dev_err(dev, "invalid thread id = %u; not within [%u, %u]\n",
 | |
| -+				ctrl->thread[i].thread_id, min_thread_id,
 | |
| -+				max_thread_id);
 | |
| -+			return -EINVAL;
 | |
| -+		}
 | |
| -+
 | |
| -+		/* Verify that the thread ID is unique for all child nodes. */
 | |
| -+		for (j = 0; j < i; j++) {
 | |
| -+			if (ctrl->thread[j].thread_id
 | |
| -+					== ctrl->thread[i].thread_id) {
 | |
| -+				dev_err(dev, "duplicate thread id = %u found\n",
 | |
| -+					ctrl->thread[i].thread_id);
 | |
| -+				return -EINVAL;
 | |
| -+			}
 | |
| -+		}
 | |
| -+
 | |
| -+		rc = cpr3_allocate_regulators(&ctrl->thread[i]);
 | |
| -+		if (rc)
 | |
| -+			return rc;
 | |
| -+
 | |
| -+		i++;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_map_fuse_base() - ioremap the base address of the fuse region
 | |
| -+ * @ctrl:	Pointer to the CPR3 controller
 | |
| -+ * @pdev:	Platform device pointer for the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_map_fuse_base(struct cpr3_controller *ctrl,
 | |
| -+			struct platform_device *pdev)
 | |
| -+{
 | |
| -+	struct resource *res;
 | |
| -+
 | |
| -+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fuse_base");
 | |
| -+	if (!res || !res->start) {
 | |
| -+		dev_err(&pdev->dev, "fuse base address is missing\n");
 | |
| -+		return -ENXIO;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->fuse_base = devm_ioremap(&pdev->dev, res->start,
 | |
| -+						resource_size(res));
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_read_tcsr_setting - reads the CPR setting bits from TCSR register
 | |
| -+ * @ctrl:	Pointer to the CPR3 controller
 | |
| -+ * @pdev:	Platform device pointer for the CPR3 controller
 | |
| -+ * @start:	start bit in TCSR register
 | |
| -+ * @end:	end bit in TCSR register
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_read_tcsr_setting(struct cpr3_controller *ctrl,
 | |
| -+			   struct platform_device *pdev, u8 start, u8 end)
 | |
| -+{
 | |
| -+	struct resource *res;
 | |
| -+	void __iomem *tcsr_reg;
 | |
| -+	u32 val;
 | |
| -+
 | |
| -+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 | |
| -+					   "cpr_tcsr_reg");
 | |
| -+	if (!res || !res->start)
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	tcsr_reg = ioremap(res->start, resource_size(res));
 | |
| -+	if (!tcsr_reg) {
 | |
| -+		dev_err(&pdev->dev, "tcsr ioremap failed\n");
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	val = readl_relaxed(tcsr_reg);
 | |
| -+	val &= GENMASK(end, start);
 | |
| -+	val >>= start;
 | |
| -+
 | |
| -+	switch (val) {
 | |
| -+	case 1:
 | |
| -+		ctrl->cpr_global_setting = CPR_DISABLED;
 | |
| -+		break;
 | |
| -+	case 2:
 | |
| -+		ctrl->cpr_global_setting = CPR_OPEN_LOOP_EN;
 | |
| -+		break;
 | |
| -+	case 3:
 | |
| -+		ctrl->cpr_global_setting = CPR_CLOSED_LOOP_EN;
 | |
| -+		break;
 | |
| -+	default:
 | |
| -+		ctrl->cpr_global_setting = CPR_DEFAULT;
 | |
| -+	}
 | |
| -+
 | |
| -+	iounmap(tcsr_reg);
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_read_fuse_param() - reads a CPR3 fuse parameter out of eFuses
 | |
| -+ * @fuse_base_addr:	Virtual memory address of the eFuse base address
 | |
| -+ * @param:		Null terminated array of fuse param segments to read
 | |
| -+ *			from
 | |
| -+ * @param_value:	Output with value read from the eFuses
 | |
| -+ *
 | |
| -+ * This function reads from each of the parameter segments listed in the param
 | |
| -+ * array and concatenates their values together.  Reading stops when an element
 | |
| -+ * is reached which has all 0 struct values.  The total number of bits specified
 | |
| -+ * for the fuse parameter across all segments must be less than or equal to 64.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_read_fuse_param(void __iomem *fuse_base_addr,
 | |
| -+		const struct cpr3_fuse_param *param, u64 *param_value)
 | |
| -+{
 | |
| -+	u64 fuse_val, val;
 | |
| -+	int bits;
 | |
| -+	int bits_total = 0;
 | |
| -+
 | |
| -+	*param_value = 0;
 | |
| -+
 | |
| -+	while (param->row || param->bit_start || param->bit_end) {
 | |
| -+		if (param->bit_start > param->bit_end
 | |
| -+		    || param->bit_end > MAX_FUSE_ROW_BIT) {
 | |
| -+			pr_err("Invalid fuse parameter segment: row=%u, start=%u, end=%u\n",
 | |
| -+				param->row, param->bit_start, param->bit_end);
 | |
| -+			return -EINVAL;
 | |
| -+		}
 | |
| -+
 | |
| -+		bits = param->bit_end - param->bit_start + 1;
 | |
| -+		if (bits_total + bits > 64) {
 | |
| -+			pr_err("Invalid fuse parameter segments; total bits = %d\n",
 | |
| -+				bits_total + bits);
 | |
| -+			return -EINVAL;
 | |
| -+		}
 | |
| -+
 | |
| -+		fuse_val = readq_relaxed(fuse_base_addr
 | |
| -+					 + param->row * BYTES_PER_FUSE_ROW);
 | |
| -+		val = (fuse_val >> param->bit_start) & ((1ULL << bits) - 1);
 | |
| -+		*param_value |= val << bits_total;
 | |
| -+		bits_total += bits;
 | |
| -+
 | |
| -+		param++;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_convert_open_loop_voltage_fuse() - converts an open loop voltage fuse
 | |
| -+ *		value into an absolute voltage with units of microvolts
 | |
| -+ * @ref_volt:		Reference voltage in microvolts
 | |
| -+ * @step_volt:		The step size in microvolts of the fuse LSB
 | |
| -+ * @fuse:		Open loop voltage fuse value
 | |
| -+ * @fuse_len:		The bit length of the fuse value
 | |
| -+ *
 | |
| -+ * The MSB of the fuse parameter corresponds to a sign bit.  If it is set, then
 | |
| -+ * the lower bits correspond to the number of steps to go down from the
 | |
| -+ * reference voltage.  If it is not set, then the lower bits correspond to the
 | |
| -+ * number of steps to go up from the reference voltage.
 | |
| -+ */
 | |
| -+int cpr3_convert_open_loop_voltage_fuse(int ref_volt, int step_volt, u32 fuse,
 | |
| -+					int fuse_len)
 | |
| -+{
 | |
| -+	int sign, steps;
 | |
| -+
 | |
| -+	sign = (fuse & (1 << (fuse_len - 1))) ? -1 : 1;
 | |
| -+	steps = fuse & ((1 << (fuse_len - 1)) - 1);
 | |
| -+
 | |
| -+	return ref_volt + sign * steps * step_volt;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_interpolate() - performs linear interpolation
 | |
| -+ * @x1		Lower known x value
 | |
| -+ * @y1		Lower known y value
 | |
| -+ * @x2		Upper known x value
 | |
| -+ * @y2		Upper known y value
 | |
| -+ * @x		Intermediate x value
 | |
| -+ *
 | |
| -+ * Returns y where (x, y) falls on the line between (x1, y1) and (x2, y2).
 | |
| -+ * It is required that x1 < x2, y1 <= y2, and x1 <= x <= x2.  If these
 | |
| -+ * conditions are not met, then y2 will be returned.
 | |
| -+ */
 | |
| -+u64 cpr3_interpolate(u64 x1, u64 y1, u64 x2, u64 y2, u64 x)
 | |
| -+{
 | |
| -+	u64 temp;
 | |
| -+
 | |
| -+	if (x1 >= x2 || y1 > y2 || x1 > x || x > x2)
 | |
| -+		return y2;
 | |
| -+
 | |
| -+	temp = (x2 - x) * (y2 - y1);
 | |
| -+	do_div(temp, (u32)(x2 - x1));
 | |
| -+
 | |
| -+	return y2 - temp;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_parse_array_property() - fill an array from a portion of the values
 | |
| -+ *		specified for a device tree property
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @prop_name:		The name of the device tree property to read from
 | |
| -+ * @tuple_size:		The number of elements in each tuple
 | |
| -+ * @out:		Output data array which must be of size tuple_size
 | |
| -+ *
 | |
| -+ * cpr3_parse_common_corner_data() must be called for vreg before this function
 | |
| -+ * is called so that fuse combo and speed bin size elements are initialized.
 | |
| -+ *
 | |
| -+ * Three formats are supported for the device tree property:
 | |
| -+ * 1. Length == tuple_size
 | |
| -+ *	(reading begins at index 0)
 | |
| -+ * 2. Length == tuple_size * vreg->fuse_combos_supported
 | |
| -+ *	(reading begins at index tuple_size * vreg->fuse_combo)
 | |
| -+ * 3. Length == tuple_size * vreg->speed_bins_supported
 | |
| -+ *	(reading begins at index tuple_size * vreg->speed_bin_fuse)
 | |
| -+ *
 | |
| -+ * All other property lengths are treated as errors.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_parse_array_property(struct cpr3_regulator *vreg,
 | |
| -+		const char *prop_name, int tuple_size, u32 *out)
 | |
| -+{
 | |
| -+	struct device_node *node = vreg->of_node;
 | |
| -+	int len = 0;
 | |
| -+	int i, offset, rc;
 | |
| -+
 | |
| -+	if (!of_find_property(node, prop_name, &len)) {
 | |
| -+		cpr3_err(vreg, "property %s is missing\n", prop_name);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (len == tuple_size * sizeof(u32)) {
 | |
| -+		offset = 0;
 | |
| -+	} else if (len == tuple_size * vreg->fuse_combos_supported
 | |
| -+				     * sizeof(u32)) {
 | |
| -+		offset = tuple_size * vreg->fuse_combo;
 | |
| -+	} else if (vreg->speed_bins_supported > 0 &&
 | |
| -+		 len == tuple_size * vreg->speed_bins_supported * sizeof(u32)) {
 | |
| -+		offset = tuple_size * vreg->speed_bin_fuse;
 | |
| -+	} else {
 | |
| -+		if (vreg->speed_bins_supported > 0)
 | |
| -+			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu, %zu, or %zu\n",
 | |
| -+				prop_name, len,
 | |
| -+				tuple_size * sizeof(u32),
 | |
| -+				tuple_size * vreg->speed_bins_supported
 | |
| -+					   * sizeof(u32),
 | |
| -+				tuple_size * vreg->fuse_combos_supported
 | |
| -+					   * sizeof(u32));
 | |
| -+		else
 | |
| -+			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu or %zu\n",
 | |
| -+				prop_name, len,
 | |
| -+				tuple_size * sizeof(u32),
 | |
| -+				tuple_size * vreg->fuse_combos_supported
 | |
| -+					   * sizeof(u32));
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < tuple_size; i++) {
 | |
| -+		rc = of_property_read_u32_index(node, prop_name, offset + i,
 | |
| -+						&out[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "error reading property %s, rc=%d\n",
 | |
| -+				prop_name, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_parse_corner_array_property() - fill a per-corner array from a portion
 | |
| -+ *		of the values specified for a device tree property
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @prop_name:		The name of the device tree property to read from
 | |
| -+ * @tuple_size:		The number of elements in each per-corner tuple
 | |
| -+ * @out:		Output data array which must be of size:
 | |
| -+ *			tuple_size * vreg->corner_count
 | |
| -+ *
 | |
| -+ * cpr3_parse_common_corner_data() must be called for vreg before this function
 | |
| -+ * is called so that fuse combo and speed bin size elements are initialized.
 | |
| -+ *
 | |
| -+ * Three formats are supported for the device tree property:
 | |
| -+ * 1. Length == tuple_size * vreg->corner_count
 | |
| -+ *	(reading begins at index 0)
 | |
| -+ * 2. Length == tuple_size * vreg->fuse_combo_corner_sum
 | |
| -+ *	(reading begins at index tuple_size * vreg->fuse_combo_offset)
 | |
| -+ * 3. Length == tuple_size * vreg->speed_bin_corner_sum
 | |
| -+ *	(reading begins at index tuple_size * vreg->speed_bin_offset)
 | |
| -+ *
 | |
| -+ * All other property lengths are treated as errors.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_parse_corner_array_property(struct cpr3_regulator *vreg,
 | |
| -+		const char *prop_name, int tuple_size, u32 *out)
 | |
| -+{
 | |
| -+	struct device_node *node = vreg->of_node;
 | |
| -+	int len = 0;
 | |
| -+	int i, offset, rc;
 | |
| -+
 | |
| -+	if (!of_find_property(node, prop_name, &len)) {
 | |
| -+		cpr3_err(vreg, "property %s is missing\n", prop_name);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (len == tuple_size * vreg->corner_count * sizeof(u32)) {
 | |
| -+		offset = 0;
 | |
| -+	} else if (len == tuple_size * vreg->fuse_combo_corner_sum
 | |
| -+				     * sizeof(u32)) {
 | |
| -+		offset = tuple_size * vreg->fuse_combo_offset;
 | |
| -+	} else if (vreg->speed_bin_corner_sum > 0 &&
 | |
| -+		 len == tuple_size * vreg->speed_bin_corner_sum * sizeof(u32)) {
 | |
| -+		offset = tuple_size * vreg->speed_bin_offset;
 | |
| -+	} else {
 | |
| -+		if (vreg->speed_bin_corner_sum > 0)
 | |
| -+			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu, %zu, or %zu\n",
 | |
| -+				prop_name, len,
 | |
| -+				tuple_size * vreg->corner_count * sizeof(u32),
 | |
| -+				tuple_size * vreg->speed_bin_corner_sum
 | |
| -+					   * sizeof(u32),
 | |
| -+				tuple_size * vreg->fuse_combo_corner_sum
 | |
| -+					   * sizeof(u32));
 | |
| -+		else
 | |
| -+			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu or %zu\n",
 | |
| -+				prop_name, len,
 | |
| -+				tuple_size * vreg->corner_count * sizeof(u32),
 | |
| -+				tuple_size * vreg->fuse_combo_corner_sum
 | |
| -+					   * sizeof(u32));
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < tuple_size * vreg->corner_count; i++) {
 | |
| -+		rc = of_property_read_u32_index(node, prop_name, offset + i,
 | |
| -+						&out[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "error reading property %s, rc=%d\n",
 | |
| -+				prop_name, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_parse_corner_band_array_property() - fill a per-corner band array
 | |
| -+ *		from a portion of the values specified for a device tree
 | |
| -+ *		property
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @prop_name:		The name of the device tree property to read from
 | |
| -+ * @tuple_size:		The number of elements in each per-corner band tuple
 | |
| -+ * @out:		Output data array which must be of size:
 | |
| -+ *			tuple_size * vreg->corner_band_count
 | |
| -+ *
 | |
| -+ * cpr3_parse_common_corner_data() must be called for vreg before this function
 | |
| -+ * is called so that fuse combo and speed bin size elements are initialized.
 | |
| -+ * In addition, corner band fuse combo and speed bin sum and offset elements
 | |
| -+ * must be initialized prior to executing this function.
 | |
| -+ *
 | |
| -+ * Three formats are supported for the device tree property:
 | |
| -+ * 1. Length == tuple_size * vreg->corner_band_count
 | |
| -+ *	(reading begins at index 0)
 | |
| -+ * 2. Length == tuple_size * vreg->fuse_combo_corner_band_sum
 | |
| -+ *	(reading begins at index tuple_size *
 | |
| -+ *		vreg->fuse_combo_corner_band_offset)
 | |
| -+ * 3. Length == tuple_size * vreg->speed_bin_corner_band_sum
 | |
| -+ *	(reading begins at index tuple_size *
 | |
| -+ *		vreg->speed_bin_corner_band_offset)
 | |
| -+ *
 | |
| -+ * All other property lengths are treated as errors.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_parse_corner_band_array_property(struct cpr3_regulator *vreg,
 | |
| -+		const char *prop_name, int tuple_size, u32 *out)
 | |
| -+{
 | |
| -+	struct device_node *node = vreg->of_node;
 | |
| -+	int len = 0;
 | |
| -+	int i, offset, rc;
 | |
| -+
 | |
| -+	if (!of_find_property(node, prop_name, &len)) {
 | |
| -+		cpr3_err(vreg, "property %s is missing\n", prop_name);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (len == tuple_size * vreg->corner_band_count * sizeof(u32)) {
 | |
| -+		offset = 0;
 | |
| -+	} else if (len == tuple_size * vreg->fuse_combo_corner_band_sum
 | |
| -+				     * sizeof(u32)) {
 | |
| -+		offset = tuple_size * vreg->fuse_combo_corner_band_offset;
 | |
| -+	} else if (vreg->speed_bin_corner_band_sum > 0 &&
 | |
| -+		 len == tuple_size * vreg->speed_bin_corner_band_sum *
 | |
| -+		   sizeof(u32)) {
 | |
| -+		offset = tuple_size * vreg->speed_bin_corner_band_offset;
 | |
| -+	} else {
 | |
| -+		if (vreg->speed_bin_corner_band_sum > 0)
 | |
| -+			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu, %zu, or %zu\n",
 | |
| -+				prop_name, len,
 | |
| -+				tuple_size * vreg->corner_band_count *
 | |
| -+				 sizeof(u32),
 | |
| -+				tuple_size * vreg->speed_bin_corner_band_sum
 | |
| -+					   * sizeof(u32),
 | |
| -+				tuple_size * vreg->fuse_combo_corner_band_sum
 | |
| -+					   * sizeof(u32));
 | |
| -+		else
 | |
| -+			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu or %zu\n",
 | |
| -+				prop_name, len,
 | |
| -+				tuple_size * vreg->corner_band_count *
 | |
| -+				 sizeof(u32),
 | |
| -+				tuple_size * vreg->fuse_combo_corner_band_sum
 | |
| -+					   * sizeof(u32));
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < tuple_size * vreg->corner_band_count; i++) {
 | |
| -+		rc = of_property_read_u32_index(node, prop_name, offset + i,
 | |
| -+						&out[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "error reading property %s, rc=%d\n",
 | |
| -+				prop_name, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_parse_common_corner_data() - parse common CPR3 properties relating to
 | |
| -+ *		the corners supported by a CPR3 regulator from device tree
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * This function reads, validates, and utilizes the following device tree
 | |
| -+ * properties: qcom,cpr-fuse-corners, qcom,cpr-fuse-combos, qcom,cpr-speed-bins,
 | |
| -+ * qcom,cpr-speed-bin-corners, qcom,cpr-corners, qcom,cpr-voltage-ceiling,
 | |
| -+ * qcom,cpr-voltage-floor, qcom,corner-frequencies,
 | |
| -+ * and qcom,cpr-corner-fmax-map.
 | |
| -+ *
 | |
| -+ * It initializes these CPR3 regulator elements: corner, corner_count,
 | |
| -+ * fuse_combos_supported, fuse_corner_map, and speed_bins_supported.  It
 | |
| -+ * initializes these elements for each corner: ceiling_volt, floor_volt,
 | |
| -+ * proc_freq, and cpr_fuse_corner.
 | |
| -+ *
 | |
| -+ * It requires that the following CPR3 regulator elements be initialized before
 | |
| -+ * being called: fuse_corner_count, fuse_combo, and speed_bin_fuse.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_parse_common_corner_data(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct device_node *node = vreg->of_node;
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	u32 max_fuse_combos, fuse_corners, aging_allowed = 0;
 | |
| -+	u32 max_speed_bins = 0;
 | |
| -+	u32 *combo_corners;
 | |
| -+	u32 *speed_bin_corners;
 | |
| -+	u32 *temp;
 | |
| -+	int i, j, rc;
 | |
| -+
 | |
| -+	rc = of_property_read_u32(node, "qcom,cpr-fuse-corners", &fuse_corners);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "error reading property qcom,cpr-fuse-corners, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (vreg->fuse_corner_count != fuse_corners) {
 | |
| -+		cpr3_err(vreg, "device tree config supports %d fuse corners but the hardware has %d fuse corners\n",
 | |
| -+			fuse_corners, vreg->fuse_corner_count);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = of_property_read_u32(node, "qcom,cpr-fuse-combos",
 | |
| -+				&max_fuse_combos);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "error reading property qcom,cpr-fuse-combos, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Sanity check against arbitrarily large value to avoid excessive
 | |
| -+	 * memory allocation.
 | |
| -+	 */
 | |
| -+	if (max_fuse_combos > 100 || max_fuse_combos == 0) {
 | |
| -+		cpr3_err(vreg, "qcom,cpr-fuse-combos is invalid: %u\n",
 | |
| -+			max_fuse_combos);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (vreg->fuse_combo >= max_fuse_combos) {
 | |
| -+		cpr3_err(vreg, "device tree config supports fuse combos 0-%u but the hardware has combo %d\n",
 | |
| -+			max_fuse_combos - 1, vreg->fuse_combo);
 | |
| -+		BUG_ON(1);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->fuse_combos_supported = max_fuse_combos;
 | |
| -+
 | |
| -+	of_property_read_u32(node, "qcom,cpr-speed-bins", &max_speed_bins);
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Sanity check against arbitrarily large value to avoid excessive
 | |
| -+	 * memory allocation.
 | |
| -+	 */
 | |
| -+	if (max_speed_bins > 100) {
 | |
| -+		cpr3_err(vreg, "qcom,cpr-speed-bins is invalid: %u\n",
 | |
| -+			max_speed_bins);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (max_speed_bins && vreg->speed_bin_fuse >= max_speed_bins) {
 | |
| -+		cpr3_err(vreg, "device tree config supports speed bins 0-%u but the hardware has speed bin %d\n",
 | |
| -+			max_speed_bins - 1, vreg->speed_bin_fuse);
 | |
| -+		BUG();
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->speed_bins_supported = max_speed_bins;
 | |
| -+
 | |
| -+	combo_corners = kcalloc(vreg->fuse_combos_supported,
 | |
| -+				sizeof(*combo_corners), GFP_KERNEL);
 | |
| -+	if (!combo_corners)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	rc = of_property_read_u32_array(node, "qcom,cpr-corners", combo_corners,
 | |
| -+					vreg->fuse_combos_supported);
 | |
| -+	if (rc == -EOVERFLOW) {
 | |
| -+		/* Single value case */
 | |
| -+		rc = of_property_read_u32(node, "qcom,cpr-corners",
 | |
| -+					combo_corners);
 | |
| -+		for (i = 1; i < vreg->fuse_combos_supported; i++)
 | |
| -+			combo_corners[i] = combo_corners[0];
 | |
| -+	}
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "error reading property qcom,cpr-corners, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		kfree(combo_corners);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->fuse_combo_offset = 0;
 | |
| -+	vreg->fuse_combo_corner_sum = 0;
 | |
| -+	for (i = 0; i < vreg->fuse_combos_supported; i++) {
 | |
| -+		vreg->fuse_combo_corner_sum += combo_corners[i];
 | |
| -+		if (i < vreg->fuse_combo)
 | |
| -+			vreg->fuse_combo_offset += combo_corners[i];
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->corner_count = combo_corners[vreg->fuse_combo];
 | |
| -+
 | |
| -+	kfree(combo_corners);
 | |
| -+
 | |
| -+	vreg->speed_bin_offset = 0;
 | |
| -+	vreg->speed_bin_corner_sum = 0;
 | |
| -+	if (vreg->speed_bins_supported > 0) {
 | |
| -+		speed_bin_corners = kcalloc(vreg->speed_bins_supported,
 | |
| -+					sizeof(*speed_bin_corners), GFP_KERNEL);
 | |
| -+		if (!speed_bin_corners)
 | |
| -+			return -ENOMEM;
 | |
| -+
 | |
| -+		rc = of_property_read_u32_array(node,
 | |
| -+				"qcom,cpr-speed-bin-corners", speed_bin_corners,
 | |
| -+				vreg->speed_bins_supported);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "error reading property qcom,cpr-speed-bin-corners, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			kfree(speed_bin_corners);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		for (i = 0; i < vreg->speed_bins_supported; i++) {
 | |
| -+			vreg->speed_bin_corner_sum += speed_bin_corners[i];
 | |
| -+			if (i < vreg->speed_bin_fuse)
 | |
| -+				vreg->speed_bin_offset += speed_bin_corners[i];
 | |
| -+		}
 | |
| -+
 | |
| -+		if (speed_bin_corners[vreg->speed_bin_fuse]
 | |
| -+		    != vreg->corner_count) {
 | |
| -+			cpr3_err(vreg, "qcom,cpr-corners and qcom,cpr-speed-bin-corners conflict on number of corners: %d vs %u\n",
 | |
| -+				vreg->corner_count,
 | |
| -+				speed_bin_corners[vreg->speed_bin_fuse]);
 | |
| -+			kfree(speed_bin_corners);
 | |
| -+			return -EINVAL;
 | |
| -+		}
 | |
| -+
 | |
| -+		kfree(speed_bin_corners);
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->corner = devm_kcalloc(ctrl->dev, vreg->corner_count,
 | |
| -+				    sizeof(*vreg->corner), GFP_KERNEL);
 | |
| -+	temp = kcalloc(vreg->corner_count, sizeof(*temp), GFP_KERNEL);
 | |
| -+	if (!vreg->corner || !temp)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-voltage-ceiling",
 | |
| -+			1, temp);
 | |
| -+	if (rc)
 | |
| -+		goto free_temp;
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		vreg->corner[i].ceiling_volt
 | |
| -+			= CPR3_ROUND(temp[i], ctrl->step_volt);
 | |
| -+		vreg->corner[i].abs_ceiling_volt = vreg->corner[i].ceiling_volt;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-voltage-floor",
 | |
| -+			1, temp);
 | |
| -+	if (rc)
 | |
| -+		goto free_temp;
 | |
| -+	for (i = 0; i < vreg->corner_count; i++)
 | |
| -+		vreg->corner[i].floor_volt
 | |
| -+			= CPR3_ROUND(temp[i], ctrl->step_volt);
 | |
| -+
 | |
| -+	/* Validate ceiling and floor values */
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		if (vreg->corner[i].floor_volt
 | |
| -+		    > vreg->corner[i].ceiling_volt) {
 | |
| -+			cpr3_err(vreg, "CPR floor[%d]=%d > ceiling[%d]=%d uV\n",
 | |
| -+				i, vreg->corner[i].floor_volt,
 | |
| -+				i, vreg->corner[i].ceiling_volt);
 | |
| -+			rc = -EINVAL;
 | |
| -+			goto free_temp;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Load optional system-supply voltages */
 | |
| -+	if (of_find_property(vreg->of_node, "qcom,system-voltage", NULL)) {
 | |
| -+		rc = cpr3_parse_corner_array_property(vreg,
 | |
| -+			"qcom,system-voltage", 1, temp);
 | |
| -+		if (rc)
 | |
| -+			goto free_temp;
 | |
| -+		for (i = 0; i < vreg->corner_count; i++)
 | |
| -+			vreg->corner[i].system_volt = temp[i];
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_parse_corner_array_property(vreg, "qcom,corner-frequencies",
 | |
| -+			1, temp);
 | |
| -+	if (rc)
 | |
| -+		goto free_temp;
 | |
| -+	for (i = 0; i < vreg->corner_count; i++)
 | |
| -+		vreg->corner[i].proc_freq = temp[i];
 | |
| -+
 | |
| -+	/* Validate frequencies */
 | |
| -+	for (i = 1; i < vreg->corner_count; i++) {
 | |
| -+		if (vreg->corner[i].proc_freq
 | |
| -+		    < vreg->corner[i - 1].proc_freq) {
 | |
| -+			cpr3_err(vreg, "invalid frequency: freq[%d]=%u < freq[%d]=%u\n",
 | |
| -+				i, vreg->corner[i].proc_freq, i - 1,
 | |
| -+				vreg->corner[i - 1].proc_freq);
 | |
| -+			rc = -EINVAL;
 | |
| -+			goto free_temp;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->fuse_corner_map = devm_kcalloc(ctrl->dev, vreg->fuse_corner_count,
 | |
| -+				    sizeof(*vreg->fuse_corner_map), GFP_KERNEL);
 | |
| -+	if (!vreg->fuse_corner_map) {
 | |
| -+		rc = -ENOMEM;
 | |
| -+		goto free_temp;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_parse_array_property(vreg, "qcom,cpr-corner-fmax-map",
 | |
| -+		vreg->fuse_corner_count, temp);
 | |
| -+	if (rc)
 | |
| -+		goto free_temp;
 | |
| -+	for (i = 0; i < vreg->fuse_corner_count; i++) {
 | |
| -+		vreg->fuse_corner_map[i] = temp[i] - CPR3_CORNER_OFFSET;
 | |
| -+		if (temp[i] < CPR3_CORNER_OFFSET
 | |
| -+		    || temp[i] > vreg->corner_count + CPR3_CORNER_OFFSET) {
 | |
| -+			cpr3_err(vreg, "invalid corner value specified in qcom,cpr-corner-fmax-map: %u\n",
 | |
| -+				temp[i]);
 | |
| -+			rc = -EINVAL;
 | |
| -+			goto free_temp;
 | |
| -+		} else if (i > 0 && temp[i - 1] >= temp[i]) {
 | |
| -+			cpr3_err(vreg, "invalid corner %u less than or equal to previous corner %u\n",
 | |
| -+				temp[i], temp[i - 1]);
 | |
| -+			rc = -EINVAL;
 | |
| -+			goto free_temp;
 | |
| -+		}
 | |
| -+	}
 | |
| -+	if (temp[vreg->fuse_corner_count - 1] != vreg->corner_count)
 | |
| -+		cpr3_debug(vreg, "Note: highest Fmax corner %u in qcom,cpr-corner-fmax-map does not match highest supported corner %d\n",
 | |
| -+			temp[vreg->fuse_corner_count - 1],
 | |
| -+			vreg->corner_count);
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		for (j = 0; j < vreg->fuse_corner_count; j++) {
 | |
| -+			if (i + CPR3_CORNER_OFFSET <= temp[j]) {
 | |
| -+				vreg->corner[i].cpr_fuse_corner = j;
 | |
| -+				break;
 | |
| -+			}
 | |
| -+		}
 | |
| -+		if (j == vreg->fuse_corner_count) {
 | |
| -+			/*
 | |
| -+			 * Handle the case where the highest fuse corner maps
 | |
| -+			 * to a corner below the highest corner.
 | |
| -+			 */
 | |
| -+			vreg->corner[i].cpr_fuse_corner
 | |
| -+				= vreg->fuse_corner_count - 1;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (of_find_property(vreg->of_node,
 | |
| -+				"qcom,allow-aging-voltage-adjustment", NULL)) {
 | |
| -+		rc = cpr3_parse_array_property(vreg,
 | |
| -+			"qcom,allow-aging-voltage-adjustment",
 | |
| -+			1, &aging_allowed);
 | |
| -+		if (rc)
 | |
| -+			goto free_temp;
 | |
| -+
 | |
| -+		vreg->aging_allowed = aging_allowed;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (of_find_property(vreg->of_node,
 | |
| -+		       "qcom,allow-aging-open-loop-voltage-adjustment", NULL)) {
 | |
| -+		rc = cpr3_parse_array_property(vreg,
 | |
| -+			"qcom,allow-aging-open-loop-voltage-adjustment",
 | |
| -+			1, &aging_allowed);
 | |
| -+		if (rc)
 | |
| -+			goto free_temp;
 | |
| -+
 | |
| -+		vreg->aging_allow_open_loop_adj = aging_allowed;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (vreg->aging_allowed) {
 | |
| -+		if (ctrl->aging_ref_volt <= 0) {
 | |
| -+			cpr3_err(ctrl, "qcom,cpr-aging-ref-voltage must be specified\n");
 | |
| -+			rc = -EINVAL;
 | |
| -+			goto free_temp;
 | |
| -+		}
 | |
| -+
 | |
| -+		rc = cpr3_parse_array_property(vreg,
 | |
| -+			"qcom,cpr-aging-max-voltage-adjustment",
 | |
| -+			1, &vreg->aging_max_adjust_volt);
 | |
| -+		if (rc)
 | |
| -+			goto free_temp;
 | |
| -+
 | |
| -+		rc = cpr3_parse_array_property(vreg,
 | |
| -+			"qcom,cpr-aging-ref-corner", 1, &vreg->aging_corner);
 | |
| -+		if (rc) {
 | |
| -+			goto free_temp;
 | |
| -+		} else if (vreg->aging_corner < CPR3_CORNER_OFFSET
 | |
| -+			   || vreg->aging_corner > vreg->corner_count - 1
 | |
| -+							+ CPR3_CORNER_OFFSET) {
 | |
| -+			cpr3_err(vreg, "aging reference corner=%d not in range [%d, %d]\n",
 | |
| -+				vreg->aging_corner, CPR3_CORNER_OFFSET,
 | |
| -+				vreg->corner_count - 1 + CPR3_CORNER_OFFSET);
 | |
| -+			rc = -EINVAL;
 | |
| -+			goto free_temp;
 | |
| -+		}
 | |
| -+		vreg->aging_corner -= CPR3_CORNER_OFFSET;
 | |
| -+
 | |
| -+		if (of_find_property(vreg->of_node, "qcom,cpr-aging-derate",
 | |
| -+					NULL)) {
 | |
| -+			rc = cpr3_parse_corner_array_property(vreg,
 | |
| -+				"qcom,cpr-aging-derate", 1, temp);
 | |
| -+			if (rc)
 | |
| -+				goto free_temp;
 | |
| -+
 | |
| -+			for (i = 0; i < vreg->corner_count; i++)
 | |
| -+				vreg->corner[i].aging_derate = temp[i];
 | |
| -+		} else {
 | |
| -+			for (i = 0; i < vreg->corner_count; i++)
 | |
| -+				vreg->corner[i].aging_derate
 | |
| -+					= CPR3_AGING_DERATE_UNITY;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+free_temp:
 | |
| -+	kfree(temp);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_parse_thread_u32() - parse the specified property from the CPR3 thread's
 | |
| -+ *		device tree node and verify that it is within the allowed limits
 | |
| -+ * @thread:		Pointer to the CPR3 thread
 | |
| -+ * @propname:		The name of the device tree property to read
 | |
| -+ * @out_value:		The output pointer to fill with the value read
 | |
| -+ * @value_min:		The minimum allowed property value
 | |
| -+ * @value_max:		The maximum allowed property value
 | |
| -+ *
 | |
| -+ * This function prints a verbose error message if the property is missing or
 | |
| -+ * has a value which is not within the specified range.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_parse_thread_u32(struct cpr3_thread *thread, const char *propname,
 | |
| -+		       u32 *out_value, u32 value_min, u32 value_max)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = of_property_read_u32(thread->of_node, propname, out_value);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(thread->ctrl, "thread %u error reading property %s, rc=%d\n",
 | |
| -+			thread->thread_id, propname, rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (*out_value < value_min || *out_value > value_max) {
 | |
| -+		cpr3_err(thread->ctrl, "thread %u %s=%u is invalid; allowed range: [%u, %u]\n",
 | |
| -+			thread->thread_id, propname, *out_value, value_min,
 | |
| -+			value_max);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_parse_ctrl_u32() - parse the specified property from the CPR3
 | |
| -+ *		controller's device tree node and verify that it is within the
 | |
| -+ *		allowed limits
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ * @propname:		The name of the device tree property to read
 | |
| -+ * @out_value:		The output pointer to fill with the value read
 | |
| -+ * @value_min:		The minimum allowed property value
 | |
| -+ * @value_max:		The maximum allowed property value
 | |
| -+ *
 | |
| -+ * This function prints a verbose error message if the property is missing or
 | |
| -+ * has a value which is not within the specified range.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_parse_ctrl_u32(struct cpr3_controller *ctrl, const char *propname,
 | |
| -+		       u32 *out_value, u32 value_min, u32 value_max)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = of_property_read_u32(ctrl->dev->of_node, propname, out_value);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "error reading property %s, rc=%d\n",
 | |
| -+			propname, rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (*out_value < value_min || *out_value > value_max) {
 | |
| -+		cpr3_err(ctrl, "%s=%u is invalid; allowed range: [%u, %u]\n",
 | |
| -+			propname, *out_value, value_min, value_max);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_parse_common_thread_data() - parse common CPR3 thread properties from
 | |
| -+ *		device tree
 | |
| -+ * @thread:		Pointer to the CPR3 thread
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_parse_common_thread_data(struct cpr3_thread *thread)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_thread_u32(thread, "qcom,cpr-consecutive-up",
 | |
| -+			&thread->consecutive_up, CPR3_CONSECUTIVE_UP_DOWN_MIN,
 | |
| -+			CPR3_CONSECUTIVE_UP_DOWN_MAX);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_thread_u32(thread, "qcom,cpr-consecutive-down",
 | |
| -+			&thread->consecutive_down, CPR3_CONSECUTIVE_UP_DOWN_MIN,
 | |
| -+			CPR3_CONSECUTIVE_UP_DOWN_MAX);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_thread_u32(thread, "qcom,cpr-up-threshold",
 | |
| -+			&thread->up_threshold, CPR3_UP_DOWN_THRESHOLD_MIN,
 | |
| -+			CPR3_UP_DOWN_THRESHOLD_MAX);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_thread_u32(thread, "qcom,cpr-down-threshold",
 | |
| -+			&thread->down_threshold, CPR3_UP_DOWN_THRESHOLD_MIN,
 | |
| -+			CPR3_UP_DOWN_THRESHOLD_MAX);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_parse_irq_affinity() - parse CPR IRQ affinity information
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_parse_irq_affinity(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct device_node *cpu_node;
 | |
| -+	int i, cpu;
 | |
| -+	int len = 0;
 | |
| -+
 | |
| -+	if (!of_find_property(ctrl->dev->of_node, "qcom,cpr-interrupt-affinity",
 | |
| -+				&len)) {
 | |
| -+		/* No IRQ affinity required */
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	len /= sizeof(u32);
 | |
| -+
 | |
| -+	for (i = 0; i < len; i++) {
 | |
| -+		cpu_node = of_parse_phandle(ctrl->dev->of_node,
 | |
| -+					    "qcom,cpr-interrupt-affinity", i);
 | |
| -+		if (!cpu_node) {
 | |
| -+			cpr3_err(ctrl, "could not find CPU node %d\n", i);
 | |
| -+			return -EINVAL;
 | |
| -+		}
 | |
| -+
 | |
| -+		for_each_possible_cpu(cpu) {
 | |
| -+			if (of_get_cpu_node(cpu, NULL) == cpu_node) {
 | |
| -+				cpumask_set_cpu(cpu, &ctrl->irq_affinity_mask);
 | |
| -+				break;
 | |
| -+			}
 | |
| -+		}
 | |
| -+		of_node_put(cpu_node);
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static int cpr3_panic_notifier_init(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct device_node *node = ctrl->dev->of_node;
 | |
| -+	struct cpr3_panic_regs_info *panic_regs_info;
 | |
| -+	struct cpr3_reg_info *regs;
 | |
| -+	int i, reg_count, len, rc = 0;
 | |
| -+
 | |
| -+	if (!of_find_property(node, "qcom,cpr-panic-reg-addr-list", &len)) {
 | |
| -+		/* panic register address list not specified */
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	reg_count = len / sizeof(u32);
 | |
| -+	if (!reg_count) {
 | |
| -+		cpr3_err(ctrl, "qcom,cpr-panic-reg-addr-list has invalid len = %d\n",
 | |
| -+			len);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!of_find_property(node, "qcom,cpr-panic-reg-name-list", NULL)) {
 | |
| -+		cpr3_err(ctrl, "property qcom,cpr-panic-reg-name-list not specified\n");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	len = of_property_count_strings(node, "qcom,cpr-panic-reg-name-list");
 | |
| -+	if (reg_count != len) {
 | |
| -+		cpr3_err(ctrl, "qcom,cpr-panic-reg-name-list should have %d strings\n",
 | |
| -+			reg_count);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	panic_regs_info = devm_kzalloc(ctrl->dev, sizeof(*panic_regs_info),
 | |
| -+					GFP_KERNEL);
 | |
| -+	if (!panic_regs_info)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	regs = devm_kcalloc(ctrl->dev, reg_count, sizeof(*regs), GFP_KERNEL);
 | |
| -+	if (!regs)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	for (i = 0; i < reg_count; i++) {
 | |
| -+		rc = of_property_read_string_index(node,
 | |
| -+				"qcom,cpr-panic-reg-name-list", i,
 | |
| -+				&(regs[i].name));
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "error reading property qcom,cpr-panic-reg-name-list, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		rc = of_property_read_u32_index(node,
 | |
| -+				"qcom,cpr-panic-reg-addr-list", i,
 | |
| -+				&(regs[i].addr));
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(ctrl, "error reading property qcom,cpr-panic-reg-addr-list, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+		regs[i].virt_addr = devm_ioremap(ctrl->dev, regs[i].addr, 0x4);
 | |
| -+		if (!regs[i].virt_addr) {
 | |
| -+			pr_err("Unable to map panic register addr 0x%08x\n",
 | |
| -+				regs[i].addr);
 | |
| -+			return -EINVAL;
 | |
| -+		}
 | |
| -+		regs[i].value = 0xFFFFFFFF;
 | |
| -+	}
 | |
| -+
 | |
| -+	panic_regs_info->reg_count = reg_count;
 | |
| -+	panic_regs_info->regs = regs;
 | |
| -+	ctrl->panic_regs_info = panic_regs_info;
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_parse_common_ctrl_data() - parse common CPR3 controller properties from
 | |
| -+ *		device tree
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_parse_common_ctrl_data(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-sensor-time",
 | |
| -+			&ctrl->sensor_time, 0, UINT_MAX);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-loop-time",
 | |
| -+			&ctrl->loop_time, 0, UINT_MAX);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-idle-cycles",
 | |
| -+			&ctrl->idle_clocks, CPR3_IDLE_CLOCKS_MIN,
 | |
| -+			CPR3_IDLE_CLOCKS_MAX);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-step-quot-init-min",
 | |
| -+			&ctrl->step_quot_init_min, CPR3_STEP_QUOT_MIN,
 | |
| -+			CPR3_STEP_QUOT_MAX);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-step-quot-init-max",
 | |
| -+			&ctrl->step_quot_init_max, CPR3_STEP_QUOT_MIN,
 | |
| -+			CPR3_STEP_QUOT_MAX);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	rc = of_property_read_u32(ctrl->dev->of_node, "qcom,voltage-step",
 | |
| -+				&ctrl->step_volt);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "error reading property qcom,voltage-step, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+	if (ctrl->step_volt <= 0) {
 | |
| -+		cpr3_err(ctrl, "qcom,voltage-step=%d is invalid\n",
 | |
| -+			ctrl->step_volt);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_parse_ctrl_u32(ctrl, "qcom,cpr-count-mode",
 | |
| -+			&ctrl->count_mode, CPR3_COUNT_MODE_ALL_AT_ONCE_MIN,
 | |
| -+			CPR3_COUNT_MODE_STAGGERED);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	/* Count repeat is optional */
 | |
| -+	ctrl->count_repeat = 0;
 | |
| -+	of_property_read_u32(ctrl->dev->of_node, "qcom,cpr-count-repeat",
 | |
| -+			&ctrl->count_repeat);
 | |
| -+
 | |
| -+	ctrl->cpr_allowed_sw =
 | |
| -+		of_property_read_bool(ctrl->dev->of_node, "qcom,cpr-enable") ||
 | |
| -+		ctrl->cpr_global_setting == CPR_CLOSED_LOOP_EN;
 | |
| -+
 | |
| -+	rc = cpr3_parse_irq_affinity(ctrl);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	/* Aging reference voltage is optional */
 | |
| -+	ctrl->aging_ref_volt = 0;
 | |
| -+	of_property_read_u32(ctrl->dev->of_node, "qcom,cpr-aging-ref-voltage",
 | |
| -+			&ctrl->aging_ref_volt);
 | |
| -+
 | |
| -+	/* Aging possible bitmask is optional */
 | |
| -+	ctrl->aging_possible_mask = 0;
 | |
| -+	of_property_read_u32(ctrl->dev->of_node,
 | |
| -+			"qcom,cpr-aging-allowed-reg-mask",
 | |
| -+			&ctrl->aging_possible_mask);
 | |
| -+
 | |
| -+	if (ctrl->aging_possible_mask) {
 | |
| -+		/*
 | |
| -+		 * Aging possible register value required if bitmask is
 | |
| -+		 * specified
 | |
| -+		 */
 | |
| -+		rc = cpr3_parse_ctrl_u32(ctrl,
 | |
| -+				"qcom,cpr-aging-allowed-reg-value",
 | |
| -+				&ctrl->aging_possible_val, 0, UINT_MAX);
 | |
| -+		if (rc)
 | |
| -+			return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (of_find_property(ctrl->dev->of_node, "clock-names", NULL)) {
 | |
| -+		ctrl->core_clk = devm_clk_get(ctrl->dev, "core_clk");
 | |
| -+		if (IS_ERR(ctrl->core_clk)) {
 | |
| -+			rc = PTR_ERR(ctrl->core_clk);
 | |
| -+			if (rc != -EPROBE_DEFER)
 | |
| -+				cpr3_err(ctrl, "unable request core clock, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_panic_notifier_init(ctrl);
 | |
| -+	if (rc)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	if (of_find_property(ctrl->dev->of_node, "vdd-supply", NULL)) {
 | |
| -+		ctrl->vdd_regulator = devm_regulator_get(ctrl->dev, "vdd");
 | |
| -+		if (IS_ERR(ctrl->vdd_regulator)) {
 | |
| -+			rc = PTR_ERR(ctrl->vdd_regulator);
 | |
| -+			if (rc != -EPROBE_DEFER)
 | |
| -+				cpr3_err(ctrl, "unable to request vdd regulator, rc=%d\n",
 | |
| -+					 rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	} else {
 | |
| -+		cpr3_err(ctrl, "vdd supply is not defined\n");
 | |
| -+		return -ENODEV;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->system_regulator = devm_regulator_get_optional(ctrl->dev,
 | |
| -+								"system");
 | |
| -+	if (IS_ERR(ctrl->system_regulator)) {
 | |
| -+		rc = PTR_ERR(ctrl->system_regulator);
 | |
| -+		if (rc != -EPROBE_DEFER) {
 | |
| -+			rc = 0;
 | |
| -+			ctrl->system_regulator = NULL;
 | |
| -+		} else {
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->mem_acc_regulator = devm_regulator_get_optional(ctrl->dev,
 | |
| -+							      "mem-acc");
 | |
| -+	if (IS_ERR(ctrl->mem_acc_regulator)) {
 | |
| -+		rc = PTR_ERR(ctrl->mem_acc_regulator);
 | |
| -+		if (rc != -EPROBE_DEFER) {
 | |
| -+			rc = 0;
 | |
| -+			ctrl->mem_acc_regulator = NULL;
 | |
| -+		} else {
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_parse_open_loop_common_ctrl_data() - parse common open loop CPR3
 | |
| -+ *			controller properties from device tree
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_parse_open_loop_common_ctrl_data(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = of_property_read_u32(ctrl->dev->of_node, "qcom,voltage-step",
 | |
| -+				  &ctrl->step_volt);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "error reading property qcom,voltage-step, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->step_volt <= 0) {
 | |
| -+		cpr3_err(ctrl, "qcom,voltage-step=%d is invalid\n",
 | |
| -+			 ctrl->step_volt);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (of_find_property(ctrl->dev->of_node, "vdd-supply", NULL)) {
 | |
| -+		ctrl->vdd_regulator = devm_regulator_get(ctrl->dev, "vdd");
 | |
| -+		if (IS_ERR(ctrl->vdd_regulator)) {
 | |
| -+			rc = PTR_ERR(ctrl->vdd_regulator);
 | |
| -+			if (rc != -EPROBE_DEFER)
 | |
| -+				cpr3_err(ctrl, "unable to request vdd regulator, rc=%d\n",
 | |
| -+					 rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	} else {
 | |
| -+		cpr3_err(ctrl, "vdd supply is not defined\n");
 | |
| -+		return -ENODEV;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->system_regulator = devm_regulator_get_optional(ctrl->dev,
 | |
| -+								"system");
 | |
| -+	if (IS_ERR(ctrl->system_regulator)) {
 | |
| -+		rc = PTR_ERR(ctrl->system_regulator);
 | |
| -+		if (rc != -EPROBE_DEFER) {
 | |
| -+			rc = 0;
 | |
| -+			ctrl->system_regulator = NULL;
 | |
| -+		} else {
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	} else {
 | |
| -+		rc = regulator_enable(ctrl->system_regulator);
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->mem_acc_regulator = devm_regulator_get_optional(ctrl->dev,
 | |
| -+							      "mem-acc");
 | |
| -+	if (IS_ERR(ctrl->mem_acc_regulator)) {
 | |
| -+		rc = PTR_ERR(ctrl->mem_acc_regulator);
 | |
| -+		if (rc != -EPROBE_DEFER) {
 | |
| -+			rc = 0;
 | |
| -+			ctrl->mem_acc_regulator = NULL;
 | |
| -+		} else {
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_limit_open_loop_voltages() - modify the open-loop voltage of each corner
 | |
| -+ *				so that it fits within the floor to ceiling
 | |
| -+ *				voltage range of the corner
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * This function clips the open-loop voltage for each corner so that it is
 | |
| -+ * limited to the floor to ceiling range.  It also rounds each open-loop voltage
 | |
| -+ * so that it corresponds to a set point available to the underlying regulator.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_limit_open_loop_voltages(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	int i, volt;
 | |
| -+
 | |
| -+	cpr3_debug(vreg, "open-loop voltages after trimming and rounding:\n");
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		volt = CPR3_ROUND(vreg->corner[i].open_loop_volt,
 | |
| -+					vreg->thread->ctrl->step_volt);
 | |
| -+		if (volt < vreg->corner[i].floor_volt)
 | |
| -+			volt = vreg->corner[i].floor_volt;
 | |
| -+		else if (volt > vreg->corner[i].ceiling_volt)
 | |
| -+			volt = vreg->corner[i].ceiling_volt;
 | |
| -+		vreg->corner[i].open_loop_volt = volt;
 | |
| -+		cpr3_debug(vreg, "corner[%2d]: open-loop=%d uV\n", i, volt);
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_open_loop_voltage_as_ceiling() - configures the ceiling voltage for each
 | |
| -+ *		corner to equal the open-loop voltage if the relevant device
 | |
| -+ *		tree property is found for the CPR3 regulator
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * This function assumes that the the open-loop voltage for each corner has
 | |
| -+ * already been rounded to the nearest allowed set point and that it falls
 | |
| -+ * within the floor to ceiling range.
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+void cpr3_open_loop_voltage_as_ceiling(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	int i;
 | |
| -+
 | |
| -+	if (!of_property_read_bool(vreg->of_node,
 | |
| -+				"qcom,cpr-scaled-open-loop-voltage-as-ceiling"))
 | |
| -+		return;
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++)
 | |
| -+		vreg->corner[i].ceiling_volt
 | |
| -+			= vreg->corner[i].open_loop_volt;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_limit_floor_voltages() - raise the floor voltage of each corner so that
 | |
| -+ *		the optional maximum floor to ceiling voltage range specified in
 | |
| -+ *		device tree is satisfied
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * This function also ensures that the open-loop voltage for each corner falls
 | |
| -+ * within the final floor to ceiling voltage range and that floor voltages
 | |
| -+ * increase monotonically.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_limit_floor_voltages(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	char *prop = "qcom,cpr-floor-to-ceiling-max-range";
 | |
| -+	int i, floor_new;
 | |
| -+	u32 *floor_range;
 | |
| -+	int rc = 0;
 | |
| -+
 | |
| -+	if (!of_find_property(vreg->of_node, prop, NULL))
 | |
| -+		goto enforce_monotonicity;
 | |
| -+
 | |
| -+	floor_range = kcalloc(vreg->corner_count, sizeof(*floor_range),
 | |
| -+				GFP_KERNEL);
 | |
| -+	if (!floor_range)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	rc = cpr3_parse_corner_array_property(vreg, prop, 1, floor_range);
 | |
| -+	if (rc)
 | |
| -+		goto free_floor_adjust;
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		if ((s32)floor_range[i] >= 0) {
 | |
| -+			floor_new = CPR3_ROUND(vreg->corner[i].ceiling_volt
 | |
| -+							- floor_range[i],
 | |
| -+						vreg->thread->ctrl->step_volt);
 | |
| -+
 | |
| -+			vreg->corner[i].floor_volt = max(floor_new,
 | |
| -+						vreg->corner[i].floor_volt);
 | |
| -+			if (vreg->corner[i].open_loop_volt
 | |
| -+			    < vreg->corner[i].floor_volt)
 | |
| -+				vreg->corner[i].open_loop_volt
 | |
| -+					= vreg->corner[i].floor_volt;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+free_floor_adjust:
 | |
| -+	kfree(floor_range);
 | |
| -+
 | |
| -+enforce_monotonicity:
 | |
| -+	/* Ensure that floor voltages increase monotonically. */
 | |
| -+	for (i = 1; i < vreg->corner_count; i++) {
 | |
| -+		if (vreg->corner[i].floor_volt
 | |
| -+		    < vreg->corner[i - 1].floor_volt) {
 | |
| -+			cpr3_debug(vreg, "corner %d floor voltage=%d uV < corner %d voltage=%d uV; overriding: corner %d voltage=%d\n",
 | |
| -+				i, vreg->corner[i].floor_volt,
 | |
| -+				i - 1, vreg->corner[i - 1].floor_volt,
 | |
| -+				i, vreg->corner[i - 1].floor_volt);
 | |
| -+			vreg->corner[i].floor_volt
 | |
| -+				= vreg->corner[i - 1].floor_volt;
 | |
| -+
 | |
| -+			if (vreg->corner[i].open_loop_volt
 | |
| -+			    < vreg->corner[i].floor_volt)
 | |
| -+				vreg->corner[i].open_loop_volt
 | |
| -+					= vreg->corner[i].floor_volt;
 | |
| -+			if (vreg->corner[i].ceiling_volt
 | |
| -+			    < vreg->corner[i].floor_volt)
 | |
| -+				vreg->corner[i].ceiling_volt
 | |
| -+					= vreg->corner[i].floor_volt;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_print_quots() - print CPR target quotients into the kernel log for
 | |
| -+ *		debugging purposes
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+void cpr3_print_quots(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	int i, j, pos;
 | |
| -+	size_t buflen;
 | |
| -+	char *buf;
 | |
| -+
 | |
| -+	buflen = sizeof(*buf) * CPR3_RO_COUNT * (MAX_CHARS_PER_INT + 2);
 | |
| -+	buf = kzalloc(buflen, GFP_KERNEL);
 | |
| -+	if (!buf)
 | |
| -+		return;
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		for (j = 0, pos = 0; j < CPR3_RO_COUNT; j++)
 | |
| -+			pos += scnprintf(buf + pos, buflen - pos, " %u",
 | |
| -+				vreg->corner[i].target_quot[j]);
 | |
| -+		cpr3_debug(vreg, "target quots[%2d]:%s\n", i, buf);
 | |
| -+	}
 | |
| -+
 | |
| -+	kfree(buf);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_determine_part_type() - determine the part type (SS/TT/FF).
 | |
| -+ *
 | |
| -+ * qcom,cpr-part-types prop tells the number of part types for which correction
 | |
| -+ * voltages are different. Another prop qcom,cpr-parts-voltage will contain the
 | |
| -+ * open loop fuse voltage which will be compared with this part voltage
 | |
| -+ * and accordingly part type will de determined.
 | |
| -+ *
 | |
| -+ * if qcom,cpr-part-types has value n, then qcom,cpr-parts-voltage will be
 | |
| -+ * array of n - 1 elements which will contain the voltage in increasing order.
 | |
| -+ * This function compares the fused volatge with all these voltage and returns
 | |
| -+ * the first index for which the fused volatge is greater.
 | |
| -+ *
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @fuse_volt:		fused open loop voltage which will be compared with
 | |
| -+ *                      qcom,cpr-parts-voltage array
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_determine_part_type(struct cpr3_regulator *vreg, int fuse_volt)
 | |
| -+{
 | |
| -+	int i, rc, len;
 | |
| -+	u32 volt;
 | |
| -+	int soc_version_major;
 | |
| -+	char prop_name[100];
 | |
| -+	const char prop_name_def[] = "qcom,cpr-parts-voltage";
 | |
| -+	const char prop_name_v2[] = "qcom,cpr-parts-voltage-v2";
 | |
| -+
 | |
| -+	soc_version_major = read_ipq_soc_version_major();
 | |
| -+        BUG_ON(soc_version_major <= 0);
 | |
| -+
 | |
| -+	if (of_property_read_u32(vreg->of_node, "qcom,cpr-part-types",
 | |
| -+				  &vreg->part_type_supported))
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	if (soc_version_major > 1)
 | |
| -+		strlcpy(prop_name, prop_name_v2, sizeof(prop_name_v2));
 | |
| -+	else
 | |
| -+		strlcpy(prop_name, prop_name_def, sizeof(prop_name_def));
 | |
| -+
 | |
| -+	if (!of_find_property(vreg->of_node, prop_name, &len)) {
 | |
| -+		cpr3_err(vreg, "property %s is missing\n", prop_name);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (len != (vreg->part_type_supported - 1) * sizeof(u32)) {
 | |
| -+		cpr3_err(vreg, "wrong len in qcom,cpr-parts-voltage\n");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->part_type_supported - 1; i++) {
 | |
| -+		rc = of_property_read_u32_index(vreg->of_node,
 | |
| -+					prop_name, i, &volt);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "error reading property %s, rc=%d\n",
 | |
| -+				 prop_name, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		if (fuse_volt < volt)
 | |
| -+			break;
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->part_type = i;
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+int cpr3_determine_temp_base_open_loop_correction(struct cpr3_regulator *vreg,
 | |
| -+		int *fuse_volt)
 | |
| -+{
 | |
| -+	int i, rc, prev_volt;
 | |
| -+	int *volt_adjust;
 | |
| -+	char prop_str[75];
 | |
| -+	int soc_version_major = read_ipq_soc_version_major();
 | |
| -+
 | |
| -+	BUG_ON(soc_version_major <= 0);
 | |
| -+
 | |
| -+	if (vreg->part_type_supported) {
 | |
| -+		if (soc_version_major > 1)
 | |
| -+			snprintf(prop_str, sizeof(prop_str),
 | |
| -+			"qcom,cpr-cold-temp-voltage-adjustment-v2-%d",
 | |
| -+			vreg->part_type);
 | |
| -+		else
 | |
| -+			snprintf(prop_str, sizeof(prop_str),
 | |
| -+			"qcom,cpr-cold-temp-voltage-adjustment-%d",
 | |
| -+			vreg->part_type);
 | |
| -+	} else {
 | |
| -+		strlcpy(prop_str, "qcom,cpr-cold-temp-voltage-adjustment",
 | |
| -+			sizeof(prop_str));
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!of_find_property(vreg->of_node, prop_str, NULL)) {
 | |
| -+		/* No adjustment required. */
 | |
| -+		cpr3_info(vreg, "No cold temperature adjustment required.\n");
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	volt_adjust = kcalloc(vreg->fuse_corner_count, sizeof(*volt_adjust),
 | |
| -+	GFP_KERNEL);
 | |
| -+	if (!volt_adjust)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	rc = cpr3_parse_array_property(vreg, prop_str,
 | |
| -+			vreg->fuse_corner_count, volt_adjust);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "could not load cold temp voltage adjustments, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->fuse_corner_count; i++) {
 | |
| -+		if (volt_adjust[i]) {
 | |
| -+			prev_volt = fuse_volt[i];
 | |
| -+			fuse_volt[i] += volt_adjust[i];
 | |
| -+			cpr3_debug(vreg,
 | |
| -+				"adjusted fuse corner %d open-loop voltage: %d -> %d uV\n",
 | |
| -+				i, prev_volt, fuse_volt[i]);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	kfree(volt_adjust);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_can_adjust_cold_temp() - Is cold temperature adjustment available
 | |
| -+ *
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * This function checks the cold temperature threshold is available
 | |
| -+ *
 | |
| -+ * Return: true on cold temperature threshold is available, else false
 | |
| -+ */
 | |
| -+bool cpr3_can_adjust_cold_temp(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	char prop_str[75];
 | |
| -+	int soc_version_major = read_ipq_soc_version_major();
 | |
| -+
 | |
| -+	BUG_ON(soc_version_major <= 0);
 | |
| -+
 | |
| -+	if (soc_version_major > 1)
 | |
| -+		strlcpy(prop_str, "qcom,cpr-cold-temp-threshold-v2",
 | |
| -+			sizeof(prop_str));
 | |
| -+	else
 | |
| -+		strlcpy(prop_str, "qcom,cpr-cold-temp-threshold",
 | |
| -+			sizeof(prop_str));
 | |
| -+
 | |
| -+	if (!of_find_property(vreg->of_node, prop_str, NULL)) {
 | |
| -+		/* No adjustment required. */
 | |
| -+		return false;
 | |
| -+	} else
 | |
| -+		return true;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_get_cold_temp_threshold() - get cold temperature threshold
 | |
| -+ *
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @cold_temp:		cold temperature read.
 | |
| -+ *
 | |
| -+ * This function reads the cold temperature threshold below which
 | |
| -+ * cold temperature adjustment margins will be applied.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_get_cold_temp_threshold(struct cpr3_regulator *vreg, int *cold_temp)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+	u32 temp;
 | |
| -+	char req_prop_str[75], prop_str[75];
 | |
| -+	int soc_version_major = read_ipq_soc_version_major();
 | |
| -+
 | |
| -+	BUG_ON(soc_version_major <= 0);
 | |
| -+
 | |
| -+	if (vreg->part_type_supported) {
 | |
| -+		if (soc_version_major > 1)
 | |
| -+			snprintf(req_prop_str, sizeof(req_prop_str),
 | |
| -+			"qcom,cpr-cold-temp-voltage-adjustment-v2-%d",
 | |
| -+			vreg->part_type);
 | |
| -+		else
 | |
| -+			snprintf(req_prop_str, sizeof(req_prop_str),
 | |
| -+			"qcom,cpr-cold-temp-voltage-adjustment-%d",
 | |
| -+			vreg->part_type);
 | |
| -+	} else {
 | |
| -+		strlcpy(req_prop_str, "qcom,cpr-cold-temp-voltage-adjustment",
 | |
| -+			sizeof(req_prop_str));
 | |
| -+	}
 | |
| -+
 | |
| -+	if (soc_version_major > 1)
 | |
| -+		strlcpy(prop_str, "qcom,cpr-cold-temp-threshold-v2",
 | |
| -+			sizeof(prop_str));
 | |
| -+	else
 | |
| -+		strlcpy(prop_str, "qcom,cpr-cold-temp-threshold",
 | |
| -+			sizeof(prop_str));
 | |
| -+
 | |
| -+	if (!of_find_property(vreg->of_node, req_prop_str, NULL)) {
 | |
| -+		/* No adjustment required. */
 | |
| -+		cpr3_info(vreg, "Cold temperature adjustment not required.\n");
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!of_find_property(vreg->of_node, prop_str, NULL)) {
 | |
| -+		/* No adjustment required. */
 | |
| -+                cpr3_err(vreg, "Missing %s required for %s\n",
 | |
| -+			prop_str, req_prop_str);
 | |
| -+		return -EINVAL;
 | |
| -+        }
 | |
| -+
 | |
| -+	rc = of_property_read_u32(vreg->of_node, prop_str, &temp);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "error reading property %s, rc=%d\n",
 | |
| -+			prop_str, rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	*cold_temp = temp;
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_adjust_fused_open_loop_voltages() - adjust the fused open-loop voltages
 | |
| -+ *		for each fuse corner according to device tree values
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @fuse_volt:		Pointer to an array of the fused open-loop voltage
 | |
| -+ *			values
 | |
| -+ *
 | |
| -+ * Voltage values in fuse_volt are modified in place.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_adjust_fused_open_loop_voltages(struct cpr3_regulator *vreg,
 | |
| -+		int *fuse_volt)
 | |
| -+{
 | |
| -+	int i, rc, prev_volt;
 | |
| -+	int *volt_adjust;
 | |
| -+	char prop_str[75];
 | |
| -+	int soc_version_major = read_ipq_soc_version_major();
 | |
| -+
 | |
| -+	BUG_ON(soc_version_major <= 0);
 | |
| -+
 | |
| -+	if (vreg->part_type_supported) {
 | |
| -+		if (soc_version_major > 1)
 | |
| -+			snprintf(prop_str, sizeof(prop_str),
 | |
| -+			"qcom,cpr-open-loop-voltage-fuse-adjustment-v2-%d",
 | |
| -+			vreg->part_type);
 | |
| -+		else
 | |
| -+		snprintf(prop_str, sizeof(prop_str),
 | |
| -+			 "qcom,cpr-open-loop-voltage-fuse-adjustment-%d",
 | |
| -+			 vreg->part_type);
 | |
| -+	} else {
 | |
| -+		strlcpy(prop_str, "qcom,cpr-open-loop-voltage-fuse-adjustment",
 | |
| -+			sizeof(prop_str));
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!of_find_property(vreg->of_node, prop_str, NULL)) {
 | |
| -+		/* No adjustment required. */
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	volt_adjust = kcalloc(vreg->fuse_corner_count, sizeof(*volt_adjust),
 | |
| -+				GFP_KERNEL);
 | |
| -+	if (!volt_adjust)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	rc = cpr3_parse_array_property(vreg,
 | |
| -+		prop_str, vreg->fuse_corner_count, volt_adjust);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "could not load open-loop fused voltage adjustments, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->fuse_corner_count; i++) {
 | |
| -+		if (volt_adjust[i]) {
 | |
| -+			prev_volt = fuse_volt[i];
 | |
| -+			fuse_volt[i] += volt_adjust[i];
 | |
| -+			cpr3_debug(vreg, "adjusted fuse corner %d open-loop voltage: %d --> %d uV\n",
 | |
| -+				i, prev_volt, fuse_volt[i]);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	kfree(volt_adjust);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_adjust_open_loop_voltages() - adjust the open-loop voltages for each
 | |
| -+ *		corner according to device tree values
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_adjust_open_loop_voltages(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	int i, rc, prev_volt, min_volt;
 | |
| -+	int *volt_adjust, *volt_diff;
 | |
| -+
 | |
| -+	if (!of_find_property(vreg->of_node,
 | |
| -+			"qcom,cpr-open-loop-voltage-adjustment", NULL)) {
 | |
| -+		/* No adjustment required. */
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	volt_adjust = kcalloc(vreg->corner_count, sizeof(*volt_adjust),
 | |
| -+				GFP_KERNEL);
 | |
| -+	volt_diff = kcalloc(vreg->corner_count, sizeof(*volt_diff), GFP_KERNEL);
 | |
| -+	if (!volt_adjust || !volt_diff) {
 | |
| -+		rc = -ENOMEM;
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_parse_corner_array_property(vreg,
 | |
| -+		"qcom,cpr-open-loop-voltage-adjustment", 1, volt_adjust);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "could not load open-loop voltage adjustments, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		if (volt_adjust[i]) {
 | |
| -+			prev_volt = vreg->corner[i].open_loop_volt;
 | |
| -+			vreg->corner[i].open_loop_volt += volt_adjust[i];
 | |
| -+			cpr3_debug(vreg, "adjusted corner %d open-loop voltage: %d --> %d uV\n",
 | |
| -+				i, prev_volt, vreg->corner[i].open_loop_volt);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (of_find_property(vreg->of_node,
 | |
| -+			"qcom,cpr-open-loop-voltage-min-diff", NULL)) {
 | |
| -+		rc = cpr3_parse_corner_array_property(vreg,
 | |
| -+			"qcom,cpr-open-loop-voltage-min-diff", 1, volt_diff);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "could not load minimum open-loop voltage differences, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Ensure that open-loop voltages increase monotonically with respect
 | |
| -+	 * to configurable minimum allowed differences.
 | |
| -+	 */
 | |
| -+	for (i = 1; i < vreg->corner_count; i++) {
 | |
| -+		min_volt = vreg->corner[i - 1].open_loop_volt + volt_diff[i];
 | |
| -+		if (vreg->corner[i].open_loop_volt < min_volt) {
 | |
| -+			cpr3_debug(vreg, "adjusted corner %d open-loop voltage=%d uV < corner %d voltage=%d uV + min diff=%d uV; overriding: corner %d voltage=%d\n",
 | |
| -+				i, vreg->corner[i].open_loop_volt,
 | |
| -+				i - 1, vreg->corner[i - 1].open_loop_volt,
 | |
| -+				volt_diff[i], i, min_volt);
 | |
| -+			vreg->corner[i].open_loop_volt = min_volt;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	kfree(volt_diff);
 | |
| -+	kfree(volt_adjust);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_quot_adjustment() - returns the quotient adjustment value resulting from
 | |
| -+ *		the specified voltage adjustment and RO scaling factor
 | |
| -+ * @ro_scale:		The CPR ring oscillator (RO) scaling factor with units
 | |
| -+ *			of QUOT/V
 | |
| -+ * @volt_adjust:	The amount to adjust the voltage by in units of
 | |
| -+ *			microvolts.  This value may be positive or negative.
 | |
| -+ */
 | |
| -+int cpr3_quot_adjustment(int ro_scale, int volt_adjust)
 | |
| -+{
 | |
| -+	unsigned long long temp;
 | |
| -+	int quot_adjust;
 | |
| -+	int sign = 1;
 | |
| -+
 | |
| -+	if (ro_scale < 0) {
 | |
| -+		sign = -sign;
 | |
| -+		ro_scale = -ro_scale;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (volt_adjust < 0) {
 | |
| -+		sign = -sign;
 | |
| -+		volt_adjust = -volt_adjust;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = (unsigned long long)ro_scale * (unsigned long long)volt_adjust;
 | |
| -+	do_div(temp, 1000000);
 | |
| -+
 | |
| -+	quot_adjust = temp;
 | |
| -+	quot_adjust *= sign;
 | |
| -+
 | |
| -+	return quot_adjust;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_voltage_adjustment() - returns the voltage adjustment value resulting
 | |
| -+ *		from the specified quotient adjustment and RO scaling factor
 | |
| -+ * @ro_scale:		The CPR ring oscillator (RO) scaling factor with units
 | |
| -+ *			of QUOT/V
 | |
| -+ * @quot_adjust:	The amount to adjust the quotient by in units of
 | |
| -+ *			QUOT.  This value may be positive or negative.
 | |
| -+ */
 | |
| -+int cpr3_voltage_adjustment(int ro_scale, int quot_adjust)
 | |
| -+{
 | |
| -+	unsigned long long temp;
 | |
| -+	int volt_adjust;
 | |
| -+	int sign = 1;
 | |
| -+
 | |
| -+	if (ro_scale < 0) {
 | |
| -+		sign = -sign;
 | |
| -+		ro_scale = -ro_scale;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (quot_adjust < 0) {
 | |
| -+		sign = -sign;
 | |
| -+		quot_adjust = -quot_adjust;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ro_scale == 0)
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	temp = (unsigned long long)quot_adjust * 1000000;
 | |
| -+	do_div(temp, ro_scale);
 | |
| -+
 | |
| -+	volt_adjust = temp;
 | |
| -+	volt_adjust *= sign;
 | |
| -+
 | |
| -+	return volt_adjust;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_parse_closed_loop_voltage_adjustments() - load per-fuse-corner and
 | |
| -+ *		per-corner closed-loop adjustment values from device tree
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @ro_sel:		Array of ring oscillator values selected for each
 | |
| -+ *			fuse corner
 | |
| -+ * @volt_adjust:	Pointer to array which will be filled with the
 | |
| -+ *			per-corner closed-loop adjustment voltages
 | |
| -+ * @volt_adjust_fuse:	Pointer to array which will be filled with the
 | |
| -+ *			per-fuse-corner closed-loop adjustment voltages
 | |
| -+ * @ro_scale:		Pointer to array which will be filled with the
 | |
| -+ *			per-fuse-corner RO scaling factor values with units of
 | |
| -+ *			QUOT/V
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_parse_closed_loop_voltage_adjustments(
 | |
| -+			struct cpr3_regulator *vreg, u64 *ro_sel,
 | |
| -+			int *volt_adjust, int *volt_adjust_fuse, int *ro_scale)
 | |
| -+{
 | |
| -+	int i, rc;
 | |
| -+	u32 *ro_all_scale;
 | |
| -+
 | |
| -+	char volt_adj[] = "qcom,cpr-closed-loop-voltage-adjustment";
 | |
| -+	char volt_fuse_adj[] = "qcom,cpr-closed-loop-voltage-fuse-adjustment";
 | |
| -+	char ro_scaling[] = "qcom,cpr-ro-scaling-factor";
 | |
| -+
 | |
| -+	if (!of_find_property(vreg->of_node, volt_adj, NULL)
 | |
| -+	    && !of_find_property(vreg->of_node, volt_fuse_adj, NULL)
 | |
| -+	    && !vreg->aging_allowed) {
 | |
| -+		/* No adjustment required. */
 | |
| -+		return 0;
 | |
| -+	} else if (!of_find_property(vreg->of_node, ro_scaling, NULL)) {
 | |
| -+		cpr3_err(vreg, "Missing %s required for closed-loop voltage adjustment.\n",
 | |
| -+				ro_scaling);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	ro_all_scale = kcalloc(vreg->fuse_corner_count * CPR3_RO_COUNT,
 | |
| -+				sizeof(*ro_all_scale), GFP_KERNEL);
 | |
| -+	if (!ro_all_scale)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	rc = cpr3_parse_array_property(vreg, ro_scaling,
 | |
| -+		vreg->fuse_corner_count * CPR3_RO_COUNT, ro_all_scale);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "could not load RO scaling factors, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->fuse_corner_count; i++)
 | |
| -+		ro_scale[i] = ro_all_scale[i * CPR3_RO_COUNT + ro_sel[i]];
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++)
 | |
| -+		memcpy(vreg->corner[i].ro_scale,
 | |
| -+		 &ro_all_scale[vreg->corner[i].cpr_fuse_corner * CPR3_RO_COUNT],
 | |
| -+		 sizeof(*ro_all_scale) * CPR3_RO_COUNT);
 | |
| -+
 | |
| -+	if (of_find_property(vreg->of_node, volt_fuse_adj, NULL)) {
 | |
| -+		rc = cpr3_parse_array_property(vreg, volt_fuse_adj,
 | |
| -+			vreg->fuse_corner_count, volt_adjust_fuse);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "could not load closed-loop fused voltage adjustments, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (of_find_property(vreg->of_node, volt_adj, NULL)) {
 | |
| -+		rc = cpr3_parse_corner_array_property(vreg, volt_adj,
 | |
| -+			1, volt_adjust);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "could not load closed-loop voltage adjustments, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	kfree(ro_all_scale);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_apm_init() - initialize APM data for a CPR3 controller
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * This function loads memory array power mux (APM) data from device tree
 | |
| -+ * if it is present and requests a handle to the appropriate APM controller
 | |
| -+ * device.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_apm_init(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct device_node *node = ctrl->dev->of_node;
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	if (!of_find_property(node, "qcom,apm-ctrl", NULL)) {
 | |
| -+		/* No APM used */
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->apm = msm_apm_ctrl_dev_get(ctrl->dev);
 | |
| -+	if (IS_ERR(ctrl->apm)) {
 | |
| -+		rc = PTR_ERR(ctrl->apm);
 | |
| -+		if (rc != -EPROBE_DEFER)
 | |
| -+			cpr3_err(ctrl, "APM get failed, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = of_property_read_u32(node, "qcom,apm-threshold-voltage",
 | |
| -+				&ctrl->apm_threshold_volt);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "error reading qcom,apm-threshold-voltage, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+	ctrl->apm_threshold_volt
 | |
| -+		= CPR3_ROUND(ctrl->apm_threshold_volt, ctrl->step_volt);
 | |
| -+
 | |
| -+	/* No error check since this is an optional property. */
 | |
| -+	of_property_read_u32(node, "qcom,apm-hysteresis-voltage",
 | |
| -+				&ctrl->apm_adj_volt);
 | |
| -+	ctrl->apm_adj_volt = CPR3_ROUND(ctrl->apm_adj_volt, ctrl->step_volt);
 | |
| -+
 | |
| -+	ctrl->apm_high_supply = MSM_APM_SUPPLY_APCC;
 | |
| -+	ctrl->apm_low_supply = MSM_APM_SUPPLY_MX;
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_mem_acc_init() - initialize mem-acc regulator data for
 | |
| -+ *		a CPR3 regulator
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_mem_acc_init(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	u32 *temp;
 | |
| -+	int i, rc;
 | |
| -+
 | |
| -+	if (!ctrl->mem_acc_regulator) {
 | |
| -+		cpr3_info(ctrl, "not using memory accelerator regulator\n");
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp = kcalloc(vreg->corner_count, sizeof(*temp), GFP_KERNEL);
 | |
| -+	if (!temp)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	rc = cpr3_parse_corner_array_property(vreg, "qcom,mem-acc-voltage",
 | |
| -+					      1, temp);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "could not load mem-acc corners, rc=%d\n", rc);
 | |
| -+	} else {
 | |
| -+		for (i = 0; i < vreg->corner_count; i++)
 | |
| -+			vreg->corner[i].mem_acc_volt = temp[i];
 | |
| -+	}
 | |
| -+
 | |
| -+	kfree(temp);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_load_core_and_temp_adj() - parse amount of voltage adjustment for
 | |
| -+ *		per-online-core and per-temperature voltage adjustment for a
 | |
| -+ *		given corner or corner band from device tree.
 | |
| -+ * @vreg:	Pointer to the CPR3 regulator
 | |
| -+ * @num:	Corner number or corner band number
 | |
| -+ * @use_corner_band:	Boolean indicating if the CPR3 regulator supports
 | |
| -+ *			adjustments per corner band
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_load_core_and_temp_adj(struct cpr3_regulator *vreg,
 | |
| -+					int num, bool use_corner_band)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	struct cpr4_sdelta *sdelta;
 | |
| -+	int sdelta_size, i, j, pos, rc = 0;
 | |
| -+	char str[75];
 | |
| -+	size_t buflen;
 | |
| -+	char *buf;
 | |
| -+
 | |
| -+	sdelta = use_corner_band ? vreg->corner_band[num].sdelta :
 | |
| -+		vreg->corner[num].sdelta;
 | |
| -+
 | |
| -+	if (!sdelta->allow_core_count_adj && !sdelta->allow_temp_adj) {
 | |
| -+		/* corner doesn't need sdelta table */
 | |
| -+		sdelta->max_core_count = 0;
 | |
| -+		sdelta->temp_band_count = 0;
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	sdelta_size = sdelta->max_core_count * sdelta->temp_band_count;
 | |
| -+	if (use_corner_band)
 | |
| -+		snprintf(str, sizeof(str),
 | |
| -+			 "corner_band=%d core_config_count=%d temp_band_count=%d sdelta_size=%d\n",
 | |
| -+			 num, sdelta->max_core_count,
 | |
| -+			 sdelta->temp_band_count, sdelta_size);
 | |
| -+	else
 | |
| -+		snprintf(str, sizeof(str),
 | |
| -+			 "corner=%d core_config_count=%d temp_band_count=%d sdelta_size=%d\n",
 | |
| -+			 num, sdelta->max_core_count,
 | |
| -+			 sdelta->temp_band_count, sdelta_size);
 | |
| -+
 | |
| -+	cpr3_debug(vreg, "%s", str);
 | |
| -+
 | |
| -+	sdelta->table = devm_kcalloc(ctrl->dev, sdelta_size,
 | |
| -+				sizeof(*sdelta->table), GFP_KERNEL);
 | |
| -+	if (!sdelta->table)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	if (use_corner_band)
 | |
| -+		snprintf(str, sizeof(str),
 | |
| -+			 "qcom,cpr-corner-band%d-temp-core-voltage-adjustment",
 | |
| -+			 num + CPR3_CORNER_OFFSET);
 | |
| -+	else
 | |
| -+		snprintf(str, sizeof(str),
 | |
| -+			 "qcom,cpr-corner%d-temp-core-voltage-adjustment",
 | |
| -+			 num + CPR3_CORNER_OFFSET);
 | |
| -+
 | |
| -+	rc = cpr3_parse_array_property(vreg, str, sdelta_size,
 | |
| -+				sdelta->table);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "could not load %s, rc=%d\n", str, rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Convert sdelta margins from uV to PMIC steps and apply negation to
 | |
| -+	 * follow the SDELTA register semantics.
 | |
| -+	 */
 | |
| -+	for (i = 0; i < sdelta_size; i++)
 | |
| -+		sdelta->table[i] = -(sdelta->table[i] / ctrl->step_volt);
 | |
| -+
 | |
| -+	buflen = sizeof(*buf) * sdelta_size * (MAX_CHARS_PER_INT + 2);
 | |
| -+	buf = kzalloc(buflen, GFP_KERNEL);
 | |
| -+	if (!buf)
 | |
| -+		return rc;
 | |
| -+
 | |
| -+	for (i = 0; i < sdelta->max_core_count; i++) {
 | |
| -+		for (j = 0, pos = 0; j < sdelta->temp_band_count; j++)
 | |
| -+			pos += scnprintf(buf + pos, buflen - pos, " %u",
 | |
| -+			 sdelta->table[i * sdelta->temp_band_count + j]);
 | |
| -+		cpr3_debug(vreg, "sdelta[%d]:%s\n", i, buf);
 | |
| -+	}
 | |
| -+
 | |
| -+	kfree(buf);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_parse_core_count_temp_voltage_adj() - parse configuration data for
 | |
| -+ *		per-online-core and per-temperature voltage adjustment for
 | |
| -+ *		a CPR3 regulator from device tree.
 | |
| -+ * @vreg:	Pointer to the CPR3 regulator
 | |
| -+ * @use_corner_band:	Boolean indicating if the CPR3 regulator supports
 | |
| -+ *			adjustments per corner band
 | |
| -+ *
 | |
| -+ * This function supports parsing of per-online-core and per-temperature
 | |
| -+ * adjustments per corner or per corner band. CPR controllers which support
 | |
| -+ * corner bands apply the same adjustments to all corners within a corner band.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr4_parse_core_count_temp_voltage_adj(
 | |
| -+			struct cpr3_regulator *vreg, bool use_corner_band)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	struct device_node *node = vreg->of_node;
 | |
| -+	struct cpr3_corner *corner;
 | |
| -+	struct cpr4_sdelta *sdelta;
 | |
| -+	int i, sdelta_table_count, rc = 0;
 | |
| -+	int *allow_core_count_adj = NULL, *allow_temp_adj = NULL;
 | |
| -+	char prop_str[75];
 | |
| -+
 | |
| -+	if (of_find_property(node, use_corner_band ?
 | |
| -+			     "qcom,corner-band-allow-temp-adjustment"
 | |
| -+			     : "qcom,corner-allow-temp-adjustment", NULL)) {
 | |
| -+		if (!ctrl->allow_temp_adj) {
 | |
| -+			cpr3_err(ctrl, "Temperature adjustment configurations missing\n");
 | |
| -+			return -EINVAL;
 | |
| -+		}
 | |
| -+
 | |
| -+		vreg->allow_temp_adj = true;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (of_find_property(node, use_corner_band ?
 | |
| -+			     "qcom,corner-band-allow-core-count-adjustment"
 | |
| -+			     : "qcom,corner-allow-core-count-adjustment",
 | |
| -+			     NULL)) {
 | |
| -+		rc = of_property_read_u32(node, "qcom,max-core-count",
 | |
| -+				&vreg->max_core_count);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "error reading qcom,max-core-count, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			return -EINVAL;
 | |
| -+		}
 | |
| -+
 | |
| -+		vreg->allow_core_count_adj = true;
 | |
| -+		ctrl->allow_core_count_adj = true;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!vreg->allow_temp_adj && !vreg->allow_core_count_adj) {
 | |
| -+		/*
 | |
| -+		 * Both per-online-core and temperature based adjustments are
 | |
| -+		 * disabled for this regulator.
 | |
| -+		 */
 | |
| -+		return 0;
 | |
| -+	} else if (!vreg->allow_core_count_adj) {
 | |
| -+		/*
 | |
| -+		 * Only per-temperature voltage adjusments are allowed.
 | |
| -+		 * Keep max core count value as 1 to allocate SDELTA.
 | |
| -+		 */
 | |
| -+		vreg->max_core_count = 1;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (vreg->allow_core_count_adj) {
 | |
| -+		allow_core_count_adj = kcalloc(vreg->corner_count,
 | |
| -+					sizeof(*allow_core_count_adj),
 | |
| -+					GFP_KERNEL);
 | |
| -+		if (!allow_core_count_adj)
 | |
| -+			return -ENOMEM;
 | |
| -+
 | |
| -+		snprintf(prop_str, sizeof(prop_str), "%s", use_corner_band ?
 | |
| -+			 "qcom,corner-band-allow-core-count-adjustment" :
 | |
| -+			 "qcom,corner-allow-core-count-adjustment");
 | |
| -+
 | |
| -+		rc = use_corner_band ?
 | |
| -+			cpr3_parse_corner_band_array_property(vreg, prop_str,
 | |
| -+					      1, allow_core_count_adj) :
 | |
| -+			cpr3_parse_corner_array_property(vreg, prop_str,
 | |
| -+						 1, allow_core_count_adj);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "error reading %s, rc=%d\n", prop_str,
 | |
| -+				 rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (vreg->allow_temp_adj) {
 | |
| -+		allow_temp_adj = kcalloc(vreg->corner_count,
 | |
| -+					sizeof(*allow_temp_adj), GFP_KERNEL);
 | |
| -+		if (!allow_temp_adj) {
 | |
| -+			rc = -ENOMEM;
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+
 | |
| -+		snprintf(prop_str, sizeof(prop_str), "%s", use_corner_band ?
 | |
| -+			 "qcom,corner-band-allow-temp-adjustment" :
 | |
| -+			 "qcom,corner-allow-temp-adjustment");
 | |
| -+
 | |
| -+		rc = use_corner_band ?
 | |
| -+			cpr3_parse_corner_band_array_property(vreg, prop_str,
 | |
| -+						      1, allow_temp_adj) :
 | |
| -+			cpr3_parse_corner_array_property(vreg, prop_str,
 | |
| -+						 1, allow_temp_adj);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "error reading %s, rc=%d\n", prop_str,
 | |
| -+				 rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	sdelta_table_count = use_corner_band ? vreg->corner_band_count :
 | |
| -+		vreg->corner_count;
 | |
| -+
 | |
| -+	for (i = 0; i < sdelta_table_count; i++) {
 | |
| -+		sdelta = devm_kzalloc(ctrl->dev, sizeof(*corner->sdelta),
 | |
| -+				      GFP_KERNEL);
 | |
| -+		if (!sdelta) {
 | |
| -+			rc = -ENOMEM;
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+
 | |
| -+		if (allow_core_count_adj)
 | |
| -+			sdelta->allow_core_count_adj = allow_core_count_adj[i];
 | |
| -+		if (allow_temp_adj)
 | |
| -+			sdelta->allow_temp_adj = allow_temp_adj[i];
 | |
| -+		sdelta->max_core_count = vreg->max_core_count;
 | |
| -+		sdelta->temp_band_count = ctrl->temp_band_count;
 | |
| -+
 | |
| -+		if (use_corner_band)
 | |
| -+			vreg->corner_band[i].sdelta = sdelta;
 | |
| -+		else
 | |
| -+			vreg->corner[i].sdelta = sdelta;
 | |
| -+
 | |
| -+		rc = cpr4_load_core_and_temp_adj(vreg, i, use_corner_band);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "corner/band %d core and temp adjustment loading failed, rc=%d\n",
 | |
| -+				 i, rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	kfree(allow_core_count_adj);
 | |
| -+	kfree(allow_temp_adj);
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cprh_adjust_voltages_for_apm() - adjust per-corner floor and ceiling voltages
 | |
| -+ *		so that they do not overlap the APM threshold voltage.
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * The memory array power mux (APM) must be configured for a specific supply
 | |
| -+ * based upon where the VDD voltage lies with respect to the APM threshold
 | |
| -+ * voltage.  When using CPR hardware closed-loop, the voltage may vary anywhere
 | |
| -+ * between the floor and ceiling voltage without software notification.
 | |
| -+ * Therefore, it is required that the floor to ceiling range for every corner
 | |
| -+ * not intersect the APM threshold voltage.  This function adjusts the floor to
 | |
| -+ * ceiling range for each corner which violates this requirement.
 | |
| -+ *
 | |
| -+ * The following algorithm is applied:
 | |
| -+ *	if floor < threshold <= ceiling:
 | |
| -+ *		if open_loop >= threshold, then floor = threshold - adj
 | |
| -+ *		else ceiling = threshold - step
 | |
| -+ * where:
 | |
| -+ *	adj = APM hysteresis voltage established to minimize the number of
 | |
| -+ *	      corners with artificially increased floor voltages
 | |
| -+ *	step = voltage in microvolts of a single step of the VDD supply
 | |
| -+ *
 | |
| -+ * The open-loop voltage is also bounded by the new floor or ceiling value as
 | |
| -+ * needed.
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+void cprh_adjust_voltages_for_apm(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	struct cpr3_corner *corner;
 | |
| -+	int i, adj, threshold, prev_ceiling, prev_floor, prev_open_loop;
 | |
| -+
 | |
| -+	if (!ctrl->apm_threshold_volt) {
 | |
| -+		/* APM not being used. */
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->apm_threshold_volt = CPR3_ROUND(ctrl->apm_threshold_volt,
 | |
| -+						ctrl->step_volt);
 | |
| -+	ctrl->apm_adj_volt = CPR3_ROUND(ctrl->apm_adj_volt, ctrl->step_volt);
 | |
| -+
 | |
| -+	threshold = ctrl->apm_threshold_volt;
 | |
| -+	adj = ctrl->apm_adj_volt;
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		corner = &vreg->corner[i];
 | |
| -+
 | |
| -+		if (threshold <= corner->floor_volt
 | |
| -+		    || threshold > corner->ceiling_volt)
 | |
| -+			continue;
 | |
| -+
 | |
| -+		prev_floor = corner->floor_volt;
 | |
| -+		prev_ceiling = corner->ceiling_volt;
 | |
| -+		prev_open_loop = corner->open_loop_volt;
 | |
| -+
 | |
| -+		if (corner->open_loop_volt >= threshold) {
 | |
| -+			corner->floor_volt = max(corner->floor_volt,
 | |
| -+						 threshold - adj);
 | |
| -+			if (corner->open_loop_volt < corner->floor_volt)
 | |
| -+				corner->open_loop_volt = corner->floor_volt;
 | |
| -+		} else {
 | |
| -+			corner->ceiling_volt = threshold - ctrl->step_volt;
 | |
| -+		}
 | |
| -+
 | |
| -+		if (corner->floor_volt != prev_floor
 | |
| -+		    || corner->ceiling_volt != prev_ceiling
 | |
| -+		    || corner->open_loop_volt != prev_open_loop)
 | |
| -+			cpr3_debug(vreg, "APM threshold=%d, APM adj=%d changed corner %d voltages; prev: floor=%d, ceiling=%d, open-loop=%d; new: floor=%d, ceiling=%d, open-loop=%d\n",
 | |
| -+				threshold, adj, i, prev_floor, prev_ceiling,
 | |
| -+				prev_open_loop, corner->floor_volt,
 | |
| -+				corner->ceiling_volt, corner->open_loop_volt);
 | |
| -+	}
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cprh_adjust_voltages_for_mem_acc() - adjust per-corner floor and ceiling
 | |
| -+ *		voltages so that they do not intersect the MEM ACC threshold
 | |
| -+ *		voltage
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * The following algorithm is applied:
 | |
| -+ *	if floor < threshold <= ceiling:
 | |
| -+ *		if open_loop >= threshold, then floor = threshold
 | |
| -+ *		else ceiling = threshold - step
 | |
| -+ * where:
 | |
| -+ *	step = voltage in microvolts of a single step of the VDD supply
 | |
| -+ *
 | |
| -+ * The open-loop voltage is also bounded by the new floor or ceiling value as
 | |
| -+ * needed.
 | |
| -+ *
 | |
| -+ * Return: none
 | |
| -+ */
 | |
| -+void cprh_adjust_voltages_for_mem_acc(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	struct cpr3_corner *corner;
 | |
| -+	int i, threshold, prev_ceiling, prev_floor, prev_open_loop;
 | |
| -+
 | |
| -+	if (!ctrl->mem_acc_threshold_volt) {
 | |
| -+		/* MEM ACC not being used. */
 | |
| -+		return;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->mem_acc_threshold_volt = CPR3_ROUND(ctrl->mem_acc_threshold_volt,
 | |
| -+						ctrl->step_volt);
 | |
| -+
 | |
| -+	threshold = ctrl->mem_acc_threshold_volt;
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		corner = &vreg->corner[i];
 | |
| -+
 | |
| -+		if (threshold <= corner->floor_volt
 | |
| -+		    || threshold > corner->ceiling_volt)
 | |
| -+			continue;
 | |
| -+
 | |
| -+		prev_floor = corner->floor_volt;
 | |
| -+		prev_ceiling = corner->ceiling_volt;
 | |
| -+		prev_open_loop = corner->open_loop_volt;
 | |
| -+
 | |
| -+		if (corner->open_loop_volt >= threshold) {
 | |
| -+			corner->floor_volt = max(corner->floor_volt, threshold);
 | |
| -+			if (corner->open_loop_volt < corner->floor_volt)
 | |
| -+				corner->open_loop_volt = corner->floor_volt;
 | |
| -+		} else {
 | |
| -+			corner->ceiling_volt = threshold - ctrl->step_volt;
 | |
| -+		}
 | |
| -+
 | |
| -+		if (corner->floor_volt != prev_floor
 | |
| -+		    || corner->ceiling_volt != prev_ceiling
 | |
| -+		    || corner->open_loop_volt != prev_open_loop)
 | |
| -+			cpr3_debug(vreg, "MEM ACC threshold=%d changed corner %d voltages; prev: floor=%d, ceiling=%d, open-loop=%d; new: floor=%d, ceiling=%d, open-loop=%d\n",
 | |
| -+				threshold, i, prev_floor, prev_ceiling,
 | |
| -+				prev_open_loop, corner->floor_volt,
 | |
| -+				corner->ceiling_volt, corner->open_loop_volt);
 | |
| -+	}
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_apply_closed_loop_offset_voltages() - modify the closed-loop voltage
 | |
| -+ *		adjustments by the amounts that are needed for this
 | |
| -+ *		fuse combo
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @volt_adjust:	Array of closed-loop voltage adjustment values of length
 | |
| -+ *			vreg->corner_count which is further adjusted based upon
 | |
| -+ *			offset voltage fuse values.
 | |
| -+ * @fuse_volt_adjust:	Fused closed-loop voltage adjustment values of length
 | |
| -+ *			vreg->fuse_corner_count.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr3_apply_closed_loop_offset_voltages(struct cpr3_regulator *vreg,
 | |
| -+			int *volt_adjust, int *fuse_volt_adjust)
 | |
| -+{
 | |
| -+	u32 *corner_map;
 | |
| -+	int rc = 0, i;
 | |
| -+
 | |
| -+	if (!of_find_property(vreg->of_node,
 | |
| -+		"qcom,cpr-fused-closed-loop-voltage-adjustment-map", NULL)) {
 | |
| -+		/* No closed-loop offset required. */
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	corner_map = kcalloc(vreg->corner_count, sizeof(*corner_map),
 | |
| -+				GFP_KERNEL);
 | |
| -+	if (!corner_map)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	rc = cpr3_parse_corner_array_property(vreg,
 | |
| -+		"qcom,cpr-fused-closed-loop-voltage-adjustment-map",
 | |
| -+		1, corner_map);
 | |
| -+	if (rc)
 | |
| -+		goto done;
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		if (corner_map[i] == 0) {
 | |
| -+			continue;
 | |
| -+		} else if (corner_map[i] > vreg->fuse_corner_count) {
 | |
| -+			cpr3_err(vreg, "corner %d mapped to invalid fuse corner: %u\n",
 | |
| -+				i, corner_map[i]);
 | |
| -+			rc = -EINVAL;
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+
 | |
| -+		volt_adjust[i] += fuse_volt_adjust[corner_map[i] - 1];
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	kfree(corner_map);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_enforce_inc_quotient_monotonicity() - Ensure that target quotients
 | |
| -+ *		increase monotonically from lower to higher corners
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static void cpr3_enforce_inc_quotient_monotonicity(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	int i, j;
 | |
| -+
 | |
| -+	for (i = 1; i < vreg->corner_count; i++) {
 | |
| -+		for (j = 0; j < CPR3_RO_COUNT; j++) {
 | |
| -+			if (vreg->corner[i].target_quot[j]
 | |
| -+			    && vreg->corner[i].target_quot[j]
 | |
| -+					< vreg->corner[i - 1].target_quot[j]) {
 | |
| -+				cpr3_debug(vreg, "corner %d RO%u target quot=%u < corner %d RO%u target quot=%u; overriding: corner %d RO%u target quot=%u\n",
 | |
| -+					i, j,
 | |
| -+					vreg->corner[i].target_quot[j],
 | |
| -+					i - 1, j,
 | |
| -+					vreg->corner[i - 1].target_quot[j],
 | |
| -+					i, j,
 | |
| -+					vreg->corner[i - 1].target_quot[j]);
 | |
| -+				vreg->corner[i].target_quot[j]
 | |
| -+					= vreg->corner[i - 1].target_quot[j];
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_enforce_dec_quotient_monotonicity() - Ensure that target quotients
 | |
| -+ *		decrease monotonically from higher to lower corners
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static void cpr3_enforce_dec_quotient_monotonicity(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	int i, j;
 | |
| -+
 | |
| -+	for (i = vreg->corner_count - 2; i >= 0; i--) {
 | |
| -+		for (j = 0; j < CPR3_RO_COUNT; j++) {
 | |
| -+			if (vreg->corner[i + 1].target_quot[j]
 | |
| -+			    && vreg->corner[i].target_quot[j]
 | |
| -+					> vreg->corner[i + 1].target_quot[j]) {
 | |
| -+				cpr3_debug(vreg, "corner %d RO%u target quot=%u > corner %d RO%u target quot=%u; overriding: corner %d RO%u target quot=%u\n",
 | |
| -+					i, j,
 | |
| -+					vreg->corner[i].target_quot[j],
 | |
| -+					i + 1, j,
 | |
| -+					vreg->corner[i + 1].target_quot[j],
 | |
| -+					i, j,
 | |
| -+					vreg->corner[i + 1].target_quot[j]);
 | |
| -+				vreg->corner[i].target_quot[j]
 | |
| -+					= vreg->corner[i + 1].target_quot[j];
 | |
| -+			}
 | |
| -+		}
 | |
| -+	}
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * _cpr3_adjust_target_quotients() - adjust the target quotients for each
 | |
| -+ *		corner of the regulator according to input adjustment and
 | |
| -+ *		scaling arrays
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @volt_adjust:	Pointer to an array of closed-loop voltage adjustments
 | |
| -+ *			with units of microvolts.  The array must have
 | |
| -+ *			vreg->corner_count number of elements.
 | |
| -+ * @ro_scale:		Pointer to a flattened 2D array of RO scaling factors.
 | |
| -+ *			The array must have an inner dimension of CPR3_RO_COUNT
 | |
| -+ *			and an outer dimension of vreg->corner_count
 | |
| -+ * @label:		Null terminated string providing a label for the type
 | |
| -+ *			of adjustment.
 | |
| -+ *
 | |
| -+ * Return: true if any corners received a positive voltage adjustment (> 0),
 | |
| -+ *	   else false
 | |
| -+ */
 | |
| -+static bool _cpr3_adjust_target_quotients(struct cpr3_regulator *vreg,
 | |
| -+		const int *volt_adjust, const int *ro_scale, const char *label)
 | |
| -+{
 | |
| -+	int i, j, quot_adjust;
 | |
| -+	bool is_increasing = false;
 | |
| -+	u32 prev_quot;
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		for (j = 0; j < CPR3_RO_COUNT; j++) {
 | |
| -+			if (vreg->corner[i].target_quot[j]) {
 | |
| -+				quot_adjust = cpr3_quot_adjustment(
 | |
| -+					ro_scale[i * CPR3_RO_COUNT + j],
 | |
| -+					volt_adjust[i]);
 | |
| -+				if (quot_adjust) {
 | |
| -+					prev_quot = vreg->corner[i].
 | |
| -+							target_quot[j];
 | |
| -+					vreg->corner[i].target_quot[j]
 | |
| -+						+= quot_adjust;
 | |
| -+					cpr3_debug(vreg, "adjusted corner %d RO%d target quot %s: %u --> %u (%d uV)\n",
 | |
| -+						i, j, label, prev_quot,
 | |
| -+						vreg->corner[i].target_quot[j],
 | |
| -+						volt_adjust[i]);
 | |
| -+				}
 | |
| -+			}
 | |
| -+		}
 | |
| -+		if (volt_adjust[i] > 0)
 | |
| -+			is_increasing = true;
 | |
| -+	}
 | |
| -+
 | |
| -+	return is_increasing;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr3_adjust_target_quotients() - adjust the target quotients for each
 | |
| -+ *			corner according to device tree values and fuse values
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @fuse_volt_adjust:	Fused closed-loop voltage adjustment values of length
 | |
| -+ *			vreg->fuse_corner_count. This parameter could be null
 | |
| -+ *			pointer when no fused adjustments are needed.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+int cpr3_adjust_target_quotients(struct cpr3_regulator *vreg,
 | |
| -+			int *fuse_volt_adjust)
 | |
| -+{
 | |
| -+	int i, rc;
 | |
| -+	int *volt_adjust, *ro_scale;
 | |
| -+	bool explicit_adjustment, fused_adjustment, is_increasing;
 | |
| -+
 | |
| -+	explicit_adjustment = of_find_property(vreg->of_node,
 | |
| -+		"qcom,cpr-closed-loop-voltage-adjustment", NULL);
 | |
| -+	fused_adjustment = of_find_property(vreg->of_node,
 | |
| -+		"qcom,cpr-fused-closed-loop-voltage-adjustment-map", NULL);
 | |
| -+
 | |
| -+	if (!explicit_adjustment && !fused_adjustment && !vreg->aging_allowed) {
 | |
| -+		/* No adjustment required. */
 | |
| -+		return 0;
 | |
| -+	} else if (!of_find_property(vreg->of_node,
 | |
| -+			"qcom,cpr-ro-scaling-factor", NULL)) {
 | |
| -+		cpr3_err(vreg, "qcom,cpr-ro-scaling-factor is required for closed-loop voltage adjustment, but is missing\n");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	volt_adjust = kcalloc(vreg->corner_count, sizeof(*volt_adjust),
 | |
| -+				GFP_KERNEL);
 | |
| -+	ro_scale = kcalloc(vreg->corner_count * CPR3_RO_COUNT,
 | |
| -+				sizeof(*ro_scale), GFP_KERNEL);
 | |
| -+	if (!volt_adjust || !ro_scale) {
 | |
| -+		rc = -ENOMEM;
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_parse_corner_array_property(vreg,
 | |
| -+			"qcom,cpr-ro-scaling-factor", CPR3_RO_COUNT, ro_scale);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "could not load RO scaling factors, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++)
 | |
| -+		memcpy(vreg->corner[i].ro_scale, &ro_scale[i * CPR3_RO_COUNT],
 | |
| -+			sizeof(*ro_scale) * CPR3_RO_COUNT);
 | |
| -+
 | |
| -+	if (explicit_adjustment) {
 | |
| -+		rc = cpr3_parse_corner_array_property(vreg,
 | |
| -+			"qcom,cpr-closed-loop-voltage-adjustment",
 | |
| -+			1, volt_adjust);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "could not load closed-loop voltage adjustments, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+
 | |
| -+		_cpr3_adjust_target_quotients(vreg, volt_adjust, ro_scale,
 | |
| -+			"from DT");
 | |
| -+		cpr3_enforce_inc_quotient_monotonicity(vreg);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (fused_adjustment && fuse_volt_adjust) {
 | |
| -+		memset(volt_adjust, 0,
 | |
| -+			sizeof(*volt_adjust) * vreg->corner_count);
 | |
| -+
 | |
| -+		rc = cpr3_apply_closed_loop_offset_voltages(vreg, volt_adjust,
 | |
| -+				fuse_volt_adjust);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "could not apply fused closed-loop voltage reductions, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+
 | |
| -+		is_increasing = _cpr3_adjust_target_quotients(vreg, volt_adjust,
 | |
| -+					ro_scale, "from fuse");
 | |
| -+		if (is_increasing)
 | |
| -+			cpr3_enforce_inc_quotient_monotonicity(vreg);
 | |
| -+		else
 | |
| -+			cpr3_enforce_dec_quotient_monotonicity(vreg);
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	kfree(volt_adjust);
 | |
| -+	kfree(ro_scale);
 | |
| -+	return rc;
 | |
| -+}
 | |
| ---- /dev/null
 | |
| -+++ b/drivers/regulator/cpr4-apss-regulator.c
 | |
| -@@ -0,0 +1,1819 @@
 | |
| -+/*
 | |
| -+ * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
 | |
| -+ *
 | |
| -+ * This program is free software; you can redistribute it and/or modify
 | |
| -+ * it under the terms of the GNU General Public License version 2 and
 | |
| -+ * only version 2 as published by the Free Software Foundation.
 | |
| -+ *
 | |
| -+ * This program is distributed in the hope that it will be useful,
 | |
| -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| -+ * GNU General Public License for more details.
 | |
| -+ */
 | |
| -+
 | |
| -+#define pr_fmt(fmt) "%s: " fmt, __func__
 | |
| -+
 | |
| -+#include <linux/bitops.h>
 | |
| -+#include <linux/debugfs.h>
 | |
| -+#include <linux/err.h>
 | |
| -+#include <linux/init.h>
 | |
| -+#include <linux/interrupt.h>
 | |
| -+#include <linux/io.h>
 | |
| -+#include <linux/kernel.h>
 | |
| -+#include <linux/list.h>
 | |
| -+#include <linux/module.h>
 | |
| -+#include <linux/of.h>
 | |
| -+#include <linux/of_device.h>
 | |
| -+#include <linux/platform_device.h>
 | |
| -+#include <linux/pm_opp.h>
 | |
| -+#include <linux/slab.h>
 | |
| -+#include <linux/string.h>
 | |
| -+#include <linux/uaccess.h>
 | |
| -+#include <linux/regulator/driver.h>
 | |
| -+#include <linux/regulator/machine.h>
 | |
| -+#include <linux/regulator/of_regulator.h>
 | |
| -+
 | |
| -+#include "cpr3-regulator.h"
 | |
| -+
 | |
| -+#define IPQ807x_APSS_FUSE_CORNERS	4
 | |
| -+#define IPQ817x_APPS_FUSE_CORNERS	2
 | |
| -+#define IPQ6018_APSS_FUSE_CORNERS 	4
 | |
| -+#define IPQ9574_APSS_FUSE_CORNERS       4
 | |
| -+
 | |
| -+u32 g_valid_fuse_count = IPQ807x_APSS_FUSE_CORNERS;
 | |
| -+
 | |
| -+/**
 | |
| -+ * struct cpr4_ipq807x_apss_fuses - APSS specific fuse data for IPQ807x
 | |
| -+ * @ro_sel:		Ring oscillator select fuse parameter value for each
 | |
| -+ *			fuse corner
 | |
| -+ * @init_voltage:	Initial (i.e. open-loop) voltage fuse parameter value
 | |
| -+ *			for each fuse corner (raw, not converted to a voltage)
 | |
| -+ * @target_quot:	CPR target quotient fuse parameter value for each fuse
 | |
| -+ *			corner
 | |
| -+ * @quot_offset:	CPR target quotient offset fuse parameter value for each
 | |
| -+ *			fuse corner (raw, not unpacked) used for target quotient
 | |
| -+ *			interpolation
 | |
| -+ * @speed_bin:		Application processor speed bin fuse parameter value for
 | |
| -+ *			the given chip
 | |
| -+ * @cpr_fusing_rev:	CPR fusing revision fuse parameter value
 | |
| -+ * @boost_cfg:		CPR boost configuration fuse parameter value
 | |
| -+ * @boost_voltage:	CPR boost voltage fuse parameter value (raw, not
 | |
| -+ *			converted to a voltage)
 | |
| -+ *
 | |
| -+ * This struct holds the values for all of the fuses read from memory.
 | |
| -+ */
 | |
| -+struct cpr4_ipq807x_apss_fuses {
 | |
| -+	u64	ro_sel[IPQ807x_APSS_FUSE_CORNERS];
 | |
| -+	u64	init_voltage[IPQ807x_APSS_FUSE_CORNERS];
 | |
| -+	u64	target_quot[IPQ807x_APSS_FUSE_CORNERS];
 | |
| -+	u64	quot_offset[IPQ807x_APSS_FUSE_CORNERS];
 | |
| -+	u64	speed_bin;
 | |
| -+	u64	cpr_fusing_rev;
 | |
| -+	u64	boost_cfg;
 | |
| -+	u64	boost_voltage;
 | |
| -+	u64	misc;
 | |
| -+};
 | |
| -+
 | |
| -+/*
 | |
| -+ * fuse combo = fusing revision + 8 * (speed bin)
 | |
| -+ * where: fusing revision = 0 - 7 and speed bin = 0 - 7
 | |
| -+ */
 | |
| -+#define CPR4_IPQ807x_APSS_FUSE_COMBO_COUNT	64
 | |
| -+
 | |
| -+/*
 | |
| -+ * Constants which define the name of each fuse corner.
 | |
| -+ */
 | |
| -+enum cpr4_ipq807x_apss_fuse_corner {
 | |
| -+	CPR4_IPQ807x_APSS_FUSE_CORNER_SVS	= 0,
 | |
| -+	CPR4_IPQ807x_APSS_FUSE_CORNER_NOM	= 1,
 | |
| -+	CPR4_IPQ807x_APSS_FUSE_CORNER_TURBO	= 2,
 | |
| -+	CPR4_IPQ807x_APSS_FUSE_CORNER_STURBO	= 3,
 | |
| -+};
 | |
| -+
 | |
| -+static const char * const cpr4_ipq807x_apss_fuse_corner_name[] = {
 | |
| -+	[CPR4_IPQ807x_APSS_FUSE_CORNER_SVS]	= "SVS",
 | |
| -+	[CPR4_IPQ807x_APSS_FUSE_CORNER_NOM]	= "NOM",
 | |
| -+	[CPR4_IPQ807x_APSS_FUSE_CORNER_TURBO]	= "TURBO",
 | |
| -+	[CPR4_IPQ807x_APSS_FUSE_CORNER_STURBO]	= "STURBO",
 | |
| -+};
 | |
| -+
 | |
| -+/*
 | |
| -+ * IPQ807x APSS fuse parameter locations:
 | |
| -+ *
 | |
| -+ * Structs are organized with the following dimensions:
 | |
| -+ *	Outer: 0 to 3 for fuse corners from lowest to highest corner
 | |
| -+ *	Inner: large enough to hold the longest set of parameter segments which
 | |
| -+ *		fully defines a fuse parameter, +1 (for NULL termination).
 | |
| -+ *		Each segment corresponds to a contiguous group of bits from a
 | |
| -+ *		single fuse row.  These segments are concatentated together in
 | |
| -+ *		order to form the full fuse parameter value.  The segments for
 | |
| -+ *		a given parameter may correspond to different fuse rows.
 | |
| -+ */
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq807x_apss_ro_sel_param[IPQ807x_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{73,  8, 11}, {} },
 | |
| -+	{{73,  4,  7}, {} },
 | |
| -+	{{73,  0,  3}, {} },
 | |
| -+	{{73, 12, 15}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq807x_apss_init_voltage_param[IPQ807x_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{71, 18, 23}, {} },
 | |
| -+	{{71, 12, 17}, {} },
 | |
| -+	{{71,  6, 11}, {} },
 | |
| -+	{{71,  0,  5}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq807x_apss_target_quot_param[IPQ807x_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{72, 32, 43}, {} },
 | |
| -+	{{72, 20, 31}, {} },
 | |
| -+	{{72,  8, 19}, {} },
 | |
| -+	{{72, 44, 55}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq807x_apss_quot_offset_param[IPQ807x_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{} },
 | |
| -+	{{71, 46, 52}, {} },
 | |
| -+	{{71, 39, 45}, {} },
 | |
| -+	{{71, 32, 38}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq807x_cpr_fusing_rev_param[] = {
 | |
| -+	{71, 53, 55},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq807x_apss_speed_bin_param[] = {
 | |
| -+	{36, 40, 42},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq807x_cpr_boost_fuse_cfg_param[] = {
 | |
| -+	{36, 43, 45},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq807x_apss_boost_fuse_volt_param[] = {
 | |
| -+	{71, 0, 5},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq807x_misc_fuse_volt_adj_param[] = {
 | |
| -+	{36, 54, 54},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_parameters ipq807x_fuse_params = {
 | |
| -+	.apss_ro_sel_param = ipq807x_apss_ro_sel_param,
 | |
| -+	.apss_init_voltage_param = ipq807x_apss_init_voltage_param,
 | |
| -+	.apss_target_quot_param = ipq807x_apss_target_quot_param,
 | |
| -+	.apss_quot_offset_param = ipq807x_apss_quot_offset_param,
 | |
| -+	.cpr_fusing_rev_param = ipq807x_cpr_fusing_rev_param,
 | |
| -+	.apss_speed_bin_param = ipq807x_apss_speed_bin_param,
 | |
| -+	.cpr_boost_fuse_cfg_param = ipq807x_cpr_boost_fuse_cfg_param,
 | |
| -+	.apss_boost_fuse_volt_param = ipq807x_apss_boost_fuse_volt_param,
 | |
| -+	.misc_fuse_volt_adj_param = ipq807x_misc_fuse_volt_adj_param
 | |
| -+};
 | |
| -+
 | |
| -+/*
 | |
| -+ * The number of possible values for misc fuse is
 | |
| -+ * 2^(#bits defined for misc fuse)
 | |
| -+ */
 | |
| -+#define IPQ807x_MISC_FUSE_VAL_COUNT		BIT(1)
 | |
| -+
 | |
| -+/*
 | |
| -+ * Open loop voltage fuse reference voltages in microvolts for IPQ807x
 | |
| -+ */
 | |
| -+static int ipq807x_apss_fuse_ref_volt
 | |
| -+	[IPQ807x_APSS_FUSE_CORNERS] = {
 | |
| -+	720000,
 | |
| -+	864000,
 | |
| -+	992000,
 | |
| -+	1064000,
 | |
| -+};
 | |
| -+
 | |
| -+#define IPQ807x_APSS_FUSE_STEP_VOLT		8000
 | |
| -+#define IPQ807x_APSS_VOLTAGE_FUSE_SIZE	6
 | |
| -+#define IPQ807x_APSS_QUOT_OFFSET_SCALE	5
 | |
| -+
 | |
| -+#define IPQ807x_APSS_CPR_SENSOR_COUNT	6
 | |
| -+
 | |
| -+#define IPQ807x_APSS_CPR_CLOCK_RATE		19200000
 | |
| -+
 | |
| -+#define IPQ807x_APSS_MAX_TEMP_POINTS	3
 | |
| -+#define IPQ807x_APSS_TEMP_SENSOR_ID_START	4
 | |
| -+#define IPQ807x_APSS_TEMP_SENSOR_ID_END	13
 | |
| -+/*
 | |
| -+ * Boost voltage fuse reference and ceiling voltages in microvolts for
 | |
| -+ * IPQ807x.
 | |
| -+ */
 | |
| -+#define IPQ807x_APSS_BOOST_FUSE_REF_VOLT	1140000
 | |
| -+#define IPQ807x_APSS_BOOST_CEILING_VOLT	1140000
 | |
| -+#define IPQ807x_APSS_BOOST_FLOOR_VOLT	900000
 | |
| -+#define MAX_BOOST_CONFIG_FUSE_VALUE		8
 | |
| -+
 | |
| -+#define IPQ807x_APSS_CPR_SDELTA_CORE_COUNT	15
 | |
| -+
 | |
| -+#define IPQ807x_APSS_CPR_TCSR_START		8
 | |
| -+#define IPQ807x_APSS_CPR_TCSR_END		9
 | |
| -+
 | |
| -+/*
 | |
| -+ * Array of integer values mapped to each of the boost config fuse values to
 | |
| -+ * indicate boost enable/disable status.
 | |
| -+ */
 | |
| -+static bool boost_fuse[MAX_BOOST_CONFIG_FUSE_VALUE] = {0, 1, 1, 1, 1, 1, 1, 1};
 | |
| -+
 | |
| -+/*
 | |
| -+ * IPQ6018 (Few parameters are changed, remaining are same as IPQ807x)
 | |
| -+ */
 | |
| -+#define IPQ6018_APSS_FUSE_STEP_VOLT		12500
 | |
| -+#define IPQ6018_APSS_CPR_CLOCK_RATE		24000000
 | |
| -+
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq6018_apss_ro_sel_param[IPQ6018_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{75,  8, 11}, {} },
 | |
| -+	{{75,  4,  7}, {} },
 | |
| -+	{{75,  0,  3}, {} },
 | |
| -+	{{75, 12, 15}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq6018_apss_init_voltage_param[IPQ6018_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{73, 18, 23}, {} },
 | |
| -+	{{73, 12, 17}, {} },
 | |
| -+	{{73,  6, 11}, {} },
 | |
| -+	{{73,  0,  5}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq6018_apss_target_quot_param[IPQ6018_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{74, 32, 43}, {} },
 | |
| -+	{{74, 20, 31}, {} },
 | |
| -+	{{74,  8, 19}, {} },
 | |
| -+	{{74, 44, 55}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq6018_apss_quot_offset_param[IPQ6018_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{} },
 | |
| -+	{{73, 48, 55}, {} },
 | |
| -+	{{73, 40, 47}, {} },
 | |
| -+	{{73, 32, 39}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq6018_cpr_fusing_rev_param[] = {
 | |
| -+	{75, 16, 18},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq6018_apss_speed_bin_param[] = {
 | |
| -+	{36, 40, 42},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq6018_cpr_boost_fuse_cfg_param[] = {
 | |
| -+	{36, 43, 45},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq6018_apss_boost_fuse_volt_param[] = {
 | |
| -+	{73, 0, 5},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq6018_misc_fuse_volt_adj_param[] = {
 | |
| -+	{36, 54, 54},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_parameters ipq6018_fuse_params = {
 | |
| -+	.apss_ro_sel_param = ipq6018_apss_ro_sel_param,
 | |
| -+	.apss_init_voltage_param = ipq6018_apss_init_voltage_param,
 | |
| -+	.apss_target_quot_param = ipq6018_apss_target_quot_param,
 | |
| -+	.apss_quot_offset_param = ipq6018_apss_quot_offset_param,
 | |
| -+	.cpr_fusing_rev_param = ipq6018_cpr_fusing_rev_param,
 | |
| -+	.apss_speed_bin_param = ipq6018_apss_speed_bin_param,
 | |
| -+	.cpr_boost_fuse_cfg_param = ipq6018_cpr_boost_fuse_cfg_param,
 | |
| -+	.apss_boost_fuse_volt_param = ipq6018_apss_boost_fuse_volt_param,
 | |
| -+	.misc_fuse_volt_adj_param = ipq6018_misc_fuse_volt_adj_param
 | |
| -+};
 | |
| -+
 | |
| -+
 | |
| -+/*
 | |
| -+ * Boost voltage fuse reference and ceiling voltages in microvolts for
 | |
| -+ * IPQ6018.
 | |
| -+ */
 | |
| -+#define IPQ6018_APSS_BOOST_FUSE_REF_VOLT	1140000
 | |
| -+#define IPQ6018_APSS_BOOST_CEILING_VOLT	1140000
 | |
| -+#define IPQ6018_APSS_BOOST_FLOOR_VOLT	900000
 | |
| -+
 | |
| -+/*
 | |
| -+ * Open loop voltage fuse reference voltages in microvolts for IPQ807x
 | |
| -+ */
 | |
| -+static int ipq6018_apss_fuse_ref_volt
 | |
| -+	[IPQ6018_APSS_FUSE_CORNERS] = {
 | |
| -+	725000,
 | |
| -+	862500,
 | |
| -+	987500,
 | |
| -+	1062500,
 | |
| -+};
 | |
| -+
 | |
| -+/*
 | |
| -+ * IPQ6018 Memory ACC settings on TCSR
 | |
| -+ *
 | |
| -+ * Turbo_L1: write TCSR_MEM_ACC_SW_OVERRIDE_LEGACY_APC0 0x10
 | |
| -+ *           write TCSR_CUSTOM_VDDAPC0_ACC_1            0x1
 | |
| -+ * Other modes: write TCSR_MEM_ACC_SW_OVERRIDE_LEGACY_APC0 0x0
 | |
| -+ *              write TCSR_CUSTOM_VDDAPC0_ACC_1            0x0
 | |
| -+ *
 | |
| -+ */
 | |
| -+#define IPQ6018_APSS_MEM_ACC_TCSR_COUNT         2
 | |
| -+#define TCSR_MEM_ACC_SW_OVERRIDE_LEGACY_APC0    0x1946178
 | |
| -+#define TCSR_CUSTOM_VDDAPC0_ACC_1               0x1946124
 | |
| -+
 | |
| -+struct mem_acc_tcsr {
 | |
| -+	u32 phy_addr;
 | |
| -+	void __iomem *ioremap_addr;
 | |
| -+	u32 value;
 | |
| -+};
 | |
| -+
 | |
| -+static struct mem_acc_tcsr ipq6018_mem_acc_tcsr[IPQ6018_APSS_MEM_ACC_TCSR_COUNT] = {
 | |
| -+	{TCSR_MEM_ACC_SW_OVERRIDE_LEGACY_APC0, NULL, 0x10},
 | |
| -+	{TCSR_CUSTOM_VDDAPC0_ACC_1, NULL, 0x1},
 | |
| -+};
 | |
| -+
 | |
| -+/*
 | |
| -+ * IPQ9574 (Few parameters are changed, remaining are same as IPQ6018)
 | |
| -+ */
 | |
| -+#define IPQ9574_APSS_FUSE_STEP_VOLT             10000
 | |
| -+
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq9574_apss_ro_sel_param[IPQ9574_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{107, 4, 7}, {} },
 | |
| -+	{{107, 0, 3}, {} },
 | |
| -+	{{106, 4, 7}, {} },
 | |
| -+	{{106, 0, 3}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq9574_apss_init_voltage_param[IPQ9574_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{104, 24, 29}, {} },
 | |
| -+	{{104, 18, 23}, {} },
 | |
| -+	{{104, 12, 17}, {} },
 | |
| -+	{{104,  6, 11}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq9574_apss_target_quot_param[IPQ9574_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{106, 32, 43}, {} },
 | |
| -+	{{106, 20, 31}, {} },
 | |
| -+	{{106,  8, 19}, {} },
 | |
| -+	{{106, 44, 55}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param
 | |
| -+ipq9574_apss_quot_offset_param[IPQ9574_APSS_FUSE_CORNERS][2] = {
 | |
| -+	{{} },
 | |
| -+	{{105, 48, 55}, {} },
 | |
| -+	{{105, 40, 47}, {} },
 | |
| -+	{{105, 32, 39}, {} },
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq9574_cpr_fusing_rev_param[] = {
 | |
| -+	{107, 8, 10},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq9574_apss_speed_bin_param[] = {
 | |
| -+	{0, 40, 42},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq9574_cpr_boost_fuse_cfg_param[] = {
 | |
| -+	{0, 43, 45},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq9574_apss_boost_fuse_volt_param[] = {
 | |
| -+	{104, 0, 5},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_param ipq9574_misc_fuse_volt_adj_param[] = {
 | |
| -+	{0, 54, 54},
 | |
| -+	{},
 | |
| -+};
 | |
| -+
 | |
| -+static struct cpr3_fuse_parameters ipq9574_fuse_params = {
 | |
| -+	.apss_ro_sel_param = ipq9574_apss_ro_sel_param,
 | |
| -+	.apss_init_voltage_param = ipq9574_apss_init_voltage_param,
 | |
| -+	.apss_target_quot_param = ipq9574_apss_target_quot_param,
 | |
| -+	.apss_quot_offset_param = ipq9574_apss_quot_offset_param,
 | |
| -+	.cpr_fusing_rev_param = ipq9574_cpr_fusing_rev_param,
 | |
| -+	.apss_speed_bin_param = ipq9574_apss_speed_bin_param,
 | |
| -+	.cpr_boost_fuse_cfg_param = ipq9574_cpr_boost_fuse_cfg_param,
 | |
| -+	.apss_boost_fuse_volt_param = ipq9574_apss_boost_fuse_volt_param,
 | |
| -+	.misc_fuse_volt_adj_param = ipq9574_misc_fuse_volt_adj_param
 | |
| -+};
 | |
| -+
 | |
| -+/*
 | |
| -+ * Open loop voltage fuse reference voltages in microvolts for IPQ9574
 | |
| -+ */
 | |
| -+static int ipq9574_apss_fuse_ref_volt
 | |
| -+	[IPQ9574_APSS_FUSE_CORNERS] = {
 | |
| -+	725000,
 | |
| -+	862500,
 | |
| -+	987500,
 | |
| -+	1062500,
 | |
| -+};
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_ipq807x_apss_read_fuse_data() - load APSS specific fuse parameter values
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * This function allocates a cpr4_ipq807x_apss_fuses struct, fills it with
 | |
| -+ * values read out of hardware fuses, and finally copies common fuse values
 | |
| -+ * into the CPR3 regulator struct.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_ipq807x_apss_read_fuse_data(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	void __iomem *base = vreg->thread->ctrl->fuse_base;
 | |
| -+	struct cpr4_ipq807x_apss_fuses *fuse;
 | |
| -+	int i, rc;
 | |
| -+
 | |
| -+	fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL);
 | |
| -+	if (!fuse)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	rc = cpr3_read_fuse_param(base, vreg->cpr4_regulator_data->cpr3_fuse_params->apss_speed_bin_param,
 | |
| -+				  &fuse->speed_bin);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "Unable to read speed bin fuse, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+	cpr3_info(vreg, "speed bin = %llu\n", fuse->speed_bin);
 | |
| -+
 | |
| -+	rc = cpr3_read_fuse_param(base, vreg->cpr4_regulator_data->cpr3_fuse_params->cpr_fusing_rev_param,
 | |
| -+				  &fuse->cpr_fusing_rev);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "Unable to read CPR fusing revision fuse, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+	cpr3_info(vreg, "CPR fusing revision = %llu\n", fuse->cpr_fusing_rev);
 | |
| -+
 | |
| -+	rc = cpr3_read_fuse_param(base, vreg->cpr4_regulator_data->cpr3_fuse_params->misc_fuse_volt_adj_param,
 | |
| -+				  &fuse->misc);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "Unable to read misc voltage adjustment fuse, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+	cpr3_info(vreg, "CPR misc fuse value = %llu\n", fuse->misc);
 | |
| -+	if (fuse->misc >= IPQ807x_MISC_FUSE_VAL_COUNT) {
 | |
| -+		cpr3_err(vreg, "CPR misc fuse value = %llu, should be < %lu\n",
 | |
| -+			fuse->misc, IPQ807x_MISC_FUSE_VAL_COUNT);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < g_valid_fuse_count; i++) {
 | |
| -+		rc = cpr3_read_fuse_param(base,
 | |
| -+				vreg->cpr4_regulator_data->cpr3_fuse_params->apss_init_voltage_param[i],
 | |
| -+				&fuse->init_voltage[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "Unable to read fuse-corner %d initial voltage fuse, rc=%d\n",
 | |
| -+				i, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		rc = cpr3_read_fuse_param(base,
 | |
| -+				vreg->cpr4_regulator_data->cpr3_fuse_params->apss_target_quot_param[i],
 | |
| -+				&fuse->target_quot[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "Unable to read fuse-corner %d target quotient fuse, rc=%d\n",
 | |
| -+				i, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		rc = cpr3_read_fuse_param(base,
 | |
| -+				vreg->cpr4_regulator_data->cpr3_fuse_params->apss_ro_sel_param[i],
 | |
| -+				&fuse->ro_sel[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "Unable to read fuse-corner %d RO select fuse, rc=%d\n",
 | |
| -+				i, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		rc = cpr3_read_fuse_param(base,
 | |
| -+				vreg->cpr4_regulator_data->cpr3_fuse_params->apss_quot_offset_param[i],
 | |
| -+				&fuse->quot_offset[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "Unable to read fuse-corner %d quotient offset fuse, rc=%d\n",
 | |
| -+				i, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_read_fuse_param(base, vreg->cpr4_regulator_data->cpr3_fuse_params->cpr_boost_fuse_cfg_param,
 | |
| -+				  &fuse->boost_cfg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "Unable to read CPR boost config fuse, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+	cpr3_info(vreg, "Voltage boost fuse config = %llu boost = %s\n",
 | |
| -+			fuse->boost_cfg, boost_fuse[fuse->boost_cfg]
 | |
| -+			? "enable" : "disable");
 | |
| -+
 | |
| -+	rc = cpr3_read_fuse_param(base,
 | |
| -+				vreg->cpr4_regulator_data->cpr3_fuse_params->apss_boost_fuse_volt_param,
 | |
| -+				&fuse->boost_voltage);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "failed to read boost fuse voltage, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->fuse_combo = fuse->cpr_fusing_rev + 8 * fuse->speed_bin;
 | |
| -+	if (vreg->fuse_combo >= CPR4_IPQ807x_APSS_FUSE_COMBO_COUNT) {
 | |
| -+		cpr3_err(vreg, "invalid CPR fuse combo = %d found\n",
 | |
| -+			vreg->fuse_combo);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	vreg->speed_bin_fuse	= fuse->speed_bin;
 | |
| -+	vreg->cpr_rev_fuse	= fuse->cpr_fusing_rev;
 | |
| -+	vreg->fuse_corner_count	= g_valid_fuse_count;
 | |
| -+	vreg->platform_fuses	= fuse;
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_apss_parse_corner_data() - parse APSS corner data from device tree
 | |
| -+ *		properties of the CPR3 regulator's device node
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_apss_parse_corner_data(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct device_node *node = vreg->of_node;
 | |
| -+	struct cpr4_ipq807x_apss_fuses *fuse = vreg->platform_fuses;
 | |
| -+	u32 *temp = NULL;
 | |
| -+	int i, rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_common_corner_data(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "error reading corner data, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	/* If fuse has incorrect RO Select values and dtsi has "qcom,cpr-ro-sel"
 | |
| -+	 * entry with RO select values other than zero, then dtsi values will
 | |
| -+	 * be used.
 | |
| -+	 */
 | |
| -+	if (of_find_property(node, "qcom,cpr-ro-sel", NULL)) {
 | |
| -+		temp = kcalloc(vreg->fuse_corner_count, sizeof(*temp),
 | |
| -+				GFP_KERNEL);
 | |
| -+		if (!temp)
 | |
| -+			return -ENOMEM;
 | |
| -+
 | |
| -+		rc = cpr3_parse_array_property(vreg, "qcom,cpr-ro-sel",
 | |
| -+				vreg->fuse_corner_count, temp);
 | |
| -+		if (rc)
 | |
| -+			goto done;
 | |
| -+
 | |
| -+		for (i = 0; i < vreg->fuse_corner_count; i++) {
 | |
| -+			if (temp[i] != 0)
 | |
| -+				fuse->ro_sel[i] = temp[i];
 | |
| -+		}
 | |
| -+	}
 | |
| -+done:
 | |
| -+	kfree(temp);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_apss_parse_misc_fuse_voltage_adjustments() - fill an array from a
 | |
| -+ *		portion of the voltage adjustments specified based on
 | |
| -+ *		miscellaneous fuse bits.
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @volt_adjust:	Voltage adjustment output data array which must be
 | |
| -+ *			of size vreg->corner_count
 | |
| -+ *
 | |
| -+ * cpr3_parse_common_corner_data() must be called for vreg before this function
 | |
| -+ * is called so that speed bin size elements are initialized.
 | |
| -+ *
 | |
| -+ * Two formats are supported for the device tree property:
 | |
| -+ * 1. Length == tuple_list_size * vreg->corner_count
 | |
| -+ *	(reading begins at index 0)
 | |
| -+ * 2. Length == tuple_list_size * vreg->speed_bin_corner_sum
 | |
| -+ *	(reading begins at index tuple_list_size * vreg->speed_bin_offset)
 | |
| -+ *
 | |
| -+ * Here, tuple_list_size is the number of possible values for misc fuse.
 | |
| -+ * All other property lengths are treated as errors.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_apss_parse_misc_fuse_voltage_adjustments(
 | |
| -+	struct cpr3_regulator *vreg, u32 *volt_adjust)
 | |
| -+{
 | |
| -+	struct device_node *node = vreg->of_node;
 | |
| -+	struct cpr4_ipq807x_apss_fuses *fuse = vreg->platform_fuses;
 | |
| -+	int tuple_list_size = IPQ807x_MISC_FUSE_VAL_COUNT;
 | |
| -+	int i, offset, rc, len = 0;
 | |
| -+	const char *prop_name = "qcom,cpr-misc-fuse-voltage-adjustment";
 | |
| -+
 | |
| -+	if (!of_find_property(node, prop_name, &len)) {
 | |
| -+		cpr3_err(vreg, "property %s is missing\n", prop_name);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (len == tuple_list_size * vreg->corner_count * sizeof(u32)) {
 | |
| -+		offset = 0;
 | |
| -+	} else if (vreg->speed_bin_corner_sum > 0 &&
 | |
| -+			len == tuple_list_size * vreg->speed_bin_corner_sum
 | |
| -+			* sizeof(u32)) {
 | |
| -+		offset = tuple_list_size * vreg->speed_bin_offset
 | |
| -+			+ fuse->misc * vreg->corner_count;
 | |
| -+	} else {
 | |
| -+		if (vreg->speed_bin_corner_sum > 0)
 | |
| -+			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu or %zu\n",
 | |
| -+				prop_name, len,
 | |
| -+				tuple_list_size * vreg->corner_count
 | |
| -+					* sizeof(u32),
 | |
| -+				tuple_list_size * vreg->speed_bin_corner_sum
 | |
| -+					* sizeof(u32));
 | |
| -+		else
 | |
| -+			cpr3_err(vreg, "property %s has invalid length=%d, should be %zu\n",
 | |
| -+				prop_name, len,
 | |
| -+				tuple_list_size * vreg->corner_count
 | |
| -+				* sizeof(u32));
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		rc = of_property_read_u32_index(node, prop_name, offset + i,
 | |
| -+						&volt_adjust[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "error reading property %s, rc=%d\n",
 | |
| -+				prop_name, rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_ipq807x_apss_calculate_open_loop_voltages() - calculate the open-loop
 | |
| -+ *		voltage for each corner of a CPR3 regulator
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * If open-loop voltage interpolation is allowed in device tree, then
 | |
| -+ * this function calculates the open-loop voltage for a given corner using
 | |
| -+ * linear interpolation.  This interpolation is performed using the processor
 | |
| -+ * frequencies of the lower and higher Fmax corners along with their fused
 | |
| -+ * open-loop voltages.
 | |
| -+ *
 | |
| -+ * If open-loop voltage interpolation is not allowed, then this function uses
 | |
| -+ * the Fmax fused open-loop voltage for all of the corners associated with a
 | |
| -+ * given fuse corner.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_ipq807x_apss_calculate_open_loop_voltages(
 | |
| -+			struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct device_node *node = vreg->of_node;
 | |
| -+	struct cpr4_ipq807x_apss_fuses *fuse = vreg->platform_fuses;
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	int i, j, rc = 0;
 | |
| -+	bool allow_interpolation;
 | |
| -+	u64 freq_low, volt_low, freq_high, volt_high;
 | |
| -+	int *fuse_volt, *misc_adj_volt;
 | |
| -+	int *fmax_corner;
 | |
| -+
 | |
| -+	fuse_volt = kcalloc(vreg->fuse_corner_count, sizeof(*fuse_volt),
 | |
| -+				GFP_KERNEL);
 | |
| -+	fmax_corner = kcalloc(vreg->fuse_corner_count, sizeof(*fmax_corner),
 | |
| -+				GFP_KERNEL);
 | |
| -+	if (!fuse_volt || !fmax_corner) {
 | |
| -+		rc = -ENOMEM;
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->fuse_corner_count; i++) {
 | |
| -+		if (ctrl->cpr_global_setting == CPR_DISABLED)
 | |
| -+			fuse_volt[i] = vreg->cpr4_regulator_data->fuse_ref_volt[i];
 | |
| -+		else
 | |
| -+			fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse(
 | |
| -+				vreg->cpr4_regulator_data->fuse_ref_volt[i],
 | |
| -+				vreg->cpr4_regulator_data->fuse_step_volt,
 | |
| -+				fuse->init_voltage[i],
 | |
| -+				IPQ807x_APSS_VOLTAGE_FUSE_SIZE);
 | |
| -+
 | |
| -+		/* Log fused open-loop voltage values for debugging purposes. */
 | |
| -+		cpr3_info(vreg, "fused %8s: open-loop=%7d uV\n",
 | |
| -+			  cpr4_ipq807x_apss_fuse_corner_name[i],
 | |
| -+			  fuse_volt[i]);
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_determine_part_type(vreg,
 | |
| -+			  fuse_volt[vreg->fuse_corner_count - 1]);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "fused part type detection failed failed, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_adjust_fused_open_loop_voltages(vreg, fuse_volt);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "fused open-loop voltage adjustment failed, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	allow_interpolation = of_property_read_bool(node,
 | |
| -+				"qcom,allow-voltage-interpolation");
 | |
| -+
 | |
| -+	for (i = 1; i < vreg->fuse_corner_count; i++) {
 | |
| -+		if (fuse_volt[i] < fuse_volt[i - 1]) {
 | |
| -+			cpr3_info(vreg, "fuse corner %d voltage=%d uV < fuse corner %d voltage=%d uV; overriding: fuse corner %d voltage=%d\n",
 | |
| -+				i, fuse_volt[i], i - 1, fuse_volt[i - 1],
 | |
| -+				i, fuse_volt[i - 1]);
 | |
| -+			fuse_volt[i] = fuse_volt[i - 1];
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!allow_interpolation) {
 | |
| -+		/* Use fused open-loop voltage for lower frequencies. */
 | |
| -+		for (i = 0; i < vreg->corner_count; i++)
 | |
| -+			vreg->corner[i].open_loop_volt
 | |
| -+				= fuse_volt[vreg->corner[i].cpr_fuse_corner];
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Determine highest corner mapped to each fuse corner */
 | |
| -+	j = vreg->fuse_corner_count - 1;
 | |
| -+	for (i = vreg->corner_count - 1; i >= 0; i--) {
 | |
| -+		if (vreg->corner[i].cpr_fuse_corner == j) {
 | |
| -+			fmax_corner[j] = i;
 | |
| -+			j--;
 | |
| -+		}
 | |
| -+	}
 | |
| -+	if (j >= 0) {
 | |
| -+		cpr3_err(vreg, "invalid fuse corner mapping\n");
 | |
| -+		rc = -EINVAL;
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Interpolation is not possible for corners mapped to the lowest fuse
 | |
| -+	 * corner so use the fuse corner value directly.
 | |
| -+	 */
 | |
| -+	for (i = 0; i <= fmax_corner[0]; i++)
 | |
| -+		vreg->corner[i].open_loop_volt = fuse_volt[0];
 | |
| -+
 | |
| -+	/* Interpolate voltages for the higher fuse corners. */
 | |
| -+	for (i = 1; i < vreg->fuse_corner_count; i++) {
 | |
| -+		freq_low = vreg->corner[fmax_corner[i - 1]].proc_freq;
 | |
| -+		volt_low = fuse_volt[i - 1];
 | |
| -+		freq_high = vreg->corner[fmax_corner[i]].proc_freq;
 | |
| -+		volt_high = fuse_volt[i];
 | |
| -+
 | |
| -+		for (j = fmax_corner[i - 1] + 1; j <= fmax_corner[i]; j++)
 | |
| -+			vreg->corner[j].open_loop_volt = cpr3_interpolate(
 | |
| -+				freq_low, volt_low, freq_high, volt_high,
 | |
| -+				vreg->corner[j].proc_freq);
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	if (rc == 0) {
 | |
| -+		cpr3_debug(vreg, "unadjusted per-corner open-loop voltages:\n");
 | |
| -+		for (i = 0; i < vreg->corner_count; i++)
 | |
| -+			cpr3_debug(vreg, "open-loop[%2d] = %d uV\n", i,
 | |
| -+				vreg->corner[i].open_loop_volt);
 | |
| -+
 | |
| -+		rc = cpr3_adjust_open_loop_voltages(vreg);
 | |
| -+		if (rc)
 | |
| -+			cpr3_err(vreg, "open-loop voltage adjustment failed, rc=%d\n",
 | |
| -+				rc);
 | |
| -+
 | |
| -+		if (of_find_property(node,
 | |
| -+			"qcom,cpr-misc-fuse-voltage-adjustment",
 | |
| -+			NULL)) {
 | |
| -+			misc_adj_volt = kcalloc(vreg->corner_count,
 | |
| -+					sizeof(*misc_adj_volt), GFP_KERNEL);
 | |
| -+			if (!misc_adj_volt) {
 | |
| -+				rc = -ENOMEM;
 | |
| -+				goto _exit;
 | |
| -+			}
 | |
| -+
 | |
| -+			rc = cpr4_apss_parse_misc_fuse_voltage_adjustments(vreg,
 | |
| -+				misc_adj_volt);
 | |
| -+			if (rc) {
 | |
| -+				cpr3_err(vreg, "qcom,cpr-misc-fuse-voltage-adjustment reading failed, rc=%d\n",
 | |
| -+					rc);
 | |
| -+				kfree(misc_adj_volt);
 | |
| -+				goto _exit;
 | |
| -+			}
 | |
| -+
 | |
| -+			for (i = 0; i < vreg->corner_count; i++)
 | |
| -+				vreg->corner[i].open_loop_volt
 | |
| -+						+= misc_adj_volt[i];
 | |
| -+			kfree(misc_adj_volt);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+_exit:
 | |
| -+	kfree(fuse_volt);
 | |
| -+	kfree(fmax_corner);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_ipq807x_apss_set_no_interpolation_quotients() - use the fused target
 | |
| -+ *		quotient values for lower frequencies.
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ * @volt_adjust:	Pointer to array of per-corner closed-loop adjustment
 | |
| -+ *			voltages
 | |
| -+ * @volt_adjust_fuse:	Pointer to array of per-fuse-corner closed-loop
 | |
| -+ *			adjustment voltages
 | |
| -+ * @ro_scale:		Pointer to array of per-fuse-corner RO scaling factor
 | |
| -+ *			values with units of QUOT/V
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_ipq807x_apss_set_no_interpolation_quotients(
 | |
| -+			struct cpr3_regulator *vreg, int *volt_adjust,
 | |
| -+			int *volt_adjust_fuse, int *ro_scale)
 | |
| -+{
 | |
| -+	struct cpr4_ipq807x_apss_fuses *fuse = vreg->platform_fuses;
 | |
| -+	u32 quot, ro;
 | |
| -+	int quot_adjust;
 | |
| -+	int i, fuse_corner;
 | |
| -+
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		fuse_corner = vreg->corner[i].cpr_fuse_corner;
 | |
| -+		quot = fuse->target_quot[fuse_corner];
 | |
| -+		quot_adjust = cpr3_quot_adjustment(ro_scale[fuse_corner],
 | |
| -+					   volt_adjust_fuse[fuse_corner] +
 | |
| -+					   volt_adjust[i]);
 | |
| -+		ro = fuse->ro_sel[fuse_corner];
 | |
| -+		vreg->corner[i].target_quot[ro] = quot + quot_adjust;
 | |
| -+		cpr3_debug(vreg, "corner=%d RO=%u target quot=%u\n",
 | |
| -+			  i, ro, quot);
 | |
| -+
 | |
| -+		if (quot_adjust)
 | |
| -+			cpr3_debug(vreg, "adjusted corner %d RO%u target quot: %u --> %u (%d uV)\n",
 | |
| -+				  i, ro, quot, vreg->corner[i].target_quot[ro],
 | |
| -+				  volt_adjust_fuse[fuse_corner] +
 | |
| -+				  volt_adjust[i]);
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_ipq807x_apss_calculate_target_quotients() - calculate the CPR target
 | |
| -+ *		quotient for each corner of a CPR3 regulator
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * If target quotient interpolation is allowed in device tree, then this
 | |
| -+ * function calculates the target quotient for a given corner using linear
 | |
| -+ * interpolation.  This interpolation is performed using the processor
 | |
| -+ * frequencies of the lower and higher Fmax corners along with the fused
 | |
| -+ * target quotient and quotient offset of the higher Fmax corner.
 | |
| -+ *
 | |
| -+ * If target quotient interpolation is not allowed, then this function uses
 | |
| -+ * the Fmax fused target quotient for all of the corners associated with a
 | |
| -+ * given fuse corner.
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_ipq807x_apss_calculate_target_quotients(
 | |
| -+			struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct cpr4_ipq807x_apss_fuses *fuse = vreg->platform_fuses;
 | |
| -+	int rc;
 | |
| -+	bool allow_interpolation;
 | |
| -+	u64 freq_low, freq_high, prev_quot;
 | |
| -+	u64 *quot_low;
 | |
| -+	u64 *quot_high;
 | |
| -+	u32 quot, ro;
 | |
| -+	int i, j, fuse_corner, quot_adjust;
 | |
| -+	int *fmax_corner;
 | |
| -+	int *volt_adjust, *volt_adjust_fuse, *ro_scale;
 | |
| -+	int *voltage_adj_misc;
 | |
| -+
 | |
| -+	/* Log fused quotient values for debugging purposes. */
 | |
| -+	for (i = CPR4_IPQ807x_APSS_FUSE_CORNER_SVS;
 | |
| -+		i < vreg->fuse_corner_count; i++)
 | |
| -+		cpr3_info(vreg, "fused %8s: quot[%2llu]=%4llu, quot_offset[%2llu]=%4llu\n",
 | |
| -+			cpr4_ipq807x_apss_fuse_corner_name[i],
 | |
| -+			fuse->ro_sel[i], fuse->target_quot[i],
 | |
| -+			fuse->ro_sel[i], fuse->quot_offset[i] *
 | |
| -+			IPQ807x_APSS_QUOT_OFFSET_SCALE);
 | |
| -+
 | |
| -+	allow_interpolation = of_property_read_bool(vreg->of_node,
 | |
| -+					"qcom,allow-quotient-interpolation");
 | |
| -+
 | |
| -+	volt_adjust = kcalloc(vreg->corner_count, sizeof(*volt_adjust),
 | |
| -+					GFP_KERNEL);
 | |
| -+	volt_adjust_fuse = kcalloc(vreg->fuse_corner_count,
 | |
| -+					sizeof(*volt_adjust_fuse), GFP_KERNEL);
 | |
| -+	ro_scale = kcalloc(vreg->fuse_corner_count, sizeof(*ro_scale),
 | |
| -+					GFP_KERNEL);
 | |
| -+	fmax_corner = kcalloc(vreg->fuse_corner_count, sizeof(*fmax_corner),
 | |
| -+					GFP_KERNEL);
 | |
| -+	quot_low = kcalloc(vreg->fuse_corner_count, sizeof(*quot_low),
 | |
| -+					GFP_KERNEL);
 | |
| -+	quot_high = kcalloc(vreg->fuse_corner_count, sizeof(*quot_high),
 | |
| -+					GFP_KERNEL);
 | |
| -+	if (!volt_adjust || !volt_adjust_fuse || !ro_scale ||
 | |
| -+	    !fmax_corner || !quot_low || !quot_high) {
 | |
| -+		rc = -ENOMEM;
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_parse_closed_loop_voltage_adjustments(vreg, &fuse->ro_sel[0],
 | |
| -+				volt_adjust, volt_adjust_fuse, ro_scale);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "could not load closed-loop voltage adjustments, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (of_find_property(vreg->of_node,
 | |
| -+		"qcom,cpr-misc-fuse-voltage-adjustment", NULL)) {
 | |
| -+		voltage_adj_misc = kcalloc(vreg->corner_count,
 | |
| -+				sizeof(*voltage_adj_misc), GFP_KERNEL);
 | |
| -+		if (!voltage_adj_misc) {
 | |
| -+			rc = -ENOMEM;
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+
 | |
| -+		rc = cpr4_apss_parse_misc_fuse_voltage_adjustments(vreg,
 | |
| -+			voltage_adj_misc);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "qcom,cpr-misc-fuse-voltage-adjustment reading failed, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			kfree(voltage_adj_misc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+
 | |
| -+		for (i = 0; i < vreg->corner_count; i++)
 | |
| -+			volt_adjust[i] += voltage_adj_misc[i];
 | |
| -+
 | |
| -+		kfree(voltage_adj_misc);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!allow_interpolation) {
 | |
| -+		/* Use fused target quotients for lower frequencies. */
 | |
| -+		return cpr4_ipq807x_apss_set_no_interpolation_quotients(
 | |
| -+				vreg, volt_adjust, volt_adjust_fuse, ro_scale);
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Determine highest corner mapped to each fuse corner */
 | |
| -+	j = vreg->fuse_corner_count - 1;
 | |
| -+	for (i = vreg->corner_count - 1; i >= 0; i--) {
 | |
| -+		if (vreg->corner[i].cpr_fuse_corner == j) {
 | |
| -+			fmax_corner[j] = i;
 | |
| -+			j--;
 | |
| -+		}
 | |
| -+	}
 | |
| -+	if (j >= 0) {
 | |
| -+		cpr3_err(vreg, "invalid fuse corner mapping\n");
 | |
| -+		rc = -EINVAL;
 | |
| -+		goto done;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Interpolation is not possible for corners mapped to the lowest fuse
 | |
| -+	 * corner so use the fuse corner value directly.
 | |
| -+	 */
 | |
| -+	i = CPR4_IPQ807x_APSS_FUSE_CORNER_SVS;
 | |
| -+	quot_adjust = cpr3_quot_adjustment(ro_scale[i], volt_adjust_fuse[i]);
 | |
| -+	quot = fuse->target_quot[i] + quot_adjust;
 | |
| -+	quot_high[i] = quot_low[i] = quot;
 | |
| -+	ro = fuse->ro_sel[i];
 | |
| -+	if (quot_adjust)
 | |
| -+		cpr3_debug(vreg, "adjusted fuse corner %d RO%u target quot: %llu --> %u (%d uV)\n",
 | |
| -+			i, ro, fuse->target_quot[i], quot, volt_adjust_fuse[i]);
 | |
| -+
 | |
| -+	for (i = 0; i <= fmax_corner[CPR4_IPQ807x_APSS_FUSE_CORNER_SVS];
 | |
| -+		i++)
 | |
| -+		vreg->corner[i].target_quot[ro] = quot;
 | |
| -+
 | |
| -+	for (i = CPR4_IPQ807x_APSS_FUSE_CORNER_NOM;
 | |
| -+	     i < vreg->fuse_corner_count; i++) {
 | |
| -+		quot_high[i] = fuse->target_quot[i];
 | |
| -+		if (fuse->ro_sel[i] == fuse->ro_sel[i - 1])
 | |
| -+			quot_low[i] = quot_high[i - 1];
 | |
| -+		else
 | |
| -+			quot_low[i] = quot_high[i]
 | |
| -+					- fuse->quot_offset[i]
 | |
| -+					  * IPQ807x_APSS_QUOT_OFFSET_SCALE;
 | |
| -+		if (quot_high[i] < quot_low[i]) {
 | |
| -+			cpr3_debug(vreg, "quot_high[%d]=%llu < quot_low[%d]=%llu; overriding: quot_high[%d]=%llu\n",
 | |
| -+				i, quot_high[i], i, quot_low[i],
 | |
| -+				i, quot_low[i]);
 | |
| -+			quot_high[i] = quot_low[i];
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Perform per-fuse-corner target quotient adjustment */
 | |
| -+	for (i = 1; i < vreg->fuse_corner_count; i++) {
 | |
| -+		quot_adjust = cpr3_quot_adjustment(ro_scale[i],
 | |
| -+						   volt_adjust_fuse[i]);
 | |
| -+		if (quot_adjust) {
 | |
| -+			prev_quot = quot_high[i];
 | |
| -+			quot_high[i] += quot_adjust;
 | |
| -+			cpr3_debug(vreg, "adjusted fuse corner %d RO%llu target quot: %llu --> %llu (%d uV)\n",
 | |
| -+				i, fuse->ro_sel[i], prev_quot, quot_high[i],
 | |
| -+				volt_adjust_fuse[i]);
 | |
| -+		}
 | |
| -+
 | |
| -+		if (fuse->ro_sel[i] == fuse->ro_sel[i - 1])
 | |
| -+			quot_low[i] = quot_high[i - 1];
 | |
| -+		else
 | |
| -+			quot_low[i] += cpr3_quot_adjustment(ro_scale[i],
 | |
| -+						    volt_adjust_fuse[i - 1]);
 | |
| -+
 | |
| -+		if (quot_high[i] < quot_low[i]) {
 | |
| -+			cpr3_debug(vreg, "quot_high[%d]=%llu < quot_low[%d]=%llu after adjustment; overriding: quot_high[%d]=%llu\n",
 | |
| -+				i, quot_high[i], i, quot_low[i],
 | |
| -+				i, quot_low[i]);
 | |
| -+			quot_high[i] = quot_low[i];
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Interpolate voltages for the higher fuse corners. */
 | |
| -+	for (i = 1; i < vreg->fuse_corner_count; i++) {
 | |
| -+		freq_low = vreg->corner[fmax_corner[i - 1]].proc_freq;
 | |
| -+		freq_high = vreg->corner[fmax_corner[i]].proc_freq;
 | |
| -+
 | |
| -+		ro = fuse->ro_sel[i];
 | |
| -+		for (j = fmax_corner[i - 1] + 1; j <= fmax_corner[i]; j++)
 | |
| -+			vreg->corner[j].target_quot[ro] = cpr3_interpolate(
 | |
| -+				freq_low, quot_low[i], freq_high, quot_high[i],
 | |
| -+				vreg->corner[j].proc_freq);
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Perform per-corner target quotient adjustment */
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		fuse_corner = vreg->corner[i].cpr_fuse_corner;
 | |
| -+		ro = fuse->ro_sel[fuse_corner];
 | |
| -+		quot_adjust = cpr3_quot_adjustment(ro_scale[fuse_corner],
 | |
| -+						   volt_adjust[i]);
 | |
| -+		if (quot_adjust) {
 | |
| -+			prev_quot = vreg->corner[i].target_quot[ro];
 | |
| -+			vreg->corner[i].target_quot[ro] += quot_adjust;
 | |
| -+			cpr3_debug(vreg, "adjusted corner %d RO%u target quot: %llu --> %u (%d uV)\n",
 | |
| -+				i, ro, prev_quot,
 | |
| -+				vreg->corner[i].target_quot[ro],
 | |
| -+				volt_adjust[i]);
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Ensure that target quotients increase monotonically */
 | |
| -+	for (i = 1; i < vreg->corner_count; i++) {
 | |
| -+		ro = fuse->ro_sel[vreg->corner[i].cpr_fuse_corner];
 | |
| -+		if (fuse->ro_sel[vreg->corner[i - 1].cpr_fuse_corner] == ro
 | |
| -+		    && vreg->corner[i].target_quot[ro]
 | |
| -+				< vreg->corner[i - 1].target_quot[ro]) {
 | |
| -+			cpr3_debug(vreg, "adjusted corner %d RO%u target quot=%u < adjusted corner %d RO%u target quot=%u; overriding: corner %d RO%u target quot=%u\n",
 | |
| -+				i, ro, vreg->corner[i].target_quot[ro],
 | |
| -+				i - 1, ro, vreg->corner[i - 1].target_quot[ro],
 | |
| -+				i, ro, vreg->corner[i - 1].target_quot[ro]);
 | |
| -+			vreg->corner[i].target_quot[ro]
 | |
| -+				= vreg->corner[i - 1].target_quot[ro];
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+done:
 | |
| -+	kfree(volt_adjust);
 | |
| -+	kfree(volt_adjust_fuse);
 | |
| -+	kfree(ro_scale);
 | |
| -+	kfree(fmax_corner);
 | |
| -+	kfree(quot_low);
 | |
| -+	kfree(quot_high);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_apss_print_settings() - print out APSS CPR configuration settings into
 | |
| -+ *		the kernel log for debugging purposes
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ */
 | |
| -+static void cpr4_apss_print_settings(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct cpr3_corner *corner;
 | |
| -+	int i;
 | |
| -+
 | |
| -+	cpr3_debug(vreg, "Corner: Frequency (Hz), Fuse Corner, Floor (uV), Open-Loop (uV), Ceiling (uV)\n");
 | |
| -+	for (i = 0; i < vreg->corner_count; i++) {
 | |
| -+		corner = &vreg->corner[i];
 | |
| -+		cpr3_debug(vreg, "%3d: %10u, %2d, %7d, %7d, %7d\n",
 | |
| -+			i, corner->proc_freq, corner->cpr_fuse_corner,
 | |
| -+			corner->floor_volt, corner->open_loop_volt,
 | |
| -+			corner->ceiling_volt);
 | |
| -+	}
 | |
| -+
 | |
| -+	if (vreg->thread->ctrl->apm)
 | |
| -+		cpr3_debug(vreg, "APM threshold = %d uV, APM adjust = %d uV\n",
 | |
| -+			vreg->thread->ctrl->apm_threshold_volt,
 | |
| -+			vreg->thread->ctrl->apm_adj_volt);
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_apss_init_thread() - perform steps necessary to initialize the
 | |
| -+ *		configuration data for a CPR3 thread
 | |
| -+ * @thread:		Pointer to the CPR3 thread
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_apss_init_thread(struct cpr3_thread *thread)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_common_thread_data(thread);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(thread->ctrl, "thread %u unable to read CPR thread data from device tree, rc=%d\n",
 | |
| -+			thread->thread_id, rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_apss_parse_temp_adj_properties() - parse temperature based
 | |
| -+ *		adjustment properties from device tree.
 | |
| -+ * @ctrl:	Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_apss_parse_temp_adj_properties(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	struct device_node *of_node = ctrl->dev->of_node;
 | |
| -+	int rc, i, len, temp_point_count;
 | |
| -+
 | |
| -+	if (!of_find_property(of_node, "qcom,cpr-temp-point-map", &len)) {
 | |
| -+		/*
 | |
| -+		 * Temperature based adjustments are not defined. Single
 | |
| -+		 * temperature band is still valid for per-online-core
 | |
| -+		 * adjustments.
 | |
| -+		 */
 | |
| -+		ctrl->temp_band_count = 1;
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	temp_point_count = len / sizeof(u32);
 | |
| -+	if (temp_point_count <= 0 ||
 | |
| -+	    temp_point_count > IPQ807x_APSS_MAX_TEMP_POINTS) {
 | |
| -+		cpr3_err(ctrl, "invalid number of temperature points %d > %d (max)\n",
 | |
| -+			 temp_point_count, IPQ807x_APSS_MAX_TEMP_POINTS);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->temp_points = devm_kcalloc(ctrl->dev, temp_point_count,
 | |
| -+					sizeof(*ctrl->temp_points), GFP_KERNEL);
 | |
| -+	if (!ctrl->temp_points)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	rc = of_property_read_u32_array(of_node, "qcom,cpr-temp-point-map",
 | |
| -+					ctrl->temp_points, temp_point_count);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "error reading property qcom,cpr-temp-point-map, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < temp_point_count; i++)
 | |
| -+		cpr3_debug(ctrl, "Temperature Point %d=%d\n", i,
 | |
| -+				   ctrl->temp_points[i]);
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * If t1, t2, and t3 are the temperature points, then the temperature
 | |
| -+	 * bands are: (-inf, t1], (t1, t2], (t2, t3], and (t3, inf).
 | |
| -+	 */
 | |
| -+	ctrl->temp_band_count = temp_point_count + 1;
 | |
| -+	cpr3_debug(ctrl, "Number of temp bands =%d\n", ctrl->temp_band_count);
 | |
| -+
 | |
| -+	rc = of_property_read_u32(of_node, "qcom,cpr-initial-temp-band",
 | |
| -+				  &ctrl->initial_temp_band);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "error reading qcom,cpr-initial-temp-band, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->initial_temp_band >= ctrl->temp_band_count) {
 | |
| -+		cpr3_err(ctrl, "Initial temperature band value %d should be in range [0 - %d]\n",
 | |
| -+			ctrl->initial_temp_band, ctrl->temp_band_count - 1);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->temp_sensor_id_start = IPQ807x_APSS_TEMP_SENSOR_ID_START;
 | |
| -+	ctrl->temp_sensor_id_end = IPQ807x_APSS_TEMP_SENSOR_ID_END;
 | |
| -+	ctrl->allow_temp_adj = true;
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_apss_parse_boost_properties() - parse configuration data for boost
 | |
| -+ *		voltage adjustment for CPR3 regulator from device tree.
 | |
| -+ * @vreg:	Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_apss_parse_boost_properties(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = vreg->thread->ctrl;
 | |
| -+	struct cpr4_ipq807x_apss_fuses *fuse = vreg->platform_fuses;
 | |
| -+	struct cpr3_corner *corner;
 | |
| -+	int i, boost_voltage, final_boost_volt, rc = 0;
 | |
| -+	int *boost_table = NULL, *boost_temp_adj = NULL;
 | |
| -+	int boost_voltage_adjust = 0, boost_num_cores = 0;
 | |
| -+	u32 boost_allowed = 0;
 | |
| -+
 | |
| -+	if (!boost_fuse[fuse->boost_cfg])
 | |
| -+		/* Voltage boost is disabled in fuse */
 | |
| -+		return 0;
 | |
| -+
 | |
| -+	if (of_find_property(vreg->of_node, "qcom,allow-boost", NULL)) {
 | |
| -+		rc = cpr3_parse_array_property(vreg, "qcom,allow-boost", 1,
 | |
| -+				&boost_allowed);
 | |
| -+		if (rc)
 | |
| -+			return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (!boost_allowed) {
 | |
| -+		/* Voltage boost is not enabled for this regulator */
 | |
| -+		return 0;
 | |
| -+	}
 | |
| -+
 | |
| -+	boost_voltage = cpr3_convert_open_loop_voltage_fuse(
 | |
| -+				vreg->cpr4_regulator_data->boost_fuse_ref_volt,
 | |
| -+				vreg->cpr4_regulator_data->fuse_step_volt,
 | |
| -+				fuse->boost_voltage,
 | |
| -+				IPQ807x_APSS_VOLTAGE_FUSE_SIZE);
 | |
| -+
 | |
| -+	/* Log boost voltage value for debugging purposes. */
 | |
| -+	cpr3_info(vreg, "Boost open-loop=%7d uV\n", boost_voltage);
 | |
| -+
 | |
| -+	if (of_find_property(vreg->of_node,
 | |
| -+			"qcom,cpr-boost-voltage-fuse-adjustment", NULL)) {
 | |
| -+		rc = cpr3_parse_array_property(vreg,
 | |
| -+			"qcom,cpr-boost-voltage-fuse-adjustment",
 | |
| -+			1, &boost_voltage_adjust);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "qcom,cpr-boost-voltage-fuse-adjustment reading failed, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+
 | |
| -+		boost_voltage += boost_voltage_adjust;
 | |
| -+		/* Log boost voltage value for debugging purposes. */
 | |
| -+		cpr3_info(vreg, "Adjusted boost open-loop=%7d uV\n",
 | |
| -+			boost_voltage);
 | |
| -+	}
 | |
| -+
 | |
| -+	/* Limit boost voltage value between ceiling and floor voltage limits */
 | |
| -+	boost_voltage = min(boost_voltage, vreg->cpr4_regulator_data->boost_ceiling_volt);
 | |
| -+	boost_voltage = max(boost_voltage, vreg->cpr4_regulator_data->boost_floor_volt);
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * The boost feature can only be used for the highest voltage corner.
 | |
| -+	 * Also, keep core-count adjustments disabled when the boost feature
 | |
| -+	 * is enabled.
 | |
| -+	 */
 | |
| -+	corner = &vreg->corner[vreg->corner_count - 1];
 | |
| -+	if (!corner->sdelta) {
 | |
| -+		/*
 | |
| -+		 * If core-count/temp adjustments are not defined, the cpr4
 | |
| -+		 * sdelta for this corner will not be allocated. Allocate it
 | |
| -+		 * here for boost configuration.
 | |
| -+		 */
 | |
| -+		corner->sdelta = devm_kzalloc(ctrl->dev,
 | |
| -+					sizeof(*corner->sdelta), GFP_KERNEL);
 | |
| -+		if (!corner->sdelta)
 | |
| -+			return -ENOMEM;
 | |
| -+	}
 | |
| -+	corner->sdelta->temp_band_count = ctrl->temp_band_count;
 | |
| -+
 | |
| -+	rc = of_property_read_u32(vreg->of_node, "qcom,cpr-num-boost-cores",
 | |
| -+				&boost_num_cores);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "qcom,cpr-num-boost-cores reading failed, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (boost_num_cores <= 0 ||
 | |
| -+	    boost_num_cores > IPQ807x_APSS_CPR_SDELTA_CORE_COUNT) {
 | |
| -+		cpr3_err(vreg, "Invalid boost number of cores = %d\n",
 | |
| -+			boost_num_cores);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+	corner->sdelta->boost_num_cores = boost_num_cores;
 | |
| -+
 | |
| -+	boost_table = devm_kcalloc(ctrl->dev, corner->sdelta->temp_band_count,
 | |
| -+					sizeof(*boost_table), GFP_KERNEL);
 | |
| -+	if (!boost_table)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	if (of_find_property(vreg->of_node,
 | |
| -+				"qcom,cpr-boost-temp-adjustment", NULL)) {
 | |
| -+		boost_temp_adj = kcalloc(corner->sdelta->temp_band_count,
 | |
| -+					sizeof(*boost_temp_adj), GFP_KERNEL);
 | |
| -+		if (!boost_temp_adj)
 | |
| -+			return -ENOMEM;
 | |
| -+
 | |
| -+		rc = cpr3_parse_array_property(vreg,
 | |
| -+				"qcom,cpr-boost-temp-adjustment",
 | |
| -+				corner->sdelta->temp_band_count,
 | |
| -+				boost_temp_adj);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(vreg, "qcom,cpr-boost-temp-adjustment reading failed, rc=%d\n",
 | |
| -+				rc);
 | |
| -+			goto done;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < corner->sdelta->temp_band_count; i++) {
 | |
| -+		/* Apply static adjustments to boost voltage */
 | |
| -+		final_boost_volt = boost_voltage + (boost_temp_adj == NULL
 | |
| -+						? 0 : boost_temp_adj[i]);
 | |
| -+		/*
 | |
| -+		 * Limit final adjusted boost voltage value between ceiling
 | |
| -+		 * and floor voltage limits
 | |
| -+		 */
 | |
| -+		final_boost_volt = min(final_boost_volt,
 | |
| -+					vreg->cpr4_regulator_data->boost_ceiling_volt);
 | |
| -+		final_boost_volt = max(final_boost_volt,
 | |
| -+					vreg->cpr4_regulator_data->boost_floor_volt);
 | |
| -+
 | |
| -+		boost_table[i] = (corner->open_loop_volt - final_boost_volt)
 | |
| -+					/ ctrl->step_volt;
 | |
| -+		cpr3_debug(vreg, "Adjusted boost voltage margin for temp band %d = %d steps\n",
 | |
| -+			i, boost_table[i]);
 | |
| -+	}
 | |
| -+
 | |
| -+	corner->ceiling_volt = vreg->cpr4_regulator_data->boost_ceiling_volt;
 | |
| -+	corner->sdelta->boost_table = boost_table;
 | |
| -+	corner->sdelta->allow_boost = true;
 | |
| -+	corner->sdelta->allow_core_count_adj = false;
 | |
| -+	vreg->allow_boost = true;
 | |
| -+	ctrl->allow_boost = true;
 | |
| -+done:
 | |
| -+	kfree(boost_temp_adj);
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_apss_init_regulator() - perform all steps necessary to initialize the
 | |
| -+ *		configuration data for a CPR3 regulator
 | |
| -+ * @vreg:		Pointer to the CPR3 regulator
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_apss_init_regulator(struct cpr3_regulator *vreg)
 | |
| -+{
 | |
| -+	struct cpr4_ipq807x_apss_fuses *fuse;
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = cpr4_ipq807x_apss_read_fuse_data(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "unable to read CPR fuse data, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	fuse = vreg->platform_fuses;
 | |
| -+
 | |
| -+	rc = cpr4_apss_parse_corner_data(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "unable to read CPR corner data from device tree, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_mem_acc_init(vreg);
 | |
| -+	if (rc) {
 | |
| -+		if (rc != -EPROBE_DEFER)
 | |
| -+			cpr3_err(vreg, "unable to initialize mem-acc regulator settings, rc=%d\n",
 | |
| -+				 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr4_ipq807x_apss_calculate_open_loop_voltages(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "unable to calculate open-loop voltages, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_limit_open_loop_voltages(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "unable to limit open-loop voltages, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr3_open_loop_voltage_as_ceiling(vreg);
 | |
| -+
 | |
| -+	rc = cpr3_limit_floor_voltages(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "unable to limit floor voltages, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr4_ipq807x_apss_calculate_target_quotients(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "unable to calculate target quotients, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr4_parse_core_count_temp_voltage_adj(vreg, false);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "unable to parse temperature and core count voltage adjustments, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (vreg->allow_core_count_adj && (vreg->max_core_count <= 0
 | |
| -+				   || vreg->max_core_count >
 | |
| -+				   IPQ807x_APSS_CPR_SDELTA_CORE_COUNT)) {
 | |
| -+		cpr3_err(vreg, "qcom,max-core-count has invalid value = %d\n",
 | |
| -+			 vreg->max_core_count);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr4_apss_parse_boost_properties(vreg);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(vreg, "unable to parse boost adjustments, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	cpr4_apss_print_settings(vreg);
 | |
| -+
 | |
| -+	return rc;
 | |
| -+}
 | |
| -+
 | |
| -+/**
 | |
| -+ * cpr4_apss_init_controller() - perform APSS CPR4 controller specific
 | |
| -+ *		initializations
 | |
| -+ * @ctrl:		Pointer to the CPR3 controller
 | |
| -+ *
 | |
| -+ * Return: 0 on success, errno on failure
 | |
| -+ */
 | |
| -+static int cpr4_apss_init_controller(struct cpr3_controller *ctrl)
 | |
| -+{
 | |
| -+	int rc;
 | |
| -+
 | |
| -+	rc = cpr3_parse_common_ctrl_data(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		if (rc != -EPROBE_DEFER)
 | |
| -+			cpr3_err(ctrl, "unable to parse common controller data, rc=%d\n",
 | |
| -+				rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = of_property_read_u32(ctrl->dev->of_node,
 | |
| -+				  "qcom,cpr-down-error-step-limit",
 | |
| -+				  &ctrl->down_error_step_limit);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "error reading qcom,cpr-down-error-step-limit, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = of_property_read_u32(ctrl->dev->of_node,
 | |
| -+				  "qcom,cpr-up-error-step-limit",
 | |
| -+				  &ctrl->up_error_step_limit);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "error reading qcom,cpr-up-error-step-limit, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * Use fixed step quotient if specified otherwise use dynamic
 | |
| -+	 * calculated per RO step quotient
 | |
| -+	 */
 | |
| -+	of_property_read_u32(ctrl->dev->of_node, "qcom,cpr-step-quot-fixed",
 | |
| -+			&ctrl->step_quot_fixed);
 | |
| -+	ctrl->use_dynamic_step_quot = ctrl->step_quot_fixed ? false : true;
 | |
| -+
 | |
| -+	ctrl->saw_use_unit_mV = of_property_read_bool(ctrl->dev->of_node,
 | |
| -+					"qcom,cpr-saw-use-unit-mV");
 | |
| -+
 | |
| -+	of_property_read_u32(ctrl->dev->of_node,
 | |
| -+			"qcom,cpr-voltage-settling-time",
 | |
| -+			&ctrl->voltage_settling_time);
 | |
| -+
 | |
| -+	if (of_find_property(ctrl->dev->of_node, "vdd-limit-supply", NULL)) {
 | |
| -+		ctrl->vdd_limit_regulator =
 | |
| -+			devm_regulator_get(ctrl->dev, "vdd-limit");
 | |
| -+		if (IS_ERR(ctrl->vdd_limit_regulator)) {
 | |
| -+			rc = PTR_ERR(ctrl->vdd_limit_regulator);
 | |
| -+			if (rc != -EPROBE_DEFER)
 | |
| -+				cpr3_err(ctrl, "unable to request vdd-limit regulator, rc=%d\n",
 | |
| -+					 rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_apm_init(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		if (rc != -EPROBE_DEFER)
 | |
| -+			cpr3_err(ctrl, "unable to initialize APM settings, rc=%d\n",
 | |
| -+				rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr4_apss_parse_temp_adj_properties(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "unable to parse temperature adjustment properties, rc=%d\n",
 | |
| -+			 rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl->sensor_count = IPQ807x_APSS_CPR_SENSOR_COUNT;
 | |
| -+
 | |
| -+	/*
 | |
| -+	 * APSS only has one thread (0) per controller so the zeroed
 | |
| -+	 * array does not need further modification.
 | |
| -+	 */
 | |
| -+	ctrl->sensor_owner = devm_kcalloc(ctrl->dev, ctrl->sensor_count,
 | |
| -+		sizeof(*ctrl->sensor_owner), GFP_KERNEL);
 | |
| -+	if (!ctrl->sensor_owner)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	ctrl->ctrl_type = CPR_CTRL_TYPE_CPR4;
 | |
| -+	ctrl->supports_hw_closed_loop = false;
 | |
| -+	ctrl->use_hw_closed_loop = of_property_read_bool(ctrl->dev->of_node,
 | |
| -+						"qcom,cpr-hw-closed-loop");
 | |
| -+	return 0;
 | |
| -+}
 | |
| -+
 | |
| -+static int cpr4_apss_regulator_suspend(struct platform_device *pdev,
 | |
| -+				pm_message_t state)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = platform_get_drvdata(pdev);
 | |
| -+
 | |
| -+	return cpr3_regulator_suspend(ctrl);
 | |
| -+}
 | |
| -+
 | |
| -+static int cpr4_apss_regulator_resume(struct platform_device *pdev)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = platform_get_drvdata(pdev);
 | |
| -+
 | |
| -+	return cpr3_regulator_resume(ctrl);
 | |
| -+}
 | |
| -+
 | |
| -+static void ipq6018_set_mem_acc(struct regulator_dev *rdev)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg = rdev_get_drvdata(rdev);
 | |
| -+
 | |
| -+	ipq6018_mem_acc_tcsr[0].ioremap_addr =
 | |
| -+		ioremap(ipq6018_mem_acc_tcsr[0].phy_addr, 0x4);
 | |
| -+	ipq6018_mem_acc_tcsr[1].ioremap_addr =
 | |
| -+		ioremap(ipq6018_mem_acc_tcsr[1].phy_addr, 0x4);
 | |
| -+
 | |
| -+	if ((ipq6018_mem_acc_tcsr[0].ioremap_addr != NULL) &&
 | |
| -+			(ipq6018_mem_acc_tcsr[1].ioremap_addr != NULL) &&
 | |
| -+			(vreg->current_corner == (vreg->corner_count - CPR3_CORNER_OFFSET))) {
 | |
| -+
 | |
| -+		writel_relaxed(ipq6018_mem_acc_tcsr[0].value,
 | |
| -+				ipq6018_mem_acc_tcsr[0].ioremap_addr);
 | |
| -+		writel_relaxed(ipq6018_mem_acc_tcsr[1].value,
 | |
| -+				ipq6018_mem_acc_tcsr[1].ioremap_addr);
 | |
| -+	}
 | |
| -+}
 | |
| -+
 | |
| -+static void ipq6018_clr_mem_acc(struct regulator_dev *rdev)
 | |
| -+{
 | |
| -+	struct cpr3_regulator *vreg = rdev_get_drvdata(rdev);
 | |
| -+
 | |
| -+	if ((ipq6018_mem_acc_tcsr[0].ioremap_addr != NULL) &&
 | |
| -+			(ipq6018_mem_acc_tcsr[1].ioremap_addr != NULL) &&
 | |
| -+			(vreg->current_corner != vreg->corner_count - CPR3_CORNER_OFFSET)) {
 | |
| -+		writel_relaxed(0x0, ipq6018_mem_acc_tcsr[0].ioremap_addr);
 | |
| -+		writel_relaxed(0x0, ipq6018_mem_acc_tcsr[1].ioremap_addr);
 | |
| -+	}
 | |
| -+
 | |
| -+	iounmap(ipq6018_mem_acc_tcsr[0].ioremap_addr);
 | |
| -+	iounmap(ipq6018_mem_acc_tcsr[1].ioremap_addr);
 | |
| -+}
 | |
| -+
 | |
| -+static struct cpr4_mem_acc_func ipq6018_mem_acc_funcs = {
 | |
| -+	.set_mem_acc = ipq6018_set_mem_acc,
 | |
| -+	.clear_mem_acc = ipq6018_clr_mem_acc
 | |
| -+};
 | |
| -+
 | |
| -+static const struct cpr4_reg_data ipq807x_cpr_apss = {
 | |
| -+	.cpr_valid_fuse_count = IPQ807x_APSS_FUSE_CORNERS,
 | |
| -+	.fuse_ref_volt = ipq807x_apss_fuse_ref_volt,
 | |
| -+	.fuse_step_volt = IPQ807x_APSS_FUSE_STEP_VOLT,
 | |
| -+	.cpr_clk_rate = IPQ807x_APSS_CPR_CLOCK_RATE,
 | |
| -+	.boost_fuse_ref_volt= IPQ807x_APSS_BOOST_FUSE_REF_VOLT,
 | |
| -+	.boost_ceiling_volt= IPQ807x_APSS_BOOST_CEILING_VOLT,
 | |
| -+	.boost_floor_volt= IPQ807x_APSS_BOOST_FLOOR_VOLT,
 | |
| -+	.cpr3_fuse_params = &ipq807x_fuse_params,
 | |
| -+	.mem_acc_funcs = NULL,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct cpr4_reg_data ipq817x_cpr_apss = {
 | |
| -+	.cpr_valid_fuse_count = IPQ817x_APPS_FUSE_CORNERS,
 | |
| -+	.fuse_ref_volt = ipq807x_apss_fuse_ref_volt,
 | |
| -+	.fuse_step_volt = IPQ807x_APSS_FUSE_STEP_VOLT,
 | |
| -+	.cpr_clk_rate = IPQ807x_APSS_CPR_CLOCK_RATE,
 | |
| -+	.boost_fuse_ref_volt= IPQ807x_APSS_BOOST_FUSE_REF_VOLT,
 | |
| -+	.boost_ceiling_volt= IPQ807x_APSS_BOOST_CEILING_VOLT,
 | |
| -+	.boost_floor_volt= IPQ807x_APSS_BOOST_FLOOR_VOLT,
 | |
| -+	.cpr3_fuse_params = &ipq807x_fuse_params,
 | |
| -+	.mem_acc_funcs = NULL,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct cpr4_reg_data ipq6018_cpr_apss = {
 | |
| -+	.cpr_valid_fuse_count = IPQ6018_APSS_FUSE_CORNERS,
 | |
| -+	.fuse_ref_volt = ipq6018_apss_fuse_ref_volt,
 | |
| -+	.fuse_step_volt = IPQ6018_APSS_FUSE_STEP_VOLT,
 | |
| -+	.cpr_clk_rate = IPQ6018_APSS_CPR_CLOCK_RATE,
 | |
| -+	.boost_fuse_ref_volt = IPQ6018_APSS_BOOST_FUSE_REF_VOLT,
 | |
| -+	.boost_ceiling_volt = IPQ6018_APSS_BOOST_CEILING_VOLT,
 | |
| -+	.boost_floor_volt = IPQ6018_APSS_BOOST_FLOOR_VOLT,
 | |
| -+	.cpr3_fuse_params = &ipq6018_fuse_params,
 | |
| -+	.mem_acc_funcs = &ipq6018_mem_acc_funcs,
 | |
| -+};
 | |
| -+
 | |
| -+static const struct cpr4_reg_data ipq9574_cpr_apss = {
 | |
| -+	.cpr_valid_fuse_count = IPQ9574_APSS_FUSE_CORNERS,
 | |
| -+	.fuse_ref_volt = ipq9574_apss_fuse_ref_volt,
 | |
| -+	.fuse_step_volt = IPQ9574_APSS_FUSE_STEP_VOLT,
 | |
| -+	.cpr_clk_rate = IPQ6018_APSS_CPR_CLOCK_RATE,
 | |
| -+	.boost_fuse_ref_volt = IPQ6018_APSS_BOOST_FUSE_REF_VOLT,
 | |
| -+	.boost_ceiling_volt = IPQ6018_APSS_BOOST_CEILING_VOLT,
 | |
| -+	.boost_floor_volt = IPQ6018_APSS_BOOST_FLOOR_VOLT,
 | |
| -+	.cpr3_fuse_params = &ipq9574_fuse_params,
 | |
| -+	.mem_acc_funcs = NULL,
 | |
| -+};
 | |
| -+
 | |
| -+static struct of_device_id cpr4_regulator_match_table[] = {
 | |
| -+	{
 | |
| -+		.compatible = "qcom,cpr4-ipq807x-apss-regulator",
 | |
| -+		.data = &ipq807x_cpr_apss
 | |
| -+	},
 | |
| -+	{
 | |
| -+		.compatible = "qcom,cpr4-ipq817x-apss-regulator",
 | |
| -+		.data = &ipq817x_cpr_apss
 | |
| -+	},
 | |
| -+	{
 | |
| -+		.compatible = "qcom,cpr4-ipq6018-apss-regulator",
 | |
| -+		.data = &ipq6018_cpr_apss
 | |
| -+	},
 | |
| -+	{
 | |
| -+		.compatible = "qcom,cpr4-ipq9574-apss-regulator",
 | |
| -+		.data = &ipq9574_cpr_apss
 | |
| -+	},
 | |
| -+	{}
 | |
| -+};
 | |
| -+
 | |
| -+static int cpr4_apss_regulator_probe(struct platform_device *pdev)
 | |
| -+{
 | |
| -+	struct device *dev = &pdev->dev;
 | |
| -+	struct cpr3_controller *ctrl;
 | |
| -+	const struct of_device_id *match;
 | |
| -+	struct cpr4_reg_data *cpr_data;
 | |
| -+	int i, rc;
 | |
| -+
 | |
| -+	if (!dev->of_node) {
 | |
| -+		dev_err(dev, "Device tree node is missing\n");
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
 | |
| -+	if (!ctrl)
 | |
| -+		return -ENOMEM;
 | |
| -+
 | |
| -+	match = of_match_device(cpr4_regulator_match_table, &pdev->dev);
 | |
| -+	if (!match)
 | |
| -+		return -ENODEV;
 | |
| -+
 | |
| -+	cpr_data = (struct cpr4_reg_data *)match->data;
 | |
| -+	g_valid_fuse_count = cpr_data->cpr_valid_fuse_count;
 | |
| -+	dev_info(dev, "CPR valid fuse count: %d\n", g_valid_fuse_count);
 | |
| -+	ctrl->cpr_clock_rate = cpr_data->cpr_clk_rate;
 | |
| -+
 | |
| -+	ctrl->dev = dev;
 | |
| -+	/* Set to false later if anything precludes CPR operation. */
 | |
| -+	ctrl->cpr_allowed_hw = true;
 | |
| -+
 | |
| -+	rc = of_property_read_string(dev->of_node, "qcom,cpr-ctrl-name",
 | |
| -+					&ctrl->name);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "unable to read qcom,cpr-ctrl-name, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_map_fuse_base(ctrl, pdev);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "could not map fuse base address\n");
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_read_tcsr_setting(ctrl, pdev, IPQ807x_APSS_CPR_TCSR_START,
 | |
| -+				    IPQ807x_APSS_CPR_TCSR_END);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "could not read CPR tcsr setting\n");
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr3_allocate_threads(ctrl, 0, 0);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "failed to allocate CPR thread array, rc=%d\n",
 | |
| -+			rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	if (ctrl->thread_count != 1) {
 | |
| -+		cpr3_err(ctrl, "expected 1 thread but found %d\n",
 | |
| -+			ctrl->thread_count);
 | |
| -+		return -EINVAL;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr4_apss_init_controller(ctrl);
 | |
| -+	if (rc) {
 | |
| -+		if (rc != -EPROBE_DEFER)
 | |
| -+			cpr3_err(ctrl, "failed to initialize CPR controller parameters, rc=%d\n",
 | |
| -+				rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	rc = cpr4_apss_init_thread(&ctrl->thread[0]);
 | |
| -+	if (rc) {
 | |
| -+		cpr3_err(ctrl, "thread initialization failed, rc=%d\n", rc);
 | |
| -+		return rc;
 | |
| -+	}
 | |
| -+
 | |
| -+	for (i = 0; i < ctrl->thread[0].vreg_count; i++) {
 | |
| -+		ctrl->thread[0].vreg[i].cpr4_regulator_data = cpr_data;
 | |
| -+		rc = cpr4_apss_init_regulator(&ctrl->thread[0].vreg[i]);
 | |
| -+		if (rc) {
 | |
| -+			cpr3_err(&ctrl->thread[0].vreg[i], "regulator initialization failed, rc=%d\n",
 | |
| -+				 rc);
 | |
| -+			return rc;
 | |
| -+		}
 | |
| -+	}
 | |
| -+
 | |
| -+	platform_set_drvdata(pdev, ctrl);
 | |
| -+
 | |
| -+	return cpr3_regulator_register(pdev, ctrl);
 | |
| -+}
 | |
| -+
 | |
| -+static int cpr4_apss_regulator_remove(struct platform_device *pdev)
 | |
| -+{
 | |
| -+	struct cpr3_controller *ctrl = platform_get_drvdata(pdev);
 | |
| -+
 | |
| -+	return cpr3_regulator_unregister(ctrl);
 | |
| -+}
 | |
| -+
 | |
| -+static struct platform_driver cpr4_apss_regulator_driver = {
 | |
| -+	.driver		= {
 | |
| -+		.name		= "qcom,cpr4-apss-regulator",
 | |
| -+		.of_match_table	= cpr4_regulator_match_table,
 | |
| -+		.owner		= THIS_MODULE,
 | |
| -+	},
 | |
| -+	.probe		= cpr4_apss_regulator_probe,
 | |
| -+	.remove		= cpr4_apss_regulator_remove,
 | |
| -+	.suspend	= cpr4_apss_regulator_suspend,
 | |
| -+	.resume		= cpr4_apss_regulator_resume,
 | |
| -+};
 | |
| -+
 | |
| -+static int cpr4_regulator_init(void)
 | |
| -+{
 | |
| -+	return platform_driver_register(&cpr4_apss_regulator_driver);
 | |
| -+}
 | |
| -+
 | |
| -+static void cpr4_regulator_exit(void)
 | |
| -+{
 | |
| -+	platform_driver_unregister(&cpr4_apss_regulator_driver);
 | |
| -+}
 | |
| -+
 | |
| -+MODULE_DESCRIPTION("CPR4 APSS regulator driver");
 | |
| -+MODULE_LICENSE("GPL v2");
 | |
| -+
 | |
| -+arch_initcall(cpr4_regulator_init);
 | |
| -+module_exit(cpr4_regulator_exit);
 | |
| ---- /dev/null
 | |
| -+++ b/include/soc/qcom/socinfo.h
 | |
| -@@ -0,0 +1,463 @@
 | |
| -+/* Copyright (c) 2009-2014, 2016, 2020, The Linux Foundation. All rights reserved.
 | |
| -+ *
 | |
| -+ * This program is free software; you can redistribute it and/or modify
 | |
| -+ * it under the terms of the GNU General Public License version 2 and
 | |
| -+ * only version 2 as published by the Free Software Foundation.
 | |
| -+ *
 | |
| -+ * This program is distributed in the hope that it will be useful,
 | |
| -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| -+ * GNU General Public License for more details.
 | |
| -+ *
 | |
| -+ */
 | |
| -+
 | |
| -+#ifndef _ARCH_ARM_MACH_MSM_SOCINFO_H_
 | |
| -+#define _ARCH_ARM_MACH_MSM_SOCINFO_H_
 | |
| -+
 | |
| -+#include <linux/of.h>
 | |
| -+
 | |
| -+#define CPU_IPQ8074 323
 | |
| -+#define CPU_IPQ8072 342
 | |
| -+#define CPU_IPQ8076 343
 | |
| -+#define CPU_IPQ8078 344
 | |
| -+#define CPU_IPQ8070 375
 | |
| -+#define CPU_IPQ8071 376
 | |
| -+
 | |
| -+#define CPU_IPQ8072A 389
 | |
| -+#define CPU_IPQ8074A 390
 | |
| -+#define CPU_IPQ8076A 391
 | |
| -+#define CPU_IPQ8078A 392
 | |
| -+#define CPU_IPQ8070A 395
 | |
| -+#define CPU_IPQ8071A 396
 | |
| -+
 | |
| -+#define CPU_IPQ8172  397
 | |
| -+#define CPU_IPQ8173  398
 | |
| -+#define CPU_IPQ8174  399
 | |
| -+
 | |
| -+#define CPU_IPQ6018 402
 | |
| -+#define CPU_IPQ6028 403
 | |
| -+#define CPU_IPQ6000 421
 | |
| -+#define CPU_IPQ6010 422
 | |
| -+#define CPU_IPQ6005 453
 | |
| -+
 | |
| -+#define CPU_IPQ5010 446
 | |
| -+#define CPU_IPQ5018 447
 | |
| -+#define CPU_IPQ5028 448
 | |
| -+#define CPU_IPQ5000 503
 | |
| -+#define CPU_IPQ0509 504
 | |
| -+#define CPU_IPQ0518 505
 | |
| -+
 | |
| -+#define CPU_IPQ9514 510
 | |
| -+#define CPU_IPQ9554 512
 | |
| -+#define CPU_IPQ9570 513
 | |
| -+#define CPU_IPQ9574 514
 | |
| -+#define CPU_IPQ9550 511
 | |
| -+#define CPU_IPQ9510 521
 | |
| -+
 | |
| -+static inline int read_ipq_soc_version_major(void)
 | |
| -+{
 | |
| -+	const int *prop;
 | |
| -+	prop = of_get_property(of_find_node_by_path("/"), "soc_version_major",
 | |
| -+				NULL);
 | |
| -+
 | |
| -+	if (!prop)
 | |
| -+		return -EINVAL;
 | |
| -+
 | |
| -+	return le32_to_cpu(*prop);
 | |
| -+}
 | |
| -+
 | |
| -+static inline int read_ipq_cpu_type(void)
 | |
| -+{
 | |
| -+	const int *prop;
 | |
| -+	prop = of_get_property(of_find_node_by_path("/"), "cpu_type", NULL);
 | |
| -+	/*
 | |
| -+	 * Return Default CPU type if "cpu_type" property is not found in DTSI
 | |
| -+	 */
 | |
| -+	if (!prop)
 | |
| -+		return CPU_IPQ8074;
 | |
| -+
 | |
| -+	return le32_to_cpu(*prop);
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8070(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8070;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8071(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8071;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8072(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8072;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8074(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8074;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8076(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8076;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8078(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8078;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8072a(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8072A;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8074a(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8074A;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8076a(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8076A;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8078a(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8078A;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8070a(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8070A;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8071a(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8071A;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8172(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8172;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8173(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8173;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq8174(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ8174;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq6018(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ6018;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq6028(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ6028;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq6000(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ6000;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq6010(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ6010;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq6005(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ6005;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq5010(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ5010;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq5018(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ5018;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq5028(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ5028;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq5000(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ5000;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq0509(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ0509;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq0518(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ0518;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq9514(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ9514;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq9554(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ9554;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq9570(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ9570;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq9574(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ9574;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq9550(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ9550;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq9510(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return read_ipq_cpu_type() == CPU_IPQ9510;
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq807x(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return  cpu_is_ipq8072() || cpu_is_ipq8074() ||
 | |
| -+		cpu_is_ipq8076() || cpu_is_ipq8078() ||
 | |
| -+		cpu_is_ipq8070() || cpu_is_ipq8071() ||
 | |
| -+		cpu_is_ipq8072a() || cpu_is_ipq8074a() ||
 | |
| -+		cpu_is_ipq8076a() || cpu_is_ipq8078a() ||
 | |
| -+		cpu_is_ipq8070a() || cpu_is_ipq8071a() ||
 | |
| -+		cpu_is_ipq8172() || cpu_is_ipq8173() ||
 | |
| -+		cpu_is_ipq8174();
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq60xx(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return  cpu_is_ipq6018() || cpu_is_ipq6028() ||
 | |
| -+		cpu_is_ipq6000() || cpu_is_ipq6010() ||
 | |
| -+		cpu_is_ipq6005();
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq50xx(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return  cpu_is_ipq5010() || cpu_is_ipq5018() ||
 | |
| -+		cpu_is_ipq5028() || cpu_is_ipq5000() ||
 | |
| -+		cpu_is_ipq0509() || cpu_is_ipq0518();
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_ipq95xx(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return  cpu_is_ipq9514() || cpu_is_ipq9554() ||
 | |
| -+		cpu_is_ipq9570() || cpu_is_ipq9574() ||
 | |
| -+		cpu_is_ipq9550() || cpu_is_ipq9510();
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_nss_crypto_enabled(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return  cpu_is_ipq807x() || cpu_is_ipq60xx() ||
 | |
| -+		cpu_is_ipq50xx() || cpu_is_ipq9570() ||
 | |
| -+		cpu_is_ipq9550() || cpu_is_ipq9574() ||
 | |
| -+		cpu_is_ipq9554();
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_internal_wifi_enabled(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return  cpu_is_ipq807x() || cpu_is_ipq60xx() ||
 | |
| -+		cpu_is_ipq50xx() || cpu_is_ipq9514() ||
 | |
| -+		cpu_is_ipq9554() || cpu_is_ipq9574();
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_uniphy1_enabled(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return  cpu_is_ipq807x() || cpu_is_ipq60xx() ||
 | |
| -+		cpu_is_ipq9554() || cpu_is_ipq9570() ||
 | |
| -+		cpu_is_ipq9574() || cpu_is_ipq9550();
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+static inline int cpu_is_uniphy2_enabled(void)
 | |
| -+{
 | |
| -+#ifdef CONFIG_ARCH_QCOM
 | |
| -+	return  cpu_is_ipq807x() || cpu_is_ipq9570() ||
 | |
| -+		cpu_is_ipq9574();
 | |
| -+#else
 | |
| -+	return 0;
 | |
| -+#endif
 | |
| -+}
 | |
| -+
 | |
| -+#endif /* _ARCH_ARM_MACH_MSM_SOCINFO_H_ */
 | |
| diff --git a/target/linux/ipq807x/patches-5.15/0902-arm64-dts-ipq8074-add-label-to-clocks.patch b/target/linux/ipq807x/patches-5.15/0902-arm64-dts-ipq8074-add-label-to-clocks.patch
 | |
| deleted file mode 100644
 | |
| index 9b8b4df12b..0000000000
 | |
| --- a/target/linux/ipq807x/patches-5.15/0902-arm64-dts-ipq8074-add-label-to-clocks.patch
 | |
| +++ /dev/null
 | |
| @@ -1,24 +0,0 @@
 | |
| -From 6baf7e4abcea6f7ac21eccf072a20078b39d064c Mon Sep 17 00:00:00 2001
 | |
| -From: Robert Marko <robimarko@gmail.com>
 | |
| -Date: Wed, 9 Feb 2022 23:13:26 +0100
 | |
| -Subject: [PATCH] arm64: dts: ipq8074: add label to clocks
 | |
| -
 | |
| -Add label to clocks node as that makes it easy to add the NSS fixed
 | |
| -clocks that are required in their DTSI.
 | |
| -
 | |
| -Signed-off-by: Robert Marko <robimarko@gmail.com>
 | |
| ----
 | |
| - arch/arm64/boot/dts/qcom/ipq8074.dtsi | 2 +-
 | |
| - 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| -
 | |
| ---- a/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -+++ b/arch/arm64/boot/dts/qcom/ipq8074.dtsi
 | |
| -@@ -15,7 +15,7 @@
 | |
| - 	compatible = "qcom,ipq8074";
 | |
| - 	interrupt-parent = <&intc>;
 | |
| - 
 | |
| --	clocks {
 | |
| -+	clocks: clocks {
 | |
| - 		sleep_clk: sleep_clk {
 | |
| - 			compatible = "fixed-clock";
 | |
| - 			clock-frequency = <32768>;
 | |
| -- 
 | |
| 2.34.1
 | |
| 
 | 
