18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * PLL clock driver for Keystone devices 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2013 Texas Instruments Inc. 68c2ecf20Sopenharmony_ci * Murali Karicheri <m-karicheri2@ti.com> 78c2ecf20Sopenharmony_ci * Santosh Shilimkar <santosh.shilimkar@ti.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci#include <linux/clk-provider.h> 108c2ecf20Sopenharmony_ci#include <linux/err.h> 118c2ecf20Sopenharmony_ci#include <linux/io.h> 128c2ecf20Sopenharmony_ci#include <linux/slab.h> 138c2ecf20Sopenharmony_ci#include <linux/of_address.h> 148c2ecf20Sopenharmony_ci#include <linux/of.h> 158c2ecf20Sopenharmony_ci#include <linux/module.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#define PLLM_LOW_MASK 0x3f 188c2ecf20Sopenharmony_ci#define PLLM_HIGH_MASK 0x7ffc0 198c2ecf20Sopenharmony_ci#define MAIN_PLLM_HIGH_MASK 0x7f000 208c2ecf20Sopenharmony_ci#define PLLM_HIGH_SHIFT 6 218c2ecf20Sopenharmony_ci#define PLLD_MASK 0x3f 228c2ecf20Sopenharmony_ci#define CLKOD_MASK 0x780000 238c2ecf20Sopenharmony_ci#define CLKOD_SHIFT 19 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci/** 268c2ecf20Sopenharmony_ci * struct clk_pll_data - pll data structure 278c2ecf20Sopenharmony_ci * @has_pllctrl: If set to non zero, lower 6 bits of multiplier is in pllm 288c2ecf20Sopenharmony_ci * register of pll controller, else it is in the pll_ctrl0((bit 11-6) 298c2ecf20Sopenharmony_ci * @phy_pllm: Physical address of PLLM in pll controller. Used when 308c2ecf20Sopenharmony_ci * has_pllctrl is non zero. 318c2ecf20Sopenharmony_ci * @phy_pll_ctl0: Physical address of PLL ctrl0. This could be that of 328c2ecf20Sopenharmony_ci * Main PLL or any other PLLs in the device such as ARM PLL, DDR PLL 338c2ecf20Sopenharmony_ci * or PA PLL available on keystone2. These PLLs are controlled by 348c2ecf20Sopenharmony_ci * this register. Main PLL is controlled by a PLL controller. 358c2ecf20Sopenharmony_ci * @pllm: PLL register map address for multiplier bits 368c2ecf20Sopenharmony_ci * @pllod: PLL register map address for post divider bits 378c2ecf20Sopenharmony_ci * @pll_ctl0: PLL controller map address 388c2ecf20Sopenharmony_ci * @pllm_lower_mask: multiplier lower mask 398c2ecf20Sopenharmony_ci * @pllm_upper_mask: multiplier upper mask 408c2ecf20Sopenharmony_ci * @pllm_upper_shift: multiplier upper shift 418c2ecf20Sopenharmony_ci * @plld_mask: divider mask 428c2ecf20Sopenharmony_ci * @clkod_mask: output divider mask 438c2ecf20Sopenharmony_ci * @clkod_shift: output divider shift 448c2ecf20Sopenharmony_ci * @plld_mask: divider mask 458c2ecf20Sopenharmony_ci * @postdiv: Fixed post divider 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_cistruct clk_pll_data { 488c2ecf20Sopenharmony_ci bool has_pllctrl; 498c2ecf20Sopenharmony_ci u32 phy_pllm; 508c2ecf20Sopenharmony_ci u32 phy_pll_ctl0; 518c2ecf20Sopenharmony_ci void __iomem *pllm; 528c2ecf20Sopenharmony_ci void __iomem *pllod; 538c2ecf20Sopenharmony_ci void __iomem *pll_ctl0; 548c2ecf20Sopenharmony_ci u32 pllm_lower_mask; 558c2ecf20Sopenharmony_ci u32 pllm_upper_mask; 568c2ecf20Sopenharmony_ci u32 pllm_upper_shift; 578c2ecf20Sopenharmony_ci u32 plld_mask; 588c2ecf20Sopenharmony_ci u32 clkod_mask; 598c2ecf20Sopenharmony_ci u32 clkod_shift; 608c2ecf20Sopenharmony_ci u32 postdiv; 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci/** 648c2ecf20Sopenharmony_ci * struct clk_pll - Main pll clock 658c2ecf20Sopenharmony_ci * @hw: clk_hw for the pll 668c2ecf20Sopenharmony_ci * @pll_data: PLL driver specific data 678c2ecf20Sopenharmony_ci */ 688c2ecf20Sopenharmony_cistruct clk_pll { 698c2ecf20Sopenharmony_ci struct clk_hw hw; 708c2ecf20Sopenharmony_ci struct clk_pll_data *pll_data; 718c2ecf20Sopenharmony_ci}; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw) 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic unsigned long clk_pllclk_recalc(struct clk_hw *hw, 768c2ecf20Sopenharmony_ci unsigned long parent_rate) 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci struct clk_pll *pll = to_clk_pll(hw); 798c2ecf20Sopenharmony_ci struct clk_pll_data *pll_data = pll->pll_data; 808c2ecf20Sopenharmony_ci unsigned long rate = parent_rate; 818c2ecf20Sopenharmony_ci u32 mult = 0, prediv, postdiv, val; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci /* 848c2ecf20Sopenharmony_ci * get bits 0-5 of multiplier from pllctrl PLLM register 858c2ecf20Sopenharmony_ci * if has_pllctrl is non zero 868c2ecf20Sopenharmony_ci */ 878c2ecf20Sopenharmony_ci if (pll_data->has_pllctrl) { 888c2ecf20Sopenharmony_ci val = readl(pll_data->pllm); 898c2ecf20Sopenharmony_ci mult = (val & pll_data->pllm_lower_mask); 908c2ecf20Sopenharmony_ci } 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci /* bit6-12 of PLLM is in Main PLL control register */ 938c2ecf20Sopenharmony_ci val = readl(pll_data->pll_ctl0); 948c2ecf20Sopenharmony_ci mult |= ((val & pll_data->pllm_upper_mask) 958c2ecf20Sopenharmony_ci >> pll_data->pllm_upper_shift); 968c2ecf20Sopenharmony_ci prediv = (val & pll_data->plld_mask); 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci if (!pll_data->has_pllctrl) 998c2ecf20Sopenharmony_ci /* read post divider from od bits*/ 1008c2ecf20Sopenharmony_ci postdiv = ((val & pll_data->clkod_mask) >> 1018c2ecf20Sopenharmony_ci pll_data->clkod_shift) + 1; 1028c2ecf20Sopenharmony_ci else if (pll_data->pllod) { 1038c2ecf20Sopenharmony_ci postdiv = readl(pll_data->pllod); 1048c2ecf20Sopenharmony_ci postdiv = ((postdiv & pll_data->clkod_mask) >> 1058c2ecf20Sopenharmony_ci pll_data->clkod_shift) + 1; 1068c2ecf20Sopenharmony_ci } else 1078c2ecf20Sopenharmony_ci postdiv = pll_data->postdiv; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci rate /= (prediv + 1); 1108c2ecf20Sopenharmony_ci rate = (rate * (mult + 1)); 1118c2ecf20Sopenharmony_ci rate /= postdiv; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci return rate; 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cistatic const struct clk_ops clk_pll_ops = { 1178c2ecf20Sopenharmony_ci .recalc_rate = clk_pllclk_recalc, 1188c2ecf20Sopenharmony_ci}; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistatic struct clk *clk_register_pll(struct device *dev, 1218c2ecf20Sopenharmony_ci const char *name, 1228c2ecf20Sopenharmony_ci const char *parent_name, 1238c2ecf20Sopenharmony_ci struct clk_pll_data *pll_data) 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci struct clk_init_data init; 1268c2ecf20Sopenharmony_ci struct clk_pll *pll; 1278c2ecf20Sopenharmony_ci struct clk *clk; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci pll = kzalloc(sizeof(*pll), GFP_KERNEL); 1308c2ecf20Sopenharmony_ci if (!pll) 1318c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci init.name = name; 1348c2ecf20Sopenharmony_ci init.ops = &clk_pll_ops; 1358c2ecf20Sopenharmony_ci init.flags = 0; 1368c2ecf20Sopenharmony_ci init.parent_names = (parent_name ? &parent_name : NULL); 1378c2ecf20Sopenharmony_ci init.num_parents = (parent_name ? 1 : 0); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci pll->pll_data = pll_data; 1408c2ecf20Sopenharmony_ci pll->hw.init = &init; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci clk = clk_register(NULL, &pll->hw); 1438c2ecf20Sopenharmony_ci if (IS_ERR(clk)) 1448c2ecf20Sopenharmony_ci goto out; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci return clk; 1478c2ecf20Sopenharmony_ciout: 1488c2ecf20Sopenharmony_ci kfree(pll); 1498c2ecf20Sopenharmony_ci return NULL; 1508c2ecf20Sopenharmony_ci} 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci/** 1538c2ecf20Sopenharmony_ci * _of_pll_clk_init - PLL initialisation via DT 1548c2ecf20Sopenharmony_ci * @node: device tree node for this clock 1558c2ecf20Sopenharmony_ci * @pllctrl: If true, lower 6 bits of multiplier is in pllm register of 1568c2ecf20Sopenharmony_ci * pll controller, else it is in the control register0(bit 11-6) 1578c2ecf20Sopenharmony_ci */ 1588c2ecf20Sopenharmony_cistatic void __init _of_pll_clk_init(struct device_node *node, bool pllctrl) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci struct clk_pll_data *pll_data; 1618c2ecf20Sopenharmony_ci const char *parent_name; 1628c2ecf20Sopenharmony_ci struct clk *clk; 1638c2ecf20Sopenharmony_ci int i; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci pll_data = kzalloc(sizeof(*pll_data), GFP_KERNEL); 1668c2ecf20Sopenharmony_ci if (!pll_data) { 1678c2ecf20Sopenharmony_ci pr_err("%s: Out of memory\n", __func__); 1688c2ecf20Sopenharmony_ci return; 1698c2ecf20Sopenharmony_ci } 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci parent_name = of_clk_get_parent_name(node, 0); 1728c2ecf20Sopenharmony_ci if (of_property_read_u32(node, "fixed-postdiv", &pll_data->postdiv)) { 1738c2ecf20Sopenharmony_ci /* assume the PLL has output divider register bits */ 1748c2ecf20Sopenharmony_ci pll_data->clkod_mask = CLKOD_MASK; 1758c2ecf20Sopenharmony_ci pll_data->clkod_shift = CLKOD_SHIFT; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci /* 1788c2ecf20Sopenharmony_ci * Check if there is an post-divider register. If not 1798c2ecf20Sopenharmony_ci * assume od bits are part of control register. 1808c2ecf20Sopenharmony_ci */ 1818c2ecf20Sopenharmony_ci i = of_property_match_string(node, "reg-names", 1828c2ecf20Sopenharmony_ci "post-divider"); 1838c2ecf20Sopenharmony_ci pll_data->pllod = of_iomap(node, i); 1848c2ecf20Sopenharmony_ci } 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci i = of_property_match_string(node, "reg-names", "control"); 1878c2ecf20Sopenharmony_ci pll_data->pll_ctl0 = of_iomap(node, i); 1888c2ecf20Sopenharmony_ci if (!pll_data->pll_ctl0) { 1898c2ecf20Sopenharmony_ci pr_err("%s: ioremap failed\n", __func__); 1908c2ecf20Sopenharmony_ci iounmap(pll_data->pllod); 1918c2ecf20Sopenharmony_ci goto out; 1928c2ecf20Sopenharmony_ci } 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci pll_data->pllm_lower_mask = PLLM_LOW_MASK; 1958c2ecf20Sopenharmony_ci pll_data->pllm_upper_shift = PLLM_HIGH_SHIFT; 1968c2ecf20Sopenharmony_ci pll_data->plld_mask = PLLD_MASK; 1978c2ecf20Sopenharmony_ci pll_data->has_pllctrl = pllctrl; 1988c2ecf20Sopenharmony_ci if (!pll_data->has_pllctrl) { 1998c2ecf20Sopenharmony_ci pll_data->pllm_upper_mask = PLLM_HIGH_MASK; 2008c2ecf20Sopenharmony_ci } else { 2018c2ecf20Sopenharmony_ci pll_data->pllm_upper_mask = MAIN_PLLM_HIGH_MASK; 2028c2ecf20Sopenharmony_ci i = of_property_match_string(node, "reg-names", "multiplier"); 2038c2ecf20Sopenharmony_ci pll_data->pllm = of_iomap(node, i); 2048c2ecf20Sopenharmony_ci if (!pll_data->pllm) { 2058c2ecf20Sopenharmony_ci iounmap(pll_data->pll_ctl0); 2068c2ecf20Sopenharmony_ci iounmap(pll_data->pllod); 2078c2ecf20Sopenharmony_ci goto out; 2088c2ecf20Sopenharmony_ci } 2098c2ecf20Sopenharmony_ci } 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci clk = clk_register_pll(NULL, node->name, parent_name, pll_data); 2128c2ecf20Sopenharmony_ci if (!IS_ERR_OR_NULL(clk)) { 2138c2ecf20Sopenharmony_ci of_clk_add_provider(node, of_clk_src_simple_get, clk); 2148c2ecf20Sopenharmony_ci return; 2158c2ecf20Sopenharmony_ci } 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ciout: 2188c2ecf20Sopenharmony_ci pr_err("%s: error initializing pll %pOFn\n", __func__, node); 2198c2ecf20Sopenharmony_ci kfree(pll_data); 2208c2ecf20Sopenharmony_ci} 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci/** 2238c2ecf20Sopenharmony_ci * of_keystone_pll_clk_init - PLL initialisation DT wrapper 2248c2ecf20Sopenharmony_ci * @node: device tree node for this clock 2258c2ecf20Sopenharmony_ci */ 2268c2ecf20Sopenharmony_cistatic void __init of_keystone_pll_clk_init(struct device_node *node) 2278c2ecf20Sopenharmony_ci{ 2288c2ecf20Sopenharmony_ci _of_pll_clk_init(node, false); 2298c2ecf20Sopenharmony_ci} 2308c2ecf20Sopenharmony_ciCLK_OF_DECLARE(keystone_pll_clock, "ti,keystone,pll-clock", 2318c2ecf20Sopenharmony_ci of_keystone_pll_clk_init); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci/** 2348c2ecf20Sopenharmony_ci * of_keystone_main_pll_clk_init - Main PLL initialisation DT wrapper 2358c2ecf20Sopenharmony_ci * @node: device tree node for this clock 2368c2ecf20Sopenharmony_ci */ 2378c2ecf20Sopenharmony_cistatic void __init of_keystone_main_pll_clk_init(struct device_node *node) 2388c2ecf20Sopenharmony_ci{ 2398c2ecf20Sopenharmony_ci _of_pll_clk_init(node, true); 2408c2ecf20Sopenharmony_ci} 2418c2ecf20Sopenharmony_ciCLK_OF_DECLARE(keystone_main_pll_clock, "ti,keystone,main-pll-clock", 2428c2ecf20Sopenharmony_ci of_keystone_main_pll_clk_init); 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci/** 2458c2ecf20Sopenharmony_ci * of_pll_div_clk_init - PLL divider setup function 2468c2ecf20Sopenharmony_ci * @node: device tree node for this clock 2478c2ecf20Sopenharmony_ci */ 2488c2ecf20Sopenharmony_cistatic void __init of_pll_div_clk_init(struct device_node *node) 2498c2ecf20Sopenharmony_ci{ 2508c2ecf20Sopenharmony_ci const char *parent_name; 2518c2ecf20Sopenharmony_ci void __iomem *reg; 2528c2ecf20Sopenharmony_ci u32 shift, mask; 2538c2ecf20Sopenharmony_ci struct clk *clk; 2548c2ecf20Sopenharmony_ci const char *clk_name = node->name; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci of_property_read_string(node, "clock-output-names", &clk_name); 2578c2ecf20Sopenharmony_ci reg = of_iomap(node, 0); 2588c2ecf20Sopenharmony_ci if (!reg) { 2598c2ecf20Sopenharmony_ci pr_err("%s: ioremap failed\n", __func__); 2608c2ecf20Sopenharmony_ci return; 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci parent_name = of_clk_get_parent_name(node, 0); 2648c2ecf20Sopenharmony_ci if (!parent_name) { 2658c2ecf20Sopenharmony_ci pr_err("%s: missing parent clock\n", __func__); 2668c2ecf20Sopenharmony_ci iounmap(reg); 2678c2ecf20Sopenharmony_ci return; 2688c2ecf20Sopenharmony_ci } 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci if (of_property_read_u32(node, "bit-shift", &shift)) { 2718c2ecf20Sopenharmony_ci pr_err("%s: missing 'shift' property\n", __func__); 2728c2ecf20Sopenharmony_ci iounmap(reg); 2738c2ecf20Sopenharmony_ci return; 2748c2ecf20Sopenharmony_ci } 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci if (of_property_read_u32(node, "bit-mask", &mask)) { 2778c2ecf20Sopenharmony_ci pr_err("%s: missing 'bit-mask' property\n", __func__); 2788c2ecf20Sopenharmony_ci iounmap(reg); 2798c2ecf20Sopenharmony_ci return; 2808c2ecf20Sopenharmony_ci } 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci clk = clk_register_divider(NULL, clk_name, parent_name, 0, reg, shift, 2838c2ecf20Sopenharmony_ci mask, 0, NULL); 2848c2ecf20Sopenharmony_ci if (IS_ERR(clk)) { 2858c2ecf20Sopenharmony_ci pr_err("%s: error registering divider %s\n", __func__, clk_name); 2868c2ecf20Sopenharmony_ci iounmap(reg); 2878c2ecf20Sopenharmony_ci return; 2888c2ecf20Sopenharmony_ci } 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci of_clk_add_provider(node, of_clk_src_simple_get, clk); 2918c2ecf20Sopenharmony_ci} 2928c2ecf20Sopenharmony_ciCLK_OF_DECLARE(pll_divider_clock, "ti,keystone,pll-divider-clock", of_pll_div_clk_init); 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci/** 2958c2ecf20Sopenharmony_ci * of_pll_mux_clk_init - PLL mux setup function 2968c2ecf20Sopenharmony_ci * @node: device tree node for this clock 2978c2ecf20Sopenharmony_ci */ 2988c2ecf20Sopenharmony_cistatic void __init of_pll_mux_clk_init(struct device_node *node) 2998c2ecf20Sopenharmony_ci{ 3008c2ecf20Sopenharmony_ci void __iomem *reg; 3018c2ecf20Sopenharmony_ci u32 shift, mask; 3028c2ecf20Sopenharmony_ci struct clk *clk; 3038c2ecf20Sopenharmony_ci const char *parents[2]; 3048c2ecf20Sopenharmony_ci const char *clk_name = node->name; 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci of_property_read_string(node, "clock-output-names", &clk_name); 3078c2ecf20Sopenharmony_ci reg = of_iomap(node, 0); 3088c2ecf20Sopenharmony_ci if (!reg) { 3098c2ecf20Sopenharmony_ci pr_err("%s: ioremap failed\n", __func__); 3108c2ecf20Sopenharmony_ci return; 3118c2ecf20Sopenharmony_ci } 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci of_clk_parent_fill(node, parents, 2); 3148c2ecf20Sopenharmony_ci if (!parents[0] || !parents[1]) { 3158c2ecf20Sopenharmony_ci pr_err("%s: missing parent clocks\n", __func__); 3168c2ecf20Sopenharmony_ci return; 3178c2ecf20Sopenharmony_ci } 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci if (of_property_read_u32(node, "bit-shift", &shift)) { 3208c2ecf20Sopenharmony_ci pr_err("%s: missing 'shift' property\n", __func__); 3218c2ecf20Sopenharmony_ci return; 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci if (of_property_read_u32(node, "bit-mask", &mask)) { 3258c2ecf20Sopenharmony_ci pr_err("%s: missing 'bit-mask' property\n", __func__); 3268c2ecf20Sopenharmony_ci return; 3278c2ecf20Sopenharmony_ci } 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci clk = clk_register_mux(NULL, clk_name, (const char **)&parents, 3308c2ecf20Sopenharmony_ci ARRAY_SIZE(parents) , 0, reg, shift, mask, 3318c2ecf20Sopenharmony_ci 0, NULL); 3328c2ecf20Sopenharmony_ci if (IS_ERR(clk)) { 3338c2ecf20Sopenharmony_ci pr_err("%s: error registering mux %s\n", __func__, clk_name); 3348c2ecf20Sopenharmony_ci return; 3358c2ecf20Sopenharmony_ci } 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci of_clk_add_provider(node, of_clk_src_simple_get, clk); 3388c2ecf20Sopenharmony_ci} 3398c2ecf20Sopenharmony_ciCLK_OF_DECLARE(pll_mux_clock, "ti,keystone,pll-mux-clock", of_pll_mux_clk_init); 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 3428c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("PLL clock driver for Keystone devices"); 3438c2ecf20Sopenharmony_ciMODULE_AUTHOR("Murali Karicheri <m-karicheri2@ti.com>"); 3448c2ecf20Sopenharmony_ciMODULE_AUTHOR("Santosh Shilimkar <santosh.shilimkar@ti.com>"); 345