1.1 --- a/pkg/devices/lib/cpm/include/cpm-common.h Sat Sep 16 16:53:06 2023 +0200
1.2 +++ b/pkg/devices/lib/cpm/include/cpm-common.h Sat Sep 16 17:56:49 2023 +0200
1.3 @@ -118,6 +118,8 @@
1.4 enum Clock_identifiers get_input(int num);
1.5 };
1.6
1.7 +
1.8 +
1.9 class Source
1.10 {
1.11 Mux _inputs;
1.12 @@ -157,6 +159,83 @@
1.13
1.14
1.15
1.16 +// Frequency transformation.
1.17 +
1.18 +class Transform
1.19 +{
1.20 +public:
1.21 +
1.22 + // Output frequency.
1.23 +
1.24 + virtual uint32_t get_frequency(Cpm_regs ®s, uint32_t source_frequency) = 0;
1.25 +};
1.26 +
1.27 +
1.28 +
1.29 +class Divider : public Transform
1.30 +{
1.31 + Field _divider;
1.32 +
1.33 +public:
1.34 + explicit Divider(Field divider)
1.35 + : _divider(divider)
1.36 + {
1.37 + }
1.38 +
1.39 + explicit Divider()
1.40 + : _divider(Field::undefined)
1.41 + {
1.42 + }
1.43 +
1.44 + // Clock divider.
1.45 +
1.46 + uint32_t get_divider(Cpm_regs ®s);
1.47 + void set_divider(Cpm_regs ®s, uint32_t division);
1.48 +
1.49 + // Output frequency.
1.50 +
1.51 + uint32_t get_frequency(Cpm_regs ®s, uint32_t source_frequency);
1.52 +
1.53 + // Undefined divider.
1.54 +
1.55 + static Divider undefined;
1.56 +};
1.57 +
1.58 +
1.59 +
1.60 +class Divider_pll : public Transform
1.61 +{
1.62 + Field _multiplier, _input_division, _output_division0, _output_division1;
1.63 +
1.64 +public:
1.65 + explicit Divider_pll(Field multiplier, Field input_division,
1.66 + Field output_division0, Field output_division1)
1.67 + : _multiplier(multiplier), _input_division(input_division),
1.68 + _output_division0(output_division0), _output_division1(output_division1)
1.69 + {
1.70 + }
1.71 +
1.72 + // General frequency modifiers.
1.73 +
1.74 + uint16_t get_multiplier(Cpm_regs ®s);
1.75 + void set_multiplier(Cpm_regs ®s, uint16_t multiplier);
1.76 + uint8_t get_input_division(Cpm_regs ®s);
1.77 + void set_input_division(Cpm_regs ®s, uint8_t divider);
1.78 + uint8_t get_output_division(Cpm_regs ®s);
1.79 + void set_output_division(Cpm_regs ®s, uint8_t divider);
1.80 +
1.81 + // Output frequency.
1.82 +
1.83 + uint32_t get_frequency(Cpm_regs ®s, uint32_t source_frequency);
1.84 +
1.85 + // Other operations.
1.86 +
1.87 + void set_pll_parameters(Cpm_regs ®s, uint16_t multiplier,
1.88 + uint8_t in_divider, uint8_t out_divider);
1.89 +};
1.90 +
1.91 +
1.92 +
1.93 // Common clock abstraction.
1.94
1.95 class Clock_base
1.96 @@ -201,17 +280,15 @@
1.97 class Pll : public Clock_base
1.98 {
1.99 Field _enable, _stable, _bypass;
1.100 - Field _multiplier, _input_division, _output_division0, _output_division1;
1.101 + Divider_pll _divider;
1.102
1.103 public:
1.104 explicit Pll(Source source,
1.105 Field enable, Field stable, Field bypass,
1.106 - Field multiplier, Field input_division,
1.107 - Field output_division0, Field output_division1)
1.108 + Divider_pll divider)
1.109 : Clock_base(source),
1.110 _enable(enable), _stable(stable), _bypass(bypass),
1.111 - _multiplier(multiplier), _input_division(input_division),
1.112 - _output_division0(output_division0), _output_division1(output_division1)
1.113 + _divider(divider)
1.114 {
1.115 }
1.116
1.117 @@ -252,7 +329,8 @@
1.118
1.119 class Clock : public Clock_base
1.120 {
1.121 - Field _gate, _change_enable, _busy, _divider;
1.122 + Field _gate, _change_enable, _busy;
1.123 + Divider _divider;
1.124
1.125 // Clock control.
1.126
1.127 @@ -265,7 +343,7 @@
1.128 Field gate = Field::undefined,
1.129 Field change_enable = Field::undefined,
1.130 Field busy = Field::undefined,
1.131 - Field divider = Field::undefined)
1.132 + Divider divider = Divider::undefined)
1.133 : Clock_base(source),
1.134 _gate(gate), _change_enable(change_enable), _busy(busy), _divider(divider)
1.135 {
1.136 @@ -285,6 +363,10 @@
1.137 // Clock source.
1.138
1.139 void set_source(Cpm_regs ®s, uint8_t source);
1.140 +
1.141 + // Output frequency.
1.142 +
1.143 + uint32_t get_frequency(Cpm_regs ®s);
1.144 };
1.145
1.146 #endif /* __cplusplus */