# HG changeset patch # User Paul Boddie # Date 1694811789 -7200 # Node ID e497c64050c41b93ec9eeffa2deda0c6c57ba134 # Parent b876c7d44aaa34a87b867e82c4630bc12dca8470 Introduced field abstractions to the PLLs. diff -r b876c7d44aaa -r e497c64050c4 pkg/devices/lib/cpm/src/x1600.cc --- a/pkg/devices/lib/cpm/src/x1600.cc Fri Sep 15 19:29:34 2023 +0200 +++ b/pkg/devices/lib/cpm/src/x1600.cc Fri Sep 15 23:03:09 2023 +0200 @@ -83,25 +83,6 @@ Source_mask = 0x3, }; -enum Pll_bits : unsigned -{ - // Pll_control_A, Pll_control_M, Pll_control_E - - Pll_multiplier = 20, // xPLLM - Pll_input_division = 14, // xPLLN - Pll_output_division1 = 11, // xPLLOD1 - Pll_output_division0 = 8, // xPLLOD0 - Pll_stable = 3, // xPLL_ON - Pll_enabled = 0, // xPLLEN -}; - -enum Pll_bypass_bits : unsigned -{ - Pll_bypass_A = 30, // APLL_BP - Pll_bypass_M = 28, // MPLL_BP - Pll_bypass_E = 26, // EPLL_BP -}; - // Register field abstraction. @@ -186,13 +167,18 @@ class Pll : public Clock_base { - uint32_t control_reg; - enum Pll_bypass_bits bypass_bit; + Field _enable, _stable, _bypass; + Field _multiplier, _input_division, _output_division0, _output_division1; public: explicit Pll(int num_inputs, enum Clock_identifiers inputs[], - uint32_t control_reg, enum Pll_bypass_bits bypass_bit) - : Clock_base(num_inputs, inputs), control_reg(control_reg), bypass_bit(bypass_bit) + Field enable, Field stable, Field bypass, + Field multiplier, Field input_division, + Field output_division0, Field output_division1) + : Clock_base(num_inputs, inputs), + _enable(enable), _stable(stable), _bypass(bypass), + _multiplier(multiplier), _input_division(input_division), + _output_division0(output_division0), _output_division1(output_division1) { } @@ -273,23 +259,23 @@ // Register field definitions. -Field Clock_source_main (Clock_control, 3, 30); // SEL_SRC (output to SCLK_A) -Field Clock_source_cpu (Clock_control, 3, 28); // SEL_CPLL (output to CCLK) -Field Clock_source_hclock0 (Clock_control, 3, 26); // SEL_H0PLL (output to AHB0) -Field Clock_source_hclock2 (Clock_control, 3, 24); // SEL_H2PLL (output to AHB2) -Field Clock_source_can0 (Divider_can0, 3, 30); // CA0CS -Field Clock_source_can1 (Divider_can1, 3, 30); // CA1CS -Field Clock_source_cdbus (Divider_cdbus, 3, 30); // CDCS -Field Clock_source_cim (Divider_cim, 3, 30); // CIMPCS -Field Clock_source_ddr (Divider_ddr, 3, 30); // DCS -Field Clock_source_i2s (Divider0_i2s0, 1, 31); // I2PCS -Field Clock_source_lcd (Divider_lcd, 3, 30); // LPCS -Field Clock_source_mac (Divider_mac, 3, 30); // MACPCS -Field Clock_source_msc0 (Divider_msc0, 3, 30); // MPCS -Field Clock_source_msc1 (Divider_msc1, 3, 30); // MPCS -Field Clock_source_pwm (Divider_pwm, 3, 30); // PWMPCS -Field Clock_source_sfc (Divider_sfc, 3, 30); // SFCS -Field Clock_source_ssi (Divider_ssi, 3, 30); // SPCS +Field Clock_source_main (Clock_control, 3, 30); // SEL_SRC (output to SCLK_A) +Field Clock_source_cpu (Clock_control, 3, 28); // SEL_CPLL (output to CCLK) +Field Clock_source_hclock0 (Clock_control, 3, 26); // SEL_H0PLL (output to AHB0) +Field Clock_source_hclock2 (Clock_control, 3, 24); // SEL_H2PLL (output to AHB2) +Field Clock_source_can0 (Divider_can0, 3, 30); // CA0CS +Field Clock_source_can1 (Divider_can1, 3, 30); // CA1CS +Field Clock_source_cdbus (Divider_cdbus, 3, 30); // CDCS +Field Clock_source_cim (Divider_cim, 3, 30); // CIMPCS +Field Clock_source_ddr (Divider_ddr, 3, 30); // DCS +Field Clock_source_i2s (Divider0_i2s0, 1, 31); // I2PCS +Field Clock_source_lcd (Divider_lcd, 3, 30); // LPCS +Field Clock_source_mac (Divider_mac, 3, 30); // MACPCS +Field Clock_source_msc0 (Divider_msc0, 3, 30); // MPCS +Field Clock_source_msc1 (Divider_msc1, 3, 30); // MPCS +Field Clock_source_pwm (Divider_pwm, 3, 30); // PWMPCS +Field Clock_source_sfc (Divider_sfc, 3, 30); // SFCS +Field Clock_source_ssi (Divider_ssi, 3, 30); // SPCS Field Clock_busy_cpu (Clock_status, 1, 0); Field Clock_busy_ddr (Divider_ddr, 1, 28); @@ -322,63 +308,91 @@ Field Clock_change_enable_can1 (Divider_can1, 1, 29); Field Clock_change_enable_cdbus (Divider_cdbus, 1, 29); -Field Clock_divider_can0 (Divider_can0, 0xff, 0); // CAN0CDR -Field Clock_divider_can1 (Divider_can1, 0xff, 0); // CAN1CDR -Field Clock_divider_cdbus (Divider_cdbus, 0xff, 0); // CDBUSCDR -Field Clock_divider_cim (Divider_cim, 0xff, 0); // CIMCDR -Field Clock_divider_cpu (Clock_control, 0x0f, 0); // CDIV -Field Clock_divider_ddr (Divider_ddr, 0x0f, 0); // DDRCDR -Field Clock_divider_hclock0 (Clock_control, 0x0f, 8); // H0DIV (fast AHB peripherals) -Field Clock_divider_hclock2 (Clock_control, 0x0f, 12); // H2DIV (fast AHB peripherals) -Field Clock_divider_l2cache (Clock_control, 0x0f, 4); // L2CDIV -Field Clock_divider_lcd (Divider_lcd, 0xff, 0); // LPCDR -Field Clock_divider_mac (Divider_mac, 0xff, 0); // MACCDR -Field Clock_divider_msc0 (Divider_msc0, 0xff, 0); // MSC0CDR -Field Clock_divider_msc1 (Divider_msc1, 0xff, 0); // MSC1CDR -Field Clock_divider_pclock (Clock_control, 0x0f, 16); // PDIV (slow APB peripherals) -Field Clock_divider_pwm (Divider_pwm, 0x0f, 0); // PWMCDR -Field Clock_divider_sfc (Divider_sfc, 0xff, 0); // SFCCDR -Field Clock_divider_ssi (Divider_ssi, 0xff, 0); // SSICDR +Field Clock_divider_can0 (Divider_can0, 0xff, 0); // CAN0CDR +Field Clock_divider_can1 (Divider_can1, 0xff, 0); // CAN1CDR +Field Clock_divider_cdbus (Divider_cdbus, 0xff, 0); // CDBUSCDR +Field Clock_divider_cim (Divider_cim, 0xff, 0); // CIMCDR +Field Clock_divider_cpu (Clock_control, 0x0f, 0); // CDIV +Field Clock_divider_ddr (Divider_ddr, 0x0f, 0); // DDRCDR +Field Clock_divider_hclock0 (Clock_control, 0x0f, 8); // H0DIV (fast AHB peripherals) +Field Clock_divider_hclock2 (Clock_control, 0x0f, 12); // H2DIV (fast AHB peripherals) +Field Clock_divider_l2cache (Clock_control, 0x0f, 4); // L2CDIV +Field Clock_divider_lcd (Divider_lcd, 0xff, 0); // LPCDR +Field Clock_divider_mac (Divider_mac, 0xff, 0); // MACCDR +Field Clock_divider_msc0 (Divider_msc0, 0xff, 0); // MSC0CDR +Field Clock_divider_msc1 (Divider_msc1, 0xff, 0); // MSC1CDR +Field Clock_divider_pclock (Clock_control, 0x0f, 16); // PDIV (slow APB peripherals) +Field Clock_divider_pwm (Divider_pwm, 0x0f, 0); // PWMCDR +Field Clock_divider_sfc (Divider_sfc, 0xff, 0); // SFCCDR +Field Clock_divider_ssi (Divider_ssi, 0xff, 0); // SSICDR -Field Clock_gate_main (Clock_control, 1, 23); // GATE_SCLKA -Field Clock_gate_ddr (Clock_gate0, 1, 31); // DDR -Field Clock_gate_ahb0 (Clock_gate0, 1, 29); // AHB0 -Field Clock_gate_apb0 (Clock_gate0, 1, 28); // APB0 -Field Clock_gate_rtc (Clock_gate0, 1, 27); // RTC -Field Clock_gate_aes (Clock_gate0, 1, 24); // AES -Field Clock_gate_lcd_pixel (Clock_gate0, 1, 23); // LCD -Field Clock_gate_cim (Clock_gate0, 1, 22); // CIM -Field Clock_gate_dma (Clock_gate0, 1, 21); // PDMA -Field Clock_gate_ost (Clock_gate0, 1, 20); // OST -Field Clock_gate_ssi0 (Clock_gate0, 1, 19); // SSI0 -Field Clock_gate_timer (Clock_gate0, 1, 18); // TCU -Field Clock_gate_dtrng (Clock_gate0, 1, 17); // DTRNG -Field Clock_gate_uart2 (Clock_gate0, 1, 16); // UART2 -Field Clock_gate_uart1 (Clock_gate0, 1, 15); // UART1 -Field Clock_gate_uart0 (Clock_gate0, 1, 14); // UART0 -Field Clock_gate_sadc (Clock_gate0, 1, 13); // SADC -Field Clock_gate_audio (Clock_gate0, 1, 11); // AUDIO -Field Clock_gate_ssi_slv (Clock_gate0, 1, 10); // SSI_SLV -Field Clock_gate_i2c1 (Clock_gate0, 1, 8); // I2C1 -Field Clock_gate_i2c0 (Clock_gate0, 1, 7); // I2C0 -Field Clock_gate_msc1 (Clock_gate0, 1, 5); // MSC1 -Field Clock_gate_msc0 (Clock_gate0, 1, 4); // MSC0 -Field Clock_gate_otg (Clock_gate0, 1, 3); // OTG -Field Clock_gate_sfc (Clock_gate0, 1, 2); // SFC -Field Clock_gate_efuse (Clock_gate0, 1, 1); // EFUSE -Field Clock_gate_nemc (Clock_gate0, 1, 0); // NEMC -Field Clock_gate_arb (Clock_gate1, 1, 30); // ARB -Field Clock_gate_mipi_csi (Clock_gate1, 1, 28); // MIPI_CSI -Field Clock_gate_intc (Clock_gate1, 1, 26); // INTC -Field Clock_gate_gmac0 (Clock_gate1, 1, 23); // GMAC0 -Field Clock_gate_uart3 (Clock_gate1, 1, 16); // UART3 -Field Clock_gate_i2s0_tx (Clock_gate1, 1, 9); // I2S0_dev_tclk -Field Clock_gate_i2s0_rx (Clock_gate1, 1, 8); // I2S0_dev_rclk -Field Clock_gate_hash (Clock_gate1, 1, 6); // HASH -Field Clock_gate_pwm (Clock_gate1, 1, 5); // PWM -Field Clock_gate_cdbus (Clock_gate1, 1, 2); // CDBUS -Field Clock_gate_can1 (Clock_gate1, 1, 1); // CAN1 -Field Clock_gate_can0 (Clock_gate1, 1, 0); // CAN0 +Field Clock_gate_main (Clock_control, 1, 23); // GATE_SCLKA +Field Clock_gate_ddr (Clock_gate0, 1, 31); // DDR +Field Clock_gate_ahb0 (Clock_gate0, 1, 29); // AHB0 +Field Clock_gate_apb0 (Clock_gate0, 1, 28); // APB0 +Field Clock_gate_rtc (Clock_gate0, 1, 27); // RTC +Field Clock_gate_aes (Clock_gate0, 1, 24); // AES +Field Clock_gate_lcd_pixel (Clock_gate0, 1, 23); // LCD +Field Clock_gate_cim (Clock_gate0, 1, 22); // CIM +Field Clock_gate_dma (Clock_gate0, 1, 21); // PDMA +Field Clock_gate_ost (Clock_gate0, 1, 20); // OST +Field Clock_gate_ssi0 (Clock_gate0, 1, 19); // SSI0 +Field Clock_gate_timer (Clock_gate0, 1, 18); // TCU +Field Clock_gate_dtrng (Clock_gate0, 1, 17); // DTRNG +Field Clock_gate_uart2 (Clock_gate0, 1, 16); // UART2 +Field Clock_gate_uart1 (Clock_gate0, 1, 15); // UART1 +Field Clock_gate_uart0 (Clock_gate0, 1, 14); // UART0 +Field Clock_gate_sadc (Clock_gate0, 1, 13); // SADC +Field Clock_gate_audio (Clock_gate0, 1, 11); // AUDIO +Field Clock_gate_ssi_slv (Clock_gate0, 1, 10); // SSI_SLV +Field Clock_gate_i2c1 (Clock_gate0, 1, 8); // I2C1 +Field Clock_gate_i2c0 (Clock_gate0, 1, 7); // I2C0 +Field Clock_gate_msc1 (Clock_gate0, 1, 5); // MSC1 +Field Clock_gate_msc0 (Clock_gate0, 1, 4); // MSC0 +Field Clock_gate_otg (Clock_gate0, 1, 3); // OTG +Field Clock_gate_sfc (Clock_gate0, 1, 2); // SFC +Field Clock_gate_efuse (Clock_gate0, 1, 1); // EFUSE +Field Clock_gate_nemc (Clock_gate0, 1, 0); // NEMC +Field Clock_gate_arb (Clock_gate1, 1, 30); // ARB +Field Clock_gate_mipi_csi (Clock_gate1, 1, 28); // MIPI_CSI +Field Clock_gate_intc (Clock_gate1, 1, 26); // INTC +Field Clock_gate_gmac0 (Clock_gate1, 1, 23); // GMAC0 +Field Clock_gate_uart3 (Clock_gate1, 1, 16); // UART3 +Field Clock_gate_i2s0_tx (Clock_gate1, 1, 9); // I2S0_dev_tclk +Field Clock_gate_i2s0_rx (Clock_gate1, 1, 8); // I2S0_dev_rclk +Field Clock_gate_hash (Clock_gate1, 1, 6); // HASH +Field Clock_gate_pwm (Clock_gate1, 1, 5); // PWM +Field Clock_gate_cdbus (Clock_gate1, 1, 2); // CDBUS +Field Clock_gate_can1 (Clock_gate1, 1, 1); // CAN1 +Field Clock_gate_can0 (Clock_gate1, 1, 0); // CAN0 + +Field Pll_enable_A (Pll_control_A, 1, 0); // APLLEN +Field Pll_enable_E (Pll_control_E, 1, 0); // EPLLEN +Field Pll_enable_M (Pll_control_M, 1, 0); // MPLLEN + +Field Pll_stable_A (Pll_control_A, 1, 3); // APLL_ON +Field Pll_stable_E (Pll_control_E, 1, 3); // EPLL_ON +Field Pll_stable_M (Pll_control_M, 1, 3); // MPLL_ON + +Field Pll_bypass_A (Pll_control_A, 1, 30); // APLL_BP +Field Pll_bypass_E (Pll_control_E, 1, 26); // EPLL_BP +Field Pll_bypass_M (Pll_control_M, 1, 28); // MPLL_BP + +Field Pll_multiplier_A (Pll_control_A, 0x1fff, 20); // APLLM +Field Pll_multiplier_E (Pll_control_E, 0x1fff, 20); // EPLLM +Field Pll_multiplier_M (Pll_control_M, 0x1fff, 20); // MPLLM + +Field Pll_input_division_A (Pll_control_A, 0x3f, 14); // APLLN +Field Pll_input_division_E (Pll_control_E, 0x3f, 14); // EPLLN +Field Pll_input_division_M (Pll_control_M, 0x3f, 14); // MPLLN + +Field Pll_output_division1_A (Pll_control_A, 0x07, 11); // APLLOD1 +Field Pll_output_division1_E (Pll_control_E, 0x07, 11); // EPLLOD1 +Field Pll_output_division1_M (Pll_control_M, 0x07, 11); // MPLLOD1 + +Field Pll_output_division0_A (Pll_control_A, 0x07, 8); // APLLOD0 +Field Pll_output_division0_E (Pll_control_E, 0x07, 8); // EPLLOD0 +Field Pll_output_division0_M (Pll_control_M, 0x07, 8); // MPLLOD0 @@ -536,13 +550,19 @@ Clock_divider_pclock); Pll clock_pll_A(1, Clock_inputs(Clock_external), - Pll_control_A, Pll_bypass_A); + 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_control_E, Pll_bypass_E); + 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_control_M, Pll_bypass_M); + 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_source_pwm, @@ -817,19 +837,19 @@ int Pll::have_pll(Cpm_regs ®s) { - return regs.get_field(control_reg, 1, Pll_stable); + return _stable.get_field(regs); } int Pll::pll_enabled(Cpm_regs ®s) { - return regs.get_field(control_reg, 1, Pll_enabled); + return _enable.get_field(regs); } int Pll::pll_bypassed(Cpm_regs ®s) { - return regs.get_field(control_reg, 1, bypass_bit); + return _bypass.get_field(regs); } // Clock control. @@ -843,14 +863,14 @@ void Pll::start_clock(Cpm_regs ®s) { - regs.set_field(control_reg, 1, Pll_enabled, 1); + _enable.set_field(regs, 1); while (!have_pll(regs)); } void Pll::stop_clock(Cpm_regs ®s) { - regs.set_field(control_reg, 1, Pll_enabled, 0); + _enable.set_field(regs, 0); while (have_pll(regs)); } @@ -859,13 +879,13 @@ uint16_t Pll::get_multiplier(Cpm_regs ®s) { - return regs.get_field(control_reg, 0x1fff, Pll_multiplier) + 1; + return _multiplier.get_field(regs) + 1; } void Pll::set_multiplier(Cpm_regs ®s, uint16_t multiplier) { - regs.set_field(control_reg, 0x1fff, Pll_multiplier, multiplier - 1); + _multiplier.set_field(regs, multiplier - 1); } // Input (6-bit) divider. @@ -873,13 +893,13 @@ uint8_t Pll::get_input_division(Cpm_regs ®s) { - return regs.get_field(control_reg, 0x3f, Pll_input_division) + 1; + return _input_division.get_field(regs) + 1; } void Pll::set_input_division(Cpm_regs ®s, uint8_t divider) { - regs.set_field(control_reg, 0x3f, Pll_input_division, divider - 1); + _input_division.set_field(regs, divider - 1); } // Output (dual 3-bit) dividers. @@ -887,8 +907,8 @@ uint8_t Pll::get_output_division(Cpm_regs ®s) { - uint8_t d0 = regs.get_field(control_reg, 0x07, Pll_output_division0); - uint8_t d1 = regs.get_field(control_reg, 0x07, Pll_output_division1); + uint8_t d0 = _output_division0.get_field(regs); + uint8_t d1 = _output_division1.get_field(regs); return d0 * d1; } @@ -902,8 +922,8 @@ uint8_t d0 = (uint8_t) floor(sqrt(divider ? divider : 1)); uint8_t d1 = divider / d0; - regs.set_field(control_reg, 0x07, Pll_output_division0, d0); - regs.set_field(control_reg, 0x07, Pll_output_division1, d1); + _output_division0.set_field(regs, d0); + _output_division1.set_field(regs, d1); } uint32_t