13495e295SManivannan Sadhasivam // SPDX-License-Identifier: GPL-2.0+ 23495e295SManivannan Sadhasivam // 33495e295SManivannan Sadhasivam // OWL common clock driver 43495e295SManivannan Sadhasivam // 53495e295SManivannan Sadhasivam // Copyright (c) 2014 Actions Semi Inc. 63495e295SManivannan Sadhasivam // Author: David Liu <liuwei@actions-semi.com> 73495e295SManivannan Sadhasivam // 83495e295SManivannan Sadhasivam // Copyright (c) 2018 Linaro Ltd. 93495e295SManivannan Sadhasivam // Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 103495e295SManivannan Sadhasivam 113495e295SManivannan Sadhasivam #include <linux/of_address.h> 123495e295SManivannan Sadhasivam #include <linux/of_platform.h> 133495e295SManivannan Sadhasivam #include <linux/platform_device.h> 143495e295SManivannan Sadhasivam #include <linux/regmap.h> 153495e295SManivannan Sadhasivam 163495e295SManivannan Sadhasivam #include "owl-common.h" 173495e295SManivannan Sadhasivam 183495e295SManivannan Sadhasivam static const struct regmap_config owl_regmap_config = { 193495e295SManivannan Sadhasivam .reg_bits = 32, 203495e295SManivannan Sadhasivam .reg_stride = 4, 213495e295SManivannan Sadhasivam .val_bits = 32, 223495e295SManivannan Sadhasivam .max_register = 0x00cc, 233495e295SManivannan Sadhasivam .fast_io = true, 243495e295SManivannan Sadhasivam }; 253495e295SManivannan Sadhasivam 263495e295SManivannan Sadhasivam static void owl_clk_set_regmap(const struct owl_clk_desc *desc, 273495e295SManivannan Sadhasivam struct regmap *regmap) 283495e295SManivannan Sadhasivam { 293495e295SManivannan Sadhasivam int i; 303495e295SManivannan Sadhasivam struct owl_clk_common *clks; 313495e295SManivannan Sadhasivam 323495e295SManivannan Sadhasivam for (i = 0; i < desc->num_clks; i++) { 333495e295SManivannan Sadhasivam clks = desc->clks[i]; 343495e295SManivannan Sadhasivam if (!clks) 353495e295SManivannan Sadhasivam continue; 363495e295SManivannan Sadhasivam 373495e295SManivannan Sadhasivam clks->regmap = regmap; 383495e295SManivannan Sadhasivam } 393495e295SManivannan Sadhasivam } 403495e295SManivannan Sadhasivam 413495e295SManivannan Sadhasivam int owl_clk_regmap_init(struct platform_device *pdev, 423a23eb72SManivannan Sadhasivam struct owl_clk_desc *desc) 433495e295SManivannan Sadhasivam { 443495e295SManivannan Sadhasivam void __iomem *base; 453495e295SManivannan Sadhasivam struct regmap *regmap; 463495e295SManivannan Sadhasivam struct resource *res; 473495e295SManivannan Sadhasivam 483495e295SManivannan Sadhasivam res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 493495e295SManivannan Sadhasivam base = devm_ioremap_resource(&pdev->dev, res); 503495e295SManivannan Sadhasivam if (IS_ERR(base)) 513495e295SManivannan Sadhasivam return PTR_ERR(base); 523495e295SManivannan Sadhasivam 533495e295SManivannan Sadhasivam regmap = devm_regmap_init_mmio(&pdev->dev, base, &owl_regmap_config); 543495e295SManivannan Sadhasivam if (IS_ERR(regmap)) { 553495e295SManivannan Sadhasivam pr_err("failed to init regmap\n"); 563495e295SManivannan Sadhasivam return PTR_ERR(regmap); 573495e295SManivannan Sadhasivam } 583495e295SManivannan Sadhasivam 593495e295SManivannan Sadhasivam owl_clk_set_regmap(desc, regmap); 603a23eb72SManivannan Sadhasivam desc->regmap = regmap; 613495e295SManivannan Sadhasivam 623495e295SManivannan Sadhasivam return 0; 633495e295SManivannan Sadhasivam } 643495e295SManivannan Sadhasivam 653495e295SManivannan Sadhasivam int owl_clk_probe(struct device *dev, struct clk_hw_onecell_data *hw_clks) 663495e295SManivannan Sadhasivam { 673495e295SManivannan Sadhasivam int i, ret; 683495e295SManivannan Sadhasivam struct clk_hw *hw; 693495e295SManivannan Sadhasivam 703495e295SManivannan Sadhasivam for (i = 0; i < hw_clks->num; i++) { 71cf9ec1fcSStephen Boyd const char *name; 723495e295SManivannan Sadhasivam 733495e295SManivannan Sadhasivam hw = hw_clks->hws[i]; 743495e295SManivannan Sadhasivam if (IS_ERR_OR_NULL(hw)) 753495e295SManivannan Sadhasivam continue; 763495e295SManivannan Sadhasivam 77cf9ec1fcSStephen Boyd name = hw->init->name; 783495e295SManivannan Sadhasivam ret = devm_clk_hw_register(dev, hw); 793495e295SManivannan Sadhasivam if (ret) { 803495e295SManivannan Sadhasivam dev_err(dev, "Couldn't register clock %d - %s\n", 81cf9ec1fcSStephen Boyd i, name); 823495e295SManivannan Sadhasivam return ret; 833495e295SManivannan Sadhasivam } 843495e295SManivannan Sadhasivam } 853495e295SManivannan Sadhasivam 863495e295SManivannan Sadhasivam ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_clks); 873495e295SManivannan Sadhasivam if (ret) 883495e295SManivannan Sadhasivam dev_err(dev, "Failed to add clock provider\n"); 893495e295SManivannan Sadhasivam 903495e295SManivannan Sadhasivam return ret; 913495e295SManivannan Sadhasivam } 92