From 43f844c5442b967bfc833b82323d4e53407f1fc8 Mon Sep 17 00:00:00 2001 From: JiaY-shi Date: Sat, 17 Jun 2023 16:36:08 +0800 Subject: [PATCH] QualcommAX: ipq60xx: enable subtarget and add some miss patch --- target/linux/qualcommax/config-6.6 | 3 + .../arm64/boot/dts/qcom/ipq6018-256m.dtsi | 19 + .../base-files/etc/init.d/smp_affinity | 36 + target/linux/qualcommax/ipq60xx/target.mk | 1 - ...6018-add-qdss_at-clock-needed-for-wi.patch | 2 +- ...dts-qcom-ipq6018-add-blsp1_i2c6-node.patch | 33 + ...pq6018-repair-reserved-memory-missin.patch | 35 + ...com-ipq6018-Add-missing-fixed-clocks.patch | 40 ++ ...-clk-qcom-ipq6018-add-missing-clocks.patch | 642 ++++++++++++++++++ ...c-Add-non-secure-Q6-bringup-sequence.patch | 435 ++++++++++++ ...-rproc-Add-non-secure-Q6-bringup-seq.patch | 55 ++ ...river-for-qualcomm-ipq6018-pwm-block.patch | 601 ++++++++++++++++ ...-arm64-dts-qcom-ipq6018-add-pwm-node.patch | 187 +++++ ...pq6018-rework-nss_port5-clock-to-mul.patch | 66 ++ ...om-ipq6018-assign-some-clock-to-wifi.patch | 40 ++ ...4-dts-qcom-ipq6018-Add-QUP5-SPI-node.patch | 36 + 16 files changed, 2229 insertions(+), 2 deletions(-) create mode 100644 target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-256m.dtsi create mode 100755 target/linux/qualcommax/ipq60xx/base-files/etc/init.d/smp_affinity create mode 100644 target/linux/qualcommax/patches-6.6/1002-arm64-dts-qcom-ipq6018-add-blsp1_i2c6-node.patch create mode 100644 target/linux/qualcommax/patches-6.6/1003-arm64-dts-qcom-ipq6018-repair-reserved-memory-missin.patch create mode 100644 target/linux/qualcommax/patches-6.6/1004-arm64-dts-qcom-ipq6018-Add-missing-fixed-clocks.patch create mode 100644 target/linux/qualcommax/patches-6.6/1005-clk-qcom-ipq6018-add-missing-clocks.patch create mode 100644 target/linux/qualcommax/patches-6.6/1006-ipq6018-rproc-Add-non-secure-Q6-bringup-sequence.patch create mode 100644 target/linux/qualcommax/patches-6.6/1007-Simplify-ipq6018-rproc-Add-non-secure-Q6-bringup-seq.patch create mode 100644 target/linux/qualcommax/patches-6.6/1008-pwm-driver-for-qualcomm-ipq6018-pwm-block.patch create mode 100644 target/linux/qualcommax/patches-6.6/1009-arm64-dts-qcom-ipq6018-add-pwm-node.patch create mode 100644 target/linux/qualcommax/patches-6.6/1010-clk-qcom-gcc-ipq6018-rework-nss_port5-clock-to-mul.patch create mode 100644 target/linux/qualcommax/patches-6.6/1011-arm64-dts-qcom-ipq6018-assign-some-clock-to-wifi.patch create mode 100644 target/linux/qualcommax/patches-6.6/1012-arm64-dts-qcom-ipq6018-Add-QUP5-SPI-node.patch diff --git a/target/linux/qualcommax/config-6.6 b/target/linux/qualcommax/config-6.6 index 1d05868cafd29..70dcc6e614ad9 100644 --- a/target/linux/qualcommax/config-6.6 +++ b/target/linux/qualcommax/config-6.6 @@ -379,6 +379,9 @@ CONFIG_POWER_SUPPLY=y CONFIG_PREEMPT_NONE_BUILD=y CONFIG_PRINTK_TIME=y CONFIG_PTP_1588_CLOCK_OPTIONAL=y +CONFIG_PWM=y +CONFIG_PWM_IPQ=y +CONFIG_PWM_SYSFS=y CONFIG_QCA807X_PHY=y CONFIG_QCA808X_PHY=y # CONFIG_QCM_DISPCC_2290 is not set diff --git a/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-256m.dtsi b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-256m.dtsi new file mode 100644 index 0000000000000..67280b5e6d6d1 --- /dev/null +++ b/target/linux/qualcommax/files/arch/arm64/boot/dts/qcom/ipq6018-256m.dtsi @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include "ipq6018.dtsi" + +&nss_region { + reg = <0x0 0x40000000 0x0 0x00800000>; +}; + +&q6_region { + reg = <0x0 0x4ab00000 0x0 0x02800000>; +}; + +&m3_dump_region { + reg = <0x0 0x4d400000 0x0 0x00100000>; +}; + +&q6_etr_region { + reg = <0x0 0x4d300000 0x0 0x00100000>; +}; \ No newline at end of file diff --git a/target/linux/qualcommax/ipq60xx/base-files/etc/init.d/smp_affinity b/target/linux/qualcommax/ipq60xx/base-files/etc/init.d/smp_affinity new file mode 100755 index 0000000000000..7e3cafa4e087c --- /dev/null +++ b/target/linux/qualcommax/ipq60xx/base-files/etc/init.d/smp_affinity @@ -0,0 +1,36 @@ +#!/bin/sh /etc/rc.common + +START=93 + +enable_affinity_ipq() { + set_affinity() { + irq=$(awk "/$1/{ print substr(\$1, 1, length(\$1)-1); exit }" /proc/interrupts) + [ -n "$irq" ] && echo $2 > /proc/irq/$irq/smp_affinity + } + + # assign 4 rx interrupts to each core + set_affinity 'reo2host-destination-ring1' 1 + set_affinity 'reo2host-destination-ring2' 2 + set_affinity 'reo2host-destination-ring3' 4 + set_affinity 'reo2host-destination-ring4' 8 + + # assign 3 tcl completions to last 3 CPUs + set_affinity 'wbm2host-tx-completions-ring1' 2 + set_affinity 'wbm2host-tx-completions-ring2' 4 + set_affinity 'wbm2host-tx-completions-ring3' 8 + + # assign 3 ppdu mac interrupts to last 3 cores + set_affinity 'ppdu-end-interrupts-mac1' 2 + set_affinity 'ppdu-end-interrupts-mac2' 4 + set_affinity 'ppdu-end-interrupts-mac3' 8 + + # assign lan/wan to core 4 + set_affinity 'edma_txcmpl' 8 + set_affinity 'edma_rxfill' 8 + set_affinity 'edma_rxdesc' 8 + set_affinity 'edma_misc' 8 +} + +boot() { + enable_affinity_ipq +} diff --git a/target/linux/qualcommax/ipq60xx/target.mk b/target/linux/qualcommax/ipq60xx/target.mk index dc3a2ceff607b..06a85ab5e4fbb 100644 --- a/target/linux/qualcommax/ipq60xx/target.mk +++ b/target/linux/qualcommax/ipq60xx/target.mk @@ -1,5 +1,4 @@ SUBTARGET:=ipq60xx -FEATURES += source-only BOARDNAME:=Qualcomm Atheros IPQ60xx DEFAULT_PACKAGES += ath11k-firmware-ipq6018 diff --git a/target/linux/qualcommax/patches-6.6/0060-v6.9-clk-qcom-gcc-ipq6018-add-qdss_at-clock-needed-for-wi.patch b/target/linux/qualcommax/patches-6.6/0060-v6.9-clk-qcom-gcc-ipq6018-add-qdss_at-clock-needed-for-wi.patch index 5f0af1352a8cd..f798fffb28b4a 100644 --- a/target/linux/qualcommax/patches-6.6/0060-v6.9-clk-qcom-gcc-ipq6018-add-qdss_at-clock-needed-for-wi.patch +++ b/target/linux/qualcommax/patches-6.6/0060-v6.9-clk-qcom-gcc-ipq6018-add-qdss_at-clock-needed-for-wi.patch @@ -31,7 +31,7 @@ Signed-off-by: Bjorn Andersson + .parent_hws = (const struct clk_hw *[]){ + &qdss_at_clk_src.clkr.hw }, + .num_parents = 1, -+ .flags = CLK_SET_RATE_PARENT, ++ .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, diff --git a/target/linux/qualcommax/patches-6.6/1002-arm64-dts-qcom-ipq6018-add-blsp1_i2c6-node.patch b/target/linux/qualcommax/patches-6.6/1002-arm64-dts-qcom-ipq6018-add-blsp1_i2c6-node.patch new file mode 100644 index 0000000000000..45197366dd019 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/1002-arm64-dts-qcom-ipq6018-add-blsp1_i2c6-node.patch @@ -0,0 +1,33 @@ +From ba4cdc72744a217ba1d0d345e074ff65d7ec8c37 Mon Sep 17 00:00:00 2001 +From: JiaY-shi +Date: Tue, 6 Jun 2023 19:35:55 +0800 +Subject: [PATCH 155/155] arm64: dts: qcom: ipq6018: add blsp1_i2c6 node + +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -626,6 +626,21 @@ + status = "disabled"; + }; + ++ blsp1_i2c6: i2c@78ba000 { ++ compatible = "qcom,i2c-qup-v2.2.1"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x0 0x078ba000 0x0 0x600>; ++ interrupts = ; ++ clocks = <&gcc GCC_BLSP1_QUP6_I2C_APPS_CLK>, ++ <&gcc GCC_BLSP1_AHB_CLK>; ++ clock-names = "core", "iface"; ++ clock-frequency = <400000>; ++ dmas = <&blsp_dma 22>, <&blsp_dma 23>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ + qpic_bam: dma-controller@7984000 { + compatible = "qcom,bam-v1.7.0"; + reg = <0x0 0x07984000 0x0 0x1a000>; diff --git a/target/linux/qualcommax/patches-6.6/1003-arm64-dts-qcom-ipq6018-repair-reserved-memory-missin.patch b/target/linux/qualcommax/patches-6.6/1003-arm64-dts-qcom-ipq6018-repair-reserved-memory-missin.patch new file mode 100644 index 0000000000000..d502277a7b6f6 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/1003-arm64-dts-qcom-ipq6018-repair-reserved-memory-missin.patch @@ -0,0 +1,35 @@ +From 0ad5a9666e0eca72fc4546ed384a40b1430ddd8b Mon Sep 17 00:00:00 2001 +From: JiaY-shi +Date: Mon, 12 Jun 2023 15:06:01 +0800 +Subject: [PATCH] arm64: dts: qcom: ipq6018: repair reserved-memory missing + nodes + +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 31 +++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -223,6 +223,22 @@ + reg = <0x0 0x4ab00000 0x0 0x5500000>; + no-map; + }; ++ ++ nss_region: nss@40000000 { ++ no-map; ++ reg = <0x0 0x40000000 0x0 0x01000000>; ++ }; ++ ++ q6_etr_region: q6_etr_dump@1 { ++ no-map; ++ reg = <0x0 0x50000000 0x0 0x00100000>; ++ }; ++ ++ m3_dump_region: m3_dump@50100000 { ++ no-map; ++ reg = <0x0 0x50100000 0x0 0x00100000>; ++ }; ++ + }; + + smem { diff --git a/target/linux/qualcommax/patches-6.6/1004-arm64-dts-qcom-ipq6018-Add-missing-fixed-clocks.patch b/target/linux/qualcommax/patches-6.6/1004-arm64-dts-qcom-ipq6018-Add-missing-fixed-clocks.patch new file mode 100644 index 0000000000000..4f96b319599bd --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/1004-arm64-dts-qcom-ipq6018-Add-missing-fixed-clocks.patch @@ -0,0 +1,40 @@ +From 48d8e82ed977f07211f827834d6ee6e6fe3336d8 Mon Sep 17 00:00:00 2001 +From: Alexandru Gagniuc +Date: Sat, 27 Aug 2022 17:33:37 -0500 +Subject: [PATCH 1004/1010] arm64: dts: qcom: ipq6018: Add missing fixed-clocks + +Signed-off-by: Alexandru Gagniuc +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -28,6 +28,12 @@ + clock-frequency = <24000000>; + #clock-cells = <0>; + }; ++ ++ usb3phy_0_cc_pipe_clk: usb3phy-0-cc-pipe-clk { ++ compatible = "fixed-clock"; ++ clock-frequency = <125000000>; ++ #clock-cells = <0>; ++ }; + }; + + cpus: cpus { +@@ -433,8 +439,12 @@ + gcc: gcc@1800000 { + compatible = "qcom,gcc-ipq6018"; + reg = <0x0 0x01800000 0x0 0x80000>; +- clocks = <&xo>, <&sleep_clk>; +- clock-names = "xo", "sleep_clk"; ++ clocks = <&xo>, ++ <&sleep_clk>, ++ <&usb3phy_0_cc_pipe_clk>; ++ clock-names = "xo", ++ "sleep_clk", ++ "usb3phy_0_cc_pipe_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + }; diff --git a/target/linux/qualcommax/patches-6.6/1005-clk-qcom-ipq6018-add-missing-clocks.patch b/target/linux/qualcommax/patches-6.6/1005-clk-qcom-ipq6018-add-missing-clocks.patch new file mode 100644 index 0000000000000..1f210fc24c31c --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/1005-clk-qcom-ipq6018-add-missing-clocks.patch @@ -0,0 +1,642 @@ +From 86c704b73063eb61d1dc7aaf0d110a88b09c6134 Mon Sep 17 00:00:00 2001 +From: anusha +Date: Wed, 19 Aug 2020 17:59:22 +0530 +Subject: [PATCH 1001/1010] clk: qcom: ipq6018: add missing clocks + +A large number of clocks are missing for the IPQ6018. Add those clocks +from the downstream QCA 5.4 kernel. + +Signed-off-by: anusha +Signed-off-by: Alexandru Gagniuc +--- + drivers/clk/qcom/gcc-ipq6018.c | 587 +++++++++++++++++++++++++++++++++ + 1 file changed, 587 insertions(+) + +--- a/drivers/clk/qcom/gcc-ipq6018.c ++++ b/drivers/clk/qcom/gcc-ipq6018.c +@@ -212,6 +212,19 @@ static struct clk_rcg2 pcnoc_bfdcd_clk_s + }, + }; + ++static struct clk_fixed_factor pcnoc_clk_src = { ++ .mult = 1, ++ .div = 1, ++ .hw.init = &(struct clk_init_data){ ++ .name = "pcnoc_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, ++ }, ++}; ++ + static struct clk_alpha_pll gpll2_main = { + .offset = 0x4a000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], +@@ -490,6 +503,19 @@ static struct clk_rcg2 snoc_nssnoc_bfdcd + }, + }; + ++static struct clk_fixed_factor snoc_nssnoc_clk_src = { ++ .mult = 1, ++ .div = 1, ++ .hw.init = &(struct clk_init_data){ ++ .name = "snoc_nssnoc_clk_src", ++ .parent_hws = (const struct clk_hw *[]){ ++ &snoc_nssnoc_bfdcd_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .ops = &clk_fixed_factor_ops, ++ .flags = CLK_SET_RATE_PARENT, ++ }, ++}; ++ + static const struct freq_tbl ftbl_apss_ahb_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0_DIV2, 16, 0, 0), +@@ -1890,6 +1916,19 @@ static struct clk_rcg2 system_noc_bfdcd_ + }, + }; + ++static struct clk_fixed_factor system_noc_clk_src = { ++ .mult = 1, ++ .div = 1, ++ .hw.init = &(struct clk_init_data){ ++ .name = "system_noc_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, ++ }, ++}; ++ + static const struct freq_tbl ftbl_ubi32_mem_noc_bfdcd_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(307670000, P_BIAS_PLL_NSS_NOC, 1.5, 0, 0), +@@ -1924,6 +1963,19 @@ static struct clk_rcg2 ubi32_mem_noc_bfd + }, + }; + ++static struct clk_fixed_factor ubi32_mem_noc_clk_src = { ++ .mult = 1, ++ .div = 1, ++ .hw.init = &(struct clk_init_data){ ++ .name = "ubi32_mem_noc_clk_src", ++ .parent_hws = (const struct clk_hw *[]){ ++ &ubi32_mem_noc_bfdcd_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .ops = &clk_fixed_factor_ops, ++ .flags = CLK_SET_RATE_PARENT, ++ }, ++}; ++ + static struct clk_branch gcc_apss_axi_clk = { + .halt_reg = 0x46020, + .halt_check = BRANCH_HALT_VOTED, +@@ -2681,6 +2733,454 @@ static struct clk_rcg2 lpass_q6_axim_clk + }, + }; + ++static struct clk_branch gcc_wcss_axi_m_clk = { ++ .halt_reg = 0x5903C, ++ .clkr = { ++ .enable_reg = 0x5903C, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_axi_m_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &system_noc_clk_src.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_sys_noc_wcss_ahb_clk = { ++ .halt_reg = 0x26034, ++ .clkr = { ++ .enable_reg = 0x26034, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_sys_noc_wcss_ahb_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &wcss_ahb_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_q6_axim_clk = { ++ .halt_reg = 0x5913C, ++ .clkr = { ++ .enable_reg = 0x5913C, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_q6_axim_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &q6_axi_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_q6ss_atbm_clk = { ++ .halt_reg = 0x59144, ++ .clkr = { ++ .enable_reg = 0x59144, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_q6ss_atbm_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_at_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_q6ss_pclkdbg_clk = { ++ .halt_reg = 0x59140, ++ .clkr = { ++ .enable_reg = 0x59140, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_q6ss_pclkdbg_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_dap_sync_clk_src.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_q6_tsctr_1to2_clk = { ++ .halt_reg = 0x59148, ++ .clkr = { ++ .enable_reg = 0x59148, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_q6_tsctr_1to2_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_tsctr_div2_clk_src.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_core_tbu_clk = { ++ .halt_reg = 0x12028, ++ .clkr = { ++ .enable_reg = 0xb00c, ++ .enable_mask = BIT(7), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_core_tbu_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &system_noc_clk_src.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_q6_tbu_clk = { ++ .halt_reg = 0x1202C, ++ .clkr = { ++ .enable_reg = 0xb00c, ++ .enable_mask = BIT(8), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_q6_tbu_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &q6_axi_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_q6_axim2_clk = { ++ .halt_reg = 0x59150, ++ .clkr = { ++ .enable_reg = 0x59150, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_q6_axim2_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &q6_axi_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_q6_ahb_clk = { ++ .halt_reg = 0x59138, ++ .clkr = { ++ .enable_reg = 0x59138, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_q6_ahb_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &wcss_ahb_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_q6_ahb_s_clk = { ++ .halt_reg = 0x5914C, ++ .clkr = { ++ .enable_reg = 0x5914C, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_q6_ahb_s_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &wcss_ahb_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_dbg_ifc_apb_clk = { ++ .halt_reg = 0x59040, ++ .clkr = { ++ .enable_reg = 0x59040, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_dbg_ifc_apb_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_dap_sync_clk_src.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_dbg_ifc_atb_clk = { ++ .halt_reg = 0x59044, ++ .clkr = { ++ .enable_reg = 0x59044, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_dbg_ifc_atb_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_at_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_dbg_ifc_nts_clk = { ++ .halt_reg = 0x59048, ++ .clkr = { ++ .enable_reg = 0x59048, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_dbg_ifc_nts_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_tsctr_div2_clk_src.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_dbg_ifc_dapbus_clk = { ++ .halt_reg = 0x5905C, ++ .clkr = { ++ .enable_reg = 0x5905C, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_dbg_ifc_dapbus_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_dap_sync_clk_src.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_dbg_ifc_apb_bdg_clk = { ++ .halt_reg = 0x59050, ++ .clkr = { ++ .enable_reg = 0x59050, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_dbg_ifc_apb_bdg_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_dap_sync_clk_src.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_dbg_ifc_atb_bdg_clk = { ++ .halt_reg = 0x59054, ++ .clkr = { ++ .enable_reg = 0x59054, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_dbg_ifc_atb_bdg_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_at_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_dbg_ifc_nts_bdg_clk = { ++ .halt_reg = 0x59058, ++ .clkr = { ++ .enable_reg = 0x59058, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_dbg_ifc_nts_bdg_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_tsctr_div2_clk_src.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_dbg_ifc_dapbus_bdg_clk = { ++ .halt_reg = 0x59060, ++ .clkr = { ++ .enable_reg = 0x59060, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_dbg_ifc_dapbus_bdg_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_dap_sync_clk_src.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_nssnoc_atb_clk = { ++ .halt_reg = 0x6818C, ++ .clkr = { ++ .enable_reg = 0x6818C, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_nssnoc_atb_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_at_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_ecahb_clk = { ++ .halt_reg = 0x59038, ++ .clkr = { ++ .enable_reg = 0x59038, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_ecahb_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &wcss_ahb_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_acmt_clk = { ++ .halt_reg = 0x59064, ++ .clkr = { ++ .enable_reg = 0x59064, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_acmt_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &wcss_ahb_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_wcss_ahb_s_clk = { ++ .halt_reg = 0x59034, ++ .clkr = { ++ .enable_reg = 0x59034, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_wcss_ahb_s_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &wcss_ahb_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++struct clk_branch gcc_rbcpr_wcss_ahb_clk = { ++ .halt_reg = 0x3A008, ++ .clkr = { ++ .enable_reg = 0x3A008, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_rbcpr_wcss_ahb_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &pcnoc_clk_src.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++struct clk_branch gcc_mem_noc_q6_axi_clk = { ++ .halt_reg = 0x1D038, ++ .clkr = { ++ .enable_reg = 0x1D038, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_mem_noc_q6_axi_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &q6_axi_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_sys_noc_qdss_stm_axi_clk = { ++ .halt_reg = 0x26024, ++ .clkr = { ++ .enable_reg = 0x26024, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_sys_noc_qdss_stm_axi_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_stm_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_qdss_stm_clk = { ++ .halt_reg = 0x29044, ++ .clkr = { ++ .enable_reg = 0x29044, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_qdss_stm_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_stm_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++static struct clk_branch gcc_qdss_traceclkin_clk = { ++ .halt_reg = 0x29060, ++ .clkr = { ++ .enable_reg = 0x29060, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_qdss_traceclkin_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &qdss_traceclkin_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ + static struct freq_tbl ftbl_rbcpr_wcss_clk_src[] = { + F(24000000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), +@@ -2700,6 +3200,23 @@ static struct clk_rcg2 rbcpr_wcss_clk_sr + }, + }; + ++struct clk_branch gcc_rbcpr_wcss_clk = { ++ .halt_reg = 0x3A004, ++ .clkr = { ++ .enable_reg = 0x3A004, ++ .enable_mask = BIT(0), ++ .hw.init = &(struct clk_init_data){ ++ .name = "gcc_rbcpr_wcss_clk", ++ .parent_hws = (const struct clk_hw *[]){ ++ &rbcpr_wcss_clk_src.clkr.hw }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, ++ .ops = &clk_branch2_ops, ++ }, ++ }, ++}; ++ ++ + static struct clk_branch gcc_lpass_core_axim_clk = { + .halt_reg = 0x1F028, + .clkr = { +@@ -4213,6 +4730,9 @@ static struct clk_hw *gcc_ipq6018_hws[] + &gpll6_out_main_div2.hw, + &qdss_dap_sync_clk_src.hw, + &qdss_tsctr_div2_clk_src.hw, ++ &pcnoc_clk_src.hw, ++ &snoc_nssnoc_clk_src.hw, ++ &ubi32_mem_noc_clk_src.hw, + }; + + static struct clk_regmap *gcc_ipq6018_clks[] = { +@@ -4418,9 +4938,35 @@ static struct clk_regmap *gcc_ipq6018_cl + [PCIE0_RCHNG_CLK_SRC] = &pcie0_rchng_clk_src.clkr, + [GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr, + [PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr, ++ [GCC_WCSS_AXI_M_CLK] = &gcc_wcss_axi_m_clk.clkr, ++ [GCC_SYS_NOC_WCSS_AHB_CLK] = &gcc_sys_noc_wcss_ahb_clk.clkr, + [WCSS_AHB_CLK_SRC] = &wcss_ahb_clk_src.clkr, ++ [GCC_Q6_AXIM_CLK] = &gcc_q6_axim_clk.clkr, + [Q6_AXI_CLK_SRC] = &q6_axi_clk_src.clkr, ++ [GCC_Q6SS_ATBM_CLK] = &gcc_q6ss_atbm_clk.clkr, ++ [GCC_Q6SS_PCLKDBG_CLK] = &gcc_q6ss_pclkdbg_clk.clkr, ++ [GCC_Q6_TSCTR_1TO2_CLK] = &gcc_q6_tsctr_1to2_clk.clkr, ++ [GCC_WCSS_CORE_TBU_CLK] = &gcc_wcss_core_tbu_clk.clkr, ++ [GCC_WCSS_Q6_TBU_CLK] = &gcc_wcss_q6_tbu_clk.clkr, ++ [GCC_Q6_AXIM2_CLK] = &gcc_q6_axim2_clk.clkr, ++ [GCC_Q6_AHB_CLK] = &gcc_q6_ahb_clk.clkr, ++ [GCC_Q6_AHB_S_CLK] = &gcc_q6_ahb_s_clk.clkr, ++ [GCC_WCSS_DBG_IFC_APB_CLK] = &gcc_wcss_dbg_ifc_apb_clk.clkr, ++ [GCC_WCSS_DBG_IFC_ATB_CLK] = &gcc_wcss_dbg_ifc_atb_clk.clkr, ++ [GCC_WCSS_DBG_IFC_NTS_CLK] = &gcc_wcss_dbg_ifc_nts_clk.clkr, ++ [GCC_WCSS_DBG_IFC_DAPBUS_CLK] = &gcc_wcss_dbg_ifc_dapbus_clk.clkr, ++ [GCC_WCSS_DBG_IFC_APB_BDG_CLK] = &gcc_wcss_dbg_ifc_apb_bdg_clk.clkr, ++ [GCC_WCSS_DBG_IFC_ATB_BDG_CLK] = &gcc_wcss_dbg_ifc_atb_bdg_clk.clkr, ++ [GCC_WCSS_DBG_IFC_NTS_BDG_CLK] = &gcc_wcss_dbg_ifc_nts_bdg_clk.clkr, ++ [GCC_WCSS_DBG_IFC_DAPBUS_BDG_CLK] = &gcc_wcss_dbg_ifc_dapbus_bdg_clk.clkr, ++ [GCC_NSSNOC_ATB_CLK] = &gcc_nssnoc_atb_clk.clkr, ++ [GCC_WCSS_ECAHB_CLK] = &gcc_wcss_ecahb_clk.clkr, ++ [GCC_WCSS_ACMT_CLK] = &gcc_wcss_acmt_clk.clkr, ++ [GCC_WCSS_AHB_S_CLK] = &gcc_wcss_ahb_s_clk.clkr, ++ [GCC_RBCPR_WCSS_CLK] = &gcc_rbcpr_wcss_clk.clkr, + [RBCPR_WCSS_CLK_SRC] = &rbcpr_wcss_clk_src.clkr, ++ [GCC_RBCPR_WCSS_AHB_CLK] = &gcc_rbcpr_wcss_ahb_clk.clkr, ++ [GCC_MEM_NOC_Q6_AXI_CLK] = &gcc_mem_noc_q6_axi_clk.clkr, + [GCC_LPASS_CORE_AXIM_CLK] = &gcc_lpass_core_axim_clk.clkr, + [LPASS_CORE_AXIM_CLK_SRC] = &lpass_core_axim_clk_src.clkr, + [GCC_LPASS_SNOC_CFG_CLK] = &gcc_lpass_snoc_cfg_clk.clkr, +@@ -4436,6 +4982,9 @@ static struct clk_regmap *gcc_ipq6018_cl + [GCC_MEM_NOC_UBI32_CLK] = &gcc_mem_noc_ubi32_clk.clkr, + [GCC_MEM_NOC_LPASS_CLK] = &gcc_mem_noc_lpass_clk.clkr, + [GCC_SNOC_LPASS_CFG_CLK] = &gcc_snoc_lpass_cfg_clk.clkr, ++ [GCC_SYS_NOC_QDSS_STM_AXI_CLK] = &gcc_sys_noc_qdss_stm_axi_clk.clkr, ++ [GCC_QDSS_STM_CLK] = &gcc_qdss_stm_clk.clkr, ++ [GCC_QDSS_TRACECLKIN_CLK] = &gcc_qdss_traceclkin_clk.clkr, + [QDSS_STM_CLK_SRC] = &qdss_stm_clk_src.clkr, + [QDSS_TRACECLKIN_CLK_SRC] = &qdss_traceclkin_clk_src.clkr, + }; +@@ -4617,6 +5166,10 @@ static const struct qcom_cc_desc gcc_ipq + static int gcc_ipq6018_probe(struct platform_device *pdev) + { + struct regmap *regmap; ++ struct device *dev = &pdev->dev; ++ ++ clk_register_fixed_rate(dev, "pcie20_phy0_pipe_clk", NULL, 0, ++ 250000000); + + regmap = qcom_cc_map(pdev, &gcc_ipq6018_desc); + if (IS_ERR(regmap)) diff --git a/target/linux/qualcommax/patches-6.6/1006-ipq6018-rproc-Add-non-secure-Q6-bringup-sequence.patch b/target/linux/qualcommax/patches-6.6/1006-ipq6018-rproc-Add-non-secure-Q6-bringup-sequence.patch new file mode 100644 index 0000000000000..93d54740d1363 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/1006-ipq6018-rproc-Add-non-secure-Q6-bringup-sequence.patch @@ -0,0 +1,435 @@ +From 4ebe7624c51ff95ec13f5dda9cca7c0abe59cd0e Mon Sep 17 00:00:00 2001 +From: Manikanta Mylavarapu +Date: Fri, 31 Dec 2021 17:13:59 +0530 +Subject: [PATCH 1006/1010] ipq6018: rproc: Add non secure Q6 bringup sequence + +This patch adds Q6 bring up sequence support. + +Change-Id: I28eee991168034cc240d863e736ed9c766ec4f33 +Signed-off-by: Manikanta Mylavarapu +--- + drivers/remoteproc/qcom_q6v5_wcss.c | 223 ++++++++++++++++++++++++-- + 2 files changed, 227 insertions(+), 16 deletions(-) + +--- a/drivers/remoteproc/qcom_q6v5_wcss.c ++++ b/drivers/remoteproc/qcom_q6v5_wcss.c +@@ -27,6 +27,7 @@ + + /* Q6SS Register Offsets */ + #define Q6SS_RESET_REG 0x014 ++#define Q6SS_DBG_CFG 0x018 + #define Q6SS_GFMUX_CTL_REG 0x020 + #define Q6SS_PWR_CTL_REG 0x030 + #define Q6SS_MEM_PWR_CTL 0x0B0 +@@ -68,6 +69,7 @@ + #define HALT_CHECK_MAX_LOOPS 200 + #define Q6SS_XO_CBCR GENMASK(5, 3) + #define Q6SS_SLEEP_CBCR GENMASK(5, 2) ++#define Q6SS_TIMEOUT_US 1000 + + /* Q6SS config/status registers */ + #define TCSR_GLOBAL_CFG0 0x0 +@@ -78,6 +80,7 @@ + #define Q6SS_RST_EVB 0x10 + + #define BHS_EN_REST_ACK BIT(0) ++#define WCSS_HM_RET BIT(1) + #define SSCAON_ENABLE BIT(13) + #define SSCAON_BUS_EN BIT(15) + #define SSCAON_BUS_MUX_MASK GENMASK(18, 16) +@@ -120,6 +123,11 @@ struct q6v5_wcss { + struct clk *qdsp6ss_core_gfmux; + struct clk *lcc_bcr_sleep; + struct clk *prng_clk; ++ struct clk *gcc_sys_noc_wcss_ahb_clk; ++ struct clk *gcc_q6ss_atbm_clk; ++ struct clk *gcc_q6ss_pclkdbg_clk; ++ struct clk *gcc_q6_tsctr_1to2_clk; ++ + struct clk *qdss_clk; + struct regulator *cx_supply; + struct qcom_sysmon *sysmon; +@@ -165,12 +173,77 @@ struct wcss_data { + bool need_auto_boot; + }; + ++static const struct wcss_data wcss_ipq6018_res_init; ++ ++static int ipq6018_clks_prepare_enable(struct q6v5_wcss *wcss) ++{ ++ int ret; ++ ++ ret = clk_prepare_enable(wcss->gcc_sys_noc_wcss_ahb_clk); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare_enable(wcss->gcc_q6ss_atbm_clk); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare_enable(wcss->gcc_q6ss_pclkdbg_clk); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare_enable(wcss->gcc_q6_tsctr_1to2_clk); ++ if (ret) ++ return ret; ++ ++ return 0; ++} ++ ++static void ipq6018_clks_prepare_disable(struct q6v5_wcss *wcss) ++{ ++ clk_disable_unprepare(wcss->gcc_sys_noc_wcss_ahb_clk); ++ clk_disable_unprepare(wcss->gcc_q6ss_atbm_clk); ++ clk_disable_unprepare(wcss->gcc_q6ss_pclkdbg_clk); ++ clk_disable_unprepare(wcss->gcc_q6_tsctr_1to2_clk); ++} ++ + static int q6v5_wcss_reset(struct q6v5_wcss *wcss) + { ++ const struct wcss_data *desc; + int ret; + u32 val; + int i; + ++ desc = device_get_match_data(wcss->dev); ++ if (desc == &wcss_ipq6018_res_init) { ++ if (desc->aon_reset_required) { ++ /* Deassert wcss aon reset */ ++ ret = reset_control_deassert(wcss->wcss_aon_reset); ++ if (ret) { ++ dev_err(wcss->dev, "wcss_aon_reset failed\n"); ++ return ret; ++ } ++ mdelay(1); ++ } ++ ++ ret = ipq6018_clks_prepare_enable(wcss); ++ if (ret) { ++ dev_err(wcss->dev, "failed to enable clock\n"); ++ return ret; ++ } ++ } ++ ++ val = readl(wcss->rmb_base + SSCAON_CONFIG); ++ val |= BIT(0); ++ writel(val, wcss->rmb_base + SSCAON_CONFIG); ++ mdelay(1); ++ ++ /*set CFG[18:15]=1* and clear CFG[1]=0*/ ++ val = readl(wcss->rmb_base + SSCAON_CONFIG); ++ val &= ~(SSCAON_BUS_MUX_MASK | WCSS_HM_RET); ++ val |= SSCAON_BUS_EN; ++ writel(val, wcss->rmb_base + SSCAON_CONFIG); ++ mdelay(1); ++ + /* Assert resets, stop core */ + val = readl(wcss->reg_base + Q6SS_RESET_REG); + val |= Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE; +@@ -196,7 +269,19 @@ static int q6v5_wcss_reset(struct q6v5_w + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + udelay(1); + ++ if (desc == &wcss_ipq6018_res_init) { ++ /* 10 - Wait till BHS Reset is done */ ++ ret = readl_poll_timeout(wcss->reg_base + Q6SS_BHS_STATUS, ++ val, (val & BHS_EN_REST_ACK), 1000, ++ Q6SS_TIMEOUT_US * 50); ++ if (ret) { ++ dev_err(wcss->dev, "BHS_STATUS not ON (rc:%d) val:0x%X\n", ret, val); ++ return ret; ++ } ++ } ++ + /* Put LDO in bypass mode */ ++ val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG); + val |= Q6SS_LDO_BYP; + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + +@@ -206,6 +291,7 @@ static int q6v5_wcss_reset(struct q6v5_w + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + + /* Deassert memory peripheral sleep and L2 memory standby */ ++ val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG); + val |= Q6SS_L2DATA_STBY_N | Q6SS_SLP_RET_N; + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + +@@ -220,7 +306,10 @@ static int q6v5_wcss_reset(struct q6v5_w + * array to turn on. + */ + val |= readl(wcss->reg_base + Q6SS_MEM_PWR_CTL); +- udelay(1); ++ if (desc == &wcss_ipq6018_res_init) ++ mdelay(10); ++ else ++ udelay(1); + } + /* Remove word line clamp */ + val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG); +@@ -228,6 +317,7 @@ static int q6v5_wcss_reset(struct q6v5_w + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + + /* Remove IO clamp */ ++ val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG); + val &= ~Q6SS_CLAMP_IO; + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + +@@ -246,6 +336,16 @@ static int q6v5_wcss_reset(struct q6v5_w + val &= ~Q6SS_STOP_CORE; + writel(val, wcss->reg_base + Q6SS_RESET_REG); + ++ /* Wait for SSCAON_STATUS */ ++ val = readl(wcss->rmb_base + SSCAON_STATUS); ++ ret = readl_poll_timeout(wcss->rmb_base + SSCAON_STATUS, ++ val, (val & 0xffff) == 0x10, 1000, ++ Q6SS_TIMEOUT_US * 1000); ++ if (ret) { ++ dev_err(wcss->dev, " Boot Error, SSCAON=0x%08X\n", val); ++ return ret; ++ } ++ + return 0; + } + +@@ -380,7 +480,7 @@ static int q6v5_wcss_qcs404_power_on(str + /* Read CLKOFF bit to go low indicating CLK is enabled */ + ret = readl_poll_timeout(wcss->reg_base + Q6SS_XO_CBCR, + val, !(val & BIT(31)), 1, +- HALT_CHECK_MAX_LOOPS); ++ Q6SS_TIMEOUT_US); + if (ret) { + dev_err(wcss->dev, + "xo cbcr enabling timed out (rc:%d)\n", ret); +@@ -533,13 +633,18 @@ static void q6v5_wcss_halt_axi_port(stru + unsigned long timeout; + unsigned int val; + int ret; ++ const struct wcss_data *desc = device_get_match_data(wcss->dev); + +- /* Check if we're already idle */ +- ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); +- if (!ret && val) +- return; ++ if (desc != &wcss_ipq6018_res_init) { ++ /* Check if we're already idle */ ++ ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); ++ if (!ret && val) ++ return; ++ } + + /* Assert halt request */ ++ regmap_read(halt_map, offset + AXI_HALTREQ_REG, &val); ++ val |= BIT(0); + regmap_write(halt_map, offset + AXI_HALTREQ_REG, 1); + + /* Wait for halt */ +@@ -552,12 +657,14 @@ static void q6v5_wcss_halt_axi_port(stru + msleep(1); + } + +- ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); +- if (ret || !val) +- dev_err(wcss->dev, "port failed halt\n"); ++ if (desc != &wcss_ipq6018_res_init) { ++ ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); ++ if (ret || !val) ++ dev_err(wcss->dev, "port failed halt\n"); + +- /* Clear halt request (port will remain halted until reset) */ +- regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0); ++ /* Clear halt request (port will remain halted until reset) */ ++ regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0); ++ } + } + + static int q6v5_qcs404_wcss_shutdown(struct q6v5_wcss *wcss) +@@ -626,6 +733,7 @@ static int q6v5_qcs404_wcss_shutdown(str + + static int q6v5_wcss_powerdown(struct q6v5_wcss *wcss) + { ++ const struct wcss_data *desc = device_get_match_data(wcss->dev); + int ret; + u32 val; + +@@ -643,21 +751,26 @@ static int q6v5_wcss_powerdown(struct q6 + writel(val, wcss->rmb_base + SSCAON_CONFIG); + + /* 4 - SSCAON_CONFIG 1 */ ++ val = readl(wcss->rmb_base + SSCAON_CONFIG); + val |= BIT(1); + writel(val, wcss->rmb_base + SSCAON_CONFIG); + + /* 5 - wait for SSCAON_STATUS */ + ret = readl_poll_timeout(wcss->rmb_base + SSCAON_STATUS, + val, (val & 0xffff) == 0x400, 1000, +- HALT_CHECK_MAX_LOOPS); ++ Q6SS_TIMEOUT_US * 10); + if (ret) { + dev_err(wcss->dev, + "can't get SSCAON_STATUS rc:%d)\n", ret); + return ret; + } + ++ mdelay(2); ++ + /* 6 - De-assert WCSS_AON reset */ + reset_control_assert(wcss->wcss_aon_reset); ++ if (desc == &wcss_ipq6018_res_init) ++ mdelay(1); + + /* 7 - Disable WCSSAON_CONFIG 13 */ + val = readl(wcss->rmb_base + SSCAON_CONFIG); +@@ -667,6 +780,13 @@ static int q6v5_wcss_powerdown(struct q6 + /* 8 - De-assert WCSS/Q6 HALTREQ */ + reset_control_assert(wcss->wcss_reset); + ++ if (desc == &wcss_ipq6018_res_init) { ++ /* Clear halt request (port will remain halted until reset) */ ++ regmap_read(wcss->halt_map, wcss->halt_wcss + AXI_HALTREQ_REG, &val); ++ val &= ~0x1; ++ regmap_write(wcss->halt_map, wcss->halt_wcss + AXI_HALTREQ_REG, val); ++ } ++ + return 0; + } + +@@ -675,6 +795,12 @@ static int q6v5_q6_powerdown(struct q6v5 + int ret; + u32 val; + int i; ++ const struct wcss_data *desc = device_get_match_data(wcss->dev); ++ ++ if (desc == &wcss_ipq6018_res_init) { ++ /* To retain power domain after q6 powerdown */ ++ writel(0x1, wcss->reg_base + Q6SS_DBG_CFG); ++ } + + /* 1 - Halt Q6 bus interface */ + q6v5_wcss_halt_axi_port(wcss, wcss->halt_map, wcss->halt_q6); +@@ -690,14 +816,17 @@ static int q6v5_q6_powerdown(struct q6v5 + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + + /* 4 - Clamp WL */ ++ val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG); + val |= QDSS_BHS_ON; + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + + /* 5 - Clear Erase standby */ ++ val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG); + val &= ~Q6SS_L2DATA_STBY_N; + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + + /* 6 - Clear Sleep RTN */ ++ val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG); + val &= ~Q6SS_SLP_RET_N; + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + +@@ -715,6 +844,7 @@ static int q6v5_q6_powerdown(struct q6v5 + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + + /* 9 - Turn off BHS */ ++ val = readl(wcss->reg_base + Q6SS_PWR_CTL_REG); + val &= ~Q6SS_BHS_ON; + writel(val, wcss->reg_base + Q6SS_PWR_CTL_REG); + udelay(1); +@@ -722,7 +852,7 @@ static int q6v5_q6_powerdown(struct q6v5 + /* 10 - Wait till BHS Reset is done */ + ret = readl_poll_timeout(wcss->reg_base + Q6SS_BHS_STATUS, + val, !(val & BHS_EN_REST_ACK), 1000, +- HALT_CHECK_MAX_LOOPS); ++ Q6SS_TIMEOUT_US * 10); + if (ret) { + dev_err(wcss->dev, "BHS_STATUS not OFF (rc:%d)\n", ret); + return ret; +@@ -730,9 +860,23 @@ static int q6v5_q6_powerdown(struct q6v5 + + /* 11 - Assert WCSS reset */ + reset_control_assert(wcss->wcss_reset); ++ if (desc == &wcss_ipq6018_res_init) ++ mdelay(1); + + /* 12 - Assert Q6 reset */ + reset_control_assert(wcss->wcss_q6_reset); ++ if (desc == &wcss_ipq6018_res_init) { ++ mdelay(2); ++ ++ /* Clear halt request (port will remain halted until reset) */ ++ regmap_read(wcss->halt_map, wcss->halt_q6 + AXI_HALTREQ_REG, &val); ++ val &= ~0x1; ++ regmap_write(wcss->halt_map, wcss->halt_q6 + AXI_HALTREQ_REG, val); ++ mdelay(1); ++ ++ /* Disable clocks*/ ++ ipq6018_clks_prepare_disable(wcss); ++ } + + return 0; + } +@@ -975,6 +1119,57 @@ static int q6v5_alloc_memory_region(stru + return 0; + } + ++static int ipq6018_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; ++ } ++ ++ wcss->gcc_sys_noc_wcss_ahb_clk = ++ devm_clk_get(wcss->dev, "gcc_sys_noc_wcss_ahb_clk"); ++ if (IS_ERR(wcss->gcc_sys_noc_wcss_ahb_clk)) { ++ ret = PTR_ERR(wcss->gcc_sys_noc_wcss_ahb_clk); ++ if (ret != -EPROBE_DEFER) ++ dev_err(wcss->dev, "Failed to get sys_noc_wcss_ahb clock\n"); ++ return ret; ++ } ++ ++ wcss->gcc_q6ss_atbm_clk = ++ devm_clk_get(wcss->dev, "gcc_q6ss_atbm_clk"); ++ if (IS_ERR(wcss->gcc_q6ss_atbm_clk)) { ++ ret = PTR_ERR(wcss->gcc_q6ss_atbm_clk); ++ if (ret != -EPROBE_DEFER) ++ dev_err(wcss->dev, "Failed to get q6ss_atbm clock\n"); ++ return ret; ++ } ++ ++ wcss->gcc_q6ss_pclkdbg_clk = ++ devm_clk_get(wcss->dev, "gcc_q6ss_pclkdbg_clk"); ++ if (IS_ERR(wcss->gcc_q6ss_pclkdbg_clk)) { ++ ret = PTR_ERR(wcss->gcc_q6ss_pclkdbg_clk); ++ if (ret != -EPROBE_DEFER) ++ dev_err(wcss->dev, "Failed to get q6ss_pclkdbg clock\n"); ++ return ret; ++ } ++ ++ wcss->gcc_q6_tsctr_1to2_clk = ++ devm_clk_get(wcss->dev, "gcc_q6_tsctr_1to2_clk"); ++ if (IS_ERR(wcss->gcc_q6_tsctr_1to2_clk)) { ++ ret = PTR_ERR(wcss->gcc_q6_tsctr_1to2_clk); ++ if (ret != -EPROBE_DEFER) ++ dev_err(wcss->dev, "Failed to get q6_tsctr_1to2 clock\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ + static int ipq_init_clock(struct q6v5_wcss *wcss) + { + int ret; +@@ -1203,7 +1398,7 @@ static const struct wcss_data wcss_ipq80 + }; + + static const struct wcss_data wcss_ipq6018_res_init = { +- .init_clock = ipq_init_clock, ++ .init_clock = ipq6018_init_clock, + .q6_firmware_name = "IPQ6018/q6_fw.mdt", + .m3_firmware_name = "IPQ6018/m3_fw.mdt", + .crash_reason_smem = WCSS_CRASH_REASON, diff --git a/target/linux/qualcommax/patches-6.6/1007-Simplify-ipq6018-rproc-Add-non-secure-Q6-bringup-seq.patch b/target/linux/qualcommax/patches-6.6/1007-Simplify-ipq6018-rproc-Add-non-secure-Q6-bringup-seq.patch new file mode 100644 index 0000000000000..33f721ad9cdcd --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/1007-Simplify-ipq6018-rproc-Add-non-secure-Q6-bringup-seq.patch @@ -0,0 +1,55 @@ +From 737b22c05f9e994ce0ac050b987f85223d04b99f Mon Sep 17 00:00:00 2001 +From: Alexandru Gagniuc +Date: Fri, 2 Sep 2022 18:31:11 -0500 +Subject: [PATCH 1007/1009] Simplify "ipq6018: rproc: Add non secure Q6 bringup + sequence" + +--- + drivers/remoteproc/qcom_q6v5_wcss.c | 25 +++++++++---------------- + 1 file changed, 9 insertions(+), 16 deletions(-) + +--- a/drivers/remoteproc/qcom_q6v5_wcss.c ++++ b/drivers/remoteproc/qcom_q6v5_wcss.c +@@ -633,18 +633,13 @@ static void q6v5_wcss_halt_axi_port(stru + unsigned long timeout; + unsigned int val; + int ret; +- const struct wcss_data *desc = device_get_match_data(wcss->dev); + +- if (desc != &wcss_ipq6018_res_init) { +- /* Check if we're already idle */ +- ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); +- if (!ret && val) +- return; +- } ++ /* Check if we're already idle */ ++ ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); ++ if (!ret && val) ++ return; + + /* Assert halt request */ +- regmap_read(halt_map, offset + AXI_HALTREQ_REG, &val); +- val |= BIT(0); + regmap_write(halt_map, offset + AXI_HALTREQ_REG, 1); + + /* Wait for halt */ +@@ -657,14 +652,12 @@ static void q6v5_wcss_halt_axi_port(stru + msleep(1); + } + +- if (desc != &wcss_ipq6018_res_init) { +- ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); +- if (ret || !val) +- dev_err(wcss->dev, "port failed halt\n"); ++ ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); ++ if (ret || !val) ++ dev_err(wcss->dev, "port failed halt\n"); + +- /* Clear halt request (port will remain halted until reset) */ +- regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0); +- } ++ /* Clear halt request (port will remain halted until reset) */ ++ regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0); + } + + static int q6v5_qcs404_wcss_shutdown(struct q6v5_wcss *wcss) diff --git a/target/linux/qualcommax/patches-6.6/1008-pwm-driver-for-qualcomm-ipq6018-pwm-block.patch b/target/linux/qualcommax/patches-6.6/1008-pwm-driver-for-qualcomm-ipq6018-pwm-block.patch new file mode 100644 index 0000000000000..f9a1afc6b021f --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/1008-pwm-driver-for-qualcomm-ipq6018-pwm-block.patch @@ -0,0 +1,601 @@ +From patchwork Thu Oct 5 16:05:47 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: Devi Priya +X-Patchwork-Id: 13410404 +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id D89C1E92716 + for ; + Thu, 5 Oct 2023 16:21:19 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S242346AbjJEQUu (ORCPT + ); + Thu, 5 Oct 2023 12:20:50 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34274 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S242441AbjJEQR7 (ORCPT + ); + Thu, 5 Oct 2023 12:17:59 -0400 +Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com + [205.220.168.131]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 654563F020; + Thu, 5 Oct 2023 09:06:56 -0700 (PDT) +Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) + by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id + 395Aarqd017488; + Thu, 5 Oct 2023 16:06:23 GMT +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; + h=from : to : cc : + subject : date : message-id : in-reply-to : references : mime-version : + content-type : content-transfer-encoding; s=qcppdkim1; + bh=pL305QZpgz9DE4v+JRgsjWEqf1lM32BSKRkIofAZtYI=; + b=N/VkHpLPyHQX0FtgqwJTY18MM5NIRAxm/+ejcJgF+GzogJXQJVrX/JAaY+GrGMI/jBWB + fXAGI3rifkl9eKUkW2WiW2CM3NLpeKa1XcRfGYC3FvWNeVEKpAdNUnneWq5jII/7rjwr + LOEF9iGjSkqgE38uQGz0bcm+TCePCLBym1xS29C8u1B7Xx0M74w+Du98muz8yAqjQbLM + xbUkhQ5rGl34cLkYMUaT8Zuu4Je14xfsUL+dVCk2/TppUvaqZz3mzOdGiwKGz9AWdnJ2 + 1+/sxswdw/5WhuALaDoCncbTHD0BtxYj3SYmNtE0+NHQ4IJ6rpa04qfytuU3+2V8h0xw FQ== +Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com + [129.46.96.20]) + by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3th8e1u8ty-1 + (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 + verify=NOT); + Thu, 05 Oct 2023 16:06:22 +0000 +Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com + [10.47.209.196]) + by NALASPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id + 395G6Lmf025392 + (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 + verify=NOT); + Thu, 5 Oct 2023 16:06:21 GMT +Received: from hu-devipriy-blr.qualcomm.com (10.80.80.8) by + nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server + (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id + 15.2.1118.36; Thu, 5 Oct 2023 09:06:16 -0700 +From: Devi Priya +To: , , + , , , + , , + , , + , , + , , + , +CC: , , + +Subject: [PATCH V15 1/4] pwm: driver for qualcomm ipq6018 pwm block +Date: Thu, 5 Oct 2023 21:35:47 +0530 +Message-ID: <20231005160550.2423075-2-quic_devipriy@quicinc.com> +X-Mailer: git-send-email 2.34.1 +In-Reply-To: <20231005160550.2423075-1-quic_devipriy@quicinc.com> +References: <20231005160550.2423075-1-quic_devipriy@quicinc.com> +MIME-Version: 1.0 +X-Originating-IP: [10.80.80.8] +X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To + nalasex01a.na.qualcomm.com (10.47.209.196) +X-QCInternal: smtphost +X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 + signatures=585085 +X-Proofpoint-GUID: dUK910BXNf0cPwSxJTAoChM7COrWyzeE +X-Proofpoint-ORIG-GUID: dUK910BXNf0cPwSxJTAoChM7COrWyzeE +X-Proofpoint-Virus-Version: vendor=baseguard + engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 + definitions=2023-10-05_11,2023-10-05_01,2023-05-22_02 +X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 + phishscore=0 suspectscore=0 + adultscore=0 priorityscore=1501 mlxscore=0 lowpriorityscore=0 spamscore=0 + bulkscore=0 mlxlogscore=999 malwarescore=0 impostorscore=0 clxscore=1015 + classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2309180000 + definitions=main-2310050126 +Precedence: bulk +List-ID: +X-Mailing-List: linux-arm-msm@vger.kernel.org + +Driver for the PWM block in Qualcomm IPQ6018 line of SoCs. Based on +driver from downstream Codeaurora kernel tree. Removed support for older +(V1) variants because I have no access to that hardware. + +Tested on IPQ6010 based hardware. + +Co-developed-by: Baruch Siach +Signed-off-by: Baruch Siach +Signed-off-by: Devi Priya +--- +V15: + No change + +V14: + No change + +V13: + No change + +V12: + + Fix the below clang warning for overflow check reported by kernel test robot + drivers/pwm/pwm-ipq.c:122:11: warning: result of comparison of constant 16000000000 + with expression of type 'unsigned long' is always false [-Wtautological-constant-out-of-range-compare] +>> if (rate > 16ULL * GIGA) + +v11: + +Address comment from Uwe Kleine-König: + + Drop redundant registers field comments + + Fix period limit check in .apply + + Clarify the comment explaining skip of pre_div > pwm_div values + + Add explicit check for clock rate within limit + + Add comment explaining the selection of initial pre_div + + Use pwm_div division with remainder instead of separate diff calculation + + Round up duty_cycle calculation in .get_state + +v10: + + Restore round up in pwm_div calculation; otherwise diff is always <= + 0, so only bingo match works + + Don't overwrite min_diff on every loop iteration + +v9: + +Address comment from Uwe Kleine-König: + + Use period_ns*rate in dividers calculation for better accuracy + + Round down pre_div and pwm_div + + Add a comment explaining why pwm_div can't underflow + + Add a comment explaining why pre_div > pwm_div end the search loop + + Drop 'CFG_' from register macros + + Rename to_ipq_pwm_chip() to ipq_pwm_from_chip() + + Change bare 'unsigned' to 'unsigned int' + + Clarify the comment on separate REG1 write for enable/disable + Round up the period value in .get_state + + Use direct readl/writel so no need to check for regmap errors + +v7: + + Change 'offset' to 'reg' for the tcsr offset (Rob) + + Drop clock name; there is only one clock (Bjorn) + + Simplify probe failure code path (Bjorn) + +v6: + +Address Uwe Kleine-König review comments: + + Drop IPQ_PWM_MAX_DEVICES + + Rely on assigned-clock-rates; drop IPQ_PWM_CLK_SRC_FREQ + + Simplify register offset calculation + + Calculate duty cycle more precisely + + Refuse to set inverted polarity + + Drop redundant IPQ_PWM_REG1_ENABLE bit clear + + Remove x1000 factor in pwm_div calculation, use rate directly, and round up + + Choose initial pre_div such that pwm_div < IPQ_PWM_MAX_DIV + + Ensure pre_div <= pwm_div + + Rename close_ to best_ + + Explain in comment why effective_div doesn't overflow + + Limit pwm_div to IPQ_PWM_MAX_DIV - 1 to allow 100% duty cycle + + Disable clock only after pwmchip_remove() + + const pwm_ops + +Other changes: + + Add missing linux/bitfield.h header include (kernel test robot) + + Adjust code for PWM device node under TCSR (Rob Herring) + +v5: + + Use &tcsr_q6 syscon to access registers (Bjorn Andersson) + + Address Uwe Kleine-König review comments: + + Implement .get_state() + + Add IPQ_PWM_ prefix to local macros + + Use GENMASK/BIT/FIELD_PREP for register fields access + + Make type of config_div_and_duty() parameters consistent + + Derive IPQ_PWM_MIN_PERIOD_NS from IPQ_PWM_CLK_SRC_FREQ + + Integrate enable/disable into config_div_and_duty() to save register read, + and reduce frequency glitch on update + + Use min() instead of min_t() + + Fix comment format + + Use dev_err_probe() to indicate probe step failure + + Add missing clk_disable_unprepare() in .remove + + Don't set .owner + +v4: + + Use div64_u64() to fix link for 32-bit targets ((kernel test robot + , Uwe Kleine-König) + +v3: + + s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring) + + Fix integer overflow on 32-bit targets (kernel test robot ) + +v2: + +Address Uwe Kleine-König review comments: + + Fix period calculation when out of range + + Don't set period larger than requested + + Remove PWM disable on configuration change + + Implement .apply instead of non-atomic .config/.enable/.disable + + Don't modify PWM on .request/.free + + Check pwm_div underflow + + Fix various code and comment formatting issues + +Other changes: + + Use u64 divisor safe division + + Remove now empty .request/.free + + drivers/pwm/Kconfig | 12 ++ + drivers/pwm/Makefile | 1 + + drivers/pwm/pwm-ipq.c | 282 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 295 insertions(+) + create mode 100644 drivers/pwm/pwm-ipq.c + +--- a/drivers/pwm/Kconfig ++++ b/drivers/pwm/Kconfig +@@ -282,6 +282,18 @@ config PWM_INTEL_LGM + To compile this driver as a module, choose M here: the module + will be called pwm-intel-lgm. + ++config PWM_IPQ ++ tristate "IPQ PWM support" ++ depends on ARCH_QCOM || COMPILE_TEST ++ depends on HAVE_CLK && HAS_IOMEM ++ help ++ Generic PWM framework driver for IPQ PWM block which supports ++ 4 pwm channels. Each of the these channels can be configured ++ independent of each other. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called pwm-ipq. ++ + config PWM_IQS620A + tristate "Azoteq IQS620A PWM support" + depends on MFD_IQS62X || COMPILE_TEST +--- a/drivers/pwm/Makefile ++++ b/drivers/pwm/Makefile +@@ -24,6 +24,7 @@ obj-$(CONFIG_PWM_IMX1) += pwm-imx1.o + obj-$(CONFIG_PWM_IMX27) += pwm-imx27.o + obj-$(CONFIG_PWM_IMX_TPM) += pwm-imx-tpm.o + obj-$(CONFIG_PWM_INTEL_LGM) += pwm-intel-lgm.o ++obj-$(CONFIG_PWM_IPQ) += pwm-ipq.o + obj-$(CONFIG_PWM_IQS620A) += pwm-iqs620a.o + obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o + obj-$(CONFIG_PWM_KEEMBAY) += pwm-keembay.o +--- /dev/null ++++ b/drivers/pwm/pwm-ipq.c +@@ -0,0 +1,282 @@ ++// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 ++/* ++ * Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* The frequency range supported is 1 Hz to clock rate */ ++#define IPQ_PWM_MAX_PERIOD_NS ((u64)NSEC_PER_SEC) ++ ++/* ++ * The max value specified for each field is based on the number of bits ++ * in the pwm control register for that field ++ */ ++#define IPQ_PWM_MAX_DIV 0xFFFF ++ ++/* ++ * Two 32-bit registers for each PWM: REG0, and REG1. ++ * Base offset for PWM #i is at 8 * #i. ++ */ ++#define IPQ_PWM_REG0 0 ++#define IPQ_PWM_REG0_PWM_DIV GENMASK(15, 0) ++#define IPQ_PWM_REG0_HI_DURATION GENMASK(31, 16) ++ ++#define IPQ_PWM_REG1 4 ++#define IPQ_PWM_REG1_PRE_DIV GENMASK(15, 0) ++/* ++ * Enable bit is set to enable output toggling in pwm device. ++ * Update bit is set to reflect the changed divider and high duration ++ * values in register. ++ */ ++#define IPQ_PWM_REG1_UPDATE BIT(30) ++#define IPQ_PWM_REG1_ENABLE BIT(31) ++ ++struct ipq_pwm_chip { ++ struct pwm_chip chip; ++ struct clk *clk; ++ void __iomem *mem; ++}; ++ ++static struct ipq_pwm_chip *ipq_pwm_from_chip(struct pwm_chip *chip) ++{ ++ return container_of(chip, struct ipq_pwm_chip, chip); ++} ++ ++static unsigned int ipq_pwm_reg_read(struct pwm_device *pwm, unsigned int reg) ++{ ++ struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip); ++ unsigned int off = 8 * pwm->hwpwm + reg; ++ ++ return readl(ipq_chip->mem + off); ++} ++ ++static void ipq_pwm_reg_write(struct pwm_device *pwm, unsigned int reg, ++ unsigned int val) ++{ ++ struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip); ++ unsigned int off = 8 * pwm->hwpwm + reg; ++ ++ writel(val, ipq_chip->mem + off); ++} ++ ++static void config_div_and_duty(struct pwm_device *pwm, unsigned int pre_div, ++ unsigned int pwm_div, unsigned long rate, u64 duty_ns, ++ bool enable) ++{ ++ unsigned long hi_dur; ++ unsigned long val = 0; ++ ++ /* ++ * high duration = pwm duty * (pwm div + 1) ++ * pwm duty = duty_ns / period_ns ++ */ ++ hi_dur = div64_u64(duty_ns * rate, (pre_div + 1) * NSEC_PER_SEC); ++ ++ val = FIELD_PREP(IPQ_PWM_REG0_HI_DURATION, hi_dur) | ++ FIELD_PREP(IPQ_PWM_REG0_PWM_DIV, pwm_div); ++ ipq_pwm_reg_write(pwm, IPQ_PWM_REG0, val); ++ ++ val = FIELD_PREP(IPQ_PWM_REG1_PRE_DIV, pre_div); ++ ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val); ++ ++ /* PWM enable toggle needs a separate write to REG1 */ ++ val |= IPQ_PWM_REG1_UPDATE; ++ if (enable) ++ val |= IPQ_PWM_REG1_ENABLE; ++ ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val); ++} ++ ++static int ipq_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ++ const struct pwm_state *state) ++{ ++ struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(chip); ++ unsigned int pre_div, pwm_div, best_pre_div, best_pwm_div; ++ unsigned long rate = clk_get_rate(ipq_chip->clk); ++ u64 period_ns, duty_ns, period_rate; ++ u64 min_diff; ++ ++ if (state->polarity != PWM_POLARITY_NORMAL) ++ return -EINVAL; ++ ++ if (state->period < DIV64_U64_ROUND_UP(NSEC_PER_SEC, rate)) ++ return -ERANGE; ++ ++ period_ns = min(state->period, IPQ_PWM_MAX_PERIOD_NS); ++ duty_ns = min(state->duty_cycle, period_ns); ++ ++ /* ++ * period_ns is 1G or less. As long as rate is less than 16 GHz, ++ * period_rate does not overflow. Make that explicit. ++ */ ++ if ((unsigned long long)rate > 16ULL * GIGA) ++ return -EINVAL; ++ period_rate = period_ns * rate; ++ best_pre_div = IPQ_PWM_MAX_DIV; ++ best_pwm_div = IPQ_PWM_MAX_DIV; ++ /* ++ * We don't need to consider pre_div values smaller than ++ * ++ * period_rate ++ * pre_div_min := ------------------------------------ ++ * NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1) ++ * ++ * because pre_div = pre_div_min results in a better ++ * approximation. ++ */ ++ pre_div = div64_u64(period_rate, ++ (u64)NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1)); ++ min_diff = period_rate; ++ ++ for (; pre_div <= IPQ_PWM_MAX_DIV; pre_div++) { ++ u64 remainder; ++ ++ pwm_div = div64_u64_rem(period_rate, ++ (u64)NSEC_PER_SEC * (pre_div + 1), &remainder); ++ /* pwm_div is unsigned; the check below catches underflow */ ++ pwm_div--; ++ ++ /* ++ * Swapping values for pre_div and pwm_div produces the same ++ * period length. So we can skip all settings with pre_div > ++ * pwm_div which results in bigger constraints for selecting ++ * the duty_cycle than with the two values swapped. ++ */ ++ if (pre_div > pwm_div) ++ break; ++ ++ /* ++ * Make sure we can do 100% duty cycle where ++ * hi_dur == pwm_div + 1 ++ */ ++ if (pwm_div > IPQ_PWM_MAX_DIV - 1) ++ continue; ++ ++ if (remainder < min_diff) { ++ best_pre_div = pre_div; ++ best_pwm_div = pwm_div; ++ min_diff = remainder; ++ ++ if (min_diff == 0) /* bingo */ ++ break; ++ } ++ } ++ ++ /* config divider values for the closest possible frequency */ ++ config_div_and_duty(pwm, best_pre_div, best_pwm_div, ++ rate, duty_ns, state->enabled); ++ ++ return 0; ++} ++ ++static int ipq_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, ++ struct pwm_state *state) ++{ ++ struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(chip); ++ unsigned long rate = clk_get_rate(ipq_chip->clk); ++ unsigned int pre_div, pwm_div, hi_dur; ++ u64 effective_div, hi_div; ++ u32 reg0, reg1; ++ ++ reg0 = ipq_pwm_reg_read(pwm, IPQ_PWM_REG0); ++ reg1 = ipq_pwm_reg_read(pwm, IPQ_PWM_REG1); ++ ++ state->polarity = PWM_POLARITY_NORMAL; ++ state->enabled = reg1 & IPQ_PWM_REG1_ENABLE; ++ ++ pwm_div = FIELD_GET(IPQ_PWM_REG0_PWM_DIV, reg0); ++ hi_dur = FIELD_GET(IPQ_PWM_REG0_HI_DURATION, reg0); ++ pre_div = FIELD_GET(IPQ_PWM_REG1_PRE_DIV, reg1); ++ ++ /* No overflow here, both pre_div and pwm_div <= 0xffff */ ++ effective_div = (u64)(pre_div + 1) * (pwm_div + 1); ++ state->period = DIV64_U64_ROUND_UP(effective_div * NSEC_PER_SEC, rate); ++ ++ hi_div = hi_dur * (pre_div + 1); ++ state->duty_cycle = DIV64_U64_ROUND_UP(hi_div * NSEC_PER_SEC, rate); ++ ++ return 0; ++} ++ ++static const struct pwm_ops ipq_pwm_ops = { ++ .apply = ipq_pwm_apply, ++ .get_state = ipq_pwm_get_state, ++ .owner = THIS_MODULE, ++}; ++ ++static int ipq_pwm_probe(struct platform_device *pdev) ++{ ++ struct ipq_pwm_chip *pwm; ++ struct device *dev = &pdev->dev; ++ int ret; ++ ++ pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL); ++ if (!pwm) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, pwm); ++ ++ pwm->mem = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(pwm->mem)) ++ return dev_err_probe(dev, PTR_ERR(pwm->mem), ++ "regs map failed"); ++ ++ pwm->clk = devm_clk_get(dev, NULL); ++ if (IS_ERR(pwm->clk)) ++ return dev_err_probe(dev, PTR_ERR(pwm->clk), ++ "failed to get clock"); ++ ++ ret = clk_prepare_enable(pwm->clk); ++ if (ret) ++ return dev_err_probe(dev, ret, "clock enable failed"); ++ ++ pwm->chip.dev = dev; ++ pwm->chip.ops = &ipq_pwm_ops; ++ pwm->chip.npwm = 4; ++ ++ ret = pwmchip_add(&pwm->chip); ++ if (ret < 0) { ++ dev_err_probe(dev, ret, "pwmchip_add() failed\n"); ++ clk_disable_unprepare(pwm->clk); ++ } ++ ++ return ret; ++} ++ ++static int ipq_pwm_remove(struct platform_device *pdev) ++{ ++ struct ipq_pwm_chip *pwm = platform_get_drvdata(pdev); ++ ++ pwmchip_remove(&pwm->chip); ++ clk_disable_unprepare(pwm->clk); ++ ++ return 0; ++} ++ ++static const struct of_device_id pwm_ipq_dt_match[] = { ++ { .compatible = "qcom,ipq6018-pwm", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, pwm_ipq_dt_match); ++ ++static struct platform_driver ipq_pwm_driver = { ++ .driver = { ++ .name = "ipq-pwm", ++ .of_match_table = pwm_ipq_dt_match, ++ }, ++ .probe = ipq_pwm_probe, ++ .remove = ipq_pwm_remove, ++}; ++ ++module_platform_driver(ipq_pwm_driver); ++ ++MODULE_LICENSE("Dual BSD/GPL"); diff --git a/target/linux/qualcommax/patches-6.6/1009-arm64-dts-qcom-ipq6018-add-pwm-node.patch b/target/linux/qualcommax/patches-6.6/1009-arm64-dts-qcom-ipq6018-add-pwm-node.patch new file mode 100644 index 0000000000000..a54aeedb183c8 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/1009-arm64-dts-qcom-ipq6018-add-pwm-node.patch @@ -0,0 +1,187 @@ +From patchwork Thu Oct 5 16:05:50 2023 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +X-Patchwork-Submitter: Devi Priya +X-Patchwork-Id: 13410402 +Return-Path: +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 0A952E71D4F + for ; + Thu, 5 Oct 2023 16:21:13 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S242309AbjJEQUs (ORCPT + ); + Thu, 5 Oct 2023 12:20:48 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36106 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S242451AbjJEQSB (ORCPT + ); + Thu, 5 Oct 2023 12:18:01 -0400 +Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com + [205.220.180.131]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C6E8D3F025; + Thu, 5 Oct 2023 09:06:56 -0700 (PDT) +Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) + by mx0a-0031df01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id + 395CsRur015464; + Thu, 5 Oct 2023 16:06:41 GMT +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; + h=from : to : cc : + subject : date : message-id : in-reply-to : references : mime-version : + content-type : content-transfer-encoding; s=qcppdkim1; + bh=NSi6brrY0QDAZ3HzHxPaf2hgz27vKeKX8LZRRHNWQWc=; + b=bhnUe3rjnlfJlfGglxvqihGmTNQCt2GnP9fbZBkIsYd0LKp5VGtAlA0IYUcwsiTLb7RK + zTJfR/Llub7KabA70G7qxopCKO0GgBFRq3Xhug1Nnrpr08qcHCrAOSuS16i8viiv5tE/ + Lrn3/Dj59DKIWaBWzrTmI5pK0eLkK0nAPYsTjv03eE8JFtw3M0lHrMQdjuwtpNE7ivjl + CCkahl9YDirevdy+EdeBg17dBw4R3t/qo+3tDzom1COe5knM5DIJI79fxqY1ueFFOM6D + D5mVEsufaOcEQFeLv3y7PtEsPTmWdyN2PCiU8GpFFz6KH8iJLyhzHc6o5pItDDupV1EG uQ== +Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com + [129.46.96.20]) + by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3thn059cyw-1 + (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 + verify=NOT); + Thu, 05 Oct 2023 16:06:41 +0000 +Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com + [10.47.209.196]) + by NALASPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id + 395G6dfE025540 + (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 + verify=NOT); + Thu, 5 Oct 2023 16:06:40 GMT +Received: from hu-devipriy-blr.qualcomm.com (10.80.80.8) by + nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server + (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id + 15.2.1118.36; Thu, 5 Oct 2023 09:06:34 -0700 +From: Devi Priya +To: , , + , , , + , , + , , + , , + , , + , +CC: , , + +Subject: [PATCH V15 4/4] arm64: dts: qcom: ipq6018: add pwm node +Date: Thu, 5 Oct 2023 21:35:50 +0530 +Message-ID: <20231005160550.2423075-5-quic_devipriy@quicinc.com> +X-Mailer: git-send-email 2.34.1 +In-Reply-To: <20231005160550.2423075-1-quic_devipriy@quicinc.com> +References: <20231005160550.2423075-1-quic_devipriy@quicinc.com> +MIME-Version: 1.0 +X-Originating-IP: [10.80.80.8] +X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To + nalasex01a.na.qualcomm.com (10.47.209.196) +X-QCInternal: smtphost +X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 + signatures=585085 +X-Proofpoint-ORIG-GUID: pbCgYn8v-0OpdxaoHvIbH76mglvWkJsO +X-Proofpoint-GUID: pbCgYn8v-0OpdxaoHvIbH76mglvWkJsO +X-Proofpoint-Virus-Version: vendor=baseguard + engine=ICAP:2.0.267,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26 + definitions=2023-10-05_11,2023-10-05_01,2023-05-22_02 +X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 + adultscore=0 suspectscore=0 + impostorscore=0 bulkscore=0 spamscore=0 mlxlogscore=999 priorityscore=1501 + mlxscore=0 malwarescore=0 lowpriorityscore=0 phishscore=0 clxscore=1015 + classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2309180000 + definitions=main-2310050125 +Precedence: bulk +List-ID: +X-Mailing-List: linux-arm-msm@vger.kernel.org + +Describe the PWM block on IPQ6018. + +The PWM is in the TCSR area. Make &tcsr "simple-mfd" compatible, and add +&pwm as child of &tcsr. + +Add also ipq6018 specific compatible string. + +Reviewed-by: Krzysztof Kozlowski +Co-developed-by: Baruch Siach +Signed-off-by: Baruch Siach +Signed-off-by: Devi Priya +--- +v15: + + Fixed the indentation of pwm node + +v14: + + Moved ranges just after reg as suggested by Krzysztof + + Picked up the R-b tag + +v13: + + No change + +v12: + + No change + +v11: + + No change + +v10: + + No change + +v9: + + Add 'ranges' property (Rob) + +v8: + + Add size cell to 'reg' (Rob) + +v7: + + Use 'reg' instead of 'offset' (Rob) + + Add qcom,tcsr-ipq6018 (Rob) + + Drop clock-names (Bjorn) + +v6: + + Make the PWM node child of TCSR (Rob Herring) + + Add assigned-clocks/assigned-clock-rates (Uwe Kleine-König) + +v5: Use qcom,pwm-regs for TCSR phandle instead of direct regs + +v3: s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring) + + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -456,8 +456,21 @@ + }; + + tcsr: syscon@1937000 { +- compatible = "qcom,tcsr-ipq6018", "syscon"; ++ compatible = "qcom,tcsr-ipq6018", "syscon", "simple-mfd"; + reg = <0x0 0x01937000 0x0 0x21000>; ++ ranges = <0x0 0x0 0x01937000 0x21000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ pwm: pwm@a010 { ++ compatible = "qcom,ipq6018-pwm"; ++ reg = <0xa010 0x20>; ++ clocks = <&gcc GCC_ADSS_PWM_CLK>; ++ assigned-clocks = <&gcc GCC_ADSS_PWM_CLK>; ++ assigned-clock-rates = <100000000>; ++ #pwm-cells = <2>; ++ status = "disabled"; ++ }; + }; + + usb2: usb@70f8800 { diff --git a/target/linux/qualcommax/patches-6.6/1010-clk-qcom-gcc-ipq6018-rework-nss_port5-clock-to-mul.patch b/target/linux/qualcommax/patches-6.6/1010-clk-qcom-gcc-ipq6018-rework-nss_port5-clock-to-mul.patch new file mode 100644 index 0000000000000..5c1c03e349480 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/1010-clk-qcom-gcc-ipq6018-rework-nss_port5-clock-to-mul.patch @@ -0,0 +1,66 @@ +From 76b1d5178910e6714f14c1f6c17390277d227afd Mon Sep 17 00:00:00 2001 +From: JiaY-shi +Date: Thu, 17 Aug 2023 20:46:54 +0800 +Subject: [PATCH] clk: qcom: gcc-ipq6018: rework nss_port5 clock to multiple + conf + +--- + drivers/clk/qcom/gcc-ipq6018.c | 34 ++++++++++++++++++++++++++-------- + 1 file changed, 26 insertions(+), 8 deletions(-) + +--- a/drivers/clk/qcom/gcc-ipq6018.c ++++ b/drivers/clk/qcom/gcc-ipq6018.c +@@ -537,13 +537,22 @@ static struct clk_rcg2 apss_ahb_clk_src + }, + }; + ++ ++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(24000000, 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), + { } +@@ -584,13 +593,22 @@ static struct clk_rcg2 nss_port5_rx_clk_ + }, + }; + ++ ++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(24000000, 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), + { } diff --git a/target/linux/qualcommax/patches-6.6/1011-arm64-dts-qcom-ipq6018-assign-some-clock-to-wifi.patch b/target/linux/qualcommax/patches-6.6/1011-arm64-dts-qcom-ipq6018-assign-some-clock-to-wifi.patch new file mode 100644 index 0000000000000..fd7216c68c2ad --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/1011-arm64-dts-qcom-ipq6018-assign-some-clock-to-wifi.patch @@ -0,0 +1,40 @@ +From 71f30e25d21ae4981ecef6653a4ba7dfeb80db7b Mon Sep 17 00:00:00 2001 +From: JiaY-shi +Date: Tue, 23 Jan 2024 11:04:57 +0200 +Subject: [PATCH] arm64: dts: qcom: ipq6018: assign some clock to wifi remoteproc + +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 15 ++++++++------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -983,8 +983,26 @@ + "wcss_reset", + "wcss_q6_reset"; + +- clocks = <&gcc GCC_PRNG_AHB_CLK>, <&gcc GCC_QDSS_AT_CLK>; +- clock-names = "prng", "qdss" ; ++ clocks = <&gcc GCC_PRNG_AHB_CLK>, ++ <&gcc GCC_QDSS_AT_CLK>, ++ <&gcc GCC_SYS_NOC_WCSS_AHB_CLK>, ++ <&gcc GCC_Q6SS_ATBM_CLK>, ++ <&gcc GCC_Q6SS_PCLKDBG_CLK>, ++ <&gcc GCC_Q6_TSCTR_1TO2_CLK>; ++ clock-names = "prng", ++ "qdss", ++ "gcc_sys_noc_wcss_ahb_clk", ++ "gcc_q6ss_atbm_clk", ++ "gcc_q6ss_pclkdbg_clk", ++ "gcc_q6_tsctr_1to2_clk"; ++ assigned-clocks = <&gcc GCC_SYS_NOC_WCSS_AHB_CLK>, ++ <&gcc GCC_Q6SS_PCLKDBG_CLK>, ++ <&gcc GCC_Q6_TSCTR_1TO2_CLK>, ++ <&gcc GCC_Q6SS_ATBM_CLK>; ++ assigned-clock-rates = <133333333>, ++ <600000000>, ++ <600000000>, ++ <240000000>; + + qcom,halt-regs = <&tcsr 0x18000 0x1b000 0xe000>; + diff --git a/target/linux/qualcommax/patches-6.6/1012-arm64-dts-qcom-ipq6018-Add-QUP5-SPI-node.patch b/target/linux/qualcommax/patches-6.6/1012-arm64-dts-qcom-ipq6018-Add-QUP5-SPI-node.patch new file mode 100644 index 0000000000000..1398c046364b1 --- /dev/null +++ b/target/linux/qualcommax/patches-6.6/1012-arm64-dts-qcom-ipq6018-Add-QUP5-SPI-node.patch @@ -0,0 +1,36 @@ +From dc5423c92edffac4d3b59aa5fd0dcbdfdcba0bf3 Mon Sep 17 00:00:00 2001 +From: Chukun Pan +Date: Sat, 11 Nov 2023 15:50:03 +0800 +Subject: [PATCH] arm64: dts: qcom: ipq6018: Add QUP5 SPI node + +Add node to support the QUP5 SPI controller inside of IPQ6018. +Some routers use this bus to connect SPI TPM chips. + +Signed-off-by: Chukun Pan +--- + arch/arm64/boot/dts/qcom/ipq6018.dtsi | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi +@@ -635,6 +635,20 @@ + status = "disabled"; + }; + ++ blsp1_spi5: spi@78b9000 { ++ compatible = "qcom,spi-qup-v2.2.1"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ reg = <0x0 0x078b9000 0x0 0x600>; ++ interrupts = ; ++ clocks = <&gcc GCC_BLSP1_QUP5_SPI_APPS_CLK>, ++ <&gcc GCC_BLSP1_AHB_CLK>; ++ clock-names = "core", "iface"; ++ dmas = <&blsp_dma 20>, <&blsp_dma 21>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ + blsp1_i2c2: i2c@78b6000 { + compatible = "qcom,i2c-qup-v2.2.1"; + #address-cells = <1>;