1.1 --- a/pkg/devices/lib/cpm/include/cpm-common.h Sun Sep 17 19:20:18 2023 +0200
1.2 +++ b/pkg/devices/lib/cpm/include/cpm-common.h Sun Sep 17 21:36:19 2023 +0200
1.3 @@ -255,6 +255,12 @@
1.4 // Output frequency.
1.5
1.6 virtual uint32_t get_frequency(Cpm_regs ®s, uint32_t source_frequency) = 0;
1.7 +
1.8 + // Other operations.
1.9 +
1.10 + virtual int get_parameters(Cpm_regs ®s, uint32_t parameters[]) = 0;
1.11 +
1.12 + virtual void set_parameters(Cpm_regs ®s, uint32_t parameters[]) = 0;
1.13 };
1.14
1.15
1.16 @@ -285,6 +291,12 @@
1.17
1.18 uint32_t get_frequency(Cpm_regs ®s, uint32_t source_frequency);
1.19
1.20 + // Other operations.
1.21 +
1.22 + int get_parameters(Cpm_regs ®s, uint32_t parameters[]);
1.23 +
1.24 + void set_parameters(Cpm_regs ®s, uint32_t parameters[]);
1.25 +
1.26 // Undefined divider.
1.27
1.28 static Divider undefined;
1.29 @@ -321,8 +333,9 @@
1.30
1.31 // Other operations.
1.32
1.33 - void set_parameters(Cpm_regs ®s, uint32_t multiplier,
1.34 - uint32_t in_divider, uint32_t out_divider);
1.35 + int get_parameters(Cpm_regs ®s, uint32_t parameters[]);
1.36 +
1.37 + void set_parameters(Cpm_regs ®s, uint32_t parameters[]);
1.38 };
1.39
1.40
1.41 @@ -353,8 +366,9 @@
1.42
1.43 // Other operations.
1.44
1.45 - void set_parameters(Cpm_regs ®s, uint32_t multiplier,
1.46 - uint32_t divider_N, uint32_t divider_D);
1.47 + int get_parameters(Cpm_regs ®s, uint32_t parameters[]);
1.48 +
1.49 + void set_parameters(Cpm_regs ®s, uint32_t parameters[]);
1.50 };
1.51
1.52
1.53 @@ -480,6 +494,10 @@
1.54
1.55 virtual ~Clock_divided();
1.56
1.57 + virtual int get_parameters(Cpm_regs ®s, uint32_t parameters[]);
1.58 +
1.59 + virtual void set_parameters(Cpm_regs ®s, uint32_t parameters[]);
1.60 +
1.61 // Output frequency.
1.62
1.63 uint32_t get_frequency(Cpm_regs ®s);
1.64 @@ -521,11 +539,6 @@
1.65 // Output frequency.
1.66
1.67 uint32_t get_frequency(Cpm_regs ®s);
1.68 -
1.69 - // Other operations.
1.70 -
1.71 - void set_parameters(Cpm_regs ®s, uint32_t multiplier,
1.72 - uint32_t in_divider, uint32_t out_divider);
1.73 };
1.74
1.75
2.1 --- a/pkg/devices/lib/cpm/include/cpm-x1600.h Sun Sep 17 19:20:18 2023 +0200
2.2 +++ b/pkg/devices/lib/cpm/include/cpm-x1600.h Sun Sep 17 21:36:19 2023 +0200
2.3 @@ -54,8 +54,8 @@
2.4
2.5 // Clock dividers.
2.6
2.7 - uint32_t get_divider(enum Clock_identifiers clock);
2.8 - void set_divider(enum Clock_identifiers clock, uint32_t divider);
2.9 + int get_parameters(enum Clock_identifiers clock, uint32_t parameters[]);
2.10 + void set_parameters(enum Clock_identifiers clock, uint32_t parameters[]);
2.11
2.12 // Clock sources.
2.13
2.14 @@ -70,11 +70,6 @@
2.15
2.16 uint32_t get_frequency(enum Clock_identifiers clock);
2.17 void set_frequency(enum Clock_identifiers clock, uint32_t frequency);
2.18 -
2.19 - // Other operations.
2.20 -
2.21 - void set_pll_parameters(enum Clock_identifiers clock, uint16_t multiplier,
2.22 - uint8_t in_divider, uint8_t out_divider);
2.23 };
2.24
2.25 #endif /* __cplusplus */
2.26 @@ -93,8 +88,8 @@
2.27 void x1600_cpm_start_clock(void *cpm, enum Clock_identifiers clock);
2.28 void x1600_cpm_stop_clock(void *cpm, enum Clock_identifiers clock);
2.29
2.30 -uint32_t x1600_cpm_get_divider(void *cpm, enum Clock_identifiers clock);
2.31 -void x1600_cpm_set_divider(void *cpm, enum Clock_identifiers clock, uint32_t divider);
2.32 +int x1600_cpm_get_parameters(void *cpm, enum Clock_identifiers clock, uint32_t parameters[]);
2.33 +void x1600_cpm_set_parameters(void *cpm, enum Clock_identifiers clock, uint32_t parameters[]);
2.34
2.35 uint8_t x1600_cpm_get_source(void *cpm, enum Clock_identifiers clock);
2.36 void x1600_cpm_set_source(void *cpm, enum Clock_identifiers clock, uint8_t source);
2.37 @@ -104,6 +99,4 @@
2.38 uint32_t x1600_cpm_get_frequency(void *cpm, enum Clock_identifiers clock);
2.39 void x1600_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency);
2.40
2.41 -void x1600_cpm_set_mpll_parameters(void *cpm, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider);
2.42 -
2.43 EXTERN_C_END
3.1 --- a/pkg/devices/lib/cpm/src/common.cc Sun Sep 17 19:20:18 2023 +0200
3.2 +++ b/pkg/devices/lib/cpm/src/common.cc Sun Sep 17 21:36:19 2023 +0200
3.3 @@ -292,6 +292,19 @@
3.4 return source_frequency / get_divider(regs);
3.5 }
3.6
3.7 +int
3.8 +Divider::get_parameters(Cpm_regs ®s, uint32_t parameters[])
3.9 +{
3.10 + parameters[0] = get_divider(regs);
3.11 + return 1;
3.12 +}
3.13 +
3.14 +void
3.15 +Divider::set_parameters(Cpm_regs ®s, uint32_t parameters[])
3.16 +{
3.17 + set_divider(regs, parameters[0]);
3.18 +}
3.19 +
3.20 // Undefined divider.
3.21
3.22 Divider Divider::undefined;
3.23 @@ -357,13 +370,21 @@
3.24 (get_input_divider(regs) * get_output_divider(regs));
3.25 }
3.26
3.27 -void
3.28 -Divider_pll::set_parameters(Cpm_regs ®s, uint32_t multiplier,
3.29 - uint32_t in_divider, uint32_t out_divider)
3.30 +int
3.31 +Divider_pll::get_parameters(Cpm_regs ®s, uint32_t parameters[])
3.32 {
3.33 - set_multiplier(regs, multiplier);
3.34 - set_input_divider(regs, in_divider);
3.35 - set_output_divider(regs, out_divider);
3.36 + parameters[0] = get_multiplier(regs);
3.37 + parameters[1] = get_input_divider(regs);
3.38 + parameters[2] = get_output_divider(regs);
3.39 + return 3;
3.40 +}
3.41 +
3.42 +void
3.43 +Divider_pll::set_parameters(Cpm_regs ®s, uint32_t parameters[])
3.44 +{
3.45 + set_multiplier(regs, parameters[0]);
3.46 + set_input_divider(regs, parameters[1]);
3.47 + set_output_divider(regs, parameters[2]);
3.48 }
3.49
3.50
3.51 @@ -377,34 +398,44 @@
3.52 }
3.53
3.54 uint32_t
3.55 +Divider_i2s::get_divider_N(Cpm_regs ®s)
3.56 +{
3.57 + return _divider_N.get_field(regs);
3.58 +}
3.59 +
3.60 +uint32_t
3.61 Divider_i2s::get_divider_D(Cpm_regs ®s)
3.62 {
3.63 return _divider_D.get_field(regs);
3.64 }
3.65
3.66 uint32_t
3.67 -Divider_i2s::get_divider_N(Cpm_regs ®s)
3.68 -{
3.69 - return _divider_N.get_field(regs);
3.70 -}
3.71 -
3.72 -uint32_t
3.73 Divider_i2s::get_frequency(Cpm_regs ®s, uint32_t source_frequency)
3.74 {
3.75 return (source_frequency * get_multiplier(regs)) /
3.76 (get_divider_N(regs) * get_divider_D(regs));
3.77 }
3.78
3.79 +int
3.80 +Divider_i2s::get_parameters(Cpm_regs ®s, uint32_t parameters[])
3.81 +{
3.82 + parameters[0] = get_multiplier(regs);
3.83 + parameters[1] = get_divider_N(regs);
3.84 + parameters[2] = get_divider_D(regs);
3.85 + return 3;
3.86 +}
3.87 +
3.88 void
3.89 -Divider_i2s::set_parameters(Cpm_regs ®s, uint32_t multiplier,
3.90 - uint32_t divider_N, uint32_t divider_D)
3.91 +Divider_i2s::set_parameters(Cpm_regs ®s, uint32_t parameters[])
3.92 {
3.93 - if (divider_N < 2 * multiplier)
3.94 + // Test for N < 2M.
3.95 +
3.96 + if (parameters[1] < 2 * parameters[0] )
3.97 return;
3.98
3.99 - _multiplier.set_field(regs, multiplier);
3.100 - _divider_N.set_field(regs, divider_N);
3.101 - _divider_D.set_field(regs, divider_D);
3.102 + _multiplier.set_field(regs, parameters[0]);
3.103 + _divider_N.set_field(regs, parameters[1]);
3.104 + _divider_D.set_field(regs, parameters[2]);
3.105 }
3.106
3.107
3.108 @@ -557,6 +588,19 @@
3.109 return _get_divider().get_frequency(regs, get_source_frequency(regs));
3.110 }
3.111
3.112 +int
3.113 +Clock_divided::get_parameters(Cpm_regs ®s, uint32_t parameters[])
3.114 +{
3.115 + return _get_divider().get_parameters(regs, parameters);
3.116 +}
3.117 +
3.118 +void
3.119 +Clock_divided::set_parameters(Cpm_regs ®s, uint32_t parameters[])
3.120 +{
3.121 + _get_divider().set_parameters(regs, parameters);
3.122 + _get_control().wait_busy(regs);
3.123 +}
3.124 +
3.125
3.126
3.127 // PLL boilerplate.
3.128 @@ -621,14 +665,6 @@
3.129 return 0;
3.130 }
3.131
3.132 -void
3.133 -Pll::set_parameters(Cpm_regs ®s, uint32_t multiplier,
3.134 - uint32_t in_divider, uint32_t out_divider)
3.135 -{
3.136 - _divider.set_parameters(regs, multiplier, in_divider, out_divider);
3.137 - _control.wait_busy(regs);
3.138 -}
3.139 -
3.140
3.141
3.142 // Clock dividers.
4.1 --- a/pkg/devices/lib/cpm/src/x1600.cc Sun Sep 17 19:20:18 2023 +0200
4.2 +++ b/pkg/devices/lib/cpm/src/x1600.cc Sun Sep 17 21:36:19 2023 +0200
4.3 @@ -470,24 +470,24 @@
4.4 clocks[clock]->stop_clock(_cpm_regs);
4.5 }
4.6
4.7 -uint32_t
4.8 -Cpm_x1600_chip::get_divider(enum Clock_identifiers clock)
4.9 +int
4.10 +Cpm_x1600_chip::get_parameters(enum Clock_identifiers clock, uint32_t parameters[])
4.11 {
4.12 - Clock *clk = dynamic_cast<Clock *>(clocks[clock]);
4.13 + Clock_divided *clk = dynamic_cast<Clock_divided *>(clocks[clock]);
4.14
4.15 if (clk != NULL)
4.16 - return clk->get_divider(_cpm_regs);
4.17 + return clk->get_parameters(_cpm_regs, parameters);
4.18 else
4.19 - return 1;
4.20 + return 0;
4.21 }
4.22
4.23 void
4.24 -Cpm_x1600_chip::set_divider(enum Clock_identifiers clock, uint32_t division)
4.25 +Cpm_x1600_chip::set_parameters(enum Clock_identifiers clock, uint32_t parameters[])
4.26 {
4.27 - Clock *clk = dynamic_cast<Clock *>(clocks[clock]);
4.28 + Clock_divided *clk = dynamic_cast<Clock_divided *>(clocks[clock]);
4.29
4.30 if (clk != NULL)
4.31 - clk->set_divider(_cpm_regs, division);
4.32 + clk->set_parameters(_cpm_regs, parameters);
4.33 }
4.34
4.35 uint8_t
4.36 @@ -545,9 +545,11 @@
4.37
4.38 if (lcd != NULL)
4.39 {
4.40 + uint32_t parameters[] = {lcd->get_source_frequency(_cpm_regs) / frequency};
4.41 +
4.42 lcd->set_source(_cpm_regs, Source_mME_pll_M);
4.43 pll->start_clock(_cpm_regs);
4.44 - lcd->set_divider(_cpm_regs, lcd->get_source_frequency(_cpm_regs) / frequency);
4.45 + lcd->set_parameters(_cpm_regs, parameters);
4.46 }
4.47 break;
4.48 }
4.49 @@ -557,16 +559,6 @@
4.50 }
4.51 }
4.52
4.53 -void
4.54 -Cpm_x1600_chip::set_pll_parameters(enum Clock_identifiers clock, uint16_t multiplier,
4.55 - uint8_t in_divider, uint8_t out_divider)
4.56 -{
4.57 - Pll *pll = dynamic_cast<Pll *>(clocks[clock]);
4.58 -
4.59 - if (pll != NULL)
4.60 - pll->set_parameters(_cpm_regs, multiplier, in_divider, out_divider);
4.61 -}
4.62 -
4.63
4.64
4.65 // C language interface functions.
4.66 @@ -604,16 +596,16 @@
4.67 static_cast<Cpm_x1600_chip *>(cpm)->stop_clock(clock);
4.68 }
4.69
4.70 -uint32_t
4.71 -x1600_cpm_get_divider(void *cpm, enum Clock_identifiers clock)
4.72 +int
4.73 +x1600_cpm_get_parameters(void *cpm, enum Clock_identifiers clock, uint32_t parameters[])
4.74 {
4.75 - return static_cast<Cpm_x1600_chip *>(cpm)->get_divider(clock);
4.76 + return static_cast<Cpm_x1600_chip *>(cpm)->get_parameters(clock, parameters);
4.77 }
4.78
4.79 void
4.80 -x1600_cpm_set_divider(void *cpm, enum Clock_identifiers clock, uint32_t divider)
4.81 +x1600_cpm_set_parameters(void *cpm, enum Clock_identifiers clock, uint32_t parameters[])
4.82 {
4.83 - return static_cast<Cpm_x1600_chip *>(cpm)->set_divider(clock, divider);
4.84 + return static_cast<Cpm_x1600_chip *>(cpm)->set_parameters(clock, parameters);
4.85 }
4.86
4.87 uint8_t
4.88 @@ -645,9 +637,3 @@
4.89 {
4.90 static_cast<Cpm_x1600_chip *>(cpm)->set_frequency(clock, frequency);
4.91 }
4.92 -
4.93 -void
4.94 -x1600_cpm_set_mpll_parameters(void *cpm, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider)
4.95 -{
4.96 - static_cast<Cpm_x1600_chip *>(cpm)->set_pll_parameters(Clock_pll_M, multiplier, in_divider, out_divider);
4.97 -}