1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2019 Western Digital Corporation or its affiliates.
4  *
5  * Copyright (C) 2018 SiFive, Inc.
6  * Wesley Terpstra
7  * Paul Walmsley
8  * Zong Li
9  * Pragnesh Patel
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * References:
21  * - SiFive FU540-C000 manual v1p0, Chapter 7 "Clocking and Reset"
22  */
23 
24 #include <dt-bindings/clock/sifive-fu540-prci.h>
25 
26 #include "sifive-prci.h"
27 
28 /* PRCI integration data for each WRPLL instance */
29 static struct __prci_wrpll_data __prci_corepll_data = {
30 	.cfg0_offs = PRCI_COREPLLCFG0_OFFSET,
31 	.cfg1_offs = PRCI_COREPLLCFG1_OFFSET,
32 	.enable_bypass = sifive_prci_coreclksel_use_hfclk,
33 	.disable_bypass = sifive_prci_coreclksel_use_corepll,
34 };
35 
36 static struct __prci_wrpll_data __prci_ddrpll_data = {
37 	.cfg0_offs = PRCI_DDRPLLCFG0_OFFSET,
38 	.cfg1_offs = PRCI_DDRPLLCFG1_OFFSET,
39 	.release_reset = sifive_prci_ddr_release_reset,
40 };
41 
42 static struct __prci_wrpll_data __prci_gemgxlpll_data = {
43 	.cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET,
44 	.cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET,
45 	.release_reset = sifive_prci_ethernet_release_reset,
46 };
47 
48 /* Linux clock framework integration */
49 static const struct __prci_clock_ops sifive_fu540_prci_wrpll_clk_ops = {
50 	.set_rate = sifive_prci_wrpll_set_rate,
51 	.round_rate = sifive_prci_wrpll_round_rate,
52 	.recalc_rate = sifive_prci_wrpll_recalc_rate,
53 	.enable_clk = sifive_prci_clock_enable,
54 };
55 
56 static const struct __prci_clock_ops sifive_fu540_prci_tlclksel_clk_ops = {
57 	.recalc_rate = sifive_prci_tlclksel_recalc_rate,
58 };
59 
60 /* List of clock controls provided by the PRCI */
61 struct __prci_clock __prci_init_clocks_fu540[] = {
62 	[PRCI_CLK_COREPLL] = {
63 		.name = "corepll",
64 		.parent_name = "hfclk",
65 		.ops = &sifive_fu540_prci_wrpll_clk_ops,
66 		.pwd = &__prci_corepll_data,
67 	},
68 	[PRCI_CLK_DDRPLL] = {
69 		.name = "ddrpll",
70 		.parent_name = "hfclk",
71 		.ops = &sifive_fu540_prci_wrpll_clk_ops,
72 		.pwd = &__prci_ddrpll_data,
73 	},
74 	[PRCI_CLK_GEMGXLPLL] = {
75 		.name = "gemgxlpll",
76 		.parent_name = "hfclk",
77 		.ops = &sifive_fu540_prci_wrpll_clk_ops,
78 		.pwd = &__prci_gemgxlpll_data,
79 	},
80 	[PRCI_CLK_TLCLK] = {
81 		.name = "tlclk",
82 		.parent_name = "corepll",
83 		.ops = &sifive_fu540_prci_tlclksel_clk_ops,
84 	},
85 };
86