# HG changeset patch # User Paul Boddie # Date 1694818181 -7200 # Node ID 6a898a1a5dba8a32a7ae8d6f9b7843c431fe164b # Parent e497c64050c41b93ec9eeffa2deda0c6c57ba134 Introduced common clock source multiplexing objects. diff -r e497c64050c4 -r 6a898a1a5dba pkg/devices/lib/cpm/src/x1600.cc --- a/pkg/devices/lib/cpm/src/x1600.cc Fri Sep 15 23:03:09 2023 +0200 +++ b/pkg/devices/lib/cpm/src/x1600.cc Sat Sep 16 00:49:41 2023 +0200 @@ -116,23 +116,40 @@ +// Clock sources. + +class Mux +{ + int _num_inputs; + enum Clock_identifiers *_inputs; + +public: + explicit Mux(int num_inputs = 0, enum Clock_identifiers inputs[] = NULL) + : _num_inputs(num_inputs), _inputs(inputs) + { + } + + int get_number() { return _num_inputs; } + enum Clock_identifiers get_input(int num); +}; + +// Undefined sources. + +Mux Mux_undefined; + + + // Common clock abstraction. class Clock_base { -protected: - - // Clock sources and source selection. - - int num_inputs; - enum Clock_identifiers *inputs; + Mux _inputs; Field _source; public: - explicit Clock_base(int num_inputs = 0, - enum Clock_identifiers inputs[] = NULL, + explicit Clock_base(Mux inputs, Field source = Source_undefined) - : num_inputs(num_inputs), inputs(inputs), _source(source) + : _inputs(inputs), _source(source) { } @@ -171,11 +188,11 @@ Field _multiplier, _input_division, _output_division0, _output_division1; public: - explicit Pll(int num_inputs, enum Clock_identifiers inputs[], + explicit Pll(Mux inputs, Field enable, Field stable, Field bypass, Field multiplier, Field input_division, Field output_division0, Field output_division1) - : Clock_base(num_inputs, inputs), + : Clock_base(inputs), _enable(enable), _stable(stable), _bypass(bypass), _multiplier(multiplier), _input_division(input_division), _output_division0(output_division0), _output_division1(output_division1) @@ -228,13 +245,13 @@ void wait_busy(Cpm_regs ®s); public: - explicit Clock(int num_inputs = 0, enum Clock_identifiers inputs[] = NULL, + explicit Clock(Mux inputs = Mux_undefined, Field source = Source_undefined, Field gate = Gate_undefined, Field change_enable = Change_enable_undefined, Field busy = Busy_undefined, Field divider = Divider_undefined) - : Clock_base(num_inputs, inputs, source), + : Clock_base(inputs, source), _gate(gate), _change_enable(change_enable), _busy(busy), _divider(divider) { } @@ -396,75 +413,90 @@ +// Multiplexer instances. + +#define Clocks(...) ((enum Clock_identifiers []) {__VA_ARGS__}) + +Mux mux_external(1, Clocks(Clock_external)); + +Mux mux_core(3, Clocks(Clock_none, Clock_main, Clock_pll_M)); + +Mux mux_bus(4, Clocks(Clock_main, Clock_pll_M, Clock_pll_E, Clock_external)); + +Mux mux_dev(3, Clocks(Clock_main, Clock_pll_M, Clock_pll_E)); + +Mux mux_pclock(1, Clocks(Clock_pclock)); + +Mux mux_ahb2_apb(1, Clocks(Clock_ahb2_apb)); + +Mux mux_i2s(2, Clocks(Clock_main, Clock_pll_E)); + + + // Clock instances. -#define Clock_inputs(...) ((enum Clock_identifiers []) {__VA_ARGS__}) - -Clock clock_ahb2_apb(3, Clock_inputs(Clock_none, Clock_main, Clock_pll_M), - Clock_source_hclock2); +Clock clock_ahb2_apb(mux_core, Clock_source_hclock2); Clock clock_aic_bitclk; Clock clock_aic_pclk; -Clock clock_can0(4, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E, Clock_external), +Clock clock_can0(mux_bus, Clock_source_can0, Clock_gate_can0, Clock_change_enable_can0, Clock_busy_can0, Clock_divider_can0); -Clock clock_can1(4, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E, Clock_external), +Clock clock_can1(mux_bus, Clock_source_can1, Clock_gate_can1, Clock_change_enable_can1, Clock_busy_can1, Clock_divider_can1); -Clock clock_cdbus(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E), +Clock clock_cdbus(mux_dev, Clock_source_cdbus, Clock_gate_cdbus, Clock_change_enable_cdbus, Clock_busy_cdbus, Clock_divider_cdbus); -Clock clock_cim(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E), +Clock clock_cim(mux_dev, Clock_source_cim, Clock_gate_cim, Clock_change_enable_cim, Clock_busy_cim, Clock_divider_cim); -Clock clock_cpu(3, Clock_inputs(Clock_none, Clock_main, Clock_pll_M), +Clock clock_cpu(mux_core, Clock_source_cpu, Gate_undefined, Clock_change_enable_cpu, Clock_busy_cpu, Clock_divider_cpu); -Clock clock_ddr(3, Clock_inputs(Clock_none, Clock_main, Clock_pll_M), +Clock clock_ddr(mux_core, Clock_source_ddr, Clock_gate_ddr, Clock_change_enable_ddr, Clock_busy_ddr, Clock_divider_ddr); -Clock clock_dma(1, Clock_inputs(Clock_pclock), - Source_undefined, - Clock_gate_dma); +Clock clock_dma(mux_pclock, Source_undefined, Clock_gate_dma); Clock clock_emac; Clock clock_external; -Clock clock_hclock0(3, Clock_inputs(Clock_none, Clock_main, Clock_pll_M), +Clock clock_hclock0(mux_core, Clock_source_hclock0, Clock_gate_ahb0, Clock_change_enable_ahb0, Busy_undefined, Clock_divider_hclock0); -Clock clock_hclock2(1, Clock_inputs(Clock_ahb2_apb), +Clock clock_hclock2(mux_ahb2_apb, Source_undefined, Clock_gate_apb0, Clock_change_enable_ahb2, @@ -473,26 +505,26 @@ Clock clock_hdmi; -Clock clock_i2c(1, Clock_inputs(Clock_pclock), +Clock clock_i2c(mux_pclock, Source_undefined, Clock_gate_i2c0); -Clock clock_i2c0(1, Clock_inputs(Clock_pclock), +Clock clock_i2c0(mux_pclock, Source_undefined, Clock_gate_i2c0); -Clock clock_i2c1(1, Clock_inputs(Clock_pclock), +Clock clock_i2c1(mux_pclock, Source_undefined, Clock_gate_i2c1); Clock clock_i2s; -Clock clock_i2s0_rx(2, Clock_inputs(Clock_main, Clock_pll_E), +Clock clock_i2s0_rx(mux_i2s, Clock_source_i2s, Clock_gate_i2s0_rx, Clock_change_enable_i2s); -Clock clock_i2s0_tx(2, Clock_inputs(Clock_main, Clock_pll_E), +Clock clock_i2s0_tx(mux_i2s, Clock_source_i2s, Clock_gate_i2s0_tx, Clock_change_enable_i2s); @@ -501,39 +533,39 @@ Clock clock_lcd; -Clock clock_lcd_pixel(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E), +Clock clock_lcd_pixel(mux_dev, Clock_source_lcd, Clock_gate_lcd_pixel, Clock_change_enable_lcd, Clock_busy_lcd, Clock_divider_lcd); -Clock clock_mac(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E), +Clock clock_mac(mux_dev, Clock_source_mac, Clock_gate_gmac0, Clock_change_enable_mac, Clock_busy_mac, Clock_divider_mac); -Clock clock_main(3, Clock_inputs(Clock_none, Clock_external, Clock_pll_A), +Clock clock_main(mux_core, Clock_source_main, Clock_gate_main); -Clock clock_msc(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E), +Clock clock_msc(mux_dev, Clock_source_msc0, Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0, Clock_divider_msc0); -Clock clock_msc0(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E), +Clock clock_msc0(mux_dev, Clock_source_msc0, Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0, Clock_divider_msc0); -Clock clock_msc1(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E), +Clock clock_msc1(mux_dev, Clock_source_msc1, Clock_gate_msc1, Clock_change_enable_msc1, @@ -542,36 +574,36 @@ Clock clock_none; -Clock clock_pclock(1, Clock_inputs(Clock_ahb2_apb), +Clock clock_pclock(mux_ahb2_apb, Source_undefined, Clock_gate_apb0, Change_enable_undefined, Busy_undefined, Clock_divider_pclock); -Pll clock_pll_A(1, Clock_inputs(Clock_external), +Pll clock_pll_A(mux_external, Pll_enable_A, Pll_stable_A, Pll_bypass_A, Pll_multiplier_A, Pll_input_division_A, Pll_output_division0_A, Pll_output_division1_A); -Pll clock_pll_E(1, Clock_inputs(Clock_external), +Pll clock_pll_E(mux_external, Pll_enable_E, Pll_stable_E, Pll_bypass_E, Pll_multiplier_E, Pll_input_division_E, Pll_output_division0_E, Pll_output_division1_E); -Pll clock_pll_M(1, Clock_inputs(Clock_external), +Pll clock_pll_M(mux_external, Pll_enable_M, Pll_stable_M, Pll_bypass_M, Pll_multiplier_M, Pll_input_division_M, Pll_output_division0_M, Pll_output_division1_M); -Clock clock_pwm(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E), +Clock clock_pwm(mux_dev, Clock_source_pwm, Clock_gate_pwm, Clock_change_enable_pwm, Clock_busy_pwm, Clock_divider_pwm); -Clock clock_pwm0(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E), +Clock clock_pwm0(mux_dev, Clock_source_pwm, Clock_gate_pwm, Clock_change_enable_pwm, @@ -582,7 +614,7 @@ Clock clock_scc; -Clock clock_sfc(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E), +Clock clock_sfc(mux_dev, Clock_source_sfc, Clock_gate_sfc, Clock_change_enable_sfc, @@ -599,32 +631,22 @@ Clock clock_smb4; -Clock clock_ssi(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E), +Clock clock_ssi(mux_dev, Clock_source_ssi, Clock_gate_ssi0, Clock_change_enable_ssi, Clock_busy_ssi, Clock_divider_ssi); -Clock clock_timer(1, Clock_inputs(Clock_pclock), - Source_undefined, - Clock_gate_timer); +Clock clock_timer(mux_pclock, Source_undefined, Clock_gate_timer); -Clock clock_uart0(1, Clock_inputs(Clock_external), - Source_undefined, - Clock_gate_uart0); +Clock clock_uart0(mux_external, Source_undefined, Clock_gate_uart0); -Clock clock_uart1(1, Clock_inputs(Clock_external), - Source_undefined, - Clock_gate_uart1); +Clock clock_uart1(mux_external, Source_undefined, Clock_gate_uart1); -Clock clock_uart2(1, Clock_inputs(Clock_external), - Source_undefined, - Clock_gate_uart2); +Clock clock_uart2(mux_external, Source_undefined, Clock_gate_uart2); -Clock clock_uart3(1, Clock_inputs(Clock_external), - Source_undefined, - Clock_gate_uart3); +Clock clock_uart3(mux_external, Source_undefined, Clock_gate_uart3); Clock clock_udc; @@ -738,6 +760,19 @@ +// Clock sources. + +enum Clock_identifiers +Mux::get_input(int num) +{ + if (num < _num_inputs) + return _inputs[num]; + else + return Clock_undefined; +} + + + // Clock control. int @@ -802,22 +837,23 @@ { // Return the external clock frequency without any input clock. - if (num_inputs == 0) + if (_inputs.get_number() == 0) return regs.exclk_freq; // Clocks with one source yield that input frequency. - else if (num_inputs == 1) - return clocks[inputs[0]]->get_frequency(regs); + else if (_inputs.get_number() == 1) + return clocks[_inputs.get_input(0)]->get_frequency(regs); // With multiple sources, obtain the selected source for the clock. uint8_t source = get_source(regs); + enum Clock_identifiers input = _inputs.get_input(source); // Return the frequency of the source. - if (source < num_inputs) - return clocks[inputs[source]]->get_frequency(regs); + if (input != Clock_undefined) + return clocks[input]->get_frequency(regs); else return 0; }