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