# HG changeset patch # User Paul Boddie # Date 1698160716 -7200 # Node ID 7dae17488eda3b23b7e9db01b1503e587534fc2e # Parent c0e1f52048a12bde55477067c165c7d3b64baf11 Fixed X1600 audio and AIC/I2S clock hierarchy and gating. diff -r c0e1f52048a1 -r 7dae17488eda pkg/devices/include/clocks.h --- a/pkg/devices/include/clocks.h Tue Oct 24 17:15:40 2023 +0200 +++ b/pkg/devices/include/clocks.h Tue Oct 24 17:18:36 2023 +0200 @@ -27,6 +27,7 @@ enum Clock_identifiers { + Clock_audio, Clock_aic_bitclk, Clock_aic_pclk, Clock_can0, @@ -44,9 +45,12 @@ Clock_i2c, Clock_i2c0, Clock_i2c1, - Clock_i2s, + Clock_i2s0, Clock_i2s0_rx, Clock_i2s0_tx, + Clock_i2s1, + Clock_i2s1_rx, + Clock_i2s1_tx, Clock_kbc, Clock_lcd, Clock_lcd_pixel, diff -r c0e1f52048a1 -r 7dae17488eda pkg/devices/lib/cpm/include/cpm-common.h --- a/pkg/devices/lib/cpm/include/cpm-common.h Tue Oct 24 17:15:40 2023 +0200 +++ b/pkg/devices/lib/cpm/include/cpm-common.h Tue Oct 24 17:18:36 2023 +0200 @@ -67,6 +67,7 @@ uint32_t mask; uint8_t bit; bool defined; + uint32_t _asserted = 0, _deasserted = 0; public: explicit Field() @@ -74,14 +75,22 @@ { } - explicit Field(uint32_t reg, uint32_t mask, uint32_t bit) + explicit Field(uint32_t reg, uint32_t mask, uint32_t bit, + bool inverted = false) : reg(reg), mask(mask), bit(bit), defined(true) { + if (inverted) + _deasserted = mask; + else + _asserted = mask; } uint32_t get_field(Cpm_regs ®s); void set_field(Cpm_regs ®s, uint32_t value); + uint32_t get_asserted() { return _asserted; } + uint32_t get_deasserted() { return _deasserted; } + bool is_defined() { return defined; } uint32_t get_limit() { return mask; } diff -r c0e1f52048a1 -r 7dae17488eda pkg/devices/lib/cpm/src/common.cc --- a/pkg/devices/lib/cpm/src/common.cc Tue Oct 24 17:15:40 2023 +0200 +++ b/pkg/devices/lib/cpm/src/common.cc Tue Oct 24 17:18:36 2023 +0200 @@ -164,7 +164,7 @@ Control::have_clock(Cpm_regs ®s) { if (_gate.is_defined()) - return !_gate.get_field(regs); + return _gate.get_field(regs) == _gate.get_asserted(); else return true; } @@ -173,14 +173,14 @@ Control::start_clock(Cpm_regs ®s) { if (_gate.is_defined()) - _gate.set_field(regs, 0); + _gate.set_field(regs, _gate.get_asserted()); } void Control::stop_clock(Cpm_regs ®s) { if (_gate.is_defined()) - _gate.set_field(regs, 1); + _gate.set_field(regs, _gate.get_deasserted()); } void diff -r c0e1f52048a1 -r 7dae17488eda pkg/devices/lib/cpm/src/x1600.cc --- a/pkg/devices/lib/cpm/src/x1600.cc Tue Oct 24 17:15:40 2023 +0200 +++ b/pkg/devices/lib/cpm/src/x1600.cc Tue Oct 24 17:18:36 2023 +0200 @@ -98,7 +98,8 @@ Clock_source_cdbus (Divider_cdbus, 3, 30), // CDCS Clock_source_cim (Divider_cim, 3, 30), // CIMPCS Clock_source_ddr (Divider_ddr, 3, 30), // DCS - Clock_source_i2s (Divider0_i2s0, 1, 30), // I2PCS + Clock_source_i2s0 (Divider0_i2s0, 1, 30), // I2PCS + Clock_source_i2s1 (Divider0_i2s1, 1, 30), // I2PCS Clock_source_lcd (Divider_lcd, 3, 30), // LPCS Clock_source_mac (Divider_mac, 3, 30), // MACPCS Clock_source_msc0 (Divider_msc0, 3, 30), // MPCS @@ -126,7 +127,8 @@ Clock_change_enable_ahb2 (Clock_control, 1, 20), Clock_change_enable_ddr (Divider_ddr, 1, 29), Clock_change_enable_mac (Divider_mac, 1, 29), - // Clock_change_enable_i2s (Divider0_i2s0, 1, 29), // CE_I2S may not be change enable + Clock_gate_i2s0 (Divider0_i2s0, 1, 29), // CE_I2S is gate, not change enable + Clock_gate_i2s1 (Divider0_i2s1, 1, 29), // CE_I2S is gate, not change enable Clock_change_enable_lcd (Divider_lcd, 1, 29), Clock_change_enable_msc0 (Divider_msc0, 1, 29), Clock_change_enable_msc1 (Divider_msc1, 1, 29), @@ -167,45 +169,45 @@ Clock_divider_i2s1_n_auto (Divider1_i2s1, 1, 31), // I2S_NEN Clock_divider_i2s1_d_auto (Divider1_i2s1, 1, 30), // I2S_DEN - Clock_gate_main (Clock_control, 1, 23), // GATE_SCLKA - Clock_gate_ddr (Clock_gate0, 1, 31), // DDR - Clock_gate_ahb0 (Clock_gate0, 1, 29), // AHB0 - Clock_gate_apb0 (Clock_gate0, 1, 28), // APB0 - Clock_gate_rtc (Clock_gate0, 1, 27), // RTC - Clock_gate_aes (Clock_gate0, 1, 24), // AES - Clock_gate_lcd_pixel (Clock_gate0, 1, 23), // LCD - Clock_gate_cim (Clock_gate0, 1, 22), // CIM - Clock_gate_dma (Clock_gate0, 1, 21), // PDMA - Clock_gate_ost (Clock_gate0, 1, 20), // OST - Clock_gate_ssi0 (Clock_gate0, 1, 19), // SSI0 - Clock_gate_timer (Clock_gate0, 1, 18), // TCU - Clock_gate_dtrng (Clock_gate0, 1, 17), // DTRNG - Clock_gate_uart2 (Clock_gate0, 1, 16), // UART2 - Clock_gate_uart1 (Clock_gate0, 1, 15), // UART1 - Clock_gate_uart0 (Clock_gate0, 1, 14), // UART0 - Clock_gate_sadc (Clock_gate0, 1, 13), // SADC - Clock_gate_audio (Clock_gate0, 1, 11), // AUDIO - Clock_gate_ssi_slv (Clock_gate0, 1, 10), // SSI_SLV - Clock_gate_i2c1 (Clock_gate0, 1, 8), // I2C1 - Clock_gate_i2c0 (Clock_gate0, 1, 7), // I2C0 - Clock_gate_msc1 (Clock_gate0, 1, 5), // MSC1 - Clock_gate_msc0 (Clock_gate0, 1, 4), // MSC0 - Clock_gate_otg (Clock_gate0, 1, 3), // OTG - Clock_gate_sfc (Clock_gate0, 1, 2), // SFC - Clock_gate_efuse (Clock_gate0, 1, 1), // EFUSE - Clock_gate_nemc (Clock_gate0, 1, 0), // NEMC - Clock_gate_arb (Clock_gate1, 1, 30), // ARB - Clock_gate_mipi_csi (Clock_gate1, 1, 28), // MIPI_CSI - Clock_gate_intc (Clock_gate1, 1, 26), // INTC - Clock_gate_gmac0 (Clock_gate1, 1, 23), // GMAC0 - Clock_gate_uart3 (Clock_gate1, 1, 16), // UART3 - Clock_gate_i2s0_tx (Clock_gate1, 1, 9), // I2S0_dev_tclk - Clock_gate_i2s0_rx (Clock_gate1, 1, 8), // I2S0_dev_rclk - Clock_gate_hash (Clock_gate1, 1, 6), // HASH - Clock_gate_pwm (Clock_gate1, 1, 5), // PWM - Clock_gate_cdbus (Clock_gate1, 1, 2), // CDBUS - Clock_gate_can1 (Clock_gate1, 1, 1), // CAN1 - Clock_gate_can0 (Clock_gate1, 1, 0), // CAN0 + Clock_gate_main (Clock_control, 1, 23, true), // GATE_SCLKA + Clock_gate_ddr (Clock_gate0, 1, 31, true), // DDR + Clock_gate_ahb0 (Clock_gate0, 1, 29, true), // AHB0 + Clock_gate_apb0 (Clock_gate0, 1, 28, true), // APB0 + Clock_gate_rtc (Clock_gate0, 1, 27, true), // RTC + Clock_gate_aes (Clock_gate0, 1, 24, true), // AES + Clock_gate_lcd_pixel (Clock_gate0, 1, 23, true), // LCD + Clock_gate_cim (Clock_gate0, 1, 22, true), // CIM + Clock_gate_dma (Clock_gate0, 1, 21, true), // PDMA + Clock_gate_ost (Clock_gate0, 1, 20, true), // OST + Clock_gate_ssi0 (Clock_gate0, 1, 19, true), // SSI0 + Clock_gate_timer (Clock_gate0, 1, 18, true), // TCU + Clock_gate_dtrng (Clock_gate0, 1, 17, true), // DTRNG + Clock_gate_uart2 (Clock_gate0, 1, 16, true), // UART2 + Clock_gate_uart1 (Clock_gate0, 1, 15, true), // UART1 + Clock_gate_uart0 (Clock_gate0, 1, 14, true), // UART0 + Clock_gate_sadc (Clock_gate0, 1, 13, true), // SADC + Clock_gate_audio (Clock_gate0, 1, 11, true), // AUDIO + Clock_gate_ssi_slv (Clock_gate0, 1, 10, true), // SSI_SLV + Clock_gate_i2c1 (Clock_gate0, 1, 8, true), // I2C1 + Clock_gate_i2c0 (Clock_gate0, 1, 7, true), // I2C0 + Clock_gate_msc1 (Clock_gate0, 1, 5, true), // MSC1 + Clock_gate_msc0 (Clock_gate0, 1, 4, true), // MSC0 + Clock_gate_otg (Clock_gate0, 1, 3, true), // OTG + Clock_gate_sfc (Clock_gate0, 1, 2, true), // SFC + Clock_gate_efuse (Clock_gate0, 1, 1, true), // EFUSE + Clock_gate_nemc (Clock_gate0, 1, 0, true), // NEMC + Clock_gate_arb (Clock_gate1, 1, 30, true), // ARB + Clock_gate_mipi_csi (Clock_gate1, 1, 28, true), // MIPI_CSI + Clock_gate_intc (Clock_gate1, 1, 26, true), // INTC + Clock_gate_gmac0 (Clock_gate1, 1, 23, true), // GMAC0 + Clock_gate_uart3 (Clock_gate1, 1, 16, true), // UART3 + Clock_gate_i2s0_tx (Clock_gate1, 1, 9, true), // I2S0_dev_tclk + Clock_gate_i2s0_rx (Clock_gate1, 1, 8, true), // I2S0_dev_rclk + Clock_gate_hash (Clock_gate1, 1, 6, true), // HASH + Clock_gate_pwm (Clock_gate1, 1, 5, true), // PWM + Clock_gate_cdbus (Clock_gate1, 1, 2, true), // CDBUS + Clock_gate_can1 (Clock_gate1, 1, 1, true), // CAN1 + Clock_gate_can0 (Clock_gate1, 1, 0, true), // CAN0 Pll_enable_A (Pll_control_A, 1, 0), // APLLEN Pll_enable_E (Pll_control_E, 1, 0), // EPLLEN @@ -249,7 +251,9 @@ mux_core (3, Clocks(Clock_none, Clock_main, Clock_pll_M)), mux_bus (4, Clocks(Clock_main, Clock_pll_M, Clock_pll_E, Clock_external)), mux_dev (3, Clocks(Clock_main, Clock_pll_M, Clock_pll_E)), - mux_i2s (2, Clocks(Clock_main, Clock_pll_E)); + mux_i2s (2, Clocks(Clock_main, Clock_pll_E)), + mux_i2s0_rx (Clock_i2s0), + mux_i2s0_tx (Clock_i2s1); @@ -262,7 +266,9 @@ // Note the use of extra parentheses due to the annoying C++ "most vexing parse" // problem. See: https://en.wikipedia.org/wiki/Most_vexing_parse -static Clock clock_dma((Source(mux_hclock2)), (Control(Clock_gate_dma))), +static Clock clock_audio((Source(mux_hclock2)), (Control(Clock_gate_audio))), + + clock_dma((Source(mux_hclock2)), (Control(Clock_gate_dma))), clock_i2c((Source(mux_pclock)), (Control(Clock_gate_i2c0))), @@ -270,6 +276,10 @@ clock_i2c1((Source(mux_pclock)), (Control(Clock_gate_i2c1))), + clock_i2s0(Source(mux_i2s, Clock_source_i2s0), Control(Clock_gate_i2s0)), + + clock_i2s1(Source(mux_i2s, Clock_source_i2s1), Control(Clock_gate_i2s1)), + clock_main(Source(mux_main, Clock_source_main), Control(Clock_gate_main)), clock_mipi_csi((Source(mux_hclock0)), Control(Clock_gate_mipi_csi)), @@ -360,13 +370,13 @@ Divider(Clock_divider_ssi)); static Clock_divided_i2s - clock_i2s0_rx(Source(mux_i2s, Clock_source_i2s), + clock_i2s0_rx(Source(mux_i2s0_rx), Control(Clock_gate_i2s0_rx), Divider_i2s(Clock_divider_i2s0_m, Clock_divider_i2s0_n, Clock_divider_i2s0_d, Clock_divider_i2s0_n_auto, Clock_divider_i2s0_d_auto)), - clock_i2s0_tx(Source(mux_i2s, Clock_source_i2s), + clock_i2s0_tx(Source(mux_i2s0_tx), Control(Clock_gate_i2s0_tx), Divider_i2s(Clock_divider_i2s1_m, Clock_divider_i2s1_n, Clock_divider_i2s1_d, Clock_divider_i2s1_n_auto, @@ -392,6 +402,7 @@ // Clock register. static Clock_base *clocks[Clock_identifier_count] = { + &clock_audio, &clock_none, // Clock_aic_bitclk &clock_none, // Clock_aic_pclk &clock_can0, @@ -409,9 +420,12 @@ &clock_i2c, &clock_i2c0, &clock_i2c1, - &clock_none, // Clock_i2s + &clock_i2s0, // supplies i2s0_rx &clock_i2s0_rx, &clock_i2s0_tx, + &clock_i2s1, // supplies i2s0_tx + &clock_none, // Clock_i2s1_rx + &clock_none, // Clock_i2s1_tx &clock_none, // Clock_kbc &clock_none, // Clock_lcd &clock_lcd_pixel,