Skip to content

Commit dede211

Browse files
committed
Merge tag 'clk-imx-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux into clk-imx
Pull i.MX clk driver updates from Abel Vesa: - Free the imx_uart_clocks even if imx_register_uart_clocks returns early - Get the stdout clocks count from device tree - Drop the clock count argument from imx_register_uart_clocks. - Keep the uart clocks on i.MX93 for when earlycon is used - Fix SPDX comment in i.MX6SLL clocks bindings header - Drop some unnecessary spaces from i.MX8ULP clocks bindings header - Add a new clk-gpr-mux clock type and use it on i.MX6Q to add ENET ref clocks - Add the imx_obtain_fixed_of_clock for allowing to add a clock that is not configured via devicetree - Fix the ENET1 gate configuration for i.MX6UL according to the reference manual - Add ENET refclock mux support for i.MX6UL * tag 'clk-imx-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux: clk: imx6ul: add ethernet refclock mux support clk: imx6ul: fix enet1 gate configuration clk: imx: add imx_obtain_fixed_of_clock() clk: imx6q: add ethernet refclock mux support clk: imx: add clk-gpr-mux driver dt-bindings: imx8ulp: clock: no spaces before tabs clk: imx6sll: add proper spdx license identifier clk: imx: imx93: invoke imx_register_uart_clocks clk: imx: remove clk_count of imx_register_uart_clocks clk: imx: get stdout clk count from device tree clk: imx: avoid memory leak
2 parents 1b929c0 + 4e197ee commit dede211

26 files changed

+235
-35
lines changed

drivers/clk/imx/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ mxc-clk-objs += clk-pllv3.o
2222
mxc-clk-objs += clk-pllv4.o
2323
mxc-clk-objs += clk-pll14xx.o
2424
mxc-clk-objs += clk-sscg-pll.o
25+
mxc-clk-objs += clk-gpr-mux.o
2526
obj-$(CONFIG_MXC_CLK) += mxc-clk.o
2627

2728
obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o

drivers/clk/imx/clk-gpr-mux.c

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
*/
4+
5+
#define pr_fmt(fmt) "imx:clk-gpr-mux: " fmt
6+
7+
#include <linux/module.h>
8+
9+
#include <linux/clk-provider.h>
10+
#include <linux/errno.h>
11+
#include <linux/export.h>
12+
#include <linux/io.h>
13+
#include <linux/slab.h>
14+
#include <linux/regmap.h>
15+
#include <linux/mfd/syscon.h>
16+
17+
#include "clk.h"
18+
19+
struct imx_clk_gpr {
20+
struct clk_hw hw;
21+
struct regmap *regmap;
22+
u32 mask;
23+
u32 reg;
24+
const u32 *mux_table;
25+
};
26+
27+
static struct imx_clk_gpr *to_imx_clk_gpr(struct clk_hw *hw)
28+
{
29+
return container_of(hw, struct imx_clk_gpr, hw);
30+
}
31+
32+
static u8 imx_clk_gpr_mux_get_parent(struct clk_hw *hw)
33+
{
34+
struct imx_clk_gpr *priv = to_imx_clk_gpr(hw);
35+
unsigned int val;
36+
int ret;
37+
38+
ret = regmap_read(priv->regmap, priv->reg, &val);
39+
if (ret)
40+
goto get_parent_err;
41+
42+
val &= priv->mask;
43+
44+
ret = clk_mux_val_to_index(hw, priv->mux_table, 0, val);
45+
if (ret < 0)
46+
goto get_parent_err;
47+
48+
return ret;
49+
50+
get_parent_err:
51+
pr_err("failed to get parent (%pe)\n", ERR_PTR(ret));
52+
53+
/* return some realistic non negative value. Potentially we could
54+
* give index to some dummy error parent.
55+
*/
56+
return 0;
57+
}
58+
59+
static int imx_clk_gpr_mux_set_parent(struct clk_hw *hw, u8 index)
60+
{
61+
struct imx_clk_gpr *priv = to_imx_clk_gpr(hw);
62+
unsigned int val = clk_mux_index_to_val(priv->mux_table, 0, index);
63+
64+
return regmap_update_bits(priv->regmap, priv->reg, priv->mask, val);
65+
}
66+
67+
static int imx_clk_gpr_mux_determine_rate(struct clk_hw *hw,
68+
struct clk_rate_request *req)
69+
{
70+
return clk_mux_determine_rate_flags(hw, req, 0);
71+
}
72+
73+
const struct clk_ops imx_clk_gpr_mux_ops = {
74+
.get_parent = imx_clk_gpr_mux_get_parent,
75+
.set_parent = imx_clk_gpr_mux_set_parent,
76+
.determine_rate = imx_clk_gpr_mux_determine_rate,
77+
};
78+
79+
struct clk_hw *imx_clk_gpr_mux(const char *name, const char *compatible,
80+
u32 reg, const char **parent_names,
81+
u8 num_parents, const u32 *mux_table, u32 mask)
82+
{
83+
struct clk_init_data init = { };
84+
struct imx_clk_gpr *priv;
85+
struct regmap *regmap;
86+
struct clk_hw *hw;
87+
int ret;
88+
89+
regmap = syscon_regmap_lookup_by_compatible(compatible);
90+
if (IS_ERR(regmap)) {
91+
pr_err("failed to find %s regmap\n", compatible);
92+
return ERR_CAST(regmap);
93+
}
94+
95+
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
96+
if (!priv)
97+
return ERR_PTR(-ENOMEM);
98+
99+
init.name = name;
100+
init.ops = &imx_clk_gpr_mux_ops;
101+
init.parent_names = parent_names;
102+
init.num_parents = num_parents;
103+
init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
104+
105+
priv->hw.init = &init;
106+
priv->regmap = regmap;
107+
priv->mux_table = mux_table;
108+
priv->reg = reg;
109+
priv->mask = mask;
110+
111+
hw = &priv->hw;
112+
ret = clk_hw_register(NULL, &priv->hw);
113+
if (ret) {
114+
kfree(priv);
115+
hw = ERR_PTR(ret);
116+
}
117+
118+
return hw;
119+
}

drivers/clk/imx/clk-imx25.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ static int __init __mx25_clocks_init(void __iomem *ccm_base)
218218
*/
219219
clk_set_parent(clk[cko_sel], clk[ipg]);
220220

221-
imx_register_uart_clocks(6);
221+
imx_register_uart_clocks();
222222

223223
return 0;
224224
}

drivers/clk/imx/clk-imx27.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ static void __init _mx27_clocks_init(unsigned long fref)
165165

166166
clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]);
167167

168-
imx_register_uart_clocks(7);
168+
imx_register_uart_clocks();
169169

170170
imx_print_silicon_rev("i.MX27", mx27_revision());
171171
}

drivers/clk/imx/clk-imx35.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ static void __init _mx35_clocks_init(void)
235235
*/
236236
clk_prepare_enable(clk[scc_gate]);
237237

238-
imx_register_uart_clocks(4);
238+
imx_register_uart_clocks();
239239

240240
imx_print_silicon_rev("i.MX35", mx35_revision());
241241
}

drivers/clk/imx/clk-imx5.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ static void __init mx50_clocks_init(struct device_node *np)
358358
r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
359359
clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
360360

361-
imx_register_uart_clocks(5);
361+
imx_register_uart_clocks();
362362
}
363363
CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init);
364364

@@ -464,7 +464,7 @@ static void __init mx51_clocks_init(struct device_node *np)
464464
val |= 1 << 23;
465465
writel(val, MXC_CCM_CLPCR);
466466

467-
imx_register_uart_clocks(3);
467+
imx_register_uart_clocks();
468468
}
469469
CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init);
470470

@@ -609,6 +609,6 @@ static void __init mx53_clocks_init(struct device_node *np)
609609
r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
610610
clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
611611

612-
imx_register_uart_clocks(5);
612+
imx_register_uart_clocks();
613613
}
614614
CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init);

drivers/clk/imx/clk-imx6q.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/clk-provider.h>
1313
#include <linux/err.h>
1414
#include <linux/io.h>
15+
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
1516
#include <linux/of.h>
1617
#include <linux/of_address.h>
1718
#include <linux/of_irq.h>
@@ -115,6 +116,10 @@ static struct clk_div_table video_div_table[] = {
115116
{ /* sentinel */ }
116117
};
117118

119+
static const char * enet_ref_sels[] = { "enet_ref", "enet_ref_pad", };
120+
static const u32 enet_ref_sels_table[] = { IMX6Q_GPR1_ENET_CLK_SEL_ANATOP, IMX6Q_GPR1_ENET_CLK_SEL_PAD };
121+
static const u32 enet_ref_sels_table_mask = IMX6Q_GPR1_ENET_CLK_SEL_ANATOP;
122+
118123
static unsigned int share_count_esai;
119124
static unsigned int share_count_asrc;
120125
static unsigned int share_count_ssi1;
@@ -908,6 +913,12 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
908913
if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0)
909914
hws[IMX6QDL_CLK_GPT_3M] = hws[IMX6QDL_CLK_GPT_IPG_PER];
910915

916+
hws[IMX6QDL_CLK_ENET_REF_PAD] = imx6q_obtain_fixed_clk_hw(ccm_node, "enet_ref_pad", 0);
917+
918+
hws[IMX6QDL_CLK_ENET_REF_SEL] = imx_clk_gpr_mux("enet_ref_sel", "fsl,imx6q-iomuxc-gpr",
919+
IOMUXC_GPR1, enet_ref_sels, ARRAY_SIZE(enet_ref_sels),
920+
enet_ref_sels_table, enet_ref_sels_table_mask);
921+
911922
imx_check_clk_hws(hws, IMX6QDL_CLK_END);
912923

913924
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
@@ -974,6 +985,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
974985
hws[IMX6QDL_CLK_PLL3_USB_OTG]->clk);
975986
}
976987

977-
imx_register_uart_clocks(2);
988+
clk_set_parent(hws[IMX6QDL_CLK_ENET_REF_SEL]->clk, hws[IMX6QDL_CLK_ENET_REF]->clk);
989+
990+
imx_register_uart_clocks();
978991
}
979992
CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);

drivers/clk/imx/clk-imx6sl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,6 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
440440
clk_set_parent(hws[IMX6SL_CLK_LCDIF_AXI_SEL]->clk,
441441
hws[IMX6SL_CLK_PLL2_PFD2]->clk);
442442

443-
imx_register_uart_clocks(2);
443+
imx_register_uart_clocks();
444444
}
445445
CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);

drivers/clk/imx/clk-imx6sll.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node)
340340

341341
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
342342

343-
imx_register_uart_clocks(5);
343+
imx_register_uart_clocks();
344344

345345
/* Lower the AHB clock rate before changing the clock source. */
346346
clk_set_rate(hws[IMX6SLL_CLK_AHB]->clk, 99000000);

drivers/clk/imx/clk-imx6sx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,6 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
548548
clk_set_parent(hws[IMX6SX_CLK_QSPI1_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
549549
clk_set_parent(hws[IMX6SX_CLK_QSPI2_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
550550

551-
imx_register_uart_clocks(2);
551+
imx_register_uart_clocks();
552552
}
553553
CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);

0 commit comments

Comments
 (0)