1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#ifndef NPCM7XX_CLK_H
17#define NPCM7XX_CLK_H
18
19#include "exec/memory.h"
20#include "hw/clock.h"
21#include "hw/sysbus.h"
22
23
24
25
26
27#define NPCM7XX_CLK_NR_REGS (0x70 / sizeof(uint32_t))
28
29#define NPCM7XX_WATCHDOG_RESET_GPIO_IN "npcm7xx-clk-watchdog-reset-gpio-in"
30
31
32#define NPCM7XX_CLK_SEL_MAX_INPUT 5
33
34
35typedef enum NPCM7xxClockPLL {
36 NPCM7XX_CLOCK_PLL0,
37 NPCM7XX_CLOCK_PLL1,
38 NPCM7XX_CLOCK_PLL2,
39 NPCM7XX_CLOCK_PLLG,
40 NPCM7XX_CLOCK_NR_PLLS,
41} NPCM7xxClockPLL;
42
43
44typedef enum NPCM7xxClockSEL {
45 NPCM7XX_CLOCK_PIXCKSEL,
46 NPCM7XX_CLOCK_MCCKSEL,
47 NPCM7XX_CLOCK_CPUCKSEL,
48 NPCM7XX_CLOCK_CLKOUTSEL,
49 NPCM7XX_CLOCK_UARTCKSEL,
50 NPCM7XX_CLOCK_TIMCKSEL,
51 NPCM7XX_CLOCK_SDCKSEL,
52 NPCM7XX_CLOCK_GFXMSEL,
53 NPCM7XX_CLOCK_SUCKSEL,
54 NPCM7XX_CLOCK_NR_SELS,
55} NPCM7xxClockSEL;
56
57
58typedef enum NPCM7xxClockDivider {
59 NPCM7XX_CLOCK_PLL1D2,
60 NPCM7XX_CLOCK_PLL2D2,
61 NPCM7XX_CLOCK_MC_DIVIDER,
62 NPCM7XX_CLOCK_AXI_DIVIDER,
63 NPCM7XX_CLOCK_AHB_DIVIDER,
64 NPCM7XX_CLOCK_AHB3_DIVIDER,
65 NPCM7XX_CLOCK_SPI0_DIVIDER,
66 NPCM7XX_CLOCK_SPIX_DIVIDER,
67 NPCM7XX_CLOCK_APB1_DIVIDER,
68 NPCM7XX_CLOCK_APB2_DIVIDER,
69 NPCM7XX_CLOCK_APB3_DIVIDER,
70 NPCM7XX_CLOCK_APB4_DIVIDER,
71 NPCM7XX_CLOCK_APB5_DIVIDER,
72 NPCM7XX_CLOCK_CLKOUT_DIVIDER,
73 NPCM7XX_CLOCK_UART_DIVIDER,
74 NPCM7XX_CLOCK_TIMER_DIVIDER,
75 NPCM7XX_CLOCK_ADC_DIVIDER,
76 NPCM7XX_CLOCK_MMC_DIVIDER,
77 NPCM7XX_CLOCK_SDHC_DIVIDER,
78 NPCM7XX_CLOCK_GFXM_DIVIDER,
79 NPCM7XX_CLOCK_UTMI_DIVIDER,
80 NPCM7XX_CLOCK_NR_DIVIDERS,
81} NPCM7xxClockConverter;
82
83typedef struct NPCM7xxCLKState NPCM7xxCLKState;
84
85
86
87
88
89
90
91
92
93typedef struct NPCM7xxClockPLLState {
94 DeviceState parent;
95
96 const char *name;
97 NPCM7xxCLKState *clk;
98 Clock *clock_in;
99 Clock *clock_out;
100
101 int reg;
102} NPCM7xxClockPLLState;
103
104
105
106
107
108
109
110
111
112
113
114typedef struct NPCM7xxClockSELState {
115 DeviceState parent;
116
117 const char *name;
118 NPCM7xxCLKState *clk;
119 uint8_t input_size;
120 Clock *clock_in[NPCM7XX_CLK_SEL_MAX_INPUT];
121 Clock *clock_out;
122
123 int offset;
124 int len;
125} NPCM7xxClockSELState;
126
127
128
129
130
131
132
133
134
135
136
137
138
139typedef struct NPCM7xxClockDividerState {
140 DeviceState parent;
141
142 const char *name;
143 NPCM7xxCLKState *clk;
144 Clock *clock_in;
145 Clock *clock_out;
146
147 uint32_t (*divide)(struct NPCM7xxClockDividerState *s);
148 union {
149 struct {
150 int reg;
151 int offset;
152 int len;
153 };
154 int divisor;
155 };
156} NPCM7xxClockDividerState;
157
158struct NPCM7xxCLKState {
159 SysBusDevice parent;
160
161 MemoryRegion iomem;
162
163
164 NPCM7xxClockPLLState plls[NPCM7XX_CLOCK_NR_PLLS];
165 NPCM7xxClockSELState sels[NPCM7XX_CLOCK_NR_SELS];
166 NPCM7xxClockDividerState dividers[NPCM7XX_CLOCK_NR_DIVIDERS];
167
168 uint32_t regs[NPCM7XX_CLK_NR_REGS];
169
170
171 int64_t ref_ns;
172
173
174 Clock *clkref;
175};
176
177#define TYPE_NPCM7XX_CLK "npcm7xx-clk"
178OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxCLKState, NPCM7XX_CLK)
179
180#endif
181