8 months ago | Paul Boddie | raw files shortlog changelog graph | Introduced various specialised control, divider and clock abstractions. | cpm-library-improvements |
pkg/devices/lib/cpm/include/cpm-common.h (file) pkg/devices/lib/cpm/src/common.cc (file) pkg/devices/lib/cpm/src/x1600.cc (file) |
1.1 --- a/pkg/devices/lib/cpm/include/cpm-common.h Sat Sep 16 17:56:49 2023 +0200 1.2 +++ b/pkg/devices/lib/cpm/include/cpm-common.h Sun Sep 17 18:41:41 2023 +0200 1.3 @@ -120,6 +120,8 @@ 1.4 1.5 1.6 1.7 +// Controllable clock source. 1.8 + 1.9 class Source 1.10 { 1.11 Mux _inputs; 1.12 @@ -159,11 +161,96 @@ 1.13 1.14 1.15 1.16 +// Common clock control. 1.17 + 1.18 +class Control_base 1.19 +{ 1.20 +public: 1.21 + virtual ~Control_base(); 1.22 + 1.23 + virtual void change_disable(Cpm_regs ®s); 1.24 + virtual void change_enable(Cpm_regs ®s); 1.25 + 1.26 + virtual void wait_busy(Cpm_regs ®s) = 0; 1.27 + virtual int have_clock(Cpm_regs ®s) = 0; 1.28 + virtual void start_clock(Cpm_regs ®s) = 0; 1.29 + virtual void stop_clock(Cpm_regs ®s) = 0; 1.30 +}; 1.31 + 1.32 + 1.33 + 1.34 +// Clock control. 1.35 + 1.36 +class Control : public Control_base 1.37 +{ 1.38 + Field _gate, _change_enable, _busy; 1.39 + 1.40 +public: 1.41 + explicit Control(Field gate, 1.42 + Field change_enable = Field::undefined, 1.43 + Field busy = Field::undefined) 1.44 + : _gate(gate), _change_enable(change_enable), _busy(busy) 1.45 + { 1.46 + } 1.47 + 1.48 + explicit Control() 1.49 + : _gate(Field::undefined), _change_enable(Field::undefined), 1.50 + _busy(Field::undefined) 1.51 + { 1.52 + } 1.53 + 1.54 + // Clock control. 1.55 + 1.56 + void change_disable(Cpm_regs ®s); 1.57 + void change_enable(Cpm_regs ®s); 1.58 + 1.59 + void wait_busy(Cpm_regs ®s); 1.60 + int have_clock(Cpm_regs ®s); 1.61 + void start_clock(Cpm_regs ®s); 1.62 + void stop_clock(Cpm_regs ®s); 1.63 + 1.64 + // Undefined control. 1.65 + 1.66 + static Control undefined; 1.67 +}; 1.68 + 1.69 + 1.70 + 1.71 +// PLL control. 1.72 + 1.73 +class Control_pll : public Control_base 1.74 +{ 1.75 + Field _enable, _stable, _bypass; 1.76 + 1.77 + // PLL_specific control. 1.78 + 1.79 + int have_pll(Cpm_regs ®s); 1.80 + int pll_enabled(Cpm_regs ®s); 1.81 + 1.82 +public: 1.83 + explicit Control_pll(Field enable, Field stable, Field bypass) 1.84 + : _enable(enable), _stable(stable), _bypass(bypass) 1.85 + { 1.86 + } 1.87 + 1.88 + // Clock control. 1.89 + 1.90 + int pll_bypassed(Cpm_regs ®s); 1.91 + 1.92 + void wait_busy(Cpm_regs ®s); 1.93 + int have_clock(Cpm_regs ®s); 1.94 + void start_clock(Cpm_regs ®s); 1.95 + void stop_clock(Cpm_regs ®s); 1.96 +}; 1.97 + 1.98 + 1.99 + 1.100 // Frequency transformation. 1.101 1.102 -class Transform 1.103 +class Divider_base 1.104 { 1.105 public: 1.106 + virtual ~Divider_base(); 1.107 1.108 // Output frequency. 1.109 1.110 @@ -172,7 +259,9 @@ 1.111 1.112 1.113 1.114 -class Divider : public Transform 1.115 +// Simple divider for regular clocks. 1.116 + 1.117 +class Divider : public Divider_base 1.118 { 1.119 Field _divider; 1.120 1.121 @@ -190,7 +279,7 @@ 1.122 // Clock divider. 1.123 1.124 uint32_t get_divider(Cpm_regs ®s); 1.125 - void set_divider(Cpm_regs ®s, uint32_t division); 1.126 + void set_divider(Cpm_regs ®s, uint32_t divider); 1.127 1.128 // Output frequency. 1.129 1.130 @@ -203,26 +292,28 @@ 1.131 1.132 1.133 1.134 -class Divider_pll : public Transform 1.135 +// Divider for PLLs. 1.136 + 1.137 +class Divider_pll : public Divider_base 1.138 { 1.139 - Field _multiplier, _input_division, _output_division0, _output_division1; 1.140 + Field _multiplier, _input_divider, _output_divider0, _output_divider1; 1.141 1.142 public: 1.143 - explicit Divider_pll(Field multiplier, Field input_division, 1.144 - Field output_division0, Field output_division1) 1.145 - : _multiplier(multiplier), _input_division(input_division), 1.146 - _output_division0(output_division0), _output_division1(output_division1) 1.147 + explicit Divider_pll(Field multiplier, Field input_divider, 1.148 + Field output_divider0, Field output_divider1) 1.149 + : _multiplier(multiplier), _input_divider(input_divider), 1.150 + _output_divider0(output_divider0), _output_divider1(output_divider1) 1.151 { 1.152 } 1.153 1.154 // General frequency modifiers. 1.155 1.156 - uint16_t get_multiplier(Cpm_regs ®s); 1.157 - void set_multiplier(Cpm_regs ®s, uint16_t multiplier); 1.158 - uint8_t get_input_division(Cpm_regs ®s); 1.159 - void set_input_division(Cpm_regs ®s, uint8_t divider); 1.160 - uint8_t get_output_division(Cpm_regs ®s); 1.161 - void set_output_division(Cpm_regs ®s, uint8_t divider); 1.162 + uint32_t get_multiplier(Cpm_regs ®s); 1.163 + void set_multiplier(Cpm_regs ®s, uint32_t multiplier); 1.164 + uint32_t get_input_divider(Cpm_regs ®s); 1.165 + void set_input_divider(Cpm_regs ®s, uint32_t divider); 1.166 + uint32_t get_output_divider(Cpm_regs ®s); 1.167 + void set_output_divider(Cpm_regs ®s, uint32_t divider); 1.168 1.169 // Output frequency. 1.170 1.171 @@ -230,8 +321,40 @@ 1.172 1.173 // Other operations. 1.174 1.175 - void set_pll_parameters(Cpm_regs ®s, uint16_t multiplier, 1.176 - uint8_t in_divider, uint8_t out_divider); 1.177 + void set_parameters(Cpm_regs ®s, uint32_t multiplier, 1.178 + uint32_t in_divider, uint32_t out_divider); 1.179 +}; 1.180 + 1.181 + 1.182 + 1.183 +// Divider for I2S clocks. 1.184 + 1.185 +class Divider_i2s : public Divider_base 1.186 +{ 1.187 + Field _multiplier, _divider_N, _divider_D; 1.188 + 1.189 +public: 1.190 + explicit Divider_i2s(Field multiplier, Field divider_N, 1.191 + Field divider_D) 1.192 + : _multiplier(multiplier), _divider_N(divider_N), 1.193 + _divider_D(divider_D) 1.194 + { 1.195 + } 1.196 + 1.197 + // General frequency modifiers. 1.198 + 1.199 + uint32_t get_multiplier(Cpm_regs ®s); 1.200 + uint32_t get_divider_N(Cpm_regs ®s); 1.201 + uint32_t get_divider_D(Cpm_regs ®s); 1.202 + 1.203 + // Output frequency. 1.204 + 1.205 + uint32_t get_frequency(Cpm_regs ®s, uint32_t source_frequency); 1.206 + 1.207 + // Other operations. 1.208 + 1.209 + void set_parameters(Cpm_regs ®s, uint32_t multiplier, 1.210 + uint32_t divider_N, uint32_t divider_D); 1.211 }; 1.212 1.213 1.214 @@ -240,13 +363,46 @@ 1.215 1.216 class Clock_base 1.217 { 1.218 - Source _source; 1.219 - 1.220 public: 1.221 - explicit Clock_base(Source source) 1.222 - : _source(source) 1.223 - { 1.224 - } 1.225 + virtual ~Clock_base(); 1.226 + 1.227 + // Clock control. 1.228 + 1.229 + virtual int have_clock(Cpm_regs ®s) = 0; 1.230 + virtual void start_clock(Cpm_regs ®s) = 0; 1.231 + virtual void stop_clock(Cpm_regs ®s) = 0; 1.232 + 1.233 + // Output frequency. 1.234 + 1.235 + virtual uint32_t get_frequency(Cpm_regs ®s) = 0; 1.236 +}; 1.237 + 1.238 + 1.239 + 1.240 +// Null (absent or undefined) clock abstraction. 1.241 + 1.242 +class Clock_null : public Clock_base 1.243 +{ 1.244 +public: 1.245 + 1.246 + // Clock control. 1.247 + 1.248 + int have_clock(Cpm_regs ®s); 1.249 + void start_clock(Cpm_regs ®s); 1.250 + void stop_clock(Cpm_regs ®s); 1.251 + 1.252 + // Output frequency. 1.253 + 1.254 + uint32_t get_frequency(Cpm_regs ®s); 1.255 +}; 1.256 + 1.257 + 1.258 + 1.259 +// Passive (root or input) clock without any source of its own. 1.260 + 1.261 +class Clock_passive : public Clock_base 1.262 +{ 1.263 +public: 1.264 1.265 // Clock control. 1.266 1.267 @@ -254,10 +410,40 @@ 1.268 virtual void start_clock(Cpm_regs ®s); 1.269 virtual void stop_clock(Cpm_regs ®s); 1.270 1.271 - // Clock divider. 1.272 + // Output frequency. 1.273 + 1.274 + uint32_t get_frequency(Cpm_regs ®s); 1.275 +}; 1.276 + 1.277 + 1.278 + 1.279 +// An actively managed clock with source. 1.280 + 1.281 +class Clock_active : public Clock_base 1.282 +{ 1.283 +protected: 1.284 + Source _source; 1.285 + 1.286 + virtual Control_base &_get_control() = 0; 1.287 1.288 - virtual uint32_t get_divider(Cpm_regs ®s); 1.289 - virtual void set_divider(Cpm_regs ®s, uint32_t division); 1.290 +public: 1.291 + explicit Clock_active(Source source) 1.292 + : _source(source) 1.293 + { 1.294 + } 1.295 + 1.296 + explicit Clock_active() 1.297 + : _source(Source::undefined) 1.298 + { 1.299 + } 1.300 + 1.301 + virtual ~Clock_active(); 1.302 + 1.303 + // Clock control. 1.304 + 1.305 + virtual int have_clock(Cpm_regs ®s); 1.306 + virtual void start_clock(Cpm_regs ®s); 1.307 + virtual void stop_clock(Cpm_regs ®s); 1.308 1.309 // Clock source. 1.310 1.311 @@ -275,98 +461,114 @@ 1.312 1.313 1.314 1.315 -// PLL descriptions. 1.316 +// Divided clock interface. 1.317 1.318 -class Pll : public Clock_base 1.319 +class Clock_divided : public Clock_active 1.320 { 1.321 - Field _enable, _stable, _bypass; 1.322 - Divider_pll _divider; 1.323 +protected: 1.324 + virtual Divider_base &_get_divider() = 0; 1.325 1.326 public: 1.327 - explicit Pll(Source source, 1.328 - Field enable, Field stable, Field bypass, 1.329 - Divider_pll divider) 1.330 - : Clock_base(source), 1.331 - _enable(enable), _stable(stable), _bypass(bypass), 1.332 - _divider(divider) 1.333 + explicit Clock_divided(Source source) 1.334 + : Clock_active(source) 1.335 { 1.336 } 1.337 1.338 - // PLL_specific control. 1.339 - 1.340 - int have_pll(Cpm_regs ®s); 1.341 - int pll_enabled(Cpm_regs ®s); 1.342 - int pll_bypassed(Cpm_regs ®s); 1.343 - 1.344 - // Clock control. 1.345 - 1.346 - int have_clock(Cpm_regs ®s); 1.347 - void start_clock(Cpm_regs ®s); 1.348 - void stop_clock(Cpm_regs ®s); 1.349 - 1.350 - // General frequency modifiers. 1.351 - 1.352 - uint16_t get_multiplier(Cpm_regs ®s); 1.353 - void set_multiplier(Cpm_regs ®s, uint16_t multiplier); 1.354 - uint8_t get_input_division(Cpm_regs ®s); 1.355 - void set_input_division(Cpm_regs ®s, uint8_t divider); 1.356 - uint8_t get_output_division(Cpm_regs ®s); 1.357 - void set_output_division(Cpm_regs ®s, uint8_t divider); 1.358 - 1.359 - // PLL output frequency. 1.360 - 1.361 - uint32_t get_frequency(Cpm_regs ®s); 1.362 - 1.363 - // Other operations. 1.364 - 1.365 - void set_pll_parameters(Cpm_regs ®s, uint16_t multiplier, 1.366 - uint8_t in_divider, uint8_t out_divider); 1.367 -}; 1.368 - 1.369 - 1.370 - 1.371 -// Clock descriptions. 1.372 - 1.373 -class Clock : public Clock_base 1.374 -{ 1.375 - Field _gate, _change_enable, _busy; 1.376 - Divider _divider; 1.377 - 1.378 - // Clock control. 1.379 - 1.380 - void change_disable(Cpm_regs ®s); 1.381 - void change_enable(Cpm_regs ®s); 1.382 - void wait_busy(Cpm_regs ®s); 1.383 - 1.384 -public: 1.385 - explicit Clock(Source source = Source::undefined, 1.386 - Field gate = Field::undefined, 1.387 - Field change_enable = Field::undefined, 1.388 - Field busy = Field::undefined, 1.389 - Divider divider = Divider::undefined) 1.390 - : Clock_base(source), 1.391 - _gate(gate), _change_enable(change_enable), _busy(busy), _divider(divider) 1.392 - { 1.393 - } 1.394 - 1.395 - // Clock control. 1.396 - 1.397 - int have_clock(Cpm_regs ®s); 1.398 - void start_clock(Cpm_regs ®s); 1.399 - void stop_clock(Cpm_regs ®s); 1.400 - 1.401 - // Clock divider. 1.402 - 1.403 - uint32_t get_divider(Cpm_regs ®s); 1.404 - void set_divider(Cpm_regs ®s, uint32_t division); 1.405 - 1.406 - // Clock source. 1.407 - 1.408 - void set_source(Cpm_regs ®s, uint8_t source); 1.409 + virtual ~Clock_divided(); 1.410 1.411 // Output frequency. 1.412 1.413 uint32_t get_frequency(Cpm_regs ®s); 1.414 }; 1.415 1.416 + 1.417 + 1.418 +// PLL description. 1.419 + 1.420 +class Pll : public Clock_divided 1.421 +{ 1.422 + // Value storage. 1.423 + 1.424 + Control_pll _control; 1.425 + Divider_pll _divider; 1.426 + 1.427 + virtual Control_base &_get_control() { return _control; } 1.428 + virtual Divider_base &_get_divider() { return _divider; } 1.429 + 1.430 +public: 1.431 + explicit Pll(Source source, Control_pll control, Divider_pll divider) 1.432 + : Clock_divided(source), _control(control), _divider(divider) 1.433 + { 1.434 + } 1.435 + 1.436 + virtual ~Pll(); 1.437 + 1.438 + // General frequency modifiers. 1.439 + 1.440 + uint32_t get_multiplier(Cpm_regs ®s); 1.441 + void set_multiplier(Cpm_regs ®s, uint32_t multiplier); 1.442 + uint32_t get_input_divider(Cpm_regs ®s); 1.443 + void set_input_divider(Cpm_regs ®s, uint32_t divider); 1.444 + uint32_t get_output_divider(Cpm_regs ®s); 1.445 + void set_output_divider(Cpm_regs ®s, uint32_t divider); 1.446 + 1.447 + // Output frequency. 1.448 + 1.449 + uint32_t get_frequency(Cpm_regs ®s); 1.450 + 1.451 + // Other operations. 1.452 + 1.453 + void set_parameters(Cpm_regs ®s, uint32_t multiplier, 1.454 + uint32_t in_divider, uint32_t out_divider); 1.455 +}; 1.456 + 1.457 + 1.458 + 1.459 +// Clock description. 1.460 + 1.461 +class Clock : public Clock_divided 1.462 +{ 1.463 + // Value storage. 1.464 + 1.465 + Control _control; 1.466 + Divider _divider; 1.467 + 1.468 + virtual Control_base &_get_control() { return _control; } 1.469 + virtual Divider_base &_get_divider() { return _divider; } 1.470 + 1.471 +public: 1.472 + explicit Clock(Source source, 1.473 + Control control = Control::undefined, 1.474 + Divider divider = Divider::undefined) 1.475 + : Clock_divided(source), _control(control), _divider(divider) 1.476 + { 1.477 + } 1.478 + 1.479 + // Clock divider. 1.480 + 1.481 + uint32_t get_divider(Cpm_regs ®s); 1.482 + void set_divider(Cpm_regs ®s, uint32_t divider); 1.483 +}; 1.484 + 1.485 + 1.486 + 1.487 +// I2S clock description. 1.488 + 1.489 +class Clock_divided_i2s : public Clock_divided 1.490 +{ 1.491 + // Value storage. 1.492 + 1.493 + Control _control; 1.494 + Divider_i2s _divider; 1.495 + 1.496 + virtual Control_base &_get_control() { return _control; } 1.497 + virtual Divider_base &_get_divider() { return _divider; } 1.498 + 1.499 +public: 1.500 + explicit Clock_divided_i2s(Source source, Control control, Divider_i2s divider) 1.501 + : Clock_divided(source), _control(control), _divider(divider) 1.502 + { 1.503 + } 1.504 +}; 1.505 + 1.506 #endif /* __cplusplus */
2.1 --- a/pkg/devices/lib/cpm/src/common.cc Sat Sep 16 17:56:49 2023 +0200 2.2 +++ b/pkg/devices/lib/cpm/src/common.cc Sun Sep 17 18:41:41 2023 +0200 2.3 @@ -117,14 +117,9 @@ 2.4 uint32_t 2.5 Source::get_frequency(Cpm_regs ®s) 2.6 { 2.7 - // Return the external clock frequency without any input clock. 2.8 - 2.9 - if (get_number() == 0) 2.10 - return regs.exclk_freq; 2.11 - 2.12 // Clocks with one source yield that input frequency. 2.13 2.14 - else if (get_number() == 1) 2.15 + if (get_number() == 1) 2.16 return regs.get_clock(get_input(0))->get_frequency(regs); 2.17 2.18 // With multiple sources, obtain the selected source for the clock. 2.19 @@ -146,8 +141,133 @@ 2.20 2.21 2.22 2.23 +// Clock control. 2.24 + 2.25 +Control_base::~Control_base() 2.26 +{ 2.27 +} 2.28 + 2.29 +void 2.30 +Control_base::change_disable(Cpm_regs ®s) 2.31 +{ 2.32 + (void) regs; 2.33 +} 2.34 + 2.35 +void 2.36 +Control_base::change_enable(Cpm_regs ®s) 2.37 +{ 2.38 + (void) regs; 2.39 +} 2.40 + 2.41 +int 2.42 +Control::have_clock(Cpm_regs ®s) 2.43 +{ 2.44 + if (_gate.is_defined()) 2.45 + return !_gate.get_field(regs); 2.46 + else 2.47 + return true; 2.48 +} 2.49 + 2.50 +void 2.51 +Control::start_clock(Cpm_regs ®s) 2.52 +{ 2.53 + if (_gate.is_defined()) 2.54 + _gate.set_field(regs, 0); 2.55 +} 2.56 + 2.57 +void 2.58 +Control::stop_clock(Cpm_regs ®s) 2.59 +{ 2.60 + if (_gate.is_defined()) 2.61 + _gate.set_field(regs, 1); 2.62 +} 2.63 + 2.64 +void 2.65 +Control::wait_busy(Cpm_regs ®s) 2.66 +{ 2.67 + if (_busy.is_defined()) 2.68 + while (_busy.get_field(regs)); 2.69 +} 2.70 + 2.71 +void 2.72 +Control::change_disable(Cpm_regs ®s) 2.73 +{ 2.74 + if (_change_enable.is_defined()) 2.75 + _change_enable.set_field(regs, 0); 2.76 +} 2.77 + 2.78 +void 2.79 +Control::change_enable(Cpm_regs ®s) 2.80 +{ 2.81 + if (_change_enable.is_defined()) 2.82 + _change_enable.set_field(regs, 1); 2.83 +} 2.84 + 2.85 +// Undefined control. 2.86 + 2.87 +Control Control::undefined; 2.88 + 2.89 + 2.90 + 2.91 +// PLL-specific control. 2.92 + 2.93 +int 2.94 +Control_pll::have_pll(Cpm_regs ®s) 2.95 +{ 2.96 + return _stable.get_field(regs); 2.97 +} 2.98 + 2.99 +int 2.100 +Control_pll::pll_enabled(Cpm_regs ®s) 2.101 +{ 2.102 + return _enable.get_field(regs); 2.103 +} 2.104 + 2.105 +int 2.106 +Control_pll::pll_bypassed(Cpm_regs ®s) 2.107 +{ 2.108 + return _bypass.get_field(regs); 2.109 +} 2.110 + 2.111 +// Clock control. 2.112 + 2.113 +int 2.114 +Control_pll::have_clock(Cpm_regs ®s) 2.115 +{ 2.116 + return have_pll(regs) && pll_enabled(regs); 2.117 +} 2.118 + 2.119 +void 2.120 +Control_pll::start_clock(Cpm_regs ®s) 2.121 +{ 2.122 + _enable.set_field(regs, 1); 2.123 + while (!have_pll(regs)); 2.124 +} 2.125 + 2.126 +void 2.127 +Control_pll::stop_clock(Cpm_regs ®s) 2.128 +{ 2.129 + _enable.set_field(regs, 0); 2.130 + while (have_pll(regs)); 2.131 +} 2.132 + 2.133 +void 2.134 +Control_pll::wait_busy(Cpm_regs ®s) 2.135 +{ 2.136 + if (pll_enabled(regs) && !pll_bypassed(regs)) 2.137 + while (!have_pll(regs)); 2.138 +} 2.139 + 2.140 + 2.141 + 2.142 // Clock dividers. 2.143 2.144 +Divider_base::~Divider_base() 2.145 +{ 2.146 +} 2.147 + 2.148 + 2.149 + 2.150 uint32_t 2.151 Divider::get_divider(Cpm_regs ®s) 2.152 { 2.153 @@ -158,10 +278,10 @@ 2.154 } 2.155 2.156 void 2.157 -Divider::set_divider(Cpm_regs ®s, uint32_t division) 2.158 +Divider::set_divider(Cpm_regs ®s, uint32_t divider) 2.159 { 2.160 if (_divider.is_defined()) 2.161 - _divider.set_field(regs, division - 1); 2.162 + _divider.set_field(regs, divider - 1); 2.163 } 2.164 2.165 // Output clock frequencies. 2.166 @@ -180,129 +300,235 @@ 2.167 2.168 // Feedback (13-bit) multiplier. 2.169 2.170 -uint16_t 2.171 +uint32_t 2.172 Divider_pll::get_multiplier(Cpm_regs ®s) 2.173 { 2.174 return _multiplier.get_field(regs) + 1; 2.175 } 2.176 2.177 void 2.178 -Divider_pll::set_multiplier(Cpm_regs ®s, uint16_t multiplier) 2.179 +Divider_pll::set_multiplier(Cpm_regs ®s, uint32_t multiplier) 2.180 { 2.181 _multiplier.set_field(regs, multiplier - 1); 2.182 } 2.183 2.184 // Input (6-bit) divider. 2.185 2.186 -uint8_t 2.187 -Divider_pll::get_input_division(Cpm_regs ®s) 2.188 +uint32_t 2.189 +Divider_pll::get_input_divider(Cpm_regs ®s) 2.190 { 2.191 - return _input_division.get_field(regs) + 1; 2.192 + return _input_divider.get_field(regs) + 1; 2.193 } 2.194 2.195 void 2.196 -Divider_pll::set_input_division(Cpm_regs ®s, uint8_t divider) 2.197 +Divider_pll::set_input_divider(Cpm_regs ®s, uint32_t divider) 2.198 { 2.199 - _input_division.set_field(regs, divider - 1); 2.200 + _input_divider.set_field(regs, divider - 1); 2.201 } 2.202 2.203 // Output (dual 3-bit) dividers. 2.204 2.205 -uint8_t 2.206 -Divider_pll::get_output_division(Cpm_regs ®s) 2.207 +uint32_t 2.208 +Divider_pll::get_output_divider(Cpm_regs ®s) 2.209 { 2.210 - uint8_t d0 = _output_division0.get_field(regs); 2.211 - uint8_t d1 = _output_division1.get_field(regs); 2.212 + uint32_t d0 = _output_divider0.get_field(regs); 2.213 + uint32_t d1 = _output_divider1.get_field(regs); 2.214 2.215 return d0 * d1; 2.216 } 2.217 2.218 void 2.219 -Divider_pll::set_output_division(Cpm_regs ®s, uint8_t divider) 2.220 +Divider_pll::set_output_divider(Cpm_regs ®s, uint32_t divider) 2.221 { 2.222 // Assert 1 as a minimum. 2.223 // Divider 0 must be less than or equal to divider 1. 2.224 2.225 - uint8_t d0 = (uint8_t) floor(sqrt(divider ? divider : 1)); 2.226 - uint8_t d1 = divider / d0; 2.227 + uint32_t d0 = (uint32_t) floor(sqrt(divider ? divider : 1)); 2.228 + uint32_t d1 = divider / d0; 2.229 2.230 - _output_division0.set_field(regs, d0); 2.231 - _output_division1.set_field(regs, d1); 2.232 + _output_divider0.set_field(regs, d0); 2.233 + _output_divider1.set_field(regs, d1); 2.234 } 2.235 2.236 uint32_t 2.237 Divider_pll::get_frequency(Cpm_regs ®s, uint32_t source_frequency) 2.238 { 2.239 return (source_frequency * get_multiplier(regs)) / 2.240 - (get_input_division(regs) * get_output_division(regs)); 2.241 + (get_input_divider(regs) * get_output_divider(regs)); 2.242 } 2.243 2.244 void 2.245 -Divider_pll::set_pll_parameters(Cpm_regs ®s, uint16_t multiplier, 2.246 - uint8_t in_divider, uint8_t out_divider) 2.247 +Divider_pll::set_parameters(Cpm_regs ®s, uint32_t multiplier, 2.248 + uint32_t in_divider, uint32_t out_divider) 2.249 { 2.250 set_multiplier(regs, multiplier); 2.251 - set_input_division(regs, in_divider); 2.252 - set_output_division(regs, out_divider); 2.253 + set_input_divider(regs, in_divider); 2.254 + set_output_divider(regs, out_divider); 2.255 } 2.256 2.257 2.258 2.259 -// Clock control. 2.260 +// I2S clock divider. 2.261 + 2.262 +uint32_t 2.263 +Divider_i2s::get_multiplier(Cpm_regs ®s) 2.264 +{ 2.265 + return _multiplier.get_field(regs); 2.266 +} 2.267 + 2.268 +uint32_t 2.269 +Divider_i2s::get_divider_D(Cpm_regs ®s) 2.270 +{ 2.271 + return _divider_D.get_field(regs); 2.272 +} 2.273 + 2.274 +uint32_t 2.275 +Divider_i2s::get_divider_N(Cpm_regs ®s) 2.276 +{ 2.277 + return _divider_N.get_field(regs); 2.278 +} 2.279 + 2.280 +uint32_t 2.281 +Divider_i2s::get_frequency(Cpm_regs ®s, uint32_t source_frequency) 2.282 +{ 2.283 + return (source_frequency * get_multiplier(regs)) / 2.284 + (get_divider_N(regs) * get_divider_D(regs)); 2.285 +} 2.286 + 2.287 +void 2.288 +Divider_i2s::set_parameters(Cpm_regs ®s, uint32_t multiplier, 2.289 + uint32_t divider_N, uint32_t divider_D) 2.290 +{ 2.291 + if (divider_N < 2 * multiplier) 2.292 + return; 2.293 + 2.294 + _multiplier.set_field(regs, multiplier); 2.295 + _divider_N.set_field(regs, divider_N); 2.296 + _divider_D.set_field(regs, divider_D); 2.297 +} 2.298 + 2.299 + 2.300 + 2.301 +// Clock interface. 2.302 + 2.303 +Clock_base::~Clock_base() 2.304 +{ 2.305 +} 2.306 + 2.307 + 2.308 + 2.309 +// Null clock. 2.310 2.311 int 2.312 -Clock_base::have_clock(Cpm_regs ®s) 2.313 +Clock_null::have_clock(Cpm_regs ®s) 2.314 +{ 2.315 + (void) regs; 2.316 + return false; 2.317 +} 2.318 + 2.319 +void 2.320 +Clock_null::start_clock(Cpm_regs ®s) 2.321 +{ 2.322 + (void) regs; 2.323 +} 2.324 + 2.325 +void 2.326 +Clock_null::stop_clock(Cpm_regs ®s) 2.327 +{ 2.328 + (void) regs; 2.329 +} 2.330 + 2.331 +// Output clock frequencies. 2.332 + 2.333 +uint32_t 2.334 +Clock_null::get_frequency(Cpm_regs ®s) 2.335 +{ 2.336 + (void) regs; 2.337 + return 0; 2.338 +} 2.339 + 2.340 + 2.341 + 2.342 +// Passive clock. 2.343 + 2.344 +int 2.345 +Clock_passive::have_clock(Cpm_regs ®s) 2.346 { 2.347 (void) regs; 2.348 return true; 2.349 } 2.350 2.351 void 2.352 -Clock_base::start_clock(Cpm_regs ®s) 2.353 +Clock_passive::start_clock(Cpm_regs ®s) 2.354 { 2.355 (void) regs; 2.356 } 2.357 2.358 void 2.359 -Clock_base::stop_clock(Cpm_regs ®s) 2.360 +Clock_passive::stop_clock(Cpm_regs ®s) 2.361 { 2.362 (void) regs; 2.363 } 2.364 2.365 -// Default divider. 2.366 +// Output clock frequencies. 2.367 2.368 uint32_t 2.369 -Clock_base::get_divider(Cpm_regs ®s) 2.370 +Clock_passive::get_frequency(Cpm_regs ®s) 2.371 { 2.372 - (void) regs; 2.373 - return 1; 2.374 + // NOTE: Return the external clock frequency. 2.375 + 2.376 + return regs.exclk_freq; 2.377 +} 2.378 + 2.379 + 2.380 + 2.381 +// Active clock interface. 2.382 + 2.383 +Clock_active::~Clock_active() 2.384 +{ 2.385 +} 2.386 + 2.387 +// Clock control. 2.388 + 2.389 +int 2.390 +Clock_active::have_clock(Cpm_regs ®s) 2.391 +{ 2.392 + return _get_control().have_clock(regs); 2.393 } 2.394 2.395 void 2.396 -Clock_base::set_divider(Cpm_regs ®s, uint32_t division) 2.397 +Clock_active::start_clock(Cpm_regs ®s) 2.398 { 2.399 - (void) regs; 2.400 - (void) division; 2.401 + _get_control().start_clock(regs); 2.402 +} 2.403 + 2.404 +void 2.405 +Clock_active::stop_clock(Cpm_regs ®s) 2.406 +{ 2.407 + _get_control().stop_clock(regs); 2.408 } 2.409 2.410 // Clock sources. 2.411 2.412 uint8_t 2.413 -Clock_base::get_source(Cpm_regs ®s) 2.414 +Clock_active::get_source(Cpm_regs ®s) 2.415 { 2.416 return _source.get_source(regs); 2.417 } 2.418 2.419 void 2.420 -Clock_base::set_source(Cpm_regs ®s, uint8_t source) 2.421 +Clock_active::set_source(Cpm_regs ®s, uint8_t source) 2.422 { 2.423 + _get_control().change_enable(regs); 2.424 _source.set_source(regs, source); 2.425 + _get_control().wait_busy(regs); 2.426 + _get_control().change_disable(regs); 2.427 } 2.428 2.429 // Clock source frequencies. 2.430 2.431 uint32_t 2.432 -Clock_base::get_source_frequency(Cpm_regs ®s) 2.433 +Clock_active::get_source_frequency(Cpm_regs ®s) 2.434 { 2.435 return _source.get_frequency(regs); 2.436 } 2.437 @@ -310,105 +536,83 @@ 2.438 // Output clock frequencies. 2.439 2.440 uint32_t 2.441 -Clock_base::get_frequency(Cpm_regs ®s) 2.442 +Clock_active::get_frequency(Cpm_regs ®s) 2.443 { 2.444 return get_source_frequency(regs); 2.445 } 2.446 2.447 2.448 2.449 -// PLL-specific control. 2.450 - 2.451 -int 2.452 -Pll::have_pll(Cpm_regs ®s) 2.453 -{ 2.454 - return _stable.get_field(regs); 2.455 -} 2.456 +// Divided clock interface. 2.457 2.458 -int 2.459 -Pll::pll_enabled(Cpm_regs ®s) 2.460 +Clock_divided::~Clock_divided() 2.461 { 2.462 - return _enable.get_field(regs); 2.463 -} 2.464 - 2.465 -int 2.466 -Pll::pll_bypassed(Cpm_regs ®s) 2.467 -{ 2.468 - return _bypass.get_field(regs); 2.469 } 2.470 2.471 -// Clock control. 2.472 +// Output clock frequencies. 2.473 2.474 -int 2.475 -Pll::have_clock(Cpm_regs ®s) 2.476 +uint32_t 2.477 +Clock_divided::get_frequency(Cpm_regs ®s) 2.478 { 2.479 - return have_pll(regs) && pll_enabled(regs); 2.480 + return _get_divider().get_frequency(regs, get_source_frequency(regs)); 2.481 } 2.482 2.483 -void 2.484 -Pll::start_clock(Cpm_regs ®s) 2.485 + 2.486 + 2.487 +// PLL boilerplate. 2.488 + 2.489 +Pll::~Pll() 2.490 { 2.491 - _enable.set_field(regs, 1); 2.492 - while (!have_pll(regs)); 2.493 -} 2.494 - 2.495 -void 2.496 -Pll::stop_clock(Cpm_regs ®s) 2.497 -{ 2.498 - _enable.set_field(regs, 0); 2.499 - while (have_pll(regs)); 2.500 } 2.501 2.502 // Feedback (13-bit) multiplier. 2.503 2.504 -uint16_t 2.505 +uint32_t 2.506 Pll::get_multiplier(Cpm_regs ®s) 2.507 { 2.508 return _divider.get_multiplier(regs); 2.509 } 2.510 2.511 void 2.512 -Pll::set_multiplier(Cpm_regs ®s, uint16_t multiplier) 2.513 +Pll::set_multiplier(Cpm_regs ®s, uint32_t multiplier) 2.514 { 2.515 _divider.set_multiplier(regs, multiplier); 2.516 } 2.517 2.518 // Input (6-bit) divider. 2.519 2.520 -uint8_t 2.521 -Pll::get_input_division(Cpm_regs ®s) 2.522 +uint32_t 2.523 +Pll::get_input_divider(Cpm_regs ®s) 2.524 { 2.525 - return _divider.get_input_division(regs); 2.526 + return _divider.get_input_divider(regs); 2.527 } 2.528 2.529 void 2.530 -Pll::set_input_division(Cpm_regs ®s, uint8_t divider) 2.531 +Pll::set_input_divider(Cpm_regs ®s, uint32_t divider) 2.532 { 2.533 - _divider.set_input_division(regs, divider); 2.534 + _divider.set_input_divider(regs, divider); 2.535 } 2.536 2.537 // Output (dual 3-bit) dividers. 2.538 2.539 -uint8_t 2.540 -Pll::get_output_division(Cpm_regs ®s) 2.541 +uint32_t 2.542 +Pll::get_output_divider(Cpm_regs ®s) 2.543 { 2.544 - return _divider.get_output_division(regs); 2.545 + return _divider.get_output_divider(regs); 2.546 } 2.547 2.548 void 2.549 -Pll::set_output_division(Cpm_regs ®s, uint8_t divider) 2.550 +Pll::set_output_divider(Cpm_regs ®s, uint32_t divider) 2.551 { 2.552 - _divider.set_output_division(regs, divider); 2.553 + _divider.set_output_divider(regs, divider); 2.554 } 2.555 2.556 uint32_t 2.557 Pll::get_frequency(Cpm_regs ®s) 2.558 { 2.559 - // Test for PLL enable and not PLL bypass. 2.560 - 2.561 - if (pll_enabled(regs)) 2.562 + if (have_clock(regs)) 2.563 { 2.564 - if (!pll_bypassed(regs)) 2.565 + if (!_control.pll_bypassed(regs)) 2.566 return _divider.get_frequency(regs, get_source_frequency(regs)); 2.567 else 2.568 return get_source_frequency(regs); 2.569 @@ -418,63 +622,15 @@ 2.570 } 2.571 2.572 void 2.573 -Pll::set_pll_parameters(Cpm_regs ®s, uint16_t multiplier, 2.574 - uint8_t in_divider, uint8_t out_divider) 2.575 +Pll::set_parameters(Cpm_regs ®s, uint32_t multiplier, 2.576 + uint32_t in_divider, uint32_t out_divider) 2.577 { 2.578 - set_pll_parameters(regs, multiplier, in_divider, out_divider); 2.579 - 2.580 - if (pll_enabled(regs) && !pll_bypassed(regs)) 2.581 - while (!have_pll(regs)); 2.582 + set_parameters(regs, multiplier, in_divider, out_divider); 2.583 + _control.wait_busy(regs); 2.584 } 2.585 2.586 2.587 2.588 -// Clock control. 2.589 - 2.590 -void 2.591 -Clock::change_disable(Cpm_regs ®s) 2.592 -{ 2.593 - if (_change_enable.is_defined()) 2.594 - _change_enable.set_field(regs, 0); 2.595 -} 2.596 - 2.597 -void 2.598 -Clock::change_enable(Cpm_regs ®s) 2.599 -{ 2.600 - if (_change_enable.is_defined()) 2.601 - _change_enable.set_field(regs, 1); 2.602 -} 2.603 - 2.604 -int 2.605 -Clock::have_clock(Cpm_regs ®s) 2.606 -{ 2.607 - if (_gate.is_defined()) 2.608 - return !_gate.get_field(regs); 2.609 - else 2.610 - return true; 2.611 -} 2.612 - 2.613 -void 2.614 -Clock::start_clock(Cpm_regs ®s) 2.615 -{ 2.616 - if (_gate.is_defined()) 2.617 - _gate.set_field(regs, 0); 2.618 -} 2.619 - 2.620 -void 2.621 -Clock::stop_clock(Cpm_regs ®s) 2.622 -{ 2.623 - if (_gate.is_defined()) 2.624 - _gate.set_field(regs, 1); 2.625 -} 2.626 - 2.627 -void 2.628 -Clock::wait_busy(Cpm_regs ®s) 2.629 -{ 2.630 - if (_busy.is_defined()) 2.631 - while (_busy.get_field(regs)); 2.632 -} 2.633 - 2.634 // Clock dividers. 2.635 2.636 uint32_t 2.637 @@ -484,27 +640,10 @@ 2.638 } 2.639 2.640 void 2.641 -Clock::set_divider(Cpm_regs ®s, uint32_t division) 2.642 -{ 2.643 - change_enable(regs); 2.644 - _divider.set_divider(regs, division); 2.645 - wait_busy(regs); 2.646 - change_disable(regs); 2.647 -} 2.648 - 2.649 -void 2.650 -Clock::set_source(Cpm_regs ®s, uint8_t source) 2.651 +Clock::set_divider(Cpm_regs ®s, uint32_t divider) 2.652 { 2.653 - change_enable(regs); 2.654 - Clock_base::set_source(regs, source); 2.655 - wait_busy(regs); 2.656 - change_disable(regs); 2.657 + _control.change_enable(regs); 2.658 + _divider.set_divider(regs, divider); 2.659 + _control.wait_busy(regs); 2.660 + _control.change_disable(regs); 2.661 } 2.662 - 2.663 -// Output clock frequencies. 2.664 - 2.665 -uint32_t 2.666 -Clock::get_frequency(Cpm_regs ®s) 2.667 -{ 2.668 - return _divider.get_frequency(regs, get_source_frequency(regs)); 2.669 -}
3.1 --- a/pkg/devices/lib/cpm/src/x1600.cc Sat Sep 16 17:56:49 2023 +0200 3.2 +++ b/pkg/devices/lib/cpm/src/x1600.cc Sun Sep 17 18:41:41 2023 +0200 3.3 @@ -40,8 +40,10 @@ 3.4 Clock_status = 0x0d4, // CPCSR 3.5 Divider_ddr = 0x02c, // DDRCDR 3.6 Divider_mac = 0x054, // MACCDR 3.7 - Divider0_i2s0 = 0x060, // I2SCDR 3.8 - Divider1_i2s0 = 0x070, // I2S1CDR 3.9 + Divider0_i2s0 = 0x060, // I2S0CDR 3.10 + Divider1_i2s0 = 0x070, // I2S0CDR1 3.11 + Divider0_i2s1 = 0x07c, // I2S1CDR (from X2000 manual) 3.12 + Divider1_i2s1 = 0x080, // I2S1CDR1 (from X2000 manual) 3.13 Divider_lcd = 0x064, // LPCDR 3.14 Divider_msc0 = 0x068, // MSC0CDR 3.15 Divider_msc1 = 0x0a4, // MSC1CDR 3.16 @@ -87,140 +89,146 @@ 3.17 3.18 // Register field definitions. 3.19 3.20 -Field Clock_source_main (Clock_control, 3, 30); // SEL_SRC (output to SCLK_A) 3.21 -Field Clock_source_cpu (Clock_control, 3, 28); // SEL_CPLL (output to CCLK) 3.22 -Field Clock_source_hclock0 (Clock_control, 3, 26); // SEL_H0PLL (output to AHB0) 3.23 -Field Clock_source_hclock2 (Clock_control, 3, 24); // SEL_H2PLL (output to AHB2) 3.24 -Field Clock_source_can0 (Divider_can0, 3, 30); // CA0CS 3.25 -Field Clock_source_can1 (Divider_can1, 3, 30); // CA1CS 3.26 -Field Clock_source_cdbus (Divider_cdbus, 3, 30); // CDCS 3.27 -Field Clock_source_cim (Divider_cim, 3, 30); // CIMPCS 3.28 -Field Clock_source_ddr (Divider_ddr, 3, 30); // DCS 3.29 -Field Clock_source_i2s (Divider0_i2s0, 1, 31); // I2PCS 3.30 -Field Clock_source_lcd (Divider_lcd, 3, 30); // LPCS 3.31 -Field Clock_source_mac (Divider_mac, 3, 30); // MACPCS 3.32 -Field Clock_source_msc0 (Divider_msc0, 3, 30); // MPCS 3.33 -Field Clock_source_msc1 (Divider_msc1, 3, 30); // MPCS 3.34 -Field Clock_source_pwm (Divider_pwm, 3, 30); // PWMPCS 3.35 -Field Clock_source_sfc (Divider_sfc, 3, 30); // SFCS 3.36 -Field Clock_source_ssi (Divider_ssi, 3, 30); // SPCS 3.37 - 3.38 -Field Clock_busy_cpu (Clock_status, 1, 0); 3.39 -Field Clock_busy_ddr (Divider_ddr, 1, 28); 3.40 -Field Clock_busy_mac (Divider_mac, 1, 28); 3.41 -Field Clock_busy_lcd (Divider_lcd, 1, 28); 3.42 -Field Clock_busy_msc0 (Divider_msc0, 1, 28); 3.43 -Field Clock_busy_msc1 (Divider_msc1, 1, 28); 3.44 -Field Clock_busy_sfc (Divider_sfc, 1, 28); 3.45 -Field Clock_busy_ssi (Divider_ssi, 1, 28); 3.46 -Field Clock_busy_cim (Divider_cim, 1, 28); 3.47 -Field Clock_busy_pwm (Divider_pwm, 1, 28); 3.48 -Field Clock_busy_can0 (Divider_can0, 1, 28); 3.49 -Field Clock_busy_can1 (Divider_can1, 1, 28); 3.50 -Field Clock_busy_cdbus (Divider_cdbus, 1, 28); 3.51 +static Field Clock_source_main (Clock_control, 3, 30), // SEL_SRC (output to SCLK_A) 3.52 + Clock_source_cpu (Clock_control, 3, 28), // SEL_CPLL (output to CCLK) 3.53 + Clock_source_hclock0 (Clock_control, 3, 26), // SEL_H0PLL (output to AHB0) 3.54 + Clock_source_hclock2 (Clock_control, 3, 24), // SEL_H2PLL (output to AHB2) 3.55 + Clock_source_can0 (Divider_can0, 3, 30), // CA0CS 3.56 + Clock_source_can1 (Divider_can1, 3, 30), // CA1CS 3.57 + Clock_source_cdbus (Divider_cdbus, 3, 30), // CDCS 3.58 + Clock_source_cim (Divider_cim, 3, 30), // CIMPCS 3.59 + Clock_source_ddr (Divider_ddr, 3, 30), // DCS 3.60 + Clock_source_i2s (Divider0_i2s0, 1, 31), // I2PCS 3.61 + Clock_source_lcd (Divider_lcd, 3, 30), // LPCS 3.62 + Clock_source_mac (Divider_mac, 3, 30), // MACPCS 3.63 + Clock_source_msc0 (Divider_msc0, 3, 30), // MPCS 3.64 + Clock_source_msc1 (Divider_msc1, 3, 30), // MPCS 3.65 + Clock_source_pwm (Divider_pwm, 3, 30), // PWMPCS 3.66 + Clock_source_sfc (Divider_sfc, 3, 30), // SFCS 3.67 + Clock_source_ssi (Divider_ssi, 3, 30), // SPCS 3.68 3.69 -Field Clock_change_enable_cpu (Clock_control, 1, 22); 3.70 -Field Clock_change_enable_ahb0 (Clock_control, 1, 21); 3.71 -Field Clock_change_enable_ahb2 (Clock_control, 1, 20); 3.72 -Field Clock_change_enable_ddr (Divider_ddr, 1, 29); 3.73 -Field Clock_change_enable_mac (Divider_mac, 1, 29); 3.74 -Field Clock_change_enable_i2s (Divider0_i2s0, 1, 29); 3.75 -Field Clock_change_enable_lcd (Divider_lcd, 1, 29); 3.76 -Field Clock_change_enable_msc0 (Divider_msc0, 1, 29); 3.77 -Field Clock_change_enable_msc1 (Divider_msc1, 1, 29); 3.78 -Field Clock_change_enable_sfc (Divider_sfc, 1, 29); 3.79 -Field Clock_change_enable_ssi (Divider_ssi, 1, 29); 3.80 -Field Clock_change_enable_cim (Divider_cim, 1, 29); 3.81 -Field Clock_change_enable_pwm (Divider_pwm, 1, 29); 3.82 -Field Clock_change_enable_can0 (Divider_can0, 1, 29); 3.83 -Field Clock_change_enable_can1 (Divider_can1, 1, 29); 3.84 -Field Clock_change_enable_cdbus (Divider_cdbus, 1, 29); 3.85 + Clock_busy_cpu (Clock_status, 1, 0), 3.86 + Clock_busy_ddr (Divider_ddr, 1, 28), 3.87 + Clock_busy_mac (Divider_mac, 1, 28), 3.88 + Clock_busy_lcd (Divider_lcd, 1, 28), 3.89 + Clock_busy_msc0 (Divider_msc0, 1, 28), 3.90 + Clock_busy_msc1 (Divider_msc1, 1, 28), 3.91 + Clock_busy_sfc (Divider_sfc, 1, 28), 3.92 + Clock_busy_ssi (Divider_ssi, 1, 28), 3.93 + Clock_busy_cim (Divider_cim, 1, 28), 3.94 + Clock_busy_pwm (Divider_pwm, 1, 28), 3.95 + Clock_busy_can0 (Divider_can0, 1, 28), 3.96 + Clock_busy_can1 (Divider_can1, 1, 28), 3.97 + Clock_busy_cdbus (Divider_cdbus, 1, 28), 3.98 3.99 -Field Clock_divider_can0 (Divider_can0, 0xff, 0); // CAN0CDR 3.100 -Field Clock_divider_can1 (Divider_can1, 0xff, 0); // CAN1CDR 3.101 -Field Clock_divider_cdbus (Divider_cdbus, 0xff, 0); // CDBUSCDR 3.102 -Field Clock_divider_cim (Divider_cim, 0xff, 0); // CIMCDR 3.103 -Field Clock_divider_cpu (Clock_control, 0x0f, 0); // CDIV 3.104 -Field Clock_divider_ddr (Divider_ddr, 0x0f, 0); // DDRCDR 3.105 -Field Clock_divider_hclock0 (Clock_control, 0x0f, 8); // H0DIV (fast AHB peripherals) 3.106 -Field Clock_divider_hclock2 (Clock_control, 0x0f, 12); // H2DIV (fast AHB peripherals) 3.107 -Field Clock_divider_l2cache (Clock_control, 0x0f, 4); // L2CDIV 3.108 -Field Clock_divider_lcd (Divider_lcd, 0xff, 0); // LPCDR 3.109 -Field Clock_divider_mac (Divider_mac, 0xff, 0); // MACCDR 3.110 -Field Clock_divider_msc0 (Divider_msc0, 0xff, 0); // MSC0CDR 3.111 -Field Clock_divider_msc1 (Divider_msc1, 0xff, 0); // MSC1CDR 3.112 -Field Clock_divider_pclock (Clock_control, 0x0f, 16); // PDIV (slow APB peripherals) 3.113 -Field Clock_divider_pwm (Divider_pwm, 0x0f, 0); // PWMCDR 3.114 -Field Clock_divider_sfc (Divider_sfc, 0xff, 0); // SFCCDR 3.115 -Field Clock_divider_ssi (Divider_ssi, 0xff, 0); // SSICDR 3.116 + Clock_change_enable_cpu (Clock_control, 1, 22), 3.117 + Clock_change_enable_ahb0 (Clock_control, 1, 21), 3.118 + Clock_change_enable_ahb2 (Clock_control, 1, 20), 3.119 + Clock_change_enable_ddr (Divider_ddr, 1, 29), 3.120 + Clock_change_enable_mac (Divider_mac, 1, 29), 3.121 + Clock_change_enable_i2s (Divider0_i2s0, 1, 29), 3.122 + Clock_change_enable_lcd (Divider_lcd, 1, 29), 3.123 + Clock_change_enable_msc0 (Divider_msc0, 1, 29), 3.124 + Clock_change_enable_msc1 (Divider_msc1, 1, 29), 3.125 + Clock_change_enable_sfc (Divider_sfc, 1, 29), 3.126 + Clock_change_enable_ssi (Divider_ssi, 1, 29), 3.127 + Clock_change_enable_cim (Divider_cim, 1, 29), 3.128 + Clock_change_enable_pwm (Divider_pwm, 1, 29), 3.129 + Clock_change_enable_can0 (Divider_can0, 1, 29), 3.130 + Clock_change_enable_can1 (Divider_can1, 1, 29), 3.131 + Clock_change_enable_cdbus (Divider_cdbus, 1, 29), 3.132 3.133 -Field Clock_gate_main (Clock_control, 1, 23); // GATE_SCLKA 3.134 -Field Clock_gate_ddr (Clock_gate0, 1, 31); // DDR 3.135 -Field Clock_gate_ahb0 (Clock_gate0, 1, 29); // AHB0 3.136 -Field Clock_gate_apb0 (Clock_gate0, 1, 28); // APB0 3.137 -Field Clock_gate_rtc (Clock_gate0, 1, 27); // RTC 3.138 -Field Clock_gate_aes (Clock_gate0, 1, 24); // AES 3.139 -Field Clock_gate_lcd_pixel (Clock_gate0, 1, 23); // LCD 3.140 -Field Clock_gate_cim (Clock_gate0, 1, 22); // CIM 3.141 -Field Clock_gate_dma (Clock_gate0, 1, 21); // PDMA 3.142 -Field Clock_gate_ost (Clock_gate0, 1, 20); // OST 3.143 -Field Clock_gate_ssi0 (Clock_gate0, 1, 19); // SSI0 3.144 -Field Clock_gate_timer (Clock_gate0, 1, 18); // TCU 3.145 -Field Clock_gate_dtrng (Clock_gate0, 1, 17); // DTRNG 3.146 -Field Clock_gate_uart2 (Clock_gate0, 1, 16); // UART2 3.147 -Field Clock_gate_uart1 (Clock_gate0, 1, 15); // UART1 3.148 -Field Clock_gate_uart0 (Clock_gate0, 1, 14); // UART0 3.149 -Field Clock_gate_sadc (Clock_gate0, 1, 13); // SADC 3.150 -Field Clock_gate_audio (Clock_gate0, 1, 11); // AUDIO 3.151 -Field Clock_gate_ssi_slv (Clock_gate0, 1, 10); // SSI_SLV 3.152 -Field Clock_gate_i2c1 (Clock_gate0, 1, 8); // I2C1 3.153 -Field Clock_gate_i2c0 (Clock_gate0, 1, 7); // I2C0 3.154 -Field Clock_gate_msc1 (Clock_gate0, 1, 5); // MSC1 3.155 -Field Clock_gate_msc0 (Clock_gate0, 1, 4); // MSC0 3.156 -Field Clock_gate_otg (Clock_gate0, 1, 3); // OTG 3.157 -Field Clock_gate_sfc (Clock_gate0, 1, 2); // SFC 3.158 -Field Clock_gate_efuse (Clock_gate0, 1, 1); // EFUSE 3.159 -Field Clock_gate_nemc (Clock_gate0, 1, 0); // NEMC 3.160 -Field Clock_gate_arb (Clock_gate1, 1, 30); // ARB 3.161 -Field Clock_gate_mipi_csi (Clock_gate1, 1, 28); // MIPI_CSI 3.162 -Field Clock_gate_intc (Clock_gate1, 1, 26); // INTC 3.163 -Field Clock_gate_gmac0 (Clock_gate1, 1, 23); // GMAC0 3.164 -Field Clock_gate_uart3 (Clock_gate1, 1, 16); // UART3 3.165 -Field Clock_gate_i2s0_tx (Clock_gate1, 1, 9); // I2S0_dev_tclk 3.166 -Field Clock_gate_i2s0_rx (Clock_gate1, 1, 8); // I2S0_dev_rclk 3.167 -Field Clock_gate_hash (Clock_gate1, 1, 6); // HASH 3.168 -Field Clock_gate_pwm (Clock_gate1, 1, 5); // PWM 3.169 -Field Clock_gate_cdbus (Clock_gate1, 1, 2); // CDBUS 3.170 -Field Clock_gate_can1 (Clock_gate1, 1, 1); // CAN1 3.171 -Field Clock_gate_can0 (Clock_gate1, 1, 0); // CAN0 3.172 + Clock_divider_can0 (Divider_can0, 0xff, 0), // CAN0CDR 3.173 + Clock_divider_can1 (Divider_can1, 0xff, 0), // CAN1CDR 3.174 + Clock_divider_cdbus (Divider_cdbus, 0xff, 0), // CDBUSCDR 3.175 + Clock_divider_cim (Divider_cim, 0xff, 0), // CIMCDR 3.176 + Clock_divider_cpu (Clock_control, 0x0f, 0), // CDIV 3.177 + Clock_divider_ddr (Divider_ddr, 0x0f, 0), // DDRCDR 3.178 + Clock_divider_hclock0 (Clock_control, 0x0f, 8), // H0DIV (fast AHB peripherals) 3.179 + Clock_divider_hclock2 (Clock_control, 0x0f, 12), // H2DIV (fast AHB peripherals) 3.180 + Clock_divider_i2s0_m (Divider0_i2s0, 0x1ff, 20), // I2SDIV_M 3.181 + Clock_divider_i2s0_n (Divider0_i2s0, 0xfffff, 0), // I2SDIV_N 3.182 + Clock_divider_i2s0_d (Divider1_i2s0, 0xfffff, 0), // I2SDIV_D 3.183 + Clock_divider_i2s1_m (Divider0_i2s1, 0x1ff, 20), // I2SDIV_M 3.184 + Clock_divider_i2s1_n (Divider0_i2s1, 0xfffff, 0), // I2SDIV_N 3.185 + Clock_divider_i2s1_d (Divider1_i2s1, 0xfffff, 0), // I2SDIV_D 3.186 + Clock_divider_l2cache (Clock_control, 0x0f, 4), // L2CDIV 3.187 + Clock_divider_lcd (Divider_lcd, 0xff, 0), // LPCDR 3.188 + Clock_divider_mac (Divider_mac, 0xff, 0), // MACCDR 3.189 + Clock_divider_msc0 (Divider_msc0, 0xff, 0), // MSC0CDR 3.190 + Clock_divider_msc1 (Divider_msc1, 0xff, 0), // MSC1CDR 3.191 + Clock_divider_pclock (Clock_control, 0x0f, 16), // PDIV (slow APB peripherals) 3.192 + Clock_divider_pwm (Divider_pwm, 0x0f, 0), // PWMCDR 3.193 + Clock_divider_sfc (Divider_sfc, 0xff, 0), // SFCCDR 3.194 + Clock_divider_ssi (Divider_ssi, 0xff, 0), // SSICDR 3.195 3.196 -Field Pll_enable_A (Pll_control_A, 1, 0); // APLLEN 3.197 -Field Pll_enable_E (Pll_control_E, 1, 0); // EPLLEN 3.198 -Field Pll_enable_M (Pll_control_M, 1, 0); // MPLLEN 3.199 - 3.200 -Field Pll_stable_A (Pll_control_A, 1, 3); // APLL_ON 3.201 -Field Pll_stable_E (Pll_control_E, 1, 3); // EPLL_ON 3.202 -Field Pll_stable_M (Pll_control_M, 1, 3); // MPLL_ON 3.203 - 3.204 -Field Pll_bypass_A (Pll_control_A, 1, 30); // APLL_BP 3.205 -Field Pll_bypass_E (Pll_control_E, 1, 26); // EPLL_BP 3.206 -Field Pll_bypass_M (Pll_control_M, 1, 28); // MPLL_BP 3.207 + Clock_gate_main (Clock_control, 1, 23), // GATE_SCLKA 3.208 + Clock_gate_ddr (Clock_gate0, 1, 31), // DDR 3.209 + Clock_gate_ahb0 (Clock_gate0, 1, 29), // AHB0 3.210 + Clock_gate_apb0 (Clock_gate0, 1, 28), // APB0 3.211 + Clock_gate_rtc (Clock_gate0, 1, 27), // RTC 3.212 + Clock_gate_aes (Clock_gate0, 1, 24), // AES 3.213 + Clock_gate_lcd_pixel (Clock_gate0, 1, 23), // LCD 3.214 + Clock_gate_cim (Clock_gate0, 1, 22), // CIM 3.215 + Clock_gate_dma (Clock_gate0, 1, 21), // PDMA 3.216 + Clock_gate_ost (Clock_gate0, 1, 20), // OST 3.217 + Clock_gate_ssi0 (Clock_gate0, 1, 19), // SSI0 3.218 + Clock_gate_timer (Clock_gate0, 1, 18), // TCU 3.219 + Clock_gate_dtrng (Clock_gate0, 1, 17), // DTRNG 3.220 + Clock_gate_uart2 (Clock_gate0, 1, 16), // UART2 3.221 + Clock_gate_uart1 (Clock_gate0, 1, 15), // UART1 3.222 + Clock_gate_uart0 (Clock_gate0, 1, 14), // UART0 3.223 + Clock_gate_sadc (Clock_gate0, 1, 13), // SADC 3.224 + Clock_gate_audio (Clock_gate0, 1, 11), // AUDIO 3.225 + Clock_gate_ssi_slv (Clock_gate0, 1, 10), // SSI_SLV 3.226 + Clock_gate_i2c1 (Clock_gate0, 1, 8), // I2C1 3.227 + Clock_gate_i2c0 (Clock_gate0, 1, 7), // I2C0 3.228 + Clock_gate_msc1 (Clock_gate0, 1, 5), // MSC1 3.229 + Clock_gate_msc0 (Clock_gate0, 1, 4), // MSC0 3.230 + Clock_gate_otg (Clock_gate0, 1, 3), // OTG 3.231 + Clock_gate_sfc (Clock_gate0, 1, 2), // SFC 3.232 + Clock_gate_efuse (Clock_gate0, 1, 1), // EFUSE 3.233 + Clock_gate_nemc (Clock_gate0, 1, 0), // NEMC 3.234 + Clock_gate_arb (Clock_gate1, 1, 30), // ARB 3.235 + Clock_gate_mipi_csi (Clock_gate1, 1, 28), // MIPI_CSI 3.236 + Clock_gate_intc (Clock_gate1, 1, 26), // INTC 3.237 + Clock_gate_gmac0 (Clock_gate1, 1, 23), // GMAC0 3.238 + Clock_gate_uart3 (Clock_gate1, 1, 16), // UART3 3.239 + Clock_gate_i2s0_tx (Clock_gate1, 1, 9), // I2S0_dev_tclk 3.240 + Clock_gate_i2s0_rx (Clock_gate1, 1, 8), // I2S0_dev_rclk 3.241 + Clock_gate_hash (Clock_gate1, 1, 6), // HASH 3.242 + Clock_gate_pwm (Clock_gate1, 1, 5), // PWM 3.243 + Clock_gate_cdbus (Clock_gate1, 1, 2), // CDBUS 3.244 + Clock_gate_can1 (Clock_gate1, 1, 1), // CAN1 3.245 + Clock_gate_can0 (Clock_gate1, 1, 0), // CAN0 3.246 3.247 -Field Pll_multiplier_A (Pll_control_A, 0x1fff, 20); // APLLM 3.248 -Field Pll_multiplier_E (Pll_control_E, 0x1fff, 20); // EPLLM 3.249 -Field Pll_multiplier_M (Pll_control_M, 0x1fff, 20); // MPLLM 3.250 + Pll_enable_A (Pll_control_A, 1, 0), // APLLEN 3.251 + Pll_enable_E (Pll_control_E, 1, 0), // EPLLEN 3.252 + Pll_enable_M (Pll_control_M, 1, 0), // MPLLEN 3.253 3.254 -Field Pll_input_division_A (Pll_control_A, 0x3f, 14); // APLLN 3.255 -Field Pll_input_division_E (Pll_control_E, 0x3f, 14); // EPLLN 3.256 -Field Pll_input_division_M (Pll_control_M, 0x3f, 14); // MPLLN 3.257 + Pll_stable_A (Pll_control_A, 1, 3), // APLL_ON 3.258 + Pll_stable_E (Pll_control_E, 1, 3), // EPLL_ON 3.259 + Pll_stable_M (Pll_control_M, 1, 3), // MPLL_ON 3.260 + 3.261 + Pll_bypass_A (Pll_control_A, 1, 30), // APLL_BP 3.262 + Pll_bypass_E (Pll_control_E, 1, 26), // EPLL_BP 3.263 + Pll_bypass_M (Pll_control_M, 1, 28), // MPLL_BP 3.264 3.265 -Field Pll_output_division1_A (Pll_control_A, 0x07, 11); // APLLOD1 3.266 -Field Pll_output_division1_E (Pll_control_E, 0x07, 11); // EPLLOD1 3.267 -Field Pll_output_division1_M (Pll_control_M, 0x07, 11); // MPLLOD1 3.268 + Pll_multiplier_A (Pll_control_A, 0x1fff, 20), // APLLM 3.269 + Pll_multiplier_E (Pll_control_E, 0x1fff, 20), // EPLLM 3.270 + Pll_multiplier_M (Pll_control_M, 0x1fff, 20), // MPLLM 3.271 + 3.272 + Pll_input_division_A (Pll_control_A, 0x3f, 14), // APLLN 3.273 + Pll_input_division_E (Pll_control_E, 0x3f, 14), // EPLLN 3.274 + Pll_input_division_M (Pll_control_M, 0x3f, 14), // MPLLN 3.275 3.276 -Field Pll_output_division0_A (Pll_control_A, 0x07, 8); // APLLOD0 3.277 -Field Pll_output_division0_E (Pll_control_E, 0x07, 8); // EPLLOD0 3.278 -Field Pll_output_division0_M (Pll_control_M, 0x07, 8); // MPLLOD0 3.279 + Pll_output_division1_A (Pll_control_A, 0x07, 11), // APLLOD1 3.280 + Pll_output_division1_E (Pll_control_E, 0x07, 11), // EPLLOD1 3.281 + Pll_output_division1_M (Pll_control_M, 0x07, 11), // MPLLOD1 3.282 + 3.283 + Pll_output_division0_A (Pll_control_A, 0x07, 8), // APLLOD0 3.284 + Pll_output_division0_E (Pll_control_E, 0x07, 8), // EPLLOD0 3.285 + Pll_output_division0_M (Pll_control_M, 0x07, 8); // MPLLOD0 3.286 3.287 3.288 3.289 @@ -248,195 +256,127 @@ 3.290 3.291 Clock clock_ahb2_apb(Source(mux_core, Clock_source_hclock2)); 3.292 3.293 -Clock clock_aic_bitclk; 3.294 - 3.295 -Clock clock_aic_pclk; 3.296 - 3.297 Clock clock_can0(Source(mux_bus, Clock_source_can0), 3.298 - Clock_gate_can0, 3.299 - Clock_change_enable_can0, 3.300 - Clock_busy_can0, 3.301 + Control(Clock_gate_can0, Clock_change_enable_can0, Clock_busy_can0), 3.302 Divider(Clock_divider_can0)); 3.303 3.304 Clock clock_can1(Source(mux_bus, Clock_source_can1), 3.305 - Clock_gate_can1, 3.306 - Clock_change_enable_can1, 3.307 - Clock_busy_can1, 3.308 + Control(Clock_gate_can1, Clock_change_enable_can1, Clock_busy_can1), 3.309 Divider(Clock_divider_can1)); 3.310 3.311 Clock clock_cdbus(Source(mux_dev, Clock_source_cdbus), 3.312 - Clock_gate_cdbus, 3.313 - Clock_change_enable_cdbus, 3.314 - Clock_busy_cdbus, 3.315 + Control(Clock_gate_cdbus, Clock_change_enable_cdbus, Clock_busy_cdbus), 3.316 Divider(Clock_divider_cdbus)); 3.317 3.318 Clock clock_cim(Source(mux_dev, Clock_source_cim), 3.319 - Clock_gate_cim, 3.320 - Clock_change_enable_cim, 3.321 - Clock_busy_cim, 3.322 + Control(Clock_gate_cim, Clock_change_enable_cim, Clock_busy_cim), 3.323 Divider(Clock_divider_cim)); 3.324 3.325 Clock clock_cpu(Source(mux_core, Clock_source_cpu), 3.326 - Field::undefined, 3.327 - Clock_change_enable_cpu, 3.328 - Clock_busy_cpu, 3.329 + Control(Field::undefined, Clock_change_enable_cpu, Clock_busy_cpu), 3.330 Divider(Clock_divider_cpu)); 3.331 3.332 Clock clock_ddr(Source(mux_core, Clock_source_ddr), 3.333 - Clock_gate_ddr, 3.334 - Clock_change_enable_ddr, 3.335 - Clock_busy_ddr, 3.336 + Control(Clock_gate_ddr, Clock_change_enable_ddr, Clock_busy_ddr), 3.337 Divider(Clock_divider_ddr)); 3.338 3.339 -Clock clock_dma(Source(mux_pclock), Clock_gate_dma); 3.340 +Clock clock_dma(Source(mux_pclock), Control(Clock_gate_dma), Divider::undefined); 3.341 3.342 -Clock clock_emac; 3.343 - 3.344 -Clock clock_external; 3.345 +Clock_passive clock_external; 3.346 3.347 Clock clock_hclock0(Source(mux_core, Clock_source_hclock0), 3.348 - Clock_gate_ahb0, 3.349 - Clock_change_enable_ahb0, 3.350 - Field::undefined, 3.351 + Control(Clock_gate_ahb0, Clock_change_enable_ahb0), 3.352 Divider(Clock_divider_hclock0)); 3.353 3.354 Clock clock_hclock2(Source(mux_ahb2_apb), 3.355 - Clock_gate_apb0, 3.356 - Clock_change_enable_ahb2, 3.357 - Field::undefined, 3.358 + Control(Clock_gate_apb0, Clock_change_enable_ahb2), 3.359 Divider(Clock_divider_hclock2)); 3.360 3.361 -Clock clock_hdmi; 3.362 - 3.363 -Clock clock_i2c(Source(mux_pclock), Clock_gate_i2c0); 3.364 +Clock clock_i2c(Source(mux_pclock), Control(Clock_gate_i2c0), Divider::undefined); 3.365 3.366 -Clock clock_i2c0(Source(mux_pclock), Clock_gate_i2c0); 3.367 +Clock clock_i2c0(Source(mux_pclock), Control(Clock_gate_i2c0), Divider::undefined); 3.368 3.369 -Clock clock_i2c1(Source(mux_pclock), Clock_gate_i2c1); 3.370 - 3.371 -Clock clock_i2s; 3.372 +Clock clock_i2c1(Source(mux_pclock), Control(Clock_gate_i2c1), Divider::undefined); 3.373 3.374 -Clock clock_i2s0_rx(Source(mux_i2s, Clock_source_i2s), 3.375 - Clock_gate_i2s0_rx, 3.376 - Clock_change_enable_i2s); 3.377 +Clock_divided_i2s clock_i2s0_rx(Source(mux_i2s, Clock_source_i2s), 3.378 + Control(Clock_gate_i2s0_rx, Clock_change_enable_i2s), 3.379 + Divider_i2s(Clock_divider_i2s0_m, Clock_divider_i2s0_n, 3.380 + Clock_divider_i2s0_d)); 3.381 3.382 -Clock clock_i2s0_tx(Source(mux_i2s, Clock_source_i2s), 3.383 - Clock_gate_i2s0_tx, 3.384 - Clock_change_enable_i2s); 3.385 - 3.386 -Clock clock_kbc; 3.387 - 3.388 -Clock clock_lcd; 3.389 +Clock_divided_i2s clock_i2s0_tx(Source(mux_i2s, Clock_source_i2s), 3.390 + Control(Clock_gate_i2s0_tx, Clock_change_enable_i2s), 3.391 + Divider_i2s(Clock_divider_i2s1_m, Clock_divider_i2s1_n, 3.392 + Clock_divider_i2s1_d)); 3.393 3.394 Clock clock_lcd_pixel(Source(mux_dev, Clock_source_lcd), 3.395 - Clock_gate_lcd_pixel, 3.396 - Clock_change_enable_lcd, 3.397 - Clock_busy_lcd, 3.398 + Control(Clock_gate_lcd_pixel, Clock_change_enable_lcd, Clock_busy_lcd), 3.399 Divider(Clock_divider_lcd)); 3.400 3.401 Clock clock_mac(Source(mux_dev, Clock_source_mac), 3.402 - Clock_gate_gmac0, 3.403 - Clock_change_enable_mac, 3.404 - Clock_busy_mac, 3.405 + Control(Clock_gate_gmac0, Clock_change_enable_mac, Clock_busy_mac), 3.406 Divider(Clock_divider_mac)); 3.407 3.408 Clock clock_main(Source(mux_core, Clock_source_main), 3.409 - Clock_gate_main); 3.410 + Control(Clock_gate_main)); 3.411 3.412 Clock clock_msc(Source(mux_dev, Clock_source_msc0), 3.413 - Clock_gate_msc0, 3.414 - Clock_change_enable_msc0, 3.415 - Clock_busy_msc0, 3.416 + Control(Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0), 3.417 Divider(Clock_divider_msc0)); 3.418 3.419 Clock clock_msc0(Source(mux_dev, Clock_source_msc0), 3.420 - Clock_gate_msc0, 3.421 - Clock_change_enable_msc0, 3.422 - Clock_busy_msc0, 3.423 + Control(Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0), 3.424 Divider(Clock_divider_msc0)); 3.425 3.426 Clock clock_msc1(Source(mux_dev, Clock_source_msc1), 3.427 - Clock_gate_msc1, 3.428 - Clock_change_enable_msc1, 3.429 - Clock_busy_msc1, 3.430 + Control(Clock_gate_msc1, Clock_change_enable_msc1, Clock_busy_msc1), 3.431 Divider(Clock_divider_msc1)); 3.432 3.433 -Clock clock_none; 3.434 +Clock_null clock_none; 3.435 3.436 Clock clock_pclock(Source(mux_ahb2_apb), 3.437 - Clock_gate_apb0, 3.438 - Field::undefined, 3.439 - Field::undefined, 3.440 + Control(Clock_gate_apb0, Field::undefined, Field::undefined), 3.441 Divider(Clock_divider_pclock)); 3.442 3.443 Pll clock_pll_A(Source(mux_external), 3.444 - Pll_enable_A, Pll_stable_A, Pll_bypass_A, 3.445 + Control_pll(Pll_enable_A, Pll_stable_A, Pll_bypass_A), 3.446 Divider_pll(Pll_multiplier_A, Pll_input_division_A, 3.447 Pll_output_division0_A, Pll_output_division1_A)); 3.448 3.449 Pll clock_pll_E(Source(mux_external), 3.450 - Pll_enable_E, Pll_stable_E, Pll_bypass_E, 3.451 + Control_pll(Pll_enable_E, Pll_stable_E, Pll_bypass_E), 3.452 Divider_pll(Pll_multiplier_E, Pll_input_division_E, 3.453 Pll_output_division0_E, Pll_output_division1_E)); 3.454 3.455 Pll clock_pll_M(Source(mux_external), 3.456 - Pll_enable_M, Pll_stable_M, Pll_bypass_M, 3.457 + Control_pll(Pll_enable_M, Pll_stable_M, Pll_bypass_M), 3.458 Divider_pll(Pll_multiplier_M, Pll_input_division_M, 3.459 Pll_output_division0_M, Pll_output_division1_M)); 3.460 3.461 Clock clock_pwm(Source(mux_dev, Clock_source_pwm), 3.462 - Clock_gate_pwm, 3.463 - Clock_change_enable_pwm, 3.464 - Clock_busy_pwm, 3.465 + Control(Clock_gate_pwm, Clock_change_enable_pwm, Clock_busy_pwm), 3.466 Divider(Clock_divider_pwm)); 3.467 3.468 Clock clock_pwm0(Source(mux_dev, Clock_source_pwm), 3.469 - Clock_gate_pwm, 3.470 - Clock_change_enable_pwm, 3.471 - Clock_busy_pwm, 3.472 + Control(Clock_gate_pwm, Clock_change_enable_pwm, Clock_busy_pwm), 3.473 Divider(Clock_divider_pwm)); 3.474 3.475 -Clock clock_pwm1; 3.476 - 3.477 -Clock clock_scc; 3.478 - 3.479 Clock clock_sfc(Source(mux_dev, Clock_source_sfc), 3.480 - Clock_gate_sfc, 3.481 - Clock_change_enable_sfc, 3.482 - Clock_busy_sfc, 3.483 + Control(Clock_gate_sfc, Clock_change_enable_sfc, Clock_busy_sfc), 3.484 Divider(Clock_divider_sfc)); 3.485 3.486 -Clock clock_smb0; 3.487 - 3.488 -Clock clock_smb1; 3.489 - 3.490 -Clock clock_smb2; 3.491 - 3.492 -Clock clock_smb3; 3.493 - 3.494 -Clock clock_smb4; 3.495 - 3.496 Clock clock_ssi(Source(mux_dev, Clock_source_ssi), 3.497 - Clock_gate_ssi0, 3.498 - Clock_change_enable_ssi, 3.499 - Clock_busy_ssi, 3.500 + Control(Clock_gate_ssi0, Clock_change_enable_ssi, Clock_busy_ssi), 3.501 Divider(Clock_divider_ssi)); 3.502 3.503 -Clock clock_timer(Source(mux_pclock), Clock_gate_timer); 3.504 - 3.505 -Clock clock_uart0(Source(mux_external), Clock_gate_uart0); 3.506 +Clock clock_timer(Source(mux_pclock), Control(Clock_gate_timer), Divider::undefined); 3.507 3.508 -Clock clock_uart1(Source(mux_external), Clock_gate_uart1); 3.509 - 3.510 -Clock clock_uart2(Source(mux_external), Clock_gate_uart2); 3.511 +Clock clock_uart0(Source(mux_external), Control(Clock_gate_uart0), Divider::undefined); 3.512 3.513 -Clock clock_uart3(Source(mux_external), Clock_gate_uart3); 3.514 - 3.515 -Clock clock_udc; 3.516 +Clock clock_uart1(Source(mux_external), Control(Clock_gate_uart1), Divider::undefined); 3.517 3.518 -Clock clock_uhc; 3.519 +Clock clock_uart2(Source(mux_external), Control(Clock_gate_uart2), Divider::undefined); 3.520 3.521 -Clock clock_uprt; 3.522 +Clock clock_uart3(Source(mux_external), Control(Clock_gate_uart3), Divider::undefined); 3.523 3.524 3.525 3.526 @@ -444,8 +384,8 @@ 3.527 3.528 static Clock_base *clocks[Clock_identifier_count] = { 3.529 &clock_ahb2_apb, 3.530 - &clock_aic_bitclk, 3.531 - &clock_aic_pclk, 3.532 + &clock_none, // Clock_aic_bitclk 3.533 + &clock_none, // Clock_aic_pclk 3.534 &clock_can0, 3.535 &clock_can1, 3.536 &clock_cdbus, 3.537 @@ -453,19 +393,19 @@ 3.538 &clock_cpu, 3.539 &clock_ddr, 3.540 &clock_dma, 3.541 - &clock_emac, 3.542 + &clock_none, // Clock_emac 3.543 &clock_external, 3.544 &clock_hclock0, 3.545 &clock_hclock2, 3.546 - &clock_hdmi, 3.547 + &clock_none, // Clock_hdmi 3.548 &clock_i2c, 3.549 &clock_i2c0, 3.550 &clock_i2c1, 3.551 - &clock_i2s, 3.552 + &clock_none, // Clock_i2s 3.553 &clock_i2s0_rx, 3.554 &clock_i2s0_tx, 3.555 - &clock_kbc, 3.556 - &clock_lcd, 3.557 + &clock_none, // Clock_kbc 3.558 + &clock_none, // Clock_lcd 3.559 &clock_lcd_pixel, 3.560 &clock_mac, 3.561 &clock_main, 3.562 @@ -479,23 +419,23 @@ 3.563 &clock_pll_M, 3.564 &clock_pwm, 3.565 &clock_pwm0, 3.566 - &clock_pwm1, 3.567 - &clock_scc, 3.568 + &clock_none, // Clock_pwm1 3.569 + &clock_none, // Clock_scc 3.570 &clock_sfc, 3.571 - &clock_smb0, 3.572 - &clock_smb1, 3.573 - &clock_smb2, 3.574 - &clock_smb3, 3.575 - &clock_smb4, 3.576 + &clock_none, // Clock_smb0 3.577 + &clock_none, // Clock_smb1 3.578 + &clock_none, // Clock_smb2 3.579 + &clock_none, // Clock_smb3 3.580 + &clock_none, // Clock_smb4 3.581 &clock_ssi, 3.582 &clock_timer, 3.583 &clock_uart0, 3.584 &clock_uart1, 3.585 &clock_uart2, 3.586 &clock_uart3, 3.587 - &clock_udc, 3.588 - &clock_uhc, 3.589 - &clock_uprt, 3.590 + &clock_none, // Clock_udc 3.591 + &clock_none, // Clock_uhc 3.592 + &clock_none, // Clock_uprt 3.593 }; 3.594 3.595 3.596 @@ -533,31 +473,52 @@ 3.597 uint32_t 3.598 Cpm_x1600_chip::get_divider(enum Clock_identifiers clock) 3.599 { 3.600 - return clocks[clock]->get_divider(_cpm_regs); 3.601 + Clock *clk = dynamic_cast<Clock *>(clocks[clock]); 3.602 + 3.603 + if (clk != NULL) 3.604 + return clk->get_divider(_cpm_regs); 3.605 + else 3.606 + return 1; 3.607 } 3.608 3.609 void 3.610 Cpm_x1600_chip::set_divider(enum Clock_identifiers clock, uint32_t division) 3.611 { 3.612 - clocks[clock]->set_divider(_cpm_regs, division); 3.613 + Clock *clk = dynamic_cast<Clock *>(clocks[clock]); 3.614 + 3.615 + if (clk != NULL) 3.616 + clk->set_divider(_cpm_regs, division); 3.617 } 3.618 3.619 uint8_t 3.620 Cpm_x1600_chip::get_source(enum Clock_identifiers clock) 3.621 { 3.622 - return clocks[clock]->get_source(_cpm_regs); 3.623 + Clock_active *clk = dynamic_cast<Clock_active *>(clocks[clock]); 3.624 + 3.625 + if (clk != NULL) 3.626 + return clk->get_source(_cpm_regs); 3.627 + else 3.628 + return 0; 3.629 } 3.630 3.631 void 3.632 Cpm_x1600_chip::set_source(enum Clock_identifiers clock, uint8_t source) 3.633 { 3.634 - clocks[clock]->set_source(_cpm_regs, source); 3.635 + Clock_active *clk = dynamic_cast<Clock_active *>(clocks[clock]); 3.636 + 3.637 + if (clk != NULL) 3.638 + clk->set_source(_cpm_regs, source); 3.639 } 3.640 3.641 uint32_t 3.642 Cpm_x1600_chip::get_source_frequency(enum Clock_identifiers clock) 3.643 { 3.644 - return clocks[clock]->get_source_frequency(_cpm_regs); 3.645 + Clock_active *clk = dynamic_cast<Clock_active *>(clocks[clock]); 3.646 + 3.647 + if (clk != NULL) 3.648 + return clk->get_source_frequency(_cpm_regs); 3.649 + else 3.650 + return 0; 3.651 } 3.652 3.653 uint32_t 3.654 @@ -579,12 +540,15 @@ 3.655 3.656 // Switch to the MPLL and attempt to set the divider. 3.657 3.658 - Clock_base *lcd = clocks[Clock_lcd_pixel]; 3.659 + Clock *lcd = dynamic_cast<Clock *>(clocks[Clock_lcd_pixel]); 3.660 Clock_base *pll = clocks[Clock_pll_M]; 3.661 3.662 - lcd->set_source(_cpm_regs, Source_mME_pll_M); 3.663 - pll->start_clock(_cpm_regs); 3.664 - lcd->set_divider(_cpm_regs, lcd->get_source_frequency(_cpm_regs) / frequency); 3.665 + if (lcd != NULL) 3.666 + { 3.667 + lcd->set_source(_cpm_regs, Source_mME_pll_M); 3.668 + pll->start_clock(_cpm_regs); 3.669 + lcd->set_divider(_cpm_regs, lcd->get_source_frequency(_cpm_regs) / frequency); 3.670 + } 3.671 break; 3.672 } 3.673 3.674 @@ -599,7 +563,8 @@ 3.675 { 3.676 Pll *pll = dynamic_cast<Pll *>(clocks[clock]); 3.677 3.678 - pll->set_pll_parameters(_cpm_regs, multiplier, in_divider, out_divider); 3.679 + if (pll != NULL) 3.680 + pll->set_parameters(_cpm_regs, multiplier, in_divider, out_divider); 3.681 } 3.682 3.683