From 9c17b85ad73c49be993c161cbcfcb98c70d3010b Mon Sep 17 00:00:00 2001 From: Naina Mehta Date: Thu, 26 Oct 2023 17:58:55 +0530 Subject: [PATCH 01/46] soc: qcom: Add check if part is more than firmware supported range Add check to compare part with the number of parts supported by firmware and return error if it exceeds the range. Change-Id: I047dc392ac50a6124ea476eaf95385e6739795ae Signed-off-by: Naina Mehta --- drivers/soc/qcom/socinfo.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index de69d9bb2c97..5def74231498 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -371,10 +371,14 @@ struct smem_image_version { int num_parts = 0; \ int str_pos = 0, i = 0, ret = 0; \ num_parts = socinfo_get_part_count(part_enum); \ + if (num_parts <= 0) \ + return -EINVAL; \ part_info = kmalloc_array(num_parts, sizeof(*part_info), GFP_KERNEL); \ ret = socinfo_get_subpart_info(part_enum, part_info, num_parts); \ - if (ret < 0) \ + if (ret < 0) { \ + kfree(part_info); \ return -EINVAL; \ + } \ for (i = 0; i < num_parts; i++) { \ str_pos += scnprintf(buf+str_pos, PAGE_SIZE-str_pos, "0x%x", \ part_info[i]); \ @@ -886,8 +890,9 @@ bool socinfo_get_part_info(enum subset_part_type part) { uint32_t partinfo; + uint32_t num_parts = socinfo_get_num_subset_parts(); - if (part >= NUM_PARTS_MAX) { + if ((part <= PART_UNKNOWN) || (part >= NUM_PARTS_MAX) || (part >= num_parts)) { pr_err("Bad part number\n"); return false; } @@ -925,10 +930,11 @@ int socinfo_get_part_count(enum subset_part_type part) { int part_count = 1; + uint32_t num_parts = socinfo_get_num_subset_parts(); /* TODO: part_count to be read from SMEM after firmware adds support */ - if ((part <= PART_UNKNOWN) || (part >= NUM_PARTS_MAX)) { + if ((part <= PART_UNKNOWN) || (part >= NUM_PARTS_MAX) || (part >= num_parts)) { pr_err("Bad part number\n"); return -EINVAL; } From b6540fad534b1620bc7c0ca6e796b1da52fed1ca Mon Sep 17 00:00:00 2001 From: Shivangi Yadav Date: Mon, 16 Oct 2023 22:26:44 +0530 Subject: [PATCH 02/46] msm: ep_pcie: Avoid dumping registers for linkdown after PERST assert Dumping of registers after PERST assert leads to NOC error as the regulators and clocks are turned off. Adding PERST assert check to avoid dumping of registers after PERST assert in link down case and removing suspending flag which is not used in ep_pcie driver. Change-Id: I6f720b41864d4e041c29a71c24f9c6653f997c2c Signed-off-by: Sai Chaitanya Kaveti Signed-off-by: Shivangi Yadav --- drivers/platform/msm/ep_pcie/ep_pcie_com.h | 1 - drivers/platform/msm/ep_pcie/ep_pcie_core.c | 7 +++---- drivers/platform/msm/ep_pcie/ep_pcie_dbg.c | 2 -- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_com.h b/drivers/platform/msm/ep_pcie/ep_pcie_com.h index 61eab2c63a43..9f26d563ce78 100644 --- a/drivers/platform/msm/ep_pcie/ep_pcie_com.h +++ b/drivers/platform/msm/ep_pcie/ep_pcie_com.h @@ -478,7 +478,6 @@ struct ep_pcie_dev_t { bool enumerated; enum ep_pcie_link_status link_status; bool power_on; - bool suspending; bool l23_ready; bool l1ss_enabled; bool no_notify; diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_core.c b/drivers/platform/msm/ep_pcie/ep_pcie_core.c index f6be0184a74d..7273f09012ee 100644 --- a/drivers/platform/msm/ep_pcie/ep_pcie_core.c +++ b/drivers/platform/msm/ep_pcie/ep_pcie_core.c @@ -2434,7 +2434,6 @@ checkbme: dev->link_status = EP_PCIE_LINK_UP; } - dev->suspending = false; goto out; link_fail_pipe_clk_deinit: @@ -2631,13 +2630,13 @@ static irqreturn_t ep_pcie_handle_linkdown_irq(int irq, void *data) EP_PCIE_DBG(dev, "PCIe V%d:Linkdown IRQ happened when the link is disabled\n", dev->rev); - } else if (dev->suspending) { + } else if (!atomic_read(&dev->perst_deast)) { EP_PCIE_DBG(dev, - "PCIe V%d:Linkdown IRQ happened when the link is suspending\n", + "PCIe V%d:Linkdown IRQ happened when PERST asserted\n", dev->rev); } else { dev->link_status = EP_PCIE_LINK_DISABLED; - EP_PCIE_ERR(dev, "PCIe V%d:PCIe link is down for %ld times\n", + EP_PCIE_DBG(dev, "PCIe V%d:PCIe link is down for %ld times\n", dev->rev, dev->linkdown_counter); ep_pcie_reg_dump(dev, BIT(EP_PCIE_RES_PHY) | BIT(EP_PCIE_RES_PARF), true); diff --git a/drivers/platform/msm/ep_pcie/ep_pcie_dbg.c b/drivers/platform/msm/ep_pcie/ep_pcie_dbg.c index f490049b6c70..8b2998188189 100644 --- a/drivers/platform/msm/ep_pcie/ep_pcie_dbg.c +++ b/drivers/platform/msm/ep_pcie/ep_pcie_dbg.c @@ -309,8 +309,6 @@ static void ep_pcie_show_status(struct ep_pcie_dev_t *dev) EP_PCIE_DBG_FS("PCIe: link is %s\n", (dev->link_status == EP_PCIE_LINK_ENABLED) ? "enabled" : "disabled"); - EP_PCIE_DBG_FS("the link is %s suspending\n", - dev->suspending ? "" : "not"); EP_PCIE_DBG_FS("the power is %s on\n", dev->power_on ? "" : "not"); EP_PCIE_DBG_FS("linkdown_counter: %lu\n", From 2f6f8525187af158f93b74abbc82000073d2261d Mon Sep 17 00:00:00 2001 From: Sushrut Shree Trivedi Date: Tue, 5 Dec 2023 13:18:48 +0530 Subject: [PATCH 03/46] arm64: configs: vendor: Enable EP and MHI module loading Enable EP and MHI module loading. Change-Id: I56b35d0f990cc0299664871bd161025e6789e7be Signed-off-by: Sushrut Shree Trivedi --- arch/arm64/configs/vendor/kalama_le_GKI.config | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/configs/vendor/kalama_le_GKI.config b/arch/arm64/configs/vendor/kalama_le_GKI.config index 42ce44525fbe..152233281c26 100644 --- a/arch/arm64/configs/vendor/kalama_le_GKI.config +++ b/arch/arm64/configs/vendor/kalama_le_GKI.config @@ -39,6 +39,7 @@ CONFIG_CPU_IDLE_GOV_QCOM_LPM=m CONFIG_EDAC_QCOM=m # CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y +CONFIG_EP_PCIE=m # CONFIG_EXT4_KUNIT_TESTS is not set # CONFIG_FAT_KUNIT_TEST is not set CONFIG_GH_ARM64_DRV=m @@ -114,6 +115,8 @@ CONFIG_MSM_CORE_HANG_DETECT=m CONFIG_MSM_GLOBAL_SYNX=m CONFIG_MSM_GPI_DMA=m # CONFIG_MSM_GPI_DMA_DEBUG is not set +CONFIG_MSM_MHI_DEV=m +CONFIG_MSM_MHI_NET_DEV=m CONFIG_MSM_PERFORMANCE=m CONFIG_MSM_POWER_STATE=m CONFIG_MSM_QBT_HANDLER=m @@ -257,6 +260,7 @@ CONFIG_QCOM_WDT_CORE=m CONFIG_QRTR=m CONFIG_QRTR_GUNYAH=m CONFIG_QRTR_MHI=m +# CONFIG_QRTR_MHI_DEV is not set CONFIG_QRTR_SMD=m # CONFIG_QRTR_TUN is not set CONFIG_QSEECOM_PROXY=m From cf2dc5e5facd6be97c2d02bdc07ff75969127ed5 Mon Sep 17 00:00:00 2001 From: Saranya R Date: Mon, 27 Nov 2023 17:50:29 +0530 Subject: [PATCH 04/46] defconfig: Enable CONFIG_EDAC_KRYO_ARM64 support for qcs605 Enable CONFIG_EDAC_KRYO_ARM64 support for qcs605. Change-Id: I7a3765821948fdf5817eab813c76adee1e344bce Signed-off-by: Saranya R --- arch/arm64/configs/vendor/qcs605_GKI.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/vendor/qcs605_GKI.config b/arch/arm64/configs/vendor/qcs605_GKI.config index c9ccb510a164..bcd93fa30487 100644 --- a/arch/arm64/configs/vendor/qcs605_GKI.config +++ b/arch/arm64/configs/vendor/qcs605_GKI.config @@ -32,6 +32,9 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=m CONFIG_CPU_FREQ_GOV_USERSPACE=m CONFIG_CPU_IDLE_GOV_QCOM_LPM=m # CONFIG_DEBUG_PREEMPT is not set +CONFIG_EDAC_KRYO_ARM64=m +# CONFIG_EDAC_KRYO_ARM64_PANIC_ON_CE is not set +CONFIG_EDAC_KRYO_ARM64_PANIC_ON_UE=y CONFIG_EXTCON_USB_GPIO=m CONFIG_HWSPINLOCK_QCOM=m CONFIG_HW_RANDOM_MSM_LEGACY=m From 6931fe14326929168f1edde5ef3b3dc33bb660c7 Mon Sep 17 00:00:00 2001 From: Anaadi Mishra Date: Wed, 1 Nov 2023 20:54:51 +0530 Subject: [PATCH 05/46] clk: qcom: gpucc: Add support for FREQUENCY LIMITER reset for CROW Add support for the consumer to be able to set/reset the GPU_CC_FREQUENCY_LIMITER_IRQ_CLEAR register as an when required. Change-Id: I631404203558751bda442cd59684e382bb8e3120 Signed-off-by: Anaadi Mishra --- drivers/clk/qcom/gpucc-crow.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/clk/qcom/gpucc-crow.c b/drivers/clk/qcom/gpucc-crow.c index b40a3efbe2fe..9df63f9770c0 100644 --- a/drivers/clk/qcom/gpucc-crow.c +++ b/drivers/clk/qcom/gpucc-crow.c @@ -567,6 +567,7 @@ static const struct qcom_reset_map gpu_cc_crow_resets[] = { [GPUCC_GPU_CC_GX_BCR] = { 0x9058 }, [GPUCC_GPU_CC_RBCPR_BCR] = { 0x91e0 }, [GPUCC_GPU_CC_XO_BCR] = { 0x9000 }, + [GPUCC_GPU_CC_FREQUENCY_LIMITER_IRQ_CLEAR] = { 0x9538 }, }; static const struct regmap_config gpu_cc_crow_regmap_config = { @@ -605,6 +606,9 @@ static int gpu_cc_crow_probe(struct platform_device *pdev) clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); + /* Enable frequency limiter irq */ + regmap_write(regmap, 0x9534, 0x0); + /* * Keep clocks always enabled: * gpu_cc_cxo_aon_clk From ee520eb0e2ca2c58f897fe00d997ff9cc6e12e51 Mon Sep 17 00:00:00 2001 From: Ashok Kadavul Date: Wed, 15 Nov 2023 18:18:26 +0530 Subject: [PATCH 06/46] stmmac: fix crash in LPM Disable fpesel capability which is not needed and causing crash during LPM. Change-Id: I9698cb54edfe09dfc16c4c6b1b241f4dc05e655d Signed-off-by: Ashok Kadavul --- drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c index b06fdc6f92e5..49dba918dfd7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c @@ -3031,6 +3031,8 @@ static int qcom_ethqos_probe(struct platform_device *pdev) /* Read en_wol from device tree */ priv->en_wol = of_property_read_bool(np, "enable-wol"); + if (of_property_read_bool(np, "disable-frame-preem")) + priv->dma_cap.fpesel = 0; /* enable safety feature from device tree */ if (of_property_read_bool(np, "safety-feat") && priv->dma_cap.asp) From e6298624c288e8c4631d81e8aed81e8338cdeae5 Mon Sep 17 00:00:00 2001 From: Somesh Dey Date: Fri, 24 Nov 2023 14:16:40 +0530 Subject: [PATCH 07/46] i2c: i2c-msm-geni: check for gi2c->cur null pointer In geni_i2c_irq_handle_watermark, due to spurious interrupt gi2c->cur is becoming null resulting in crash. Hence added a check to prevent this scenario due to spurious interrupts. Change-Id: I522b2dbdacb48208ecddd81115c7a9a7c40da021 Signed-off-by: Visweswara Tanuku Signed-off-by: Somesh Dey Signed-off-by: Madhu Ananthula --- drivers/i2c/busses/i2c-msm-geni.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-msm-geni.c b/drivers/i2c/busses/i2c-msm-geni.c index 9eb3060011ee..0c50fc70aed0 100644 --- a/drivers/i2c/busses/i2c-msm-geni.c +++ b/drivers/i2c/busses/i2c-msm-geni.c @@ -679,6 +679,12 @@ static void geni_i2c_irq_handle_watermark(struct geni_i2c_dev *gi2c, u32 m_stat) int i, j; u32 rx_st = readl_relaxed(gi2c->base + SE_GENI_RX_FIFO_STATUS); + if (!cur) { + I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "%s: Spurious irq\n", __func__); + geni_i2c_err(gi2c, GENI_SPURIOUS_IRQ); + return; + } + if (((m_stat & M_RX_FIFO_WATERMARK_EN) || (m_stat & M_RX_FIFO_LAST_EN)) && (cur->flags & I2C_M_RD)) { u32 rxcnt = rx_st & RX_FIFO_WC_MSK; @@ -737,7 +743,7 @@ static irqreturn_t geni_i2c_irq(int irq, void *dev) "%s: m_irq_status:0x%x\n", __func__, m_stat); if (!cur) { - I2C_LOG_ERR(gi2c->ipcl, false, gi2c->dev, "Spurious irq\n"); + I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "Spurious irq\n"); geni_i2c_err(gi2c, GENI_SPURIOUS_IRQ); gi2c->cmd_done = true; is_clear_watermark = true; From a62a7972e84eb4e72630c82769007d21cd8ecdc4 Mon Sep 17 00:00:00 2001 From: Canfeng Zhuang Date: Mon, 13 Nov 2023 14:34:31 +0800 Subject: [PATCH 08/46] Arm: config: Enable necessary config for kalama lu Enable necessary config for kalama lu: | commit e215ca459e1c1 ("config: Add defconfigs to enable compile for TDK sensor"). | commit 9bfe7aa7feac5 ("config: Enable CAN functionality for RB5 gen2 device"). | commit 6da0f8f54be69 ("ARM: config: msm: Enable config for pcie to usb hub"). | commit 234c78d779ddd ("driver: can: spi: add mcp25xxfd driver"). Change-Id: I2ca35d987bf382a1f0eee9ffe9f6a4621c5f5a97 Signed-off-by: Canfeng Zhuang --- arch/arm64/configs/kalama_lu_gki.fragment | 4 ++++ arch/arm64/configs/vendor/kalama_lu_GKI.config | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/arch/arm64/configs/kalama_lu_gki.fragment b/arch/arm64/configs/kalama_lu_gki.fragment index ca040383c0bb..a6716f9d66d1 100644 --- a/arch/arm64/configs/kalama_lu_gki.fragment +++ b/arch/arm64/configs/kalama_lu_gki.fragment @@ -3,5 +3,9 @@ CONFIG_TMPFS_POSIX_ACL=y CONFIG_USB_SERIAL=y CONFIG_USB_SERIAL_CH341=y CONFIG_USB_SERIAL_CP210X=y +CONFIG_I2C_MUX=y +CONFIG_PINCTRL_SX150X=y CONFIG_GPIO_SYSFS=y CONFIG_PM_AUTOSLEEP=y +CONFIG_CAN=y +CONFIG_USB_XHCI_PCI_RENESAS=y diff --git a/arch/arm64/configs/vendor/kalama_lu_GKI.config b/arch/arm64/configs/vendor/kalama_lu_GKI.config index 68d12e751f57..d3e3f98066ad 100644 --- a/arch/arm64/configs/vendor/kalama_lu_GKI.config +++ b/arch/arm64/configs/vendor/kalama_lu_GKI.config @@ -1,3 +1,4 @@ +CONFIG_ADS7052_TDK_THERMISTOR=m CONFIG_ARCH_KAKA=y CONFIG_ARCH_KALAMA=y CONFIG_ARCH_QCOM=y @@ -7,6 +8,7 @@ CONFIG_ARM_SMMU=m CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT=y # CONFIG_ARM_SMMU_SELFTEST is not set CONFIG_BLK_DEV_NVME=m +CONFIG_CAN_MCP25XXFD=m CONFIG_CFG80211=m # CONFIG_CFG80211_CERTIFICATION_ONUS is not set # CONFIG_CFG80211_CRDA_SUPPORT is not set @@ -16,6 +18,8 @@ CONFIG_CFG80211=m CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y # CONFIG_CFG80211_WEXT is not set +CONFIG_CH101=m +CONFIG_CH101_I2C=m # CONFIG_CHARGER_QCOM_SMBB is not set CONFIG_CHR_DEV_SG=m CONFIG_COMMON_CLK_QCOM=m From 7e751b9858cde4874d7a75be3000241774f583bf Mon Sep 17 00:00:00 2001 From: Prerna Singh Date: Fri, 20 Oct 2023 15:33:08 +0530 Subject: [PATCH 09/46] clk: qcom: Add measure support for CPU clk on Trinket Add measure support for CPU clks in DEBUGCC in Trinket so that one can get the frequency at which they are running at. Change-Id: Ic199787dc6ef32415c41f721011d0e3e93e496ad Signed-off-by: Prerna Singh --- drivers/clk/qcom/debugcc-trinket.c | 59 ++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/drivers/clk/qcom/debugcc-trinket.c b/drivers/clk/qcom/debugcc-trinket.c index 1ceee64a732e..71c287c6334c 100644 --- a/drivers/clk/qcom/debugcc-trinket.c +++ b/drivers/clk/qcom/debugcc-trinket.c @@ -25,6 +25,42 @@ static struct measure_clk_data debug_mux_priv = { .xo_div4_cbcr = 0x28008, }; +static const char *const cpu_cc_debug_mux_parent_names[] = { + "pwrcl_clk", + "perfcl_clk", +}; + +static int apss_cc_debug_mux_pre_divs[] = { + 0x8, /* pwrcl_clk */ + 0x8, /* perfcl_clk */ +}; + +static int cpu_cc_debug_mux_sels[] = { + 0x0, /* pwrcl_clk */ + 0x1, /* perfcl_clk */ +}; + +static struct clk_debug_mux cpu_cc_debug_mux = { + .priv = &debug_mux_priv, + .debug_offset = 0x0, + .post_div_offset = 0x0, + .cbcr_offset = U32_MAX, + .src_sel_mask = 0x3FF, + .src_sel_shift = 8, + .post_div_mask = 0xF, + .post_div_shift = 28, + .post_div_val = 1, + .pre_div_vals = apss_cc_debug_mux_pre_divs, + .mux_sels = cpu_cc_debug_mux_sels, + .num_mux_sels = ARRAY_SIZE(cpu_cc_debug_mux_sels), + .hw.init = &(const struct clk_init_data){ + .name = "cpu_cc_debug_mux", + .ops = &clk_debug_mux_ops, + .parent_names = cpu_cc_debug_mux_parent_names, + .num_parents = ARRAY_SIZE(cpu_cc_debug_mux_parent_names), + }, +}; + static const char *const disp_cc_debug_mux_parent_names[] = { "disp_cc_mdss_ahb_clk", "disp_cc_mdss_byte0_clk", @@ -235,6 +271,7 @@ static const char *const gcc_debug_mux_parent_names[] = { "measure_only_ipa_2x_clk", "measure_only_snoc_clk", "video_cc_debug_mux", + "cpu_cc_debug_mux", }; static int gcc_debug_mux_sels[] = { @@ -389,6 +426,7 @@ static int gcc_debug_mux_sels[] = { 0xC2, /* measure_only_ipa_2x_clk */ 0x7, /* measure_only_snoc_clk */ 0x42, /* video_cc_debug_mux */ + 0xAB, /* cpu_cc_debug_mux */ }; static struct clk_debug_mux gcc_debug_mux = { @@ -520,11 +558,28 @@ static struct clk_debug_mux mc_cc_debug_mux = { static struct mux_regmap_names mux_list[] = { { .mux = &mc_cc_debug_mux, .regmap_name = "qcom,mccc" }, { .mux = &video_cc_debug_mux, .regmap_name = "qcom,videocc" }, + { .mux = &cpu_cc_debug_mux, .regmap_name = "qcom,cpucc" }, { .mux = &gpu_cc_debug_mux, .regmap_name = "qcom,gpucc" }, { .mux = &disp_cc_debug_mux, .regmap_name = "qcom,dispcc" }, { .mux = &gcc_debug_mux, .regmap_name = "qcom,gcc" }, }; +static struct clk_dummy perfcl_clk = { + .rrate = 1000, + .hw.init = &(struct clk_init_data){ + .name = "perfcl_clk", + .ops = &clk_dummy_ops, + }, +}; + +static struct clk_dummy pwrcl_clk = { + .rrate = 1000, + .hw.init = &(struct clk_init_data){ + .name = "pwrcl_clk", + .ops = &clk_dummy_ops, + }, +}; + static struct clk_dummy measure_only_mccc_clk = { .rrate = 1000, .hw.init = &(struct clk_init_data){ @@ -562,6 +617,8 @@ static struct clk_hw *debugcc_trinket_hws[] = { &measure_only_ipa_2x_clk.hw, &measure_only_mccc_clk.hw, &measure_only_snoc_clk.hw, + &perfcl_clk.hw, + &pwrcl_clk.hw, }; static const struct of_device_id clk_debug_match_table[] = { @@ -581,6 +638,8 @@ static int clk_debug_trinket_probe(struct platform_device *pdev) ARRAY_SIZE(gpu_cc_debug_mux_sels)); BUILD_BUG_ON(ARRAY_SIZE(video_cc_debug_mux_parent_names) != ARRAY_SIZE(video_cc_debug_mux_sels)); + BUILD_BUG_ON(ARRAY_SIZE(cpu_cc_debug_mux_parent_names) != + ARRAY_SIZE(cpu_cc_debug_mux_sels)); clk = devm_clk_get(&pdev->dev, "xo_clk_src"); if (IS_ERR(clk)) { From 0ae958c774d097264be360ae0411c6a7dc37a40a Mon Sep 17 00:00:00 2001 From: Mehul Raninga Date: Thu, 14 Dec 2023 14:28:27 +0530 Subject: [PATCH 10/46] i2c: i2c-msm-geni: Correct ipc logging for ret value One of the ipc logging statement was missing argument of ret. Corrected by adding last argument in ipc log. Change-Id: Icaf6cba021abb1df8d12ab6b821a9a12c04e4f17 Signed-off-by: Mehul Raninga --- drivers/i2c/busses/i2c-msm-geni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-msm-geni.c b/drivers/i2c/busses/i2c-msm-geni.c index 9eb3060011ee..d921a8bab679 100644 --- a/drivers/i2c/busses/i2c-msm-geni.c +++ b/drivers/i2c/busses/i2c-msm-geni.c @@ -2420,7 +2420,7 @@ static int geni_i2c_suspend_late(struct device *device) pm_runtime_enable(device); } i2c_unlock_bus(&gi2c->adap, I2C_LOCK_SEGMENT); - I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "%s ret=%d\n", __func__); + I2C_LOG_DBG(gi2c->ipcl, false, gi2c->dev, "%s ret=%d\n", __func__, ret); return 0; } #else From 1c3a4c1a76ee07d2a99c3c5732509acd7a50e6ed Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Mon, 4 Sep 2023 19:24:58 +0530 Subject: [PATCH 11/46] soc: qcom: minidump: Do not copy content from address around X* registers There was a debug feature on minidump to collect content around pointers present in panicked cpu registers from X0-X30. PC, LR, SP. and it was having check present before copy the contents about address need to be kernel mapped and not hyp assigned. We should be able to do most of the checking present as well but tracking the buffers which are assigned to other VMID through qcom_scm_assign_mem() and since it is upstream API and adding magic value to each PFN and restore it if there is failure is kind of overhead for such a debug feature, ideally it should have done on client side but doing at the client is very difficult task to do as there are many users of this API. For now, we are cleaning this up, unless we know the user of this information and it is worth doable. Change-Id: I638877063a4c8c6dabb7d16bcc4eeb63f5108fba Signed-off-by: Mukesh Ojha Signed-off-by: Srinivasarao Pathipati --- drivers/soc/qcom/minidump_log.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/soc/qcom/minidump_log.c b/drivers/soc/qcom/minidump_log.c index da170a7c0372..e28f62561824 100644 --- a/drivers/soc/qcom/minidump_log.c +++ b/drivers/soc/qcom/minidump_log.c @@ -968,7 +968,6 @@ static void md_dump_data(unsigned long addr, int nbytes, const char *name) static void md_reg_context_data(struct pt_regs *regs) { - unsigned int i; int nbytes = 128; if (user_mode(regs) || !regs->pc) @@ -977,12 +976,6 @@ static void md_reg_context_data(struct pt_regs *regs) md_dump_data(regs->pc - nbytes, nbytes * 2, "PC"); md_dump_data(regs->regs[30] - nbytes, nbytes * 2, "LR"); md_dump_data(regs->sp - nbytes, nbytes * 2, "SP"); - for (i = 0; i < 30; i++) { - char name[4]; - - snprintf(name, sizeof(name), "X%u", i); - md_dump_data(regs->regs[i] - nbytes, nbytes * 2, name); - } } static inline void md_dump_panic_regs(void) From e2bd6c9735206d3743283a2416cb75b146e9a409 Mon Sep 17 00:00:00 2001 From: zhezhe song Date: Fri, 20 Oct 2023 14:58:56 +0800 Subject: [PATCH 12/46] config: enable CONFIG_USB_NET_AX88179_178A for kalama LE target Enable CONFIG_USB_NET_AX88179_178A for kalama LE target. Change-Id: I7a3a40ed2b58d44bc091f1b469a359fd619bd719 Signed-off-by: zhezhe song --- arch/arm64/configs/vendor/kalama_le_GKI.config | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/vendor/kalama_le_GKI.config b/arch/arm64/configs/vendor/kalama_le_GKI.config index 42ce44525fbe..bd68a96d652d 100644 --- a/arch/arm64/configs/vendor/kalama_le_GKI.config +++ b/arch/arm64/configs/vendor/kalama_le_GKI.config @@ -368,6 +368,7 @@ CONFIG_USB_M31_MSM_EUSB2_PHY=m CONFIG_USB_MON=m CONFIG_USB_MSM_EUSB2_PHY=m CONFIG_USB_MSM_SSPHY_QMP=m +CONFIG_USB_NET_AX88179_178A=m # CONFIG_USB_NET_RNDIS_WLAN is not set CONFIG_USB_QCOM_EMU_PHY=m CONFIG_USB_REDRIVER=m From 1efc952c902436efae1931ac27f39d2f3ccc746a Mon Sep 17 00:00:00 2001 From: Srinivasarao Pathipati Date: Thu, 14 Dec 2023 02:30:59 -0800 Subject: [PATCH 13/46] Revert "qcom_spss: Assign spss PIL memory to SPSS and HLOS ownership" This reverts commit 7da358c0ed8c084a95fe29ac5d3c45421b1c8073. Reason for revert: HLOS is accessing outside PIL region causing crash, so reverting the change that is accessing outside SPSS PIL region. Change-Id: I1cbc4c9a0885a316509ab829fcd3559a1aeb0bb8 Signed-off-by: Srinivasarao Pathipati --- drivers/remoteproc/qcom_spss.c | 67 +--------------------------------- include/linux/qcom_scm.h | 1 - 2 files changed, 1 insertion(+), 67 deletions(-) diff --git a/drivers/remoteproc/qcom_spss.c b/drivers/remoteproc/qcom_spss.c index 08d345c1992f..645e0e8f6905 100644 --- a/drivers/remoteproc/qcom_spss.c +++ b/drivers/remoteproc/qcom_spss.c @@ -40,10 +40,6 @@ #define SP_SCSR_MB1_SP2CL_GP0_ADDR 0x1888020 #define SP_SCSR_MB3_SP2CL_GP0_ADDR 0x188C020 -#define MAX_ROT_DATA_SIZE_IN_BYTES 4096 - -static bool ssr_already_occurred_since_boot; - #define NUM_OF_DEBUG_REGISTERS_READ 0x3 struct spss_data { const char *firmware_name; @@ -302,74 +298,13 @@ static bool check_status(struct qcom_spss *spss, int *ret_error) return false; } -static int manage_unused_pil_region_memory(struct qcom_spss *spss) -{ - unsigned int src_vmid_list; - struct qcom_scm_vmperm newvm[2]; - u8 *spss_rot_data; - int res; - - spss_rot_data = kcalloc(MAX_ROT_DATA_SIZE_IN_BYTES, sizeof(*spss_rot_data), GFP_KERNEL); - if (!spss_rot_data) - return -ENOMEM; - - /* - * When assigning memory to different ownership, previous data is erased, - * ROT data needs to remain in SPSS region as written by SPSS before. - */ - memcpy(spss_rot_data, - (uint8_t *)(uintptr_t)(spss->mem_region+spss->mem_size-MAX_ROT_DATA_SIZE_IN_BYTES), - MAX_ROT_DATA_SIZE_IN_BYTES); - - src_vmid_list = BIT(QCOM_SCM_VMID_HLOS); - - newvm[0].vmid = QCOM_SCM_VMID_HLOS; - newvm[0].perm = QCOM_SCM_PERM_RW; - newvm[1].vmid = QCOM_SCM_VMID_CP_SPSS_SP; - newvm[1].perm = QCOM_SCM_PERM_RW; - - res = qcom_scm_assign_mem(spss->mem_phys + spss->mem_size - MAX_ROT_DATA_SIZE_IN_BYTES, - MAX_ROT_DATA_SIZE_IN_BYTES, &src_vmid_list, newvm, 2); - if (res) { - dev_err(spss->dev, "qcom_scm_assign_mem failed %d\n", res); - kfree(spss_rot_data); - return res; - } - - memcpy((uint8_t *)(uintptr_t)(spss->mem_region+spss->mem_size-MAX_ROT_DATA_SIZE_IN_BYTES), - spss_rot_data, MAX_ROT_DATA_SIZE_IN_BYTES); - - kfree(spss_rot_data); - return res; -} - static int spss_load(struct rproc *rproc, const struct firmware *fw) { struct qcom_spss *spss = (struct qcom_spss *)rproc->priv; - int res; - res = qcom_mdt_load(spss->dev, fw, rproc->firmware, spss->pas_id, + return qcom_mdt_load(spss->dev, fw, rproc->firmware, spss->pas_id, spss->mem_region, spss->mem_phys, spss->mem_size, &spss->mem_reloc); - - if (res) { - dev_err(spss->dev, "qcom_mdt_load of SPSS image failed, error value %d\n", res); - return res; - } - - /* - * During SSR only PIL memory is released. - * If an SSR already occurred, the memory beyond image_size - * remains assigned since PIL didn't own it. - */ - if (!ssr_already_occurred_since_boot) { - res = manage_unused_pil_region_memory(spss); - /* Set to true only if memory was successfully assigned*/ - if (!res) - ssr_already_occurred_since_boot = true; - } - - return res; } static int spss_stop(struct rproc *rproc) diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 2a4ef3a5acd7..21e030bda8e9 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -91,7 +91,6 @@ extern enum qcom_scm_custom_reset_type qcom_scm_custom_reset_type; #define QCOM_SCM_VMID_MSS_MSA 0xF #define QCOM_SCM_VMID_WLAN 0x18 #define QCOM_SCM_VMID_WLAN_CE 0x19 -#define QCOM_SCM_VMID_CP_SPSS_SP 0x1A #define QCOM_SCM_PERM_READ 0x4 #define QCOM_SCM_PERM_WRITE 0x2 #define QCOM_SCM_PERM_EXEC 0x1 From 447103dd442d1a4fad66fefe1b0d852e7ee3d8da Mon Sep 17 00:00:00 2001 From: Chetan C R Date: Thu, 30 Nov 2023 14:59:18 +0530 Subject: [PATCH 14/46] build.config: modules.list.msm.qcs605: Add interconnect and clock Add Interconnect, qos, qnoc, clock support for QCS605. Change-Id: Iead8fb2a4cb306213bd187576150ca2f51211fc4 Signed-off-by: Chetan C R --- modules.list.msm.qcs605 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules.list.msm.qcs605 b/modules.list.msm.qcs605 index df9dece68d90..9248c0ed2a61 100644 --- a/modules.list.msm.qcs605 +++ b/modules.list.msm.qcs605 @@ -1,17 +1,19 @@ qcom_wdt_core.ko qcom_cpu_vendor_hooks.ko -clk-rpmh.ko -gcc-sdm845.ko -icc-rpmh.ko qcom_ipcc.ko qcom_ipc_logging.ko qcom-pdc.ko rpmh-regulator.ko bwmon.ko +qcom_rpmh.ko qcom-cpufreq-hw.ko sched-walt.ko -clk-dummy.ko +clk-rpmh.ko clk-qcom.ko +clk-dummy.ko +gdsc-regulator.ko +gcc-sdm845.ko +dispcc-sdm845.ko cmd-db.ko cqhci.ko crypto-qti-common.ko @@ -19,7 +21,6 @@ crypto-qti-hwkm.ko dcc_v2.ko dcvs_fp.ko debug-regulator.ko -gdsc-regulator.ko smp2p.ko rproc_qcom_common.ko qcom_pil_info.ko @@ -31,6 +32,9 @@ qcom_smd.ko mdt_loader.ko hwkm.ko icc-bcm-voter.ko +icc-rpmh.ko +qnoc-qos.ko +qnoc-sdm670.ko icc-debug.ko iommu-logger.ko llcc-qcom.ko @@ -54,9 +58,7 @@ qcom_llcc_pmu.ko qcom-pmu-lib.ko qcom-spmi-pmic.ko spmi-pmic-arb.ko -qcom_rpmh.ko qcom-scm.ko -qnoc-qos.ko qrtr.ko qti-regmap-debugfs.ko regmap-spmi.ko From 382930125ed4a2a44f41205ac510b56fa30d96a4 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Tue, 21 Nov 2023 15:38:42 +0530 Subject: [PATCH 15/46] soc: qcom: rpmh-rsc: Use stack memory for rpmh transfers During low memory situations caused by some scenarios such as OTA upgrade rpmh transfers may fail. Use stack memory for rpmh transfers to avoid such failures. Change-Id: I904f788dd865d083191bc5113a27e6ee232ebfc8 Signed-off-by: Maulik Shah --- drivers/soc/qcom/rpmh-internal.h | 27 +++- drivers/soc/qcom/rpmh-rsc.c | 56 ++++++-- drivers/soc/qcom/rpmh.c | 227 +++++++++---------------------- 3 files changed, 130 insertions(+), 180 deletions(-) diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h index 50f9c82e6d4e..462c9e925104 100644 --- a/drivers/soc/qcom/rpmh-internal.h +++ b/drivers/soc/qcom/rpmh-internal.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2016-2018, 2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ @@ -28,8 +28,25 @@ #define SOLVER_PRESENT 1 #define HW_CHANNEL_PRESENT 2 +#define CMD_DB_MAX_RESOURCES 250 + struct rsc_drv; +/** + * struct cache_req: the request object for caching + * + * @addr: the address of the resource + * @sleep_val: the sleep vote + * @wake_val: the wake vote + * @list: linked list obj + */ +struct cache_req { + u32 addr; + u32 sleep_val; + u32 wake_val; + struct list_head list; +}; + /** * struct tcs_group: group of Trigger Command Sets (TCS) to send state requests * to the controller @@ -70,20 +87,17 @@ struct tcs_group { * @cmd: the payload that will be part of the @msg * @completion: triggered when request is done * @dev: the device making the request - * @needs_free: check to free dynamically allocated request object */ struct rpmh_request { struct tcs_request msg; struct tcs_cmd cmd[MAX_RPMH_PAYLOAD]; struct completion *completion; const struct device *dev; - bool needs_free; }; /** * struct rpmh_ctrlr: our representation of the controller * - * @cache: the list of cached requests * @cache_lock: synchronize access to the cache data * @dirty: was the cache updated since flush * @in_solver_mode: Controller is busy in solver mode @@ -91,12 +105,13 @@ struct rpmh_request { * @batch_cache: Cache sleep and wake requests sent as batch */ struct rpmh_ctrlr { - struct list_head cache; spinlock_t cache_lock; bool dirty; bool in_solver_mode; u32 flags; - struct list_head batch_cache; + struct rpmh_request batch_cache[RPMH_ACTIVE_ONLY_STATE]; + u32 non_batch_cache_idx; + struct cache_req *non_batch_cache; }; /** diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 0f370a9a245b..71a5a5452a6e 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -704,11 +704,22 @@ static int find_free_tcs(struct tcs_group *tcs) const struct rsc_drv *drv = tcs->drv; unsigned long i; unsigned long max = tcs->offset + tcs->num_tcs; + int timeout = 100; i = find_next_zero_bit(drv->tcs_in_use, max, tcs->offset); if (i >= max) return -EBUSY; + while (timeout) { + if (read_tcs_reg(drv, drv->regs[RSC_DRV_STATUS], i)) + break; + timeout--; + udelay(1); + } + + if (!timeout) + return -EBUSY; + return i; } @@ -791,17 +802,20 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg, int c tcs->req[tcs_id - tcs->offset] = msg; set_bit(tcs_id, drv->tcs_in_use); - if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) { - /* - * Clear previously programmed WAKE commands in selected - * repurposed TCS to avoid triggering them. tcs->slots will be - * cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate() - */ - write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0); - write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id, 0); + + /* + * Clear previously programmed ACTIVE/WAKE commands in selected + * repurposed TCS to avoid triggering them. tcs->slots will be + * cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate() + */ + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0); + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id, 0); + + if (msg->wait_for_compl || (msg->state == RPMH_ACTIVE_ONLY_STATE && + tcs->type != ACTIVE_TCS)) enable_tcs_irq(drv, tcs_id, true); - } - spin_unlock_irqrestore(&drv->lock, flags); + else + enable_tcs_irq(drv, tcs_id, false); /* * These two can be done after the lock is released because: @@ -813,7 +827,16 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg, int c */ __tcs_buffer_write(drv, tcs_id, 0, msg); __tcs_set_trigger(drv, tcs_id, true); - ipc_log_string(drv->ipc_log_ctx, "TCS trigger: m=%d", tcs_id); + ipc_log_string(drv->ipc_log_ctx, "TCS trigger: m=%d wait_for_compl=%u", + tcs_id, msg->wait_for_compl); + + if (!msg->wait_for_compl) + clear_bit(tcs_id, drv->tcs_in_use); + + spin_unlock_irqrestore(&drv->lock, flags); + + if (!msg->wait_for_compl) + wake_up(&drv->tcs_wait); return 0; } @@ -1586,7 +1609,7 @@ static int rpmh_rsc_probe(struct platform_device *pdev) struct rsc_drv_top *rsc_top; int ret, irq; u32 rsc_id, major_ver, minor_ver, solver_config; - int i, drv_count; + int i, j, drv_count; const char *name; /* @@ -1717,6 +1740,13 @@ static int rpmh_rsc_probe(struct platform_device *pdev) spin_lock_init(&drv[i].lock); init_waitqueue_head(&drv[i].tcs_wait); bitmap_zero(drv[i].tcs_in_use, MAX_TCS_NR); + drv[i].client.non_batch_cache = devm_kcalloc(&pdev->dev, CMD_DB_MAX_RESOURCES, + sizeof(struct cache_req), GFP_KERNEL); + if (!drv[i].client.non_batch_cache) + return -ENOMEM; + + for (j = 0; j < CMD_DB_MAX_RESOURCES; j++) + INIT_LIST_HEAD(&drv[i].client.non_batch_cache[j].list); irq = platform_get_irq(pdev, drv[i].id); if (irq < 0) @@ -1731,8 +1761,6 @@ static int rpmh_rsc_probe(struct platform_device *pdev) return ret; spin_lock_init(&drv[i].client.cache_lock); - INIT_LIST_HEAD(&drv[i].client.cache); - INIT_LIST_HEAD(&drv[i].client.batch_cache); drv[i].ipc_log_ctx = ipc_log_context_create( RSC_DRV_IPC_LOG_SIZE, diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index dbd5da6a7119..9c5d87a27872 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2018, 2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -36,40 +36,10 @@ .cmd = { { 0 } }, \ .completion = q, \ .dev = device, \ - .needs_free = false, \ } #define ctrlr_to_drv(ctrlr) container_of(ctrlr, struct rsc_drv, client) -/** - * struct cache_req: the request object for caching - * - * @addr: the address of the resource - * @sleep_val: the sleep vote - * @wake_val: the wake vote - * @list: linked list obj - */ -struct cache_req { - u32 addr; - u32 sleep_val; - u32 wake_val; - struct list_head list; -}; - -/** - * struct batch_cache_req - An entry in our batch catch - * - * @list: linked list obj - * @count: number of messages - * @rpm_msgs: the messages - */ - -struct batch_cache_req { - struct list_head list; - int count; - struct rpmh_request *rpm_msgs; -}; - static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct device *dev) { struct rsc_drv *drv = dev_get_drvdata(dev->parent); @@ -108,30 +78,32 @@ void rpmh_tx_done(const struct tcs_request *msg) struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request, msg); struct completion *compl = rpm_msg->completion; - bool free = rpm_msg->needs_free; if (!compl) - goto exit; + return; /* Signal the blocking thread we are done */ complete(compl); - -exit: - if (free) - kfree(rpm_msg); } -static struct cache_req *__find_req(struct rpmh_ctrlr *ctrlr, u32 addr) +static struct cache_req *get_non_batch_cache_req(struct rpmh_ctrlr *ctrlr, u32 addr) { - struct cache_req *p, *req = NULL; + struct cache_req *req = ctrlr->non_batch_cache; + int i; - list_for_each_entry(p, &ctrlr->cache, list) { - if (p->addr == addr) { - req = p; - break; - } + if (ctrlr->non_batch_cache_idx >= CMD_DB_MAX_RESOURCES) + return NULL; + + for (i = 0; i < ctrlr->non_batch_cache_idx; i++) { + req = &ctrlr->non_batch_cache[i]; + if (req->addr == addr) + return req; } + req = &ctrlr->non_batch_cache[ctrlr->non_batch_cache_idx]; + req->sleep_val = req->wake_val = UINT_MAX; + ctrlr->non_batch_cache_idx++; + return req; } @@ -144,21 +116,14 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr, u32 old_sleep_val, old_wake_val; spin_lock_irqsave(&ctrlr->cache_lock, flags); - req = __find_req(ctrlr, cmd->addr); - if (req) - goto existing; - req = kzalloc(sizeof(*req), GFP_ATOMIC); + req = get_non_batch_cache_req(ctrlr, cmd->addr); if (!req) { req = ERR_PTR(-ENOMEM); goto unlock; } req->addr = cmd->addr; - req->sleep_val = req->wake_val = UINT_MAX; - list_add_tail(&req->list, &ctrlr->cache); - -existing: old_sleep_val = req->sleep_val; old_wake_val = req->wake_val; @@ -255,29 +220,23 @@ static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state, int rpmh_write_async(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) { + DEFINE_RPMH_MSG_ONSTACK(dev, state, NULL, rpm_msg); struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); - struct rpmh_request *rpm_msg; int ret; if (rpmh_standalone) return 0; + rpm_msg.msg.wait_for_compl = false; ret = check_ctrlr_state(ctrlr, state); if (ret) return ret; - rpm_msg = kzalloc(sizeof(*rpm_msg), GFP_ATOMIC); - if (!rpm_msg) - return -ENOMEM; - rpm_msg->needs_free = true; - - ret = __fill_rpmh_msg(rpm_msg, state, cmd, n); - if (ret) { - kfree(rpm_msg); + ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n); + if (ret) return ret; - } - return __rpmh_write(dev, state, rpm_msg); + return __rpmh_write(dev, state, &rpm_msg); } EXPORT_SYMBOL(rpmh_write_async); @@ -324,35 +283,18 @@ int rpmh_write(const struct device *dev, enum rpmh_state state, } EXPORT_SYMBOL(rpmh_write); -static void cache_batch(struct rpmh_ctrlr *ctrlr, struct batch_cache_req *req) -{ - unsigned long flags; - - spin_lock_irqsave(&ctrlr->cache_lock, flags); - list_add_tail(&req->list, &ctrlr->batch_cache); - ctrlr->dirty = true; - spin_unlock_irqrestore(&ctrlr->cache_lock, flags); -} - static int flush_batch(struct rpmh_ctrlr *ctrlr, int ch) { - struct batch_cache_req *req; - const struct rpmh_request *rpm_msg; - int ret = 0; - int i; + int ret; - /* Send Sleep/Wake requests to the controller, expect no response */ - list_for_each_entry(req, &ctrlr->batch_cache, list) { - for (i = 0; i < req->count; i++) { - rpm_msg = req->rpm_msgs + i; - ret = rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr), - &rpm_msg->msg, ch); - if (ret) - break; - } - } + /* Send Sleep/Wake requests to the controller, expect no response IRQ */ + ret = rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr), + &ctrlr->batch_cache[RPMH_SLEEP_STATE].msg, ch); + if (ret) + return ret; - return ret; + return rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr), + &ctrlr->batch_cache[RPMH_WAKE_ONLY_STATE].msg, ch); } /** @@ -375,14 +317,10 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr, int ch) int rpmh_write_batch(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 *n) { - struct batch_cache_req *req; - struct rpmh_request *rpm_msgs; - struct completion *compls; + DECLARE_COMPLETION_ONSTACK(compl); + DEFINE_RPMH_MSG_ONSTACK(dev, state, &compl, rpm_msg); struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); - unsigned long time_left; - int count = 0; - int ret, i, ch; - void *ptr; + int ret, ch; if (rpmh_standalone) return 0; @@ -391,73 +329,46 @@ int rpmh_write_batch(const struct device *dev, enum rpmh_state state, if (ret) return ret; - if (!cmd || !n) - return -EINVAL; + if (state == RPMH_ACTIVE_ONLY_STATE) { + ret = __fill_rpmh_msg(&rpm_msg, state, cmd, *n); + if (ret) + return ret; + } else { + memset(&ctrlr->batch_cache[state], 0, sizeof(struct rpmh_request)); + ret = __fill_rpmh_msg(&ctrlr->batch_cache[state], state, cmd, *n); + if (ret) + return ret; - while (n[count] > 0) - count++; - if (!count) - return -EINVAL; + spin_lock(&ctrlr->cache_lock); + ctrlr->dirty = true; + spin_unlock(&ctrlr->cache_lock); - ptr = kzalloc(sizeof(*req) + - count * (sizeof(req->rpm_msgs[0]) + sizeof(*compls)), - GFP_ATOMIC); - if (!ptr) - return -ENOMEM; - - req = ptr; - rpm_msgs = ptr + sizeof(*req); - compls = ptr + sizeof(*req) + count * sizeof(*rpm_msgs); - - req->count = count; - req->rpm_msgs = rpm_msgs; - - for (i = 0; i < count; i++) { - __fill_rpmh_msg(rpm_msgs + i, state, cmd, n[i]); - cmd += n[i]; - } - - if (state != RPMH_ACTIVE_ONLY_STATE) { - cache_batch(ctrlr, req); return 0; } ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr)); - if (ch < 0) { - kfree(ptr); + if (ch < 0) return ch; + + ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg.msg, ch); + if (ret) { + pr_err("Error(%d) sending RPMH message addr=%#x\n", + ret, rpm_msg.msg.cmds[0].addr); + return ret; } - for (i = 0; i < count; i++) { - struct completion *compl = &compls[i]; - - init_completion(compl); - rpm_msgs[i].completion = compl; - ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msgs[i].msg, ch); - if (ret) { - pr_err("Error(%d) sending RPMH message addr=%#x\n", - ret, rpm_msgs[i].msg.cmds[0].addr); - break; - } + ret = wait_for_completion_timeout(&compl, RPMH_TIMEOUT_MS); + if (!ret) { + /* + * Better hope they never finish because they'll signal + * the completion that we're going to free once + * we've returned from this function. + */ + rpmh_rsc_debug(ctrlr_to_drv(ctrlr), &compl); + BUG_ON(1); } - time_left = RPMH_TIMEOUT_MS; - while (i--) { - time_left = wait_for_completion_timeout(&compls[i], time_left); - if (!time_left) { - /* - * Better hope they never finish because they'll signal - * the completion that we're going to free once - * we've returned from this function. - */ - rpmh_rsc_debug(ctrlr_to_drv(ctrlr), &compls[i]); - BUG_ON(1); - } - } - - kfree(ptr); - - return ret; + return 0; } EXPORT_SYMBOL(rpmh_write_batch); @@ -485,7 +396,7 @@ static int send_single(struct rpmh_ctrlr *ctrlr, enum rpmh_state state, int _rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch) { struct cache_req *p; - int ret = 0; + int ret = 0, i; if (!ctrlr->dirty) { pr_debug("Skipping flush, TCS has latest data.\n"); @@ -500,7 +411,8 @@ int _rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch) if (ret) return ret; - list_for_each_entry(p, &ctrlr->cache, list) { + for (i = 0; i < ctrlr->non_batch_cache_idx; i++) { + p = &ctrlr->non_batch_cache[i]; if (!is_req_valid(p)) { pr_debug("%s: skipping RPMH req: a:%#x s:%#x w:%#x\n", __func__, p->addr, p->sleep_val, p->wake_val); @@ -628,19 +540,14 @@ EXPORT_SYMBOL(rpmh_write_sleep_and_wake_no_child); void rpmh_invalidate(const struct device *dev) { struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); - struct batch_cache_req *req, *tmp; unsigned long flags; if (rpmh_standalone) return; spin_lock_irqsave(&ctrlr->cache_lock, flags); - list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list) { - list_del(&req->list); - kfree(req); - } - - INIT_LIST_HEAD(&ctrlr->batch_cache); + memset(&ctrlr->batch_cache[RPMH_SLEEP_STATE], 0, sizeof(struct rpmh_request)); + memset(&ctrlr->batch_cache[RPMH_WAKE_ONLY_STATE], 0, sizeof(struct rpmh_request)); ctrlr->dirty = true; spin_unlock_irqrestore(&ctrlr->cache_lock, flags); } From 3ea4f00d65fc22512f730451cbdd381a1a7ff63e Mon Sep 17 00:00:00 2001 From: Sivakanth Vaka Date: Fri, 15 Dec 2023 16:16:38 +0530 Subject: [PATCH 16/46] msm: ipa3: add new ETH PDU LL QMI Add new QMI messages and struct to support ETH PDU TSN FR. Change-Id: I4197893741673db72177447dc281349992cb0c10 Signed-off-by: Sivakanth Vaka --- include/uapi/linux/ipa_qmi_service_v01.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/uapi/linux/ipa_qmi_service_v01.h b/include/uapi/linux/ipa_qmi_service_v01.h index 692ed2ead614..acbe6e5342a4 100644 --- a/include/uapi/linux/ipa_qmi_service_v01.h +++ b/include/uapi/linux/ipa_qmi_service_v01.h @@ -2,6 +2,7 @@ /* * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. */ /* @@ -2585,6 +2586,8 @@ enum ipa_ep_desc_type_enum_v01 { DATA_EP_DESC_TYPE_TETH_RMNET_PROD_V01 = 0x09, DATA_EP_DESC_TYPE_EMB_FLOW_CTL_CONS_V01 = 0x0A, DATA_EP_DESC_TYPE_EMB_FLOW_CTL_PROD_V01 = 0x0B, + DATA_EP_DESC_TYPE_TETH_LL_CONS_V01 = 0x0C, + DATA_EP_DESC_TYPE_TETH_LL_PROD_V01 = 0x0D, IPA_EP_DESC_TYPE_ENUM_MAX_VAL_V01 = IPA_INT_MAX, }; From b27fb9fa6dd2760670a29d9e8cb154f8469c77cc Mon Sep 17 00:00:00 2001 From: simran jaiswal Date: Mon, 18 Dec 2023 13:14:26 +0530 Subject: [PATCH 17/46] drivers: soc: qcom: Fixing overflow issue in LPLH Fixing issue of overflow while parsing init ipc freq table parameters for LPLH. Change-Id: I15cca3b722a1ffbb9c596119eb3a819295143f30 Signed-off-by: simran jaiswal --- drivers/soc/qcom/msm_performance.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/msm_performance.c b/drivers/soc/qcom/msm_performance.c index a5aa1c37674b..75b8e8eb4b22 100644 --- a/drivers/soc/qcom/msm_performance.c +++ b/drivers/soc/qcom/msm_performance.c @@ -1318,7 +1318,7 @@ static int init_lplh_notif(const char *buf) return -EINVAL; cp = buf; if (sscanf(cp, INIT ":%hu", &nClusters)) { - if (!nClusters) + if (!nClusters || nClusters > LPLH_CLUSTER_MAX_CNT) return -EINVAL; *ptmp++ = nClusters; @@ -1358,7 +1358,7 @@ static int init_lplh_notif(const char *buf) while ((cp1 = strpbrk(cp1 + 1, ","))) nValues++; - if (nValues % 2 != 0) + if (nValues % 2 != 0 || LPLH_IPC_FREQ_VTBL_MAX_CNT < nValues/2) return -EINVAL; *ptmp++ = nValues/2; From 18af9e38eaea28c9cc0197bc5e3aef3609c0313e Mon Sep 17 00:00:00 2001 From: Shreyas K K Date: Thu, 14 Dec 2023 08:18:58 +0530 Subject: [PATCH 18/46] drivers: arm-smmu: Power-on SMMU during freeze There can be a possibility that runtime power management has powered-down SMMU. Now, if there is a freeze request on top of that, we will see SMMU register access errors, as the SMMU is already powered-down. Power-on SMMU during the freeze for accessing the SMMU registers as part of qcom_free_io_pgtable_ops(). Change-Id: I6fff3ca0a70c071947e34bc4e574e3e565ee875d Signed-off-by: Shreyas K K Signed-off-by: Yadu MG --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index e2eac342c8c0..5bf0e5d79293 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -4136,6 +4136,12 @@ static int __maybe_unused arm_smmu_pm_freeze_late(struct device *dev) struct arm_smmu_cb *cb; int idx, ret; + ret = arm_smmu_runtime_resume(dev); + if (ret) { + dev_err(dev, "Failed to Resume:%d\n", ret); + return ret; + } + for (idx = 0; idx < smmu->num_context_banks; idx++) { cb = &smmu->cbs[idx]; if (cb && cb->cfg) { From dceb8b6fb7cd8f23a71e1a820c7448de06774e93 Mon Sep 17 00:00:00 2001 From: Srinath Pandey Date: Thu, 26 Oct 2023 19:42:09 +0530 Subject: [PATCH 19/46] net: stmmac: enable/disable irq LPM Free_irq on suspend and request_irq on resume. Change-Id: I5340b16b21eeb11aa3d950d22d64c7681efc2293 Signed-off-by: Srinath Pandey Signed-off-by: Vivek Yadav --- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 + .../net/ethernet/stmicro/stmmac/stmmac_main.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 3c382ef404f6..9110744236ee 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -205,6 +205,7 @@ struct stmmac_priv { int tx_coalesce; int hwts_tx_en; + int irq_number; bool tx_path_in_lpi_mode; bool tso; int sph; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 5159720ad773..b6471ef8ce59 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3956,6 +3956,8 @@ static int stmmac_open(struct net_device *dev) if (ret) goto irq_error; + priv->irq_number = dev->irq; + stmmac_enable_all_queues(priv); netif_tx_start_all_queues(priv->dev); stmmac_enable_all_dma_irq(priv); @@ -7659,6 +7661,12 @@ int stmmac_suspend(struct device *dev) hrtimer_cancel(&priv->tx_queue[chan].txtimer); } + /* Free the IRQ lines */ + if (priv->irq_number != 0) { + free_irq(ndev->irq, ndev); + priv->irq_number = 0; + } + if (priv->eee_enabled) { priv->tx_path_in_lpi_mode = false; del_timer_sync(&priv->eee_ctrl_timer); @@ -7813,6 +7821,16 @@ int stmmac_resume(struct device *dev) stmmac_restore_hw_vlan_rx_fltr(priv, ndev, priv->hw); + if (priv->irq_number == 0) { + ret = request_irq(ndev->irq, stmmac_interrupt, + IRQF_SHARED, ndev->name, ndev); + if (unlikely(ret < 0)) + netdev_err(priv->dev, + "%s: ERROR: allocating the IRQ %d (error: %d)\n", + __func__, ndev->irq, ret); + priv->irq_number = ndev->irq; + } + stmmac_enable_all_queues(priv); stmmac_enable_all_dma_irq(priv); From 1221637cb7c32480695153e5ad8aabaaff11eff8 Mon Sep 17 00:00:00 2001 From: Shreyas K K Date: Fri, 1 Dec 2023 02:23:14 +0530 Subject: [PATCH 20/46] drivers: remoteproc: Modify callbacks for Rproc during Deepsleep Handle deviations in Deepsleep requirements by introducing new callbacks that would be invoked during deepsleep suspend. Change-Id: I988a72fa3b175de4338b4e5fa2a90191a438aa4b Signed-off-by: Shreyas K K --- drivers/remoteproc/qcom_common.h | 4 +++ drivers/remoteproc/qcom_q6v5_pas.c | 49 +++++++++++++++++++++++++++ drivers/remoteproc/qcom_sysmon.c | 45 ++++++++++++++++++++++++ drivers/soc/qcom/power_state.c | 2 ++ include/linux/remoteproc/qcom_rproc.h | 8 +++++ 5 files changed, 108 insertions(+) diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h index a61646963020..db15f8cef11e 100644 --- a/drivers/remoteproc/qcom_common.h +++ b/drivers/remoteproc/qcom_common.h @@ -93,6 +93,7 @@ void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon); bool qcom_sysmon_shutdown_acked(struct qcom_sysmon *sysmon); uint32_t qcom_sysmon_get_txn_id(struct qcom_sysmon *sysmon); int qcom_sysmon_get_reason(struct qcom_sysmon *sysmon, char *buf, size_t len); +void qcom_sysmon_set_ops_stop(struct qcom_sysmon *sysmon, bool suspend); #else static inline struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc, const char *name, @@ -120,6 +121,9 @@ static inline int qcom_sysmon_get_reason(struct qcom_sysmon *sysmon, { return -ENODEV; } + +static inline void qcom_sysmon_set_ops_stop(struct qcom_sysmon *sysmon, + bool suspend) { } #endif #endif diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 84bc8c4ac60f..9557d963e3c6 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "qcom_common.h" #include "qcom_pil_info.h" @@ -635,6 +636,54 @@ static int adsp_stop(struct rproc *rproc) return ret; } +static int adsp_shutdown(struct rproc *rproc) +{ + struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; + int handover; + int ret; + + trace_rproc_qcom_event(dev_name(adsp->dev), "adsp_shutdown", "enter"); + + scm_pas_enable_bw(); + if (adsp->retry_shutdown) + ret = qcom_scm_pas_shutdown_retry(adsp->pas_id); + else + ret = qcom_scm_pas_shutdown(adsp->pas_id); + if (ret) + panic("Panicking, remoteproc %s failed to shutdown.\n", rproc->name); + + if (adsp->dtb_pas_id) { + ret = qcom_scm_pas_shutdown(adsp->dtb_pas_id); + if (ret) + panic("Panicking, remoteproc %s dtb failed to shutdown.\n", rproc->name); + } + + scm_pas_disable_bw(); + adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count); + if (adsp->qmp) + qcom_rproc_toggle_load_state(adsp->qmp, adsp->qmp_name, false); + handover = qcom_q6v5_unprepare(&adsp->q6v5); + if (handover) + qcom_pas_handover(&adsp->q6v5); + + trace_rproc_qcom_event(dev_name(adsp->dev), "adsp_shutdown", "exit"); + + return ret; +} + +void adsp_set_ops_stop(struct rproc *rproc, bool suspend) +{ + struct qcom_adsp *adsp; + + adsp = (struct qcom_adsp *)rproc->priv; + qcom_sysmon_set_ops_stop(adsp->sysmon, suspend); + if (suspend) + rproc->ops->stop = adsp_shutdown; + else + rproc->ops->stop = adsp_stop; +} +EXPORT_SYMBOL_GPL(adsp_set_ops_stop); + static int adsp_attach(struct rproc *rproc) { struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c index 593a37b9210d..7e0c447eb26a 100644 --- a/drivers/remoteproc/qcom_sysmon.c +++ b/drivers/remoteproc/qcom_sysmon.c @@ -775,6 +775,51 @@ static void sysmon_stop(struct rproc_subdev *subdev, bool crashed) del_timer_sync(&sysmon->timeout_data.timer); } +static void sysmon_shutdown(struct rproc_subdev *subdev, bool crashed) +{ + unsigned long timeout; + struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon, subdev); + + trace_rproc_qcom_event(dev_name(sysmon->rproc->dev.parent), SYSMON_SUBDEV_NAME, + crashed ? "crash stop" : "stop"); + + sysmon->shutdown_acked = false; + + mutex_lock(&sysmon->state_lock); + sysmon->state = QCOM_SSR_BEFORE_SHUTDOWN; + + sysmon->transaction_id++; + dev_info(sysmon->dev, "Incrementing tid for %s to %d\n", sysmon->name, + sysmon->transaction_id); + + blocking_notifier_call_chain(&sysmon_notifiers, 0, (void *)sysmon); + mutex_unlock(&sysmon->state_lock); + + /* Don't request graceful shutdown if we've crashed */ + if (crashed) + return; + + sysmon->timeout_data.timer.function = sysmon_shutdown_notif_timeout_handler; + timeout = jiffies + msecs_to_jiffies(SYSMON_NOTIF_TIMEOUT); + mod_timer(&sysmon->timeout_data.timer, timeout); + + if (sysmon->ssctl_instance) { + if (!wait_for_completion_timeout(&sysmon->ssctl_comp, HZ / 2)) + dev_err(sysmon->dev, "timeout waiting for ssctl service\n"); + } + + del_timer_sync(&sysmon->timeout_data.timer); +} + +void qcom_sysmon_set_ops_stop(struct qcom_sysmon *sysmon, bool suspend) +{ + if (suspend) + sysmon->subdev.stop = sysmon_shutdown; + else + sysmon->subdev.stop = sysmon_stop; +} +EXPORT_SYMBOL_GPL(qcom_sysmon_set_ops_stop); + static void sysmon_unprepare(struct rproc_subdev *subdev) { struct qcom_sysmon *sysmon = container_of(subdev, struct qcom_sysmon, diff --git a/drivers/soc/qcom/power_state.c b/drivers/soc/qcom/power_state.c index b48f35c658fe..fd7fdfd4153e 100644 --- a/drivers/soc/qcom/power_state.c +++ b/drivers/soc/qcom/power_state.c @@ -124,6 +124,7 @@ static int subsys_suspend(struct subsystem_data *ss_data, struct rproc *rproc, u case SUBSYS_DEEPSLEEP: case SUBSYS_HIBERNATE: ss_data->ignore_ssr = true; + adsp_set_ops_stop(rproc, true); rproc_shutdown(rproc); ss_data->ignore_ssr = false; break; @@ -144,6 +145,7 @@ static int subsys_resume(struct subsystem_data *ss_data, struct rproc *rproc, u3 case SUBSYS_DEEPSLEEP: case SUBSYS_HIBERNATE: ss_data->ignore_ssr = true; + adsp_set_ops_stop(rproc, false); ret = rproc_boot(rproc); ss_data->ignore_ssr = false; break; diff --git a/include/linux/remoteproc/qcom_rproc.h b/include/linux/remoteproc/qcom_rproc.h index bb84ce48f58b..82c7e078cd42 100644 --- a/include/linux/remoteproc/qcom_rproc.h +++ b/include/linux/remoteproc/qcom_rproc.h @@ -61,6 +61,14 @@ static inline int qcom_rproc_set_dtb_firmware(struct rproc *rproc, const char *d { return -EINVAL; } + + +#endif + +#if IS_ENABLED(CONFIG_QCOM_Q6V5_PAS) +void adsp_set_ops_stop(struct rproc *rproc, bool suspend); +#else +static inline void adsp_set_ops_stop(struct rproc *rproc, bool suspend) { } #endif #endif From e85fdc7854d49da54c932d6c87303fe620063eae Mon Sep 17 00:00:00 2001 From: Ansa Ahmed Date: Wed, 27 Sep 2023 10:59:21 +0530 Subject: [PATCH 21/46] msm: adsprpc: Share initial debug config to DSP This change enables sharing of a new page to DSP. New page will contain initial debug parameters which we need to pass to the DSP during process initiation. Change-Id: Idb5793f2dc9fe3c0892c68da103abef9e3f3ea18 Acked-by: quic_anane Signed-off-by: Ansa Ahmed --- drivers/char/adsprpc.c | 49 ++++++++++++++++++++++++++++++++--- drivers/char/adsprpc_shared.h | 16 ++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 671a53a7eccd..7e7689225cd5 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -215,6 +215,12 @@ #define FASTRPC_USER_PD_FORCE_KILL 2 +/* + * No of pages shared with DSP during process init with + * First page for init-mem and second page for proc-attrs + */ +#define PAGESLEN_WITH_SHAREDBUF 2 + /* Unique index flag used for mini dump */ static int md_unique_index_flag[MAX_UNIQUE_ID] = { 0, 0, 0, 0, 0 }; @@ -3636,6 +3642,7 @@ int fastrpc_internal_invoke2(struct fastrpc_file *fl, struct fastrpc_ioctl_async_response async_res; uint32_t user_concurrency; struct fastrpc_ioctl_notif_rsp notif; + struct fastrpc_proc_sharedbuf_info buff_info; } p; struct fastrpc_dsp_capabilities *dsp_cap_ptr = NULL; uint32_t size = 0; @@ -3714,6 +3721,21 @@ int fastrpc_internal_invoke2(struct fastrpc_file *fl, err = fastrpc_get_notif_response(&p.notif, (void *)inv2->invparam, fl); break; + case FASTRPC_INVOKE2_PROC_SHAREDBUF_INFO: + VERIFY(err, + sizeof(struct fastrpc_proc_sharedbuf_info) >= inv2->size); + if (err) { + err = -EBADE; + goto bail; + } + K_COPY_FROM_USER(err, fl->is_compat, &p.buff_info, + (void *)inv2->invparam, inv2->size); + if (err) + goto bail; + + fl->sharedbuf_info.buf_fd = p.buff_info.buf_fd; + fl->sharedbuf_info.buf_size = p.buff_info.buf_size; + break; default: err = -ENOTTY; break; @@ -3814,7 +3836,8 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl, int err = 0, memlen = 0, mflags = 0, locked = 0; struct fastrpc_ioctl_invoke_async ioctl; struct fastrpc_ioctl_init *init = &uproc->init; - struct smq_phy_page pages[1]; + /* First page for init-mem and second page for proc-attrs */ + struct smq_phy_page pages[PAGESLEN_WITH_SHAREDBUF]; struct fastrpc_mmap *file = NULL; struct fastrpc_buf *imem = NULL; unsigned long imem_dma_attr = 0; @@ -3823,6 +3846,7 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl, unsigned int gid = 0, one_mb = 1024*1024; unsigned int dsp_userpd_memlen = 3 * one_mb; struct fastrpc_buf *init_mem; + struct fastrpc_mmap *sharedbuf_map = NULL; struct { int pgid; @@ -3934,11 +3958,23 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl, goto bail; fl->init_mem = imem; + inbuf.pageslen = 1; + if ((fl->sharedbuf_info.buf_fd != -1) && fl->sharedbuf_info.buf_size) { + mutex_lock(&fl->map_mutex); + err = fastrpc_mmap_create(fl, fl->sharedbuf_info.buf_fd, NULL, 0, + 0, fl->sharedbuf_info.buf_size, mflags, &sharedbuf_map); + mutex_unlock(&fl->map_mutex); + if (err) + goto bail; + + /* if shared buff is available send this as the second page and set pageslen as 2 */ + inbuf.pageslen = PAGESLEN_WITH_SHAREDBUF; + } + /* * Prepare remote arguments for dynamic process create * call to remote subsystem. */ - inbuf.pageslen = 1; ra[0].buf.pv = (void *)&inbuf; ra[0].buf.len = sizeof(inbuf); fds[0] = -1; @@ -3953,8 +3989,14 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl, pages[0].addr = imem->phys; pages[0].size = imem->size; + + /* Update IOVA of second page shared with DSP */ + if (inbuf.pageslen > 1) { + pages[1].addr = sharedbuf_map->phys; + pages[1].size = sharedbuf_map->size; + } ra[3].buf.pv = (void *)pages; - ra[3].buf.len = 1 * sizeof(*pages); + ra[3].buf.len = (inbuf.pageslen) * sizeof(*pages); fds[3] = -1; inbuf.attrs = uproc->attrs; @@ -6167,6 +6209,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) init_completion(&fl->dma_invoke); fl->file_close = FASTRPC_PROCESS_DEFAULT_STATE; filp->private_data = fl; + fl->sharedbuf_info.buf_fd = -1; mutex_init(&fl->internal_map_mutex); mutex_init(&fl->map_mutex); spin_lock_irqsave(&me->hlock, irq_flags); diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index aa6e7d50ffc9..b33b8d32f1b0 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -213,6 +213,15 @@ struct remote_buf { size_t len; /* length of buffer */ }; +/* structure to hold fd and size of buffer shared with DSP, + * which contains initial debug parameters that needs to be passed + * during process initialization. + */ +struct fastrpc_proc_sharedbuf_info { + int buf_fd; + int buf_size; +}; + struct remote_dma_handle { int fd; uint32_t offset; @@ -310,6 +319,7 @@ enum fastrpc_invoke2_type { FASTRPC_INVOKE2_ASYNC_RESPONSE = 2, FASTRPC_INVOKE2_KERNEL_OPTIMIZATIONS, FASTRPC_INVOKE2_STATUS_NOTIF, + FASTRPC_INVOKE2_PROC_SHAREDBUF_INFO, }; struct fastrpc_ioctl_invoke2 { @@ -1119,6 +1129,12 @@ struct fastrpc_file { bool exit_notif; /* Flag to indicate async thread exit requested*/ bool exit_async; + /* + * structure to hold fd and size of buffer shared with DSP, + * which contains initial debug configurations and other initial + * config parameters. + */ + struct fastrpc_proc_sharedbuf_info sharedbuf_info; }; union fastrpc_ioctl_param { From 52e69646a2105219dfe40836ef096fcc76523ef1 Mon Sep 17 00:00:00 2001 From: jianshu Date: Tue, 14 Nov 2023 10:54:32 +0800 Subject: [PATCH 22/46] ice_driver: Fix the ice keyslot conflict FDE only use one ice keyslot on gen3, the remains used by FBE. For the ufs crypto layer, it needs to support FBE and FDE request concurrently. Test cases: 1. LV host FDE OTA and basic test validated pass 2. LA container FBE OTA and basic test validated pass. Change-Id: Ic0c6e0f9d39d351c1095f531f1fa8bd2a8e614b7 Signed-off-by: jianshu --- drivers/scsi/ufs/ufs-qcom.c | 20 +++++++++++++------- drivers/scsi/ufs/ufshcd-crypto-qti.c | 23 +++++++++++++++++++++-- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 2e43703308d2..cf633d574605 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -5402,14 +5402,20 @@ static void ufs_qcom_hook_prepare_command(void *param, struct ufs_hba *hba, #if IS_ENABLED(CONFIG_QTI_CRYPTO_FDE) struct ice_data_setting setting; - if (!crypto_qti_ice_config_start(rq, &setting)) { - if ((rq_data_dir(rq) == WRITE) ? setting.encr_bypass : setting.decr_bypass) { - lrbp->crypto_key_slot = -1; - } else { - lrbp->crypto_key_slot = setting.crypto_data.key_index; - lrbp->data_unit_num = rq->bio->bi_iter.bi_sector >> - ICE_CRYPTO_DATA_UNIT_4_KB; + if (!rq->crypt_keyslot) { + if (!crypto_qti_ice_config_start(rq, &setting)) { + if ((rq_data_dir(rq) == WRITE) ? setting.encr_bypass : + setting.decr_bypass) { + lrbp->crypto_key_slot = -1; + } else { + lrbp->crypto_key_slot = setting.crypto_data.key_index; + lrbp->data_unit_num = rq->bio->bi_iter.bi_sector >> + ICE_CRYPTO_DATA_UNIT_4_KB; + } } + } else { + lrbp->crypto_key_slot = blk_ksm_get_slot_idx(rq->crypt_keyslot); + lrbp->data_unit_num = rq->crypt_ctx->bc_dun[0]; } #endif } diff --git a/drivers/scsi/ufs/ufshcd-crypto-qti.c b/drivers/scsi/ufs/ufshcd-crypto-qti.c index cd17134841f2..1654ebe43cd8 100644 --- a/drivers/scsi/ufs/ufshcd-crypto-qti.c +++ b/drivers/scsi/ufs/ufshcd-crypto-qti.c @@ -186,6 +186,7 @@ int ufshcd_qti_hba_init_crypto_capabilities(struct ufs_hba *hba) { int cap_idx; int err = 0; + unsigned int max_slots = 0; enum blk_crypto_mode_num blk_mode_num; /* @@ -212,9 +213,27 @@ int ufshcd_qti_hba_init_crypto_capabilities(struct ufs_hba *hba) goto out; } + max_slots = hba->crypto_capabilities.config_count + 1; +#if IS_ENABLED(CONFIG_QTI_CRYPTO_FDE) + if (max_slots > crypto_qti_ice_get_num_fde_slots()) { + /* + * Reduce the total number of slots available to FBE + * (by the number reserved for the FDE) + * Check at least one slot for backward compatibility, + * otherwise return failure + */ + if (max_slots - crypto_qti_ice_get_num_fde_slots() < 1) { + pr_err("%s: Too much slots allocated to fde\n", __func__); + err = -EINVAL; + goto out; + } else { + max_slots = max_slots - crypto_qti_ice_get_num_fde_slots(); + } + } +#endif + /* The actual number of configurations supported is (CFGC+1) */ - err = devm_blk_ksm_init(hba->dev, &hba->ksm, - hba->crypto_capabilities.config_count + 1); + err = devm_blk_ksm_init(hba->dev, &hba->ksm, max_slots); if (err) goto out; From ab126178dcd94d1419ae8cc1bb21d22f49d3412a Mon Sep 17 00:00:00 2001 From: Xiaoqi Zhuang Date: Wed, 20 Dec 2023 10:04:10 +0800 Subject: [PATCH 23/46] coresight: ETR: Disable BAM SMMU when mapping config is set as bypass BAM SMMU should be disabled when mapping config is set as bypass. Change-Id: If92cd1ed23ada0473fc7e8dea0adf35a88980ce0 Signed-off-by: Xiaoqi Zhuang --- drivers/hwtracing/coresight/coresight-tmc-usb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-usb.c b/drivers/hwtracing/coresight/coresight-tmc-usb.c index c0c5242fb2ed..e1659313d759 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-usb.c +++ b/drivers/hwtracing/coresight/coresight-tmc-usb.c @@ -775,10 +775,12 @@ int tmc_etr_usb_init(struct amba_device *adev, mapping_config = qcom_iommu_get_mappings_configuration(domain); if (mapping_config < 0) return -ENOMEM; - if (!(mapping_config & QCOM_IOMMU_MAPPING_CONF_S1_BYPASS)) + if (!(mapping_config & QCOM_IOMMU_MAPPING_CONF_S1_BYPASS)) { pr_debug("%s: setting SPS_BAM_SMMU_EN flag with (%s)\n", __func__, dev_name(dev)); - bamdata->props.options |= SPS_BAM_SMMU_EN; + + bamdata->props.options |= SPS_BAM_SMMU_EN; + } } return sps_register_bam_device(&bamdata->props, &bamdata->handle); From 0d30a26909e9383e9b75aab74d63cf08980f315a Mon Sep 17 00:00:00 2001 From: Ansa Ahmed Date: Wed, 27 Sep 2023 16:59:46 +0530 Subject: [PATCH 24/46] msm: adsprpc: Allocate designated context bank session Currently SMMU context banks are chosen dynamically based on available context bank. Few use cases requires context banks to be fixed to retain SMMU mappings even after process exits and resumes again. Few other use cases requires to use multiple context banks of similar remote subsystem process types. Allocate designated context bank session with process type matching with remote subsystem process type. Change-Id: Ie8ccad2fde4e2e21aaf8c6ede0ab31645cdf350c Acked-by: Santosh Sakore Signed-off-by: Ansa Ahmed --- drivers/char/adsprpc.c | 109 ++++++++++++++++++++++++++++++---- drivers/char/adsprpc_shared.h | 31 ++++++++++ 2 files changed, 129 insertions(+), 11 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 7e7689225cd5..e458d0676132 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -1108,8 +1108,8 @@ bail: kfree(map); } -static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure, - int sharedcb, struct fastrpc_session_ctx **session); +static int fastrpc_session_alloc_secure_memory(struct fastrpc_channel_ctx *chan, int secure, + int sharedcb, int pd_type, struct fastrpc_session_ctx **session); static inline bool fastrpc_get_persistent_map(size_t len, struct fastrpc_mmap **pers_map) { @@ -1299,11 +1299,11 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, struct dma_buf * map->secure = (mem_buf_dma_buf_exclusive_owner(map->buf)) ? 0 : 1; if (map->secure) { if (!fl->secsctx) - err = fastrpc_session_alloc(chan, 1, 0, - &fl->secsctx); + err = fastrpc_session_alloc_secure_memory(chan, 1, 0, + fl->pd_type, &fl->secsctx); if (err) { ADSPRPC_ERR( - "fastrpc_session_alloc failed for fd %d ret %d\n", + "fastrpc_session_alloc_secure_memory failed for fd %d ret %d\n", fd, err); err = -ENOSR; goto bail; @@ -3561,6 +3561,54 @@ bail: return err; } +static int fastrpc_set_session_info( + struct fastrpc_proc_sess_info *sess_info, + void *param, struct fastrpc_file *fl) +{ + int err = 0; + struct fastrpc_apps *me = &gfa; + + /* + * Third-party apps don't have permission to open the fastrpc device, so + * it is opened on their behalf by DSP HAL. This is detected by + * comparing current PID with the one stored during device open. + */ + if (current->tgid != fl->tgid_open) + fl->untrusted_process = true; + VERIFY(err, sess_info->pd_type > DEFAULT_UNUSED && + sess_info->pd_type < MAX_PD_TYPE); + if (err) { + ADSPRPC_ERR( + "Session PD type %u is invalid for the process\n", + sess_info->pd_type); + err = -EBADR; + goto bail; + } + if (fl->untrusted_process && sess_info->pd_type != USERPD) { + ADSPRPC_ERR( + "Session PD type %u not allowed for untrusted process\n", + sess_info->pd_type); + err = -EBADR; + goto bail; + } + /* + * If PD type is not configured for context banks, + * ignore PD type passed by the user, leave pd_type set to DEFAULT_UNUSED(0) + */ + if (me->cb_pd_type) + fl->pd_type = sess_info->pd_type; + // Processes attaching to Sensor Static PD, share context bank. + if (sess_info->pd_type == SENSORS_STATICPD) + fl->sharedcb = 1; + VERIFY(err, 0 == (err = fastrpc_get_info(fl, &(sess_info->domain_id)))); + if (err) + goto bail; + K_COPY_TO_USER(err, 0, param, sess_info, + sizeof(struct fastrpc_proc_sess_info)); +bail: + return err; +} + static int fastrpc_create_persistent_headers(struct fastrpc_file *fl, uint32_t user_concurrency) { @@ -3643,6 +3691,7 @@ int fastrpc_internal_invoke2(struct fastrpc_file *fl, uint32_t user_concurrency; struct fastrpc_ioctl_notif_rsp notif; struct fastrpc_proc_sharedbuf_info buff_info; + struct fastrpc_proc_sess_info sess_info; } p; struct fastrpc_dsp_capabilities *dsp_cap_ptr = NULL; uint32_t size = 0; @@ -3736,6 +3785,20 @@ int fastrpc_internal_invoke2(struct fastrpc_file *fl, fl->sharedbuf_info.buf_fd = p.buff_info.buf_fd; fl->sharedbuf_info.buf_size = p.buff_info.buf_size; break; + case FASTRPC_INVOKE2_SESS_INFO: + VERIFY(err, + sizeof(struct fastrpc_proc_sess_info) >= inv2->size); + if (err) { + err = -EBADE; + goto bail; + } + K_COPY_FROM_USER(err, fl->is_compat, &p.sess_info, + (void *)inv2->invparam, inv2->size); + if (err) + goto bail; + err = fastrpc_set_session_info(&p.sess_info, + (void *)inv2->invparam, fl); + break; default: err = -ENOTTY; break; @@ -5473,17 +5536,23 @@ int fastrpc_internal_mmap(struct fastrpc_file *fl, static void fastrpc_context_list_dtor(struct fastrpc_file *fl); static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan, - int secure, int sharedcb, struct fastrpc_session_ctx **session) + int secure, int sharedcb, int pd_type, struct fastrpc_session_ctx **session) { struct fastrpc_apps *me = &gfa; uint64_t idx = 0; int err = 0; + /* + * PD type can be either unused(DEFAULT_UNUSED) (or) if PD type + * is used, choose the context bank with matching PD type. + */ if (chan->sesscount) { for (idx = 0; idx < chan->sesscount; ++idx) { if (!chan->session[idx].used && chan->session[idx].smmu.secure == secure && - chan->session[idx].smmu.sharedcb == sharedcb) { + chan->session[idx].smmu.sharedcb == sharedcb && + (pd_type == DEFAULT_UNUSED || + chan->session[idx].smmu.pd_type == pd_type)) { chan->session[idx].used = 1; break; } @@ -5674,14 +5743,22 @@ bail: return err; } -static int fastrpc_session_alloc(struct fastrpc_channel_ctx *chan, int secure, - int sharedcb, struct fastrpc_session_ctx **session) +static int fastrpc_session_alloc_secure_memory(struct fastrpc_channel_ctx *chan, int secure, + int sharedcb, int pd_type, struct fastrpc_session_ctx **session) { int err = 0; + struct fastrpc_apps *me = &gfa; + + /* + * If PD type is configured for context banks, + * Use CPZ_USERPD, to allocate secure context bank type. + */ + if (pd_type != DEFAULT_UNUSED && me->cb_pd_type) + pd_type = CPZ_USERPD; mutex_lock(&chan->smd_mutex); if (!*session) - err = fastrpc_session_alloc_locked(chan, secure, sharedcb, session); + err = fastrpc_session_alloc_locked(chan, secure, sharedcb, pd_type, session); mutex_unlock(&chan->smd_mutex); if (err == -EUSERS) { ADSPRPC_WARN( @@ -6192,6 +6269,8 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) INIT_HLIST_NODE(&fl->hn); fl->sessionid = 0; fl->tgid_open = current->tgid; + /* PD type is not known, when device is opened */ + fl->pd_type = DEFAULT_UNUSED; fl->apps = me; fl->mode = FASTRPC_MODE_SERIAL; fl->cid = -1; @@ -6358,7 +6437,7 @@ int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info) fl->ssrcount = fl->apps->channel[cid].ssrcount; mutex_lock(&fl->apps->channel[cid].smd_mutex); err = fastrpc_session_alloc_locked(&fl->apps->channel[cid], - 0, fl->sharedcb, &fl->sctx); + 0, fl->sharedcb, fl->pd_type, &fl->sctx); mutex_unlock(&fl->apps->channel[cid].smd_mutex); if (err == -EUSERS) { ADSPRPC_WARN( @@ -7767,6 +7846,14 @@ static int fastrpc_cb_probe(struct device *dev) me->max_size_limit = (dma_addr_pool[1] == 0 ? 0x78000000 : dma_addr_pool[1]); + if (of_get_property(dev->of_node, "pd-type", NULL) != NULL) { + err = of_property_read_u32(dev->of_node, "pd-type", + &(sess->smmu.pd_type)); + if (err) + goto bail; + // Set cb_pd_type, if the process type is configured for context banks + me->cb_pd_type = true; + } if (of_get_property(dev->of_node, "shared-cb", NULL) != NULL) { sess->smmu.sharedcb = 1; err = of_property_read_u32(dev->of_node, "shared-cb", diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index b33b8d32f1b0..1e2f9473aeb5 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -305,6 +305,14 @@ struct fastrpc_ioctl_notif_rsp { uint32_t status; /* Status of the process */ }; +/* FastRPC ioctl structure to set session related info */ +struct fastrpc_proc_sess_info { + uint32_t domain_id; /* Set the remote subsystem, Domain ID of the session */ + uint32_t session_id; /* Unused, Set the Session ID on remote subsystem */ + uint32_t pd_type; /* Set the process type on remote subsystem */ + uint32_t sharedcb; /* Unused, Session can share context bank with other sessions */ +}; + /* INIT a new process or attach to guestos */ enum fastrpc_init_flags { FASTRPC_INIT_NO_CREATE = -1, @@ -320,6 +328,8 @@ enum fastrpc_invoke2_type { FASTRPC_INVOKE2_KERNEL_OPTIMIZATIONS, FASTRPC_INVOKE2_STATUS_NOTIF, FASTRPC_INVOKE2_PROC_SHAREDBUF_INFO, + /* Set session info of remote sub system */ + FASTRPC_INVOKE2_SESS_INFO, }; struct fastrpc_ioctl_invoke2 { @@ -720,6 +730,21 @@ struct gid_list { unsigned int gidcount; }; +/* + * Process types on remote subsystem + * Always add new PD types at the end, before MAX_PD_TYPE + */ +#define DEFAULT_UNUSED 0 /* pd type not configured for context banks */ +#define ROOT_PD 1 /* Root PD */ +#define AUDIO_STATICPD 2 /* ADSP Audio Static PD */ +#define SENSORS_STATICPD 3 /* ADSP Sensors Static PD */ +#define SECURE_STATICPD 4 /* CDSP Secure Static PD */ +#define OIS_STATICPD 5 /* ADSP OIS Static PD */ +#define CPZ_USERPD 6 /* CDSP CPZ USER PD */ +#define USERPD 7 /* DSP User Dynamic PD */ +#define GUEST_OS_SHARED 8 /* Legacy Guest OS Shared */ +#define MAX_PD_TYPE 9 /* Max PD type */ + struct fastrpc_file; struct fastrpc_buf { @@ -860,6 +885,8 @@ struct fastrpc_smmu { int secure; int coherent; int sharedcb; + /* Process type on remote sub system */ + int pd_type; /* gen pool for QRTR */ struct gen_pool *frpc_genpool; /* fastrpc gen pool buffer */ @@ -966,6 +993,8 @@ struct fastrpc_apps { unsigned int lowest_capacity_core_count; /* Flag to check if PM QoS vote needs to be done for only one core */ bool single_core_latency_vote; + /* Indicates process type is configured for SMMU context bank */ + bool cb_pd_type; }; struct fastrpc_mmap { @@ -1074,6 +1103,8 @@ struct fastrpc_file { int file_close; int dsp_proc_init; int sharedcb; + /* Process type on remote sub system */ + int pd_type; struct fastrpc_apps *apps; struct dentry *debugfs_file; struct dev_pm_qos_request *dev_pm_qos_req; From 75619d91a6f99f76a1de5f892ff68911166a2de9 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Wed, 27 Sep 2023 12:09:19 +0530 Subject: [PATCH 25/46] soc: qcom: rpmh-rsc: Add delay during waiting for TCS complete The RSC channel switch in certain cases may take more time to complete at RPMH end. Add delay of maximum 100usec. Change-Id: I65862ad80fbb698e6b66e2038a7692c4b78c2ce9 Signed-off-by: Maulik Shah --- drivers/soc/qcom/rpmh-rsc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 71a5a5452a6e..05775e056952 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -1218,6 +1218,13 @@ int rpmh_rsc_is_tcs_completed(struct rsc_drv *drv, int ch) sts &= CH1_WAKE_TCS_STATUS; retry--; + /* + * Wait till all the WAKE votes of the new channel are + * applied during channel switch. + * Maximum delay of 100 usec. + */ + if (!sts) + udelay(10); } while (!sts && retry); if (!retry) { From d051a7c61f161482abcf28b14e9461fb10be3d80 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Wed, 18 Oct 2023 12:47:45 +0530 Subject: [PATCH 26/46] soc: qcom: rpmh: Do not use spin_trylock() rpmh_flush() is called for APPS RSC only from last CPU entering power down. spin_trylock() was used to abort flushing as it would mean another CPU is already up. However rpmh_flush() may get invoked by other RSCes too and may fail if another CPU is holding lock. Fix by removing spin_trylock(). Change-Id: Ic94f6bcb9a762e02ccfb98c79f6181f20ee67915 Signed-off-by: Maulik Shah --- drivers/soc/qcom/rpmh.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index 9c5d87a27872..d1494d7033af 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c @@ -445,6 +445,7 @@ int _rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch) */ int rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch) { + unsigned long flags; int ret; if (rpmh_standalone) @@ -464,14 +465,9 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch) if (!(ctrlr->flags & SOLVER_PRESENT)) lockdep_assert_irqs_disabled(); - /* - * If the lock is busy it means another transaction is on going, - * in such case it's better to abort than spin. - */ - if (!spin_trylock(&ctrlr->cache_lock)) - return -EBUSY; + spin_lock_irqsave(&ctrlr->cache_lock, flags); ret = _rpmh_flush(ctrlr, ch); - spin_unlock(&ctrlr->cache_lock); + spin_unlock_irqrestore(&ctrlr->cache_lock, flags); return ret; } From 54541d5e952f5469c4f13e32d0be5af6f3f8de65 Mon Sep 17 00:00:00 2001 From: Pradnya Dahiwale Date: Wed, 13 Dec 2023 13:41:39 +0530 Subject: [PATCH 27/46] remoteproc: Add check for tzapp coredump cmd response status Add check for tzapp coredump cmd response status in AoN subsystem. This check is to confirm whether dumps are written successfully. Change-Id: Idc452fc1d1e24d25cf4b95d642b68af8a8dd059d Signed-off-by: Pradnya Dahiwale --- drivers/remoteproc/qcom_rproc_slate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/remoteproc/qcom_rproc_slate.c b/drivers/remoteproc/qcom_rproc_slate.c index 5413d357e72a..ded6828a95ec 100644 --- a/drivers/remoteproc/qcom_rproc_slate.c +++ b/drivers/remoteproc/qcom_rproc_slate.c @@ -757,7 +757,7 @@ static void slate_coredump(struct rproc *rproc) slate_tz_req.address_fw = start_addr; slate_tz_req.size_fw = size; ret = slate_tzapp_comm(slate_data, &slate_tz_req); - if (ret != 0) { + if (ret != 0 || slate_data->cmd_status) { dev_dbg(slate_data->dev, "%s: SLATE RPROC ramdmp collection failed\n", __func__); From 9576c8ce3f1dc97c432c4b1a5921771bfeeda446 Mon Sep 17 00:00:00 2001 From: Praveen koya Date: Tue, 19 Dec 2023 16:13:03 +0530 Subject: [PATCH 28/46] soc: qcom: sanity check for aon_com_dev node Add sanity check to handle write operation on aon_com_dev node from userspace when driver is not initialized. Change-Id: I1bd1fb94ee5b59ff113f8e359c303a2dd1f47430 Signed-off-by: Praveen koya --- drivers/soc/qcom/slatecom_interface.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/slatecom_interface.c b/drivers/soc/qcom/slatecom_interface.c index bb324d73c2b8..d7b52fbca779 100644 --- a/drivers/soc/qcom/slatecom_interface.c +++ b/drivers/soc/qcom/slatecom_interface.c @@ -1051,10 +1051,15 @@ static ssize_t slatecom_char_write(struct file *f, const char __user *buf, unsigned char qcli_cmnd; uint32_t opcode; int ret = 0; - struct slatedaemon_priv *dev = container_of(slatecom_intf_drv, + struct slatedaemon_priv *dev = NULL; + + if (!slatecom_intf_drv) { + pr_err("Invalid use-case, slatecom driver is not ready\n"); + return -EINVAL; + } + dev = container_of(slatecom_intf_drv, struct slatedaemon_priv, lhndl); - if (copy_from_user(&qcli_cmnd, buf, sizeof(unsigned char))) return -EFAULT; From b40e47367dd08638791224a11a106dc57a66fc10 Mon Sep 17 00:00:00 2001 From: Ansa Ahmed Date: Tue, 3 Oct 2023 14:21:40 +0530 Subject: [PATCH 29/46] msm: adsprpc: Support multiple sessions per process Currently a process is limited to create only 2 sessions, by toggling the 30th bit of tgid of the process, to create different process IDs on DSP remote sybsystem. This approach is not scalable to create unique process IDs to DSP, by using bits within the tgid of the process. Add support to allow a process to create multiple sessions by choosing and sending unique dsp process IDs on DSP remote sub system, instead of tgid of HLOS process. Change-Id: I33f52c68453301bdbb83dfb9a10df16143098a49 Acked-by: Santosh Sakore Signed-off-by: Ansa Ahmed --- drivers/char/adsprpc.c | 167 ++++++++++++++++++++++++++-------- drivers/char/adsprpc_shared.h | 11 +++ 2 files changed, 139 insertions(+), 39 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index e458d0676132..53e9328fda72 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -103,9 +103,6 @@ #define M_KERNEL_PERF_LIST (PERF_KEY_MAX) #define M_DSP_PERF_LIST (12) -#define SESSION_ID_INDEX (30) -#define SESSION_ID_MASK (1 << SESSION_ID_INDEX) -#define PROCESS_ID_MASK ((2^SESSION_ID_INDEX) - 1) #define FASTRPC_CTX_MAGIC (0xbeeddeed) /* Process status notifications from DSP will be sent with this unique context */ @@ -198,6 +195,9 @@ /* Max no. of persistent headers pre-allocated per process */ #define MAX_PERSISTENT_HEADERS (25) +/* Max value of the unique fastrpc tgid */ +#define MAX_FRPC_TGID 256 + #define PERF_CAPABILITY_SUPPORT (1 << 1) #define KERNEL_ERROR_CODE_V1_SUPPORT 1 #define USERSPACE_ALLOCATION_SUPPORT 1 @@ -224,6 +224,9 @@ /* Unique index flag used for mini dump */ static int md_unique_index_flag[MAX_UNIQUE_ID] = { 0, 0, 0, 0, 0 }; +/* Array to keep track unique tgid_frpc usage */ +static bool frpc_tgid_usage_array[MAX_FRPC_TGID] = {0}; + /* Fastrpc remote process attributes */ enum fastrpc_proc_attr { /* Macro for Debug attr */ @@ -1872,6 +1875,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, } ctx->retval = -1; ctx->pid = current->pid; + /* Store HLOS PID in context, it is not being sent to DSP */ ctx->tgid = fl->tgid; init_completion(&ctx->work); ctx->magic = FASTRPC_CTX_MAGIC; @@ -1889,6 +1893,10 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, goto bail; } memset(ctx->perf, 0, sizeof(*(ctx->perf))); + /* + * Use HLOS PID, as perf tid is not being sent + * to DSP and is used to log in traces. + */ ctx->perf->tid = fl->tgid; } if (invokefd->job) { @@ -2066,13 +2074,11 @@ static void fastrpc_notif_find_process(int domain, struct smq_notif_rspv3 *notif struct fastrpc_file *fl = NULL; struct hlist_node *n; bool is_process_found = false; - int sessionid = 0; unsigned long irq_flags = 0; spin_lock_irqsave(&me->hlock, irq_flags); hlist_for_each_entry_safe(fl, n, &me->drivers, hn) { - if (fl->tgid == notif->pid || - (fl->tgid == (notif->pid & PROCESS_ID_MASK))) { + if (fl->tgid_frpc == notif->pid) { is_process_found = true; break; } @@ -2081,9 +2087,7 @@ static void fastrpc_notif_find_process(int domain, struct smq_notif_rspv3 *notif if (!is_process_found) return; - if (notif->pid & SESSION_ID_MASK) - sessionid = 1; - fastrpc_queue_pd_status(fl, domain, notif->status, sessionid); + fastrpc_queue_pd_status(fl, domain, notif->status, fl->sessionid); } static void context_notify_user(struct smq_invoke_ctx *ctx, @@ -2915,10 +2919,9 @@ static int fastrpc_invoke_send(struct smq_invoke_ctx *ctx, channel_ctx = &fl->apps->channel[cid]; mutex_lock(&channel_ctx->smd_mutex); - msg->pid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + msg->pid = fl->tgid_frpc; msg->tid = current->pid; - if (fl->sessionid) - msg->tid |= SESSION_ID_MASK; if (kernel == KERNEL_MSG_WITH_ZERO_PID) msg->pid = 0; msg->invoke.header.ctx = ctx->ctxid | fl->pd; @@ -3002,6 +3005,7 @@ static void fastrpc_init(struct fastrpc_apps *me) spin_lock_init(&me->hlock); me->channel = &gcinfo[0]; mutex_init(&me->mut_uid); + me->max_sess_per_proc = DEFAULT_MAX_SESS_PER_PROC; for (i = 0; i < NUM_CHANNELS; i++) { init_completion(&me->channel[i].work); init_completion(&me->channel[i].workport); @@ -3568,6 +3572,12 @@ static int fastrpc_set_session_info( int err = 0; struct fastrpc_apps *me = &gfa; + if (fl->set_session_info) { + ADSPRPC_ERR("Set session info invoked multiple times\n"); + err = -EBADR; + goto bail; + } + /* * Third-party apps don't have permission to open the fastrpc device, so * it is opened on their behalf by DSP HAL. This is detected by @@ -3600,6 +3610,16 @@ static int fastrpc_set_session_info( // Processes attaching to Sensor Static PD, share context bank. if (sess_info->pd_type == SENSORS_STATICPD) fl->sharedcb = 1; + if (sess_info->session_id >= me->max_sess_per_proc) { + ADSPRPC_ERR( + "Session ID %u cannot be beyond %u\n", + sess_info->session_id, me->max_sess_per_proc); + err = -EBADR; + goto bail; + } + fl->sessionid = sess_info->session_id; + // Set multi_session_support, to disable old way of setting session_id + fl->multi_session_support = true; VERIFY(err, 0 == (err = fastrpc_get_info(fl, &(sess_info->domain_id)))); if (err) goto bail; @@ -3849,7 +3869,7 @@ static int fastrpc_mmap_remove_ssr(struct fastrpc_file *fl, int locked); static int fastrpc_init_attach_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init *init) { - int err = 0, tgid = fl->tgid; + int err = 0, tgid = fl->tgid_frpc; remote_arg_t ra[1]; struct fastrpc_ioctl_invoke_async ioctl; @@ -3862,6 +3882,7 @@ static int fastrpc_init_attach_process(struct fastrpc_file *fl, /* * Prepare remote arguments for creating thread group * in guestOS/staticPD on the remote subsystem. + * Send unique fastrpc id to dsp */ ra[0].buf.pv = (void *)&tgid; ra[0].buf.len = sizeof(tgid); @@ -3930,7 +3951,7 @@ static int fastrpc_init_create_dynamic_process(struct fastrpc_file *fl, fl->dsp_process_state = PROCESS_CREATE_IS_INPROGRESS; spin_unlock(&fl->hlock); - inbuf.pgid = fl->tgid; + inbuf.pgid = fl->tgid_frpc; inbuf.namelen = strlen(current->comm) + 1; inbuf.filelen = init->filelen; fl->pd = 1; @@ -4174,7 +4195,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_file *fl, } fl->pd = 1; - inbuf.pgid = fl->tgid; + inbuf.pgid = fl->tgid_frpc; inbuf.namelen = init->filelen; inbuf.pageslen = 0; @@ -4628,7 +4649,8 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl) err = -ECONNRESET; goto bail; } - tgid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + tgid = fl->tgid_frpc; ra[0].buf.pv = (void *)&tgid; ra[0].buf.len = sizeof(tgid); ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP; @@ -4687,7 +4709,8 @@ static int fastrpc_mem_map_to_dsp(struct fastrpc_file *fl, int fd, int offset, uint64_t vaddrout; } routargs; - inargs.pid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + inargs.pid = fl->tgid_frpc; inargs.fd = fd; inargs.offset = offset; inargs.vaddrin = (uintptr_t)va; @@ -4738,7 +4761,8 @@ static int fastrpc_mem_unmap_to_dsp(struct fastrpc_file *fl, int fd, uint64_t len; } inargs; - inargs.pid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + inargs.pid = fl->tgid_frpc; inargs.fd = fd; inargs.vaddrin = (uint64_t)va; inargs.len = (uint64_t)size; @@ -4774,7 +4798,8 @@ static int fastrpc_unmap_on_dsp(struct fastrpc_file *fl, size_t size; } inargs; - inargs.pid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + inargs.pid = fl->tgid_frpc; inargs.size = size; inargs.vaddrout = raddr; ra[0].buf.pv = (void *)&inargs; @@ -4826,7 +4851,8 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags, goto bail; } cid = fl->cid; - inargs.pid = fl->tgid; + /* Send unique fastrpc process ID to dsp */ + inargs.pid = fl->tgid_frpc; inargs.vaddrin = (uintptr_t)va; inargs.flags = flags; inargs.num = fl->apps->compat ? num * sizeof(page) : num; @@ -5604,7 +5630,11 @@ static void handle_remote_signal(uint64_t msg, int cid) spin_lock_irqsave(&me->hlock, irq_flags); hlist_for_each_entry_safe(fl, n, &me->drivers, hn) { - if ((fl->tgid == pid) && (fl->cid == cid)) { + /* + * Response from DSP contains unique fastrpc process id, + * use unique fastrpc process ID to compare. + */ + if ((fl->tgid_frpc == pid) && (fl->cid == cid)) { unsigned long fflags = 0; spin_lock_irqsave(&fl->dspsignals_lock, fflags); @@ -5825,6 +5855,9 @@ skip_dump_wait: fl->is_ramdump_pend = false; fl->is_dma_invoke_pend = false; fl->dsp_process_state = PROCESS_CREATE_DEFAULT; + /* Reset the tgid usage to false */ + if (fl->tgid_frpc != -1) + frpc_tgid_usage_array[fl->tgid_frpc] = false; is_locked = false; spin_unlock_irqrestore(&fl->apps->hlock, irq_flags); @@ -6274,6 +6307,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->apps = me; fl->mode = FASTRPC_MODE_SERIAL; fl->cid = -1; + fl->tgid_frpc = -1; fl->dev_minor = dev_minor; fl->init_mem = NULL; fl->qos_request = 0; @@ -6284,6 +6318,8 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fl->is_compat = false; fl->exit_notif = false; fl->exit_async = false; + fl->multi_session_support = false; + fl->set_session_info = false; init_completion(&fl->work); init_completion(&fl->dma_invoke); fl->file_close = FASTRPC_PROCESS_DEFAULT_STATE; @@ -6332,6 +6368,25 @@ bail: return err; } +// Generate a unique process ID to DSP process +static int get_unique_hlos_process_id(void) +{ + int tgid_frpc = -1, tgid_index = 1; + struct fastrpc_apps *me = &gfa; + + spin_lock(&me->hlock); + for (tgid_index = 1; tgid_index < MAX_FRPC_TGID; tgid_index++) { + if (!frpc_tgid_usage_array[tgid_index]) { + tgid_frpc = tgid_index; + /* Set the tgid usage to false */ + frpc_tgid_usage_array[tgid_index] = true; + break; + } + } + spin_unlock(&me->hlock); + return tgid_frpc; +} + static int fastrpc_set_process_info(struct fastrpc_file *fl, uint32_t cid) { int err = 0, buf_size = 0; @@ -6341,6 +6396,13 @@ static int fastrpc_set_process_info(struct fastrpc_file *fl, uint32_t cid) memcpy(cur_comm, current->comm, TASK_COMM_LEN); cur_comm[TASK_COMM_LEN-1] = '\0'; fl->tgid = current->tgid; + fl->tgid_frpc = get_unique_hlos_process_id(); + VERIFY(err, fl->tgid_frpc != -1); + if (err) { + ADSPRPC_ERR("too many fastrpc clients, max %u allowed\n", MAX_FRPC_TGID); + err = -EUSERS; + goto bail; + } /* * Third-party apps don't have permission to open the fastrpc device, so @@ -6373,8 +6435,12 @@ static int fastrpc_set_process_info(struct fastrpc_file *fl, uint32_t cid) err = -ENOMEM; return err; } - snprintf(fl->debug_buf, buf_size, "%.10s%s%d%s%d", - cur_comm, "_", current->pid, "_", cid); + /* + * Use HLOS PID, unique fastrpc PID, CID in debugfs filename, + * for better ability to debug. + */ + snprintf(fl->debug_buf, buf_size, "%.10s%s%d%s%d%s%d", + cur_comm, "_", current->pid, "_", fl->tgid_frpc, "_", cid); fl->debugfs_file = debugfs_create_file(fl->debug_buf, 0644, debugfs_root, fl, &debugfs_fops); if (IS_ERR_OR_NULL(fl->debugfs_file)) { @@ -6400,6 +6466,21 @@ int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info) err = -EBADF; goto bail; } + spin_lock(&fl->hlock); + if (fl->set_session_info) { + spin_unlock(&fl->hlock); + ADSPRPC_ERR("Set session info invoked multiple times\n"); + err = -EBADR; + goto bail; + } + // Set set_session_info to true + fl->set_session_info = true; + spin_unlock(&fl->hlock); + VERIFY(err, VALID_FASTRPC_CID(cid)); + if (err) { + err = -ECHRNG; + goto bail; + } fastrpc_get_process_gids(&fl->gidlist); err = fastrpc_set_process_info(fl, cid); @@ -6494,7 +6575,6 @@ int fastrpc_internal_control(struct fastrpc_file *fl, int err = 0; unsigned int latency; struct fastrpc_apps *me = &gfa; - int sessionid = 0; unsigned int cpu; unsigned long flags = 0; @@ -6590,9 +6670,7 @@ int fastrpc_internal_control(struct fastrpc_file *fl, break; case FASTRPC_CONTROL_DSPPROCESS_CLEAN: (void)fastrpc_release_current_dsp_process(fl); - if (fl->tgid & SESSION_ID_MASK) - sessionid = 1; - fastrpc_queue_pd_status(fl, fl->cid, FASTRPC_USER_PD_FORCE_KILL, sessionid); + fastrpc_queue_pd_status(fl, fl->cid, FASTRPC_USER_PD_FORCE_KILL, fl->sessionid); break; case FASTRPC_CONTROL_RPC_POLL: err = fastrpc_manage_poll_mode(fl, cp->lp.enable, cp->lp.latency); @@ -6669,8 +6747,8 @@ int fastrpc_setmode(unsigned long ioctl_param, "multiple sessions not allowed for untrusted apps\n"); goto bail; } - fl->sessionid = 1; - fl->tgid |= SESSION_ID_MASK; + if (!fl->multi_session_support) + fl->sessionid = 1; break; default: err = -ENOTTY; @@ -6741,8 +6819,9 @@ int fastrpc_dspsignal_signal(struct fastrpc_file *fl, // track outgoing signals in the driver. The userspace library does a // basic sanity check and any security validation needs to be done by // the recipient. - DSPSIGNAL_VERBOSE("Send signal PID %u, signal %u\n", - (unsigned int)fl->tgid, (unsigned int)sig->signal_id); + DSPSIGNAL_VERBOSE("Send signal PID %u, unique fastrpc pid %u signal %u\n", + (unsigned int)fl->tgid, (unsigned int)fl->tgid_frpc, + (unsigned int)sig->signal_id); VERIFY(err, sig->signal_id < DSPSIGNAL_NUM_SIGNALS); if (err) { ADSPRPC_ERR("Sending bad signal %u for PID %u", @@ -6766,7 +6845,8 @@ int fastrpc_dspsignal_signal(struct fastrpc_file *fl, goto bail; } - msg = (((uint64_t)fl->tgid) << 32) | ((uint64_t)sig->signal_id); + /* Use unique fastrpc pid, to signal DSP process */ + msg = (((uint64_t)fl->tgid_frpc) << 32) | ((uint64_t)sig->signal_id); err = fastrpc_transport_send(cid, (void *)&msg, sizeof(msg), fl->trusted_vm); mutex_unlock(&channel_ctx->smd_mutex); @@ -7849,10 +7929,10 @@ static int fastrpc_cb_probe(struct device *dev) if (of_get_property(dev->of_node, "pd-type", NULL) != NULL) { err = of_property_read_u32(dev->of_node, "pd-type", &(sess->smmu.pd_type)); + /* Set cb_pd_type, if the process type is set for context banks */ + me->cb_pd_type = true; if (err) goto bail; - // Set cb_pd_type, if the process type is configured for context banks - me->cb_pd_type = true; } if (of_get_property(dev->of_node, "shared-cb", NULL) != NULL) { sess->smmu.sharedcb = 1; @@ -8186,6 +8266,8 @@ static int fastrpc_probe(struct platform_device *pdev) me->lowest_capacity_core_count = 1; of_property_read_u32(dev->of_node, "qcom,rpc-latency-us", &me->latency); + of_property_read_u32(dev->of_node, "qcom,max-sessions", + &me->max_sess_per_proc); if (of_get_property(dev->of_node, "qcom,secure-domains", NULL) != NULL) { VERIFY(err, !of_property_read_u32(dev->of_node, @@ -8602,17 +8684,24 @@ static int fastrpc_device_create(struct fastrpc_file *fl) frpc_dev->dev.parent = &fastrpc_bus; frpc_dev->dev.bus = &fastrpc_bus_type; - dev_set_name(&frpc_dev->dev, "%s-%d-%d", - dev_name(frpc_dev->dev.parent), fl->tgid, fl->cid); + /* + * Use HLOS PID, unique fastrpc process ID and CID to create device file, + * Else names would conflict for multiple sessions + * And also for better ability to debug + */ + dev_set_name(&frpc_dev->dev, "%s-%d-%d-%d", + dev_name(frpc_dev->dev.parent), fl->tgid, fl->tgid_frpc, fl->cid); frpc_dev->dev.release = fastrpc_dev_release; frpc_dev->fl = fl; - frpc_dev->handle = fl->tgid; + /* Use unique fastrpc tgid as handle */ + frpc_dev->handle = fl->tgid_frpc; err = device_register(&frpc_dev->dev); if (err) { put_device(&frpc_dev->dev); - ADSPRPC_ERR("fastrpc device register failed for process %d with error %d\n", - fl->tgid, err); + ADSPRPC_ERR( + "fastrpc device register failed for process %d unique fastrpc tgid %d session %d with error %d\n", + fl->tgid, fl->tgid_frpc, fl->sessionid, err); goto bail; } fl->device = frpc_dev; diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index 1e2f9473aeb5..5da2da7107cf 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -120,6 +120,9 @@ #define NUM_CHANNELS (MAX_DOMAIN_ID + 1) /* adsp, mdsp, slpi, cdsp, cdsp1, gpdsp, gpdsp1*/ #define NUM_SESSIONS 13 /* max 12 compute, 1 cpz */ +/* Default maximum sessions allowed per process */ +#define DEFAULT_MAX_SESS_PER_PROC 4 + #define RH_CID ADSP_DOMAIN_ID #define VALID_FASTRPC_CID(cid) \ @@ -995,6 +998,8 @@ struct fastrpc_apps { bool single_core_latency_vote; /* Indicates process type is configured for SMMU context bank */ bool cb_pd_type; + /* Maximum sessions allowed to be created per process */ + uint32_t max_sess_per_proc; }; struct fastrpc_mmap { @@ -1095,6 +1100,8 @@ struct fastrpc_file { int sessionid; int tgid_open; /* Process ID during device open */ int tgid; /* Process ID that uses device for RPC calls */ + /* Unique HLOS process ID created by fastrpc for each client */ + int tgid_frpc; int cid; bool trusted_vm; uint64_t ssrcount; @@ -1166,6 +1173,10 @@ struct fastrpc_file { * config parameters. */ struct fastrpc_proc_sharedbuf_info sharedbuf_info; + /* Flag to indicate 4 session support available */ + bool multi_session_support; + /* Flag to indicate session info is set */ + bool set_session_info; }; union fastrpc_ioctl_param { From 65b80d06da656c1311bbb38498801dee764b4be1 Mon Sep 17 00:00:00 2001 From: Praveen koya Date: Wed, 20 Dec 2023 17:20:21 +0530 Subject: [PATCH 30/46] soc: qcom: handle AON spi device when driver is not ready Handle accessing the AON spi device when driver is not ready & when device enter to shutdown path. Change-Id: Ibebb2f526b289ee31517d7e52e48ca46ce705d1c Signed-off-by: Praveen koya --- drivers/soc/qcom/slatecom_spi.c | 36 +++++++++++++++++---------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/soc/qcom/slatecom_spi.c b/drivers/soc/qcom/slatecom_spi.c index 67faac3ca9d2..521ba6a200bc 100644 --- a/drivers/soc/qcom/slatecom_spi.c +++ b/drivers/soc/qcom/slatecom_spi.c @@ -352,7 +352,7 @@ static int slatecom_transfer(void *handle, uint8_t *tx_buf, struct spi_transfer *tx_xfer; struct slate_spi_priv *slate_spi; struct slate_context *cntx; - struct spi_device *spi; + struct spi_device *spi = NULL; int ret = 0; if (!handle || !tx_buf) @@ -428,8 +428,11 @@ void send_event(enum slatecom_event_type event, void slatecom_slatedown_handler(void) { - struct spi_device *spi = get_spi_device(); + struct spi_device *spi = NULL; + if (!is_slatecom_ready()) + return; + spi = get_spi_device(); g_slav_status_reg = 0; atomic_set(&ok_to_sleep, 0); pm_runtime_get_sync(&spi->dev); @@ -863,7 +866,7 @@ int slatecom_ahb_read(void *handle, uint32_t ahb_start_addr, int ret = 0; uint8_t cmnd = 0; uint32_t ahb_addr = 0; - struct spi_device *spi = get_spi_device(); + struct spi_device *spi = NULL; if (!handle || !read_buf || num_words == 0 || num_words > SLATE_SPI_MAX_WORDS) { @@ -877,7 +880,7 @@ int slatecom_ahb_read(void *handle, uint32_t ahb_start_addr, SLATECOM_ERR("Device busy\n"); return -EBUSY; } - + spi = get_spi_device(); pm_runtime_get_sync(&spi->dev); mutex_lock(&slate_task_mutex); @@ -928,7 +931,7 @@ int slatecom_ahb_write_bytes(void *handle, uint32_t ahb_start_addr, uint8_t cmnd = 0; uint32_t ahb_addr = 0; uint32_t curr_num_bytes; - struct spi_device *spi = get_spi_device(); + struct spi_device *spi = NULL; if (!handle || !write_buf || num_bytes == 0 || num_bytes > (SLATE_SPI_MAX_WORDS * sizeof(int))) { @@ -943,7 +946,7 @@ int slatecom_ahb_write_bytes(void *handle, uint32_t ahb_start_addr, SLATECOM_ERR("Device busy\n"); return -EBUSY; } - + spi = get_spi_device(); pm_runtime_get_sync(&spi->dev); mutex_lock(&slate_task_mutex); @@ -998,7 +1001,7 @@ int slatecom_ahb_write(void *handle, uint32_t ahb_start_addr, uint32_t ahb_addr = 0; uint32_t curr_num_words; uint32_t curr_num_bytes; - struct spi_device *spi = get_spi_device(); + struct spi_device *spi = NULL; if (!handle || !write_buf || num_words == 0 || num_words > SLATE_SPI_MAX_WORDS) { @@ -1013,7 +1016,7 @@ int slatecom_ahb_write(void *handle, uint32_t ahb_start_addr, SLATECOM_ERR("Device busy\n"); return -EBUSY; } - + spi = get_spi_device(); pm_runtime_get_sync(&spi->dev); mutex_lock(&slate_task_mutex); @@ -1062,13 +1065,11 @@ int slatecom_fifo_write(void *handle, uint32_t num_words, uint32_t size; int ret = 0; uint8_t cmnd = 0; - struct spi_device *spi; + struct spi_device *spi = NULL; if (!is_slatecom_ready()) return -ENODEV; - spi = get_spi_device(); - if (!handle || !write_buf || num_words == 0 || num_words > SLATE_SPI_MAX_WORDS) { SLATECOM_ERR("Invalid param\n"); @@ -1079,7 +1080,7 @@ int slatecom_fifo_write(void *handle, uint32_t num_words, SLATECOM_ERR("Device busy\n"); return -EBUSY; } - + spi = get_spi_device(); pm_runtime_get_sync(&spi->dev); mutex_lock(&slate_task_mutex); @@ -1116,7 +1117,7 @@ int slatecom_fifo_read(void *handle, uint32_t num_words, uint32_t size; uint8_t cmnd = 0; int ret = 0; - struct spi_device *spi = get_spi_device(); + struct spi_device *spi = NULL; if (!handle || !read_buf || num_words == 0 || num_words > SLATE_SPI_MAX_WORDS) { @@ -1131,7 +1132,7 @@ int slatecom_fifo_read(void *handle, uint32_t num_words, SLATECOM_ERR("Device busy\n"); return -EBUSY; } - + spi = get_spi_device(); pm_runtime_get_sync(&spi->dev); mutex_lock(&slate_task_mutex); @@ -1216,8 +1217,9 @@ int slatecom_reg_write(void *handle, uint8_t reg_start_addr, uint8_t num_regs, void *write_buf) { int ret = 0; - struct spi_device *spi = get_spi_device(); + struct spi_device *spi = NULL; + spi = get_spi_device(); pm_runtime_get_sync(&spi->dev); mutex_lock(&slate_task_mutex); @@ -1294,7 +1296,7 @@ int slatecom_reg_read(void *handle, uint8_t reg_start_addr, uint32_t size; int ret = 0; uint8_t cmnd = 0; - struct spi_device *spi = get_spi_device(); + struct spi_device *spi = NULL; if (!handle || !read_buf || num_regs == 0 || num_regs > SLATE_SPI_MAX_REGS) { @@ -1309,7 +1311,7 @@ int slatecom_reg_read(void *handle, uint8_t reg_start_addr, SLATECOM_ERR("Device busy\n"); return -EBUSY; } - + spi = get_spi_device(); pm_runtime_get_sync(&spi->dev); mutex_lock(&slate_task_mutex); From 2fc5564dea427030176ec2be236f551498e02c2e Mon Sep 17 00:00:00 2001 From: Yadu MG Date: Thu, 21 Dec 2023 12:07:45 +0530 Subject: [PATCH 31/46] Revert "drivers: arm-smmu: Power-on SMMU during freeze" This reverts commit 18af9e38eaea28c9cc0197bc5e3aef3609c0313e. Reason for revert: Mismatch in power count which prevents sleep. Change-Id: I8412404f269fd7054b55136cc7cba7734964023f Signed-off-by: Yadu MG --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 5bf0e5d79293..e2eac342c8c0 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -4136,12 +4136,6 @@ static int __maybe_unused arm_smmu_pm_freeze_late(struct device *dev) struct arm_smmu_cb *cb; int idx, ret; - ret = arm_smmu_runtime_resume(dev); - if (ret) { - dev_err(dev, "Failed to Resume:%d\n", ret); - return ret; - } - for (idx = 0; idx < smmu->num_context_banks; idx++) { cb = &smmu->cbs[idx]; if (cb && cb->cfg) { From 3d9eb05d27cf62d0a180429d3599424a7db26faf Mon Sep 17 00:00:00 2001 From: Saranya R Date: Thu, 21 Dec 2023 12:18:52 +0530 Subject: [PATCH 32/46] defconfig: Enable CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_UNCACHED for qcs605 Enable CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_UNCACHED for qcs605. Change-Id: I51ab216ec785f9f5fedba515b7020d19d6417c6e Signed-off-by: Saranya R --- arch/arm64/configs/vendor/qcs605_GKI.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/configs/vendor/qcs605_GKI.config b/arch/arm64/configs/vendor/qcs605_GKI.config index c9ccb510a164..25480f487760 100644 --- a/arch/arm64/configs/vendor/qcs605_GKI.config +++ b/arch/arm64/configs/vendor/qcs605_GKI.config @@ -104,7 +104,7 @@ CONFIG_QCOM_DMABUF_HEAPS_CMA=y CONFIG_QCOM_DMABUF_HEAPS_PAGE_POOL_REFILL=y CONFIG_QCOM_DMABUF_HEAPS_SYSTEM=y CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_SECURE=y -# CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_UNCACHED is not set +CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_UNCACHED=y # CONFIG_QCOM_DYN_MINIDUMP_STACK is not set CONFIG_QCOM_EUD=m CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y From 77709cd1bf6597846b1b93278ba01d5f6196f93d Mon Sep 17 00:00:00 2001 From: Chetan C R Date: Wed, 9 Aug 2023 15:38:11 +0530 Subject: [PATCH 33/46] clk: qcom: sdm845: Update the support for clock controllers Update GCC, GPUCC, VIDEOCC, DISPCC and CAMCC clock controllers with vdd_data struct to support voltage voting for SDM845. Change-Id: Icc75301ed289d72ee3bf9fdb541b690ac6a7ba53 Signed-off-by: Chetan C R --- drivers/clk/qcom/Kconfig | 18 +- drivers/clk/qcom/camcc-sdm845.c | 771 ++++++++++++++---- drivers/clk/qcom/dispcc-sdm845.c | 264 ++++++- drivers/clk/qcom/gcc-sdm845.c | 1144 +++++++++++++++++++++------ drivers/clk/qcom/gpucc-sdm845.c | 490 +++++++++++- drivers/clk/qcom/vdd-level-sdm845.h | 58 ++ drivers/clk/qcom/videocc-sdm845.c | 118 ++- 7 files changed, 2400 insertions(+), 463 deletions(-) create mode 100644 drivers/clk/qcom/vdd-level-sdm845.h diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index b00f44bf83ba..b59ff4db1a4f 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -460,13 +460,6 @@ config SC_VIDEOCC_7280 Say Y if you want to support video devices and functionality such as video encode and decode. -config SDM_CAMCC_845 - tristate "SDM845 Camera Clock Controller" - select SDM_GCC_845 - help - Support for the camera clock controller on SDM845 devices. - Say Y if you want to support camera devices and camera functionality. - config SDM_GCC_660 tristate "SDM660 Global Clock Controller" select QCOM_GDSC @@ -507,9 +500,18 @@ config QCS_Q6SSTOP_404 Say Y if you want to use the Q6SSTOP branch clocks of the WCSS clock controller to reset the Q6SSTOP subsystem. +config SDM_CAMCC_845 + tristate "SDM845 Camera Clock Controller" + select SDM_GCC_845 + help + Support for the camera clock controller on Qualcomm Technologies, Inc + SDM845 devices. + Say Y if you want to support camera devices and functionality such as + capturing pictures. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" - select QCOM_GDSC + depends on COMMON_CLK_QCOM help Support for the global clock controller on SDM845 devices. Say Y if you want to use peripheral devices such as UART, SPI, diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c index a8a2cfa83290..addcfd2e3918 100644 --- a/drivers/clk/qcom/camcc-sdm845.c +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -15,51 +16,64 @@ #include "clk-branch.h" #include "clk-rcg.h" #include "clk-regmap.h" +#include "vdd-level-sdm845.h" +#include "reset.h" #include "gdsc.h" +static DEFINE_VDD_REGULATORS(vdd_cx, VDD_NUM, 1, vdd_corner); +static DEFINE_VDD_REGULATORS(vdd_mx, VDD_NUM, 1, vdd_corner); + +static struct clk_vdd_class *cam_cc_sdm845_regulators[] = { + &vdd_cx, + &vdd_mx, +}; + enum { P_BI_TCXO, P_CAM_CC_PLL0_OUT_EVEN, P_CAM_CC_PLL1_OUT_EVEN, P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL2_OUT_ODD, P_CAM_CC_PLL3_OUT_EVEN, P_CORE_BI_PLL_TEST_SE, }; -static const struct parent_map cam_cc_parent_map_0[] = { - { P_BI_TCXO, 0 }, - { P_CAM_CC_PLL2_OUT_EVEN, 1 }, - { P_CAM_CC_PLL1_OUT_EVEN, 2 }, - { P_CAM_CC_PLL3_OUT_EVEN, 5 }, - { P_CAM_CC_PLL0_OUT_EVEN, 6 }, - { P_CORE_BI_PLL_TEST_SE, 7 }, -}; - -static const char * const cam_cc_parent_names_0[] = { - "bi_tcxo", - "cam_cc_pll2_out_even", - "cam_cc_pll1_out_even", - "cam_cc_pll3_out_even", - "cam_cc_pll0_out_even", - "core_bi_pll_test_se", +static struct pll_vco fabia_vco[] = { + { 249600000, 2000000000, 0 }, + { 125000000, 1000000000, 1 }, }; static struct clk_alpha_pll cam_cc_pll0 = { .offset = 0x0, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr = { .hw.init = &(struct clk_init_data){ .name = "cam_cc_pll0", - .parent_names = (const char *[]){ "bi_tcxo" }, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, .num_parents = 1, .ops = &clk_alpha_pll_fabia_ops, }, + .vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 615000000, + [VDD_LOW] = 1066000000, + [VDD_LOW_L1] = 1600000000, + [VDD_NOMINAL] = 2000000000 }, + }, }, }; static const struct clk_div_table post_div_table_fabia_even[] = { { 0x0, 1 }, { 0x1, 2 }, + { 0x3, 4 }, + { 0x7, 8 }, { } }; @@ -72,7 +86,9 @@ static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_pll0_out_even", - .parent_names = (const char *[]){ "cam_cc_pll0" }, + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_pll0.clkr.hw, + }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_fabia_ops, }, @@ -80,14 +96,27 @@ static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { static struct clk_alpha_pll cam_cc_pll1 = { .offset = 0x1000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr = { .hw.init = &(struct clk_init_data){ .name = "cam_cc_pll1", - .parent_names = (const char *[]){ "bi_tcxo" }, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, .num_parents = 1, .ops = &clk_alpha_pll_fabia_ops, }, + .vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 615000000, + [VDD_LOW] = 1066000000, + [VDD_LOW_L1] = 1600000000, + [VDD_NOMINAL] = 2000000000 }, + }, }, }; @@ -100,7 +129,9 @@ static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_pll1_out_even", - .parent_names = (const char *[]){ "cam_cc_pll1" }, + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_pll1.clkr.hw, + }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_fabia_ops, }, @@ -108,14 +139,27 @@ static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { static struct clk_alpha_pll cam_cc_pll2 = { .offset = 0x2000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr = { .hw.init = &(struct clk_init_data){ .name = "cam_cc_pll2", - .parent_names = (const char *[]){ "bi_tcxo" }, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, .num_parents = 1, .ops = &clk_alpha_pll_fabia_ops, }, + .vdd_data = { + .vdd_class = &vdd_mx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 615000000, + [VDD_LOW] = 1066000000, + [VDD_LOW_L1] = 1600000000, + [VDD_NOMINAL] = 2000000000 }, + }, }, }; @@ -128,7 +172,34 @@ static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_pll2_out_even", - .parent_names = (const char *[]){ "cam_cc_pll2" }, + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_pll2.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static const struct clk_div_table post_div_table_fabia_odd[] = { + { 0x0, 1 }, + { 0x3, 3 }, + { 0x5, 5 }, + { 0x7, 7 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_odd = { + .offset = 0x2000, + .post_div_shift = 12, + .post_div_table = post_div_table_fabia_odd, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll2_out_odd", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_pll2.clkr.hw, + }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_fabia_ops, }, @@ -136,14 +207,27 @@ static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { static struct clk_alpha_pll cam_cc_pll3 = { .offset = 0x3000, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr = { .hw.init = &(struct clk_init_data){ .name = "cam_cc_pll3", - .parent_names = (const char *[]){ "bi_tcxo" }, + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, .num_parents = 1, .ops = &clk_alpha_pll_fabia_ops, }, + .vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 615000000, + [VDD_LOW] = 1066000000, + [VDD_LOW_L1] = 1600000000, + [VDD_NOMINAL] = 2000000000 }, + }, }, }; @@ -156,12 +240,48 @@ static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = { .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_pll3_out_even", - .parent_names = (const char *[]){ "cam_cc_pll3" }, + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_pll3.clkr.hw, + }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &cam_cc_pll2_out_even.clkr.hw }, + { .hw = &cam_cc_pll1_out_even.clkr.hw }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL2_OUT_ODD, 4 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &cam_cc_pll2_out_even.clkr.hw }, + { .hw = &cam_cc_pll1_out_even.clkr.hw }, + { .hw = &cam_cc_pll2_out_odd.clkr.hw }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, +}; + static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = { F(19200000, P_BI_TCXO, 1, 0, 0), F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), @@ -189,11 +309,21 @@ static struct clk_rcg2 cam_cc_bps_clk_src = { .freq_tbl = ftbl_cam_cc_bps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_bps_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 200000000, + [VDD_LOW] = 404000000, + [VDD_LOW_L1] = 480000000, + [VDD_NOMINAL] = 600000000 }, + }, }; static const struct freq_tbl ftbl_cam_cc_cci_clk_src[] = { @@ -210,12 +340,23 @@ static struct clk_rcg2 cam_cc_cci_clk_src = { .hid_width = 5, .parent_map = cam_cc_parent_map_0, .freq_tbl = ftbl_cam_cc_cci_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_cci_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 37500000, + [VDD_LOW] = 50000000, + [VDD_NOMINAL] = 100000000 }, + }, }; static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = { @@ -228,14 +369,25 @@ static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { .cmd_rcgr = 0x9060, .mnd_width = 0, .hid_width = 5, - .parent_map = cam_cc_parent_map_0, + .parent_map = cam_cc_parent_map_1, .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_cphy_rx_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 300000000, + [VDD_LOW] = 320000000, + [VDD_HIGH] = 384000000 }, + }, }; static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = { @@ -251,13 +403,22 @@ static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { .hid_width = 5, .parent_map = cam_cc_parent_map_0, .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_csi0phytimer_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 240000000, + [VDD_LOW] = 269333333 }, + }, }; static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { @@ -266,13 +427,22 @@ static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { .hid_width = 5, .parent_map = cam_cc_parent_map_0, .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_csi1phytimer_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 240000000, + [VDD_LOW] = 269333333 }, + }, }; static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { @@ -281,13 +451,22 @@ static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { .hid_width = 5, .parent_map = cam_cc_parent_map_0, .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_csi2phytimer_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 240000000, + [VDD_LOW] = 269333333 }, + }, }; static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { @@ -296,13 +475,22 @@ static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { .hid_width = 5, .parent_map = cam_cc_parent_map_0, .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_csi3phytimer_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 240000000, + [VDD_LOW] = 269333333 }, + }, }; static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = { @@ -321,12 +509,24 @@ static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { .hid_width = 5, .parent_map = cam_cc_parent_map_0, .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_fast_ahb_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 100000000, + [VDD_LOW] = 200000000, + [VDD_LOW_L1] = 300000000, + [VDD_NOMINAL] = 400000000 }, + }, }; static const struct freq_tbl ftbl_cam_cc_fd_core_clk_src[] = { @@ -346,13 +546,33 @@ static struct clk_rcg2 cam_cc_fd_core_clk_src = { .freq_tbl = ftbl_cam_cc_fd_core_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_fd_core_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 320000000, + [VDD_LOW] = 400000000, + [VDD_LOW_L1] = 538666667, + [VDD_NOMINAL] = 600000000 }, + }, }; static const struct freq_tbl ftbl_cam_cc_icp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(320000000, P_CAM_CC_PLL2_OUT_EVEN, 1.5, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_cam_cc_icp_clk_src_sdm670[] = { F(19200000, P_BI_TCXO, 1, 0, 0), F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), @@ -369,10 +589,21 @@ static struct clk_rcg2 cam_cc_icp_clk_src = { .freq_tbl = ftbl_cam_cc_icp_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_icp_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 320000000, + [VDD_LOW] = 400000000, + [VDD_LOW_L1] = 538666667, + [VDD_NOMINAL] = 600000000 }, + }, }; static const struct freq_tbl ftbl_cam_cc_ife_0_clk_src[] = { @@ -393,11 +624,21 @@ static struct clk_rcg2 cam_cc_ife_0_clk_src = { .freq_tbl = ftbl_cam_cc_ife_0_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_0_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 320000000, + [VDD_LOW] = 404000000, + [VDD_LOW_L1] = 480000000, + [VDD_NOMINAL] = 600000000 }, + }, }; static const struct freq_tbl ftbl_cam_cc_ife_0_csid_clk_src[] = { @@ -412,14 +653,23 @@ static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = { .cmd_rcgr = 0x9038, .mnd_width = 0, .hid_width = 5, - .parent_map = cam_cc_parent_map_0, + .parent_map = cam_cc_parent_map_1, .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_0_csid_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 384000000, + [VDD_NOMINAL] = 538666667 }, + }, }; static struct clk_rcg2 cam_cc_ife_1_clk_src = { @@ -430,25 +680,44 @@ static struct clk_rcg2 cam_cc_ife_1_clk_src = { .freq_tbl = ftbl_cam_cc_ife_0_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_1_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 320000000, + [VDD_LOW] = 404000000, + [VDD_LOW_L1] = 480000000, + [VDD_NOMINAL] = 600000000 }, + }, }; static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = { .cmd_rcgr = 0xa030, .mnd_width = 0, .hid_width = 5, - .parent_map = cam_cc_parent_map_0, + .parent_map = cam_cc_parent_map_1, .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_1_csid_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 384000000, + [VDD_NOMINAL] = 538666667 }, + }, }; static struct clk_rcg2 cam_cc_ife_lite_clk_src = { @@ -459,25 +728,44 @@ static struct clk_rcg2 cam_cc_ife_lite_clk_src = { .freq_tbl = ftbl_cam_cc_ife_0_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_lite_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 320000000, + [VDD_LOW] = 404000000, + [VDD_LOW_L1] = 480000000, + [VDD_NOMINAL] = 600000000 }, + }, }; static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { .cmd_rcgr = 0xb024, .mnd_width = 0, .hid_width = 5, - .parent_map = cam_cc_parent_map_0, + .parent_map = cam_cc_parent_map_1, .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_lite_csid_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 384000000, + [VDD_NOMINAL] = 538666667 }, + }, }; static const struct freq_tbl ftbl_cam_cc_ipe_0_clk_src[] = { @@ -499,11 +787,22 @@ static struct clk_rcg2 cam_cc_ipe_0_clk_src = { .freq_tbl = ftbl_cam_cc_ipe_0_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_ipe_0_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 240000000, + [VDD_LOW] = 404000000, + [VDD_LOW_L1] = 480000000, + [VDD_NOMINAL] = 538666667, + [VDD_HIGH] = 600000000 }, + }, }; static struct clk_rcg2 cam_cc_ipe_1_clk_src = { @@ -514,11 +813,22 @@ static struct clk_rcg2 cam_cc_ipe_1_clk_src = { .freq_tbl = ftbl_cam_cc_ipe_0_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_ipe_1_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 240000000, + [VDD_LOW] = 404000000, + [VDD_LOW_L1] = 480000000, + [VDD_NOMINAL] = 538666667, + [VDD_HIGH] = 600000000 }, + }, }; static struct clk_rcg2 cam_cc_jpeg_clk_src = { @@ -529,14 +839,34 @@ static struct clk_rcg2 cam_cc_jpeg_clk_src = { .freq_tbl = ftbl_cam_cc_bps_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_jpeg_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 200000000, + [VDD_LOW] = 404000000, + [VDD_LOW_L1] = 480000000, + [VDD_NOMINAL] = 600000000 }, + }, }; static const struct freq_tbl ftbl_cam_cc_lrme_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(384000000, P_CAM_CC_PLL2_OUT_ODD, 2.5, 0, 0), + F(480000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_cam_cc_lrme_clk_src_sdm670[] = { F(19200000, P_BI_TCXO, 1, 0, 0), F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), @@ -550,18 +880,29 @@ static struct clk_rcg2 cam_cc_lrme_clk_src = { .cmd_rcgr = 0xb0f8, .mnd_width = 0, .hid_width = 5, - .parent_map = cam_cc_parent_map_0, + .parent_map = cam_cc_parent_map_1, .freq_tbl = ftbl_cam_cc_lrme_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_lrme_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 200000000, + [VDD_LOW] = 384000000, + [VDD_LOW_L1] = 480000000, + [VDD_NOMINAL] = 600000000 }, + }, }; static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = { + F(8000000, P_CAM_CC_PLL2_OUT_EVEN, 10, 1, 6), F(19200000, P_BI_TCXO, 1, 0, 0), F(24000000, P_CAM_CC_PLL2_OUT_EVEN, 10, 1, 2), F(33333333, P_CAM_CC_PLL0_OUT_EVEN, 2, 1, 9), @@ -575,13 +916,21 @@ static struct clk_rcg2 cam_cc_mclk0_clk_src = { .hid_width = 5, .parent_map = cam_cc_parent_map_0, .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_mclk0_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 34285714 }, + }, }; static struct clk_rcg2 cam_cc_mclk1_clk_src = { @@ -590,13 +939,21 @@ static struct clk_rcg2 cam_cc_mclk1_clk_src = { .hid_width = 5, .parent_map = cam_cc_parent_map_0, .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_mclk1_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 34285714 }, + }, }; static struct clk_rcg2 cam_cc_mclk2_clk_src = { @@ -605,13 +962,21 @@ static struct clk_rcg2 cam_cc_mclk2_clk_src = { .hid_width = 5, .parent_map = cam_cc_parent_map_0, .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_mclk2_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 34285714 }, + }, }; static struct clk_rcg2 cam_cc_mclk3_clk_src = { @@ -620,13 +985,21 @@ static struct clk_rcg2 cam_cc_mclk3_clk_src = { .hid_width = 5, .parent_map = cam_cc_parent_map_0, .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_mclk3_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 34285714 }, + }, }; static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = { @@ -644,13 +1017,24 @@ static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { .hid_width = 5, .parent_map = cam_cc_parent_map_0, .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "cam_cc_slow_ahb_clk_src", - .parent_names = cam_cc_parent_names_0, - .num_parents = 6, + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 60000000, + [VDD_LOW] = 66666667, + [VDD_LOW_L1] = 73846154, + [VDD_NOMINAL] = 80000000 }, + }, }; static struct clk_branch cam_cc_bps_ahb_clk = { @@ -661,8 +1045,8 @@ static struct clk_branch cam_cc_bps_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_bps_ahb_clk", - .parent_names = (const char *[]){ - "cam_cc_slow_ahb_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -679,8 +1063,8 @@ static struct clk_branch cam_cc_bps_areg_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_bps_areg_clk", - .parent_names = (const char *[]){ - "cam_cc_fast_ahb_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_fast_ahb_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -710,8 +1094,8 @@ static struct clk_branch cam_cc_bps_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_bps_clk", - .parent_names = (const char *[]){ - "cam_cc_bps_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_bps_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -754,8 +1138,8 @@ static struct clk_branch cam_cc_cci_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_cci_clk", - .parent_names = (const char *[]){ - "cam_cc_cci_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cci_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -772,8 +1156,8 @@ static struct clk_branch cam_cc_cpas_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_cpas_ahb_clk", - .parent_names = (const char *[]){ - "cam_cc_slow_ahb_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -790,8 +1174,8 @@ static struct clk_branch cam_cc_csi0phytimer_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_csi0phytimer_clk", - .parent_names = (const char *[]){ - "cam_cc_csi0phytimer_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_csi0phytimer_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -808,8 +1192,8 @@ static struct clk_branch cam_cc_csi1phytimer_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_csi1phytimer_clk", - .parent_names = (const char *[]){ - "cam_cc_csi1phytimer_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_csi1phytimer_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -826,8 +1210,8 @@ static struct clk_branch cam_cc_csi2phytimer_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_csi2phytimer_clk", - .parent_names = (const char *[]){ - "cam_cc_csi2phytimer_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_csi2phytimer_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -844,8 +1228,8 @@ static struct clk_branch cam_cc_csi3phytimer_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_csi3phytimer_clk", - .parent_names = (const char *[]){ - "cam_cc_csi3phytimer_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_csi3phytimer_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -862,8 +1246,8 @@ static struct clk_branch cam_cc_csiphy0_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_csiphy0_clk", - .parent_names = (const char *[]){ - "cam_cc_cphy_rx_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -880,8 +1264,8 @@ static struct clk_branch cam_cc_csiphy1_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_csiphy1_clk", - .parent_names = (const char *[]){ - "cam_cc_cphy_rx_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -898,8 +1282,8 @@ static struct clk_branch cam_cc_csiphy2_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_csiphy2_clk", - .parent_names = (const char *[]){ - "cam_cc_cphy_rx_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -916,8 +1300,8 @@ static struct clk_branch cam_cc_csiphy3_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_csiphy3_clk", - .parent_names = (const char *[]){ - "cam_cc_cphy_rx_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -934,8 +1318,8 @@ static struct clk_branch cam_cc_fd_core_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_fd_core_clk", - .parent_names = (const char *[]){ - "cam_cc_fd_core_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_fd_core_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -952,8 +1336,8 @@ static struct clk_branch cam_cc_fd_core_uar_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_fd_core_uar_clk", - .parent_names = (const char *[]){ - "cam_cc_fd_core_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_fd_core_clk_src.clkr.hw, }, .num_parents = 1, .ops = &clk_branch2_ops, @@ -995,8 +1379,8 @@ static struct clk_branch cam_cc_icp_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_icp_clk", - .parent_names = (const char *[]){ - "cam_cc_icp_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_icp_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1052,8 +1436,8 @@ static struct clk_branch cam_cc_ife_0_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_0_clk", - .parent_names = (const char *[]){ - "cam_cc_ife_0_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_0_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1070,8 +1454,8 @@ static struct clk_branch cam_cc_ife_0_cphy_rx_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_0_cphy_rx_clk", - .parent_names = (const char *[]){ - "cam_cc_cphy_rx_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1088,8 +1472,8 @@ static struct clk_branch cam_cc_ife_0_csid_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_0_csid_clk", - .parent_names = (const char *[]){ - "cam_cc_ife_0_csid_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_0_csid_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1106,8 +1490,8 @@ static struct clk_branch cam_cc_ife_0_dsp_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_0_dsp_clk", - .parent_names = (const char *[]){ - "cam_cc_ife_0_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_0_clk_src.clkr.hw, }, .num_parents = 1, .ops = &clk_branch2_ops, @@ -1136,8 +1520,8 @@ static struct clk_branch cam_cc_ife_1_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_1_clk", - .parent_names = (const char *[]){ - "cam_cc_ife_1_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_1_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1154,8 +1538,8 @@ static struct clk_branch cam_cc_ife_1_cphy_rx_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_1_cphy_rx_clk", - .parent_names = (const char *[]){ - "cam_cc_cphy_rx_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1172,8 +1556,8 @@ static struct clk_branch cam_cc_ife_1_csid_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_1_csid_clk", - .parent_names = (const char *[]){ - "cam_cc_ife_1_csid_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_1_csid_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1190,8 +1574,8 @@ static struct clk_branch cam_cc_ife_1_dsp_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_1_dsp_clk", - .parent_names = (const char *[]){ - "cam_cc_ife_1_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_1_clk_src.clkr.hw, }, .num_parents = 1, .ops = &clk_branch2_ops, @@ -1207,8 +1591,8 @@ static struct clk_branch cam_cc_ife_lite_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_lite_clk", - .parent_names = (const char *[]){ - "cam_cc_ife_lite_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_lite_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1225,8 +1609,8 @@ static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_lite_cphy_rx_clk", - .parent_names = (const char *[]){ - "cam_cc_cphy_rx_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1243,8 +1627,8 @@ static struct clk_branch cam_cc_ife_lite_csid_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ife_lite_csid_clk", - .parent_names = (const char *[]){ - "cam_cc_ife_lite_csid_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_lite_csid_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1261,8 +1645,8 @@ static struct clk_branch cam_cc_ipe_0_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ipe_0_ahb_clk", - .parent_names = (const char *[]){ - "cam_cc_slow_ahb_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1279,8 +1663,8 @@ static struct clk_branch cam_cc_ipe_0_areg_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ipe_0_areg_clk", - .parent_names = (const char *[]){ - "cam_cc_fast_ahb_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_fast_ahb_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1310,8 +1694,8 @@ static struct clk_branch cam_cc_ipe_0_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ipe_0_clk", - .parent_names = (const char *[]){ - "cam_cc_ipe_0_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ipe_0_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1328,8 +1712,8 @@ static struct clk_branch cam_cc_ipe_1_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ipe_1_ahb_clk", - .parent_names = (const char *[]){ - "cam_cc_slow_ahb_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1346,8 +1730,8 @@ static struct clk_branch cam_cc_ipe_1_areg_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ipe_1_areg_clk", - .parent_names = (const char *[]){ - "cam_cc_fast_ahb_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_fast_ahb_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1377,8 +1761,8 @@ static struct clk_branch cam_cc_ipe_1_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_ipe_1_clk", - .parent_names = (const char *[]){ - "cam_cc_ipe_1_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ipe_1_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1395,8 +1779,8 @@ static struct clk_branch cam_cc_jpeg_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_jpeg_clk", - .parent_names = (const char *[]){ - "cam_cc_jpeg_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_jpeg_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1413,8 +1797,8 @@ static struct clk_branch cam_cc_lrme_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_lrme_clk", - .parent_names = (const char *[]){ - "cam_cc_lrme_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_lrme_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1431,8 +1815,8 @@ static struct clk_branch cam_cc_mclk0_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_mclk0_clk", - .parent_names = (const char *[]){ - "cam_cc_mclk0_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_mclk0_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1449,8 +1833,8 @@ static struct clk_branch cam_cc_mclk1_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_mclk1_clk", - .parent_names = (const char *[]){ - "cam_cc_mclk1_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_mclk1_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1467,8 +1851,8 @@ static struct clk_branch cam_cc_mclk2_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_mclk2_clk", - .parent_names = (const char *[]){ - "cam_cc_mclk2_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_mclk2_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1485,8 +1869,8 @@ static struct clk_branch cam_cc_mclk3_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "cam_cc_mclk3_clk", - .parent_names = (const char *[]){ - "cam_cc_mclk3_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_mclk3_clk_src.clkr.hw, }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1660,6 +2044,7 @@ static struct clk_regmap *cam_cc_sdm845_clocks[] = { [CAM_CC_PLL1_OUT_EVEN] = &cam_cc_pll1_out_even.clkr, [CAM_CC_PLL2] = &cam_cc_pll2.clkr, [CAM_CC_PLL2_OUT_EVEN] = &cam_cc_pll2_out_even.clkr, + [CAM_CC_PLL2_OUT_ODD] = &cam_cc_pll2_out_odd.clkr, [CAM_CC_PLL3] = &cam_cc_pll3.clkr, [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr, [CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, @@ -1667,6 +2052,19 @@ static struct clk_regmap *cam_cc_sdm845_clocks[] = { [CAM_CC_SYS_TMR_CLK] = &cam_cc_sys_tmr_clk.clkr, }; +static const struct qcom_reset_map cam_cc_sdm845_resets[] = { + [TITAN_CAM_CC_CCI_BCR] = { 0xb0d4 }, + [TITAN_CAM_CC_CPAS_BCR] = { 0xb118 }, + [TITAN_CAM_CC_CSI0PHY_BCR] = { 0x5000 }, + [TITAN_CAM_CC_CSI1PHY_BCR] = { 0x5024 }, + [TITAN_CAM_CC_CSI2PHY_BCR] = { 0x5048 }, + [TITAN_CAM_CC_MCLK0_BCR] = { 0x4000 }, + [TITAN_CAM_CC_MCLK1_BCR] = { 0x4020 }, + [TITAN_CAM_CC_MCLK2_BCR] = { 0x4040 }, + [TITAN_CAM_CC_MCLK3_BCR] = { 0x4060 }, + [TITAN_CAM_CC_TITAN_TOP_BCR] = { 0xb130 }, +}; + static struct gdsc *cam_cc_sdm845_gdscs[] = { [BPS_GDSC] = &bps_gdsc, [IPE_0_GDSC] = &ipe_0_gdsc, @@ -1684,45 +2082,97 @@ static const struct regmap_config cam_cc_sdm845_regmap_config = { .fast_io = true, }; -static const struct qcom_cc_desc cam_cc_sdm845_desc = { +static struct qcom_cc_desc cam_cc_sdm845_desc = { .config = &cam_cc_sdm845_regmap_config, .clks = cam_cc_sdm845_clocks, .num_clks = ARRAY_SIZE(cam_cc_sdm845_clocks), .gdscs = cam_cc_sdm845_gdscs, .num_gdscs = ARRAY_SIZE(cam_cc_sdm845_gdscs), + .resets = cam_cc_sdm845_resets, + .num_resets = ARRAY_SIZE(cam_cc_sdm845_resets), + .clk_regulators = cam_cc_sdm845_regulators, + .num_clk_regulators = ARRAY_SIZE(cam_cc_sdm845_regulators), }; static const struct of_device_id cam_cc_sdm845_match_table[] = { { .compatible = "qcom,sdm845-camcc" }, + { .compatible = "qcom,sdm670-camcc" }, { } }; MODULE_DEVICE_TABLE(of, cam_cc_sdm845_match_table); +static void cam_cc_sdm845_fixup_sdm670(void) +{ + cam_cc_cphy_rx_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = 384000000; + cam_cc_cphy_rx_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = 384000000; + cam_cc_fd_core_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = 384000000; + cam_cc_icp_clk_src.freq_tbl = ftbl_cam_cc_icp_clk_src_sdm670; + cam_cc_icp_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = 384000000; + cam_cc_icp_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] = 600000000; + cam_cc_ipe_0_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = 600000000; + cam_cc_ipe_1_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = 600000000; + cam_cc_lrme_clk_src.freq_tbl = ftbl_cam_cc_lrme_clk_src_sdm670; + cam_cc_lrme_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = 269333333; + cam_cc_lrme_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] = 320000000; + cam_cc_lrme_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = 400000000; + cam_cc_slow_ahb_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = 80000000; + cam_cc_slow_ahb_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = 80000000; + cam_cc_slow_ahb_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] = + 80000000; +} + static int cam_cc_sdm845_probe(struct platform_device *pdev) { struct regmap *regmap; struct alpha_pll_config cam_cc_pll_config = { }; + int ret; + bool sdm670; + + sdm670 = of_device_is_compatible(pdev->dev.of_node, + "qcom,sdm670-camcc"); regmap = qcom_cc_map(pdev, &cam_cc_sdm845_desc); if (IS_ERR(regmap)) return PTR_ERR(regmap); + if (sdm670) + cam_cc_sdm845_fixup_sdm670(); + + cam_cc_sdm845_desc.gdscs = NULL; + cam_cc_sdm845_desc.num_gdscs = 0; + + /* 600 MHz Configuration*/ cam_cc_pll_config.l = 0x1f; cam_cc_pll_config.alpha = 0x4000; clk_fabia_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll_config); + /* 808 MHz Configuration*/ cam_cc_pll_config.l = 0x2a; - cam_cc_pll_config.alpha = 0x1556; + cam_cc_pll_config.alpha = 0x1555; clk_fabia_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll_config); + /* 960 MHz Configuration*/ cam_cc_pll_config.l = 0x32; cam_cc_pll_config.alpha = 0x0; clk_fabia_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll_config); + /* 384 MHz Configuration*/ cam_cc_pll_config.l = 0x14; clk_fabia_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll_config); - return qcom_cc_really_probe(pdev, &cam_cc_sdm845_desc, regmap); + ret = qcom_cc_really_probe(pdev, &cam_cc_sdm845_desc, regmap); + if (ret) { + dev_err(&pdev->dev, "Failed to register Camera CC clocks\n"); + return ret; + } + + dev_info(&pdev->dev, "Registered Camera CC clocks\n"); + return ret; +} + +static void cam_cc_sdm845_sync_state(struct device *dev) +{ + qcom_cc_sync_state(dev, &cam_cc_sdm845_desc); } static struct platform_driver cam_cc_sdm845_driver = { @@ -1730,6 +2180,7 @@ static struct platform_driver cam_cc_sdm845_driver = { .driver = { .name = "sdm845-camcc", .of_match_table = cam_cc_sdm845_match_table, + .sync_state = cam_cc_sdm845_sync_state, }, }; diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c index 414ffb6feb02..d0ffd8a7a3de 100644 --- a/drivers/clk/qcom/dispcc-sdm845.c +++ b/drivers/clk/qcom/dispcc-sdm845.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -19,6 +20,13 @@ #include "common.h" #include "gdsc.h" #include "reset.h" +#include "vdd-level-sdm845.h" + +static DEFINE_VDD_REGULATORS(vdd_cx, VDD_NUM, 1, vdd_corner); + +static struct clk_vdd_class *disp_cc_sdm845_regulators[] = { + &vdd_cx, +}; enum { P_BI_TCXO, @@ -33,18 +41,34 @@ enum { P_DP_PHY_PLL_VCO_DIV_CLK, }; +static struct pll_vco fabia_vco[] = { + { 249600000, 2000000000, 0 }, + { 125000000, 1000000000, 1 }, +}; + static struct clk_alpha_pll disp_cc_pll0 = { .offset = 0x0, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), .clkr = { .hw.init = &(struct clk_init_data){ .name = "disp_cc_pll0", .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", .name = "bi_tcxo", + .fw_name = "bi_tcxo", }, .num_parents = 1, .ops = &clk_alpha_pll_fabia_ops, }, + .vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 615000000, + [VDD_LOW] = 1066000000, + [VDD_LOW_L1] = 1600000000, + [VDD_NOMINAL] = 2000000000 }, + }, }, }; @@ -55,7 +79,7 @@ static const struct parent_map disp_cc_parent_map_0[] = { }; static const struct clk_parent_data disp_cc_parent_data_0[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, { .fw_name = "dsi0_phy_pll_out_byteclk", .name = "dsi0_phy_pll_out_byteclk" }, { .fw_name = "dsi1_phy_pll_out_byteclk", .name = "dsi1_phy_pll_out_byteclk" }, }; @@ -67,7 +91,7 @@ static const struct parent_map disp_cc_parent_map_1[] = { }; static const struct clk_parent_data disp_cc_parent_data_1[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, { .fw_name = "dp_link_clk_divsel_ten", .name = "dp_link_clk_divsel_ten" }, { .fw_name = "dp_vco_divided_clk_src_mux", .name = "dp_vco_divided_clk_src_mux" }, }; @@ -77,7 +101,7 @@ static const struct parent_map disp_cc_parent_map_2[] = { }; static const struct clk_parent_data disp_cc_parent_data_2[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, }; static const struct parent_map disp_cc_parent_map_3[] = { @@ -88,7 +112,7 @@ static const struct parent_map disp_cc_parent_map_3[] = { }; static const struct clk_parent_data disp_cc_parent_data_3[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, { .hw = &disp_cc_pll0.clkr.hw }, { .fw_name = "gcc_disp_gpll0_clk_src", .name = "gcc_disp_gpll0_clk_src" }, { .fw_name = "gcc_disp_gpll0_div_clk_src", .name = "gcc_disp_gpll0_div_clk_src" }, @@ -101,7 +125,7 @@ static const struct parent_map disp_cc_parent_map_4[] = { }; static const struct clk_parent_data disp_cc_parent_data_4[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, { .fw_name = "dsi0_phy_pll_out_dsiclk", .name = "dsi0_phy_pll_out_dsiclk" }, { .fw_name = "dsi1_phy_pll_out_dsiclk", .name = "dsi1_phy_pll_out_dsiclk" }, }; @@ -119,6 +143,16 @@ static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { .flags = CLK_SET_RATE_PARENT, .ops = &clk_byte2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 150000000, + [VDD_LOW] = 240000000, + [VDD_LOW_L1] = 262500000, + [VDD_NOMINAL] = 358000000 }, + }, }; /* Return the HW recalc rate for idle use case */ @@ -134,6 +168,16 @@ static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = { .flags = CLK_SET_RATE_PARENT, .ops = &clk_byte2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 150000000, + [VDD_LOW] = 240000000, + [VDD_LOW_L1] = 262500000, + [VDD_NOMINAL] = 358000000 }, + }, }; static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = { @@ -154,6 +198,12 @@ static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000 }, + }, }; static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = { @@ -165,8 +215,19 @@ static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = { .name = "disp_cc_mdss_dp_crypto_clk_src", .parent_data = disp_cc_parent_data_1, .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_byte2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 12800000, + [VDD_LOWER] = 108000000, + [VDD_LOW] = 180000000, + [VDD_LOW_L1] = 360000000, + [VDD_NOMINAL] = 540000000 }, + }, }; static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { @@ -181,6 +242,16 @@ static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { .flags = CLK_SET_RATE_PARENT, .ops = &clk_byte2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 162000000, + [VDD_LOW] = 270000000, + [VDD_LOW_L1] = 540000000, + [VDD_NOMINAL] = 810000000 }, + }, }; static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = { @@ -195,6 +266,15 @@ static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = { .flags = CLK_SET_RATE_PARENT, .ops = &clk_dp_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 202500000, + [VDD_LOW] = 296735000, + [VDD_LOW_L1] = 675000000 }, + }, }; static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = { @@ -209,6 +289,15 @@ static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = { .flags = CLK_SET_RATE_PARENT, .ops = &clk_dp_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 202500000, + [VDD_LOW] = 296735000, + [VDD_LOW_L1] = 675000000 }, + }, }; static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = { @@ -226,8 +315,15 @@ static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { .name = "disp_cc_mdss_esc0_clk_src", .parent_data = disp_cc_parent_data_0, .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000 }, + }, }; static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { @@ -242,15 +338,35 @@ static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000 }, + }, }; static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(165000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(275000000, P_DISP_CC_PLL0_OUT_MAIN, 1.5, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + F(412500000, P_DISP_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src_sdm670[] = { F(19200000, P_BI_TCXO, 1, 0, 0), F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0), F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(286666667, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), @@ -267,8 +383,18 @@ static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { .name = "disp_cc_mdss_mdp_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 165000000, + [VDD_LOW] = 300000000, + [VDD_NOMINAL] = 412500000 }, + }, }; /* Return the HW recalc rate for idle use case */ @@ -284,6 +410,16 @@ static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { .flags = CLK_SET_RATE_PARENT, .ops = &clk_pixel_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 184000000, + [VDD_LOW] = 295000000, + [VDD_LOW_L1] = 350000000, + [VDD_NOMINAL] = 571428571 }, + }, }; /* Return the HW recalc rate for idle use case */ @@ -299,9 +435,27 @@ static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { .flags = CLK_SET_RATE_PARENT, .ops = &clk_pixel_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 184000000, + [VDD_LOW] = 295000000, + [VDD_LOW_L1] = 350000000, + [VDD_NOMINAL] = 571428571 }, + }, }; static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(165000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + F(412500000, P_DISP_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src_sdm670[] = { F(19200000, P_BI_TCXO, 1, 0, 0), F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), @@ -320,8 +474,18 @@ static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { .name = "disp_cc_mdss_rot_clk_src", .parent_data = disp_cc_parent_data_3, .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 165000000, + [VDD_LOW] = 300000000, + [VDD_NOMINAL] = 412500000 }, + }, }; static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { @@ -334,8 +498,15 @@ static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { .name = "disp_cc_mdss_vsync_clk_src", .parent_data = disp_cc_parent_data_2, .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000 }, + }, }; static struct clk_branch disp_cc_mdss_ahb_clk = { @@ -829,7 +1000,7 @@ static const struct regmap_config disp_cc_sdm845_regmap_config = { .fast_io = true, }; -static const struct qcom_cc_desc disp_cc_sdm845_desc = { +static struct qcom_cc_desc disp_cc_sdm845_desc = { .config = &disp_cc_sdm845_regmap_config, .clks = disp_cc_sdm845_clocks, .num_clks = ARRAY_SIZE(disp_cc_sdm845_clocks), @@ -837,23 +1008,86 @@ static const struct qcom_cc_desc disp_cc_sdm845_desc = { .num_resets = ARRAY_SIZE(disp_cc_sdm845_resets), .gdscs = disp_cc_sdm845_gdscs, .num_gdscs = ARRAY_SIZE(disp_cc_sdm845_gdscs), + .clk_regulators = disp_cc_sdm845_regulators, + .num_clk_regulators = ARRAY_SIZE(disp_cc_sdm845_regulators), }; static const struct of_device_id disp_cc_sdm845_match_table[] = { { .compatible = "qcom,sdm845-dispcc" }, + { .compatible = "qcom,sdm670-dispcc" }, { } }; MODULE_DEVICE_TABLE(of, disp_cc_sdm845_match_table); +static void disp_cc_sdm845_fixup_sdm670(void) +{ + disp_cc_mdss_byte0_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = + 180000000; + disp_cc_mdss_byte0_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = + 275000000; + disp_cc_mdss_byte0_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] = + 358000000; + disp_cc_mdss_byte1_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = + 180000000; + disp_cc_mdss_byte1_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = + 275000000; + disp_cc_mdss_byte1_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] = + 358000000; + disp_cc_mdss_dp_pixel1_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = + 337500000; + disp_cc_mdss_dp_pixel_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = + 337500000; + disp_cc_mdss_mdp_clk_src.freq_tbl = + ftbl_disp_cc_mdss_mdp_clk_src_sdm670; + disp_cc_mdss_mdp_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = + 171428571; + disp_cc_mdss_mdp_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] = + 344000000; + disp_cc_mdss_mdp_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 430000000; + disp_cc_mdss_pclk0_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = + 280000000; + disp_cc_mdss_pclk0_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = + 430000000; + disp_cc_mdss_pclk0_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] = + 430000000; + disp_cc_mdss_pclk1_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = + 280000000; + disp_cc_mdss_pclk1_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = + 430000000; + disp_cc_mdss_pclk1_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] = + 430000000; + disp_cc_mdss_rot_clk_src.freq_tbl = + ftbl_disp_cc_mdss_rot_clk_src_sdm670; + disp_cc_mdss_rot_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = + 171428571; + disp_cc_mdss_rot_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] = + 344000000; + disp_cc_mdss_rot_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 430000000; +} + static int disp_cc_sdm845_probe(struct platform_device *pdev) { struct regmap *regmap; struct alpha_pll_config disp_cc_pll0_config = {}; + int ret; + bool sdm670; + + sdm670 = of_device_is_compatible(pdev->dev.of_node, + "qcom,sdm670-dispcc"); regmap = qcom_cc_map(pdev, &disp_cc_sdm845_desc); if (IS_ERR(regmap)) return PTR_ERR(regmap); + if (sdm670) + disp_cc_sdm845_fixup_sdm670(); + + disp_cc_sdm845_desc.gdscs = NULL; + disp_cc_sdm845_desc.num_gdscs = 0; + + /* 960 MHz Configuration*/ disp_cc_pll0_config.l = 0x2c; disp_cc_pll0_config.alpha = 0xcaaa; @@ -862,7 +1096,19 @@ static int disp_cc_sdm845_probe(struct platform_device *pdev) /* Enable hardware clock gating for DSI and MDP clocks */ regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0); - return qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap); + ret = qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap); + if (ret) { + dev_err(&pdev->dev, "Failed to register Display CC clocks\n"); + return ret; + } + + dev_info(&pdev->dev, "Registered Display CC clocks\n"); + return ret; +} + +static void disp_cc_sdm845_sync_state(struct device *dev) +{ + qcom_cc_sync_state(dev, &disp_cc_sdm845_desc); } static struct platform_driver disp_cc_sdm845_driver = { @@ -870,7 +1116,7 @@ static struct platform_driver disp_cc_sdm845_driver = { .driver = { .name = "disp_cc-sdm845", .of_match_table = disp_cc_sdm845_match_table, - .sync_state = clk_sync_state, + .sync_state = disp_cc_sdm845_sync_state, }, }; diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index c2f093f6ae61..1c02eccf1e03 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -21,9 +22,18 @@ #include "clk-pll.h" #include "clk-rcg.h" #include "clk-branch.h" -#include "clk-alpha-pll.h" -#include "gdsc.h" #include "reset.h" +#include "gdsc.h" +#include "clk-alpha-pll.h" +#include "vdd-level-sdm845.h" + +static DEFINE_VDD_REGULATORS(vdd_cx, VDD_NUM, 1, vdd_corner); +static DEFINE_VDD_REGULATORS(vdd_cx_ao, VDD_NUM, 1, vdd_corner); + +static struct clk_vdd_class *gcc_sdm845_regulators[] = { + &vdd_cx, + &vdd_cx_ao, +}; enum { P_BI_TCXO, @@ -31,6 +41,7 @@ enum { P_GPLL0_OUT_EVEN, P_GPLL0_OUT_MAIN, P_GPLL4_OUT_MAIN, + P_GPLL6_OUT_MAIN, P_SLEEP_CLK, }; @@ -43,11 +54,20 @@ static struct clk_alpha_pll gpll0 = { .hw.init = &(struct clk_init_data){ .name = "gpll0", .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", .name = "bi_tcxo", + .fw_name = "bi_tcxo", }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, }, + .vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 615000000, + [VDD_LOW] = 1066000000, + [VDD_LOW_L1] = 1600000000, + [VDD_NOMINAL] = 2000000000}, + }, }, }; @@ -60,11 +80,20 @@ static struct clk_alpha_pll gpll4 = { .hw.init = &(struct clk_init_data){ .name = "gpll4", .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", .name = "bi_tcxo", + .fw_name = "bi_tcxo", }, .num_parents = 1, .ops = &clk_alpha_pll_fixed_fabia_ops, }, + .vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 615000000, + [VDD_LOW] = 1066000000, + [VDD_LOW_L1] = 1600000000, + [VDD_NOMINAL] = 2000000000}, + }, }, }; @@ -93,6 +122,32 @@ static struct clk_alpha_pll_postdiv gpll0_out_even = { }, }; +static struct clk_alpha_pll gpll6 = { + .offset = 0x13000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "gpll6", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_fabia_ops, + }, + .vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 615000000, + [VDD_LOW] = 1066000000, + [VDD_LOW_L1] = 1600000000, + [VDD_NOMINAL] = 2000000000}, + }, + }, +}; + static const struct parent_map gcc_parent_map_0[] = { { P_BI_TCXO, 0 }, { P_GPLL0_OUT_MAIN, 1 }, @@ -100,7 +155,7 @@ static const struct parent_map gcc_parent_map_0[] = { }; static const struct clk_parent_data gcc_parent_data_0[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, { .hw = &gpll0.clkr.hw }, { .hw = &gpll0_out_even.clkr.hw }, }; @@ -113,7 +168,7 @@ static const struct parent_map gcc_parent_map_1[] = { }; static const struct clk_parent_data gcc_parent_data_1[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, { .hw = &gpll0.clkr.hw }, { .fw_name = "sleep_clk", .name = "core_pi_sleep_clk" }, { .hw = &gpll0_out_even.clkr.hw }, @@ -125,7 +180,7 @@ static const struct parent_map gcc_parent_map_2[] = { }; static const struct clk_parent_data gcc_parent_data_2[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, { .fw_name = "sleep_clk", .name = "core_pi_sleep_clk" }, }; @@ -135,7 +190,7 @@ static const struct parent_map gcc_parent_map_3[] = { }; static const struct clk_parent_data gcc_parent_data_3[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, { .hw = &gpll0.clkr.hw }, }; @@ -144,7 +199,7 @@ static const struct parent_map gcc_parent_map_4[] = { }; static const struct clk_parent_data gcc_parent_data_4[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, }; static const struct parent_map gcc_parent_map_6[] = { @@ -155,7 +210,7 @@ static const struct parent_map gcc_parent_map_6[] = { }; static const struct clk_parent_data gcc_parent_data_6[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, { .hw = &gpll0.clkr.hw }, { .fw_name = "aud_ref_clk", .name = "aud_ref_clk" }, { .hw = &gpll0_out_even.clkr.hw }, @@ -169,7 +224,7 @@ static const struct clk_parent_data gcc_parent_data_7_ao[] = { }; static const struct clk_parent_data gcc_parent_data_8[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, { .hw = &gpll0.clkr.hw }, { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, }; @@ -188,12 +243,25 @@ static const struct parent_map gcc_parent_map_10[] = { }; static const struct clk_parent_data gcc_parent_data_10[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, { .hw = &gpll0.clkr.hw }, { .hw = &gpll4.clkr.hw }, { .hw = &gpll0_out_even.clkr.hw }, }; +static const struct parent_map gcc_parent_map_11[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_MAIN, 1 }, + { P_GPLL6_OUT_MAIN, 2 }, + { P_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_11[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll6.clkr.hw }, + { .hw = &gpll0_out_even.clkr.hw }, +}; static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { F(19200000, P_BI_TCXO, 1, 0, 0), @@ -210,8 +278,17 @@ static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { .name = "gcc_cpuss_ahb_clk_src", .parent_data = gcc_parent_data_7_ao, .num_parents = ARRAY_SIZE(gcc_parent_data_7_ao), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOW] = 50000000, + [VDD_NOMINAL] = 100000000}, + }, }; static const struct freq_tbl ftbl_gcc_cpuss_rbcpr_clk_src[] = { @@ -219,6 +296,12 @@ static const struct freq_tbl ftbl_gcc_cpuss_rbcpr_clk_src[] = { { } }; +static const struct freq_tbl ftbl_gcc_cpuss_rbcpr_clk_src_sdm670[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0), + { } +}; + static struct clk_rcg2 gcc_cpuss_rbcpr_clk_src = { .cmd_rcgr = 0x4815c, .mnd_width = 0, @@ -229,8 +312,16 @@ static struct clk_rcg2 gcc_cpuss_rbcpr_clk_src = { .name = "gcc_cpuss_rbcpr_clk_src", .parent_data = gcc_parent_data_8_ao, .num_parents = ARRAY_SIZE(gcc_parent_data_8_ao), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + }, + }, }; static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { @@ -252,8 +343,18 @@ static struct clk_rcg2 gcc_gp1_clk_src = { .name = "gcc_gp1_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 50000000, + [VDD_LOW] = 100000000, + [VDD_NOMINAL] = 200000000}, + }, }; static struct clk_rcg2 gcc_gp2_clk_src = { @@ -266,8 +367,18 @@ static struct clk_rcg2 gcc_gp2_clk_src = { .name = "gcc_gp2_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 50000000, + [VDD_LOW] = 100000000, + [VDD_NOMINAL] = 200000000}, + }, }; static struct clk_rcg2 gcc_gp3_clk_src = { @@ -280,8 +391,18 @@ static struct clk_rcg2 gcc_gp3_clk_src = { .name = "gcc_gp3_clk_src", .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 50000000, + [VDD_LOW] = 100000000, + [VDD_NOMINAL] = 200000000}, + }, }; static const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = { @@ -300,8 +421,16 @@ static struct clk_rcg2 gcc_pcie_0_aux_clk_src = { .name = "gcc_pcie_0_aux_clk_src", .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 9600000, + [VDD_LOW] = 19200000}, + }, }; static struct clk_rcg2 gcc_pcie_1_aux_clk_src = { @@ -314,8 +443,16 @@ static struct clk_rcg2 gcc_pcie_1_aux_clk_src = { .name = "gcc_pcie_1_aux_clk_src", .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 9600000, + [VDD_LOW] = 19200000}, + }, }; static const struct freq_tbl ftbl_gcc_pcie_phy_refgen_clk_src[] = { @@ -334,29 +471,15 @@ static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = { .name = "gcc_pcie_phy_refgen_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, -}; - -static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = { - F(19200000, P_BI_TCXO, 1, 0, 0), - F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), - F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), - F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), - { } -}; - -static struct clk_rcg2 gcc_qspi_core_clk_src = { - .cmd_rcgr = 0x4b008, - .mnd_width = 0, - .hid_width = 5, - .parent_map = gcc_parent_map_0, - .freq_tbl = ftbl_gcc_qspi_core_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qspi_core_clk_src", - .parent_data = gcc_parent_data_0, - .num_parents = ARRAY_SIZE(gcc_parent_data_0), - .ops = &clk_rcg2_floor_ops, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOW] = 100000000}, }, }; @@ -377,11 +500,35 @@ static struct clk_rcg2 gcc_pdm2_clk_src = { .name = "gcc_pdm2_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 9600000, + [VDD_LOWER] = 19200000, + [VDD_LOW] = 60000000}, + }, }; static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75), + F(38400000, P_GPLL0_OUT_EVEN, 1, 16, 125), + F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25), + F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75), + F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670[] = { F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625), F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625), F(19200000, P_BI_TCXO, 1, 0, 0), @@ -404,6 +551,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { .name = "gcc_qupv3_wrap0_s0_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -413,13 +561,22 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { .name = "gcc_qupv3_wrap0_s1_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -430,12 +587,21 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { .name = "gcc_qupv3_wrap0_s2_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -446,12 +612,21 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { .name = "gcc_qupv3_wrap0_s3_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -462,12 +637,22 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, + + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { .name = "gcc_qupv3_wrap0_s4_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -478,12 +663,21 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { .name = "gcc_qupv3_wrap0_s5_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -494,12 +688,21 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = { .name = "gcc_qupv3_wrap0_s6_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -510,12 +713,21 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = { .name = "gcc_qupv3_wrap0_s7_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -526,12 +738,21 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { .name = "gcc_qupv3_wrap1_s0_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -542,12 +763,21 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { .name = "gcc_qupv3_wrap1_s1_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -557,13 +787,22 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { .name = "gcc_qupv3_wrap1_s2_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -574,12 +813,21 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { .name = "gcc_qupv3_wrap1_s3_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -590,12 +838,21 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { .name = "gcc_qupv3_wrap1_s4_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -606,12 +863,21 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { .name = "gcc_qupv3_wrap1_s5_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -622,12 +888,21 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = { .name = "gcc_qupv3_wrap1_s6_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -638,12 +913,21 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, }; static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = { .name = "gcc_qupv3_wrap1_s7_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }; @@ -654,6 +938,83 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_src_init, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 75000000, + [VDD_LOW] = 100000000}, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = { + F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x26010, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src, + .enable_safe_config = true, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 75000000, + [VDD_LOW] = 150000000, + [VDD_NOMINAL] = 300000000}, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = { + F(144000, P_BI_TCXO, 16, 3, 25), + F(400000, P_BI_TCXO, 12, 1, 4), + F(20000000, P_GPLL0_OUT_EVEN, 5, 1, 3), + F(25000000, P_GPLL0_OUT_EVEN, 6, 1, 2), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0), + F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { + .cmd_rcgr = 0x26028, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_11, + .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src, + .enable_safe_config = true, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk_src", + .parent_data = gcc_parent_data_11, + .num_parents = ARRAY_SIZE(gcc_parent_data_11), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 50000000, + [VDD_LOW] = 100000000, + [VDD_NOMINAL] = 384000000}, + }, }; static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { @@ -673,12 +1034,23 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_10, .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_10, .num_parents = ARRAY_SIZE(gcc_parent_data_10), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_floor_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 9600000, + [VDD_LOWER] = 19200000, + [VDD_LOW] = 100000000, + [VDD_LOW_L1] = 201500000}, + }, }; static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = { @@ -691,18 +1063,40 @@ static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = { { } }; +static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src_sdm670[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(33333333, P_GPLL0_OUT_EVEN, 9, 0, 0), + F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .cmd_rcgr = 0x1600c, .mnd_width = 8, .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src, + .enable_safe_config = true, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_sdcc4_apps_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_floor_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 9600000, + [VDD_LOWER] = 19200000, + [VDD_LOW] = 50000000, + [VDD_NOMINAL] = 100000000}, + }, }; static const struct freq_tbl ftbl_gcc_tsif_ref_clk_src[] = { @@ -720,11 +1114,26 @@ static struct clk_rcg2 gcc_tsif_ref_clk_src = { .name = "gcc_tsif_ref_clk_src", .parent_data = gcc_parent_data_6, .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 105495}, + }, }; static const struct freq_tbl ftbl_gcc_ufs_card_axi_clk_src[] = { + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_gcc_ufs_card_axi_clk_src_sdm670[] = { F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), @@ -739,12 +1148,22 @@ static struct clk_rcg2 gcc_ufs_card_axi_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_ufs_card_axi_clk_src, + .flags = FORCE_ENABLE_RCG, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_card_axi_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 50000000, + [VDD_LOW] = 100000000, + [VDD_NOMINAL] = 200000000}, + }, }; static const struct freq_tbl ftbl_gcc_ufs_card_ice_core_clk_src[] = { @@ -761,12 +1180,22 @@ static struct clk_rcg2 gcc_ufs_card_ice_core_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src, + .flags = FORCE_ENABLE_RCG, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_card_ice_core_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 75000000, + [VDD_LOW] = 150000000, + [VDD_NOMINAL] = 300000000}, + }, }; static struct clk_rcg2 gcc_ufs_card_phy_aux_clk_src = { @@ -775,12 +1204,20 @@ static struct clk_rcg2 gcc_ufs_card_phy_aux_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_4, .freq_tbl = ftbl_gcc_cpuss_rbcpr_clk_src, + .flags = FORCE_ENABLE_RCG, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_card_phy_aux_clk_src", .parent_data = gcc_parent_data_4, .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000}, + }, }; static const struct freq_tbl ftbl_gcc_ufs_card_unipro_core_clk_src[] = { @@ -796,12 +1233,22 @@ static struct clk_rcg2 gcc_ufs_card_unipro_core_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_ufs_card_unipro_core_clk_src, + .flags = FORCE_ENABLE_RCG, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_card_unipro_core_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 37500000, + [VDD_LOW] = 75000000, + [VDD_NOMINAL] = 150000000}, + }, }; static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = { @@ -819,12 +1266,23 @@ static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, + .flags = FORCE_ENABLE_RCG, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_axi_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 50000000, + [VDD_LOW] = 100000000, + [VDD_NOMINAL] = 200000000, + [VDD_HIGH] = 240000000}, + }, }; static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { @@ -833,12 +1291,22 @@ static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_ufs_card_ice_core_clk_src, + .flags = FORCE_ENABLE_RCG, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_ice_core_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 75000000, + [VDD_LOW] = 150000000, + [VDD_NOMINAL] = 300000000}, + }, }; static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { @@ -847,12 +1315,20 @@ static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_4, .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .flags = FORCE_ENABLE_RCG, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_phy_aux_clk_src", .parent_data = gcc_parent_data_4, .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000}, + }, }; static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { @@ -861,12 +1337,22 @@ static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_ufs_card_unipro_core_clk_src, + .flags = FORCE_ENABLE_RCG, .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_unipro_core_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 37500000, + [VDD_LOW] = 75000000, + [VDD_NOMINAL] = 150000000}, + }, }; static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { @@ -888,8 +1374,19 @@ static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { .name = "gcc_usb30_prim_master_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 33333333, + [VDD_LOWER] = 66666667, + [VDD_LOW] = 133333333, + [VDD_NOMINAL] = 200000000, + [VDD_HIGH] = 240000000}, + }, }; static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = { @@ -910,8 +1407,17 @@ static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { .name = "gcc_usb30_prim_mock_utmi_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 40000000, + [VDD_LOW] = 60000000}, + }, }; static struct clk_rcg2 gcc_usb30_sec_master_clk_src = { @@ -924,8 +1430,19 @@ static struct clk_rcg2 gcc_usb30_sec_master_clk_src = { .name = "gcc_usb30_sec_master_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 33333333, + [VDD_LOWER] = 66666667, + [VDD_LOW] = 133333333, + [VDD_NOMINAL] = 200000000, + [VDD_HIGH] = 240000000}, + }, }; static struct clk_rcg2 gcc_usb30_sec_mock_utmi_clk_src = { @@ -938,8 +1455,17 @@ static struct clk_rcg2 gcc_usb30_sec_mock_utmi_clk_src = { .name = "gcc_usb30_sec_mock_utmi_clk_src", .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOWER] = 40000000, + [VDD_LOW] = 60000000}, + }, }; static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { @@ -952,8 +1478,15 @@ static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { .name = "gcc_usb3_prim_phy_aux_clk_src", .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000}, + }, }; static struct clk_rcg2 gcc_usb3_sec_phy_aux_clk_src = { @@ -966,8 +1499,15 @@ static struct clk_rcg2 gcc_usb3_sec_phy_aux_clk_src = { .name = "gcc_usb3_sec_phy_aux_clk_src", .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000}, + }, }; static struct clk_rcg2 gcc_vs_ctrl_clk_src = { @@ -980,8 +1520,15 @@ static struct clk_rcg2 gcc_vs_ctrl_clk_src = { .name = "gcc_vs_ctrl_clk_src", .parent_data = gcc_parent_data_3, .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000}, + }, }; static const struct freq_tbl ftbl_gcc_vsensor_clk_src[] = { @@ -1001,8 +1548,17 @@ static struct clk_rcg2 gcc_vsensor_clk_src = { .name = "gcc_vsensor_clk_src", .parent_data = gcc_parent_data_8, .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 19200000, + [VDD_LOW] = 300000000, + [VDD_LOW_L1] = 600000000}, + }, }; static struct clk_branch gcc_aggre_noc_pcie_tbu_clk = { @@ -1127,22 +1683,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = { }, }; -static struct clk_branch gcc_camera_ahb_clk = { - .halt_reg = 0xb008, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb008, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb008, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_ahb_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_camera_axi_clk = { .halt_reg = 0xb020, .halt_check = BRANCH_VOTED, @@ -1156,20 +1696,6 @@ static struct clk_branch gcc_camera_axi_clk = { }, }; -static struct clk_branch gcc_camera_xo_clk = { - .halt_reg = 0xb02c, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb02c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_camera_xo_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_ce1_ahb_clk = { .halt_reg = 0x4100c, .halt_check = BRANCH_HALT_VOTED, @@ -1296,22 +1822,6 @@ static struct clk_branch gcc_ddrss_gpu_axi_clk = { }, }; -static struct clk_branch gcc_disp_ahb_clk = { - .halt_reg = 0xb00c, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb00c, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb00c, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_ahb_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_disp_axi_clk = { .halt_reg = 0xb024, .halt_check = BRANCH_VOTED, @@ -1326,6 +1836,7 @@ static struct clk_branch gcc_disp_axi_clk = { }; static struct clk_branch gcc_disp_gpll0_clk_src = { + .halt_reg = 0x52004, .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x52004, @@ -1336,12 +1847,14 @@ static struct clk_branch gcc_disp_gpll0_clk_src = { &gpll0.clkr.hw, }, .num_parents = 1, - .ops = &clk_branch2_aon_ops, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, }, }, }; static struct clk_branch gcc_disp_gpll0_div_clk_src = { + .halt_reg = 0x52004, .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x52004, @@ -1352,20 +1865,7 @@ static struct clk_branch gcc_disp_gpll0_div_clk_src = { &gpll0_out_even.clkr.hw, }, .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch gcc_disp_xo_clk = { - .halt_reg = 0xb030, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb030, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_disp_xo_clk", - .flags = CLK_IS_CRITICAL, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1425,23 +1925,8 @@ static struct clk_branch gcc_gp3_clk = { }, }; -static struct clk_branch gcc_gpu_cfg_ahb_clk = { - .halt_reg = 0x71004, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0x71004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x71004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_gpu_cfg_ahb_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_reg = 0x52004, .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x52004, @@ -1452,12 +1937,14 @@ static struct clk_branch gcc_gpu_gpll0_clk_src = { &gpll0.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, }; static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_reg = 0x52004, .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x52004, @@ -1468,6 +1955,7 @@ static struct clk_branch gcc_gpu_gpll0_div_clk_src = { &gpll0_out_even.clkr.hw, }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -1559,6 +2047,7 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = { }; static struct clk_branch gcc_mss_gpll0_div_clk_src = { + .halt_reg = 0x52004, .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x52004, @@ -1689,6 +2178,7 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = { }; static struct clk_branch gcc_pcie_0_pipe_clk = { + .halt_reg = 0x6b020, .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x5200c, @@ -1793,6 +2283,7 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = { }; static struct clk_branch gcc_pcie_1_pipe_clk = { + .halt_reg = 0x8d020, .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x52004, @@ -1977,38 +2468,6 @@ static struct clk_branch gcc_qmip_video_ahb_clk = { }, }, }; - -static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = { - .halt_reg = 0x4b000, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x4b000, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_qspi_cnoc_periph_ahb_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch gcc_qspi_core_clk = { - .halt_reg = 0x4b004, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x4b004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_qspi_core_clk", - .parent_hws = (const struct clk_hw*[]){ - &gcc_qspi_core_clk_src.clkr.hw, - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_qupv3_wrap0_s0_clk = { .halt_reg = 0x17030, .halt_check = BRANCH_HALT_VOTED, @@ -2353,6 +2812,55 @@ static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { }, }; +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x2600c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_sdcc1_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x26008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x26008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x26004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x26004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_sdcc1_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_sdcc2_ahb_clk = { .halt_reg = 0x14008, .halt_check = BRANCH_HALT, @@ -2566,6 +3074,7 @@ static struct clk_branch gcc_ufs_card_phy_aux_clk = { }; static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = { + .halt_reg = 0x75018, .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x75018, @@ -2578,6 +3087,7 @@ static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = { }; static struct clk_branch gcc_ufs_card_rx_symbol_1_clk = { + .halt_reg = 0x750a8, .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x750a8, @@ -2590,6 +3100,7 @@ static struct clk_branch gcc_ufs_card_rx_symbol_1_clk = { }; static struct clk_branch gcc_ufs_card_tx_symbol_0_clk = { + .halt_reg = 0x75014, .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x75014, @@ -2710,6 +3221,7 @@ static struct clk_branch gcc_ufs_phy_phy_aux_clk = { }; static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { + .halt_reg = 0x77018, .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x77018, @@ -2722,6 +3234,7 @@ static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { }; static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { + .halt_reg = 0x770a8, .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x770a8, @@ -2734,6 +3247,7 @@ static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { }; static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { + .halt_reg = 0x77014, .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x77014, @@ -2913,6 +3427,7 @@ static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { }; static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0xf054, .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0xf054, @@ -2974,6 +3489,7 @@ static struct clk_branch gcc_usb3_sec_phy_com_aux_clk = { }; static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { + .halt_reg = 0x10054, .halt_check = BRANCH_HALT_SKIP, .clkr = { .enable_reg = 0x10054, @@ -3054,22 +3570,6 @@ static struct clk_branch gcc_vddmx_vs_clk = { }, }; -static struct clk_branch gcc_video_ahb_clk = { - .halt_reg = 0xb004, - .halt_check = BRANCH_HALT, - .hwcg_reg = 0xb004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0xb004, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_video_ahb_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_video_axi_clk = { .halt_reg = 0xb01c, .halt_check = BRANCH_VOTED, @@ -3083,20 +3583,6 @@ static struct clk_branch gcc_video_axi_clk = { }, }; -static struct clk_branch gcc_video_xo_clk = { - .halt_reg = 0xb028, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0xb028, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_video_xo_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_vs_ctrl_ahb_clk = { .halt_reg = 0x7a014, .halt_check = BRANCH_HALT, @@ -3130,67 +3616,6 @@ static struct clk_branch gcc_vs_ctrl_clk = { }, }; -static struct clk_branch gcc_cpuss_dvm_bus_clk = { - .halt_reg = 0x48190, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x48190, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_cpuss_dvm_bus_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch gcc_cpuss_gnoc_clk = { - .halt_reg = 0x48004, - .halt_check = BRANCH_HALT_VOTED, - .hwcg_reg = 0x48004, - .hwcg_bit = 1, - .clkr = { - .enable_reg = 0x52004, - .enable_mask = BIT(22), - .hw.init = &(struct clk_init_data){ - .name = "gcc_cpuss_gnoc_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - -/* TODO: Remove after DTS updated to protect these */ -#ifdef CONFIG_SDM_LPASSCC_845 -static struct clk_branch gcc_lpass_q6_axi_clk = { - .halt_reg = 0x47000, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x47000, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_lpass_q6_axi_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; - -static struct clk_branch gcc_lpass_sway_clk = { - .halt_reg = 0x47008, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x47008, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_lpass_sway_clk", - .flags = CLK_IS_CRITICAL, - .ops = &clk_branch2_ops, - }, - }, -}; -#endif - static struct gdsc pcie_0_gdsc = { .gdscr = 0x6b004, .pd = { @@ -3316,9 +3741,7 @@ static struct clk_regmap *gcc_sdm845_clocks[] = { [GCC_AGGRE_USB3_SEC_AXI_CLK] = &gcc_aggre_usb3_sec_axi_clk.clkr, [GCC_APC_VS_CLK] = &gcc_apc_vs_clk.clkr, [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, - [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr, [GCC_CAMERA_AXI_CLK] = &gcc_camera_axi_clk.clkr, - [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr, [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr, [GCC_CE1_CLK] = &gcc_ce1_clk.clkr, @@ -3329,18 +3752,15 @@ static struct clk_regmap *gcc_sdm845_clocks[] = { [GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr, [GCC_CPUSS_RBCPR_CLK_SRC] = &gcc_cpuss_rbcpr_clk_src.clkr, [GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr, - [GCC_DISP_AHB_CLK] = &gcc_disp_ahb_clk.clkr, [GCC_DISP_AXI_CLK] = &gcc_disp_axi_clk.clkr, [GCC_DISP_GPLL0_CLK_SRC] = &gcc_disp_gpll0_clk_src.clkr, [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr, - [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr, [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, - [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr, [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, [GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr, @@ -3483,9 +3903,7 @@ static struct clk_regmap *gcc_sdm845_clocks[] = { [GCC_VDDA_VS_CLK] = &gcc_vdda_vs_clk.clkr, [GCC_VDDCX_VS_CLK] = &gcc_vddcx_vs_clk.clkr, [GCC_VDDMX_VS_CLK] = &gcc_vddmx_vs_clk.clkr, - [GCC_VIDEO_AHB_CLK] = &gcc_video_ahb_clk.clkr, [GCC_VIDEO_AXI_CLK] = &gcc_video_axi_clk.clkr, - [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr, [GCC_VS_CTRL_AHB_CLK] = &gcc_vs_ctrl_ahb_clk.clkr, [GCC_VS_CTRL_CLK] = &gcc_vs_ctrl_clk.clkr, [GCC_VS_CTRL_CLK_SRC] = &gcc_vs_ctrl_clk_src.clkr, @@ -3493,15 +3911,12 @@ static struct clk_regmap *gcc_sdm845_clocks[] = { [GPLL0] = &gpll0.clkr, [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, [GPLL4] = &gpll4.clkr, - [GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr, - [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr, - [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr, - [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr, - [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr, -#ifdef CONFIG_SDM_LPASSCC_845 - [GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr, - [GCC_LPASS_SWAY_CLK] = &gcc_lpass_sway_clk.clkr, -#endif + [GCC_SDCC1_AHB_CLK] = NULL, + [GCC_SDCC1_APPS_CLK] = NULL, + [GCC_SDCC1_ICE_CORE_CLK] = NULL, + [GCC_SDCC1_APPS_CLK_SRC] = NULL, + [GCC_SDCC1_ICE_CORE_CLK_SRC] = NULL, + [GPLL6] = NULL, }; static const struct qcom_reset_map gcc_sdm845_resets[] = { @@ -3531,6 +3946,7 @@ static const struct qcom_reset_map gcc_sdm845_resets[] = { [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x6a000 }, [GCC_PCIE_0_PHY_BCR] = { 0x6c01c }, [GCC_PCIE_1_PHY_BCR] = { 0x8e01c }, + [GCC_SDCC1_BCR] = { 0x26000 }, }; static struct gdsc *gcc_sdm845_gdscs[] = { @@ -3563,7 +3979,7 @@ static const struct regmap_config gcc_sdm845_regmap_config = { .fast_io = true, }; -static const struct qcom_cc_desc gcc_sdm845_desc = { +static struct qcom_cc_desc gcc_sdm845_desc = { .config = &gcc_sdm845_regmap_config, .clks = gcc_sdm845_clocks, .num_clks = ARRAY_SIZE(gcc_sdm845_clocks), @@ -3571,10 +3987,13 @@ static const struct qcom_cc_desc gcc_sdm845_desc = { .num_resets = ARRAY_SIZE(gcc_sdm845_resets), .gdscs = gcc_sdm845_gdscs, .num_gdscs = ARRAY_SIZE(gcc_sdm845_gdscs), + .clk_regulators = gcc_sdm845_regulators, + .num_clk_regulators = ARRAY_SIZE(gcc_sdm845_regulators), }; static const struct of_device_id gcc_sdm845_match_table[] = { - { .compatible = "qcom,gcc-sdm845" }, + { .compatible = "qcom,sdm845-gcc" }, + { .compatible = "qcom,sdm670-gcc" }, { } }; MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table); @@ -3598,10 +4017,189 @@ static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk_src), }; +static void gcc_sdm845_fixup_sdm670(void) +{ + gcc_qupv3_wrap0_s0_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap0_s0_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap0_s0_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap0_s1_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap0_s1_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap0_s1_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap0_s2_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap0_s2_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap0_s2_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap0_s3_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap0_s3_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap0_s3_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap0_s4_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap0_s4_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap0_s4_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap0_s5_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap0_s5_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap0_s5_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap0_s6_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap0_s6_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap0_s6_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap0_s7_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap0_s7_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap0_s7_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap1_s0_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap1_s0_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap1_s0_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap1_s1_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap1_s1_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap1_s1_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap1_s2_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap1_s2_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap1_s2_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap1_s3_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap1_s3_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap1_s3_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap1_s4_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap1_s4_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap1_s4_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap1_s5_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap1_s5_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap1_s5_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap1_s6_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap1_s6_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap1_s6_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_qupv3_wrap1_s7_clk_src.freq_tbl = + ftbl_gcc_qupv3_wrap0_s0_clk_src_sdm670; + gcc_qupv3_wrap1_s7_clk_src.clkr.vdd_data.rate_max[VDD_MIN] = + 50000000; + gcc_qupv3_wrap1_s7_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 128000000; + gcc_ufs_card_axi_clk_src.freq_tbl = + ftbl_gcc_ufs_card_axi_clk_src_sdm670; + gcc_ufs_card_axi_clk_src.clkr.vdd_data.rate_max[VDD_HIGH] = + 240000000; + gcc_ufs_phy_axi_clk_src.freq_tbl = + ftbl_gcc_ufs_card_axi_clk_src_sdm670; + gcc_vsensor_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = 600000000; + + gcc_sdm845_clocks[GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr; + gcc_sdm845_clocks[GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr; + gcc_sdm845_clocks[GCC_SDCC1_ICE_CORE_CLK] = + &gcc_sdcc1_ice_core_clk.clkr; + gcc_sdm845_clocks[GCC_SDCC1_APPS_CLK_SRC] = + &gcc_sdcc1_apps_clk_src.clkr; + gcc_sdm845_clocks[GCC_SDCC1_ICE_CORE_CLK_SRC] = + &gcc_sdcc1_ice_core_clk_src.clkr; + gcc_sdm845_clocks[GPLL6] = &gpll6.clkr; + gcc_sdm845_clocks[GCC_AGGRE_UFS_CARD_AXI_CLK] = NULL; + gcc_sdm845_clocks[GCC_AGGRE_USB3_SEC_AXI_CLK] = NULL; + gcc_sdm845_clocks[GCC_AGGRE_NOC_PCIE_TBU_CLK] = NULL; + gcc_sdm845_clocks[GCC_CFG_NOC_USB3_SEC_AXI_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_0_AUX_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_0_AUX_CLK_SRC] = NULL; + gcc_sdm845_clocks[GCC_PCIE_0_CFG_AHB_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_0_CLKREF_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_0_MSTR_AXI_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_0_PIPE_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_0_SLV_AXI_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_0_SLV_Q2A_AXI_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_1_AUX_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_1_AUX_CLK_SRC] = NULL; + gcc_sdm845_clocks[GCC_PCIE_1_CFG_AHB_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_1_CLKREF_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_1_MSTR_AXI_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_1_PIPE_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_1_SLV_AXI_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_1_SLV_Q2A_AXI_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_PHY_AUX_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_PHY_REFGEN_CLK] = NULL; + gcc_sdm845_clocks[GCC_PCIE_PHY_REFGEN_CLK_SRC] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_AHB_CLK] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_AXI_CLK] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_AXI_CLK_SRC] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_CLKREF_CLK] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_ICE_CORE_CLK] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_ICE_CORE_CLK_SRC] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_PHY_AUX_CLK] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_PHY_AUX_CLK_SRC] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_RX_SYMBOL_0_CLK] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_RX_SYMBOL_1_CLK] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_TX_SYMBOL_0_CLK] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_UNIPRO_CORE_CLK] = NULL; + gcc_sdm845_clocks[GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC] = NULL; + gcc_sdm845_clocks[GCC_UFS_PHY_RX_SYMBOL_1_CLK] = NULL; + gcc_sdm845_clocks[GCC_USB30_SEC_MASTER_CLK] = NULL; + gcc_sdm845_clocks[GCC_USB30_SEC_MASTER_CLK_SRC] = NULL; + gcc_sdm845_clocks[GCC_USB30_SEC_MOCK_UTMI_CLK] = NULL; + gcc_sdm845_clocks[GCC_USB30_SEC_MOCK_UTMI_CLK_SRC] = NULL; + gcc_sdm845_clocks[GCC_USB30_SEC_SLEEP_CLK] = NULL; + gcc_sdm845_clocks[GCC_USB3_SEC_CLKREF_CLK] = NULL; + gcc_sdm845_clocks[GCC_USB3_SEC_PHY_AUX_CLK] = NULL; + gcc_sdm845_clocks[GCC_USB3_SEC_PHY_AUX_CLK_SRC] = NULL; + gcc_sdm845_clocks[GCC_USB3_SEC_PHY_COM_AUX_CLK] = NULL; + gcc_sdm845_clocks[GCC_USB3_SEC_PHY_PIPE_CLK] = NULL; + + gcc_cpuss_rbcpr_clk_src.freq_tbl = ftbl_gcc_cpuss_rbcpr_clk_src_sdm670; + gcc_cpuss_rbcpr_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 50000000; + gcc_sdcc2_apps_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = 50000000; + gcc_sdcc2_apps_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] = + 100000000; + gcc_sdcc2_apps_clk_src.clkr.vdd_data.rate_max[VDD_NOMINAL] = + 201500000; + gcc_sdcc4_apps_clk_src.freq_tbl = ftbl_gcc_sdcc4_apps_clk_src_sdm670; + gcc_sdcc4_apps_clk_src.clkr.vdd_data.rate_max[VDD_LOWER] = 33333333; +} + static int gcc_sdm845_probe(struct platform_device *pdev) { struct regmap *regmap; int ret; + bool sdm670; + + sdm670 = of_device_is_compatible(pdev->dev.of_node, + "qcom,sdm670-gcc"); regmap = qcom_cc_map(pdev, &gcc_sdm845_desc); if (IS_ERR(regmap)) @@ -3611,12 +4209,46 @@ static int gcc_sdm845_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); regmap_update_bits(regmap, 0x71028, 0x3, 0x3); + /* Keep critical clocks gcc_camera_ahb_clk, gcc_camera_xo_clk, + * gcc_disp_ahb_clk, gcc_disp_xo_clk, gcc_gpu_cfg_ahb_clk, + * gcc_video_ahb_clk, gcc_video_xo_clk, gcc_cpuss_dvm_bus_clk + * gcc_cpuss_gnoc_clk, always ON + */ + + regmap_update_bits(regmap, 0xb008, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb02c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb00c, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb030, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb004, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0xb028, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x48190, BIT(0), BIT(0)); + regmap_update_bits(regmap, 0x48004, BIT(0), BIT(0)); + + if (sdm670) + gcc_sdm845_fixup_sdm670(); + + gcc_sdm845_desc.gdscs = NULL; + gcc_sdm845_desc.num_gdscs = 0; + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, ARRAY_SIZE(gcc_dfs_clocks)); if (ret) return ret; - return qcom_cc_really_probe(pdev, &gcc_sdm845_desc, regmap); + ret = qcom_cc_really_probe(pdev, &gcc_sdm845_desc, regmap); + if (ret) { + dev_err(&pdev->dev, "Failed to register GCC clocks\n"); + return ret; + } + + dev_info(&pdev->dev, "Registered GCC clocks\n"); + return ret; +} + +static void gcc_sdm845_sync_state(struct device *dev) +{ + qcom_cc_sync_state(dev, &gcc_sdm845_desc); } static struct platform_driver gcc_sdm845_driver = { @@ -3624,7 +4256,7 @@ static struct platform_driver gcc_sdm845_driver = { .driver = { .name = "gcc-sdm845", .of_match_table = gcc_sdm845_match_table, - .sync_state = clk_sync_state, + .sync_state = gcc_sdm845_sync_state, }, }; @@ -3642,4 +4274,4 @@ module_exit(gcc_sdm845_exit); MODULE_DESCRIPTION("QTI GCC SDM845 Driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:gcc-sdm845"); +MODULE_ALIAS("platform:sdm845-gcc"); diff --git a/drivers/clk/qcom/gpucc-sdm845.c b/drivers/clk/qcom/gpucc-sdm845.c index 8749aabd3b0d..c4cb4845ed64 100644 --- a/drivers/clk/qcom/gpucc-sdm845.c +++ b/drivers/clk/qcom/gpucc-sdm845.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -17,6 +18,8 @@ #include "clk-rcg.h" #include "clk-regmap.h" #include "gdsc.h" +#include "reset.h" +#include "vdd-level-sdm845.h" #define CX_GMU_CBCR_SLEEP_MASK 0xf #define CX_GMU_CBCR_SLEEP_SHIFT 4 @@ -25,51 +28,188 @@ #define CLK_DIS_WAIT_SHIFT 12 #define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) +static DEFINE_VDD_REGULATORS(vdd_cx, VDD_NUM, 1, vdd_corner); +static DEFINE_VDD_REGULATORS(vdd_mx, VDD_NUM, 1, vdd_corner); +static DEFINE_VDD_REGULATORS(vdd_gfx, VDD_GX_NUM, 1, vdd_gx_corner); + +static struct clk_vdd_class *gpu_cc_sdm845_regulators[] = { + &vdd_cx, + &vdd_mx, + &vdd_gfx, +}; + enum { P_BI_TCXO, P_GPLL0_OUT_MAIN, P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_EVEN, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL0_OUT_ODD, + P_GPU_CC_PLL1_OUT_EVEN, P_GPU_CC_PLL1_OUT_MAIN, + P_GPU_CC_PLL1_OUT_ODD, + P_CRC_DIV, }; -static const struct alpha_pll_config gpu_cc_pll1_config = { - .l = 0x1a, - .alpha = 0xaab, +static struct pll_vco fabia_vco[] = { + { 249600000, 2000000000, 0 }, + { 125000000, 1000000000, 1 }, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + .vdd_data = { + .vdd_class = &vdd_mx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 615000000, + [VDD_LOW] = 1066000000, + [VDD_LOW_L1] = 1600000000, + [VDD_NOMINAL] = 2000000000 }, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { 0x3, 4 }, + { 0x7, 8 }, + {}, +}; + +static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, }; static struct clk_alpha_pll gpu_cc_pll1 = { .offset = 0x100, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr = { .hw.init = &(struct clk_init_data){ .name = "gpu_cc_pll1", .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", .name = "bi_tcxo", + .fw_name = "bi_tcxo", }, .num_parents = 1, .ops = &clk_alpha_pll_fabia_ops, }, + .vdd_data = { + .vdd_class = &vdd_mx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 615000000, + [VDD_LOW] = 1066000000, + [VDD_LOW_L1] = 1600000000, + [VDD_NOMINAL] = 2000000000 }, + }, + }, +}; + +static struct clk_fixed_factor crc_div = { + .mult = 1, + .div = 1, + .hw.init = &(struct clk_init_data){ + .name = "crc_div", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_pll0_out_even.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_fixed_factor_ops, }, }; static const struct parent_map gpu_cc_parent_map_0[] = { { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, { P_GPU_CC_PLL1_OUT_MAIN, 3 }, { P_GPLL0_OUT_MAIN, 5 }, { P_GPLL0_OUT_MAIN_DIV, 6 }, }; static const struct clk_parent_data gpu_cc_parent_data_0[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, + { .hw = &gpu_cc_pll0.clkr.hw }, { .hw = &gpu_cc_pll1.clkr.hw }, - { .fw_name = "gcc_gpu_gpll0_clk_src", .name = "gcc_gpu_gpll0_clk_src" }, - { .fw_name = "gcc_gpu_gpll0_div_clk_src", .name = "gcc_gpu_gpll0_div_clk_src" }, + { .fw_name = "gcc_gpu_gpll0_clk_src" }, + { .fw_name = "gcc_gpu_gpll0_div_clk_src" }, +}; + +static const struct parent_map gpu_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_EVEN, 1 }, + { P_GPU_CC_PLL0_OUT_ODD, 2 }, + { P_GPU_CC_PLL1_OUT_EVEN, 3 }, + { P_GPU_CC_PLL1_OUT_ODD, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_1[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpu_cc_pll0_out_even.clkr.hw }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .fw_name = "gcc_gpu_gpll0_clk_src" }, +}; + +static const struct parent_map gpu_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_CRC_DIV, 1 }, + { P_GPU_CC_PLL0_OUT_ODD, 2 }, + { P_GPU_CC_PLL1_OUT_EVEN, 3 }, + { P_GPU_CC_PLL1_OUT_ODD, 4 }, + { P_GPLL0_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_2[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &crc_div.hw }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .hw = &gpu_cc_pll1.clkr.hw }, + { .fw_name = "gcc_gpu_gpll0_clk_src" }, }; static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { F(19200000, P_BI_TCXO, 1, 0, 0), F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0), - F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0), + F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src_sdm670[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0), { } }; @@ -83,8 +223,160 @@ static struct clk_rcg2 gpu_cc_gmu_clk_src = { .name = "gpu_cc_gmu_clk_src", .parent_data = gpu_cc_parent_data_0, .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 200000000, + [VDD_LOW] = 400000000 }, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = { + F(147000000, P_CRC_DIV, 1, 0, 0), + F(210000000, P_CRC_DIV, 1, 0, 0), + F(280000000, P_CRC_DIV, 1, 0, 0), + F(338000000, P_CRC_DIV, 1, 0, 0), + F(425000000, P_CRC_DIV, 1, 0, 0), + F(487000000, P_CRC_DIV, 1, 0, 0), + F(548000000, P_CRC_DIV, 1, 0, 0), + F(600000000, P_CRC_DIV, 1, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src_sdm670[] = { + F(180000000, P_CRC_DIV, 1, 0, 0), + F(267000000, P_CRC_DIV, 1, 0, 0), + F(355000000, P_CRC_DIV, 1, 0, 0), + F(430000000, P_CRC_DIV, 1, 0, 0), + F(504000000, P_CRC_DIV, 1, 0, 0), + F(565000000, P_CRC_DIV, 1, 0, 0), + F(610000000, P_CRC_DIV, 1, 0, 0), + F(650000000, P_CRC_DIV, 1, 0, 0), + F(700000000, P_CRC_DIV, 1, 0, 0), + F(750000000, P_CRC_DIV, 1, 0, 0), + F(780000000, P_CRC_DIV, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = { + .cmd_rcgr = 0x101c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_2, + .freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src, + .flags = FORCE_ENABLE_RCG, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gx_gfx3d_clk_src", + .parent_data = gpu_cc_parent_data_2, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, + .clkr.vdd_data = { + .vdd_class = &vdd_gfx, + .num_rate_max = VDD_GX_NUM, + .rate_max = (unsigned long[VDD_GX_NUM]) { + [VDD_GX_MIN] = 147000000, + [VDD_GX_LOWER] = 210000000, + [VDD_GX_LOW] = 280000000, + [VDD_GX_LOW_L1] = 338000000, + [VDD_GX_NOMINAL] = 425000000, + [VDD_GX_NOMINAL_L1] = 487000000, + [VDD_GX_HIGH] = 548000000, + [VDD_GX_HIGH_L1] = 600000000 }, + }, +}; + +static struct clk_branch gpu_cc_acd_ahb_clk = { + .halt_reg = 0x1168, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1168, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_acd_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_acd_cxo_clk = { + .halt_reg = 0x1164, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1164, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_acd_cxo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_crc_ahb_clk = { + .halt_reg = 0x107c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x107c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_crc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_apb_clk = { + .halt_reg = 0x1088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1088, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_apb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gfx3d_clk = { + .halt_reg = 0x10a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10a4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_gfx3d_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_gx_gfx3d_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gfx3d_slv_clk = { + .halt_reg = 0x10a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10a8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_gfx3d_slv_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_gx_gfx3d_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, }; static struct clk_branch gpu_cc_cx_gmu_clk = { @@ -105,6 +397,32 @@ static struct clk_branch gpu_cc_cx_gmu_clk = { }, }; +static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { + .halt_reg = 0x108c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x108c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cx_snoc_dvm_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_aon_clk = { + .halt_reg = 0x1004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_cxo_aon_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gpu_cc_cxo_clk = { .halt_reg = 0x109c, .halt_check = BRANCH_HALT, @@ -118,6 +436,55 @@ static struct clk_branch gpu_cc_cxo_clk = { }, }; +static struct clk_branch gpu_cc_gx_gfx3d_clk = { + .halt_reg = 0x1054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gx_gfx3d_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_gx_gfx3d_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_gmu_clk = { + .halt_reg = 0x1064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gx_gmu_clk", + .parent_hws = (const struct clk_hw*[]){ + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_vsense_clk = { + .halt_reg = 0x1058, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x1058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpu_cc_gx_vsense_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct gdsc gpu_cx_gdsc = { .gdscr = 0x106c, .gds_hw_ctrl = 0x1540, @@ -140,15 +507,34 @@ static struct gdsc gpu_gx_gdsc = { }; static struct clk_regmap *gpu_cc_sdm845_clocks[] = { - [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, + [GPU_CC_ACD_AHB_CLK] = &gpu_cc_acd_ahb_clk.clkr, + [GPU_CC_ACD_CXO_CLK] = &gpu_cc_acd_cxo_clk.clkr, + [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, + [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr, + [GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr, + [GPU_CC_CX_GFX3D_SLV_CLK] = &gpu_cc_cx_gfx3d_slv_clk.clkr, [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, + [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr, + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, + [GPU_CC_GX_VSENSE_CLK] = &gpu_cc_gx_vsense_clk.clkr, + [GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr, + [GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr, + [GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr, + [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, }; -static struct gdsc *gpu_cc_sdm845_gdscs[] = { - [GPU_CX_GDSC] = &gpu_cx_gdsc, - [GPU_GX_GDSC] = &gpu_gx_gdsc, +static const struct qcom_reset_map gpu_cc_sdm845_resets[] = { + [GPUCC_GPU_CC_ACD_BCR] = { 0x1160 }, + [GPUCC_GPU_CC_CX_BCR] = { 0x1068 }, + [GPUCC_GPU_CC_GFX3D_AON_BCR] = { 0x10a0 }, + [GPUCC_GPU_CC_GMU_BCR] = { 0x111c }, + [GPUCC_GPU_CC_GX_BCR] = { 0x1008 }, + [GPUCC_GPU_CC_SPDM_BCR] = { 0x1110 }, + [GPUCC_GPU_CC_XO_BCR] = { 0x1000 }, }; static const struct regmap_config gpu_cc_sdm845_regmap_config = { @@ -159,30 +545,90 @@ static const struct regmap_config gpu_cc_sdm845_regmap_config = { .fast_io = true, }; -static const struct qcom_cc_desc gpu_cc_sdm845_desc = { +static struct gdsc *gpu_cc_sdm845_gdscs[] = { + [GPU_CX_GDSC] = &gpu_cx_gdsc, + [GPU_GX_GDSC] = &gpu_gx_gdsc, +}; + +static struct qcom_cc_desc gpu_cc_sdm845_desc = { .config = &gpu_cc_sdm845_regmap_config, .clks = gpu_cc_sdm845_clocks, .num_clks = ARRAY_SIZE(gpu_cc_sdm845_clocks), + .resets = gpu_cc_sdm845_resets, + .num_resets = ARRAY_SIZE(gpu_cc_sdm845_resets), .gdscs = gpu_cc_sdm845_gdscs, .num_gdscs = ARRAY_SIZE(gpu_cc_sdm845_gdscs), + .clk_regulators = gpu_cc_sdm845_regulators, + .num_clk_regulators = ARRAY_SIZE(gpu_cc_sdm845_regulators), }; static const struct of_device_id gpu_cc_sdm845_match_table[] = { { .compatible = "qcom,sdm845-gpucc" }, + { .compatible = "qcom,sdm670-gpucc" }, { } }; MODULE_DEVICE_TABLE(of, gpu_cc_sdm845_match_table); +static void gpu_cc_sdm845_fixup_sdm670(void) +{ + gpu_cc_gmu_clk_src.freq_tbl = ftbl_gpu_cc_gmu_clk_src_sdm670; + gpu_cc_gmu_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = 200000000; + + /* GFX clocks */ + gpu_cc_gx_gfx3d_clk_src.freq_tbl = + ftbl_gpu_cc_gx_gfx3d_clk_src_sdm670; + gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_MIN] = 180000000; + gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_LOWER] = + 267000000; + gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_LOW] = 355000000; + gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_LOW_L1] = + 430000000; + gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_NOMINAL] = + 565000000; + gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_NOMINAL_L1] = + 650000000; + gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_HIGH] = 750000000; + gpu_cc_gx_gfx3d_clk_src.clkr.vdd_data.rate_max[VDD_GX_HIGH_L1] = + 780000000; +} + static int gpu_cc_sdm845_probe(struct platform_device *pdev) { struct regmap *regmap; unsigned int value, mask; + struct alpha_pll_config gpu_cc_pll0_config = {}; + int ret; + bool sdm670; + + sdm670 = of_device_is_compatible(pdev->dev.of_node, + "qcom,sdm670-gpucc"); regmap = qcom_cc_map(pdev, &gpu_cc_sdm845_desc); if (IS_ERR(regmap)) return PTR_ERR(regmap); - clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); + /* Register clock fixed factor for CRC divide. */ + ret = devm_clk_hw_register(&pdev->dev, &crc_div.hw); + if (ret) { + dev_err(&pdev->dev, "Failed to register hardware clock\n"); + return ret; + } + + if (sdm670) + gpu_cc_sdm845_fixup_sdm670(); + + gpu_cc_sdm845_desc.gdscs = NULL; + gpu_cc_sdm845_desc.num_gdscs = 0; + + /* 560 MHz configuration */ + gpu_cc_pll0_config.l = 0x1d, + gpu_cc_pll0_config.alpha = 0x2aaa, + clk_fabia_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); + + /* 512 Mhz configuration */ + gpu_cc_pll0_config.l = 0x1a, + gpu_cc_pll0_config.alpha = 0xaaaa, + clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll0_config); /* * Configure gpu_cc_cx_gmu_clk with recommended @@ -197,7 +643,19 @@ static int gpu_cc_sdm845_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK, 8 << CLK_DIS_WAIT_SHIFT); - return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap); + ret = qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap); + if (ret) { + dev_err(&pdev->dev, "Failed to register GPU CC clocks\n"); + return ret; + } + + dev_info(&pdev->dev, "Registered GPU CC clocks\n"); + return ret; +} + +static void gpu_cc_sdm845_sync_state(struct device *dev) +{ + qcom_cc_sync_state(dev, &gpu_cc_sdm845_desc); } static struct platform_driver gpu_cc_sdm845_driver = { @@ -205,7 +663,7 @@ static struct platform_driver gpu_cc_sdm845_driver = { .driver = { .name = "sdm845-gpucc", .of_match_table = gpu_cc_sdm845_match_table, - .sync_state = clk_sync_state, + .sync_state = gpu_cc_sdm845_sync_state, }, }; diff --git a/drivers/clk/qcom/vdd-level-sdm845.h b/drivers/clk/qcom/vdd-level-sdm845.h new file mode 100644 index 000000000000..6ca364db621a --- /dev/null +++ b/drivers/clk/qcom/vdd-level-sdm845.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef __DRIVERS_CLK_QCOM_VDD_LEVEL_SDM845_H +#define __DRIVERS_CLK_QCOM_VDD_LEVEL_SDM845_H + +#include +#include + +enum vdd_levels { + VDD_NONE, + VDD_MIN, /* MIN SVS */ + VDD_LOWER, /* SVS2 */ + VDD_LOW, /* SVS */ + VDD_LOW_L1, /* SVSL1 */ + VDD_NOMINAL, /* NOM */ + VDD_HIGH, /* TURBO */ + VDD_NUM, +}; + +static int vdd_corner[] = { + [VDD_NONE] = 0, + [VDD_MIN] = RPMH_REGULATOR_LEVEL_MIN_SVS, + [VDD_LOWER] = RPMH_REGULATOR_LEVEL_LOW_SVS, + [VDD_LOW] = RPMH_REGULATOR_LEVEL_SVS, + [VDD_LOW_L1] = RPMH_REGULATOR_LEVEL_SVS_L1, + [VDD_NOMINAL] = RPMH_REGULATOR_LEVEL_NOM, + [VDD_HIGH] = RPMH_REGULATOR_LEVEL_TURBO, +}; + +enum vdd_gx_levels { + VDD_GX_NONE, + VDD_GX_MIN, /* MIN SVS */ + VDD_GX_LOWER, /* SVS2 */ + VDD_GX_LOW, /* SVS */ + VDD_GX_LOW_L1, /* SVSL1 */ + VDD_GX_NOMINAL, /* NOM */ + VDD_GX_NOMINAL_L1, /* NOM1 */ + VDD_GX_HIGH, /* TURBO */ + VDD_GX_HIGH_L1, /* TURBO1 */ + VDD_GX_NUM, +}; + +static int vdd_gx_corner[] = { + [VDD_GX_NONE] = 0, /* VDD_GX_NONE */ + [VDD_GX_MIN] = RPMH_REGULATOR_LEVEL_MIN_SVS, /* VDD_GX_MIN */ + [VDD_GX_LOWER] = RPMH_REGULATOR_LEVEL_LOW_SVS, /* VDD_GX_LOWER */ + [VDD_GX_LOW] = RPMH_REGULATOR_LEVEL_SVS, /* VDD_GX_LOW */ + [VDD_GX_LOW_L1] = RPMH_REGULATOR_LEVEL_SVS_L1, /* VDD_GX_LOW_L1 */ + [VDD_GX_NOMINAL] = RPMH_REGULATOR_LEVEL_NOM, /* VDD_GX_NOMINAL */ + [VDD_GX_NOMINAL_L1] = RPMH_REGULATOR_LEVEL_NOM_L1, /* VDD_GX_NOMINAL_L1 */ + [VDD_GX_HIGH] = RPMH_REGULATOR_LEVEL_TURBO, /* VDD_GX_HIGH */ + [VDD_GX_HIGH_L1] = RPMH_REGULATOR_LEVEL_TURBO_L1, /* VDD_GX_HIGH_L1 */ +}; + +#endif diff --git a/drivers/clk/qcom/videocc-sdm845.c b/drivers/clk/qcom/videocc-sdm845.c index f678ade82656..b850ea94ac4b 100644 --- a/drivers/clk/qcom/videocc-sdm845.c +++ b/drivers/clk/qcom/videocc-sdm845.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -17,58 +18,102 @@ #include "clk-regmap.h" #include "clk-pll.h" #include "gdsc.h" +#include "reset.h" +#include "vdd-level-sdm845.h" + +static DEFINE_VDD_REGULATORS(vdd_cx, VDD_NUM, 1, vdd_corner); + +static struct clk_vdd_class *video_cc_sdm845_regulators[] = { + &vdd_cx, +}; enum { P_BI_TCXO, + P_VIDEO_PLL0_OUT_EVEN, P_VIDEO_PLL0_OUT_MAIN, - /* P_VIDEO_PLL0_OUT_EVEN, */ - /* P_VIDEO_PLL0_OUT_ODD, */ + P_VIDEO_PLL0_OUT_ODD, }; -static const struct alpha_pll_config video_pll0_config = { +static struct pll_vco fabia_vco[] = { + { 249600000, 2000000000, 0 }, + { 125000000, 1000000000, 1 }, +}; + +/*320 MHz configuration */ +static struct alpha_pll_config video_pll0_config = { .l = 0x10, - .alpha = 0xaaab, + .cal_l = 0x32, + .alpha = 0xaaaa, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00002067, + .test_ctl_val = 0x40000000, + .test_ctl_hi_val = 0x00000002, + .user_ctl_val = 0x00000000, + .user_ctl_hi_val = 0x00004805, }; static struct clk_alpha_pll video_pll0 = { .offset = 0x42c, + .vco_table = fabia_vco, + .num_vco = ARRAY_SIZE(fabia_vco), .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr = { .hw.init = &(struct clk_init_data){ .name = "video_pll0", .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", .name = "bi_tcxo", + .fw_name = "bi_tcxo", }, .num_parents = 1, .ops = &clk_alpha_pll_fabia_ops, }, + .vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 615000000, + [VDD_LOW] = 1066000000, + [VDD_LOW_L1] = 1600000000, + [VDD_NOMINAL] = 2000000000 }, + }, }, }; static const struct parent_map video_cc_parent_map_0[] = { { P_BI_TCXO, 0 }, { P_VIDEO_PLL0_OUT_MAIN, 1 }, - /* { P_VIDEO_PLL0_OUT_EVEN, 2 }, */ - /* { P_VIDEO_PLL0_OUT_ODD, 3 }, */ + { P_VIDEO_PLL0_OUT_EVEN, 2 }, + { P_VIDEO_PLL0_OUT_ODD, 3 }, }; static const struct clk_parent_data video_cc_parent_data_0[] = { - { .fw_name = "bi_tcxo", .name = "bi_tcxo" }, + { .fw_name = "bi_tcxo" }, + { .hw = &video_pll0.clkr.hw }, + { .hw = &video_pll0.clkr.hw }, { .hw = &video_pll0.clkr.hw }, - /* { .name = "video_pll0_out_even" }, */ - /* { .name = "video_pll0_out_odd" }, */ }; static const struct freq_tbl ftbl_video_cc_venus_clk_src[] = { F(100000000, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0), F(200000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0), - F(330000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + F(320000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + F(380000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + F(444000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + F(533000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_video_cc_venus_clk_src_sdm670[] = { + F(100000000, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0), + F(200000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0), + F(330000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0), + F(364700000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0), F(404000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), F(444000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), F(533000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), { } }; + static struct clk_rcg2 video_cc_venus_clk_src = { .cmd_rcgr = 0x7f0, .mnd_width = 0, @@ -81,6 +126,17 @@ static struct clk_rcg2 video_cc_venus_clk_src = { .num_parents = ARRAY_SIZE(video_cc_parent_data_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_shared_ops, + }, + .clkr.vdd_data = { + .vdd_class = &vdd_cx, + .num_rate_max = VDD_NUM, + .rate_max = (unsigned long[VDD_NUM]) { + [VDD_MIN] = 100000000, + [VDD_LOWER] = 200000000, + [VDD_LOW] = 320000000, + [VDD_LOW_L1] = 380000000, + [VDD_NOMINAL] = 444000000, + [VDD_HIGH] = 533000000 }, }, }; @@ -305,31 +361,65 @@ static const struct regmap_config video_cc_sdm845_regmap_config = { .fast_io = true, }; -static const struct qcom_cc_desc video_cc_sdm845_desc = { +static struct qcom_cc_desc video_cc_sdm845_desc = { .config = &video_cc_sdm845_regmap_config, .clks = video_cc_sdm845_clocks, .num_clks = ARRAY_SIZE(video_cc_sdm845_clocks), .gdscs = video_cc_sdm845_gdscs, .num_gdscs = ARRAY_SIZE(video_cc_sdm845_gdscs), + .clk_regulators = video_cc_sdm845_regulators, + .num_clk_regulators = ARRAY_SIZE(video_cc_sdm845_regulators), }; static const struct of_device_id video_cc_sdm845_match_table[] = { { .compatible = "qcom,sdm845-videocc" }, + { .compatible = "qcom,sdm670-videocc" }, { } }; MODULE_DEVICE_TABLE(of, video_cc_sdm845_match_table); +static void video_cc_sdm845_fixup_sdm670(void) +{ + video_cc_venus_clk_src.freq_tbl = ftbl_video_cc_venus_clk_src_sdm670; + video_cc_venus_clk_src.clkr.vdd_data.rate_max[VDD_LOW] = 330000000; + video_cc_venus_clk_src.clkr.vdd_data.rate_max[VDD_LOW_L1] = + 404000000; +} + static int video_cc_sdm845_probe(struct platform_device *pdev) { struct regmap *regmap; + int ret; + bool sdm670; + + sdm670 = of_device_is_compatible(pdev->dev.of_node, + "qcom,sdm670-videocc"); regmap = qcom_cc_map(pdev, &video_cc_sdm845_desc); if (IS_ERR(regmap)) return PTR_ERR(regmap); + if (sdm670) + video_cc_sdm845_fixup_sdm670(); + + video_cc_sdm845_desc.gdscs = NULL; + video_cc_sdm845_desc.num_gdscs = 0; + clk_fabia_pll_configure(&video_pll0, regmap, &video_pll0_config); - return qcom_cc_really_probe(pdev, &video_cc_sdm845_desc, regmap); + ret = qcom_cc_really_probe(pdev, &video_cc_sdm845_desc, regmap); + if (ret) { + dev_err(&pdev->dev, "Failed to register Video CC clocks\n"); + return ret; + } + + dev_info(&pdev->dev, "Registered Video CC clocks\n"); + return ret; +} + +static void video_cc_sdm845_sync_state(struct device *dev) +{ + qcom_cc_sync_state(dev, &video_cc_sdm845_desc); } static struct platform_driver video_cc_sdm845_driver = { @@ -337,7 +427,7 @@ static struct platform_driver video_cc_sdm845_driver = { .driver = { .name = "sdm845-videocc", .of_match_table = video_cc_sdm845_match_table, - .sync_state = clk_sync_state, + .sync_state = video_cc_sdm845_sync_state, }, }; From c5aeaa454d19b013e081d2926dde017114d31508 Mon Sep 17 00:00:00 2001 From: Ansa Ahmed Date: Mon, 6 Nov 2023 18:22:20 +0530 Subject: [PATCH 34/46] msm: adsprpc: Removal of duplicate session check with fastrpc_session_exists Removal of duplicate session check with fastrpc_session_exists API as it is no longer needed. Duplicate session creation is restricted using set_session_info flag already. Change-Id: I6b85d96f85e8d1e5af005a6939d8b9a25ca06fcf Signed-off-by: Ansa Ahmed --- drivers/char/adsprpc.c | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 53e9328fda72..562178294448 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -4348,38 +4348,6 @@ bail: kfree(proc_name); } -/* - * Function to restrict duplicate session creation with same tgid, cid. - * check introduced after extended session creation - * to avoid breaking in case of extended sessions. - */ - -static bool fastrpc_session_exists(struct fastrpc_apps *me, uint32_t cid, int tgid) -{ - struct fastrpc_file *fl; - struct hlist_node *n; - bool session_found = false; - unsigned long irq_flags = 0; - int total_session_count = 0; - - spin_lock_irqsave(&me->hlock, irq_flags); - hlist_for_each_entry_safe(fl, n, &me->drivers, hn) { - if (fl->tgid == tgid && fl->cid == cid) { - ++total_session_count; - if (total_session_count > 1) { - session_found = true; - break; - } - } - } - spin_unlock_irqrestore(&me->hlock, irq_flags); - if (session_found) - ADSPRPC_ERR( - "trying to open a session that already exists for tgid %d, channel ID %u\n", - tgid, cid); - - return session_found; -} int fastrpc_init_process(struct fastrpc_file *fl, struct fastrpc_ioctl_init_attrs *uproc) @@ -4405,11 +4373,6 @@ int fastrpc_init_process(struct fastrpc_file *fl, err = -ECHRNG; goto bail; } - VERIFY(err, !fastrpc_session_exists(me, fl->cid, fl->tgid)); - if (err) { - err = -EEXIST; - goto bail; - } chan = &me->channel[cid]; if (chan->unsigned_support && fl->dev_minor == MINOR_NUM_DEV) { /* Make sure third party applications */ From 9a3386af0d76a7a09c97c15a2e6966c66e3e4910 Mon Sep 17 00:00:00 2001 From: Seshu Madhavi Puppala Date: Sun, 3 Dec 2023 19:43:09 -0800 Subject: [PATCH 35/46] Revert "Revert "defconfig: sa8225p: enable fbe UFS modules"" This reverts commit 07c9ebd0b37c78aad17e09d91a4f216485486d5b. Reason for revert: HWKM clock voting bug fixed in TZ. Change-Id: Ia0c74c1b4d6acd63ac9463022898b61ed906932d Signed-off-by: Seshu Madhavi Puppala --- arch/arm64/configs/vendor/gen4auto_GKI.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/configs/vendor/gen4auto_GKI.config b/arch/arm64/configs/vendor/gen4auto_GKI.config index d256593fb4e2..d86a35b54079 100644 --- a/arch/arm64/configs/vendor/gen4auto_GKI.config +++ b/arch/arm64/configs/vendor/gen4auto_GKI.config @@ -203,6 +203,8 @@ CONFIG_QRTR_WAKEUP_MS=0 CONFIG_QTI_CPUFREQ_CDEV=m CONFIG_QTI_CPU_HOTPLUG_COOLING_DEVICE=m # CONFIG_QTI_CPU_PAUSE_COOLING_DEVICE is not set +CONFIG_QTI_CRYPTO_COMMON=m +CONFIG_QTI_CRYPTO_TZ=m CONFIG_QTI_DEVFREQ_CDEV=m CONFIG_QTI_PMIC_PON_LOG=m CONFIG_QTI_QMI_COOLING_DEVICE=m @@ -233,6 +235,7 @@ CONFIG_SA_DISPCC_LEMANS=m CONFIG_SA_GCC_LEMANS=m CONFIG_SA_GPUCC_LEMANS=m CONFIG_SA_VIDEOCC_LEMANS=m +CONFIG_SCSI_UFS_CRYPTO_QTI=m CONFIG_SCSI_UFS_QCOM=m CONFIG_SERIAL_MSM_GENI=m # CONFIG_SND_USB_AUDIO_QMI is not set From af05db4d20c01714105f19ea68c84a70ee38d029 Mon Sep 17 00:00:00 2001 From: Keming Zhang Date: Mon, 25 Dec 2023 15:07:48 +0800 Subject: [PATCH 36/46] soc: qcom: hgsl: Fix dereference NULL pointer in hgsl page could be NULL when out of memory, only dereference it when allocate successfully. Change-Id: Ib3af2dabe9fdb69211b63196086736a5e6c82768 Signed-off-by: Keming Zhang --- drivers/soc/qcom/hgsl/hgsl_memory.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/hgsl/hgsl_memory.c b/drivers/soc/qcom/hgsl/hgsl_memory.c index cec168ac7017..36f0bb9f718c 100644 --- a/drivers/soc/qcom/hgsl/hgsl_memory.c +++ b/drivers/soc/qcom/hgsl/hgsl_memory.c @@ -511,10 +511,9 @@ static int hgsl_alloc_pages(struct device *dev, uint32_t requested_pcount, for (i = 0; i < pcount; i++) pages[i] = nth_page(page, i); _dma_cache_op(dev, page, pcount, GSL_CACHEFLAGS_FLUSH); - } - - mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE, + mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE, (1 << order)); + } return pcount; } From 6c873fcda8efa00bf598293dced022d0504bbbff Mon Sep 17 00:00:00 2001 From: Qiang Yu Date: Mon, 11 Dec 2023 18:26:17 +0800 Subject: [PATCH 37/46] pci: msm: Correct link width setting to PCIE20_CAP and GEN2_CTRL_OFF As per databook, when there are unused lanes in a system, you must reprogram the following registers through the DBI. For this example, where a 4-lane controller is connected to a 1-lane PHY: 1. Reprogram LINK_CAPABLE field of the PORT_LINK_CTRL_OFF register to 6h1 from 6h7. This is used by the LTSSM in Detect. 2. Reprogram NUM_OF_LANES[8:0] field of the GEN2_CTRL_OFF register to 9h1 from 9h4. This indicates to the LTSSM, the number of lanes to check for exiting from L2.Idle or Polling.Active. 3. Reprogram PCIE_CAP_MAX_LINK_WIDTH field of the LINK_CAPABILITIES_REG register to 6h1 from 6h4. This enables the RP to determine the Maximum Link Width for this port. We should not set link_width to PCIE20_CAP and GEN2_CTRL_OFF, but should set the target_link_width. NUM_OF_LANES[8:0] field is recommended to set as LINK_WIDTH_X1 even if there are more one lane. Change-Id: I7b32160d6582b6ddc65d860b5e58f6ec77baf48d Signed-off-by: Qiang Yu --- drivers/pci/controller/pci-msm.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/pci-msm.c b/drivers/pci/controller/pci-msm.c index aed84199f11b..aa6cb0cdd9a9 100644 --- a/drivers/pci/controller/pci-msm.c +++ b/drivers/pci/controller/pci-msm.c @@ -8005,11 +8005,15 @@ static int msm_pcie_set_link_width(struct msm_pcie_dev_t *pcie_dev, LINK_WIDTH_MASK << LINK_WIDTH_SHIFT, link_width); - /* Set NUM_OF_LANES in GEN2_CTRL_OFF */ + /* + * It's advisable to set NUM_OF_LANES[8:0] field to 0x1. It allows + * establishing connection on one line even if there is a termination + * on the second line. Otherwise the link will go to compliance. + */ msm_pcie_write_reg_field(pcie_dev->dm_core, PCIE_GEN3_GEN2_CTRL, NUM_OF_LANES_MASK << NUM_OF_LANES_SHIFT, - link_width); + LINK_WIDTH_X1); /* enable write access to RO register */ msm_pcie_write_mask(pcie_dev->dm_core + PCIE_GEN3_MISC_CONTROL, 0, @@ -8017,7 +8021,8 @@ static int msm_pcie_set_link_width(struct msm_pcie_dev_t *pcie_dev, /* Set Maximum link width as current width */ msm_pcie_write_reg_field(pcie_dev->dm_core, PCIE20_CAP + PCI_EXP_LNKCAP, - PCI_EXP_LNKCAP_MLW, link_width); + PCI_EXP_LNKCAP_MLW, + target_link_width >> PCI_EXP_LNKSTA_NLW_SHIFT); /* disable write access to RO register */ msm_pcie_write_mask(pcie_dev->dm_core + PCIE_GEN3_MISC_CONTROL, BIT(0), From 06763fa5315724d100922cf94f08692bd7f68bb6 Mon Sep 17 00:00:00 2001 From: Raghavendra Kakarla Date: Wed, 20 Dec 2023 19:07:57 +0530 Subject: [PATCH 38/46] power_state: bring the QMP channel check to early stage Bring the QMP channel availability check to early stage of probe so that if channel not available we can return EPROBE_DEFER early instead do register SSR notification and unregister if QMP get_channel fails. This patch also duplicates the subsystem name into the subsystem's data structure instead assigning the name pointer. Change-Id: I03a37e8c002b8357052542b8594d64b6fb280a03 Signed-off-by: Raghavendra Kakarla --- drivers/soc/qcom/power_state.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/soc/qcom/power_state.c b/drivers/soc/qcom/power_state.c index fd7fdfd4153e..c512632a62cb 100644 --- a/drivers/soc/qcom/power_state.c +++ b/drivers/soc/qcom/power_state.c @@ -573,6 +573,12 @@ static int power_state_probe(struct platform_device *pdev) if (!drv) return -ENOMEM; + if (IS_ENABLED(CONFIG_NOTIFY_AOP)) { + drv->qmp = qmp_get(&pdev->dev); + if (IS_ERR(drv->qmp)) + return -EPROBE_DEFER; + } + drv->ps_pm_nb.notifier_call = ps_pm_cb; drv->ps_pm_nb.priority = PS_PM_NOTIFIER_PRIORITY; ret = register_pm_notifier(&drv->ps_pm_nb); @@ -601,7 +607,7 @@ static int power_state_probe(struct platform_device *pdev) goto remove_ss; } - ss_data->name = name; + ss_data->name = kstrdup_const(name, GFP_KERNEL); ss_data->rproc_handle = rproc_handle; ss_data->ps_ssr_nb.notifier_call = ps_ssr_cb; @@ -627,14 +633,6 @@ static int power_state_probe(struct platform_device *pdev) list_add_tail(&ss_data->list, &drv->sub_sys_list); } - if (IS_ENABLED(CONFIG_NOTIFY_AOP)) { - drv->qmp = qmp_get(&pdev->dev); - if (IS_ERR(drv->qmp)) { - ret = PTR_ERR(drv->qmp); - goto remove_ss; - } - } - ret = power_state_dev_init(drv); if (ret) goto remove_ss; From f1534906460484ffb18ee2490e402f95600f8d92 Mon Sep 17 00:00:00 2001 From: lixiang Date: Tue, 26 Dec 2023 17:10:02 +0800 Subject: [PATCH 39/46] soc: qcom: hab: Refine sanity check in hab_msg_recv Refined the sanity check branch to decrease the complexity. Change-Id: Ifb99709c62261e75231469f165765d6602f38a82 Signed-off-by: lixiang --- drivers/soc/qcom/hab/hab_msg.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/hab/hab_msg.c b/drivers/soc/qcom/hab/hab_msg.c index 41e3c372687e..ff688ebeb9da 100644 --- a/drivers/soc/qcom/hab/hab_msg.c +++ b/drivers/soc/qcom/hab/hab_msg.c @@ -614,7 +614,8 @@ static void hab_recv_unimport_msg(struct physical_channel *pchan, int vchan_exis static int hab_try_get_vchan(struct physical_channel *pchan, struct hab_header *header, - struct virtual_channel **vchan_out) + struct virtual_channel **vchan_out, + int *need_ret) { struct virtual_channel *vchan = NULL; size_t sizebytes = HAB_HEADER_GET_SIZE(*header); @@ -644,6 +645,7 @@ static int hab_try_get_vchan(struct physical_channel *pchan, */ vchan = hab_vchan_get(pchan, header); if (!vchan) { + *need_ret = 1; pr_debug("vchan not found type %d vcid %x sz %zx sesn %d\n", payload_type, vchan_id, sizebytes, session_id); @@ -661,6 +663,7 @@ static int hab_try_get_vchan(struct physical_channel *pchan, } return -EINVAL; } else if (vchan->otherend_closed) { + *need_ret = 1; hab_vchan_put(vchan); pr_info("vchan remote closed type %d, vchan id %x, sizebytes %zx, session %d\n", payload_type, vchan_id, @@ -675,6 +678,7 @@ static int hab_try_get_vchan(struct physical_channel *pchan, } } else { if (sizebytes != sizeof(struct hab_open_send_data)) { + *need_ret = 1; pr_err("%s Invalid open req type %d vcid %x bytes %zx session %d\n", pchan->name, payload_type, vchan_id, sizebytes, session_id); @@ -712,9 +716,10 @@ int hab_msg_recv(struct physical_channel *pchan, int found = 0; struct hab_import_data imp_data = {0}; int irqs_disabled = irqs_disabled(); + int need_ret = 0; - ret = hab_try_get_vchan(pchan, header, &vchan); - if (ret != 0 || ((vchan == NULL) && (payload_type == HAB_PAYLOAD_TYPE_UNIMPORT))) + ret = hab_try_get_vchan(pchan, header, &vchan, &need_ret); + if (need_ret) return ret; switch (payload_type) { From 4b5d7627f5075ce9353beabdff7e0b34f9bb5747 Mon Sep 17 00:00:00 2001 From: Yadu MG Date: Wed, 20 Dec 2023 12:10:51 +0530 Subject: [PATCH 40/46] drivers: remoteproc: Ignore SCM call return value for Deep Sleep ADSP teardown is not possible in LPM. Ignore the return value from SCM call for the ADSP teardown. Change-Id: Id41e09222893137e95b327909304973c26b8214b Signed-off-by: Yadu MG --- drivers/remoteproc/qcom_q6v5_pas.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 9557d963e3c6..948cc8bce1cc 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -640,23 +640,21 @@ static int adsp_shutdown(struct rproc *rproc) { struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv; int handover; - int ret; trace_rproc_qcom_event(dev_name(adsp->dev), "adsp_shutdown", "enter"); scm_pas_enable_bw(); + /* + * ADSP teardown is not possible in LPM. Ignore the SCM call return + * status for the teardown sequence. + */ if (adsp->retry_shutdown) - ret = qcom_scm_pas_shutdown_retry(adsp->pas_id); + qcom_scm_pas_shutdown_retry(adsp->pas_id); else - ret = qcom_scm_pas_shutdown(adsp->pas_id); - if (ret) - panic("Panicking, remoteproc %s failed to shutdown.\n", rproc->name); + qcom_scm_pas_shutdown(adsp->pas_id); - if (adsp->dtb_pas_id) { - ret = qcom_scm_pas_shutdown(adsp->dtb_pas_id); - if (ret) - panic("Panicking, remoteproc %s dtb failed to shutdown.\n", rproc->name); - } + if (adsp->dtb_pas_id) + qcom_scm_pas_shutdown(adsp->dtb_pas_id); scm_pas_disable_bw(); adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count); @@ -668,7 +666,7 @@ static int adsp_shutdown(struct rproc *rproc) trace_rproc_qcom_event(dev_name(adsp->dev), "adsp_shutdown", "exit"); - return ret; + return 0; } void adsp_set_ops_stop(struct rproc *rproc, bool suspend) From f43c02487a4a1bfe5ed754b3a5ae76e8e2111f61 Mon Sep 17 00:00:00 2001 From: Manish Nagar Date: Mon, 11 Dec 2023 10:25:49 +0530 Subject: [PATCH 41/46] usb: dwc3: Reduce Cyclomatic complexity in dwc3_msm_suspend Reduce Cyclomatic complexity in dwc3_msm_suspend function and created the dwc3_msm_suspend_phy for the phy. Change-Id: Ibcb58185224b9c2429cf543f92533d511374e754 Signed-off-by: Manish Nagar --- drivers/usb/dwc3/dwc3-msm-core.c | 98 ++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-msm-core.c b/drivers/usb/dwc3/dwc3-msm-core.c index 6b5ce240b6ed..a91e6d34722c 100644 --- a/drivers/usb/dwc3/dwc3-msm-core.c +++ b/drivers/usb/dwc3/dwc3-msm-core.c @@ -3876,13 +3876,65 @@ disable_sleep_clk: return ret; } +static void dwc3_msm_suspend_phy(struct dwc3_msm *mdwc) +{ + bool can_suspend_ssphy, no_active_ss; + + /* + * Synopsys Superspeed PHY does not support ss_phy_irq, so to detect + * any wakeup events in host mode PHY cannot be suspended. + * This Superspeed PHY can be suspended only in the following cases: + * 1. The core is not in host mode + * 2. A Highspeed device is connected but not a Superspeed device + * + */ + + no_active_ss = (!mdwc->in_host_mode) || (mdwc->in_host_mode && + ((mdwc->hs_phy->flags & (PHY_HSFS_MODE | PHY_LS_MODE)) && + !dwc3_msm_is_superspeed(mdwc))); + can_suspend_ssphy = dwc3_msm_get_max_speed(mdwc) >= USB_SPEED_SUPER && + (!(mdwc->use_pwr_event_for_wakeup & PWR_EVENT_SS_WAKEUP) || no_active_ss); + + /* Suspend SS PHY */ + if (can_suspend_ssphy) { + if (mdwc->in_host_mode) { + u32 reg = dwc3_msm_read_reg(mdwc->base, + DWC3_GUSB3PIPECTL(0)); + + reg |= DWC3_GUSB3PIPECTL_DISRXDETU3; + dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(0), + reg); + } + /* indicate phy about SS mode */ + if (dwc3_msm_is_superspeed(mdwc)) + mdwc->ss_phy->flags |= DEVICE_IN_SS_MODE; + usb_phy_set_suspend(mdwc->ss_phy, 1); + mdwc->lpm_flags |= MDWC3_SS_PHY_SUSPEND; + } else if (mdwc->use_pwr_event_for_wakeup & PWR_EVENT_SS_WAKEUP) { + mdwc->lpm_flags |= MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP; + } + + /* + * When operating in HS host mode, check if pwr event IRQ is + * required for wakeup. + */ + + if (mdwc->in_host_mode && (mdwc->use_pwr_event_for_wakeup + & PWR_EVENT_HS_WAKEUP)) + mdwc->lpm_flags |= MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP; + + if (mdwc->lpm_flags & MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP) { + dwc3_msm_set_pwr_events(mdwc, true); + enable_irq(mdwc->wakeup_irq[PWR_EVNT_IRQ].irq); + } +} + static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse) { int ret; struct dwc3 *dwc = NULL; struct dwc3_event_buffer *evt; struct usb_irq *uirq; - bool can_suspend_ssphy, no_active_ss; if (mdwc->dwc3) dwc = platform_get_drvdata(mdwc->dwc3); @@ -3959,49 +4011,7 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc, bool force_power_collapse) /* Suspend HS PHY */ usb_phy_set_suspend(mdwc->hs_phy, 1); - /* - * Synopsys Superspeed PHY does not support ss_phy_irq, so to detect - * any wakeup events in host mode PHY cannot be suspended. - * This Superspeed PHY can be suspended only in the following cases: - * 1. The core is not in host mode - * 2. A Highspeed device is connected but not a Superspeed device - */ - no_active_ss = (!mdwc->in_host_mode) || (mdwc->in_host_mode && - ((mdwc->hs_phy->flags & (PHY_HSFS_MODE | PHY_LS_MODE)) && - !dwc3_msm_is_superspeed(mdwc))); - can_suspend_ssphy = dwc3_msm_get_max_speed(mdwc) >= USB_SPEED_SUPER && - (!(mdwc->use_pwr_event_for_wakeup & PWR_EVENT_SS_WAKEUP) || no_active_ss); - /* Suspend SS PHY */ - if (can_suspend_ssphy) { - if (mdwc->in_host_mode) { - u32 reg = dwc3_msm_read_reg(mdwc->base, - DWC3_GUSB3PIPECTL(0)); - - reg |= DWC3_GUSB3PIPECTL_DISRXDETU3; - dwc3_msm_write_reg(mdwc->base, DWC3_GUSB3PIPECTL(0), - reg); - } - /* indicate phy about SS mode */ - if (dwc3_msm_is_superspeed(mdwc)) - mdwc->ss_phy->flags |= DEVICE_IN_SS_MODE; - usb_phy_set_suspend(mdwc->ss_phy, 1); - mdwc->lpm_flags |= MDWC3_SS_PHY_SUSPEND; - } else if (mdwc->use_pwr_event_for_wakeup & PWR_EVENT_SS_WAKEUP) { - mdwc->lpm_flags |= MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP; - } - - /* - * When operating in HS host mode, check if pwr event IRQ is - * required for wakeup. - */ - if (mdwc->in_host_mode && (mdwc->use_pwr_event_for_wakeup - & PWR_EVENT_HS_WAKEUP)) - mdwc->lpm_flags |= MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP; - - if (mdwc->lpm_flags & MDWC3_USE_PWR_EVENT_IRQ_FOR_WAKEUP) { - dwc3_msm_set_pwr_events(mdwc, true); - enable_irq(mdwc->wakeup_irq[PWR_EVNT_IRQ].irq); - } + dwc3_msm_suspend_phy(mdwc); /* make sure above writes are completed before turning off clocks */ wmb(); From 1b00e8fe32db705844bccc7b3291cb13d2f1223d Mon Sep 17 00:00:00 2001 From: Sushanth Vadapally Date: Thu, 31 Aug 2023 16:28:18 +0530 Subject: [PATCH 42/46] iommu/arm-smmu: Adding NULL checks Added NULL checks to avoid NULL pointer dereference. Change-Id: Ifa92792c116d752b80fbcc94daf53fd9d0cdab04 Signed-off-by: Sushanth Vadapally Signed-off-by: Madhu Ananthula --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 5bf0e5d79293..f4910bf6aa61 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -458,6 +458,9 @@ static int __arm_smmu_alloc_cb(unsigned long *map, int start, int end, int i; int cb = -EINVAL; + if (!fwspec || !cfg) + return cb; + for_each_cfg_sme(cfg, fwspec, i, idx) { if (smmu->s2crs[idx].pinned) cb = smmu->s2crs[idx].cbndx; @@ -1113,7 +1116,7 @@ static bool arm_smmu_master_attached(struct arm_smmu_device *smmu, struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev); - if (!cfg || !fwspec) + if (!fwspec || !cfg) return false; for_each_cfg_sme(cfg, fwspec, i, idx) { @@ -1959,6 +1962,9 @@ static int arm_smmu_master_alloc_smes(struct device *dev) bool config_smrs = !dev_defer_smr_configuration(dev); int i, idx, ret; + if (!fwspec || !cfg) + return -EINVAL; + mutex_lock(&smmu->stream_map_mutex); /* Figure out a viable stream map entry allocation */ for_each_cfg_sme(cfg, fwspec, i, idx) { @@ -2771,6 +2777,9 @@ static struct iommu_group *arm_smmu_device_group(struct device *dev) struct iommu_group *group = NULL; int i, idx; + if (!cfg || !fwspec) + return ERR_PTR(-EINVAL); + mutex_lock(&smmu->stream_map_mutex); group = of_get_device_group(dev); if (group) From 2c7a8e4126886ae4c076e3d52d001fd2a81250fa Mon Sep 17 00:00:00 2001 From: Sushanth Vadapally Date: Tue, 26 Sep 2023 12:31:33 +0530 Subject: [PATCH 43/46] iommu/arm-smmu: Checks added for NULL pointer Added NULL checks to avoid NULL pointer dereference. Change-Id: Id418925d708fa6bcafb37991d770d4ac7e2a69d9 Signed-off-by: Sushanth Vadapally Signed-off-by: Madhu Ananthula --- drivers/iommu/arm/arm-smmu/arm-smmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index f4910bf6aa61..fa8b0ab06d7e 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -453,14 +453,14 @@ static int __arm_smmu_alloc_cb(unsigned long *map, int start, int end, { struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev); - struct arm_smmu_device *smmu = cfg->smmu; + struct arm_smmu_device *smmu; int idx; int i; int cb = -EINVAL; if (!fwspec || !cfg) return cb; - + smmu = cfg->smmu; for_each_cfg_sme(cfg, fwspec, i, idx) { if (smmu->s2crs[idx].pinned) cb = smmu->s2crs[idx].cbndx; From 531d6f5b6b96753ed9c12e7a4333bec69ec398c9 Mon Sep 17 00:00:00 2001 From: Shudan Liu Date: Fri, 29 Dec 2023 09:57:28 +0800 Subject: [PATCH 44/46] arm64: defconfig: align defconfig with kalama le kalama lu share the same configurations as kalama le, it use the same HW platform, so sync defconfig. Change-Id: I904f84e061a7bafa10328f0b6f27431dd039fb3a Signed-off-by: Shudan Liu --- arch/arm64/configs/kalama_lu_gki.fragment | 4 ++++ arch/arm64/configs/vendor/kalama_lu_GKI.config | 7 ++++++- arch/arm64/configs/vendor/kalama_lu_consolidate.config | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/arm64/configs/kalama_lu_gki.fragment b/arch/arm64/configs/kalama_lu_gki.fragment index a6716f9d66d1..771c1d29366b 100644 --- a/arch/arm64/configs/kalama_lu_gki.fragment +++ b/arch/arm64/configs/kalama_lu_gki.fragment @@ -9,3 +9,7 @@ CONFIG_GPIO_SYSFS=y CONFIG_PM_AUTOSLEEP=y CONFIG_CAN=y CONFIG_USB_XHCI_PCI_RENESAS=y +CONFIG_HWMON=y +CONFIG_POWER_SUPPLY_HWMON=y +CONFIG_THERMAL_HWMON=y + diff --git a/arch/arm64/configs/vendor/kalama_lu_GKI.config b/arch/arm64/configs/vendor/kalama_lu_GKI.config index d3e3f98066ad..d9d299d88272 100644 --- a/arch/arm64/configs/vendor/kalama_lu_GKI.config +++ b/arch/arm64/configs/vendor/kalama_lu_GKI.config @@ -35,10 +35,11 @@ CONFIG_CORESIGHT_TGU=m CONFIG_CORESIGHT_TPDA=m CONFIG_CORESIGHT_TPDM=m CONFIG_CPU_IDLE_GOV_QCOM_LPM=m -CONFIG_DRM_LT9611UXC=m +# CONFIG_DRM_LT9611UXC is not set CONFIG_EDAC_QCOM=m # CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE is not set CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y +CONFIG_EP_PCIE=m # CONFIG_EXT4_KUNIT_TESTS is not set # CONFIG_FAT_KUNIT_TEST is not set CONFIG_GH_ARM64_DRV=m @@ -114,6 +115,8 @@ CONFIG_MSM_CORE_HANG_DETECT=m CONFIG_MSM_GLOBAL_SYNX=m CONFIG_MSM_GPI_DMA=m # CONFIG_MSM_GPI_DMA_DEBUG is not set +CONFIG_MSM_MHI_DEV=m +CONFIG_MSM_MHI_NET_DEV=m CONFIG_MSM_PERFORMANCE=m CONFIG_MSM_POWER_STATE=m CONFIG_MSM_QBT_HANDLER=m @@ -257,6 +260,7 @@ CONFIG_QCOM_WDT_CORE=m CONFIG_QRTR=m CONFIG_QRTR_GUNYAH=m CONFIG_QRTR_MHI=m +# CONFIG_QRTR_MHI_DEV is not set CONFIG_QRTR_SMD=m # CONFIG_QRTR_TUN is not set CONFIG_QSEECOM_PROXY=m @@ -368,6 +372,7 @@ CONFIG_USB_M31_MSM_EUSB2_PHY=m CONFIG_USB_MON=m CONFIG_USB_MSM_EUSB2_PHY=m CONFIG_USB_MSM_SSPHY_QMP=m +CONFIG_USB_NET_AX88179_178A=m # CONFIG_USB_NET_RNDIS_WLAN is not set CONFIG_USB_QCOM_EMU_PHY=m CONFIG_USB_REDRIVER=m diff --git a/arch/arm64/configs/vendor/kalama_lu_consolidate.config b/arch/arm64/configs/vendor/kalama_lu_consolidate.config index b298fbb0b001..1b4372fba6b9 100644 --- a/arch/arm64/configs/vendor/kalama_lu_consolidate.config +++ b/arch/arm64/configs/vendor/kalama_lu_consolidate.config @@ -15,12 +15,15 @@ CONFIG_MSM_GPI_DMA_DEBUG=y # CONFIG_QCOM_DYN_MINIDUMP_STACK is not set CONFIG_QCOM_RTB=m CONFIG_QCOM_RTB_SEPARATE_CPUS=y +CONFIG_QRC=m +CONFIG_QRC_DEBUG=m CONFIG_QTI_PMIC_GLINK_CLIENT_DEBUG=y CONFIG_RCU_TORTURE_TEST=m CONFIG_REGMAP_QTI_DEBUGFS_ALLOW_WRITE=y CONFIG_RPMSG_QCOM_GLINK_DEBUG=y CONFIG_RUNTIME_TESTING_MENU=y CONFIG_SCHED_WALT_DEBUG=m +CONFIG_SENSORS_PWM_FAN=m CONFIG_SPI_SPIDEV=m CONFIG_TEST_USER_COPY=m CONFIG_UFS_DBG=y From 5f191aac3de0c81bfc3cbd2432569c07d6d24e23 Mon Sep 17 00:00:00 2001 From: Jagadeesh Kona Date: Mon, 20 Nov 2023 15:53:38 +0530 Subject: [PATCH 45/46] clk: qcom: videocc-kalama: Keep video_cc_sleep_clk always ON Remove video_cc_sleep_clk modelling and keep it always ON from clock driver. Change-Id: I4148e9223ba28a2ad3d2533ead368a76f5095efa Signed-off-by: Jagadeesh Kona --- drivers/clk/qcom/videocc-kalama.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/clk/qcom/videocc-kalama.c b/drivers/clk/qcom/videocc-kalama.c index 8a2848c1be58..bde07062eca9 100644 --- a/drivers/clk/qcom/videocc-kalama.c +++ b/drivers/clk/qcom/videocc-kalama.c @@ -493,32 +493,16 @@ static struct clk_branch video_cc_mvs1c_clk = { }, }; -static struct clk_branch video_cc_sleep_clk = { - .halt_reg = 0x8140, - .halt_check = BRANCH_HALT, - .clkr = { - .enable_reg = 0x8140, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "video_cc_sleep_clk", - .parent_hws = (const struct clk_hw*[]){ - &video_cc_sleep_clk_src.clkr.hw, - }, - .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, - .ops = &clk_branch2_ops, - }, - }, -}; - /* * video_cc_ahb_clk * video_cc_xo_clk + * video_cc_sleep_clk */ static struct critical_clk_offset critical_clk_list[] = { { .offset = 0x80f4, .mask = BIT(0) }, { .offset = 0x8124, .mask = BIT(0) }, + { .offset = 0x8140, .mask = BIT(0) }, }; static struct clk_regmap *video_cc_kalama_clocks[] = { @@ -535,7 +519,6 @@ static struct clk_regmap *video_cc_kalama_clocks[] = { [VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr, [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, [VIDEO_CC_PLL1] = &video_cc_pll1.clkr, - [VIDEO_CC_SLEEP_CLK] = &video_cc_sleep_clk.clkr, [VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr, [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, }; From 16935d4078a21f27da3ce3ebbcac5d31882422ec Mon Sep 17 00:00:00 2001 From: Saranya R Date: Tue, 2 Jan 2024 17:30:52 +0530 Subject: [PATCH 46/46] soc: qcom: Add CROW_LTE SoC information to socinfo Add CROW_LTE SoC information to socinfo. Change-Id: I8bcd5246c23f2772785e67dea7966852d7a89e88 Signed-off-by: Saranya R --- drivers/soc/qcom/socinfo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index de69d9bb2c97..c6da8233ce71 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -2,7 +2,7 @@ /* * Copyright (c) 2009-2017, 2021 The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019, Linaro Ltd. - * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1249,6 +1249,7 @@ static const struct soc_id soc_id[] = { { 606, "MONACOAU_IVI"}, { 607, "MONACOAU_SRV1L"}, { 608, "CROW" }, + { 644, "CROW_LTE" }, }; static struct qcom_socinfo *qsocinfo;