1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/clk.h> 3 #include <linux/err.h> 4 #include <linux/of.h> 5 #include <linux/slab.h> 6 #include <linux/spinlock.h> 7 #include "clk.h" 8 9 DEFINE_SPINLOCK(imx_ccm_lock); 10 11 void __init imx_check_clocks(struct clk *clks[], unsigned int count) 12 { 13 unsigned i; 14 15 for (i = 0; i < count; i++) 16 if (IS_ERR(clks[i])) 17 pr_err("i.MX clk %u: register failed with %ld\n", 18 i, PTR_ERR(clks[i])); 19 } 20 21 void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count) 22 { 23 unsigned int i; 24 25 for (i = 0; i < count; i++) 26 if (IS_ERR(clks[i])) 27 pr_err("i.MX clk %u: register failed with %ld\n", 28 i, PTR_ERR(clks[i])); 29 } 30 31 static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name) 32 { 33 struct of_phandle_args phandle; 34 struct clk *clk = ERR_PTR(-ENODEV); 35 char *path; 36 37 path = kasprintf(GFP_KERNEL, "/clocks/%s", name); 38 if (!path) 39 return ERR_PTR(-ENOMEM); 40 41 phandle.np = of_find_node_by_path(path); 42 kfree(path); 43 44 if (phandle.np) { 45 clk = of_clk_get_from_provider(&phandle); 46 of_node_put(phandle.np); 47 } 48 return clk; 49 } 50 51 struct clk * __init imx_obtain_fixed_clock( 52 const char *name, unsigned long rate) 53 { 54 struct clk *clk; 55 56 clk = imx_obtain_fixed_clock_from_dt(name); 57 if (IS_ERR(clk)) 58 clk = imx_clk_fixed(name, rate); 59 return clk; 60 } 61 62 struct clk_hw * __init imx_obtain_fixed_clk_hw(struct device_node *np, 63 const char *name) 64 { 65 struct clk *clk; 66 67 clk = of_clk_get_by_name(np, name); 68 if (IS_ERR(clk)) 69 return ERR_PTR(-ENOENT); 70 71 return __clk_get_hw(clk); 72 } 73 74 /* 75 * This fixups the register CCM_CSCMR1 write value. 76 * The write/read/divider values of the aclk_podf field 77 * of that register have the relationship described by 78 * the following table: 79 * 80 * write value read value divider 81 * 3b'000 3b'110 7 82 * 3b'001 3b'111 8 83 * 3b'010 3b'100 5 84 * 3b'011 3b'101 6 85 * 3b'100 3b'010 3 86 * 3b'101 3b'011 4 87 * 3b'110 3b'000 1 88 * 3b'111 3b'001 2(default) 89 * 90 * That's why we do the xor operation below. 91 */ 92 #define CSCMR1_FIXUP 0x00600000 93 94 void imx_cscmr1_fixup(u32 *val) 95 { 96 *val ^= CSCMR1_FIXUP; 97 return; 98 } 99 100 static int imx_keep_uart_clocks __initdata; 101 static struct clk ** const *imx_uart_clocks __initdata; 102 103 static int __init imx_keep_uart_clocks_param(char *str) 104 { 105 imx_keep_uart_clocks = 1; 106 107 return 0; 108 } 109 __setup_param("earlycon", imx_keep_uart_earlycon, 110 imx_keep_uart_clocks_param, 0); 111 __setup_param("earlyprintk", imx_keep_uart_earlyprintk, 112 imx_keep_uart_clocks_param, 0); 113 114 void __init imx_register_uart_clocks(struct clk ** const clks[]) 115 { 116 if (imx_keep_uart_clocks) { 117 int i; 118 119 imx_uart_clocks = clks; 120 for (i = 0; imx_uart_clocks[i]; i++) 121 clk_prepare_enable(*imx_uart_clocks[i]); 122 } 123 } 124 125 static int __init imx_clk_disable_uart(void) 126 { 127 if (imx_keep_uart_clocks && imx_uart_clocks) { 128 int i; 129 130 for (i = 0; imx_uart_clocks[i]; i++) 131 clk_disable_unprepare(*imx_uart_clocks[i]); 132 } 133 134 return 0; 135 } 136 late_initcall_sync(imx_clk_disable_uart); 137