xref: /linux/drivers/clk/ultrarisc/clk-dp1000.c (revision 502d45774af09f1c681c754c4b7cdfb5d7f72fd9)
1*3948a36bSJia Wang // SPDX-License-Identifier: GPL-2.0-only
2*3948a36bSJia Wang /*
3*3948a36bSJia Wang  * Copyright (C) 2026 UltraRISC Technology (Shanghai) Co., Ltd.
4*3948a36bSJia Wang  */
5*3948a36bSJia Wang 
6*3948a36bSJia Wang #include <linux/module.h>
7*3948a36bSJia Wang 
8*3948a36bSJia Wang #include <dt-bindings/clock/ultrarisc,dp1000-clk.h>
9*3948a36bSJia Wang 
10*3948a36bSJia Wang #include "clk-ultrarisc.h"
11*3948a36bSJia Wang 
12*3948a36bSJia Wang #define DP1000_PLL_CFG1_OFFSET		0x400
13*3948a36bSJia Wang #define DP1000_PLL_CFG2_OFFSET		0x404
14*3948a36bSJia Wang 
15*3948a36bSJia Wang #define DP1000_CCR_UART_OFFSET		0x220
16*3948a36bSJia Wang #define DP1000_CCR_I2C_OFFSET		0x224
17*3948a36bSJia Wang #define DP1000_CCR_GMAC_OFFSET		0x228
18*3948a36bSJia Wang #define DP1000_CCR_SPI_OFFSET		0x22c
19*3948a36bSJia Wang #define DP1000_PERI_CLKENA_OFFSET	0x270
20*3948a36bSJia Wang 
21*3948a36bSJia Wang #define DP1000_CCR_LOAD			BIT(16)
22*3948a36bSJia Wang 
23*3948a36bSJia Wang #define DP1000_PERI_MAX_RATE		62500000UL
24*3948a36bSJia Wang #define DP1000_CLK_NUM			21
25*3948a36bSJia Wang 
26*3948a36bSJia Wang static const struct ultrarisc_pll_layout dp1000_pll_layout = {
27*3948a36bSJia Wang 	.cfg1_offset = DP1000_PLL_CFG1_OFFSET,
28*3948a36bSJia Wang 	.cfg2_offset = DP1000_PLL_CFG2_OFFSET,
29*3948a36bSJia Wang 	.frac_mask = GENMASK(23, 0),
30*3948a36bSJia Wang 	.m_mask = GENMASK(23, 16),
31*3948a36bSJia Wang 	.n_mask = GENMASK(11, 6),
32*3948a36bSJia Wang 	.oddiv1_mask = GENMASK(1, 0),
33*3948a36bSJia Wang 	.oddiv2_mask = GENMASK(4, 3),
34*3948a36bSJia Wang };
35*3948a36bSJia Wang 
36*3948a36bSJia Wang static const struct ultrarisc_pll_desc dp1000_plls[] = {
37*3948a36bSJia Wang 	{
38*3948a36bSJia Wang 		.id = DP1000_CLK_SYSPLL,
39*3948a36bSJia Wang 		.name = "syspll_clk",
40*3948a36bSJia Wang 	},
41*3948a36bSJia Wang };
42*3948a36bSJia Wang 
43*3948a36bSJia Wang #define DP1000_FIXED_FACTOR(_id, _name, _parent, _mult, _div)	\
44*3948a36bSJia Wang 	{							\
45*3948a36bSJia Wang 		.id = (_id),					\
46*3948a36bSJia Wang 		.name = (_name),				\
47*3948a36bSJia Wang 		.parent_id = (_parent),				\
48*3948a36bSJia Wang 		.mult = (_mult),				\
49*3948a36bSJia Wang 		.div = (_div),					\
50*3948a36bSJia Wang 	}
51*3948a36bSJia Wang 
52*3948a36bSJia Wang #define DP1000_DIV(_id, _name, _offset, _parent, _max_rate)	\
53*3948a36bSJia Wang 	{							\
54*3948a36bSJia Wang 		.id = (_id),					\
55*3948a36bSJia Wang 		.name = (_name),				\
56*3948a36bSJia Wang 		.offset = (_offset),				\
57*3948a36bSJia Wang 		.parent_id = (_parent),				\
58*3948a36bSJia Wang 		.max_rate = (_max_rate),			\
59*3948a36bSJia Wang 		.load_mask = DP1000_CCR_LOAD,			\
60*3948a36bSJia Wang 		.div_shift = 8,					\
61*3948a36bSJia Wang 		.div_width = 4,					\
62*3948a36bSJia Wang 		.gate_bit = 0,					\
63*3948a36bSJia Wang 		.divider_flags = CLK_DIVIDER_ONE_BASED,		\
64*3948a36bSJia Wang 		.gate_flags = 0,				\
65*3948a36bSJia Wang 	}
66*3948a36bSJia Wang 
67*3948a36bSJia Wang #define DP1000_GATE(_id, _name, _parent, _bit)		\
68*3948a36bSJia Wang 	{							\
69*3948a36bSJia Wang 		.id = (_id),					\
70*3948a36bSJia Wang 		.name = (_name),				\
71*3948a36bSJia Wang 		.offset = DP1000_PERI_CLKENA_OFFSET,		\
72*3948a36bSJia Wang 		.parent_id = (_parent),				\
73*3948a36bSJia Wang 		.gate_bit = (_bit),				\
74*3948a36bSJia Wang 		.gate_flags = 0,				\
75*3948a36bSJia Wang 	}
76*3948a36bSJia Wang 
77*3948a36bSJia Wang static const struct ultrarisc_fixed_factor_desc dp1000_fixed_factor_clks[] = {
78*3948a36bSJia Wang 	DP1000_FIXED_FACTOR(DP1000_CLK_SYSPLL_DIV2, "syspll_div2_clk",
79*3948a36bSJia Wang 			    DP1000_CLK_SYSPLL, 1, 2),
80*3948a36bSJia Wang 	DP1000_FIXED_FACTOR(DP1000_CLK_SUBSYS, "subsys_clk",
81*3948a36bSJia Wang 			    DP1000_CLK_SYSPLL_DIV2, 1, 2),
82*3948a36bSJia Wang 	DP1000_FIXED_FACTOR(DP1000_CLK_PCIE_DBI, "pcie_dbi_clk",
83*3948a36bSJia Wang 			    DP1000_CLK_SYSPLL, 1, 10),
84*3948a36bSJia Wang 	DP1000_FIXED_FACTOR(DP1000_CLK_PCIEX4_CORE, "pciex4_core_clk",
85*3948a36bSJia Wang 			    DP1000_CLK_SYSPLL, 1, 2),
86*3948a36bSJia Wang 	DP1000_FIXED_FACTOR(DP1000_CLK_PCIEX16_CORE, "pciex16_core_clk",
87*3948a36bSJia Wang 			    DP1000_CLK_SYSPLL, 1, 1),
88*3948a36bSJia Wang 	DP1000_FIXED_FACTOR(DP1000_CLK_PCIE_AUX, "pcie_aux_clk",
89*3948a36bSJia Wang 			    DP1000_CLK_SYSPLL, 1, 40),
90*3948a36bSJia Wang };
91*3948a36bSJia Wang 
92*3948a36bSJia Wang static const struct ultrarisc_divider_desc dp1000_divider_clks[] = {
93*3948a36bSJia Wang 	DP1000_DIV(DP1000_CLK_GMAC, "gmac_clk", DP1000_CCR_GMAC_OFFSET,
94*3948a36bSJia Wang 		   DP1000_CLK_SYSPLL_DIV2, 0),
95*3948a36bSJia Wang 	DP1000_DIV(DP1000_CLK_UART_ROOT, "uart_root_clk",
96*3948a36bSJia Wang 		   DP1000_CCR_UART_OFFSET, DP1000_CLK_SUBSYS,
97*3948a36bSJia Wang 		   DP1000_PERI_MAX_RATE),
98*3948a36bSJia Wang 	DP1000_DIV(DP1000_CLK_I2C_ROOT, "i2c_root_clk",
99*3948a36bSJia Wang 		   DP1000_CCR_I2C_OFFSET, DP1000_CLK_SUBSYS,
100*3948a36bSJia Wang 		   DP1000_PERI_MAX_RATE),
101*3948a36bSJia Wang 	DP1000_DIV(DP1000_CLK_SPI_ROOT, "spi_root_clk",
102*3948a36bSJia Wang 		   DP1000_CCR_SPI_OFFSET, DP1000_CLK_SUBSYS,
103*3948a36bSJia Wang 		   DP1000_PERI_MAX_RATE),
104*3948a36bSJia Wang };
105*3948a36bSJia Wang 
106*3948a36bSJia Wang static const struct ultrarisc_gate_desc dp1000_gate_clks[] = {
107*3948a36bSJia Wang 	DP1000_GATE(DP1000_CLK_UART0, "uart0_clk", DP1000_CLK_UART_ROOT, 0),
108*3948a36bSJia Wang 	DP1000_GATE(DP1000_CLK_UART1, "uart1_clk", DP1000_CLK_UART_ROOT, 1),
109*3948a36bSJia Wang 	DP1000_GATE(DP1000_CLK_UART2, "uart2_clk", DP1000_CLK_UART_ROOT, 2),
110*3948a36bSJia Wang 	DP1000_GATE(DP1000_CLK_UART3, "uart3_clk", DP1000_CLK_UART_ROOT, 3),
111*3948a36bSJia Wang 	DP1000_GATE(DP1000_CLK_I2C0, "i2c0_clk", DP1000_CLK_I2C_ROOT, 4),
112*3948a36bSJia Wang 	DP1000_GATE(DP1000_CLK_I2C1, "i2c1_clk", DP1000_CLK_I2C_ROOT, 5),
113*3948a36bSJia Wang 	DP1000_GATE(DP1000_CLK_I2C2, "i2c2_clk", DP1000_CLK_I2C_ROOT, 6),
114*3948a36bSJia Wang 	DP1000_GATE(DP1000_CLK_I2C3, "i2c3_clk", DP1000_CLK_I2C_ROOT, 7),
115*3948a36bSJia Wang 	DP1000_GATE(DP1000_CLK_SPI0, "spi0_clk", DP1000_CLK_SPI_ROOT, 8),
116*3948a36bSJia Wang 	DP1000_GATE(DP1000_CLK_SPI1, "spi1_clk", DP1000_CLK_SPI_ROOT, 9),
117*3948a36bSJia Wang };
118*3948a36bSJia Wang 
119*3948a36bSJia Wang static const struct ultrarisc_clk_soc_data dp1000_clk_soc_data = {
120*3948a36bSJia Wang 	.num_clks = DP1000_CLK_NUM,
121*3948a36bSJia Wang 	.pll_layout = &dp1000_pll_layout,
122*3948a36bSJia Wang 	.plls = dp1000_plls,
123*3948a36bSJia Wang 	.num_plls = ARRAY_SIZE(dp1000_plls),
124*3948a36bSJia Wang 	.fixed_factors = dp1000_fixed_factor_clks,
125*3948a36bSJia Wang 	.num_fixed_factors = ARRAY_SIZE(dp1000_fixed_factor_clks),
126*3948a36bSJia Wang 	.dividers = dp1000_divider_clks,
127*3948a36bSJia Wang 	.num_dividers = ARRAY_SIZE(dp1000_divider_clks),
128*3948a36bSJia Wang 	.gates = dp1000_gate_clks,
129*3948a36bSJia Wang 	.num_gates = ARRAY_SIZE(dp1000_gate_clks),
130*3948a36bSJia Wang };
131*3948a36bSJia Wang 
dp1000_clk_probe(struct platform_device * pdev)132*3948a36bSJia Wang static int dp1000_clk_probe(struct platform_device *pdev)
133*3948a36bSJia Wang {
134*3948a36bSJia Wang 	return ultrarisc_clk_probe(pdev, &dp1000_clk_soc_data);
135*3948a36bSJia Wang }
136*3948a36bSJia Wang 
137*3948a36bSJia Wang static const struct of_device_id dp1000_clk_of_match[] = {
138*3948a36bSJia Wang 	{ .compatible = "ultrarisc,dp1000-clk" },
139*3948a36bSJia Wang 	{ }
140*3948a36bSJia Wang };
141*3948a36bSJia Wang MODULE_DEVICE_TABLE(of, dp1000_clk_of_match);
142*3948a36bSJia Wang 
143*3948a36bSJia Wang static struct platform_driver dp1000_clk_driver = {
144*3948a36bSJia Wang 	.probe = dp1000_clk_probe,
145*3948a36bSJia Wang 	.driver = {
146*3948a36bSJia Wang 		.name = "ultrarisc-dp1000-clk",
147*3948a36bSJia Wang 		.of_match_table = dp1000_clk_of_match,
148*3948a36bSJia Wang 	},
149*3948a36bSJia Wang };
150*3948a36bSJia Wang module_platform_driver(dp1000_clk_driver);
151*3948a36bSJia Wang 
152*3948a36bSJia Wang MODULE_IMPORT_NS("CLK_ULTRARISC");
153*3948a36bSJia Wang MODULE_DESCRIPTION("UltraRISC DP1000 clock controller");
154*3948a36bSJia Wang MODULE_LICENSE("GPL");
155