^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2020, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/pm_clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <dt-bindings/clock/qcom,mss-sc7180.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "clk-regmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "clk-branch.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static struct clk_branch mss_axi_nav_clk = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) .halt_reg = 0x20bc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) .halt_check = BRANCH_HALT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) .clkr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) .enable_reg = 0x20bc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) .enable_mask = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) .hw.init = &(struct clk_init_data){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) .name = "mss_axi_nav_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .parent_data = &(const struct clk_parent_data){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .fw_name = "gcc_mss_nav_axi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .num_parents = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .ops = &clk_branch2_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static struct clk_branch mss_axi_crypto_clk = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .halt_reg = 0x20cc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .halt_check = BRANCH_HALT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .clkr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .enable_reg = 0x20cc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .enable_mask = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .hw.init = &(struct clk_init_data){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .name = "mss_axi_crypto_clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .parent_data = &(const struct clk_parent_data){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .fw_name = "gcc_mss_mfab_axis",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .num_parents = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .ops = &clk_branch2_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static const struct regmap_config mss_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .fast_io = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .max_register = 0x41aa0cc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static struct clk_regmap *mss_sc7180_clocks[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) [MSS_AXI_CRYPTO_CLK] = &mss_axi_crypto_clk.clkr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) [MSS_AXI_NAV_CLK] = &mss_axi_nav_clk.clkr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static const struct qcom_cc_desc mss_sc7180_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .config = &mss_regmap_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .clks = mss_sc7180_clocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .num_clks = ARRAY_SIZE(mss_sc7180_clocks),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int mss_sc7180_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ret = pm_clk_create(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) goto disable_pm_runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ret = pm_clk_add(&pdev->dev, "cfg_ahb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) dev_err(&pdev->dev, "failed to acquire iface clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) goto destroy_pm_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ret = qcom_cc_probe(pdev, &mss_sc7180_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) goto destroy_pm_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) destroy_pm_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) pm_clk_destroy(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) disable_pm_runtime:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int mss_sc7180_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) pm_clk_destroy(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static const struct dev_pm_ops mss_sc7180_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static const struct of_device_id mss_sc7180_match_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) { .compatible = "qcom,sc7180-mss" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) MODULE_DEVICE_TABLE(of, mss_sc7180_match_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static struct platform_driver mss_sc7180_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .probe = mss_sc7180_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .remove = mss_sc7180_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .name = "sc7180-mss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .of_match_table = mss_sc7180_match_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .pm = &mss_sc7180_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static int __init mss_sc7180_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return platform_driver_register(&mss_sc7180_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) subsys_initcall(mss_sc7180_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static void __exit mss_sc7180_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) platform_driver_unregister(&mss_sc7180_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) module_exit(mss_sc7180_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) MODULE_DESCRIPTION("QTI MSS SC7180 Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) MODULE_LICENSE("GPL v2");