From 45c7e7b8308efc550d3df91a4db8546e33d74a15 Mon Sep 17 00:00:00 2001 From: Xubin Bai Date: Fri, 3 Jun 2022 00:15:59 -0700 Subject: [PATCH] clk: qcom: tcsrcc-pineapple: Add initial tcsrcc driver Add the tcsrcc driver for Pineapple, which provides support for miscellaneous top-level clocks. Change-Id: Ided7c397983ccefafb6a22373eea5625781f778e Signed-off-by: Xubin Bai --- drivers/clk/qcom/Kconfig | 9 ++ drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/tcsrcc-pineapple.c | 183 ++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 drivers/clk/qcom/tcsrcc-pineapple.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 6ba11c65e912..fd89515afda8 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -737,6 +737,15 @@ config SM_VIDEOCC_PINEAPPLE Say Y if you want to support video devices and functionality such as video encode/decode. +config SM_TCSRCC_PINEAPPLE + tristate "Pineapple Top-Level CSR Clock Controller" + depends on SM_GCC_PINEAPPLE + help + Support for the TCSR clock controller on Qualcomm Technologies, Inc + Pineapple devices. + Say Y if you want to support miscellaneous top-level clocks + such as for the PHY references. + config SPMI_PMIC_CLKDIV tristate "SPMI PMIC clkdiv Support" depends on SPMI || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 3dd66975362c..13c86fdb9885 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -110,6 +110,7 @@ obj-$(CONFIG_SM_GPUCC_8250) += gpucc-sm8250.o obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o obj-$(CONFIG_SM_VIDEOCC_8250) += videocc-sm8250.o obj-$(CONFIG_SM_VIDEOCC_PINEAPPLE) += videocc-pineapple.o +obj-$(CONFIG_SM_TCSRCC_PINEAPPLE) += tcsrcc-pineapple.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o obj-$(CONFIG_QCOM_HFPLL) += hfpll.o diff --git a/drivers/clk/qcom/tcsrcc-pineapple.c b/drivers/clk/qcom/tcsrcc-pineapple.c new file mode 100644 index 000000000000..ec8da845df20 --- /dev/null +++ b/drivers/clk/qcom/tcsrcc-pineapple.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "reset.h" +#include "vdd-level.h" + +static struct clk_branch tcsr_pcie_0_clkref_en = { + .halt_reg = 0xb1100, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xb1100, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "tcsr_pcie_0_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_pcie_1_clkref_en = { + .halt_reg = 0xb1114, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xb1114, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "tcsr_pcie_1_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_ufs_clkref_en = { + .halt_reg = 0xb1110, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xb1110, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "tcsr_ufs_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_ufs_pad_clkref_en = { + .halt_reg = 0xb1104, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xb1104, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "tcsr_ufs_pad_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb2_clkref_en = { + .halt_reg = 0xb1118, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xb1118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "tcsr_usb2_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb3_clkref_en = { + .halt_reg = 0xb1108, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xb1108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data){ + .name = "tcsr_usb3_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *tcsr_cc_pineapple_clocks[] = { + [TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr, + [TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr, + [TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr, + [TCSR_UFS_PAD_CLKREF_EN] = &tcsr_ufs_pad_clkref_en.clkr, + [TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr, + [TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr, +}; + +static const struct regmap_config tcsr_cc_pineapple_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xbb000, + .fast_io = true, +}; + +static const struct qcom_cc_desc tcsr_cc_pineapple_desc = { + .config = &tcsr_cc_pineapple_regmap_config, + .clks = tcsr_cc_pineapple_clocks, + .num_clks = ARRAY_SIZE(tcsr_cc_pineapple_clocks), +}; + +static const struct of_device_id tcsr_cc_pineapple_match_table[] = { + { .compatible = "qcom,pineapple-tcsrcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, tcsr_cc_pineapple_match_table); + +static int tcsr_cc_pineapple_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + regmap = qcom_cc_map(pdev, &tcsr_cc_pineapple_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + + ret = qcom_cc_really_probe(pdev, &tcsr_cc_pineapple_desc, regmap); + if (ret) { + dev_err(&pdev->dev, "Failed to register TCSR CC clocks\n"); + return ret; + } + + dev_info(&pdev->dev, "Registered TCSR CC clocks\n"); + + return ret; +} + +static void tcsr_cc_pineapple_sync_state(struct device *dev) +{ + qcom_cc_sync_state(dev, &tcsr_cc_pineapple_desc); +} + +static struct platform_driver tcsr_cc_pineapple_driver = { + .probe = tcsr_cc_pineapple_probe, + .driver = { + .name = "tcsr_cc-pineapple", + .of_match_table = tcsr_cc_pineapple_match_table, + .sync_state = tcsr_cc_pineapple_sync_state, + }, +}; + +static int __init tcsr_cc_pineapple_init(void) +{ + return platform_driver_register(&tcsr_cc_pineapple_driver); +} +subsys_initcall(tcsr_cc_pineapple_init); + +static void __exit tcsr_cc_pineapple_exit(void) +{ + platform_driver_unregister(&tcsr_cc_pineapple_driver); +} +module_exit(tcsr_cc_pineapple_exit); + +MODULE_DESCRIPTION("QTI TCSR_CC PINEAPPLE Driver"); +MODULE_LICENSE("GPL v2");