18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 28c2ecf20Sopenharmony_ci// 38c2ecf20Sopenharmony_ci// OWL common clock driver 48c2ecf20Sopenharmony_ci// 58c2ecf20Sopenharmony_ci// Copyright (c) 2014 Actions Semi Inc. 68c2ecf20Sopenharmony_ci// Author: David Liu <liuwei@actions-semi.com> 78c2ecf20Sopenharmony_ci// 88c2ecf20Sopenharmony_ci// Copyright (c) 2018 Linaro Ltd. 98c2ecf20Sopenharmony_ci// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/of_address.h> 128c2ecf20Sopenharmony_ci#include <linux/of_platform.h> 138c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 148c2ecf20Sopenharmony_ci#include <linux/regmap.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include "owl-common.h" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_cistatic const struct regmap_config owl_regmap_config = { 198c2ecf20Sopenharmony_ci .reg_bits = 32, 208c2ecf20Sopenharmony_ci .reg_stride = 4, 218c2ecf20Sopenharmony_ci .val_bits = 32, 228c2ecf20Sopenharmony_ci .max_register = 0x00cc, 238c2ecf20Sopenharmony_ci .fast_io = true, 248c2ecf20Sopenharmony_ci}; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistatic void owl_clk_set_regmap(const struct owl_clk_desc *desc, 278c2ecf20Sopenharmony_ci struct regmap *regmap) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci int i; 308c2ecf20Sopenharmony_ci struct owl_clk_common *clks; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci for (i = 0; i < desc->num_clks; i++) { 338c2ecf20Sopenharmony_ci clks = desc->clks[i]; 348c2ecf20Sopenharmony_ci if (!clks) 358c2ecf20Sopenharmony_ci continue; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci clks->regmap = regmap; 388c2ecf20Sopenharmony_ci } 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ciint owl_clk_regmap_init(struct platform_device *pdev, 428c2ecf20Sopenharmony_ci struct owl_clk_desc *desc) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci void __iomem *base; 458c2ecf20Sopenharmony_ci struct regmap *regmap; 468c2ecf20Sopenharmony_ci struct resource *res; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 498c2ecf20Sopenharmony_ci base = devm_ioremap_resource(&pdev->dev, res); 508c2ecf20Sopenharmony_ci if (IS_ERR(base)) 518c2ecf20Sopenharmony_ci return PTR_ERR(base); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci regmap = devm_regmap_init_mmio(&pdev->dev, base, &owl_regmap_config); 548c2ecf20Sopenharmony_ci if (IS_ERR(regmap)) { 558c2ecf20Sopenharmony_ci pr_err("failed to init regmap\n"); 568c2ecf20Sopenharmony_ci return PTR_ERR(regmap); 578c2ecf20Sopenharmony_ci } 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci owl_clk_set_regmap(desc, regmap); 608c2ecf20Sopenharmony_ci desc->regmap = regmap; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci return 0; 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ciint owl_clk_probe(struct device *dev, struct clk_hw_onecell_data *hw_clks) 668c2ecf20Sopenharmony_ci{ 678c2ecf20Sopenharmony_ci int i, ret; 688c2ecf20Sopenharmony_ci struct clk_hw *hw; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci for (i = 0; i < hw_clks->num; i++) { 718c2ecf20Sopenharmony_ci const char *name; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci hw = hw_clks->hws[i]; 748c2ecf20Sopenharmony_ci if (IS_ERR_OR_NULL(hw)) 758c2ecf20Sopenharmony_ci continue; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci name = hw->init->name; 788c2ecf20Sopenharmony_ci ret = devm_clk_hw_register(dev, hw); 798c2ecf20Sopenharmony_ci if (ret) { 808c2ecf20Sopenharmony_ci dev_err(dev, "Couldn't register clock %d - %s\n", 818c2ecf20Sopenharmony_ci i, name); 828c2ecf20Sopenharmony_ci return ret; 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci } 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_clks); 878c2ecf20Sopenharmony_ci if (ret) 888c2ecf20Sopenharmony_ci dev_err(dev, "Failed to add clock provider\n"); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci return ret; 918c2ecf20Sopenharmony_ci} 92