1*b4cbe606SNobuhiro Iwamatsu // SPDX-License-Identifier: GPL-2.0-only
2*b4cbe606SNobuhiro Iwamatsu /*
3*b4cbe606SNobuhiro Iwamatsu  * Toshiba Visconti PLL controller
4*b4cbe606SNobuhiro Iwamatsu  *
5*b4cbe606SNobuhiro Iwamatsu  * Copyright (c) 2021 TOSHIBA CORPORATION
6*b4cbe606SNobuhiro Iwamatsu  * Copyright (c) 2021 Toshiba Electronic Devices & Storage Corporation
7*b4cbe606SNobuhiro Iwamatsu  *
8*b4cbe606SNobuhiro Iwamatsu  * Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
9*b4cbe606SNobuhiro Iwamatsu  */
10*b4cbe606SNobuhiro Iwamatsu 
11*b4cbe606SNobuhiro Iwamatsu #include <linux/clk-provider.h>
12*b4cbe606SNobuhiro Iwamatsu #include <linux/of_address.h>
13*b4cbe606SNobuhiro Iwamatsu #include <linux/slab.h>
14*b4cbe606SNobuhiro Iwamatsu 
15*b4cbe606SNobuhiro Iwamatsu #include <dt-bindings/clock/toshiba,tmpv770x.h>
16*b4cbe606SNobuhiro Iwamatsu 
17*b4cbe606SNobuhiro Iwamatsu #include "pll.h"
18*b4cbe606SNobuhiro Iwamatsu 
19*b4cbe606SNobuhiro Iwamatsu static DEFINE_SPINLOCK(tmpv770x_pll_lock);
20*b4cbe606SNobuhiro Iwamatsu 
21*b4cbe606SNobuhiro Iwamatsu static const struct visconti_pll_rate_table pipll0_rates[] __initconst = {
22*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(840000000, 0x1, 0x0, 0x1, 0x54, 0x000000, 0x2, 0x1),
23*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(780000000, 0x1, 0x0, 0x1, 0x4e, 0x000000, 0x2, 0x1),
24*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(600000000, 0x1, 0x0, 0x1, 0x3c, 0x000000, 0x2, 0x1),
25*b4cbe606SNobuhiro Iwamatsu 	{ /* sentinel */ },
26*b4cbe606SNobuhiro Iwamatsu };
27*b4cbe606SNobuhiro Iwamatsu 
28*b4cbe606SNobuhiro Iwamatsu static const struct visconti_pll_rate_table piddrcpll_rates[] __initconst = {
29*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(780000000, 0x1, 0x0, 0x1, 0x4e, 0x000000, 0x2, 0x1),
30*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(760000000, 0x1, 0x0, 0x1, 0x4c, 0x000000, 0x2, 0x1),
31*b4cbe606SNobuhiro Iwamatsu 	{ /* sentinel */ },
32*b4cbe606SNobuhiro Iwamatsu };
33*b4cbe606SNobuhiro Iwamatsu 
34*b4cbe606SNobuhiro Iwamatsu static const struct visconti_pll_rate_table pivoifpll_rates[] __initconst = {
35*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(165000000, 0x1, 0x0, 0x1, 0x42, 0x000000, 0x4, 0x2),
36*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(148500000, 0x1, 0x1, 0x1, 0x3b, 0x666666, 0x4, 0x2),
37*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(96000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x2),
38*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(74250000, 0x1, 0x1, 0x1, 0x3b, 0x666666, 0x4, 0x4),
39*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(54000000, 0x1, 0x0, 0x1, 0x36, 0x000000, 0x5, 0x4),
40*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(48000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x4),
41*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(35750000, 0x1, 0x1, 0x1, 0x32, 0x0ccccc, 0x7, 0x4),
42*b4cbe606SNobuhiro Iwamatsu 	{ /* sentinel */ },
43*b4cbe606SNobuhiro Iwamatsu };
44*b4cbe606SNobuhiro Iwamatsu 
45*b4cbe606SNobuhiro Iwamatsu static const struct visconti_pll_rate_table piimgerpll_rates[] __initconst = {
46*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(165000000, 0x1, 0x0, 0x1, 0x42, 0x000000, 0x4, 0x2),
47*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(96000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x2),
48*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(54000000, 0x1, 0x0, 0x1, 0x36, 0x000000, 0x5, 0x4),
49*b4cbe606SNobuhiro Iwamatsu 	VISCONTI_PLL_RATE(48000000, 0x1, 0x0, 0x1, 0x30, 0x000000, 0x5, 0x4),
50*b4cbe606SNobuhiro Iwamatsu 	{ /* sentinel */ },
51*b4cbe606SNobuhiro Iwamatsu };
52*b4cbe606SNobuhiro Iwamatsu 
53*b4cbe606SNobuhiro Iwamatsu static const struct visconti_pll_info pll_info[] __initconst = {
54*b4cbe606SNobuhiro Iwamatsu 	{ TMPV770X_PLL_PIPLL0, "pipll0", "osc2-clk", 0x0, pipll0_rates },
55*b4cbe606SNobuhiro Iwamatsu 	{ TMPV770X_PLL_PIDDRCPLL, "piddrcpll", "osc2-clk", 0x500, piddrcpll_rates },
56*b4cbe606SNobuhiro Iwamatsu 	{ TMPV770X_PLL_PIVOIFPLL, "pivoifpll", "osc2-clk", 0x600, pivoifpll_rates },
57*b4cbe606SNobuhiro Iwamatsu 	{ TMPV770X_PLL_PIIMGERPLL, "piimgerpll", "osc2-clk", 0x700, piimgerpll_rates },
58*b4cbe606SNobuhiro Iwamatsu };
59*b4cbe606SNobuhiro Iwamatsu 
tmpv770x_setup_plls(struct device_node * np)60*b4cbe606SNobuhiro Iwamatsu static void __init tmpv770x_setup_plls(struct device_node *np)
61*b4cbe606SNobuhiro Iwamatsu {
62*b4cbe606SNobuhiro Iwamatsu 	struct visconti_pll_provider *ctx;
63*b4cbe606SNobuhiro Iwamatsu 	void __iomem *reg_base;
64*b4cbe606SNobuhiro Iwamatsu 
65*b4cbe606SNobuhiro Iwamatsu 	reg_base = of_iomap(np, 0);
66*b4cbe606SNobuhiro Iwamatsu 	if (!reg_base)
67*b4cbe606SNobuhiro Iwamatsu 		return;
68*b4cbe606SNobuhiro Iwamatsu 
69*b4cbe606SNobuhiro Iwamatsu 	ctx = visconti_init_pll(np, reg_base, TMPV770X_NR_PLL);
70*b4cbe606SNobuhiro Iwamatsu 	if (IS_ERR(ctx)) {
71*b4cbe606SNobuhiro Iwamatsu 		iounmap(reg_base);
72*b4cbe606SNobuhiro Iwamatsu 		return;
73*b4cbe606SNobuhiro Iwamatsu 	}
74*b4cbe606SNobuhiro Iwamatsu 
75*b4cbe606SNobuhiro Iwamatsu 	ctx->clk_data.hws[TMPV770X_PLL_PIPLL1] =
76*b4cbe606SNobuhiro Iwamatsu 		clk_hw_register_fixed_rate(NULL, "pipll1", NULL, 0, 600000000);
77*b4cbe606SNobuhiro Iwamatsu 	ctx->clk_data.hws[TMPV770X_PLL_PIDNNPLL] =
78*b4cbe606SNobuhiro Iwamatsu 		clk_hw_register_fixed_rate(NULL, "pidnnpll", NULL, 0, 500000000);
79*b4cbe606SNobuhiro Iwamatsu 	ctx->clk_data.hws[TMPV770X_PLL_PIETHERPLL] =
80*b4cbe606SNobuhiro Iwamatsu 		clk_hw_register_fixed_rate(NULL, "pietherpll", NULL, 0, 500000000);
81*b4cbe606SNobuhiro Iwamatsu 
82*b4cbe606SNobuhiro Iwamatsu 	visconti_register_plls(ctx, pll_info, ARRAY_SIZE(pll_info), &tmpv770x_pll_lock);
83*b4cbe606SNobuhiro Iwamatsu }
84*b4cbe606SNobuhiro Iwamatsu 
85*b4cbe606SNobuhiro Iwamatsu CLK_OF_DECLARE(tmpv770x_plls, "toshiba,tmpv7708-pipllct", tmpv770x_setup_plls);
86