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