1892df019SBjorn Andersson // SPDX-License-Identifier: GPL-2.0 2892df019SBjorn Andersson /* 3892df019SBjorn Andersson * Copyright (c) 2019, Linaro Ltd. 4892df019SBjorn Andersson */ 5892df019SBjorn Andersson 6892df019SBjorn Andersson #include <linux/bitops.h> 7*96ea2a42SVinod Koul #include <linux/clk-provider.h> 8892df019SBjorn Andersson #include <linux/err.h> 9892df019SBjorn Andersson #include <linux/platform_device.h> 10892df019SBjorn Andersson #include <linux/module.h> 11892df019SBjorn Andersson #include <linux/of_address.h> 12892df019SBjorn Andersson #include <linux/pm_clock.h> 13892df019SBjorn Andersson #include <linux/pm_runtime.h> 14892df019SBjorn Andersson #include <linux/regmap.h> 15892df019SBjorn Andersson 16892df019SBjorn Andersson #include <dt-bindings/clock/qcom,turingcc-qcs404.h> 17892df019SBjorn Andersson 18892df019SBjorn Andersson #include "clk-regmap.h" 19892df019SBjorn Andersson #include "clk-branch.h" 20892df019SBjorn Andersson #include "common.h" 21892df019SBjorn Andersson #include "reset.h" 22892df019SBjorn Andersson 23892df019SBjorn Andersson static struct clk_branch turing_wrapper_aon_cbcr = { 24892df019SBjorn Andersson .halt_reg = 0x5098, 25892df019SBjorn Andersson .halt_check = BRANCH_HALT, 26892df019SBjorn Andersson .clkr = { 27892df019SBjorn Andersson .enable_reg = 0x5098, 28892df019SBjorn Andersson .enable_mask = BIT(0), 29892df019SBjorn Andersson .hw.init = &(struct clk_init_data) { 30892df019SBjorn Andersson .name = "turing_wrapper_aon_clk", 31892df019SBjorn Andersson .ops = &clk_branch2_aon_ops, 32892df019SBjorn Andersson }, 33892df019SBjorn Andersson }, 34892df019SBjorn Andersson }; 35892df019SBjorn Andersson 36892df019SBjorn Andersson static struct clk_branch turing_q6ss_ahbm_aon_cbcr = { 37892df019SBjorn Andersson .halt_reg = 0x9000, 38892df019SBjorn Andersson .halt_check = BRANCH_HALT, 39892df019SBjorn Andersson .clkr = { 40892df019SBjorn Andersson .enable_reg = 0x9000, 41892df019SBjorn Andersson .enable_mask = BIT(0), 42892df019SBjorn Andersson .hw.init = &(struct clk_init_data) { 43892df019SBjorn Andersson .name = "turing_q6ss_ahbm_aon_cbcr", 44892df019SBjorn Andersson .ops = &clk_branch2_ops, 45892df019SBjorn Andersson }, 46892df019SBjorn Andersson }, 47892df019SBjorn Andersson }; 48892df019SBjorn Andersson 49892df019SBjorn Andersson static struct clk_branch turing_q6ss_q6_axim_clk = { 50892df019SBjorn Andersson .halt_reg = 0xb000, 51892df019SBjorn Andersson .halt_check = BRANCH_HALT, 52892df019SBjorn Andersson .clkr = { 53892df019SBjorn Andersson .enable_reg = 0xb000, 54892df019SBjorn Andersson .enable_mask = BIT(0), 55892df019SBjorn Andersson .hw.init = &(struct clk_init_data) { 56892df019SBjorn Andersson .name = "turing_q6ss_q6_axim_clk", 57892df019SBjorn Andersson .ops = &clk_branch2_aon_ops, 58892df019SBjorn Andersson }, 59892df019SBjorn Andersson }, 60892df019SBjorn Andersson }; 61892df019SBjorn Andersson 62892df019SBjorn Andersson static struct clk_branch turing_q6ss_ahbs_aon_cbcr = { 63892df019SBjorn Andersson .halt_reg = 0x10000, 64892df019SBjorn Andersson .halt_check = BRANCH_HALT, 65892df019SBjorn Andersson .clkr = { 66892df019SBjorn Andersson .enable_reg = 0x10000, 67892df019SBjorn Andersson .enable_mask = BIT(0), 68892df019SBjorn Andersson .hw.init = &(struct clk_init_data) { 69892df019SBjorn Andersson .name = "turing_q6ss_ahbs_aon_clk", 70892df019SBjorn Andersson .ops = &clk_branch2_aon_ops, 71892df019SBjorn Andersson }, 72892df019SBjorn Andersson }, 73892df019SBjorn Andersson }; 74892df019SBjorn Andersson 75892df019SBjorn Andersson static struct clk_branch turing_wrapper_qos_ahbs_aon_cbcr = { 76892df019SBjorn Andersson .halt_reg = 0x11014, 77892df019SBjorn Andersson .halt_check = BRANCH_HALT, 78892df019SBjorn Andersson .clkr = { 79892df019SBjorn Andersson .enable_reg = 0x11014, 80892df019SBjorn Andersson .enable_mask = BIT(0), 81892df019SBjorn Andersson .hw.init = &(struct clk_init_data) { 82892df019SBjorn Andersson .name = "turing_wrapper_qos_ahbs_aon_clk", 83892df019SBjorn Andersson .ops = &clk_branch2_aon_ops, 84892df019SBjorn Andersson }, 85892df019SBjorn Andersson }, 86892df019SBjorn Andersson }; 87892df019SBjorn Andersson 88892df019SBjorn Andersson static struct clk_regmap *turingcc_clocks[] = { 89892df019SBjorn Andersson [TURING_WRAPPER_AON_CLK] = &turing_wrapper_aon_cbcr.clkr, 90892df019SBjorn Andersson [TURING_Q6SS_AHBM_AON_CLK] = &turing_q6ss_ahbm_aon_cbcr.clkr, 91892df019SBjorn Andersson [TURING_Q6SS_Q6_AXIM_CLK] = &turing_q6ss_q6_axim_clk.clkr, 92892df019SBjorn Andersson [TURING_Q6SS_AHBS_AON_CLK] = &turing_q6ss_ahbs_aon_cbcr.clkr, 93892df019SBjorn Andersson [TURING_WRAPPER_QOS_AHBS_AON_CLK] = &turing_wrapper_qos_ahbs_aon_cbcr.clkr, 94892df019SBjorn Andersson }; 95892df019SBjorn Andersson 96892df019SBjorn Andersson static const struct regmap_config turingcc_regmap_config = { 97892df019SBjorn Andersson .reg_bits = 32, 98892df019SBjorn Andersson .reg_stride = 4, 99892df019SBjorn Andersson .val_bits = 32, 1003bcff3e4SJorge Ramirez-Ortiz .max_register = 0x23004, 101892df019SBjorn Andersson .fast_io = true, 102892df019SBjorn Andersson }; 103892df019SBjorn Andersson 104892df019SBjorn Andersson static const struct qcom_cc_desc turingcc_desc = { 105892df019SBjorn Andersson .config = &turingcc_regmap_config, 106892df019SBjorn Andersson .clks = turingcc_clocks, 107892df019SBjorn Andersson .num_clks = ARRAY_SIZE(turingcc_clocks), 108892df019SBjorn Andersson }; 109892df019SBjorn Andersson 110892df019SBjorn Andersson static int turingcc_probe(struct platform_device *pdev) 111892df019SBjorn Andersson { 112892df019SBjorn Andersson int ret; 113892df019SBjorn Andersson 11472cfc73fSDmitry Baryshkov ret = devm_pm_runtime_enable(&pdev->dev); 115892df019SBjorn Andersson if (ret) 11672cfc73fSDmitry Baryshkov return ret; 11772cfc73fSDmitry Baryshkov 11872cfc73fSDmitry Baryshkov ret = devm_pm_clk_create(&pdev->dev); 11972cfc73fSDmitry Baryshkov if (ret) 12072cfc73fSDmitry Baryshkov return ret; 121892df019SBjorn Andersson 122892df019SBjorn Andersson ret = pm_clk_add(&pdev->dev, NULL); 123892df019SBjorn Andersson if (ret < 0) { 124892df019SBjorn Andersson dev_err(&pdev->dev, "failed to acquire iface clock\n"); 12572cfc73fSDmitry Baryshkov return ret; 126892df019SBjorn Andersson } 127892df019SBjorn Andersson 128892df019SBjorn Andersson ret = qcom_cc_probe(pdev, &turingcc_desc); 129892df019SBjorn Andersson if (ret < 0) 130892df019SBjorn Andersson return ret; 131892df019SBjorn Andersson 132892df019SBjorn Andersson return 0; 133892df019SBjorn Andersson } 134892df019SBjorn Andersson 135892df019SBjorn Andersson static const struct dev_pm_ops turingcc_pm_ops = { 136892df019SBjorn Andersson SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) 137892df019SBjorn Andersson }; 138892df019SBjorn Andersson 139892df019SBjorn Andersson static const struct of_device_id turingcc_match_table[] = { 140892df019SBjorn Andersson { .compatible = "qcom,qcs404-turingcc" }, 141892df019SBjorn Andersson { } 142892df019SBjorn Andersson }; 143892df019SBjorn Andersson MODULE_DEVICE_TABLE(of, turingcc_match_table); 144892df019SBjorn Andersson 145892df019SBjorn Andersson static struct platform_driver turingcc_driver = { 146892df019SBjorn Andersson .probe = turingcc_probe, 147892df019SBjorn Andersson .driver = { 148892df019SBjorn Andersson .name = "qcs404-turingcc", 149892df019SBjorn Andersson .of_match_table = turingcc_match_table, 150892df019SBjorn Andersson .pm = &turingcc_pm_ops, 151892df019SBjorn Andersson }, 152892df019SBjorn Andersson }; 153892df019SBjorn Andersson 154892df019SBjorn Andersson module_platform_driver(turingcc_driver); 155892df019SBjorn Andersson 156892df019SBjorn Andersson MODULE_DESCRIPTION("Qualcomm QCS404 Turing Clock Controller"); 157892df019SBjorn Andersson MODULE_LICENSE("GPL v2"); 158