1.1 --- a/pkg/devices/lib/cpm/src/x1600.cc Fri Sep 15 23:03:09 2023 +0200
1.2 +++ b/pkg/devices/lib/cpm/src/x1600.cc Sat Sep 16 00:49:41 2023 +0200
1.3 @@ -116,23 +116,40 @@
1.4
1.5
1.6
1.7 +// Clock sources.
1.8 +
1.9 +class Mux
1.10 +{
1.11 + int _num_inputs;
1.12 + enum Clock_identifiers *_inputs;
1.13 +
1.14 +public:
1.15 + explicit Mux(int num_inputs = 0, enum Clock_identifiers inputs[] = NULL)
1.16 + : _num_inputs(num_inputs), _inputs(inputs)
1.17 + {
1.18 + }
1.19 +
1.20 + int get_number() { return _num_inputs; }
1.21 + enum Clock_identifiers get_input(int num);
1.22 +};
1.23 +
1.24 +// Undefined sources.
1.25 +
1.26 +Mux Mux_undefined;
1.27 +
1.28 +
1.29 +
1.30 // Common clock abstraction.
1.31
1.32 class Clock_base
1.33 {
1.34 -protected:
1.35 -
1.36 - // Clock sources and source selection.
1.37 -
1.38 - int num_inputs;
1.39 - enum Clock_identifiers *inputs;
1.40 + Mux _inputs;
1.41 Field _source;
1.42
1.43 public:
1.44 - explicit Clock_base(int num_inputs = 0,
1.45 - enum Clock_identifiers inputs[] = NULL,
1.46 + explicit Clock_base(Mux inputs,
1.47 Field source = Source_undefined)
1.48 - : num_inputs(num_inputs), inputs(inputs), _source(source)
1.49 + : _inputs(inputs), _source(source)
1.50 {
1.51 }
1.52
1.53 @@ -171,11 +188,11 @@
1.54 Field _multiplier, _input_division, _output_division0, _output_division1;
1.55
1.56 public:
1.57 - explicit Pll(int num_inputs, enum Clock_identifiers inputs[],
1.58 + explicit Pll(Mux inputs,
1.59 Field enable, Field stable, Field bypass,
1.60 Field multiplier, Field input_division,
1.61 Field output_division0, Field output_division1)
1.62 - : Clock_base(num_inputs, inputs),
1.63 + : Clock_base(inputs),
1.64 _enable(enable), _stable(stable), _bypass(bypass),
1.65 _multiplier(multiplier), _input_division(input_division),
1.66 _output_division0(output_division0), _output_division1(output_division1)
1.67 @@ -228,13 +245,13 @@
1.68 void wait_busy(Cpm_regs ®s);
1.69
1.70 public:
1.71 - explicit Clock(int num_inputs = 0, enum Clock_identifiers inputs[] = NULL,
1.72 + explicit Clock(Mux inputs = Mux_undefined,
1.73 Field source = Source_undefined,
1.74 Field gate = Gate_undefined,
1.75 Field change_enable = Change_enable_undefined,
1.76 Field busy = Busy_undefined,
1.77 Field divider = Divider_undefined)
1.78 - : Clock_base(num_inputs, inputs, source),
1.79 + : Clock_base(inputs, source),
1.80 _gate(gate), _change_enable(change_enable), _busy(busy), _divider(divider)
1.81 {
1.82 }
1.83 @@ -396,75 +413,90 @@
1.84
1.85
1.86
1.87 +// Multiplexer instances.
1.88 +
1.89 +#define Clocks(...) ((enum Clock_identifiers []) {__VA_ARGS__})
1.90 +
1.91 +Mux mux_external(1, Clocks(Clock_external));
1.92 +
1.93 +Mux mux_core(3, Clocks(Clock_none, Clock_main, Clock_pll_M));
1.94 +
1.95 +Mux mux_bus(4, Clocks(Clock_main, Clock_pll_M, Clock_pll_E, Clock_external));
1.96 +
1.97 +Mux mux_dev(3, Clocks(Clock_main, Clock_pll_M, Clock_pll_E));
1.98 +
1.99 +Mux mux_pclock(1, Clocks(Clock_pclock));
1.100 +
1.101 +Mux mux_ahb2_apb(1, Clocks(Clock_ahb2_apb));
1.102 +
1.103 +Mux mux_i2s(2, Clocks(Clock_main, Clock_pll_E));
1.104 +
1.105 +
1.106 +
1.107 // Clock instances.
1.108
1.109 -#define Clock_inputs(...) ((enum Clock_identifiers []) {__VA_ARGS__})
1.110 -
1.111 -Clock clock_ahb2_apb(3, Clock_inputs(Clock_none, Clock_main, Clock_pll_M),
1.112 - Clock_source_hclock2);
1.113 +Clock clock_ahb2_apb(mux_core, Clock_source_hclock2);
1.114
1.115 Clock clock_aic_bitclk;
1.116
1.117 Clock clock_aic_pclk;
1.118
1.119 -Clock clock_can0(4, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E, Clock_external),
1.120 +Clock clock_can0(mux_bus,
1.121 Clock_source_can0,
1.122 Clock_gate_can0,
1.123 Clock_change_enable_can0,
1.124 Clock_busy_can0,
1.125 Clock_divider_can0);
1.126
1.127 -Clock clock_can1(4, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E, Clock_external),
1.128 +Clock clock_can1(mux_bus,
1.129 Clock_source_can1,
1.130 Clock_gate_can1,
1.131 Clock_change_enable_can1,
1.132 Clock_busy_can1,
1.133 Clock_divider_can1);
1.134
1.135 -Clock clock_cdbus(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.136 +Clock clock_cdbus(mux_dev,
1.137 Clock_source_cdbus,
1.138 Clock_gate_cdbus,
1.139 Clock_change_enable_cdbus,
1.140 Clock_busy_cdbus,
1.141 Clock_divider_cdbus);
1.142
1.143 -Clock clock_cim(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.144 +Clock clock_cim(mux_dev,
1.145 Clock_source_cim,
1.146 Clock_gate_cim,
1.147 Clock_change_enable_cim,
1.148 Clock_busy_cim,
1.149 Clock_divider_cim);
1.150
1.151 -Clock clock_cpu(3, Clock_inputs(Clock_none, Clock_main, Clock_pll_M),
1.152 +Clock clock_cpu(mux_core,
1.153 Clock_source_cpu,
1.154 Gate_undefined,
1.155 Clock_change_enable_cpu,
1.156 Clock_busy_cpu,
1.157 Clock_divider_cpu);
1.158
1.159 -Clock clock_ddr(3, Clock_inputs(Clock_none, Clock_main, Clock_pll_M),
1.160 +Clock clock_ddr(mux_core,
1.161 Clock_source_ddr,
1.162 Clock_gate_ddr,
1.163 Clock_change_enable_ddr,
1.164 Clock_busy_ddr,
1.165 Clock_divider_ddr);
1.166
1.167 -Clock clock_dma(1, Clock_inputs(Clock_pclock),
1.168 - Source_undefined,
1.169 - Clock_gate_dma);
1.170 +Clock clock_dma(mux_pclock, Source_undefined, Clock_gate_dma);
1.171
1.172 Clock clock_emac;
1.173
1.174 Clock clock_external;
1.175
1.176 -Clock clock_hclock0(3, Clock_inputs(Clock_none, Clock_main, Clock_pll_M),
1.177 +Clock clock_hclock0(mux_core,
1.178 Clock_source_hclock0,
1.179 Clock_gate_ahb0,
1.180 Clock_change_enable_ahb0,
1.181 Busy_undefined,
1.182 Clock_divider_hclock0);
1.183
1.184 -Clock clock_hclock2(1, Clock_inputs(Clock_ahb2_apb),
1.185 +Clock clock_hclock2(mux_ahb2_apb,
1.186 Source_undefined,
1.187 Clock_gate_apb0,
1.188 Clock_change_enable_ahb2,
1.189 @@ -473,26 +505,26 @@
1.190
1.191 Clock clock_hdmi;
1.192
1.193 -Clock clock_i2c(1, Clock_inputs(Clock_pclock),
1.194 +Clock clock_i2c(mux_pclock,
1.195 Source_undefined,
1.196 Clock_gate_i2c0);
1.197
1.198 -Clock clock_i2c0(1, Clock_inputs(Clock_pclock),
1.199 +Clock clock_i2c0(mux_pclock,
1.200 Source_undefined,
1.201 Clock_gate_i2c0);
1.202
1.203 -Clock clock_i2c1(1, Clock_inputs(Clock_pclock),
1.204 +Clock clock_i2c1(mux_pclock,
1.205 Source_undefined,
1.206 Clock_gate_i2c1);
1.207
1.208 Clock clock_i2s;
1.209
1.210 -Clock clock_i2s0_rx(2, Clock_inputs(Clock_main, Clock_pll_E),
1.211 +Clock clock_i2s0_rx(mux_i2s,
1.212 Clock_source_i2s,
1.213 Clock_gate_i2s0_rx,
1.214 Clock_change_enable_i2s);
1.215
1.216 -Clock clock_i2s0_tx(2, Clock_inputs(Clock_main, Clock_pll_E),
1.217 +Clock clock_i2s0_tx(mux_i2s,
1.218 Clock_source_i2s,
1.219 Clock_gate_i2s0_tx,
1.220 Clock_change_enable_i2s);
1.221 @@ -501,39 +533,39 @@
1.222
1.223 Clock clock_lcd;
1.224
1.225 -Clock clock_lcd_pixel(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.226 +Clock clock_lcd_pixel(mux_dev,
1.227 Clock_source_lcd,
1.228 Clock_gate_lcd_pixel,
1.229 Clock_change_enable_lcd,
1.230 Clock_busy_lcd,
1.231 Clock_divider_lcd);
1.232
1.233 -Clock clock_mac(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.234 +Clock clock_mac(mux_dev,
1.235 Clock_source_mac,
1.236 Clock_gate_gmac0,
1.237 Clock_change_enable_mac,
1.238 Clock_busy_mac,
1.239 Clock_divider_mac);
1.240
1.241 -Clock clock_main(3, Clock_inputs(Clock_none, Clock_external, Clock_pll_A),
1.242 +Clock clock_main(mux_core,
1.243 Clock_source_main,
1.244 Clock_gate_main);
1.245
1.246 -Clock clock_msc(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.247 +Clock clock_msc(mux_dev,
1.248 Clock_source_msc0,
1.249 Clock_gate_msc0,
1.250 Clock_change_enable_msc0,
1.251 Clock_busy_msc0,
1.252 Clock_divider_msc0);
1.253
1.254 -Clock clock_msc0(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.255 +Clock clock_msc0(mux_dev,
1.256 Clock_source_msc0,
1.257 Clock_gate_msc0,
1.258 Clock_change_enable_msc0,
1.259 Clock_busy_msc0,
1.260 Clock_divider_msc0);
1.261
1.262 -Clock clock_msc1(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.263 +Clock clock_msc1(mux_dev,
1.264 Clock_source_msc1,
1.265 Clock_gate_msc1,
1.266 Clock_change_enable_msc1,
1.267 @@ -542,36 +574,36 @@
1.268
1.269 Clock clock_none;
1.270
1.271 -Clock clock_pclock(1, Clock_inputs(Clock_ahb2_apb),
1.272 +Clock clock_pclock(mux_ahb2_apb,
1.273 Source_undefined,
1.274 Clock_gate_apb0,
1.275 Change_enable_undefined,
1.276 Busy_undefined,
1.277 Clock_divider_pclock);
1.278
1.279 -Pll clock_pll_A(1, Clock_inputs(Clock_external),
1.280 +Pll clock_pll_A(mux_external,
1.281 Pll_enable_A, Pll_stable_A, Pll_bypass_A,
1.282 Pll_multiplier_A, Pll_input_division_A,
1.283 Pll_output_division0_A, Pll_output_division1_A);
1.284
1.285 -Pll clock_pll_E(1, Clock_inputs(Clock_external),
1.286 +Pll clock_pll_E(mux_external,
1.287 Pll_enable_E, Pll_stable_E, Pll_bypass_E,
1.288 Pll_multiplier_E, Pll_input_division_E,
1.289 Pll_output_division0_E, Pll_output_division1_E);
1.290
1.291 -Pll clock_pll_M(1, Clock_inputs(Clock_external),
1.292 +Pll clock_pll_M(mux_external,
1.293 Pll_enable_M, Pll_stable_M, Pll_bypass_M,
1.294 Pll_multiplier_M, Pll_input_division_M,
1.295 Pll_output_division0_M, Pll_output_division1_M);
1.296
1.297 -Clock clock_pwm(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.298 +Clock clock_pwm(mux_dev,
1.299 Clock_source_pwm,
1.300 Clock_gate_pwm,
1.301 Clock_change_enable_pwm,
1.302 Clock_busy_pwm,
1.303 Clock_divider_pwm);
1.304
1.305 -Clock clock_pwm0(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.306 +Clock clock_pwm0(mux_dev,
1.307 Clock_source_pwm,
1.308 Clock_gate_pwm,
1.309 Clock_change_enable_pwm,
1.310 @@ -582,7 +614,7 @@
1.311
1.312 Clock clock_scc;
1.313
1.314 -Clock clock_sfc(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.315 +Clock clock_sfc(mux_dev,
1.316 Clock_source_sfc,
1.317 Clock_gate_sfc,
1.318 Clock_change_enable_sfc,
1.319 @@ -599,32 +631,22 @@
1.320
1.321 Clock clock_smb4;
1.322
1.323 -Clock clock_ssi(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.324 +Clock clock_ssi(mux_dev,
1.325 Clock_source_ssi,
1.326 Clock_gate_ssi0,
1.327 Clock_change_enable_ssi,
1.328 Clock_busy_ssi,
1.329 Clock_divider_ssi);
1.330
1.331 -Clock clock_timer(1, Clock_inputs(Clock_pclock),
1.332 - Source_undefined,
1.333 - Clock_gate_timer);
1.334 +Clock clock_timer(mux_pclock, Source_undefined, Clock_gate_timer);
1.335
1.336 -Clock clock_uart0(1, Clock_inputs(Clock_external),
1.337 - Source_undefined,
1.338 - Clock_gate_uart0);
1.339 +Clock clock_uart0(mux_external, Source_undefined, Clock_gate_uart0);
1.340
1.341 -Clock clock_uart1(1, Clock_inputs(Clock_external),
1.342 - Source_undefined,
1.343 - Clock_gate_uart1);
1.344 +Clock clock_uart1(mux_external, Source_undefined, Clock_gate_uart1);
1.345
1.346 -Clock clock_uart2(1, Clock_inputs(Clock_external),
1.347 - Source_undefined,
1.348 - Clock_gate_uart2);
1.349 +Clock clock_uart2(mux_external, Source_undefined, Clock_gate_uart2);
1.350
1.351 -Clock clock_uart3(1, Clock_inputs(Clock_external),
1.352 - Source_undefined,
1.353 - Clock_gate_uart3);
1.354 +Clock clock_uart3(mux_external, Source_undefined, Clock_gate_uart3);
1.355
1.356 Clock clock_udc;
1.357
1.358 @@ -738,6 +760,19 @@
1.359
1.360
1.361
1.362 +// Clock sources.
1.363 +
1.364 +enum Clock_identifiers
1.365 +Mux::get_input(int num)
1.366 +{
1.367 + if (num < _num_inputs)
1.368 + return _inputs[num];
1.369 + else
1.370 + return Clock_undefined;
1.371 +}
1.372 +
1.373 +
1.374 +
1.375 // Clock control.
1.376
1.377 int
1.378 @@ -802,22 +837,23 @@
1.379 {
1.380 // Return the external clock frequency without any input clock.
1.381
1.382 - if (num_inputs == 0)
1.383 + if (_inputs.get_number() == 0)
1.384 return regs.exclk_freq;
1.385
1.386 // Clocks with one source yield that input frequency.
1.387
1.388 - else if (num_inputs == 1)
1.389 - return clocks[inputs[0]]->get_frequency(regs);
1.390 + else if (_inputs.get_number() == 1)
1.391 + return clocks[_inputs.get_input(0)]->get_frequency(regs);
1.392
1.393 // With multiple sources, obtain the selected source for the clock.
1.394
1.395 uint8_t source = get_source(regs);
1.396 + enum Clock_identifiers input = _inputs.get_input(source);
1.397
1.398 // Return the frequency of the source.
1.399
1.400 - if (source < num_inputs)
1.401 - return clocks[inputs[source]]->get_frequency(regs);
1.402 + if (input != Clock_undefined)
1.403 + return clocks[input]->get_frequency(regs);
1.404 else
1.405 return 0;
1.406 }