# HG changeset patch # User Paul Boddie # Date 1700168631 -3600 # Node ID 526b5482e452b9b637c975be75fba70c7af6e251 # Parent bf804c0fe6dc33777e93c06bec69f69e0c5030b0 Added real-time clock selection, introducing a separate external real-time input clock (RTCLK) along with a divided external input clock (EXCLK/512). diff -r bf804c0fe6dc -r 526b5482e452 pkg/devices/include/clocks.h --- a/pkg/devices/include/clocks.h Thu Nov 16 17:48:32 2023 +0100 +++ b/pkg/devices/include/clocks.h Thu Nov 16 22:03:51 2023 +0100 @@ -39,6 +39,7 @@ Clock_dma, Clock_emac, Clock_external, /* EXCLK */ + Clock_external_div_512, Clock_hclock0, /* AHB0 */ Clock_hclock2, /* AHB2 */ Clock_hclock2_pclock, /* AHB2, APB parent clock (JZ4780, X1600) */ @@ -76,7 +77,8 @@ Clock_pll_V, Clock_pwm0, Clock_pwm1, - Clock_rtc, /* RTCLK */ + Clock_rtc, /* RTC parent clock */ + Clock_rtc_external, /* RTCLK */ Clock_scc, Clock_sfc, Clock_ssi, /* SSI parent clock (JZ4780) */ diff -r bf804c0fe6dc -r 526b5482e452 pkg/devices/lib/cpm/include/cpm-common.h --- a/pkg/devices/lib/cpm/include/cpm-common.h Thu Nov 16 17:48:32 2023 +0100 +++ b/pkg/devices/lib/cpm/include/cpm-common.h Thu Nov 16 22:03:51 2023 +0100 @@ -275,8 +275,32 @@ // Other operations. virtual int get_parameters(Cpm_regs ®s, uint32_t parameters[]) = 0; + virtual int set_parameters(Cpm_regs ®s, int num_parameters, uint32_t parameters[]) = 0; +}; - virtual int set_parameters(Cpm_regs ®s, int num_parameters, uint32_t parameters[]) = 0; + + +// Fixed divider. + +class Divider_fixed : public Divider_base +{ + uint32_t _value; + +public: + explicit Divider_fixed(uint32_t value) + : _value(value) + { + } + + // Output frequency. + + uint64_t get_frequency(Cpm_regs ®s, uint64_t source_frequency); + int set_frequency(Cpm_regs ®s, uint64_t source_frequency, uint64_t frequency); + + // Other operations. + + int get_parameters(Cpm_regs ®s, uint32_t parameters[]); + int set_parameters(Cpm_regs ®s, int num_parameters, uint32_t parameters[]); }; @@ -631,6 +655,27 @@ +// Fixed divider clock description. + +class Clock_divided_fixed : public Clock_divided_base +{ + Control _control; + Divider_fixed _divider; + + virtual Control_base &_get_control() { return _control; } + virtual Divider_base &_get_divider() { return _divider; } + +public: + explicit Clock_divided_fixed(Source source, Divider_fixed divider) + : Clock_divided_base(source), _control(Control::undefined), _divider(divider) + { + } + + const char *clock_type() { return "fix_div"; } +}; + + + // I2S clock description. class Clock_divided_i2s : public Clock_divided_base diff -r bf804c0fe6dc -r 526b5482e452 pkg/devices/lib/cpm/src/common.cc --- a/pkg/devices/lib/cpm/src/common.cc Thu Nov 16 17:48:32 2023 +0100 +++ b/pkg/devices/lib/cpm/src/common.cc Thu Nov 16 22:03:51 2023 +0100 @@ -301,6 +301,41 @@ +// Fixed divider. + +uint64_t +Divider_fixed::get_frequency(Cpm_regs ®s, uint64_t source_frequency) +{ + (void) regs; + return source_frequency / _value; +} + +int +Divider_fixed::set_frequency(Cpm_regs ®s, uint64_t source_frequency, uint64_t frequency) +{ + (void) regs; (void) source_frequency; (void) frequency; + return 0; +} + +int +Divider_fixed::get_parameters(Cpm_regs ®s, uint32_t parameters[]) +{ + (void) regs; + parameters[0] = _value; + return 1; +} + +int +Divider_fixed::set_parameters(Cpm_regs ®s, int num_parameters, uint32_t parameters[]) +{ + (void) regs; (void) num_parameters; (void) parameters; + return 0; +} + + + +// Simple divider for regular clocks. + uint32_t Divider::get_divider(Cpm_regs ®s) { diff -r bf804c0fe6dc -r 526b5482e452 pkg/devices/lib/cpm/src/jz4780.cc --- a/pkg/devices/lib/cpm/src/jz4780.cc Thu Nov 16 17:48:32 2023 +0100 +++ b/pkg/devices/lib/cpm/src/jz4780.cc Thu Nov 16 22:03:51 2023 +0100 @@ -252,9 +252,9 @@ // Main bus and peripheral clock sources. - mux_ahb2 (4, Clocks(Clock_none, Clock_main, Clock_pll_M, Clock_rtc)), + mux_ahb2 (4, Clocks(Clock_none, Clock_main, Clock_pll_M, Clock_rtc_external)), mux_core (4, Clocks(Clock_none, Clock_main, Clock_pll_M, Clock_pll_E)), - mux_main (4, Clocks(Clock_none, Clock_pll_A, Clock_external, Clock_rtc)), + mux_main (4, Clocks(Clock_none, Clock_pll_A, Clock_external, Clock_rtc_external)), // Memory and device clock sources. @@ -276,7 +276,8 @@ static Clock_null clock_none; -static Clock_passive clock_external(48000000), clock_rtc(32768); +static Clock_passive clock_external(48000000), + clock_rtc_external(32768); @@ -432,6 +433,9 @@ Control(Clock_gate_vpu, Clock_change_enable_vpu, Clock_busy_vpu), Divider(Clock_divider_vpu)); +static Clock_divided_fixed + clock_external_div_512((Source(mux_external)), (Divider_fixed(512))); + const double jz4780_pll_intermediate_min = 300000000, jz4780_pll_intermediate_max = 1500000000; @@ -480,6 +484,7 @@ &clock_dma, &clock_none, // Clock_emac &clock_external, + &clock_external_div_512, &clock_hclock0, &clock_hclock2, &clock_hclock2_pclock, @@ -517,7 +522,8 @@ &clock_pll_V, &clock_none, // Clock_pwm0 &clock_none, // Clock_pwm1 - &clock_rtc, + &clock_external_div_512,// Clock_rtc + &clock_rtc_external, &clock_scc, &clock_none, // Clock_sfc &clock_ssi, diff -r bf804c0fe6dc -r 526b5482e452 pkg/devices/lib/cpm/src/x1600.cc --- a/pkg/devices/lib/cpm/src/x1600.cc Thu Nov 16 17:48:32 2023 +0100 +++ b/pkg/devices/lib/cpm/src/x1600.cc Thu Nov 16 22:03:51 2023 +0100 @@ -97,6 +97,7 @@ Clock_source_msc0 (Divider_msc0, 3, 30), // MPCS Clock_source_msc1 (Divider_msc1, 3, 30), // MPCS Clock_source_pwm (Divider_pwm, 3, 30), // PWMPCS + Clock_source_rtc (Sleep_control, 0x01, 2), // ERCS Clock_source_sfc (Divider_sfc, 3, 30), // SFCS Clock_source_ssi (Divider_ssi, 3, 30), // SPCS @@ -254,7 +255,8 @@ mux_core (3, Clocks(Clock_none, Clock_main, Clock_pll_M)), mux_dev (3, Clocks(Clock_main, Clock_pll_M, Clock_pll_E)), mux_main (3, Clocks(Clock_none, Clock_external, Clock_pll_A)), - mux_i2s (2, Clocks(Clock_main, Clock_pll_E)); + mux_i2s (2, Clocks(Clock_main, Clock_pll_E)), + mux_rtc (2, Clocks(Clock_external_div_512, Clock_rtc_external)); @@ -262,7 +264,8 @@ static Clock_null clock_none; -static Clock_passive clock_external(24000000); +static Clock_passive clock_external(24000000), + clock_rtc_external(32768); // Note the use of extra parentheses due to the annoying C++ "most vexing parse" // problem. See: https://en.wikipedia.org/wiki/Most_vexing_parse @@ -285,6 +288,8 @@ clock_otg0((Source(mux_hclock2)), (Control(Clock_gate_otg))), + clock_rtc(Source(mux_rtc, Clock_source_rtc), (Control(Clock_gate_rtc))), + clock_timer((Source(mux_pclock)), (Control(Clock_gate_timer))), clock_uart0((Source(mux_external)), (Control(Clock_gate_uart0))), @@ -361,6 +366,9 @@ Control(Clock_gate_ssi0, Clock_change_enable_ssi, Clock_busy_ssi), Divider(Clock_divider_ssi)); +static Clock_divided_fixed + clock_external_div_512((Source(mux_external)), (Divider_fixed(512))); + static Clock_divided_i2s clock_i2s0_rx(Source(mux_i2s0_rx), Control(Clock_gate_i2s0_rx), @@ -415,6 +423,7 @@ &clock_dma, &clock_none, // Clock_emac &clock_external, + &clock_external_div_512, &clock_hclock0, &clock_hclock2, &clock_hclock2_pclock, @@ -452,7 +461,8 @@ &clock_none, // Clock_pll_V &clock_pwm0, &clock_none, // Clock_pwm1 - &clock_none, // Clock_rtc + &clock_rtc, + &clock_rtc_external, &clock_none, // Clock_scc &clock_sfc, &clock_none, // Clock_ssi diff -r bf804c0fe6dc -r 526b5482e452 pkg/landfall-examples/hw_info/common.h --- a/pkg/landfall-examples/hw_info/common.h Thu Nov 16 17:48:32 2023 +0100 +++ b/pkg/landfall-examples/hw_info/common.h Thu Nov 16 22:03:51 2023 +0100 @@ -173,6 +173,10 @@ void rtc_enable(void *rtc); +void rtc_alarm_disable(void *rtc); + +void rtc_alarm_enable(void *rtc); + uint32_t rtc_get_seconds(void *rtc); void rtc_set_seconds(void *rtc, uint32_t seconds); diff -r bf804c0fe6dc -r 526b5482e452 pkg/landfall-examples/hw_info/hw_info.c --- a/pkg/landfall-examples/hw_info/hw_info.c Thu Nov 16 17:48:32 2023 +0100 +++ b/pkg/landfall-examples/hw_info/hw_info.c Thu Nov 16 22:03:51 2023 +0100 @@ -334,11 +334,11 @@ { /* Read information from the clock and power management unit. */ - printf("%-5s %-10s %-7s %-6s %-12s %-12s %-24s %-12s %-3s\n" - "%-5s %-10s %-7s %-6s %-12s %-12s %-24s %-12s %-3s\n", + printf("%-10s %-15s %-7s %-6s %-12s %-12s %-24s %-12s %-3s\n" + "%-10s %-15s %-7s %-6s %-12s %-12s %-24s %-12s %-3s\n", "Id", "Clock", "Type", "Source", "Source Clock", "Source Freq.", "Parameters", "Frequency", "On", - sep(5), sep(10), sep(7), sep(6), sep(12), sep(12), + sep(10), sep(15), sep(7), sep(6), sep(12), sep(12), sep(24), sep(12), sep(3)); for (int i = 0; clocks[i].id != NULL; i++) @@ -356,7 +356,7 @@ pos += result; } - printf("%-5s %-10s %-7s %-6d %-12s %-12lld %-24s %-12lld %-3s\n", + printf("%-10s %-15s %-7s %-6d %-12s %-12lld %-24s %-12lld %-3s\n", clocks[i].id, clocks[i].name, cpm_clock_type(cpm, clocks[i].clock), @@ -1127,6 +1127,7 @@ uint32_t rtc_seconds = rtc_get_seconds(rtc); uint32_t value = seconds * cpm_get_frequency(cpm, Clock_external) / 512; + rtc_alarm_disable(rtc); rtc_set_alarm_seconds(rtc, rtc_seconds + value); rtc_hibernate(rtc); } diff -r bf804c0fe6dc -r 526b5482e452 pkg/landfall-examples/hw_info/jz4780.c --- a/pkg/landfall-examples/hw_info/jz4780.c Thu Nov 16 17:48:32 2023 +0100 +++ b/pkg/landfall-examples/hw_info/jz4780.c Thu Nov 16 22:03:51 2023 +0100 @@ -352,6 +352,16 @@ x1600_rtc_enable(rtc); } +void rtc_alarm_disable(void *rtc) +{ + x1600_rtc_alarm_disable(rtc); +} + +void rtc_alarm_enable(void *rtc) +{ + x1600_rtc_alarm_enable(rtc); +} + uint32_t rtc_get_seconds(void *rtc) { return x1600_rtc_get_seconds(rtc); @@ -476,45 +486,48 @@ /* CPM definitions. */ struct clock_info clocks[] = { - {"ext", Clock_external, "External"}, - {"plla", Clock_pll_A, "PLL A"}, - {"plle", Clock_pll_E, "PLL E"}, - {"pllm", Clock_pll_M, "PLL M"}, - {"pllv", Clock_pll_V, "PLL V"}, - {"main", Clock_main, "Main"}, - {"cpu", Clock_cpu, "CPU"}, - {"h2p", Clock_hclock2_pclock, "AHB2/APB"}, - {"ahb0", Clock_hclock0, "AHB0"}, - {"ahb2", Clock_hclock2, "AHB2"}, - {"apb", Clock_pclock, "APB"}, - {"dma", Clock_dma, "DMA"}, - {"hdmi", Clock_lcd, "HDMI"}, - {"lcd", Clock_lcd, "LCD"}, - {"lcd0", Clock_lcd_pixel0, "LCD0 pixel"}, - {"lcd1", Clock_lcd_pixel1, "LCD1 pixel"}, - {"msc", Clock_msc, "MSC"}, - {"msc0", Clock_msc0, "MSC0"}, - {"msc1", Clock_msc1, "MSC1"}, - {"msc2", Clock_msc1, "MSC2"}, - {"otg0", Clock_otg0, "USB OTG0"}, - {"otg1", Clock_otg1, "USB OTG1"}, - {"i2c0", Clock_i2c0, "I2C0"}, - {"i2c1", Clock_i2c1, "I2C1"}, - {"i2c2", Clock_i2c2, "I2C2"}, - {"i2c3", Clock_i2c3, "I2C3"}, - {"i2c4", Clock_i2c4, "I2C4"}, - {"i2s0", Clock_i2s0, "I2S0"}, - {"i2s1", Clock_i2s1, "I2S1"}, - {"pcm", Clock_pcm, "PCM"}, - {"ssi", Clock_ssi, "SSI"}, - {"ssi0", Clock_ssi0, "SSI0"}, - {"ssi1", Clock_ssi1, "SSI1"}, - {"uart0", Clock_uart0, "UART0"}, - {"uart1", Clock_uart1, "UART1"}, - {"uart2", Clock_uart2, "UART2"}, - {"uart3", Clock_uart3, "UART3"}, - {"uart4", Clock_uart4, "UART4"}, - {NULL, Clock_undefined, NULL}, + {"ext", Clock_external, "EXCLK"}, + {"ext_512", Clock_external_div_512, "EXCLK/512"}, + {"rtc_ext", Clock_rtc_external, "RTCLK"}, + {"plla", Clock_pll_A, "PLL A"}, + {"plle", Clock_pll_E, "PLL E"}, + {"pllm", Clock_pll_M, "PLL M"}, + {"pllv", Clock_pll_V, "PLL V"}, + {"main", Clock_main, "Main (SCLK_A)"}, + {"cpu", Clock_cpu, "CPU"}, + {"h2p", Clock_hclock2_pclock, "AHB2/APB"}, + {"ahb0", Clock_hclock0, "AHB0"}, + {"ahb2", Clock_hclock2, "AHB2"}, + {"apb", Clock_pclock, "APB"}, + {"dma", Clock_dma, "DMA"}, + {"hdmi", Clock_lcd, "HDMI"}, + {"lcd", Clock_lcd, "LCD"}, + {"lcd0", Clock_lcd_pixel0, "LCD0 pixel"}, + {"lcd1", Clock_lcd_pixel1, "LCD1 pixel"}, + {"msc", Clock_msc, "MSC"}, + {"msc0", Clock_msc0, "MSC0"}, + {"msc1", Clock_msc1, "MSC1"}, + {"msc2", Clock_msc1, "MSC2"}, + {"otg0", Clock_otg0, "USB OTG0"}, + {"otg1", Clock_otg1, "USB OTG1"}, + {"i2c0", Clock_i2c0, "I2C0"}, + {"i2c1", Clock_i2c1, "I2C1"}, + {"i2c2", Clock_i2c2, "I2C2"}, + {"i2c3", Clock_i2c3, "I2C3"}, + {"i2c4", Clock_i2c4, "I2C4"}, + {"i2s0", Clock_i2s0, "I2S0"}, + {"i2s1", Clock_i2s1, "I2S1"}, + {"pcm", Clock_pcm, "PCM"}, + {"rtc", Clock_rtc, "RTC"}, + {"ssi", Clock_ssi, "SSI"}, + {"ssi0", Clock_ssi0, "SSI0"}, + {"ssi1", Clock_ssi1, "SSI1"}, + {"uart0", Clock_uart0, "UART0"}, + {"uart1", Clock_uart1, "UART1"}, + {"uart2", Clock_uart2, "UART2"}, + {"uart3", Clock_uart3, "UART3"}, + {"uart4", Clock_uart4, "UART4"}, + {NULL, Clock_undefined, NULL}, }; diff -r bf804c0fe6dc -r 526b5482e452 pkg/landfall-examples/hw_info/x1600.c --- a/pkg/landfall-examples/hw_info/x1600.c Thu Nov 16 17:48:32 2023 +0100 +++ b/pkg/landfall-examples/hw_info/x1600.c Thu Nov 16 22:03:51 2023 +0100 @@ -341,6 +341,16 @@ x1600_rtc_enable(rtc); } +void rtc_alarm_disable(void *rtc) +{ + x1600_rtc_alarm_disable(rtc); +} + +void rtc_alarm_enable(void *rtc) +{ + x1600_rtc_alarm_enable(rtc); +} + uint32_t rtc_get_seconds(void *rtc) { return x1600_rtc_get_seconds(rtc); @@ -465,33 +475,36 @@ /* CPM definitions. */ struct clock_info clocks[] = { - {"ext", Clock_external, "External"}, - {"plla", Clock_pll_A, "PLL A"}, - {"plle", Clock_pll_E, "PLL E"}, - {"pllm", Clock_pll_M, "PLL M"}, - {"main", Clock_main, "Main"}, - {"cpu", Clock_cpu, "CPU"}, - {"ahb0", Clock_hclock0, "AHB0"}, - {"ahb2", Clock_hclock2, "AHB2"}, - {"apb", Clock_pclock, "APB"}, - {"aic", Clock_aic, "AIC"}, - {"dma", Clock_dma, "DMA"}, - {"lcd0", Clock_lcd_pixel0, "LCD pixel"}, - {"msc0", Clock_msc0, "MSC0"}, - {"msc1", Clock_msc1, "MSC1"}, - {"otg", Clock_otg0, "USB OTG"}, - {"i2c0", Clock_i2c0, "I2C0"}, - {"i2c1", Clock_i2c1, "I2C1"}, - {"i2s0", Clock_i2s0, "I2S0"}, - {"i2s1", Clock_i2s1, "I2S1"}, - {"i2s0r", Clock_i2s0_rx, "I2S0 RX"}, - {"i2s0t", Clock_i2s0_tx, "I2S0 TX"}, - {"ssi0", Clock_ssi0, "SSI"}, - {"uart0", Clock_uart0, "UART0"}, - {"uart1", Clock_uart1, "UART1"}, - {"uart2", Clock_uart2, "UART2"}, - {"uart3", Clock_uart3, "UART3"}, - {NULL, Clock_undefined, NULL}, + {"ext", Clock_external, "EXCLK"}, + {"ext_512", Clock_external_div_512, "EXCLK/512"}, + {"rtc_ext", Clock_rtc_external, "RTCLK"}, + {"plla", Clock_pll_A, "PLL A"}, + {"plle", Clock_pll_E, "PLL E"}, + {"pllm", Clock_pll_M, "PLL M"}, + {"main", Clock_main, "Main (SCLK_A)"}, + {"cpu", Clock_cpu, "CPU"}, + {"ahb0", Clock_hclock0, "AHB0"}, + {"ahb2", Clock_hclock2, "AHB2"}, + {"apb", Clock_pclock, "APB"}, + {"aic", Clock_aic, "AIC"}, + {"dma", Clock_dma, "DMA"}, + {"lcd0", Clock_lcd_pixel0, "LCD pixel"}, + {"msc0", Clock_msc0, "MSC0"}, + {"msc1", Clock_msc1, "MSC1"}, + {"otg", Clock_otg0, "USB OTG"}, + {"i2c0", Clock_i2c0, "I2C0"}, + {"i2c1", Clock_i2c1, "I2C1"}, + {"i2s0", Clock_i2s0, "I2S0"}, + {"i2s1", Clock_i2s1, "I2S1"}, + {"i2s0r", Clock_i2s0_rx, "I2S0 RX"}, + {"i2s0t", Clock_i2s0_tx, "I2S0 TX"}, + {"rtc", Clock_rtc, "RTC"}, + {"ssi0", Clock_ssi0, "SSI"}, + {"uart0", Clock_uart0, "UART0"}, + {"uart1", Clock_uart1, "UART1"}, + {"uart2", Clock_uart2, "UART2"}, + {"uart3", Clock_uart3, "UART3"}, + {NULL, Clock_undefined, NULL}, };