1.1 --- a/pkg/devices/lib/cpm/src/x1600.cc Fri Sep 15 19:29:34 2023 +0200
1.2 +++ b/pkg/devices/lib/cpm/src/x1600.cc Fri Sep 15 23:03:09 2023 +0200
1.3 @@ -83,25 +83,6 @@
1.4 Source_mask = 0x3,
1.5 };
1.6
1.7 -enum Pll_bits : unsigned
1.8 -{
1.9 - // Pll_control_A, Pll_control_M, Pll_control_E
1.10 -
1.11 - Pll_multiplier = 20, // xPLLM
1.12 - Pll_input_division = 14, // xPLLN
1.13 - Pll_output_division1 = 11, // xPLLOD1
1.14 - Pll_output_division0 = 8, // xPLLOD0
1.15 - Pll_stable = 3, // xPLL_ON
1.16 - Pll_enabled = 0, // xPLLEN
1.17 -};
1.18 -
1.19 -enum Pll_bypass_bits : unsigned
1.20 -{
1.21 - Pll_bypass_A = 30, // APLL_BP
1.22 - Pll_bypass_M = 28, // MPLL_BP
1.23 - Pll_bypass_E = 26, // EPLL_BP
1.24 -};
1.25 -
1.26
1.27
1.28 // Register field abstraction.
1.29 @@ -186,13 +167,18 @@
1.30
1.31 class Pll : public Clock_base
1.32 {
1.33 - uint32_t control_reg;
1.34 - enum Pll_bypass_bits bypass_bit;
1.35 + Field _enable, _stable, _bypass;
1.36 + Field _multiplier, _input_division, _output_division0, _output_division1;
1.37
1.38 public:
1.39 explicit Pll(int num_inputs, enum Clock_identifiers inputs[],
1.40 - uint32_t control_reg, enum Pll_bypass_bits bypass_bit)
1.41 - : Clock_base(num_inputs, inputs), control_reg(control_reg), bypass_bit(bypass_bit)
1.42 + Field enable, Field stable, Field bypass,
1.43 + Field multiplier, Field input_division,
1.44 + Field output_division0, Field output_division1)
1.45 + : Clock_base(num_inputs, inputs),
1.46 + _enable(enable), _stable(stable), _bypass(bypass),
1.47 + _multiplier(multiplier), _input_division(input_division),
1.48 + _output_division0(output_division0), _output_division1(output_division1)
1.49 {
1.50 }
1.51
1.52 @@ -273,23 +259,23 @@
1.53
1.54 // Register field definitions.
1.55
1.56 -Field Clock_source_main (Clock_control, 3, 30); // SEL_SRC (output to SCLK_A)
1.57 -Field Clock_source_cpu (Clock_control, 3, 28); // SEL_CPLL (output to CCLK)
1.58 -Field Clock_source_hclock0 (Clock_control, 3, 26); // SEL_H0PLL (output to AHB0)
1.59 -Field Clock_source_hclock2 (Clock_control, 3, 24); // SEL_H2PLL (output to AHB2)
1.60 -Field Clock_source_can0 (Divider_can0, 3, 30); // CA0CS
1.61 -Field Clock_source_can1 (Divider_can1, 3, 30); // CA1CS
1.62 -Field Clock_source_cdbus (Divider_cdbus, 3, 30); // CDCS
1.63 -Field Clock_source_cim (Divider_cim, 3, 30); // CIMPCS
1.64 -Field Clock_source_ddr (Divider_ddr, 3, 30); // DCS
1.65 -Field Clock_source_i2s (Divider0_i2s0, 1, 31); // I2PCS
1.66 -Field Clock_source_lcd (Divider_lcd, 3, 30); // LPCS
1.67 -Field Clock_source_mac (Divider_mac, 3, 30); // MACPCS
1.68 -Field Clock_source_msc0 (Divider_msc0, 3, 30); // MPCS
1.69 -Field Clock_source_msc1 (Divider_msc1, 3, 30); // MPCS
1.70 -Field Clock_source_pwm (Divider_pwm, 3, 30); // PWMPCS
1.71 -Field Clock_source_sfc (Divider_sfc, 3, 30); // SFCS
1.72 -Field Clock_source_ssi (Divider_ssi, 3, 30); // SPCS
1.73 +Field Clock_source_main (Clock_control, 3, 30); // SEL_SRC (output to SCLK_A)
1.74 +Field Clock_source_cpu (Clock_control, 3, 28); // SEL_CPLL (output to CCLK)
1.75 +Field Clock_source_hclock0 (Clock_control, 3, 26); // SEL_H0PLL (output to AHB0)
1.76 +Field Clock_source_hclock2 (Clock_control, 3, 24); // SEL_H2PLL (output to AHB2)
1.77 +Field Clock_source_can0 (Divider_can0, 3, 30); // CA0CS
1.78 +Field Clock_source_can1 (Divider_can1, 3, 30); // CA1CS
1.79 +Field Clock_source_cdbus (Divider_cdbus, 3, 30); // CDCS
1.80 +Field Clock_source_cim (Divider_cim, 3, 30); // CIMPCS
1.81 +Field Clock_source_ddr (Divider_ddr, 3, 30); // DCS
1.82 +Field Clock_source_i2s (Divider0_i2s0, 1, 31); // I2PCS
1.83 +Field Clock_source_lcd (Divider_lcd, 3, 30); // LPCS
1.84 +Field Clock_source_mac (Divider_mac, 3, 30); // MACPCS
1.85 +Field Clock_source_msc0 (Divider_msc0, 3, 30); // MPCS
1.86 +Field Clock_source_msc1 (Divider_msc1, 3, 30); // MPCS
1.87 +Field Clock_source_pwm (Divider_pwm, 3, 30); // PWMPCS
1.88 +Field Clock_source_sfc (Divider_sfc, 3, 30); // SFCS
1.89 +Field Clock_source_ssi (Divider_ssi, 3, 30); // SPCS
1.90
1.91 Field Clock_busy_cpu (Clock_status, 1, 0);
1.92 Field Clock_busy_ddr (Divider_ddr, 1, 28);
1.93 @@ -322,63 +308,91 @@
1.94 Field Clock_change_enable_can1 (Divider_can1, 1, 29);
1.95 Field Clock_change_enable_cdbus (Divider_cdbus, 1, 29);
1.96
1.97 -Field Clock_divider_can0 (Divider_can0, 0xff, 0); // CAN0CDR
1.98 -Field Clock_divider_can1 (Divider_can1, 0xff, 0); // CAN1CDR
1.99 -Field Clock_divider_cdbus (Divider_cdbus, 0xff, 0); // CDBUSCDR
1.100 -Field Clock_divider_cim (Divider_cim, 0xff, 0); // CIMCDR
1.101 -Field Clock_divider_cpu (Clock_control, 0x0f, 0); // CDIV
1.102 -Field Clock_divider_ddr (Divider_ddr, 0x0f, 0); // DDRCDR
1.103 -Field Clock_divider_hclock0 (Clock_control, 0x0f, 8); // H0DIV (fast AHB peripherals)
1.104 -Field Clock_divider_hclock2 (Clock_control, 0x0f, 12); // H2DIV (fast AHB peripherals)
1.105 -Field Clock_divider_l2cache (Clock_control, 0x0f, 4); // L2CDIV
1.106 -Field Clock_divider_lcd (Divider_lcd, 0xff, 0); // LPCDR
1.107 -Field Clock_divider_mac (Divider_mac, 0xff, 0); // MACCDR
1.108 -Field Clock_divider_msc0 (Divider_msc0, 0xff, 0); // MSC0CDR
1.109 -Field Clock_divider_msc1 (Divider_msc1, 0xff, 0); // MSC1CDR
1.110 -Field Clock_divider_pclock (Clock_control, 0x0f, 16); // PDIV (slow APB peripherals)
1.111 -Field Clock_divider_pwm (Divider_pwm, 0x0f, 0); // PWMCDR
1.112 -Field Clock_divider_sfc (Divider_sfc, 0xff, 0); // SFCCDR
1.113 -Field Clock_divider_ssi (Divider_ssi, 0xff, 0); // SSICDR
1.114 +Field Clock_divider_can0 (Divider_can0, 0xff, 0); // CAN0CDR
1.115 +Field Clock_divider_can1 (Divider_can1, 0xff, 0); // CAN1CDR
1.116 +Field Clock_divider_cdbus (Divider_cdbus, 0xff, 0); // CDBUSCDR
1.117 +Field Clock_divider_cim (Divider_cim, 0xff, 0); // CIMCDR
1.118 +Field Clock_divider_cpu (Clock_control, 0x0f, 0); // CDIV
1.119 +Field Clock_divider_ddr (Divider_ddr, 0x0f, 0); // DDRCDR
1.120 +Field Clock_divider_hclock0 (Clock_control, 0x0f, 8); // H0DIV (fast AHB peripherals)
1.121 +Field Clock_divider_hclock2 (Clock_control, 0x0f, 12); // H2DIV (fast AHB peripherals)
1.122 +Field Clock_divider_l2cache (Clock_control, 0x0f, 4); // L2CDIV
1.123 +Field Clock_divider_lcd (Divider_lcd, 0xff, 0); // LPCDR
1.124 +Field Clock_divider_mac (Divider_mac, 0xff, 0); // MACCDR
1.125 +Field Clock_divider_msc0 (Divider_msc0, 0xff, 0); // MSC0CDR
1.126 +Field Clock_divider_msc1 (Divider_msc1, 0xff, 0); // MSC1CDR
1.127 +Field Clock_divider_pclock (Clock_control, 0x0f, 16); // PDIV (slow APB peripherals)
1.128 +Field Clock_divider_pwm (Divider_pwm, 0x0f, 0); // PWMCDR
1.129 +Field Clock_divider_sfc (Divider_sfc, 0xff, 0); // SFCCDR
1.130 +Field Clock_divider_ssi (Divider_ssi, 0xff, 0); // SSICDR
1.131
1.132 -Field Clock_gate_main (Clock_control, 1, 23); // GATE_SCLKA
1.133 -Field Clock_gate_ddr (Clock_gate0, 1, 31); // DDR
1.134 -Field Clock_gate_ahb0 (Clock_gate0, 1, 29); // AHB0
1.135 -Field Clock_gate_apb0 (Clock_gate0, 1, 28); // APB0
1.136 -Field Clock_gate_rtc (Clock_gate0, 1, 27); // RTC
1.137 -Field Clock_gate_aes (Clock_gate0, 1, 24); // AES
1.138 -Field Clock_gate_lcd_pixel (Clock_gate0, 1, 23); // LCD
1.139 -Field Clock_gate_cim (Clock_gate0, 1, 22); // CIM
1.140 -Field Clock_gate_dma (Clock_gate0, 1, 21); // PDMA
1.141 -Field Clock_gate_ost (Clock_gate0, 1, 20); // OST
1.142 -Field Clock_gate_ssi0 (Clock_gate0, 1, 19); // SSI0
1.143 -Field Clock_gate_timer (Clock_gate0, 1, 18); // TCU
1.144 -Field Clock_gate_dtrng (Clock_gate0, 1, 17); // DTRNG
1.145 -Field Clock_gate_uart2 (Clock_gate0, 1, 16); // UART2
1.146 -Field Clock_gate_uart1 (Clock_gate0, 1, 15); // UART1
1.147 -Field Clock_gate_uart0 (Clock_gate0, 1, 14); // UART0
1.148 -Field Clock_gate_sadc (Clock_gate0, 1, 13); // SADC
1.149 -Field Clock_gate_audio (Clock_gate0, 1, 11); // AUDIO
1.150 -Field Clock_gate_ssi_slv (Clock_gate0, 1, 10); // SSI_SLV
1.151 -Field Clock_gate_i2c1 (Clock_gate0, 1, 8); // I2C1
1.152 -Field Clock_gate_i2c0 (Clock_gate0, 1, 7); // I2C0
1.153 -Field Clock_gate_msc1 (Clock_gate0, 1, 5); // MSC1
1.154 -Field Clock_gate_msc0 (Clock_gate0, 1, 4); // MSC0
1.155 -Field Clock_gate_otg (Clock_gate0, 1, 3); // OTG
1.156 -Field Clock_gate_sfc (Clock_gate0, 1, 2); // SFC
1.157 -Field Clock_gate_efuse (Clock_gate0, 1, 1); // EFUSE
1.158 -Field Clock_gate_nemc (Clock_gate0, 1, 0); // NEMC
1.159 -Field Clock_gate_arb (Clock_gate1, 1, 30); // ARB
1.160 -Field Clock_gate_mipi_csi (Clock_gate1, 1, 28); // MIPI_CSI
1.161 -Field Clock_gate_intc (Clock_gate1, 1, 26); // INTC
1.162 -Field Clock_gate_gmac0 (Clock_gate1, 1, 23); // GMAC0
1.163 -Field Clock_gate_uart3 (Clock_gate1, 1, 16); // UART3
1.164 -Field Clock_gate_i2s0_tx (Clock_gate1, 1, 9); // I2S0_dev_tclk
1.165 -Field Clock_gate_i2s0_rx (Clock_gate1, 1, 8); // I2S0_dev_rclk
1.166 -Field Clock_gate_hash (Clock_gate1, 1, 6); // HASH
1.167 -Field Clock_gate_pwm (Clock_gate1, 1, 5); // PWM
1.168 -Field Clock_gate_cdbus (Clock_gate1, 1, 2); // CDBUS
1.169 -Field Clock_gate_can1 (Clock_gate1, 1, 1); // CAN1
1.170 -Field Clock_gate_can0 (Clock_gate1, 1, 0); // CAN0
1.171 +Field Clock_gate_main (Clock_control, 1, 23); // GATE_SCLKA
1.172 +Field Clock_gate_ddr (Clock_gate0, 1, 31); // DDR
1.173 +Field Clock_gate_ahb0 (Clock_gate0, 1, 29); // AHB0
1.174 +Field Clock_gate_apb0 (Clock_gate0, 1, 28); // APB0
1.175 +Field Clock_gate_rtc (Clock_gate0, 1, 27); // RTC
1.176 +Field Clock_gate_aes (Clock_gate0, 1, 24); // AES
1.177 +Field Clock_gate_lcd_pixel (Clock_gate0, 1, 23); // LCD
1.178 +Field Clock_gate_cim (Clock_gate0, 1, 22); // CIM
1.179 +Field Clock_gate_dma (Clock_gate0, 1, 21); // PDMA
1.180 +Field Clock_gate_ost (Clock_gate0, 1, 20); // OST
1.181 +Field Clock_gate_ssi0 (Clock_gate0, 1, 19); // SSI0
1.182 +Field Clock_gate_timer (Clock_gate0, 1, 18); // TCU
1.183 +Field Clock_gate_dtrng (Clock_gate0, 1, 17); // DTRNG
1.184 +Field Clock_gate_uart2 (Clock_gate0, 1, 16); // UART2
1.185 +Field Clock_gate_uart1 (Clock_gate0, 1, 15); // UART1
1.186 +Field Clock_gate_uart0 (Clock_gate0, 1, 14); // UART0
1.187 +Field Clock_gate_sadc (Clock_gate0, 1, 13); // SADC
1.188 +Field Clock_gate_audio (Clock_gate0, 1, 11); // AUDIO
1.189 +Field Clock_gate_ssi_slv (Clock_gate0, 1, 10); // SSI_SLV
1.190 +Field Clock_gate_i2c1 (Clock_gate0, 1, 8); // I2C1
1.191 +Field Clock_gate_i2c0 (Clock_gate0, 1, 7); // I2C0
1.192 +Field Clock_gate_msc1 (Clock_gate0, 1, 5); // MSC1
1.193 +Field Clock_gate_msc0 (Clock_gate0, 1, 4); // MSC0
1.194 +Field Clock_gate_otg (Clock_gate0, 1, 3); // OTG
1.195 +Field Clock_gate_sfc (Clock_gate0, 1, 2); // SFC
1.196 +Field Clock_gate_efuse (Clock_gate0, 1, 1); // EFUSE
1.197 +Field Clock_gate_nemc (Clock_gate0, 1, 0); // NEMC
1.198 +Field Clock_gate_arb (Clock_gate1, 1, 30); // ARB
1.199 +Field Clock_gate_mipi_csi (Clock_gate1, 1, 28); // MIPI_CSI
1.200 +Field Clock_gate_intc (Clock_gate1, 1, 26); // INTC
1.201 +Field Clock_gate_gmac0 (Clock_gate1, 1, 23); // GMAC0
1.202 +Field Clock_gate_uart3 (Clock_gate1, 1, 16); // UART3
1.203 +Field Clock_gate_i2s0_tx (Clock_gate1, 1, 9); // I2S0_dev_tclk
1.204 +Field Clock_gate_i2s0_rx (Clock_gate1, 1, 8); // I2S0_dev_rclk
1.205 +Field Clock_gate_hash (Clock_gate1, 1, 6); // HASH
1.206 +Field Clock_gate_pwm (Clock_gate1, 1, 5); // PWM
1.207 +Field Clock_gate_cdbus (Clock_gate1, 1, 2); // CDBUS
1.208 +Field Clock_gate_can1 (Clock_gate1, 1, 1); // CAN1
1.209 +Field Clock_gate_can0 (Clock_gate1, 1, 0); // CAN0
1.210 +
1.211 +Field Pll_enable_A (Pll_control_A, 1, 0); // APLLEN
1.212 +Field Pll_enable_E (Pll_control_E, 1, 0); // EPLLEN
1.213 +Field Pll_enable_M (Pll_control_M, 1, 0); // MPLLEN
1.214 +
1.215 +Field Pll_stable_A (Pll_control_A, 1, 3); // APLL_ON
1.216 +Field Pll_stable_E (Pll_control_E, 1, 3); // EPLL_ON
1.217 +Field Pll_stable_M (Pll_control_M, 1, 3); // MPLL_ON
1.218 +
1.219 +Field Pll_bypass_A (Pll_control_A, 1, 30); // APLL_BP
1.220 +Field Pll_bypass_E (Pll_control_E, 1, 26); // EPLL_BP
1.221 +Field Pll_bypass_M (Pll_control_M, 1, 28); // MPLL_BP
1.222 +
1.223 +Field Pll_multiplier_A (Pll_control_A, 0x1fff, 20); // APLLM
1.224 +Field Pll_multiplier_E (Pll_control_E, 0x1fff, 20); // EPLLM
1.225 +Field Pll_multiplier_M (Pll_control_M, 0x1fff, 20); // MPLLM
1.226 +
1.227 +Field Pll_input_division_A (Pll_control_A, 0x3f, 14); // APLLN
1.228 +Field Pll_input_division_E (Pll_control_E, 0x3f, 14); // EPLLN
1.229 +Field Pll_input_division_M (Pll_control_M, 0x3f, 14); // MPLLN
1.230 +
1.231 +Field Pll_output_division1_A (Pll_control_A, 0x07, 11); // APLLOD1
1.232 +Field Pll_output_division1_E (Pll_control_E, 0x07, 11); // EPLLOD1
1.233 +Field Pll_output_division1_M (Pll_control_M, 0x07, 11); // MPLLOD1
1.234 +
1.235 +Field Pll_output_division0_A (Pll_control_A, 0x07, 8); // APLLOD0
1.236 +Field Pll_output_division0_E (Pll_control_E, 0x07, 8); // EPLLOD0
1.237 +Field Pll_output_division0_M (Pll_control_M, 0x07, 8); // MPLLOD0
1.238
1.239
1.240
1.241 @@ -536,13 +550,19 @@
1.242 Clock_divider_pclock);
1.243
1.244 Pll clock_pll_A(1, Clock_inputs(Clock_external),
1.245 - Pll_control_A, Pll_bypass_A);
1.246 + Pll_enable_A, Pll_stable_A, Pll_bypass_A,
1.247 + Pll_multiplier_A, Pll_input_division_A,
1.248 + Pll_output_division0_A, Pll_output_division1_A);
1.249
1.250 Pll clock_pll_E(1, Clock_inputs(Clock_external),
1.251 - Pll_control_E, Pll_bypass_E);
1.252 + Pll_enable_E, Pll_stable_E, Pll_bypass_E,
1.253 + Pll_multiplier_E, Pll_input_division_E,
1.254 + Pll_output_division0_E, Pll_output_division1_E);
1.255
1.256 Pll clock_pll_M(1, Clock_inputs(Clock_external),
1.257 - Pll_control_M, Pll_bypass_M);
1.258 + Pll_enable_M, Pll_stable_M, Pll_bypass_M,
1.259 + Pll_multiplier_M, Pll_input_division_M,
1.260 + Pll_output_division0_M, Pll_output_division1_M);
1.261
1.262 Clock clock_pwm(3, Clock_inputs(Clock_main, Clock_pll_M, Clock_pll_E),
1.263 Clock_source_pwm,
1.264 @@ -817,19 +837,19 @@
1.265 int
1.266 Pll::have_pll(Cpm_regs ®s)
1.267 {
1.268 - return regs.get_field(control_reg, 1, Pll_stable);
1.269 + return _stable.get_field(regs);
1.270 }
1.271
1.272 int
1.273 Pll::pll_enabled(Cpm_regs ®s)
1.274 {
1.275 - return regs.get_field(control_reg, 1, Pll_enabled);
1.276 + return _enable.get_field(regs);
1.277 }
1.278
1.279 int
1.280 Pll::pll_bypassed(Cpm_regs ®s)
1.281 {
1.282 - return regs.get_field(control_reg, 1, bypass_bit);
1.283 + return _bypass.get_field(regs);
1.284 }
1.285
1.286 // Clock control.
1.287 @@ -843,14 +863,14 @@
1.288 void
1.289 Pll::start_clock(Cpm_regs ®s)
1.290 {
1.291 - regs.set_field(control_reg, 1, Pll_enabled, 1);
1.292 + _enable.set_field(regs, 1);
1.293 while (!have_pll(regs));
1.294 }
1.295
1.296 void
1.297 Pll::stop_clock(Cpm_regs ®s)
1.298 {
1.299 - regs.set_field(control_reg, 1, Pll_enabled, 0);
1.300 + _enable.set_field(regs, 0);
1.301 while (have_pll(regs));
1.302 }
1.303
1.304 @@ -859,13 +879,13 @@
1.305 uint16_t
1.306 Pll::get_multiplier(Cpm_regs ®s)
1.307 {
1.308 - return regs.get_field(control_reg, 0x1fff, Pll_multiplier) + 1;
1.309 + return _multiplier.get_field(regs) + 1;
1.310 }
1.311
1.312 void
1.313 Pll::set_multiplier(Cpm_regs ®s, uint16_t multiplier)
1.314 {
1.315 - regs.set_field(control_reg, 0x1fff, Pll_multiplier, multiplier - 1);
1.316 + _multiplier.set_field(regs, multiplier - 1);
1.317 }
1.318
1.319 // Input (6-bit) divider.
1.320 @@ -873,13 +893,13 @@
1.321 uint8_t
1.322 Pll::get_input_division(Cpm_regs ®s)
1.323 {
1.324 - return regs.get_field(control_reg, 0x3f, Pll_input_division) + 1;
1.325 + return _input_division.get_field(regs) + 1;
1.326 }
1.327
1.328 void
1.329 Pll::set_input_division(Cpm_regs ®s, uint8_t divider)
1.330 {
1.331 - regs.set_field(control_reg, 0x3f, Pll_input_division, divider - 1);
1.332 + _input_division.set_field(regs, divider - 1);
1.333 }
1.334
1.335 // Output (dual 3-bit) dividers.
1.336 @@ -887,8 +907,8 @@
1.337 uint8_t
1.338 Pll::get_output_division(Cpm_regs ®s)
1.339 {
1.340 - uint8_t d0 = regs.get_field(control_reg, 0x07, Pll_output_division0);
1.341 - uint8_t d1 = regs.get_field(control_reg, 0x07, Pll_output_division1);
1.342 + uint8_t d0 = _output_division0.get_field(regs);
1.343 + uint8_t d1 = _output_division1.get_field(regs);
1.344
1.345 return d0 * d1;
1.346 }
1.347 @@ -902,8 +922,8 @@
1.348 uint8_t d0 = (uint8_t) floor(sqrt(divider ? divider : 1));
1.349 uint8_t d1 = divider / d0;
1.350
1.351 - regs.set_field(control_reg, 0x07, Pll_output_division0, d0);
1.352 - regs.set_field(control_reg, 0x07, Pll_output_division1, d1);
1.353 + _output_division0.set_field(regs, d0);
1.354 + _output_division1.set_field(regs, d1);
1.355 }
1.356
1.357 uint32_t