1.1 --- a/pkg/devices/cpm/src/jz4780/cpm-jz4780.cc Tue Oct 24 18:52:06 2023 +0200 1.2 +++ b/pkg/devices/cpm/src/jz4780/cpm-jz4780.cc Fri Oct 27 18:02:49 2023 +0200 1.3 @@ -100,7 +100,7 @@ 1.4 1.5 /* Initialise the CPM abstraction. */ 1.6 1.7 - Cpm_jz4780_chip cpm_device(cpm_virt_base, 48000000, 32768); 1.8 + Cpm_jz4780_chip cpm_device(cpm_virt_base); 1.9 1.10 /* Initialise and register a server object. */ 1.11
2.1 --- a/pkg/devices/display/src/ci20/display-ci20_hdmi.cc Tue Oct 24 18:52:06 2023 +0200 2.2 +++ b/pkg/devices/display/src/ci20/display-ci20_hdmi.cc Fri Oct 27 18:02:49 2023 +0200 2.3 @@ -122,7 +122,7 @@ 2.4 2.5 // NOTE: Should test to see if it is connected. 2.6 2.7 - if (!cpm_device->get_frequency(Clock_lcd_pixel, &frequency)) 2.8 + if (!cpm_device->get_frequency(Clock_lcd_pixel0, &frequency)) 2.9 { 2.10 hdmi->enable(frequency); 2.11 }
3.1 --- a/pkg/devices/include/clocks.h Tue Oct 24 18:52:06 2023 +0200 3.2 +++ b/pkg/devices/include/clocks.h Fri Oct 27 18:02:49 2023 +0200 3.3 @@ -27,7 +27,7 @@ 3.4 3.5 enum Clock_identifiers 3.6 { 3.7 - Clock_audio, 3.8 + Clock_aic, 3.9 Clock_aic_bitclk, 3.10 Clock_aic_pclk, 3.11 Clock_can0, 3.12 @@ -38,13 +38,16 @@ 3.13 Clock_ddr, 3.14 Clock_dma, 3.15 Clock_emac, 3.16 - Clock_external, 3.17 - Clock_hclock0, 3.18 - Clock_hclock2, 3.19 + Clock_external, /* EXCLK */ 3.20 + Clock_hclock0, /* AHB0 */ 3.21 + Clock_hclock2, /* AHB2 */ 3.22 + Clock_hclock2_pclock, /* AHB2, APB parent clock (JZ4780, X1600) */ 3.23 Clock_hdmi, 3.24 - Clock_i2c, 3.25 Clock_i2c0, 3.26 Clock_i2c1, 3.27 + Clock_i2c2, 3.28 + Clock_i2c3, 3.29 + Clock_i2c4, 3.30 Clock_i2s0, 3.31 Clock_i2s0_rx, 3.32 Clock_i2s0_tx, 3.33 @@ -52,31 +55,33 @@ 3.34 Clock_i2s1_rx, 3.35 Clock_i2s1_tx, 3.36 Clock_kbc, 3.37 - Clock_lcd, 3.38 - Clock_lcd_pixel, 3.39 + Clock_lcd, /* LCD peripheral clock */ 3.40 + Clock_lcd_pixel0, 3.41 + Clock_lcd_pixel1, 3.42 Clock_mac, 3.43 - Clock_main, 3.44 + Clock_main, /* SCLK_A */ 3.45 Clock_mipi_csi, 3.46 - Clock_msc, 3.47 + Clock_msc, /* MSC parent clock (JZ4780) */ 3.48 Clock_msc0, 3.49 Clock_msc1, 3.50 + Clock_msc2, 3.51 Clock_none, 3.52 - Clock_otg, 3.53 - Clock_pclock, 3.54 + Clock_otg0, 3.55 + Clock_otg1, 3.56 + Clock_pclock, /* APB */ 3.57 Clock_pll_A, 3.58 Clock_pll_E, 3.59 Clock_pll_M, 3.60 - Clock_pwm, 3.61 + Clock_pll_V, 3.62 Clock_pwm0, 3.63 Clock_pwm1, 3.64 + Clock_rtc, /* RTCLK */ 3.65 Clock_scc, 3.66 Clock_sfc, 3.67 - Clock_smb0, 3.68 - Clock_smb1, 3.69 - Clock_smb2, 3.70 - Clock_smb3, 3.71 - Clock_smb4, 3.72 - Clock_ssi, 3.73 + Clock_ssi, /* SSI parent clock (JZ4780) */ 3.74 + Clock_ssi0, 3.75 + Clock_ssi1, 3.76 + Clock_ssi2, 3.77 Clock_timer, 3.78 Clock_uart0, 3.79 Clock_uart1,
4.1 --- a/pkg/devices/lcd/src/jz4740/lcd-jz4740-device.cc Tue Oct 24 18:52:06 2023 +0200 4.2 +++ b/pkg/devices/lcd/src/jz4740/lcd-jz4740-device.cc Fri Oct 27 18:02:49 2023 +0200 4.3 @@ -67,7 +67,10 @@ 4.4 // times that of the pixel clock. 4.5 4.6 cpm_device->set_frequency(Clock_lcd, pclk * 3); 4.7 - cpm_device->set_frequency(Clock_lcd_pixel, pclk); 4.8 + 4.9 + // NOTE: Should support multiple pixel clocks. 4.10 + 4.11 + cpm_device->set_frequency(Clock_lcd_pixel0, pclk); 4.12 cpm_device->start_clock(Clock_lcd); 4.13 4.14 l4_sleep(1); // 1ms == 1000us
5.1 --- a/pkg/devices/lib/cpm/include/cpm-common.h Tue Oct 24 18:52:06 2023 +0200 5.2 +++ b/pkg/devices/lib/cpm/include/cpm-common.h Fri Oct 27 18:02:49 2023 +0200 5.3 @@ -23,8 +23,8 @@ 5.4 5.5 #ifdef __cplusplus 5.6 5.7 +#include <l4/devices/clocks.h> 5.8 #include <l4/devices/hw_register_block.h> 5.9 -#include <l4/devices/cpm.h> 5.10 #include <l4/sys/types.h> 5.11 #include <stdint.h> 5.12 5.13 @@ -38,16 +38,12 @@ 5.14 5.15 class Cpm_regs 5.16 { 5.17 +protected: 5.18 Hw::Register_block<32> _regs; 5.19 - 5.20 -protected: 5.21 Clock_base **_clocks; 5.22 5.23 public: 5.24 - uint32_t exclk_freq; 5.25 - 5.26 - explicit Cpm_regs(l4_addr_t addr, Clock_base *clocks[], 5.27 - uint32_t exclk_freq); 5.28 + explicit Cpm_regs(l4_addr_t addr, Clock_base *clocks[]); 5.29 5.30 // Utility methods. 5.31 5.32 @@ -217,6 +213,10 @@ 5.33 int have_clock(Cpm_regs ®s); 5.34 void start_clock(Cpm_regs ®s); 5.35 void stop_clock(Cpm_regs ®s); 5.36 + 5.37 + // Undefined control object. 5.38 + 5.39 + static Control undefined; 5.40 }; 5.41 5.42 5.43 @@ -314,6 +314,7 @@ 5.44 class Divider_pll : public Divider_base 5.45 { 5.46 Field _multiplier, _input_divider, _output_divider0, _output_divider1; 5.47 + double _intermediate_min, _intermediate_max; 5.48 5.49 // General frequency modifiers. 5.50 5.51 @@ -325,10 +326,26 @@ 5.52 void set_output_divider(Cpm_regs ®s, uint32_t divider); 5.53 5.54 public: 5.55 + 5.56 + // Double output divider constructor. 5.57 + 5.58 explicit Divider_pll(Field multiplier, Field input_divider, 5.59 - Field output_divider0, Field output_divider1) 5.60 + Field output_divider0, Field output_divider1, 5.61 + double intermediate_min, double intermediate_max) 5.62 : _multiplier(multiplier), _input_divider(input_divider), 5.63 - _output_divider0(output_divider0), _output_divider1(output_divider1) 5.64 + _output_divider0(output_divider0), _output_divider1(output_divider1), 5.65 + _intermediate_min(intermediate_min), _intermediate_max(intermediate_max) 5.66 + { 5.67 + } 5.68 + 5.69 + // Single output divider constructor. 5.70 + 5.71 + explicit Divider_pll(Field multiplier, Field input_divider, 5.72 + Field output_divider, 5.73 + double intermediate_min, double intermediate_max) 5.74 + : _multiplier(multiplier), _input_divider(input_divider), 5.75 + _output_divider0(output_divider), _output_divider1(Field::undefined), 5.76 + _intermediate_min(intermediate_min), _intermediate_max(intermediate_max) 5.77 { 5.78 } 5.79 5.80 @@ -425,7 +442,15 @@ 5.81 5.82 class Clock_passive : public Clock_base 5.83 { 5.84 +protected: 5.85 + uint32_t _frequency; 5.86 + 5.87 public: 5.88 + explicit Clock_passive(uint32_t frequency) 5.89 + : _frequency(frequency) 5.90 + { 5.91 + } 5.92 + 5.93 const char *clock_type() { return "passive"; } 5.94 5.95 // Clock control. 5.96 @@ -584,6 +609,11 @@ 5.97 { 5.98 } 5.99 5.100 + explicit Clock_divided(Source source, Divider divider) 5.101 + : Clock_divided_base(source), _control(Control::undefined), _divider(divider) 5.102 + { 5.103 + } 5.104 + 5.105 const char *clock_type() { return "divided"; } 5.106 }; 5.107
6.1 --- a/pkg/devices/lib/cpm/include/cpm-jz4730.h Tue Oct 24 18:52:06 2023 +0200 6.2 +++ b/pkg/devices/lib/cpm/include/cpm-jz4730.h Fri Oct 27 18:02:49 2023 +0200 6.3 @@ -21,8 +21,7 @@ 6.4 6.5 #pragma once 6.6 6.7 -#include <l4/devices/cpm.h> 6.8 - 6.9 +#include <l4/devices/clocks.h> 6.10 #include <l4/sys/types.h> 6.11 #include <stdint.h> 6.12 6.13 @@ -30,13 +29,14 @@ 6.14 6.15 #ifdef __cplusplus 6.16 6.17 +#include <l4/devices/cpm.h> 6.18 #include <l4/devices/hw_register_block.h> 6.19 6.20 /* A simple abstraction for accessing the CPM registers. 6.21 * A proper device could inherit from Hw::Device and use an 6.22 * Int_property for _exclk_freq. */ 6.23 6.24 -class Cpm_jz4730_chip : public Cpm_chip 6.25 +class Cpm_jz4730_chip : public Cpm_chip_base 6.26 { 6.27 private: 6.28 Hw::Register_block<32> _regs;
7.1 --- a/pkg/devices/lib/cpm/include/cpm-jz4740.h Tue Oct 24 18:52:06 2023 +0200 7.2 +++ b/pkg/devices/lib/cpm/include/cpm-jz4740.h Fri Oct 27 18:02:49 2023 +0200 7.3 @@ -21,8 +21,7 @@ 7.4 7.5 #pragma once 7.6 7.7 -#include <l4/devices/cpm.h> 7.8 - 7.9 +#include <l4/devices/clocks.h> 7.10 #include <l4/sys/types.h> 7.11 #include <stdint.h> 7.12 7.13 @@ -30,13 +29,14 @@ 7.14 7.15 #ifdef __cplusplus 7.16 7.17 +#include <l4/devices/cpm.h> 7.18 #include <l4/devices/hw_register_block.h> 7.19 7.20 /* A simple abstraction for accessing the CPM registers. 7.21 * A proper device could inherit from Hw::Device and use an 7.22 * Int_property for _exclk_freq. */ 7.23 7.24 -class Cpm_jz4740_chip : public Cpm_chip 7.25 +class Cpm_jz4740_chip : public Cpm_chip_base 7.26 { 7.27 private: 7.28 Hw::Register_block<32> _regs;
8.1 --- a/pkg/devices/lib/cpm/include/cpm-jz4780.h Tue Oct 24 18:52:06 2023 +0200 8.2 +++ b/pkg/devices/lib/cpm/include/cpm-jz4780.h Fri Oct 27 18:02:49 2023 +0200 8.3 @@ -21,8 +21,7 @@ 8.4 8.5 #pragma once 8.6 8.7 -#include <l4/devices/cpm.h> 8.8 - 8.9 +#include <l4/devices/clocks.h> 8.10 #include <l4/sys/types.h> 8.11 #include <stdint.h> 8.12 8.13 @@ -30,125 +29,12 @@ 8.14 8.15 #ifdef __cplusplus 8.16 8.17 -#include <l4/devices/hw_register_block.h> 8.18 - 8.19 -/* A simple abstraction for accessing the CPM registers. 8.20 - * A proper device could inherit from Hw::Device and use an 8.21 - * Int_property for _exclk_freq and _rtclk_freq. */ 8.22 +#include <l4/devices/cpm.h> 8.23 8.24 class Cpm_jz4780_chip : public Cpm_chip 8.25 { 8.26 -private: 8.27 - Hw::Register_block<32> _regs; 8.28 - uint32_t _exclk_freq, _rtclk_freq; 8.29 - 8.30 - // Utility methods. 8.31 - 8.32 - uint32_t get_field(uint32_t reg, uint32_t mask, uint8_t shift); 8.33 - void set_field(uint32_t reg, uint32_t mask, uint8_t shift, uint32_t value); 8.34 - uint8_t _get_divider(uint32_t reg, uint32_t mask, uint8_t shift); 8.35 - 8.36 - // PLL status. 8.37 - 8.38 - int have_pll(uint32_t pll_reg); 8.39 - int pll_enabled(uint32_t pll_reg); 8.40 - int pll_bypassed(uint32_t pll_reg); 8.41 - 8.42 - // PLL control. 8.43 - 8.44 - void pll_disable(uint32_t pll_reg); 8.45 - void pll_enable(uint32_t pll_reg); 8.46 - 8.47 - // General frequency modifiers. 8.48 - 8.49 - uint16_t get_multiplier(uint32_t pll_reg); 8.50 - void set_multiplier(uint32_t pll_reg, uint16_t multiplier); 8.51 - uint8_t get_input_division(uint32_t pll_reg); 8.52 - void set_input_division(uint32_t pll_reg, uint8_t divider); 8.53 - uint8_t get_output_division(uint32_t pll_reg); 8.54 - void set_output_division(uint32_t pll_reg, uint8_t divider); 8.55 - 8.56 - // Clock dividers. 8.57 - 8.58 - void set_hdmi_divider(uint16_t division); 8.59 - void set_lcd_pixel_divider(uint8_t controller, uint16_t division); 8.60 - 8.61 - // Input frequencies. 8.62 - 8.63 - uint32_t get_pll_frequency(uint32_t pll_reg); 8.64 - 8.65 - // Clock sources. 8.66 - 8.67 - void set_hclock2_source(uint8_t source); 8.68 - void set_hdmi_source(uint8_t source); 8.69 - void set_lcd_source(uint8_t controller, uint8_t source); 8.70 - 8.71 - // Clock control. 8.72 - 8.73 - uint32_t get_clock_gate_register(enum Clock_identifiers clock); 8.74 - uint32_t get_clock_gate_value(enum Clock_identifiers clock); 8.75 - 8.76 public: 8.77 - void set_pclock_source(uint8_t source); 8.78 - Cpm_jz4780_chip(l4_addr_t addr, uint32_t exclk_freq, uint32_t rtclk_freq); 8.79 - 8.80 - // Clock divider values. 8.81 - 8.82 - uint8_t get_cpu_divider(); 8.83 - uint8_t get_hclock0_divider(); 8.84 - uint8_t get_hclock2_divider(); 8.85 - uint8_t get_pclock_divider(); 8.86 - uint8_t get_hdmi_divider(); 8.87 - uint8_t get_lcd_pixel_divider(uint8_t controller = 0); 8.88 - uint8_t get_memory_divider(); 8.89 - 8.90 - // Clock sources. 8.91 - 8.92 - uint8_t get_main_source(); 8.93 - uint8_t get_cpu_source(); 8.94 - uint8_t get_hclock0_source(); 8.95 - uint8_t get_hclock2_source(); 8.96 - uint8_t get_hdmi_source(); 8.97 - uint8_t get_lcd_source(uint8_t controller); 8.98 - uint8_t get_lcd_source() { return get_lcd_source(0); } 8.99 - uint8_t get_memory_source(); 8.100 - uint8_t get_pclock_source(); 8.101 - 8.102 - // PLL frequency status. 8.103 - 8.104 - uint32_t get_apll_frequency(); 8.105 - uint32_t get_epll_frequency(); 8.106 - uint32_t get_mpll_frequency(); 8.107 - uint32_t get_vpll_frequency(); 8.108 - 8.109 - uint32_t get_main_frequency(); 8.110 - uint32_t get_cpu_source_frequency(); 8.111 - uint32_t get_hclock0_source_frequency(); 8.112 - uint32_t get_hclock2_source_frequency(); 8.113 - uint32_t get_hdmi_source_frequency(); 8.114 - uint32_t get_lcd_source_frequency(uint8_t controller); 8.115 - uint32_t get_lcd_source_frequency() { return get_lcd_source_frequency(0); } 8.116 - uint32_t get_memory_source_frequency(); 8.117 - uint32_t get_pclock_source_frequency(); 8.118 - 8.119 - // Clock frequency status. 8.120 - 8.121 - uint32_t get_cpu_frequency(); 8.122 - uint32_t get_hclock0_frequency(); 8.123 - uint32_t get_hclock2_frequency(); 8.124 - uint32_t get_memory_frequency(); 8.125 - uint32_t get_pclock_frequency(); 8.126 - 8.127 - void set_pll_parameters(uint32_t pll_reg, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider); 8.128 - 8.129 - // Clock frequency configuration. 8.130 - 8.131 - uint32_t get_frequency(enum Clock_identifiers clock); 8.132 - void set_frequency(enum Clock_identifiers clock, uint32_t frequency); 8.133 - 8.134 - int have_clock(enum Clock_identifiers clock); 8.135 - void start_clock(enum Clock_identifiers clock); 8.136 - void stop_clock(enum Clock_identifiers clock); 8.137 + explicit Cpm_jz4780_chip(l4_addr_t addr); 8.138 }; 8.139 8.140 #endif /* __cplusplus */ 8.141 @@ -161,51 +47,25 @@ 8.142 8.143 void *jz4780_cpm_init(l4_addr_t cpm_base); 8.144 8.145 +const char *jz4780_cpm_clock_type(void *cpm, enum Clock_identifiers clock); 8.146 + 8.147 int jz4780_cpm_have_clock(void *cpm, enum Clock_identifiers clock); 8.148 void jz4780_cpm_start_clock(void *cpm, enum Clock_identifiers clock); 8.149 void jz4780_cpm_stop_clock(void *cpm, enum Clock_identifiers clock); 8.150 8.151 -uint8_t jz4780_cpm_get_cpu_divider(void *cpm); 8.152 -uint8_t jz4780_cpm_get_hclock0_divider(void *cpm); 8.153 -uint8_t jz4780_cpm_get_hclock2_divider(void *cpm); 8.154 -uint8_t jz4780_cpm_get_hdmi_divider(void *cpm); 8.155 -uint8_t jz4780_cpm_get_lcd_pixel_divider(void *cpm); 8.156 -uint8_t jz4780_cpm_get_memory_divider(void *cpm); 8.157 -uint8_t jz4780_cpm_get_pclock_divider(void *cpm); 8.158 - 8.159 -uint8_t jz4780_cpm_get_hclock0_source(void *cpm); 8.160 -uint8_t jz4780_cpm_get_hclock2_source(void *cpm); 8.161 -uint8_t jz4780_cpm_get_hdmi_source(void *cpm); 8.162 -uint8_t jz4780_cpm_get_lcd_source(void *cpm); 8.163 -uint8_t jz4780_cpm_get_memory_source(void *cpm); 8.164 -uint8_t jz4780_cpm_get_pclock_source(void *cpm); 8.165 +int jz4780_cpm_get_parameters(void *cpm, enum Clock_identifiers clock, 8.166 + uint32_t parameters[]); 8.167 +int jz4780_cpm_set_parameters(void *cpm, enum Clock_identifiers clock, 8.168 + int num_parameters, uint32_t parameters[]); 8.169 8.170 -uint32_t jz4780_cpm_get_hclock0_source_frequency(void *cpm); 8.171 -uint32_t jz4780_cpm_get_hclock2_source_frequency(void *cpm); 8.172 -uint32_t jz4780_cpm_get_hdmi_source_frequency(void *cpm); 8.173 -uint32_t jz4780_cpm_get_lcd_source_frequency(void *cpm); 8.174 -uint32_t jz4780_cpm_get_memory_source_frequency(void *cpm); 8.175 -uint32_t jz4780_cpm_get_pclock_source_frequency(void *cpm); 8.176 - 8.177 -void jz4780_cpm_set_pclock_source(void *cpm, uint8_t source); 8.178 +uint8_t jz4780_cpm_get_source(void *cpm, enum Clock_identifiers clock); 8.179 +void jz4780_cpm_set_source(void *cpm, enum Clock_identifiers clock, uint8_t source); 8.180 +enum Clock_identifiers jz4780_cpm_get_source_clock(void *cpm, enum Clock_identifiers clock); 8.181 +void jz4780_cpm_set_source_clock(void *cpm, enum Clock_identifiers clock, enum Clock_identifiers source); 8.182 8.183 -uint8_t jz4780_cpm_get_main_source(void *cpm); 8.184 -uint32_t jz4780_cpm_get_main_frequency(void *cpm); 8.185 - 8.186 -uint32_t jz4780_cpm_get_cpu_frequency(void *cpm); 8.187 -uint32_t jz4780_cpm_get_hclock0_frequency(void *cpm); 8.188 -uint32_t jz4780_cpm_get_hclock2_frequency(void *cpm); 8.189 -uint32_t jz4780_cpm_get_memory_frequency(void *cpm); 8.190 -uint32_t jz4780_cpm_get_pclock_frequency(void *cpm); 8.191 - 8.192 -uint32_t jz4780_cpm_get_apll_frequency(void *cpm); 8.193 -uint32_t jz4780_cpm_get_epll_frequency(void *cpm); 8.194 -uint32_t jz4780_cpm_get_mpll_frequency(void *cpm); 8.195 -uint32_t jz4780_cpm_get_vpll_frequency(void *cpm); 8.196 +uint32_t jz4780_cpm_get_source_frequency(void *cpm, enum Clock_identifiers clock); 8.197 8.198 uint32_t jz4780_cpm_get_frequency(void *cpm, enum Clock_identifiers clock); 8.199 -void jz4780_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency); 8.200 - 8.201 -void jz4780_cpm_set_mpll_parameters(void *cpm, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider); 8.202 +int jz4780_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency); 8.203 8.204 EXTERN_C_END
9.1 --- a/pkg/devices/lib/cpm/include/cpm-x1600.h Tue Oct 24 18:52:06 2023 +0200 9.2 +++ b/pkg/devices/lib/cpm/include/cpm-x1600.h Fri Oct 27 18:02:49 2023 +0200 9.3 @@ -21,7 +21,7 @@ 9.4 9.5 #pragma once 9.6 9.7 -#include <l4/devices/cpm.h> 9.8 +#include <l4/devices/clocks.h> 9.9 #include <l4/sys/types.h> 9.10 #include <stdint.h> 9.11 9.12 @@ -29,50 +29,12 @@ 9.13 9.14 #ifdef __cplusplus 9.15 9.16 -#include <l4/devices/hw_register_block.h> 9.17 -#include <l4/devices/cpm-common.h> 9.18 - 9.19 -/* A simple abstraction for accessing the CPM registers. 9.20 - * A proper device could inherit from Hw::Device and use an 9.21 - * Int_property for _exclk_freq. */ 9.22 +#include <l4/devices/cpm.h> 9.23 9.24 class Cpm_x1600_chip : public Cpm_chip 9.25 { 9.26 -private: 9.27 - Hw::Register_block<32> _regs; 9.28 - uint32_t _exclk_freq; 9.29 - Cpm_regs _cpm_regs; 9.30 - 9.31 public: 9.32 - Cpm_x1600_chip(l4_addr_t addr, uint32_t exclk_freq); 9.33 - 9.34 - const char *clock_type(enum Clock_identifiers clock); 9.35 - 9.36 - int have_clock(enum Clock_identifiers clock); 9.37 - void start_clock(enum Clock_identifiers clock); 9.38 - void stop_clock(enum Clock_identifiers clock); 9.39 - 9.40 - // Clock dividers. 9.41 - 9.42 - int get_parameters(enum Clock_identifiers clock, uint32_t parameters[]); 9.43 - int set_parameters(enum Clock_identifiers clock, int num_parameters, 9.44 - uint32_t parameters[]); 9.45 - 9.46 - // Clock sources. 9.47 - 9.48 - uint8_t get_source(enum Clock_identifiers clock); 9.49 - void set_source(enum Clock_identifiers clock, uint8_t source); 9.50 - enum Clock_identifiers get_source_clock(enum Clock_identifiers clock); 9.51 - void set_source_clock(enum Clock_identifiers clock, enum Clock_identifiers source); 9.52 - 9.53 - // Source frequencies. 9.54 - 9.55 - uint32_t get_source_frequency(enum Clock_identifiers clock); 9.56 - 9.57 - // Output clock frequencies. 9.58 - 9.59 - uint32_t get_frequency(enum Clock_identifiers clock); 9.60 - int set_frequency(enum Clock_identifiers clock, uint32_t frequency); 9.61 + explicit Cpm_x1600_chip(l4_addr_t addr); 9.62 }; 9.63 9.64 #endif /* __cplusplus */
10.1 --- a/pkg/devices/lib/cpm/include/cpm.h Tue Oct 24 18:52:06 2023 +0200 10.2 +++ b/pkg/devices/lib/cpm/include/cpm.h Fri Oct 27 18:02:49 2023 +0200 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Clock and power management (CPM) abstractions. 10.6 + * Common clock and power management (CPM) abstractions. 10.7 * 10.8 * Copyright (C) 2017, 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk> 10.9 * 10.10 @@ -21,7 +21,7 @@ 10.11 10.12 #pragma once 10.13 10.14 -#include <l4/devices/clocks.h> 10.15 +#include <l4/devices/cpm-common.h> 10.16 #include <l4/sys/types.h> 10.17 #include <stdint.h> 10.18 10.19 @@ -29,16 +29,56 @@ 10.20 10.21 #ifdef __cplusplus 10.22 10.23 -/* A simple abstraction for accessing the CPM registers. */ 10.24 +/* A transitional abstraction supporting older CPM abstractions. */ 10.25 10.26 -class Cpm_chip 10.27 +class Cpm_chip_base 10.28 { 10.29 public: 10.30 virtual int have_clock(enum Clock_identifiers clock) = 0; 10.31 - 10.32 virtual void start_clock(enum Clock_identifiers clock) = 0; 10.33 - 10.34 virtual void stop_clock(enum Clock_identifiers clock) = 0; 10.35 }; 10.36 10.37 +/* A simple abstraction for accessing the CPM registers. */ 10.38 + 10.39 +class Cpm_chip : public Cpm_chip_base 10.40 +{ 10.41 +protected: 10.42 + Clock_base **_clocks; 10.43 + Cpm_regs _cpm_regs; 10.44 + 10.45 +public: 10.46 + explicit Cpm_chip(l4_addr_t addr, Clock_base *clocks[]); 10.47 + 10.48 + const char *clock_type(enum Clock_identifiers clock); 10.49 + 10.50 + // Clock control. 10.51 + 10.52 + int have_clock(enum Clock_identifiers clock); 10.53 + void start_clock(enum Clock_identifiers clock); 10.54 + void stop_clock(enum Clock_identifiers clock); 10.55 + 10.56 + // Clock dividers. 10.57 + 10.58 + int get_parameters(enum Clock_identifiers clock, uint32_t parameters[]); 10.59 + int set_parameters(enum Clock_identifiers clock, int num_parameters, 10.60 + uint32_t parameters[]); 10.61 + 10.62 + // Clock sources. 10.63 + 10.64 + uint8_t get_source(enum Clock_identifiers clock); 10.65 + void set_source(enum Clock_identifiers clock, uint8_t source); 10.66 + enum Clock_identifiers get_source_clock(enum Clock_identifiers clock); 10.67 + void set_source_clock(enum Clock_identifiers clock, enum Clock_identifiers source); 10.68 + 10.69 + // Source frequencies. 10.70 + 10.71 + uint32_t get_source_frequency(enum Clock_identifiers clock); 10.72 + 10.73 + // Output clock frequencies. 10.74 + 10.75 + uint32_t get_frequency(enum Clock_identifiers clock); 10.76 + int set_frequency(enum Clock_identifiers clock, uint32_t frequency); 10.77 +}; 10.78 + 10.79 #endif /* __cplusplus */
11.1 --- a/pkg/devices/lib/cpm/src/Makefile Tue Oct 24 18:52:06 2023 +0200 11.2 +++ b/pkg/devices/lib/cpm/src/Makefile Fri Oct 27 18:02:49 2023 +0200 11.3 @@ -4,7 +4,7 @@ 11.4 TARGET = libcpm.o.a libcpm.o.so 11.5 PC_FILENAME := libdrivers-cpm 11.6 11.7 -SRC_CC := common.cc jz4730.cc jz4740.cc jz4780.cc x1600.cc 11.8 +SRC_CC := chip.cc common.cc jz4730.cc jz4740.cc jz4780.cc x1600.cc 11.9 11.10 PRIVATE_INCDIR += $(PKGDIR)/lib/cpm/include 11.11
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/pkg/devices/lib/cpm/src/chip.cc Fri Oct 27 18:02:49 2023 +0200 12.3 @@ -0,0 +1,144 @@ 12.4 +/* 12.5 + * Common clock and power management functionality. 12.6 + * 12.7 + * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk> 12.8 + * 12.9 + * This program is free software; you can redistribute it and/or 12.10 + * modify it under the terms of the GNU General Public License as 12.11 + * published by the Free Software Foundation; either version 2 of 12.12 + * the License, or (at your option) any later version. 12.13 + * 12.14 + * This program is distributed in the hope that it will be useful, 12.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12.17 + * GNU General Public License for more details. 12.18 + * 12.19 + * You should have received a copy of the GNU General Public License 12.20 + * along with this program; if not, write to the Free Software 12.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 12.22 + * Boston, MA 02110-1301, USA 12.23 + */ 12.24 + 12.25 +#include "cpm.h" 12.26 +#include "cpm-common.h" 12.27 + 12.28 + 12.29 + 12.30 +Cpm_chip::Cpm_chip(l4_addr_t addr, Clock_base *clocks[]) 12.31 +: _clocks(clocks), _cpm_regs(addr, clocks) 12.32 +{ 12.33 +} 12.34 + 12.35 +const char * 12.36 +Cpm_chip::clock_type(enum Clock_identifiers clock) 12.37 +{ 12.38 + return _clocks[clock]->clock_type(); 12.39 +} 12.40 + 12.41 +int 12.42 +Cpm_chip::have_clock(enum Clock_identifiers clock) 12.43 +{ 12.44 + return _clocks[clock]->have_clock(_cpm_regs); 12.45 +} 12.46 + 12.47 +void 12.48 +Cpm_chip::start_clock(enum Clock_identifiers clock) 12.49 +{ 12.50 + _clocks[clock]->start_clock(_cpm_regs); 12.51 +} 12.52 + 12.53 +void 12.54 +Cpm_chip::stop_clock(enum Clock_identifiers clock) 12.55 +{ 12.56 + _clocks[clock]->stop_clock(_cpm_regs); 12.57 +} 12.58 + 12.59 +int 12.60 +Cpm_chip::get_parameters(enum Clock_identifiers clock, uint32_t parameters[]) 12.61 +{ 12.62 + Clock_divided_base *clk = dynamic_cast<Clock_divided_base *>(_clocks[clock]); 12.63 + 12.64 + if (clk != NULL) 12.65 + return clk->get_parameters(_cpm_regs, parameters); 12.66 + else 12.67 + return 0; 12.68 +} 12.69 + 12.70 +int 12.71 +Cpm_chip::set_parameters(enum Clock_identifiers clock, int num_parameters, uint32_t parameters[]) 12.72 +{ 12.73 + Clock_divided_base *clk = dynamic_cast<Clock_divided_base *>(_clocks[clock]); 12.74 + 12.75 + if (clk != NULL) 12.76 + return clk->set_parameters(_cpm_regs, num_parameters, parameters); 12.77 + else 12.78 + return 0; 12.79 +} 12.80 + 12.81 +uint8_t 12.82 +Cpm_chip::get_source(enum Clock_identifiers clock) 12.83 +{ 12.84 + Clock_active *clk = dynamic_cast<Clock_active *>(_clocks[clock]); 12.85 + 12.86 + if (clk != NULL) 12.87 + return clk->get_source(_cpm_regs); 12.88 + else 12.89 + return 0; 12.90 +} 12.91 + 12.92 +enum Clock_identifiers 12.93 +Cpm_chip::get_source_clock(enum Clock_identifiers clock) 12.94 +{ 12.95 + Clock_active *clk = dynamic_cast<Clock_active *>(_clocks[clock]); 12.96 + 12.97 + if (clk != NULL) 12.98 + return clk->get_source_clock(_cpm_regs); 12.99 + else 12.100 + return Clock_undefined; 12.101 +} 12.102 + 12.103 +void 12.104 +Cpm_chip::set_source_clock(enum Clock_identifiers clock, enum Clock_identifiers source) 12.105 +{ 12.106 + Clock_active *clk = dynamic_cast<Clock_active *>(_clocks[clock]); 12.107 + 12.108 + if (clk != NULL) 12.109 + clk->set_source_clock(_cpm_regs, source); 12.110 +} 12.111 + 12.112 +void 12.113 +Cpm_chip::set_source(enum Clock_identifiers clock, uint8_t source) 12.114 +{ 12.115 + Clock_active *clk = dynamic_cast<Clock_active *>(_clocks[clock]); 12.116 + 12.117 + if (clk != NULL) 12.118 + clk->set_source(_cpm_regs, source); 12.119 +} 12.120 + 12.121 +uint32_t 12.122 +Cpm_chip::get_source_frequency(enum Clock_identifiers clock) 12.123 +{ 12.124 + Clock_active *clk = dynamic_cast<Clock_active *>(_clocks[clock]); 12.125 + 12.126 + if (clk != NULL) 12.127 + return clk->get_source_frequency(_cpm_regs); 12.128 + else 12.129 + return 0; 12.130 +} 12.131 + 12.132 +uint32_t 12.133 +Cpm_chip::get_frequency(enum Clock_identifiers clock) 12.134 +{ 12.135 + return _clocks[clock]->get_frequency(_cpm_regs); 12.136 +} 12.137 + 12.138 +int 12.139 +Cpm_chip::set_frequency(enum Clock_identifiers clock, uint32_t frequency) 12.140 +{ 12.141 + Clock_divided_base *clk = dynamic_cast<Clock_divided_base *>(_clocks[clock]); 12.142 + 12.143 + if (clk != NULL) 12.144 + return clk->set_frequency(_cpm_regs, frequency); 12.145 + else 12.146 + return 0; 12.147 +}
13.1 --- a/pkg/devices/lib/cpm/src/common.cc Tue Oct 24 18:52:06 2023 +0200 13.2 +++ b/pkg/devices/lib/cpm/src/common.cc Fri Oct 27 18:02:49 2023 +0200 13.3 @@ -29,9 +29,8 @@ 13.4 13.5 // Register access. 13.6 13.7 -Cpm_regs::Cpm_regs(l4_addr_t addr, Clock_base *clocks[], 13.8 - uint32_t exclk_freq) 13.9 -: _clocks(clocks), exclk_freq(exclk_freq) 13.10 +Cpm_regs::Cpm_regs(l4_addr_t addr, Clock_base *clocks[]) 13.11 +: _clocks(clocks) 13.12 { 13.13 _regs = new Hw::Mmio_register_block<32>(addr); 13.14 } 13.15 @@ -204,6 +203,10 @@ 13.16 _change_enable.set_field(regs, 1); 13.17 } 13.18 13.19 +// Undefined control. 13.20 + 13.21 +Control Control::undefined; 13.22 + 13.23 13.24 13.25 // PLL-specific control. 13.26 @@ -419,7 +422,8 @@ 13.27 Divider_pll::get_output_divider(Cpm_regs ®s) 13.28 { 13.29 uint32_t d0 = zero_as_one(_output_divider0.get_field(regs)); 13.30 - uint32_t d1 = zero_as_one(_output_divider1.get_field(regs)); 13.31 + uint32_t d1 = _output_divider1.is_defined() ? 13.32 + zero_as_one(_output_divider1.get_field(regs)) : 1; 13.33 13.34 return d0 * d1; 13.35 } 13.36 @@ -427,14 +431,24 @@ 13.37 void 13.38 Divider_pll::set_output_divider(Cpm_regs ®s, uint32_t divider) 13.39 { 13.40 + uint32_t d0, d1; 13.41 + 13.42 // Assert 1 as a minimum. 13.43 - // Divider 0 must be less than or equal to divider 1. 13.44 - 13.45 - uint32_t d0, d1; 13.46 13.47 if (!divider) 13.48 divider = 1; 13.49 13.50 + // Attempt to set any single divider. 13.51 + 13.52 + if (!_output_divider1.is_defined()) 13.53 + { 13.54 + _output_divider0.set_field(regs, divider); 13.55 + return; 13.56 + } 13.57 + 13.58 + // For two-divider implementations such as the X1600, divider 0 must be less 13.59 + // than or equal to divider 1. 13.60 + 13.61 if (divider < _output_divider1.get_limit()) 13.62 { 13.63 d0 = 1; 13.64 @@ -460,41 +474,59 @@ 13.65 int 13.66 Divider_pll::set_frequency(Cpm_regs ®s, uint32_t source_frequency, uint32_t frequency) 13.67 { 13.68 - double intermediate_min = 600000000, intermediate_max = 2400000000; 13.69 double intermediate_multiplier, intermediate_input_divider; 13.70 uint32_t output_min, output_max, output0, output1; 13.71 uint32_t multiplier, input_divider, output_divider; 13.72 13.73 - // Distribute the divider across the input and output divider. For the X1600, 13.74 - // the multiplier and input divider should collectively deliver a frequency in 13.75 - // the range 600-2400 MHz. 13.76 + // Define the range for the output dividers using the intermediate frequency 13.77 + // range applying to each chip, this being the result of the multiplier and 13.78 + // input divider. 13.79 13.80 - output_min = (uint32_t) ceil(intermediate_min / frequency); 13.81 - output_max = (uint32_t) floor(intermediate_max / frequency); 13.82 + output_min = (uint32_t) ceil(_intermediate_min / frequency); 13.83 + output_max = (uint32_t) floor(_intermediate_max / frequency); 13.84 + 13.85 + // Distribute the divider across the input and output dividers. 13.86 13.87 output_divider = output_min; 13.88 13.89 while (output_divider <= output_max) 13.90 { 13.91 + bool usable_divider; 13.92 + 13.93 // Test divider constraints. 13.94 13.95 - output0 = (uint32_t) floor(sqrt(output_divider)); 13.96 - output1 = (uint32_t) floor(output_divider / output0); 13.97 + if (_output_divider1.is_defined()) 13.98 + { 13.99 + output0 = (uint32_t) floor(sqrt(output_divider)); 13.100 + output1 = (uint32_t) floor(output_divider / output0); 13.101 13.102 - if ((output0 * output1 == output_divider) && 13.103 + usable_divider = ((output0 * output1 == output_divider) && 13.104 (output0 <= _output_divider0.get_limit()) && 13.105 - (output1 <= _output_divider1.get_limit())) 13.106 + (output1 <= _output_divider1.get_limit())); 13.107 + } 13.108 + else 13.109 + usable_divider = output_divider <= _output_divider0.get_limit(); 13.110 + 13.111 + // Apply any usable divider. 13.112 + 13.113 + if (usable_divider) 13.114 { 13.115 - // Calculate the other parameters. 13.116 + // Calculate the other parameters. Start by working back from the desired 13.117 + // output frequency to obtain an intermediate frequency using the proposed 13.118 + // divider. 13.119 13.120 uint32_t intermediate_frequency = frequency * output_divider; 13.121 13.122 + // Calculate the required multiplier and divider. 13.123 + 13.124 get_divider_operands(intermediate_frequency, source_frequency, 13.125 &intermediate_multiplier, &intermediate_input_divider); 13.126 13.127 multiplier = (uint32_t) round(intermediate_multiplier); 13.128 input_divider = (uint32_t) round(intermediate_input_divider); 13.129 13.130 + // Attempt to reduce the multiplier and divider to usable values. 13.131 + 13.132 uint32_t multiplier_limit = _multiplier.get_limit(); 13.133 uint32_t input_divider_limit = _input_divider.get_limit(); 13.134 13.135 @@ -721,9 +753,8 @@ 13.136 uint32_t 13.137 Clock_passive::get_frequency(Cpm_regs ®s) 13.138 { 13.139 - // NOTE: Return the external clock frequency. 13.140 - 13.141 - return regs.exclk_freq; 13.142 + (void) regs; 13.143 + return _frequency; 13.144 } 13.145 13.146
14.1 --- a/pkg/devices/lib/cpm/src/jz4730.cc Tue Oct 24 18:52:06 2023 +0200 14.2 +++ b/pkg/devices/lib/cpm/src/jz4730.cc Fri Oct 27 18:02:49 2023 +0200 14.3 @@ -116,12 +116,12 @@ 14.4 case Clock_uart3: return (1 << Clock_gate_uart3); 14.5 case Clock_aic_bitclk: return (1 << Clock_gate_aic_bitclk); 14.6 case Clock_scc: return (1 << Clock_gate_scc); 14.7 - case Clock_msc: return (1 << Clock_gate_msc); 14.8 + case Clock_msc0: return (1 << Clock_gate_msc); 14.9 case Clock_ssi: return (1 << Clock_gate_ssi); 14.10 case Clock_pwm1: return (1 << Clock_gate_pwm1); 14.11 case Clock_pwm0: return (1 << Clock_gate_pwm0); 14.12 case Clock_aic_pclk: return (1 << Clock_gate_aic_pclk); 14.13 - case Clock_i2c: return (1 << Clock_gate_i2c); 14.14 + case Clock_i2c0: return (1 << Clock_gate_i2c); 14.15 case Clock_lcd: return (1 << Clock_gate_lcd); 14.16 case Clock_uhc: return (1 << Clock_gate_uhc); 14.17 case Clock_dma: return (1 << Clock_gate_dmac); 14.18 @@ -309,7 +309,7 @@ 14.19 uint32_t 14.20 Cpm_jz4730_chip::get_frequency(enum Clock_identifiers clock) 14.21 { 14.22 - if (clock == Clock_lcd_pixel) 14.23 + if (clock == Clock_lcd_pixel0) 14.24 return get_source_frequency() / get_lcd_pixel_divider(); 14.25 14.26 // NOTE: Consider a better error result. 14.27 @@ -331,7 +331,7 @@ 14.28 set_lcd_device_divider(out / frequency); 14.29 break; 14.30 14.31 - case Clock_lcd_pixel: 14.32 + case Clock_lcd_pixel0: 14.33 set_lcd_pixel_divider(out / frequency); 14.34 break; 14.35
15.1 --- a/pkg/devices/lib/cpm/src/jz4740.cc Tue Oct 24 18:52:06 2023 +0200 15.2 +++ b/pkg/devices/lib/cpm/src/jz4740.cc Fri Oct 27 18:02:49 2023 +0200 15.3 @@ -263,7 +263,7 @@ 15.4 uint32_t 15.5 Cpm_jz4740_chip::get_frequency(enum Clock_identifiers clock) 15.6 { 15.7 - if (clock == Clock_lcd_pixel) 15.8 + if (clock == Clock_lcd_pixel0) 15.9 return get_source_frequency() / get_lcd_pixel_divider(); 15.10 15.11 // NOTE: Consider a better error result. 15.12 @@ -285,7 +285,7 @@ 15.13 set_lcd_device_divider(out / frequency); 15.14 break; 15.15 15.16 - case Clock_lcd_pixel: 15.17 + case Clock_lcd_pixel0: 15.18 set_lcd_pixel_divider(out / frequency); 15.19 break; 15.20
16.1 --- a/pkg/devices/lib/cpm/src/jz4780.cc Tue Oct 24 18:52:06 2023 +0200 16.2 +++ b/pkg/devices/lib/cpm/src/jz4780.cc Fri Oct 27 18:02:49 2023 +0200 16.3 @@ -3,7 +3,7 @@ 16.4 * provided by the jz4780 and related SoCs. The power management 16.5 * functionality could be exposed using a separate driver. 16.6 * 16.7 - * Copyright (C) 2017, 2018, 2020, 2021 Paul Boddie <paul@boddie.org.uk> 16.8 + * Copyright (C) 2017, 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk> 16.9 * 16.10 * This program is free software; you can redistribute it and/or 16.11 * modify it under the terms of the GNU General Public License as 16.12 @@ -26,780 +26,514 @@ 16.13 16.14 16.15 16.16 +// Register locations. 16.17 + 16.18 enum Regs : unsigned 16.19 { 16.20 Clock_control = 0x000, // CPCCR 16.21 Low_power_control = 0x004, // LCR 16.22 + Clock_gate0 = 0x020, // CLKGR0 16.23 + Clock_gate1 = 0x028, // CLKGR1 16.24 + Sleep_control = 0x024, // OPCR (oscillator and power control) 16.25 + Clock_status = 0x0d4, // CPCSR 16.26 + 16.27 + Divider_bch = 0x0ac, // BCHCDR 16.28 + Divider_cim = 0x07c, // CIMCDR 16.29 + Divider_ddr = 0x02c, // DDRCDR 16.30 + Divider_gpu = 0x088, // GPUCDR 16.31 + Divider_hdmi = 0x08c, // HDMICDR 16.32 + Divider_i2s0 = 0x060, // I2SCDR 16.33 + Divider_i2s1 = 0x0a0, // I2S1CDR 16.34 + Divider_lcd0 = 0x054, // LP0CDR 16.35 + Divider_lcd1 = 0x064, // LP1CDR 16.36 + Divider_msc0 = 0x068, // MSC0CDR 16.37 + Divider_msc1 = 0x0a4, // MSC1CDR 16.38 + Divider_msc2 = 0x0a8, // MSC2CDR 16.39 + Divider_pcm = 0x084, // PCMCDR 16.40 + Divider_ssi = 0x074, // SSICDR 16.41 + Divider_uhc = 0x06c, // UHCCDR 16.42 + Divider_vpu = 0x030, // VPUCDR 16.43 + 16.44 + Cpm_interrupt = 0x0b0, // CPM_INTR 16.45 + Cpm_interrupt_en = 0x0b4, // CPM_INTRE 16.46 + Cpm_scratch = 0x034, // CPSPR 16.47 + Cpm_scratch_prot = 0x038, // CPSPPR 16.48 + 16.49 + Usb_param_control0 = 0x03c, // USBPCR 16.50 + Usb_reset_detect = 0x040, // USBRDT 16.51 + Usb_vbus_jitter = 0x044, // USBVBFIL 16.52 + Usb_param_control1 = 0x048, // USBPCR1 16.53 + 16.54 Pll_control = 0x00c, // CPPCR 16.55 Pll_control_A = 0x010, // CPAPCR 16.56 Pll_control_M = 0x014, // CPMPCR 16.57 Pll_control_E = 0x018, // CPEPCR 16.58 Pll_control_V = 0x01c, // CPVPCR 16.59 - Clock_gate0 = 0x020, // CLKGR0 16.60 - Clock_gate1 = 0x028, // CLKGR1 16.61 - Sleep_control = 0x024, // OPCR (oscillator and power control) 16.62 - Ddr_divider = 0x02c, // DDRCDR 16.63 - I2s_divider0 = 0x060, // I2SCDR 16.64 - I2s_divider1 = 0x0a0, // I2S1CDR 16.65 - Lcd_divider0 = 0x054, // LP0CDR 16.66 - Lcd_divider1 = 0x064, // LP1CDR 16.67 - Msc_divider0 = 0x068, // MSC0CDR 16.68 - Msc_divider1 = 0x0a4, // MSC1CDR 16.69 - Msc_divider2 = 0x0a8, // MSC2CDR 16.70 - Uhc_divider = 0x06c, // UHCCDR 16.71 - Ssi_divider = 0x074, // SSICDR 16.72 - 16.73 - // ... 16.74 - 16.75 - Hdmi_divider = 0x08c, // HDMICDR 16.76 - 16.77 - // ... 16.78 -}; 16.79 - 16.80 -enum Clock_bits : unsigned 16.81 -{ 16.82 - Clock_cpu_change_enable = 22, // CE_CPU 16.83 - Clock_pclock_divider = 16, // PDIV (slow APB peripherals) 16.84 - Clock_hclock2_divider = 12, // H2DIV (fast AHB peripherals) 16.85 - Clock_hclock0_divider = 8, // H0DIV (fast AHB peripherals) 16.86 - Clock_cpu_divider = 0, // CDIV 16.87 -}; 16.88 - 16.89 -enum Pll_bits : unsigned 16.90 -{ 16.91 - Pll_multiplier = 19, // xPLLM 16.92 - Pll_input_division = 13, // xPLLN 16.93 - Pll_output_division = 9, // xPLLOD 16.94 - Pll_stable = 4, // xPLL_ON 16.95 - Pll_bypassed = 1, // xPLLBP 16.96 - Pll_enabled = 0, // xPLLEN 16.97 -}; 16.98 - 16.99 -enum Clock_source_bits : unsigned 16.100 -{ 16.101 - Clock_source_main = 30, // SEL_SRC (output to SCLK_A) 16.102 - Clock_source_cpu = 28, // SEL_CPLL (output to CCLK) 16.103 - Clock_source_hclock0 = 26, // SEL_H0PLL (output to AHB0) 16.104 - Clock_source_hclock2 = 24, // SEL_H2PLL (output to AHB2) 16.105 - Clock_source_ddr = 30, // DCS 16.106 - Clock_source_i2s = 31, // I2CS 16.107 - Clock_source_lcd = 30, // LPCS 16.108 - Clock_source_hdmi = 30, // HPCS 16.109 -}; 16.110 - 16.111 -enum Clock_sources : unsigned 16.112 -{ 16.113 - // Main clock sources. 16.114 - 16.115 - Source_pll_A = 1, // APLL 16.116 - Source_external = 2, // EXCLK 16.117 - Source_realtime = 3, // RTCLK 16.118 - 16.119 - // Stoppable clock sources. 16.120 - 16.121 - Source_mux_stopped = 0, 16.122 - Source_mux_main = 1, // SCLK_A 16.123 - Source_mux_pll_M = 2, // MPLL 16.124 - Source_mux_pll_E = 3, // EPLL 16.125 - Source_mux_realtime = 3, // RTCLK (TCK) 16.126 - 16.127 - // Unstoppable clock sources. 16.128 - 16.129 - Source_main = 0, // SCLK_A 16.130 - Source_pll_M = 1, // MPLL 16.131 - Source_pll_E = 2, // EPLL 16.132 - Source_pll_V = 2, // VPLL 16.133 - Source_otg_phy = 3, // OTG_PHY 16.134 -}; 16.135 - 16.136 -enum Clock_gate_bits : unsigned 16.137 -{ 16.138 - Clock_gate_lcd1 = 28, // LCD (in CLKGR0) 16.139 - Clock_gate_lcd0 = 27, // TVE (in CLKGR0) 16.140 - Clock_gate_hdmi = 9, // HDMI (in CLKGR1) 16.141 - Clock_gate_smb4 = 12, // SMB4 (in CLKGR1) 16.142 - Clock_gate_smb3 = 0, // SMB3 (in CLKGR1) 16.143 - Clock_gate_smb2 = 25, // SMB2 (in CLKGR0) 16.144 - Clock_gate_smb1 = 6, // SMB1 (in CLKGR0) 16.145 - Clock_gate_smb0 = 5, // SMB0 (in CLKGR0) 16.146 -}; 16.147 - 16.148 -enum Divider_bits : unsigned 16.149 -{ 16.150 - Ddr_divider_value = 0, // DDRCDR 16.151 - Hdmi_divider_value = 0, // HDMICDR 16.152 - Lcd_divider_value = 0, // LPCDR 16.153 -}; 16.154 - 16.155 -enum Lcd_clock_values : unsigned 16.156 -{ 16.157 - Lcd_change_enable = 0x10000000, // CE_LCD 16.158 - Lcd_change_busy = 0x08000000, // LCD_BUSY 16.159 - Lcd_clock_stop = 0x04000000, // LCD_STOP 16.160 -}; 16.161 - 16.162 -enum Hdmi_divider_values : unsigned 16.163 -{ 16.164 - Hdmi_select_mask = 0xc0000000, // HPCS 16.165 - Hdmi_change_enable = 0x20000000, // CE_HDMI 16.166 - Hdmi_change_busy = 0x10000000, // HDMI_BUSY 16.167 - Hdmi_clock_stop = 0x08000000, // HDMI_STOP 16.168 }; 16.169 16.170 16.171 16.172 -// If implemented as a Hw::Device, various properties would be 16.173 -// initialised in the constructor and obtained from the device tree 16.174 -// definitions. 16.175 +// Register field definitions. 16.176 16.177 -Cpm_jz4780_chip::Cpm_jz4780_chip(l4_addr_t addr, uint32_t exclk_freq, uint32_t rtclk_freq) 16.178 -: _exclk_freq(exclk_freq), _rtclk_freq(rtclk_freq) 16.179 -{ 16.180 - _regs = new Hw::Mmio_register_block<32>(addr); 16.181 - 16.182 - // add_cid("cpm"); 16.183 - // add_cid("cpm-jz4780"); 16.184 - // register_property("exclk_freq", &_exclk_freq); 16.185 -} 16.186 - 16.187 -// Clock/timer control. 16.188 +static Field Clock_source_main (Clock_control, 3, 30), // SEL_SRC (output to SCLK_A) 16.189 + Clock_source_cpu (Clock_control, 3, 28), // SEL_CPLL (output to CCLK) 16.190 + Clock_source_hclock0 (Clock_control, 3, 26), // SEL_H0PLL (output to AHB0) 16.191 + Clock_source_hclock2 (Clock_control, 3, 24), // SEL_H2PLL (output to AHB2) 16.192 + Clock_source_bch (Divider_bch, 3, 30), // BPCS 16.193 + Clock_source_cim (Divider_cim, 1, 31), // CIMPCS 16.194 + Clock_source_ddr (Divider_ddr, 3, 30), // DCS 16.195 + Clock_source_gpu (Divider_gpu, 3, 30), // GPCS 16.196 + Clock_source_hdmi (Divider_hdmi, 3, 30), // HPCS 16.197 + Clock_source_i2s0 (Divider_i2s0, 3, 30), // I2CS, I2PCS 16.198 + Clock_source_i2s1 (Divider_i2s1, 3, 30), // I2CS, I2PCS 16.199 + Clock_source_lcd0 (Divider_lcd0, 3, 30), // LPCS 16.200 + Clock_source_lcd1 (Divider_lcd1, 3, 30), // LPCS 16.201 + Clock_source_msc (Divider_msc0, 3, 30), // MPCS 16.202 + Clock_source_pcm (Divider_pcm, 7, 29), // PCMS, PCMPCS 16.203 + Clock_source_ssi (Divider_ssi, 1, 30), // SPCS 16.204 + Clock_source_uhc (Divider_uhc, 3, 30), // UHCS 16.205 + Clock_source_vpu (Divider_vpu, 3, 30), // VCS 16.206 16.207 -uint32_t 16.208 -Cpm_jz4780_chip::get_clock_gate_register(enum Clock_identifiers clock) 16.209 -{ 16.210 - switch (clock) 16.211 - { 16.212 - case Clock_hdmi: return Clock_gate1; 16.213 - case Clock_smb4: return Clock_gate1; 16.214 - case Clock_smb3: return Clock_gate1; 16.215 - default: return Clock_gate0; 16.216 - } 16.217 -} 16.218 + Clock_busy_cpu (Clock_status, 1, 0), 16.219 + Clock_busy_hclock0 (Clock_status, 1, 1), 16.220 + Clock_busy_hclock2 (Clock_status, 1, 2), 16.221 + Clock_busy_bch (Divider_bch, 1, 28), 16.222 + Clock_busy_cim (Divider_cim, 1, 29), 16.223 + Clock_busy_ddr (Divider_ddr, 1, 28), 16.224 + Clock_busy_gpu (Divider_gpu, 1, 28), 16.225 + Clock_busy_hdmi (Divider_hdmi, 1, 28), 16.226 + Clock_busy_i2s0 (Divider_i2s0, 1, 28), 16.227 + Clock_busy_i2s1 (Divider_i2s1, 1, 28), 16.228 + Clock_busy_lcd0 (Divider_lcd0, 1, 27), 16.229 + Clock_busy_lcd1 (Divider_lcd1, 1, 27), 16.230 + Clock_busy_msc0 (Divider_msc0, 1, 28), 16.231 + Clock_busy_msc1 (Divider_msc1, 1, 28), 16.232 + Clock_busy_msc2 (Divider_msc2, 1, 28), 16.233 + Clock_busy_pcm (Divider_pcm, 1, 27), 16.234 + Clock_busy_ssi (Divider_ssi, 1, 28), 16.235 + Clock_busy_uhc (Divider_uhc, 1, 28), 16.236 + Clock_busy_vpu (Divider_vpu, 1, 28), 16.237 16.238 -uint32_t 16.239 -Cpm_jz4780_chip::get_clock_gate_value(enum Clock_identifiers clock) 16.240 -{ 16.241 - switch (clock) 16.242 - { 16.243 - case Clock_lcd: return (1 << Clock_gate_lcd1) | (1 << Clock_gate_lcd0); 16.244 - case Clock_hdmi: return (1 << Clock_gate_hdmi); 16.245 - case Clock_smb4: return (1 << Clock_gate_smb4); 16.246 - case Clock_smb3: return (1 << Clock_gate_smb3); 16.247 - case Clock_smb2: return (1 << Clock_gate_smb2); 16.248 - case Clock_smb1: return (1 << Clock_gate_smb1); 16.249 - case Clock_smb0: return (1 << Clock_gate_smb0); 16.250 - default: return 0; 16.251 - } 16.252 -} 16.253 + Clock_change_enable_cpu (Clock_control, 1, 22), 16.254 + Clock_change_enable_ahb0 (Clock_control, 1, 21), 16.255 + Clock_change_enable_ahb2 (Clock_control, 1, 20), 16.256 + Clock_change_enable_bch (Divider_bch, 1, 29), 16.257 + Clock_change_enable_cim (Divider_cim, 1, 30), 16.258 + Clock_change_enable_ddr (Divider_ddr, 1, 29), 16.259 + Clock_change_enable_gpu (Divider_gpu, 1, 29), 16.260 + Clock_change_enable_hdmi (Divider_hdmi, 1, 29), 16.261 + Clock_change_enable_i2s0 (Divider_i2s0, 1, 29), 16.262 + Clock_change_enable_i2s1 (Divider_i2s1, 1, 29), 16.263 + Clock_change_enable_lcd0 (Divider_lcd0, 1, 28), 16.264 + Clock_change_enable_lcd1 (Divider_lcd1, 1, 28), 16.265 + Clock_change_enable_msc0 (Divider_msc0, 1, 29), 16.266 + Clock_change_enable_msc1 (Divider_msc1, 1, 29), 16.267 + Clock_change_enable_msc2 (Divider_msc2, 1, 29), 16.268 + Clock_change_enable_pcm (Divider_pcm, 1, 28), 16.269 + Clock_change_enable_ssi (Divider_ssi, 1, 29), 16.270 + Clock_change_enable_uhc (Divider_uhc, 1, 29), 16.271 + Clock_change_enable_vpu (Divider_vpu, 1, 29), 16.272 16.273 -int 16.274 -Cpm_jz4780_chip::have_clock(enum Clock_identifiers clock) 16.275 -{ 16.276 - return !(_regs[get_clock_gate_register(clock)] & get_clock_gate_value(clock)); 16.277 -} 16.278 - 16.279 -void 16.280 -Cpm_jz4780_chip::start_clock(enum Clock_identifiers clock) 16.281 -{ 16.282 - uint32_t gate = get_clock_gate_register(clock); 16.283 - 16.284 - _regs[gate] = _regs[gate] & ~get_clock_gate_value(clock); 16.285 -} 16.286 - 16.287 -void 16.288 -Cpm_jz4780_chip::stop_clock(enum Clock_identifiers clock) 16.289 -{ 16.290 - uint32_t gate = get_clock_gate_register(clock); 16.291 - 16.292 - _regs[gate] = _regs[gate] | get_clock_gate_value(clock); 16.293 -} 16.294 - 16.295 - 16.296 + Clock_divider_cpu (Clock_control, 0x0f, 0), // CDIV 16.297 + Clock_divider_hclock0 (Clock_control, 0x0f, 8), // H0DIV (fast AHB peripherals) 16.298 + Clock_divider_hclock2 (Clock_control, 0x0f, 12), // H2DIV (fast AHB peripherals) 16.299 + Clock_divider_l2cache (Clock_control, 0x0f, 4), // L2CDIV 16.300 + Clock_divider_pclock (Clock_control, 0x0f, 16), // PDIV (slow APB peripherals) 16.301 + Clock_divider_bch (Divider_bch, 0x0f, 0), // BCHCDR 16.302 + Clock_divider_cim (Divider_cim, 0xff, 0), // CIMCDR 16.303 + Clock_divider_ddr (Divider_ddr, 0x0f, 0), // DDRCDR 16.304 + Clock_divider_gpu (Divider_gpu, 0x0f, 0), // GPUCDR 16.305 + Clock_divider_hdmi (Divider_hdmi, 0xff, 0), // HDMICDR 16.306 + Clock_divider_i2s0 (Divider_i2s0, 0xff, 0), // I2SCDR 16.307 + Clock_divider_i2s1 (Divider_i2s1, 0xff, 0), // I2SCDR 16.308 + Clock_divider_lcd0 (Divider_lcd0, 0xff, 0), // LPCDR 16.309 + Clock_divider_lcd1 (Divider_lcd1, 0xff, 0), // LPCDR 16.310 + Clock_divider_msc0 (Divider_msc0, 0xff, 0), // MSC0CDR 16.311 + Clock_divider_msc1 (Divider_msc1, 0xff, 0), // MSC1CDR 16.312 + Clock_divider_msc2 (Divider_msc2, 0xff, 0), // MSC2CDR 16.313 + Clock_divider_pcm (Divider_pcm, 0xff, 0), // PCMCDR 16.314 + Clock_divider_ssi (Divider_ssi, 0xff, 0), // SSICDR 16.315 + Clock_divider_uhc (Divider_uhc, 0xff, 0), // UHCCDR 16.316 + Clock_divider_vpu (Divider_vpu, 0x0f, 0), // VPUCDR 16.317 16.318 -// Utility methods. 16.319 - 16.320 -uint32_t 16.321 -Cpm_jz4780_chip::get_field(uint32_t reg, uint32_t mask, uint8_t shift) 16.322 -{ 16.323 - return (_regs[reg] & (mask << shift)) >> shift; 16.324 -} 16.325 + Clock_gate_main (Clock_control, 1, 23, true), // GATE_SCLKA 16.326 + Clock_gate_ddr (Clock_gate0, 3, 30, true), // DDR1, DDR0 16.327 + Clock_gate_ipu (Clock_gate0, 1, 29, true), // IPU 16.328 + Clock_gate_lcd (Clock_gate0, 3, 27, true), // LCD, TVE 16.329 + Clock_gate_cim (Clock_gate0, 1, 26, true), // CIM 16.330 + Clock_gate_i2c2 (Clock_gate0, 1, 25, true), // SMB2 16.331 + Clock_gate_uhc (Clock_gate0, 1, 24, true), // UHC 16.332 + Clock_gate_mac (Clock_gate0, 1, 23, true), // MAC 16.333 + Clock_gate_gps (Clock_gate0, 1, 22, true), // GPS 16.334 + Clock_gate_dma (Clock_gate0, 1, 21, true), // PDMA 16.335 + Clock_gate_ssi2 (Clock_gate0, 1, 20, true), // SSI2 16.336 + Clock_gate_ssi1 (Clock_gate0, 1, 19, true), // SSI1 16.337 + Clock_gate_uart3 (Clock_gate0, 1, 18, true), // UART3 16.338 + Clock_gate_uart2 (Clock_gate0, 1, 17, true), // UART2 16.339 + Clock_gate_uart1 (Clock_gate0, 1, 16, true), // UART1 16.340 + Clock_gate_uart0 (Clock_gate0, 1, 15, true), // UART0 16.341 + Clock_gate_sadc (Clock_gate0, 1, 14, true), // SADC 16.342 + Clock_gate_kbc (Clock_gate0, 1, 13, true), // KBC 16.343 + Clock_gate_msc2 (Clock_gate0, 1, 12, true), // MSC2 16.344 + Clock_gate_msc1 (Clock_gate0, 1, 11, true), // MSC1 16.345 + Clock_gate_owi (Clock_gate0, 1, 10, true), // OWI 16.346 + Clock_gate_tssi0 (Clock_gate0, 1, 9, true), // TSSI0 16.347 + Clock_gate_aic0 (Clock_gate0, 1, 8, true), // AIC0 16.348 + Clock_gate_scc (Clock_gate0, 1, 7, true), // SCC 16.349 + Clock_gate_i2c1 (Clock_gate0, 1, 6, true), // SMB1 16.350 + Clock_gate_i2c0 (Clock_gate0, 1, 5, true), // SMB0 16.351 + Clock_gate_ssi0 (Clock_gate0, 1, 4, true), // SSI0 16.352 + Clock_gate_msc0 (Clock_gate0, 1, 3, true), // MSC0 16.353 + Clock_gate_otg0 (Clock_gate0, 1, 2, true), // OTG0 16.354 + Clock_gate_bch (Clock_gate0, 1, 1, true), // BCH 16.355 + Clock_gate_nemc (Clock_gate0, 1, 0, true), // NEMC 16.356 + Clock_gate_p1 (Clock_gate1, 1, 15, true), // P1 16.357 + Clock_gate_x2d (Clock_gate1, 1, 14, true), // X2D 16.358 + Clock_gate_des (Clock_gate1, 1, 13, true), // DES 16.359 + Clock_gate_i2c4 (Clock_gate1, 1, 12, true), // SMB4 16.360 + Clock_gate_ahb_mon (Clock_gate1, 1, 11, true), // AHB_MON 16.361 + Clock_gate_uart4 (Clock_gate1, 1, 10, true), // UART4 16.362 + Clock_gate_hdmi (Clock_gate1, 1, 9, true), // HDMI 16.363 + Clock_gate_otg1 (Clock_gate1, 1, 8, true), // OTG1 16.364 + Clock_gate_gpvlc (Clock_gate1, 1, 7, true), // GPVLC 16.365 + Clock_gate_aic1 (Clock_gate1, 1, 6, true), // AIC1 16.366 + Clock_gate_compress (Clock_gate1, 1, 5, true), // COMPRESS 16.367 + Clock_gate_gpu (Clock_gate1, 1, 4, true), // GPU 16.368 + Clock_gate_pcm (Clock_gate1, 1, 3, true), // PCM 16.369 + Clock_gate_vpu (Clock_gate1, 1, 2, true), // VPU 16.370 + Clock_gate_tssi1 (Clock_gate1, 1, 1, true), // TSSI1 16.371 + Clock_gate_i2c3 (Clock_gate1, 1, 0, true), // I2C3 16.372 16.373 -void 16.374 -Cpm_jz4780_chip::set_field(uint32_t reg, uint32_t mask, uint8_t shift, uint32_t value) 16.375 -{ 16.376 - _regs[reg] = (_regs[reg] & (~(mask << shift))) | ((mask & value) << shift); 16.377 -} 16.378 + Pll_enable_A (Pll_control_A, 1, 0), // APLLEN 16.379 + Pll_enable_E (Pll_control_E, 1, 0), // EPLLEN 16.380 + Pll_enable_M (Pll_control_M, 1, 0), // MPLLEN 16.381 + Pll_enable_V (Pll_control_V, 1, 0), // VPLLEN 16.382 16.383 -// General clock divider access. 16.384 + Pll_stable_A (Pll_control_A, 1, 4), // APLL_ON 16.385 + Pll_stable_E (Pll_control_E, 1, 4), // EPLL_ON 16.386 + Pll_stable_M (Pll_control_M, 1, 4), // MPLL_ON 16.387 + Pll_stable_V (Pll_control_V, 1, 4), // VPLL_ON 16.388 + 16.389 + Pll_bypass_A (Pll_control_A, 1, 1), // APLL_BP 16.390 + Pll_bypass_E (Pll_control_E, 1, 1), // EPLL_BP 16.391 + Pll_bypass_M (Pll_control_M, 1, 1), // MPLL_BP 16.392 + Pll_bypass_V (Pll_control_V, 1, 1), // VPLL_BP 16.393 16.394 -uint8_t 16.395 -Cpm_jz4780_chip::_get_divider(uint32_t reg, uint32_t mask, uint8_t shift) 16.396 -{ 16.397 - uint8_t d = get_field(reg, mask, shift); 16.398 + Pll_multiplier_A (Pll_control_A, 0x1fff, 19), // APLLM 16.399 + Pll_multiplier_E (Pll_control_E, 0x1fff, 19), // EPLLM 16.400 + Pll_multiplier_M (Pll_control_M, 0x1fff, 19), // MPLLM 16.401 + Pll_multiplier_V (Pll_control_V, 0x1fff, 19), // VPLLM 16.402 16.403 - // NOTE: Value 15 stops the clock, 14 presumably resumes the clock. 16.404 + Pll_input_division_A (Pll_control_A, 0x3f, 13), // APLLN 16.405 + Pll_input_division_E (Pll_control_E, 0x3f, 13), // EPLLN 16.406 + Pll_input_division_M (Pll_control_M, 0x3f, 13), // MPLLN 16.407 + Pll_input_division_V (Pll_control_V, 0x3f, 13), // VPLLN 16.408 16.409 - return (d < 14) ? d + 1 : 1; 16.410 -} 16.411 + Pll_output_division_A (Pll_control_A, 0x0f, 9), // APLLOD 16.412 + Pll_output_division_E (Pll_control_E, 0x0f, 9), // EPLLOD 16.413 + Pll_output_division_M (Pll_control_M, 0x0f, 9), // MPLLOD 16.414 + Pll_output_division_V (Pll_control_V, 0x0f, 9); // VPLLOD 16.415 16.416 16.417 16.418 -// PLL control. 16.419 - 16.420 -// Return whether the PLL is stable. 16.421 +// Multiplexer instances. 16.422 16.423 -int 16.424 -Cpm_jz4780_chip::have_pll(uint32_t pll_reg) 16.425 -{ 16.426 - return _regs[pll_reg] & (1 << Pll_stable); 16.427 -} 16.428 +#define Clocks(...) ((enum Clock_identifiers []) {__VA_ARGS__}) 16.429 16.430 -int 16.431 -Cpm_jz4780_chip::pll_enabled(uint32_t pll_reg) 16.432 -{ 16.433 - return _regs[pll_reg] & (1 << Pll_enabled); 16.434 -} 16.435 +static Mux mux_external (Clock_external), 16.436 16.437 -int 16.438 -Cpm_jz4780_chip::pll_bypassed(uint32_t pll_reg) 16.439 -{ 16.440 - return _regs[pll_reg] & (1 << Pll_bypassed); 16.441 -} 16.442 + // Clocks being propagated to others. 16.443 16.444 -void 16.445 -Cpm_jz4780_chip::pll_enable(uint32_t pll_reg) 16.446 -{ 16.447 - _regs[pll_reg] = _regs[pll_reg] | (1 << Pll_enabled); 16.448 - while (!(_regs[pll_reg] & (1 << Pll_stable))); 16.449 -} 16.450 - 16.451 -void 16.452 -Cpm_jz4780_chip::pll_disable(uint32_t pll_reg) 16.453 -{ 16.454 - _regs[pll_reg] = _regs[pll_reg] & ~(1 << Pll_enabled); 16.455 - while (_regs[pll_reg] & (1 << Pll_stable)); 16.456 -} 16.457 + mux_clock_ssi (Clock_ssi), 16.458 + mux_clock_msc (Clock_msc), 16.459 + mux_hclock2 (Clock_hclock2), 16.460 + mux_hclock2_pclock (Clock_hclock2_pclock), 16.461 + mux_pclock (Clock_pclock), 16.462 16.463 -// Feedback (13-bit) multiplier. 16.464 - 16.465 -uint16_t 16.466 -Cpm_jz4780_chip::get_multiplier(uint32_t pll_reg) 16.467 -{ 16.468 - return get_field(pll_reg, 0x1fff, Pll_multiplier) + 1; 16.469 -} 16.470 - 16.471 -void 16.472 -Cpm_jz4780_chip::set_multiplier(uint32_t pll_reg, uint16_t multiplier) 16.473 -{ 16.474 - set_field(pll_reg, 0x1fff, Pll_multiplier, multiplier - 1); 16.475 -} 16.476 - 16.477 -// Input (6-bit) divider. 16.478 + // Main bus and peripheral clock sources. 16.479 16.480 -uint8_t 16.481 -Cpm_jz4780_chip::get_input_division(uint32_t pll_reg) 16.482 -{ 16.483 - return get_field(pll_reg, 0x3f, Pll_input_division) + 1; 16.484 -} 16.485 - 16.486 -void 16.487 -Cpm_jz4780_chip::set_input_division(uint32_t pll_reg, uint8_t divider) 16.488 -{ 16.489 - set_field(pll_reg, 0x3f, Pll_input_division, divider - 1); 16.490 -} 16.491 + mux_ahb2 (4, Clocks(Clock_none, Clock_main, Clock_pll_M, Clock_rtc)), 16.492 + mux_core (4, Clocks(Clock_none, Clock_main, Clock_pll_M, Clock_pll_E)), 16.493 + mux_main (4, Clocks(Clock_none, Clock_pll_A, Clock_external, Clock_rtc)), 16.494 16.495 -// Output divider. 16.496 - 16.497 -uint8_t 16.498 -Cpm_jz4780_chip::get_output_division(uint32_t pll_reg) 16.499 -{ 16.500 - uint8_t d = get_field(pll_reg, 0x0f, Pll_output_division); 16.501 - 16.502 - // Zero yields a division of one. Otherwise enforce even results. 16.503 - 16.504 - return d == 0 ? 1 : (d + 1) & 0x0e; 16.505 -} 16.506 + // Memory and device clock sources. 16.507 16.508 -void 16.509 -Cpm_jz4780_chip::set_output_division(uint32_t pll_reg, uint8_t divider) 16.510 -{ 16.511 - uint8_t d = divider <= 1 ? 0 : (divider & 0x0e) - 1; 16.512 - 16.513 - set_field(pll_reg, 0x0f, Pll_output_division, d); 16.514 -} 16.515 - 16.516 -uint32_t 16.517 -Cpm_jz4780_chip::get_pll_frequency(uint32_t pll_reg) 16.518 -{ 16.519 - // Test for PLL enable and not PLL bypass. 16.520 + mux_cim (2, Clocks(Clock_main, Clock_pll_M)), 16.521 + mux_dev (3, Clocks(Clock_none, Clock_main, Clock_pll_M)), 16.522 + mux_lcd (3, Clocks(Clock_main, Clock_pll_M, Clock_pll_V)), 16.523 + mux_usb (3, Clocks(Clock_main, Clock_pll_M, Clock_pll_E /* , OTG PHY */)), 16.524 16.525 - if (pll_enabled(pll_reg) && !pll_bypassed(pll_reg)) 16.526 - return (_exclk_freq * get_multiplier(pll_reg)) / 16.527 - (get_input_division(pll_reg) * get_output_division(pll_reg)); 16.528 - else 16.529 - return _exclk_freq; 16.530 -} 16.531 + // Clock selectors involving the external clock. 16.532 16.533 -void 16.534 -Cpm_jz4780_chip::set_pll_parameters(uint32_t pll_reg, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider) 16.535 -{ 16.536 - set_multiplier(pll_reg, multiplier); 16.537 - set_input_division(pll_reg, in_divider); 16.538 - set_output_division(pll_reg, out_divider); 16.539 - 16.540 - if (pll_enabled(pll_reg) && !pll_bypassed(pll_reg)) 16.541 - while (!have_pll(pll_reg)); 16.542 -} 16.543 + mux_i2s (4, Clocks(Clock_external, Clock_external, Clock_main, Clock_pll_E)), 16.544 + mux_pcm (8, Clocks(Clock_external, Clock_external, Clock_external, Clock_external, 16.545 + Clock_main, Clock_pll_M, Clock_pll_E, Clock_pll_V)), 16.546 + mux_ssi (4, Clocks(Clock_external, Clock_external, Clock_main, Clock_pll_M)); 16.547 16.548 16.549 16.550 -// CPU clock (CCLK) divider. 16.551 - 16.552 -uint8_t 16.553 -Cpm_jz4780_chip::get_cpu_divider() 16.554 -{ 16.555 - return _get_divider(Clock_control, 0xf, Clock_cpu_divider); 16.556 -} 16.557 - 16.558 -// Fast peripheral clock (H0CLK) divider. 16.559 - 16.560 -uint8_t 16.561 -Cpm_jz4780_chip::get_hclock0_divider() 16.562 -{ 16.563 - return _get_divider(Clock_control, 0xf, Clock_hclock0_divider); 16.564 -} 16.565 - 16.566 -// Fast peripheral clock (H2CLK) divider. 16.567 - 16.568 -uint8_t 16.569 -Cpm_jz4780_chip::get_hclock2_divider() 16.570 -{ 16.571 - return _get_divider(Clock_control, 0xf, Clock_hclock2_divider); 16.572 -} 16.573 - 16.574 -// Slow peripheral clock (PCLK) divider. 16.575 - 16.576 -uint8_t 16.577 -Cpm_jz4780_chip::get_pclock_divider() 16.578 -{ 16.579 - return _get_divider(Clock_control, 0xf, Clock_pclock_divider); 16.580 -} 16.581 - 16.582 -// HDMI clock divider. 16.583 - 16.584 -uint8_t 16.585 -Cpm_jz4780_chip::get_hdmi_divider() 16.586 -{ 16.587 - return get_field(Hdmi_divider, 0xff, Hdmi_divider_value) + 1; 16.588 -} 16.589 - 16.590 -// LCD clock (LPCLK) divider for LCD0 or LCD1 pixel clock. 16.591 - 16.592 -uint8_t 16.593 -Cpm_jz4780_chip::get_lcd_pixel_divider(uint8_t controller) 16.594 -{ 16.595 - return get_field(controller ? Lcd_divider1 : Lcd_divider0, 0xff, Lcd_divider_value) + 1; 16.596 -} 16.597 - 16.598 -// Memory clock (DDR_CLK) divider. 16.599 +// Clock instances. 16.600 16.601 -uint8_t 16.602 -Cpm_jz4780_chip::get_memory_divider() 16.603 -{ 16.604 - return _get_divider(Ddr_divider, 0xf, Ddr_divider_value); 16.605 -} 16.606 - 16.607 -// HDMI clock divider. 16.608 - 16.609 -void 16.610 -Cpm_jz4780_chip::set_hdmi_divider(uint16_t division) 16.611 -{ 16.612 - if ((division < 1) || (division > 256)) 16.613 - return; 16.614 - 16.615 - // Enable change. 16.616 - 16.617 - _regs[Hdmi_divider] = _regs[Hdmi_divider] | Hdmi_change_enable; 16.618 - 16.619 - // Set the divider. 16.620 - 16.621 - set_field(Hdmi_divider, 0xff, Hdmi_divider_value, division - 1); 16.622 - 16.623 - // Restart clock and disable change. 16.624 +static Clock_null clock_none; 16.625 16.626 - while (_regs[Hdmi_divider] & Hdmi_change_busy); 16.627 - _regs[Hdmi_divider] = _regs[Hdmi_divider] & ~Hdmi_change_enable; 16.628 -} 16.629 - 16.630 -// LCD pixel clock divider. 16.631 -// NOTE: This only supports the first LCD peripheral. 16.632 - 16.633 -void 16.634 -Cpm_jz4780_chip::set_lcd_pixel_divider(uint8_t controller, uint16_t division) 16.635 -{ 16.636 - uint32_t divider = controller ? Lcd_divider1 : Lcd_divider0; 16.637 - 16.638 - if ((division < 1) || (division > 256)) 16.639 - return; 16.640 - 16.641 - // Enable change. 16.642 - 16.643 - _regs[divider] = _regs[divider] | Lcd_change_enable; 16.644 - 16.645 - // Set the divider. 16.646 - 16.647 - set_field(divider, 0xff, Lcd_divider_value, division - 1); 16.648 - 16.649 - // Restart clock and disable change. 16.650 - 16.651 - while (_regs[divider] & Lcd_change_busy); 16.652 - _regs[divider] = _regs[divider] & ~Lcd_change_enable; 16.653 -} 16.654 +static Clock_passive clock_external(48000000), clock_rtc(32768); 16.655 16.656 16.657 16.658 -// Clock sources. 16.659 +// Note the use of extra parentheses due to the annoying C++ "most vexing parse" 16.660 +// problem. See: https://en.wikipedia.org/wiki/Most_vexing_parse 16.661 16.662 -uint8_t 16.663 -Cpm_jz4780_chip::get_memory_source() 16.664 -{ 16.665 - return get_field(Ddr_divider, 0x3, Clock_source_ddr); 16.666 -} 16.667 +static Clock clock_ahb_mon((Source(mux_external)), (Control(Clock_gate_ahb_mon))), 16.668 + 16.669 + clock_compress((Source(mux_external)), (Control(Clock_gate_compress))), 16.670 16.671 -uint32_t 16.672 -Cpm_jz4780_chip::get_memory_source_frequency() 16.673 -{ 16.674 - switch (get_memory_source()) 16.675 - { 16.676 - case Source_mux_main: 16.677 - return get_main_frequency(); 16.678 - case Source_mux_pll_M: 16.679 - return get_pll_frequency(Pll_control_M); 16.680 - default: 16.681 - return 0; 16.682 - } 16.683 -} 16.684 + clock_des((Source(mux_external)), (Control(Clock_gate_des))), 16.685 + 16.686 + clock_dma((Source(mux_external)), (Control(Clock_gate_dma))), 16.687 + 16.688 + clock_gps((Source(mux_external)), (Control(Clock_gate_gps))), 16.689 + 16.690 + clock_gpvlc((Source(mux_external)), (Control(Clock_gate_gpvlc))), 16.691 + 16.692 + clock_i2c0((Source(mux_pclock)), (Control(Clock_gate_i2c0))), 16.693 16.694 -uint8_t 16.695 -Cpm_jz4780_chip::get_cpu_source() 16.696 -{ 16.697 - return get_field(Clock_control, 0x3, Clock_source_cpu); 16.698 -} 16.699 + clock_i2c1((Source(mux_pclock)), (Control(Clock_gate_i2c1))), 16.700 + 16.701 + clock_i2c2((Source(mux_pclock)), (Control(Clock_gate_i2c2))), 16.702 + 16.703 + clock_i2c3((Source(mux_pclock)), (Control(Clock_gate_i2c3))), 16.704 + 16.705 + clock_i2c4((Source(mux_pclock)), (Control(Clock_gate_i2c4))), 16.706 16.707 -uint32_t 16.708 -Cpm_jz4780_chip::get_cpu_source_frequency() 16.709 -{ 16.710 - switch (get_cpu_source()) 16.711 - { 16.712 - case Source_mux_main: 16.713 - return get_main_frequency(); 16.714 - case Source_mux_pll_M: 16.715 - return get_pll_frequency(Pll_control_M); 16.716 - case Source_mux_pll_E: 16.717 - return get_pll_frequency(Pll_control_E); 16.718 - default: 16.719 - return 0; 16.720 - } 16.721 -} 16.722 + clock_i2s0(Source(mux_i2s, Clock_source_i2s0), Control(Clock_gate_aic0)), 16.723 + 16.724 + clock_i2s1(Source(mux_i2s, Clock_source_i2s1), Control(Clock_gate_aic1)), 16.725 + 16.726 + clock_ipu((Source(mux_external)), (Control(Clock_gate_ipu))), 16.727 + 16.728 + clock_kbc((Source(mux_external)), (Control(Clock_gate_kbc))), 16.729 + 16.730 + clock_lcd((Source(mux_external)), (Control(Clock_gate_lcd))), 16.731 16.732 -uint8_t 16.733 -Cpm_jz4780_chip::get_hclock0_source() 16.734 -{ 16.735 - return get_field(Clock_control, 0x3, Clock_source_hclock0); 16.736 -} 16.737 + clock_main(Source(mux_main, Clock_source_main), Control(Clock_gate_main)), 16.738 + 16.739 + clock_mac((Source(mux_external)), (Control(Clock_gate_mac))), 16.740 + 16.741 + clock_msc((Source(mux_dev, Clock_source_msc))), 16.742 + 16.743 + clock_nemc((Source(mux_hclock2)), (Control(Clock_gate_nemc))), 16.744 16.745 -uint32_t 16.746 -Cpm_jz4780_chip::get_hclock0_source_frequency() 16.747 -{ 16.748 - switch (get_hclock0_source()) 16.749 - { 16.750 - case Source_mux_main: 16.751 - return get_main_frequency(); 16.752 - case Source_mux_pll_M: 16.753 - return get_pll_frequency(Pll_control_M); 16.754 - case Source_mux_pll_E: 16.755 - return get_pll_frequency(Pll_control_E); 16.756 - default: 16.757 - return 0; 16.758 - } 16.759 -} 16.760 + clock_otg0((Source(mux_external)), (Control(Clock_gate_otg0))), 16.761 + 16.762 + clock_otg1((Source(mux_external)), (Control(Clock_gate_otg1))), 16.763 + 16.764 + clock_owi((Source(mux_external)), (Control(Clock_gate_owi))), 16.765 + 16.766 + clock_sadc((Source(mux_external)), (Control(Clock_gate_sadc))), 16.767 + 16.768 + clock_scc((Source(mux_external)), (Control(Clock_gate_scc))), 16.769 16.770 -uint8_t 16.771 -Cpm_jz4780_chip::get_hclock2_source() 16.772 -{ 16.773 - return get_field(Clock_control, 0x3, Clock_source_hclock2); 16.774 -} 16.775 + clock_tssi0((Source(mux_external)), (Control(Clock_gate_tssi0))), 16.776 + 16.777 + clock_tssi1((Source(mux_external)), (Control(Clock_gate_tssi1))), 16.778 + 16.779 + clock_uart0((Source(mux_external)), (Control(Clock_gate_uart0))), 16.780 + 16.781 + clock_uart1((Source(mux_external)), (Control(Clock_gate_uart1))), 16.782 + 16.783 + clock_uart2((Source(mux_external)), (Control(Clock_gate_uart2))), 16.784 16.785 -uint32_t 16.786 -Cpm_jz4780_chip::get_hclock2_source_frequency() 16.787 -{ 16.788 - switch (get_hclock2_source()) 16.789 - { 16.790 - case Source_mux_main: 16.791 - return get_main_frequency(); 16.792 - case Source_mux_pll_M: 16.793 - return get_pll_frequency(Pll_control_M); 16.794 - case Source_mux_realtime: 16.795 - return _rtclk_freq; // "TCK" in the manual, RTCLK in Linux driver code 16.796 - default: 16.797 - return 0; 16.798 - } 16.799 -} 16.800 + clock_uart3((Source(mux_external)), (Control(Clock_gate_uart3))), 16.801 + 16.802 + clock_x2d((Source(mux_external)), (Control(Clock_gate_x2d))), 16.803 16.804 -void 16.805 -Cpm_jz4780_chip::set_hclock2_source(uint8_t source) 16.806 -{ 16.807 - set_field(Clock_control, 0x3, Clock_source_hclock2, source); 16.808 -} 16.809 + // Special parent clock for hclock2 and pclock. 16.810 + 16.811 + clock_hclock2_pclock(Source(mux_ahb2, Clock_source_hclock2)), 16.812 + 16.813 + // SSI channel clocks depending on a common parent divider. 16.814 16.815 -uint8_t 16.816 -Cpm_jz4780_chip::get_hdmi_source() 16.817 -{ 16.818 - return get_field(Hdmi_divider, 0x3, Clock_source_hdmi); 16.819 -} 16.820 + clock_ssi0((Source(mux_clock_ssi)), Control(Clock_gate_ssi0)), 16.821 + 16.822 + clock_ssi1((Source(mux_clock_ssi)), Control(Clock_gate_ssi1)), 16.823 + 16.824 + clock_ssi2((Source(mux_clock_ssi)), Control(Clock_gate_ssi2)); 16.825 16.826 -uint32_t 16.827 -Cpm_jz4780_chip::get_hdmi_source_frequency() 16.828 -{ 16.829 - switch (get_hdmi_source()) 16.830 - { 16.831 - case Source_main: 16.832 - return get_main_frequency(); 16.833 - case Source_pll_M: 16.834 - return get_pll_frequency(Pll_control_M); 16.835 - case Source_pll_V: 16.836 - return get_pll_frequency(Pll_control_V); 16.837 - default: 16.838 - return 0; 16.839 - } 16.840 -} 16.841 +static Clock_divided 16.842 + clock_bch(Source(mux_core, Clock_source_bch), 16.843 + Control(Clock_gate_bch, Clock_change_enable_bch, Clock_busy_bch), 16.844 + Divider(Clock_divider_bch)), 16.845 + 16.846 + clock_cim(Source(mux_cim, Clock_source_cim), 16.847 + Control(Clock_gate_cim, Clock_change_enable_cim, Clock_busy_cim), 16.848 + Divider(Clock_divider_cim)), 16.849 16.850 -void 16.851 -Cpm_jz4780_chip::set_hdmi_source(uint8_t source) 16.852 -{ 16.853 - // Stop clock and enable change. 16.854 + clock_cpu(Source(mux_core, Clock_source_cpu), 16.855 + Control(Field::undefined, Clock_change_enable_cpu, Clock_busy_cpu), 16.856 + Divider(Clock_divider_cpu)), 16.857 16.858 - _regs[Hdmi_divider] = _regs[Hdmi_divider] | Hdmi_change_enable | Hdmi_clock_stop; 16.859 - 16.860 - // Set the source. 16.861 - 16.862 - set_field(Hdmi_divider, 0x03, Clock_source_hdmi, source); 16.863 + clock_ddr(Source(mux_dev, Clock_source_ddr), 16.864 + Control(Clock_gate_ddr, Clock_change_enable_ddr, Clock_busy_ddr), 16.865 + Divider(Clock_divider_ddr)), 16.866 16.867 - // Restart clock and disable change. 16.868 - 16.869 - while (_regs[Hdmi_divider] & Hdmi_change_busy); 16.870 - _regs[Hdmi_divider] = _regs[Hdmi_divider] & ~(Hdmi_change_enable | Hdmi_clock_stop); 16.871 -} 16.872 + clock_gpu(Source(mux_core, Clock_source_gpu), 16.873 + Control(Clock_gate_gpu, Clock_change_enable_gpu, Clock_busy_gpu), 16.874 + Divider(Clock_divider_gpu)), 16.875 16.876 -uint8_t 16.877 -Cpm_jz4780_chip::get_lcd_source(uint8_t controller) 16.878 -{ 16.879 - return get_field(controller ? Lcd_divider1 : Lcd_divider0, 0x3, Clock_source_lcd); 16.880 -} 16.881 + clock_hclock0(Source(mux_core, Clock_source_hclock0), 16.882 + Control(Field::undefined, Clock_change_enable_ahb0), 16.883 + Divider(Clock_divider_hclock0)), 16.884 + 16.885 + clock_hclock2(Source(mux_hclock2_pclock), 16.886 + Control(Field::undefined, Clock_change_enable_ahb2), 16.887 + Divider(Clock_divider_hclock2)), 16.888 16.889 -uint32_t 16.890 -Cpm_jz4780_chip::get_lcd_source_frequency(uint8_t controller) 16.891 -{ 16.892 - switch (get_lcd_source(controller)) 16.893 - { 16.894 - case Source_main: 16.895 - return get_main_frequency(); 16.896 - case Source_pll_M: 16.897 - return get_pll_frequency(Pll_control_M); 16.898 - case Source_pll_V: 16.899 - return get_pll_frequency(Pll_control_V); 16.900 - default: 16.901 - return 0; 16.902 - } 16.903 -} 16.904 + clock_hdmi(Source(mux_lcd, Clock_source_hdmi), 16.905 + Control(Clock_gate_hdmi, Clock_change_enable_hdmi, Clock_busy_hdmi), 16.906 + Divider(Clock_divider_hdmi)), 16.907 + 16.908 + clock_lcd_pixel0(Source(mux_lcd, Clock_source_lcd0), 16.909 + Control(Clock_gate_lcd, Clock_change_enable_lcd0, Clock_busy_lcd0), 16.910 + Divider(Clock_divider_lcd0)), 16.911 16.912 -void 16.913 -Cpm_jz4780_chip::set_lcd_source(uint8_t controller, uint8_t source) 16.914 -{ 16.915 - uint32_t divider = controller ? Lcd_divider1 : Lcd_divider0; 16.916 + clock_lcd_pixel1(Source(mux_lcd, Clock_source_lcd1), 16.917 + Control(Clock_gate_lcd, Clock_change_enable_lcd1, Clock_busy_lcd1), 16.918 + Divider(Clock_divider_lcd1)), 16.919 16.920 - // Stop clock and enable change. 16.921 + clock_msc0(Source(mux_clock_msc), 16.922 + Control(Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0), 16.923 + Divider(Clock_divider_msc0)), 16.924 16.925 - _regs[divider] = _regs[divider] | Lcd_change_enable | Lcd_clock_stop; 16.926 + clock_msc1(Source(mux_clock_msc), 16.927 + Control(Clock_gate_msc1, Clock_change_enable_msc1, Clock_busy_msc1), 16.928 + Divider(Clock_divider_msc1)), 16.929 16.930 - // Set the source. 16.931 - 16.932 - set_field(divider, 0x03, Clock_source_lcd, source); 16.933 + clock_msc2(Source(mux_clock_msc), 16.934 + Control(Clock_gate_msc2, Clock_change_enable_msc2, Clock_busy_msc2), 16.935 + Divider(Clock_divider_msc2)), 16.936 16.937 - // Restart clock and disable change. 16.938 - 16.939 - while (_regs[divider] & Lcd_change_busy); 16.940 - _regs[divider] = _regs[divider] & ~(Lcd_change_enable | Lcd_clock_stop); 16.941 -} 16.942 + clock_pcm(Source(mux_pcm, Clock_source_pcm), 16.943 + Control(Clock_gate_pcm, Clock_change_enable_pcm, Clock_busy_pcm), 16.944 + Divider(Clock_divider_pcm)), 16.945 16.946 -uint8_t 16.947 -Cpm_jz4780_chip::get_pclock_source() 16.948 -{ 16.949 - return get_hclock2_source(); 16.950 -} 16.951 + clock_pclock(Source(mux_hclock2_pclock), 16.952 + Control(Field::undefined, Clock_change_enable_ahb2), 16.953 + Divider(Clock_divider_pclock)), 16.954 16.955 -uint32_t 16.956 -Cpm_jz4780_chip::get_pclock_source_frequency() 16.957 -{ 16.958 - return get_hclock2_source_frequency(); 16.959 -} 16.960 + clock_ssi(Source(mux_ssi, Clock_source_ssi), 16.961 + Control(Field::undefined, Clock_change_enable_ssi, Clock_busy_ssi), 16.962 + Divider(Clock_divider_ssi)), 16.963 16.964 -void 16.965 -Cpm_jz4780_chip::set_pclock_source(uint8_t source) 16.966 -{ 16.967 - set_hclock2_source(source); 16.968 -} 16.969 + clock_uhc(Source(mux_usb, Clock_source_uhc), 16.970 + Control(Clock_gate_uhc, Clock_change_enable_uhc, Clock_busy_uhc), 16.971 + Divider(Clock_divider_uhc)); 16.972 16.973 16.974 16.975 -// Source frequency, used by various clock sources. 16.976 - 16.977 -uint8_t 16.978 -Cpm_jz4780_chip::get_main_source() 16.979 -{ 16.980 - return get_field(Clock_control, 0x3, Clock_source_main); 16.981 -} 16.982 +const double jz4780_pll_intermediate_min = 300000000, 16.983 + jz4780_pll_intermediate_max = 1500000000; 16.984 16.985 -uint32_t 16.986 -Cpm_jz4780_chip::get_main_frequency() 16.987 -{ 16.988 - switch (get_main_source()) 16.989 - { 16.990 - case Source_pll_A: 16.991 - return get_pll_frequency(Pll_control_A); 16.992 - case Source_external: 16.993 - return _exclk_freq; 16.994 - case Source_realtime: 16.995 - return _rtclk_freq; 16.996 - default: 16.997 - return 0; 16.998 - } 16.999 -} 16.1000 - 16.1001 -// Clock frequency for the CPU. 16.1002 - 16.1003 -uint32_t 16.1004 -Cpm_jz4780_chip::get_cpu_frequency() 16.1005 -{ 16.1006 - return get_cpu_source_frequency() / get_cpu_divider(); 16.1007 -} 16.1008 - 16.1009 -// Clock frequency for fast peripherals. 16.1010 - 16.1011 -uint32_t 16.1012 -Cpm_jz4780_chip::get_hclock0_frequency() 16.1013 -{ 16.1014 - return get_hclock0_source_frequency() / get_hclock0_divider(); 16.1015 -} 16.1016 - 16.1017 -// Clock frequency for fast peripherals. 16.1018 +static Pll clock_pll_A(Source(mux_external), 16.1019 + Control_pll(Pll_enable_A, Pll_stable_A, Pll_bypass_A), 16.1020 + Divider_pll(Pll_multiplier_A, Pll_input_division_A, 16.1021 + Pll_output_division_A, 16.1022 + jz4780_pll_intermediate_min, jz4780_pll_intermediate_max)), 16.1023 16.1024 -uint32_t 16.1025 -Cpm_jz4780_chip::get_hclock2_frequency() 16.1026 -{ 16.1027 - return get_hclock2_source_frequency() / get_hclock2_divider(); 16.1028 -} 16.1029 - 16.1030 -// Clock frequency for slow peripherals. 16.1031 - 16.1032 -uint32_t 16.1033 -Cpm_jz4780_chip::get_pclock_frequency() 16.1034 -{ 16.1035 - return get_pclock_source_frequency() / get_pclock_divider(); 16.1036 -} 16.1037 - 16.1038 -// Clock frequency for the memory. 16.1039 - 16.1040 -uint32_t 16.1041 -Cpm_jz4780_chip::get_memory_frequency() 16.1042 -{ 16.1043 - return get_memory_source_frequency() / get_memory_divider(); 16.1044 -} 16.1045 + clock_pll_E(Source(mux_external), 16.1046 + Control_pll(Pll_enable_E, Pll_stable_E, Pll_bypass_E), 16.1047 + Divider_pll(Pll_multiplier_E, Pll_input_division_E, 16.1048 + Pll_output_division_E, 16.1049 + jz4780_pll_intermediate_min, jz4780_pll_intermediate_max)), 16.1050 16.1051 -uint32_t 16.1052 -Cpm_jz4780_chip::get_apll_frequency() 16.1053 -{ 16.1054 - return get_pll_frequency(Pll_control_A); 16.1055 -} 16.1056 - 16.1057 -uint32_t 16.1058 -Cpm_jz4780_chip::get_epll_frequency() 16.1059 -{ 16.1060 - return get_pll_frequency(Pll_control_E); 16.1061 -} 16.1062 + clock_pll_M(Source(mux_external), 16.1063 + Control_pll(Pll_enable_M, Pll_stable_M, Pll_bypass_M), 16.1064 + Divider_pll(Pll_multiplier_M, Pll_input_division_M, 16.1065 + Pll_output_division_M, 16.1066 + jz4780_pll_intermediate_min, jz4780_pll_intermediate_max)), 16.1067 16.1068 -uint32_t 16.1069 -Cpm_jz4780_chip::get_mpll_frequency() 16.1070 -{ 16.1071 - return get_pll_frequency(Pll_control_M); 16.1072 -} 16.1073 - 16.1074 -uint32_t 16.1075 -Cpm_jz4780_chip::get_vpll_frequency() 16.1076 -{ 16.1077 - return get_pll_frequency(Pll_control_V); 16.1078 -} 16.1079 + clock_pll_V(Source(mux_external), 16.1080 + Control_pll(Pll_enable_V, Pll_stable_V, Pll_bypass_V), 16.1081 + Divider_pll(Pll_multiplier_V, Pll_input_division_V, 16.1082 + Pll_output_division_V, 16.1083 + jz4780_pll_intermediate_min, jz4780_pll_intermediate_max)); 16.1084 16.1085 16.1086 16.1087 -uint32_t 16.1088 -Cpm_jz4780_chip::get_frequency(enum Clock_identifiers clock) 16.1089 -{ 16.1090 - switch (clock) 16.1091 - { 16.1092 - // NOTE: Returning only the frequency for controller 0. 16.1093 - 16.1094 - case Clock_lcd_pixel: 16.1095 - return get_lcd_source_frequency(0) / get_lcd_pixel_divider(0); 16.1096 - 16.1097 - case Clock_hdmi: 16.1098 - return get_hdmi_source_frequency() / get_hdmi_divider(); 16.1099 - 16.1100 - // NOTE: Consider a better error result. 16.1101 - 16.1102 - default: 16.1103 - return 0; 16.1104 - } 16.1105 -} 16.1106 - 16.1107 -void 16.1108 -Cpm_jz4780_chip::set_frequency(enum Clock_identifiers clock, uint32_t frequency) 16.1109 -{ 16.1110 - switch (clock) 16.1111 - { 16.1112 - // NOTE: HCLK/AHB0 must be 1.5 (for TFT) or 3 (for STN) times the pixel clock. 16.1113 - // NOTE: Here, the actual frequency value is ignored, but should at least be 16.1114 - // NOTE: tested. 16.1115 +// Clock register. 16.1116 16.1117 - case Clock_lcd: 16.1118 - set_lcd_source(0, Source_pll_V); 16.1119 - set_lcd_source(1, Source_pll_V); 16.1120 - pll_enable(Pll_control_V); 16.1121 - break; 16.1122 - 16.1123 - // Unlike the JZ4740, HCLK/AHB0 is used as the device frequency, with the pixel 16.1124 - // frequency being based on the selected clock source (SCLK_A, MPLL or VPLL). 16.1125 - 16.1126 - case Clock_lcd_pixel: 16.1127 - 16.1128 - // Switch to the video PLL and attempt to set the divider. 16.1129 +static Clock_base *clocks[Clock_identifier_count] = { 16.1130 + &clock_none, // Clock_aic 16.1131 + &clock_none, // Clock_aic_bitclk 16.1132 + &clock_none, // Clock_aic_pclk 16.1133 + &clock_none, // Clock_can0 16.1134 + &clock_none, // Clock_can1 16.1135 + &clock_none, // Clock_cdbus 16.1136 + &clock_cim, 16.1137 + &clock_cpu, 16.1138 + &clock_ddr, 16.1139 + &clock_dma, 16.1140 + &clock_none, // Clock_emac 16.1141 + &clock_external, 16.1142 + &clock_hclock0, 16.1143 + &clock_hclock2, 16.1144 + &clock_hclock2_pclock, 16.1145 + &clock_hdmi, 16.1146 + &clock_i2c0, 16.1147 + &clock_i2c1, 16.1148 + &clock_i2c2, 16.1149 + &clock_i2c3, 16.1150 + &clock_i2c4, 16.1151 + &clock_i2s0, 16.1152 + &clock_none, // Clock_i2s0_rx 16.1153 + &clock_none, // Clock_i2s0_tx 16.1154 + &clock_i2s1, 16.1155 + &clock_none, // Clock_i2s1_rx 16.1156 + &clock_none, // Clock_i2s1_tx 16.1157 + &clock_none, // Clock_kbc 16.1158 + &clock_lcd, 16.1159 + &clock_lcd_pixel0, 16.1160 + &clock_lcd_pixel1, 16.1161 + &clock_mac, 16.1162 + &clock_main, 16.1163 + &clock_none, // Clock_mipi_csi 16.1164 + &clock_msc, 16.1165 + &clock_msc0, 16.1166 + &clock_msc1, 16.1167 + &clock_msc2, 16.1168 + &clock_none, // Clock_none 16.1169 + &clock_otg0, 16.1170 + &clock_otg1, 16.1171 + &clock_pclock, 16.1172 + &clock_pll_A, 16.1173 + &clock_pll_E, 16.1174 + &clock_pll_M, 16.1175 + &clock_pll_V, 16.1176 + &clock_none, // Clock_pwm0 16.1177 + &clock_none, // Clock_pwm1 16.1178 + &clock_rtc, 16.1179 + &clock_scc, 16.1180 + &clock_none, // Clock_sfc 16.1181 + &clock_ssi, 16.1182 + &clock_ssi0, 16.1183 + &clock_ssi1, 16.1184 + &clock_ssi2, 16.1185 + &clock_none, // Clock_timer 16.1186 + &clock_uart0, 16.1187 + &clock_uart1, 16.1188 + &clock_uart2, 16.1189 + &clock_uart3, 16.1190 + &clock_none, // Clock_udc 16.1191 + &clock_uhc, 16.1192 + &clock_none, // Clock_uprt 16.1193 +}; 16.1194 16.1195 - set_lcd_pixel_divider(0, get_lcd_source_frequency() / frequency); 16.1196 - set_lcd_pixel_divider(1, get_lcd_source_frequency() / frequency); 16.1197 - break; 16.1198 + 16.1199 16.1200 - case Clock_hdmi: 16.1201 - 16.1202 - // Switch to the video PLL and attempt to set the divider. 16.1203 +// Peripheral abstraction. 16.1204 16.1205 - set_hdmi_source(Source_pll_V); 16.1206 - pll_enable(Pll_control_V); 16.1207 - set_hdmi_divider(get_hdmi_source_frequency() / frequency); 16.1208 - break; 16.1209 - 16.1210 - default: 16.1211 - break; 16.1212 - } 16.1213 +Cpm_jz4780_chip::Cpm_jz4780_chip(l4_addr_t addr) 16.1214 +: Cpm_chip(addr, clocks) 16.1215 +{ 16.1216 } 16.1217 16.1218 16.1219 @@ -809,10 +543,7 @@ 16.1220 void 16.1221 *jz4780_cpm_init(l4_addr_t cpm_base) 16.1222 { 16.1223 - /* Initialise the clock and power management peripheral with the 16.1224 - register memory region and a 48MHz EXCLK frequency. */ 16.1225 - 16.1226 - return (void *) new Cpm_jz4780_chip(cpm_base, 48000000, 32768); 16.1227 + return (void *) new Cpm_jz4780_chip(cpm_base); 16.1228 } 16.1229 16.1230 int 16.1231 @@ -833,216 +564,56 @@ 16.1232 static_cast<Cpm_jz4780_chip *>(cpm)->stop_clock(clock); 16.1233 } 16.1234 16.1235 - 16.1236 - 16.1237 -uint8_t 16.1238 -jz4780_cpm_get_cpu_divider(void *cpm) 16.1239 -{ 16.1240 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_cpu_divider(); 16.1241 -} 16.1242 - 16.1243 -uint8_t 16.1244 -jz4780_cpm_get_hclock0_divider(void *cpm) 16.1245 -{ 16.1246 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_hclock0_divider(); 16.1247 +int 16.1248 +jz4780_cpm_get_parameters(void *cpm, enum Clock_identifiers clock, uint32_t parameters[]) 16.1249 +{ 16.1250 + return static_cast<Cpm_jz4780_chip *>(cpm)->get_parameters(clock, parameters); 16.1251 } 16.1252 16.1253 -uint8_t 16.1254 -jz4780_cpm_get_hclock2_divider(void *cpm) 16.1255 -{ 16.1256 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_hclock2_divider(); 16.1257 -} 16.1258 - 16.1259 -uint8_t 16.1260 -jz4780_cpm_get_hdmi_divider(void *cpm) 16.1261 -{ 16.1262 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_hdmi_divider(); 16.1263 -} 16.1264 - 16.1265 -uint8_t 16.1266 -jz4780_cpm_get_lcd_pixel_divider(void *cpm) 16.1267 -{ 16.1268 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_lcd_pixel_divider(); 16.1269 -} 16.1270 - 16.1271 -uint8_t 16.1272 -jz4780_cpm_get_memory_divider(void *cpm) 16.1273 -{ 16.1274 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_memory_divider(); 16.1275 +int 16.1276 +jz4780_cpm_set_parameters(void *cpm, enum Clock_identifiers clock, int num_parameters, uint32_t parameters[]) 16.1277 +{ 16.1278 + return static_cast<Cpm_jz4780_chip *>(cpm)->set_parameters(clock, num_parameters, parameters); 16.1279 } 16.1280 16.1281 uint8_t 16.1282 -jz4780_cpm_get_pclock_divider(void *cpm) 16.1283 -{ 16.1284 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_pclock_divider(); 16.1285 -} 16.1286 - 16.1287 - 16.1288 - 16.1289 -uint8_t 16.1290 -jz4780_cpm_get_hclock0_source(void *cpm) 16.1291 -{ 16.1292 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_hclock0_source(); 16.1293 -} 16.1294 - 16.1295 -uint8_t 16.1296 -jz4780_cpm_get_hclock2_source(void *cpm) 16.1297 -{ 16.1298 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_hclock2_source(); 16.1299 -} 16.1300 - 16.1301 -uint8_t 16.1302 -jz4780_cpm_get_hdmi_source(void *cpm) 16.1303 -{ 16.1304 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_hdmi_source(); 16.1305 -} 16.1306 - 16.1307 -uint8_t 16.1308 -jz4780_cpm_get_lcd_source(void *cpm) 16.1309 -{ 16.1310 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_lcd_source(); 16.1311 -} 16.1312 - 16.1313 -uint8_t 16.1314 -jz4780_cpm_get_memory_source(void *cpm) 16.1315 -{ 16.1316 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_memory_source(); 16.1317 -} 16.1318 - 16.1319 -uint8_t 16.1320 -jz4780_cpm_get_pclock_source(void *cpm) 16.1321 -{ 16.1322 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_pclock_source(); 16.1323 +jz4780_cpm_get_source(void *cpm, enum Clock_identifiers clock) 16.1324 +{ 16.1325 + return static_cast<Cpm_jz4780_chip *>(cpm)->get_source(clock); 16.1326 } 16.1327 16.1328 void 16.1329 -jz4780_cpm_set_pclock_source(void *cpm, uint8_t source) 16.1330 -{ 16.1331 - static_cast<Cpm_jz4780_chip *>(cpm)->set_pclock_source(source); 16.1332 +jz4780_cpm_set_source(void *cpm, enum Clock_identifiers clock, uint8_t source) 16.1333 +{ 16.1334 + static_cast<Cpm_jz4780_chip *>(cpm)->set_source(clock, source); 16.1335 } 16.1336 16.1337 - 16.1338 - 16.1339 -uint32_t 16.1340 -jz4780_cpm_get_hclock0_source_frequency(void *cpm) 16.1341 -{ 16.1342 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_hclock0_source_frequency(); 16.1343 +enum Clock_identifiers 16.1344 +jz4780_cpm_get_source_clock(void *cpm, enum Clock_identifiers clock) 16.1345 +{ 16.1346 + return static_cast<Cpm_jz4780_chip *>(cpm)->get_source_clock(clock); 16.1347 } 16.1348 16.1349 -uint32_t 16.1350 -jz4780_cpm_get_hclock2_source_frequency(void *cpm) 16.1351 -{ 16.1352 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_hclock2_source_frequency(); 16.1353 +void 16.1354 +jz4780_cpm_set_source_clock(void *cpm, enum Clock_identifiers clock, enum Clock_identifiers source) 16.1355 +{ 16.1356 + static_cast<Cpm_jz4780_chip *>(cpm)->set_source_clock(clock, source); 16.1357 } 16.1358 16.1359 uint32_t 16.1360 -jz4780_cpm_get_hdmi_source_frequency(void *cpm) 16.1361 -{ 16.1362 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_hdmi_source_frequency(); 16.1363 -} 16.1364 - 16.1365 -uint32_t 16.1366 -jz4780_cpm_get_lcd_source_frequency(void *cpm) 16.1367 -{ 16.1368 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_lcd_source_frequency(); 16.1369 -} 16.1370 - 16.1371 -uint32_t 16.1372 -jz4780_cpm_get_memory_source_frequency(void *cpm) 16.1373 -{ 16.1374 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_memory_source_frequency(); 16.1375 -} 16.1376 - 16.1377 -uint32_t 16.1378 -jz4780_cpm_get_pclock_source_frequency(void *cpm) 16.1379 -{ 16.1380 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_pclock_source_frequency(); 16.1381 -} 16.1382 - 16.1383 - 16.1384 - 16.1385 -uint8_t 16.1386 -jz4780_cpm_get_main_source(void *cpm) 16.1387 -{ 16.1388 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_main_source(); 16.1389 -} 16.1390 - 16.1391 -uint32_t 16.1392 -jz4780_cpm_get_main_frequency(void *cpm) 16.1393 -{ 16.1394 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_main_frequency(); 16.1395 -} 16.1396 - 16.1397 -uint32_t 16.1398 -jz4780_cpm_get_cpu_frequency(void *cpm) 16.1399 -{ 16.1400 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_cpu_frequency(); 16.1401 -} 16.1402 - 16.1403 -uint32_t 16.1404 -jz4780_cpm_get_hclock0_frequency(void *cpm) 16.1405 -{ 16.1406 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_hclock0_frequency(); 16.1407 +jz4780_cpm_get_source_frequency(void *cpm, enum Clock_identifiers clock) 16.1408 +{ 16.1409 + return static_cast<Cpm_jz4780_chip *>(cpm)->get_source_frequency(clock); 16.1410 } 16.1411 16.1412 uint32_t 16.1413 -jz4780_cpm_get_hclock2_frequency(void *cpm) 16.1414 -{ 16.1415 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_hclock2_frequency(); 16.1416 -} 16.1417 - 16.1418 -uint32_t 16.1419 -jz4780_cpm_get_memory_frequency(void *cpm) 16.1420 -{ 16.1421 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_memory_frequency(); 16.1422 -} 16.1423 - 16.1424 -uint32_t 16.1425 -jz4780_cpm_get_pclock_frequency(void *cpm) 16.1426 -{ 16.1427 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_pclock_frequency(); 16.1428 -} 16.1429 - 16.1430 -uint32_t 16.1431 -jz4780_cpm_get_apll_frequency(void *cpm) 16.1432 -{ 16.1433 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_apll_frequency(); 16.1434 -} 16.1435 - 16.1436 -uint32_t 16.1437 -jz4780_cpm_get_epll_frequency(void *cpm) 16.1438 -{ 16.1439 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_epll_frequency(); 16.1440 -} 16.1441 - 16.1442 -uint32_t 16.1443 -jz4780_cpm_get_mpll_frequency(void *cpm) 16.1444 -{ 16.1445 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_mpll_frequency(); 16.1446 -} 16.1447 - 16.1448 -uint32_t 16.1449 -jz4780_cpm_get_vpll_frequency(void *cpm) 16.1450 -{ 16.1451 - return static_cast<Cpm_jz4780_chip *>(cpm)->get_vpll_frequency(); 16.1452 -} 16.1453 - 16.1454 - 16.1455 - 16.1456 -uint32_t 16.1457 jz4780_cpm_get_frequency(void *cpm, enum Clock_identifiers clock) 16.1458 -{ 16.1459 +{ 16.1460 return static_cast<Cpm_jz4780_chip *>(cpm)->get_frequency(clock); 16.1461 } 16.1462 16.1463 -void 16.1464 +int 16.1465 jz4780_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency) 16.1466 { 16.1467 - static_cast<Cpm_jz4780_chip *>(cpm)->set_frequency(clock, frequency); 16.1468 + return static_cast<Cpm_jz4780_chip *>(cpm)->set_frequency(clock, frequency); 16.1469 } 16.1470 - 16.1471 -void 16.1472 -jz4780_cpm_set_mpll_parameters(void *cpm, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider) 16.1473 -{ 16.1474 - static_cast<Cpm_jz4780_chip *>(cpm)->set_pll_parameters(Pll_control_M, multiplier, in_divider, out_divider); 16.1475 -}
17.1 --- a/pkg/devices/lib/cpm/src/x1600.cc Tue Oct 24 18:52:06 2023 +0200 17.2 +++ b/pkg/devices/lib/cpm/src/x1600.cc Fri Oct 27 18:02:49 2023 +0200 17.3 @@ -23,8 +23,6 @@ 17.4 17.5 #include <l4/devices/hw_mmio_register_block.h> 17.6 #include "cpm-x1600.h" 17.7 -#include <math.h> 17.8 -#include <stdio.h> 17.9 17.10 17.11 17.12 @@ -38,6 +36,11 @@ 17.13 Clock_gate1 = 0x028, // CLKGR1 17.14 Sleep_control = 0x024, // OPCR (oscillator and power control) 17.15 Clock_status = 0x0d4, // CPCSR 17.16 + 17.17 + Divider_can0 = 0x0a0, // CAN0CDR 17.18 + Divider_can1 = 0x0a8, // CAN1CDR 17.19 + Divider_cdbus = 0x0ac, // CDBUSCDR 17.20 + Divider_cim = 0x078, // CIMCDR 17.21 Divider_ddr = 0x02c, // DDRCDR 17.22 Divider_mac = 0x054, // MACCDR 17.23 Divider0_i2s0 = 0x060, // I2S0CDR 17.24 @@ -45,26 +48,26 @@ 17.25 Divider0_i2s1 = 0x07c, // I2S1CDR (from X2000 manual) 17.26 Divider1_i2s1 = 0x080, // I2S1CDR1 (from X2000 manual) 17.27 Divider_lcd = 0x064, // LPCDR 17.28 + Divider_macphy0 = 0x0e4, // MPHY0C 17.29 Divider_msc0 = 0x068, // MSC0CDR 17.30 Divider_msc1 = 0x0a4, // MSC1CDR 17.31 + Divider_pwm = 0x06c, // PWMCDR 17.32 Divider_sfc = 0x074, // SFCCDR 17.33 Divider_ssi = 0x05c, // SSICDR 17.34 - Divider_cim = 0x078, // CIMCDR 17.35 - Divider_pwm = 0x06c, // PWMCDR 17.36 - Divider_can0 = 0x0a0, // CAN0CDR 17.37 - Divider_can1 = 0x0a8, // CAN1CDR 17.38 - Divider_cdbus = 0x0ac, // CDBUSCDR 17.39 - Divider_macphy0 = 0x0e4, // MPHY0C 17.40 + 17.41 Cpm_interrupt = 0x0b0, // CPM_INTR 17.42 Cpm_interrupt_en = 0x0b4, // CPM_INTRE 17.43 Cpm_swi = 0x0bc, // CPM_SFTINT 17.44 - Ddr_gate = 0x0d0, // DRCG 17.45 + Cpm_scratch = 0x034, // CPSPR 17.46 Cpm_scratch_prot = 0x038, // CPSPPR 17.47 - Cpm_scratch = 0x034, // CPSPR 17.48 + 17.49 + Gate_ddr = 0x0d0, // DRCG 17.50 + 17.51 Usb_param_control0 = 0x03c, // USBPCR 17.52 Usb_reset_detect = 0x040, // USBRDT 17.53 Usb_vbus_jitter = 0x044, // USBVBFIL 17.54 Usb_param_control1 = 0x048, // USBPCR1 17.55 + 17.56 Pll_control = 0x00c, // CPPCR 17.57 Pll_control_A = 0x010, // CPAPCR 17.58 Pll_control_M = 0x014, // CPMPCR 17.59 @@ -74,17 +77,6 @@ 17.60 Pll_fraction_E = 0x08c, // CPEPACR 17.61 }; 17.62 17.63 -enum Clock_source_values : unsigned 17.64 -{ 17.65 - Source_mME_main = 0, 17.66 - Source_mME_pll_M = 1, 17.67 - Source_mME_pll_E = 2, 17.68 - 17.69 - // Special value 17.70 - 17.71 - Source_mask = 0x3, 17.72 -}; 17.73 - 17.74 17.75 17.76 // Register field definitions. 17.77 @@ -109,6 +101,8 @@ 17.78 Clock_source_ssi (Divider_ssi, 3, 30), // SPCS 17.79 17.80 Clock_busy_cpu (Clock_status, 1, 0), 17.81 + Clock_busy_hclock0 (Clock_status, 1, 1), 17.82 + Clock_busy_hclock2 (Clock_status, 1, 2), 17.83 Clock_busy_ddr (Divider_ddr, 1, 28), 17.84 Clock_busy_mac (Divider_mac, 1, 28), 17.85 Clock_busy_lcd (Divider_lcd, 1, 28), 17.86 @@ -140,26 +134,26 @@ 17.87 Clock_change_enable_can1 (Divider_can1, 1, 29), 17.88 Clock_change_enable_cdbus (Divider_cdbus, 1, 29), 17.89 17.90 + Clock_divider_cpu (Clock_control, 0x0f, 0), // CDIV 17.91 + Clock_divider_hclock0 (Clock_control, 0x0f, 8), // H0DIV (fast AHB peripherals) 17.92 + Clock_divider_hclock2 (Clock_control, 0x0f, 12), // H2DIV (fast AHB peripherals) 17.93 + Clock_divider_l2cache (Clock_control, 0x0f, 4), // L2CDIV 17.94 + Clock_divider_pclock (Clock_control, 0x0f, 16), // PDIV (slow APB peripherals) 17.95 Clock_divider_can0 (Divider_can0, 0xff, 0), // CAN0CDR 17.96 Clock_divider_can1 (Divider_can1, 0xff, 0), // CAN1CDR 17.97 Clock_divider_cdbus (Divider_cdbus, 0xff, 0), // CDBUSCDR 17.98 Clock_divider_cim (Divider_cim, 0xff, 0), // CIMCDR 17.99 - Clock_divider_cpu (Clock_control, 0x0f, 0), // CDIV 17.100 Clock_divider_ddr (Divider_ddr, 0x0f, 0), // DDRCDR 17.101 - Clock_divider_hclock0 (Clock_control, 0x0f, 8), // H0DIV (fast AHB peripherals) 17.102 - Clock_divider_hclock2 (Clock_control, 0x0f, 12), // H2DIV (fast AHB peripherals) 17.103 Clock_divider_i2s0_m (Divider0_i2s0, 0x1ff, 20), // I2SDIV_M 17.104 Clock_divider_i2s0_n (Divider0_i2s0, 0xfffff, 0), // I2SDIV_N 17.105 Clock_divider_i2s0_d (Divider1_i2s0, 0xfffff, 0), // I2SDIV_D 17.106 Clock_divider_i2s1_m (Divider0_i2s1, 0x1ff, 20), // I2SDIV_M 17.107 Clock_divider_i2s1_n (Divider0_i2s1, 0xfffff, 0), // I2SDIV_N 17.108 Clock_divider_i2s1_d (Divider1_i2s1, 0xfffff, 0), // I2SDIV_D 17.109 - Clock_divider_l2cache (Clock_control, 0x0f, 4), // L2CDIV 17.110 Clock_divider_lcd (Divider_lcd, 0xff, 0), // LPCDR 17.111 Clock_divider_mac (Divider_mac, 0xff, 0), // MACCDR 17.112 Clock_divider_msc0 (Divider_msc0, 0xff, 0), // MSC0CDR 17.113 Clock_divider_msc1 (Divider_msc1, 0xff, 0), // MSC1CDR 17.114 - Clock_divider_pclock (Clock_control, 0x0f, 16), // PDIV (slow APB peripherals) 17.115 Clock_divider_pwm (Divider_pwm, 0x0f, 0), // PWMCDR 17.116 Clock_divider_sfc (Divider_sfc, 0xff, 0), // SFCCDR 17.117 Clock_divider_ssi (Divider_ssi, 0xff, 0), // SSICDR 17.118 @@ -186,7 +180,7 @@ 17.119 Clock_gate_uart1 (Clock_gate0, 1, 15, true), // UART1 17.120 Clock_gate_uart0 (Clock_gate0, 1, 14, true), // UART0 17.121 Clock_gate_sadc (Clock_gate0, 1, 13, true), // SADC 17.122 - Clock_gate_audio (Clock_gate0, 1, 11, true), // AUDIO 17.123 + Clock_gate_aic (Clock_gate0, 1, 11, true), // AUDIO 17.124 Clock_gate_ssi_slv (Clock_gate0, 1, 10, true), // SSI_SLV 17.125 Clock_gate_i2c1 (Clock_gate0, 1, 8, true), // I2C1 17.126 Clock_gate_i2c0 (Clock_gate0, 1, 7, true), // I2C0 17.127 @@ -244,16 +238,23 @@ 17.128 #define Clocks(...) ((enum Clock_identifiers []) {__VA_ARGS__}) 17.129 17.130 static Mux mux_external (Clock_external), 17.131 - mux_hclock0 (Clock_hclock0), 17.132 - mux_hclock2 (Clock_hclock2), 17.133 - mux_pclock (Clock_pclock), 17.134 - mux_main (3, Clocks(Clock_none, Clock_external, Clock_pll_A)), 17.135 + 17.136 + // Clocks being propagated to others. 17.137 + 17.138 + mux_hclock0 (Clock_hclock0), 17.139 + mux_hclock2 (Clock_hclock2), 17.140 + mux_pclock (Clock_pclock), 17.141 + mux_hclock2_pclock (Clock_hclock2_pclock), 17.142 + mux_i2s0_rx (Clock_i2s0), 17.143 + mux_i2s0_tx (Clock_i2s1), 17.144 + 17.145 + // Main peripheral and bus clock sources. 17.146 + 17.147 + mux_bus (4, Clocks(Clock_main, Clock_pll_M, Clock_pll_E, Clock_external)), 17.148 mux_core (3, Clocks(Clock_none, Clock_main, Clock_pll_M)), 17.149 - mux_bus (4, Clocks(Clock_main, Clock_pll_M, Clock_pll_E, Clock_external)), 17.150 mux_dev (3, Clocks(Clock_main, Clock_pll_M, Clock_pll_E)), 17.151 - mux_i2s (2, Clocks(Clock_main, Clock_pll_E)), 17.152 - mux_i2s0_rx (Clock_i2s0), 17.153 - mux_i2s0_tx (Clock_i2s1); 17.154 + mux_main (3, Clocks(Clock_none, Clock_external, Clock_pll_A)), 17.155 + mux_i2s (2, Clocks(Clock_main, Clock_pll_E)); 17.156 17.157 17.158 17.159 @@ -261,17 +262,15 @@ 17.160 17.161 static Clock_null clock_none; 17.162 17.163 -static Clock_passive clock_external; 17.164 +static Clock_passive clock_external(24000000); 17.165 17.166 // Note the use of extra parentheses due to the annoying C++ "most vexing parse" 17.167 // problem. See: https://en.wikipedia.org/wiki/Most_vexing_parse 17.168 17.169 -static Clock clock_audio((Source(mux_hclock2)), (Control(Clock_gate_audio))), 17.170 +static Clock clock_aic((Source(mux_hclock2)), (Control(Clock_gate_aic))), 17.171 17.172 clock_dma((Source(mux_hclock2)), (Control(Clock_gate_dma))), 17.173 17.174 - clock_i2c((Source(mux_pclock)), (Control(Clock_gate_i2c0))), 17.175 - 17.176 clock_i2c0((Source(mux_pclock)), (Control(Clock_gate_i2c0))), 17.177 17.178 clock_i2c1((Source(mux_pclock)), (Control(Clock_gate_i2c1))), 17.179 @@ -284,7 +283,7 @@ 17.180 17.181 clock_mipi_csi((Source(mux_hclock0)), Control(Clock_gate_mipi_csi)), 17.182 17.183 - clock_otg((Source(mux_hclock2)), (Control(Clock_gate_otg))), 17.184 + clock_otg0((Source(mux_hclock2)), (Control(Clock_gate_otg))), 17.185 17.186 clock_timer((Source(mux_pclock)), (Control(Clock_gate_timer))), 17.187 17.188 @@ -294,7 +293,12 @@ 17.189 17.190 clock_uart2((Source(mux_external)), (Control(Clock_gate_uart2))), 17.191 17.192 - clock_uart3((Source(mux_external)), (Control(Clock_gate_uart3))); 17.193 + clock_uart3((Source(mux_external)), (Control(Clock_gate_uart3))), 17.194 + 17.195 + // Special parent clock for hclock2 and pclock. 17.196 + 17.197 + clock_hclock2_pclock(Source(mux_core, Clock_source_hclock2), 17.198 + Control(Clock_gate_apb0, Clock_change_enable_ahb2)); 17.199 17.200 static Clock_divided 17.201 clock_can0(Source(mux_bus, Clock_source_can0), 17.202 @@ -325,9 +329,7 @@ 17.203 Control(Clock_gate_ahb0, Clock_change_enable_ahb0), 17.204 Divider(Clock_divider_hclock0)), 17.205 17.206 - clock_hclock2(Source(mux_core, Clock_source_hclock2), 17.207 - Control(Clock_gate_apb0, Clock_change_enable_ahb2), 17.208 - Divider(Clock_divider_hclock2)), 17.209 + clock_hclock2((Source(mux_hclock2_pclock)), (Divider(Clock_divider_hclock2))), 17.210 17.211 clock_lcd_pixel(Source(mux_dev, Clock_source_lcd), 17.212 Control(Clock_gate_lcd_pixel, Clock_change_enable_lcd, Clock_busy_lcd), 17.213 @@ -337,10 +339,6 @@ 17.214 Control(Clock_gate_gmac0, Clock_change_enable_mac, Clock_busy_mac), 17.215 Divider(Clock_divider_mac)), 17.216 17.217 - clock_msc(Source(mux_dev, Clock_source_msc0), 17.218 - Control(Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0), 17.219 - Divider(Clock_divider_msc0)), 17.220 - 17.221 clock_msc0(Source(mux_dev, Clock_source_msc0), 17.222 Control(Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0), 17.223 Divider(Clock_divider_msc0)), 17.224 @@ -349,13 +347,7 @@ 17.225 Control(Clock_gate_msc1, Clock_change_enable_msc1, Clock_busy_msc1), 17.226 Divider(Clock_divider_msc1)), 17.227 17.228 - clock_pclock(Source(mux_core, Clock_source_hclock2), 17.229 - Control(Clock_gate_apb0, Clock_change_enable_ahb2), 17.230 - Divider(Clock_divider_pclock)), 17.231 - 17.232 - clock_pwm(Source(mux_dev, Clock_source_pwm), 17.233 - Control(Clock_gate_pwm, Clock_change_enable_pwm, Clock_busy_pwm), 17.234 - Divider(Clock_divider_pwm)), 17.235 + clock_pclock((Source(mux_hclock2_pclock)), (Divider(Clock_divider_pclock))), 17.236 17.237 clock_pwm0(Source(mux_dev, Clock_source_pwm), 17.238 Control(Clock_gate_pwm, Clock_change_enable_pwm, Clock_busy_pwm), 17.239 @@ -365,9 +357,9 @@ 17.240 Control(Clock_gate_sfc, Clock_change_enable_sfc, Clock_busy_sfc), 17.241 Divider(Clock_divider_sfc)), 17.242 17.243 - clock_ssi(Source(mux_dev, Clock_source_ssi), 17.244 - Control(Clock_gate_ssi0, Clock_change_enable_ssi, Clock_busy_ssi), 17.245 - Divider(Clock_divider_ssi)); 17.246 + clock_ssi0(Source(mux_dev, Clock_source_ssi), 17.247 + Control(Clock_gate_ssi0, Clock_change_enable_ssi, Clock_busy_ssi), 17.248 + Divider(Clock_divider_ssi)); 17.249 17.250 static Clock_divided_i2s 17.251 clock_i2s0_rx(Source(mux_i2s0_rx), 17.252 @@ -382,29 +374,35 @@ 17.253 Clock_divider_i2s1_d, Clock_divider_i2s1_n_auto, 17.254 Clock_divider_i2s1_d_auto)); 17.255 17.256 +const double x1600_pll_intermediate_min = 600000000, 17.257 + x1600_pll_intermediate_max = 2400000000; 17.258 + 17.259 static Pll clock_pll_A(Source(mux_external), 17.260 Control_pll(Pll_enable_A, Pll_stable_A, Pll_bypass_A), 17.261 Divider_pll(Pll_multiplier_A, Pll_input_division_A, 17.262 - Pll_output_division0_A, Pll_output_division1_A)), 17.263 + Pll_output_division0_A, Pll_output_division1_A, 17.264 + x1600_pll_intermediate_min, x1600_pll_intermediate_max)), 17.265 17.266 clock_pll_E(Source(mux_external), 17.267 Control_pll(Pll_enable_E, Pll_stable_E, Pll_bypass_E), 17.268 Divider_pll(Pll_multiplier_E, Pll_input_division_E, 17.269 - Pll_output_division0_E, Pll_output_division1_E)), 17.270 + Pll_output_division0_E, Pll_output_division1_E, 17.271 + x1600_pll_intermediate_min, x1600_pll_intermediate_max)), 17.272 17.273 clock_pll_M(Source(mux_external), 17.274 Control_pll(Pll_enable_M, Pll_stable_M, Pll_bypass_M), 17.275 Divider_pll(Pll_multiplier_M, Pll_input_division_M, 17.276 - Pll_output_division0_M, Pll_output_division1_M)); 17.277 + Pll_output_division0_M, Pll_output_division1_M, 17.278 + x1600_pll_intermediate_min, x1600_pll_intermediate_max)); 17.279 17.280 17.281 17.282 // Clock register. 17.283 17.284 static Clock_base *clocks[Clock_identifier_count] = { 17.285 - &clock_audio, 17.286 - &clock_none, // Clock_aic_bitclk 17.287 - &clock_none, // Clock_aic_pclk 17.288 + &clock_aic, 17.289 + &clock_none, // Clock_aic_bitclk 17.290 + &clock_none, // Clock_aic_pclk 17.291 &clock_can0, 17.292 &clock_can1, 17.293 &clock_cdbus, 17.294 @@ -412,182 +410,68 @@ 17.295 &clock_cpu, 17.296 &clock_ddr, 17.297 &clock_dma, 17.298 - &clock_none, // Clock_emac 17.299 + &clock_none, // Clock_emac 17.300 &clock_external, 17.301 &clock_hclock0, 17.302 &clock_hclock2, 17.303 - &clock_none, // Clock_hdmi 17.304 - &clock_i2c, 17.305 + &clock_hclock2_pclock, 17.306 + &clock_none, // Clock_hdmi 17.307 &clock_i2c0, 17.308 &clock_i2c1, 17.309 - &clock_i2s0, // supplies i2s0_rx 17.310 + &clock_none, // Clock_i2c2 17.311 + &clock_none, // Clock_i2c3 17.312 + &clock_none, // Clock_i2c4 17.313 + &clock_i2s0, // supplies i2s0_rx 17.314 &clock_i2s0_rx, 17.315 &clock_i2s0_tx, 17.316 - &clock_i2s1, // supplies i2s0_tx 17.317 - &clock_none, // Clock_i2s1_rx 17.318 - &clock_none, // Clock_i2s1_tx 17.319 - &clock_none, // Clock_kbc 17.320 - &clock_none, // Clock_lcd 17.321 + &clock_i2s1, // supplies i2s0_tx 17.322 + &clock_none, // Clock_i2s1_rx 17.323 + &clock_none, // Clock_i2s1_tx 17.324 + &clock_none, // Clock_kbc 17.325 + &clock_none, // Clock_lcd 17.326 &clock_lcd_pixel, 17.327 + &clock_none, // Clock_lcd_pixel1 17.328 &clock_mac, 17.329 &clock_main, 17.330 &clock_mipi_csi, 17.331 - &clock_msc, 17.332 + &clock_none, // Clock_msc 17.333 &clock_msc0, 17.334 &clock_msc1, 17.335 - &clock_none, 17.336 - &clock_otg, 17.337 + &clock_none, // Clock_msc2 17.338 + &clock_none, // Clock_none 17.339 + &clock_otg0, 17.340 + &clock_none, // Clock_otg1 17.341 &clock_pclock, 17.342 &clock_pll_A, 17.343 &clock_pll_E, 17.344 &clock_pll_M, 17.345 - &clock_pwm, 17.346 + &clock_none, // Clock_pll_V 17.347 &clock_pwm0, 17.348 - &clock_none, // Clock_pwm1 17.349 - &clock_none, // Clock_scc 17.350 + &clock_none, // Clock_pwm1 17.351 + &clock_none, // Clock_rtc 17.352 + &clock_none, // Clock_scc 17.353 &clock_sfc, 17.354 - &clock_none, // Clock_smb0 17.355 - &clock_none, // Clock_smb1 17.356 - &clock_none, // Clock_smb2 17.357 - &clock_none, // Clock_smb3 17.358 - &clock_none, // Clock_smb4 17.359 - &clock_ssi, 17.360 + &clock_none, // Clock_ssi 17.361 + &clock_ssi0, 17.362 + &clock_none, // Clock_ssi1 17.363 + &clock_none, // Clock_ssi2 17.364 &clock_timer, 17.365 &clock_uart0, 17.366 &clock_uart1, 17.367 &clock_uart2, 17.368 &clock_uart3, 17.369 - &clock_none, // Clock_udc 17.370 - &clock_none, // Clock_uhc 17.371 - &clock_none, // Clock_uprt 17.372 + &clock_none, // Clock_udc 17.373 + &clock_none, // Clock_uhc 17.374 + &clock_none, // Clock_uprt 17.375 }; 17.376 17.377 17.378 17.379 -// If implemented as a Hw::Device, various properties would be 17.380 -// initialised in the constructor and obtained from the device tree 17.381 -// definitions. 17.382 - 17.383 -Cpm_x1600_chip::Cpm_x1600_chip(l4_addr_t addr, uint32_t exclk_freq) 17.384 -: _cpm_regs(addr, clocks, exclk_freq) 17.385 -{ 17.386 - // add_cid("cpm"); 17.387 - // add_cid("cpm-x1600"); 17.388 - // register_property("exclk_freq", &exclk_freq); 17.389 -} 17.390 - 17.391 -const char * 17.392 -Cpm_x1600_chip::clock_type(enum Clock_identifiers clock) 17.393 -{ 17.394 - return clocks[clock]->clock_type(); 17.395 -} 17.396 - 17.397 -int 17.398 -Cpm_x1600_chip::have_clock(enum Clock_identifiers clock) 17.399 -{ 17.400 - return clocks[clock]->have_clock(_cpm_regs); 17.401 -} 17.402 - 17.403 -void 17.404 -Cpm_x1600_chip::start_clock(enum Clock_identifiers clock) 17.405 -{ 17.406 - clocks[clock]->start_clock(_cpm_regs); 17.407 -} 17.408 +// Peripheral abstraction. 17.409 17.410 -void 17.411 -Cpm_x1600_chip::stop_clock(enum Clock_identifiers clock) 17.412 -{ 17.413 - clocks[clock]->stop_clock(_cpm_regs); 17.414 -} 17.415 - 17.416 -int 17.417 -Cpm_x1600_chip::get_parameters(enum Clock_identifiers clock, uint32_t parameters[]) 17.418 -{ 17.419 - Clock_divided_base *clk = dynamic_cast<Clock_divided_base *>(clocks[clock]); 17.420 - 17.421 - if (clk != NULL) 17.422 - return clk->get_parameters(_cpm_regs, parameters); 17.423 - else 17.424 - return 0; 17.425 -} 17.426 - 17.427 -int 17.428 -Cpm_x1600_chip::set_parameters(enum Clock_identifiers clock, int num_parameters, uint32_t parameters[]) 17.429 -{ 17.430 - Clock_divided_base *clk = dynamic_cast<Clock_divided_base *>(clocks[clock]); 17.431 - 17.432 - if (clk != NULL) 17.433 - return clk->set_parameters(_cpm_regs, num_parameters, parameters); 17.434 - else 17.435 - return 0; 17.436 -} 17.437 - 17.438 -uint8_t 17.439 -Cpm_x1600_chip::get_source(enum Clock_identifiers clock) 17.440 +Cpm_x1600_chip::Cpm_x1600_chip(l4_addr_t addr) 17.441 +: Cpm_chip(addr, clocks) 17.442 { 17.443 - Clock_active *clk = dynamic_cast<Clock_active *>(clocks[clock]); 17.444 - 17.445 - if (clk != NULL) 17.446 - return clk->get_source(_cpm_regs); 17.447 - else 17.448 - return 0; 17.449 -} 17.450 - 17.451 -enum Clock_identifiers 17.452 -Cpm_x1600_chip::get_source_clock(enum Clock_identifiers clock) 17.453 -{ 17.454 - Clock_active *clk = dynamic_cast<Clock_active *>(clocks[clock]); 17.455 - 17.456 - if (clk != NULL) 17.457 - return clk->get_source_clock(_cpm_regs); 17.458 - else 17.459 - return Clock_undefined; 17.460 -} 17.461 - 17.462 -void 17.463 -Cpm_x1600_chip::set_source_clock(enum Clock_identifiers clock, enum Clock_identifiers source) 17.464 -{ 17.465 - Clock_active *clk = dynamic_cast<Clock_active *>(clocks[clock]); 17.466 - 17.467 - if (clk != NULL) 17.468 - clk->set_source_clock(_cpm_regs, source); 17.469 -} 17.470 - 17.471 -void 17.472 -Cpm_x1600_chip::set_source(enum Clock_identifiers clock, uint8_t source) 17.473 -{ 17.474 - Clock_active *clk = dynamic_cast<Clock_active *>(clocks[clock]); 17.475 - 17.476 - if (clk != NULL) 17.477 - clk->set_source(_cpm_regs, source); 17.478 -} 17.479 - 17.480 -uint32_t 17.481 -Cpm_x1600_chip::get_source_frequency(enum Clock_identifiers clock) 17.482 -{ 17.483 - Clock_active *clk = dynamic_cast<Clock_active *>(clocks[clock]); 17.484 - 17.485 - if (clk != NULL) 17.486 - return clk->get_source_frequency(_cpm_regs); 17.487 - else 17.488 - return 0; 17.489 -} 17.490 - 17.491 -uint32_t 17.492 -Cpm_x1600_chip::get_frequency(enum Clock_identifiers clock) 17.493 -{ 17.494 - return clocks[clock]->get_frequency(_cpm_regs); 17.495 -} 17.496 - 17.497 -int 17.498 -Cpm_x1600_chip::set_frequency(enum Clock_identifiers clock, uint32_t frequency) 17.499 -{ 17.500 - Clock_divided_base *clk = dynamic_cast<Clock_divided_base *>(clocks[clock]); 17.501 - 17.502 - if (clk != NULL) 17.503 - return clk->set_frequency(_cpm_regs, frequency); 17.504 - else 17.505 - return 0; 17.506 } 17.507 17.508 17.509 @@ -597,10 +481,7 @@ 17.510 void 17.511 *x1600_cpm_init(l4_addr_t cpm_base) 17.512 { 17.513 - /* Initialise the clock and power management peripheral with the 17.514 - register memory region and a 24MHz EXCLK frequency. */ 17.515 - 17.516 - return (void *) new Cpm_x1600_chip(cpm_base, 24000000); 17.517 + return (void *) new Cpm_x1600_chip(cpm_base); 17.518 } 17.519 17.520 const char *
18.1 --- a/pkg/devices/lib/i2c/src/jz4730.cc Tue Oct 24 18:52:06 2023 +0200 18.2 +++ b/pkg/devices/lib/i2c/src/jz4730.cc Fri Oct 27 18:02:49 2023 +0200 18.3 @@ -89,7 +89,7 @@ 18.4 { 18.5 // Make sure that the I2C clock is available. 18.6 18.7 - _cpm->start_clock(Clock_i2c); 18.8 + _cpm->start_clock(Clock_i2c0); 18.9 18.10 // Set the bus clock frequency. 18.11 18.12 @@ -119,7 +119,7 @@ 18.13 // obtained from the CPM unit and is scaled to kHz in order to keep the 18.14 // numbers easily representable, as is the bus frequency. 18.15 18.16 - uint32_t pclk = _cpm->get_pclock_frequency() / 1000; 18.17 + uint32_t pclk = _cpm->get_frequency(Clock_pclock) / 1000; 18.18 uint32_t i2c_clk = _frequency / 1000; 18.19 uint32_t division = pclk / (16 * i2c_clk); 18.20
19.1 --- a/pkg/devices/lib/i2c/src/jz4780.cc Tue Oct 24 18:52:06 2023 +0200 19.2 +++ b/pkg/devices/lib/i2c/src/jz4780.cc Fri Oct 27 18:02:49 2023 +0200 19.3 @@ -196,7 +196,7 @@ 19.4 // kHz in order to keep the numbers easily representable, as is the bus 19.5 // frequency. 19.6 19.7 - uint32_t smb_clk = _cpm->get_pclock_frequency() / 1000; 19.8 + uint32_t smb_clk = _cpm->get_frequency(Clock_pclock) / 1000; 19.9 uint32_t i2c_clk = _frequency / 1000; 19.10 unsigned int speed = (i2c_clk <= 100) ? 1 : 2; 19.11 19.12 @@ -628,7 +628,7 @@ 19.13 I2c_jz4780_chip::get_channel(uint8_t channel) 19.14 { 19.15 l4_addr_t block = _start + channel * Smb_block_offset; 19.16 - enum Clock_identifiers bits[] = {Clock_smb0, Clock_smb1, Clock_smb2, Clock_smb3, Clock_smb4}; 19.17 + enum Clock_identifiers bits[] = {Clock_i2c0, Clock_i2c1, Clock_i2c2, Clock_i2c3, Clock_i2c4}; 19.18 19.19 if (channel < 5) 19.20 {
20.1 --- a/pkg/landfall-examples/ci20_cpm/ci20_cpm.c Tue Oct 24 18:52:06 2023 +0200 20.2 +++ b/pkg/landfall-examples/ci20_cpm/ci20_cpm.c Fri Oct 27 18:02:49 2023 +0200 20.3 @@ -129,69 +129,60 @@ 20.4 20.5 /* Read information from the clock and power management unit. */ 20.6 20.7 - printf("Main source: %d\n", jz4780_cpm_get_main_source(cpm)); 20.8 - printf(" Main frequency: %d\n", jz4780_cpm_get_main_frequency(cpm)); 20.9 - printf("APLL frequency: %d\n", jz4780_cpm_get_apll_frequency(cpm)); 20.10 - printf("EPLL frequency: %d\n", jz4780_cpm_get_epll_frequency(cpm)); 20.11 - printf("MPLL frequency: %d\n", jz4780_cpm_get_mpll_frequency(cpm)); 20.12 - printf("VPLL frequency: %d\n", jz4780_cpm_get_vpll_frequency(cpm)); 20.13 - printf("CPU divider: %d\n", jz4780_cpm_get_cpu_divider(cpm)); 20.14 - printf(" CPU frequency: %d\n", jz4780_cpm_get_cpu_frequency(cpm)); 20.15 - printf("Memory source: %d\n", jz4780_cpm_get_memory_source(cpm)); 20.16 - printf(" Memory source frequency: %d\n", jz4780_cpm_get_memory_source_frequency(cpm)); 20.17 - printf(" Memory divider: %d\n", jz4780_cpm_get_memory_divider(cpm)); 20.18 - printf(" Memory frequency: %d\n", jz4780_cpm_get_memory_frequency(cpm)); 20.19 - printf("APB source: %d\n", jz4780_cpm_get_pclock_source(cpm)); 20.20 - printf(" APB source frequency: %d\n", jz4780_cpm_get_pclock_source_frequency(cpm)); 20.21 - printf(" APB divider: %d\n", jz4780_cpm_get_pclock_divider(cpm)); 20.22 - printf(" Slow peripheral (APB) frequency: %d\n", jz4780_cpm_get_pclock_frequency(cpm)); 20.23 - printf("AHB0 source: %d\n", jz4780_cpm_get_hclock0_source(cpm)); 20.24 - printf(" AHB0 source frequency: %d\n", jz4780_cpm_get_hclock0_source_frequency(cpm)); 20.25 - printf(" AHB0 divider: %d\n", jz4780_cpm_get_hclock0_divider(cpm)); 20.26 - printf(" Fast peripheral (AHB0) frequency: %d\n", jz4780_cpm_get_hclock0_frequency(cpm)); 20.27 - printf("AHB2 source: %d\n", jz4780_cpm_get_hclock2_source(cpm)); 20.28 - printf(" AHB2 source frequency: %d\n", jz4780_cpm_get_hclock2_source_frequency(cpm)); 20.29 - printf(" AHB2 divider: %d\n", jz4780_cpm_get_hclock2_divider(cpm)); 20.30 - printf(" Fast peripheral (AHB2) frequency: %d\n", jz4780_cpm_get_hclock2_frequency(cpm)); 20.31 - printf("LCD source: %d\n", jz4780_cpm_get_lcd_source(cpm)); 20.32 - printf(" LCD source frequency: %d\n", jz4780_cpm_get_lcd_source_frequency(cpm)); 20.33 - printf(" LCD pixel clock divider: %d\n", jz4780_cpm_get_lcd_pixel_divider(cpm)); 20.34 - printf(" LCD pixel clock frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel)); 20.35 + printf("Main source: %d\n", jz4780_cpm_get_source(cpm, Clock_main)); 20.36 + printf(" Main frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_main)); 20.37 + printf("APLL frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_pll_A)); 20.38 + printf("EPLL frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_pll_E)); 20.39 + printf("MPLL frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_pll_M)); 20.40 + printf("VPLL frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_pll_V)); 20.41 + printf("CPU frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_cpu)); 20.42 + printf("Memory source: %d\n", jz4780_cpm_get_source(cpm, Clock_ddr)); 20.43 + printf(" Memory source frequency: %d\n", jz4780_cpm_get_source_frequency(cpm, Clock_ddr)); 20.44 + printf(" Memory frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_ddr)); 20.45 + printf("APB source: %d\n", jz4780_cpm_get_source(cpm, Clock_pclock)); 20.46 + printf(" APB source frequency: %d\n", jz4780_cpm_get_source_frequency(cpm, Clock_pclock)); 20.47 + printf(" Slow peripheral (APB) frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_pclock)); 20.48 + printf("AHB0 source: %d\n", jz4780_cpm_get_source(cpm, Clock_hclock0)); 20.49 + printf(" AHB0 source frequency: %d\n", jz4780_cpm_get_source_frequency(cpm, Clock_hclock0)); 20.50 + printf(" Fast peripheral (AHB0) frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_hclock0)); 20.51 + printf("AHB2 source: %d\n", jz4780_cpm_get_source(cpm, Clock_hclock2)); 20.52 + printf(" AHB2 source frequency: %d\n", jz4780_cpm_get_source_frequency(cpm, Clock_hclock2)); 20.53 + printf(" Fast peripheral (AHB2) frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_hclock2)); 20.54 + printf("LCD source: %d\n", jz4780_cpm_get_source(cpm, Clock_lcd)); 20.55 + printf(" LCD source frequency: %d\n", jz4780_cpm_get_source_frequency(cpm, Clock_lcd)); 20.56 + printf(" LCD frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd)); 20.57 + printf(" LCD pixel clock frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel0)); 20.58 20.59 /* Attempt to set the pixel clock frequency. */ 20.60 20.61 - jz4780_cpm_set_frequency(cpm, Clock_lcd_pixel, 108000000); 20.62 + jz4780_cpm_set_frequency(cpm, Clock_lcd_pixel0, 108000000); 20.63 20.64 - printf("LCD source: %d\n", jz4780_cpm_get_lcd_source(cpm)); 20.65 - printf(" LCD source frequency: %d\n", jz4780_cpm_get_lcd_source_frequency(cpm)); 20.66 - printf(" LCD pixel clock divider: %d\n", jz4780_cpm_get_lcd_pixel_divider(cpm)); 20.67 - printf(" LCD pixel clock frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel)); 20.68 + printf("LCD source: %d\n", jz4780_cpm_get_source(cpm, Clock_lcd)); 20.69 + printf(" LCD source frequency: %d\n", jz4780_cpm_get_source_frequency(cpm, Clock_lcd)); 20.70 + printf(" LCD frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd)); 20.71 + printf(" LCD pixel clock frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel0)); 20.72 20.73 /* Attempt to set the peripheral clock frequency. */ 20.74 20.75 - jz4780_cpm_set_pclock_source(cpm, 1); 20.76 + jz4780_cpm_set_source(cpm, Clock_pclock, 1); 20.77 20.78 - printf("APB source: %d\n", jz4780_cpm_get_pclock_source(cpm)); 20.79 - printf(" APB source frequency: %d\n", jz4780_cpm_get_pclock_source_frequency(cpm)); 20.80 - printf(" APB divider: %d\n", jz4780_cpm_get_pclock_divider(cpm)); 20.81 - printf(" Slow peripheral (APB) frequency: %d\n", jz4780_cpm_get_pclock_frequency(cpm)); 20.82 - printf("AHB2 source: %d\n", jz4780_cpm_get_hclock2_source(cpm)); 20.83 - printf(" AHB2 source frequency: %d\n", jz4780_cpm_get_hclock2_source_frequency(cpm)); 20.84 - printf(" AHB2 divider: %d\n", jz4780_cpm_get_hclock2_divider(cpm)); 20.85 - printf(" Fast peripheral (AHB2) frequency: %d\n", jz4780_cpm_get_hclock2_frequency(cpm)); 20.86 + printf("APB source: %d\n", jz4780_cpm_get_source(cpm, Clock_pclock)); 20.87 + printf(" APB source frequency: %d\n", jz4780_cpm_get_source_frequency(cpm, Clock_pclock)); 20.88 + printf(" Slow peripheral (APB) frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_pclock)); 20.89 + printf("AHB2 source: %d\n", jz4780_cpm_get_source(cpm, Clock_hclock2)); 20.90 + printf(" AHB2 source frequency: %d\n", jz4780_cpm_get_source_frequency(cpm, Clock_hclock2)); 20.91 + printf(" Fast peripheral (AHB2) frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_hclock2)); 20.92 20.93 /* Attempt to set the MPLL output to EXCLK divided by 4. */ 20.94 20.95 - jz4780_cpm_set_mpll_parameters(cpm, 1, 4, 1); 20.96 + jz4780_cpm_set_parameters(cpm, Clock_pll_M, 3, (uint32_t []) {1, 4, 1}); 20.97 20.98 - printf("APB source: %d\n", jz4780_cpm_get_pclock_source(cpm)); 20.99 - printf(" APB source frequency: %d\n", jz4780_cpm_get_pclock_source_frequency(cpm)); 20.100 - printf(" APB divider: %d\n", jz4780_cpm_get_pclock_divider(cpm)); 20.101 - printf(" Slow peripheral (APB) frequency: %d\n", jz4780_cpm_get_pclock_frequency(cpm)); 20.102 - printf("AHB2 source: %d\n", jz4780_cpm_get_hclock2_source(cpm)); 20.103 - printf(" AHB2 source frequency: %d\n", jz4780_cpm_get_hclock2_source_frequency(cpm)); 20.104 - printf(" AHB2 divider: %d\n", jz4780_cpm_get_hclock2_divider(cpm)); 20.105 - printf(" Fast peripheral (AHB2) frequency: %d\n", jz4780_cpm_get_hclock2_frequency(cpm)); 20.106 + printf("APB source: %d\n", jz4780_cpm_get_source(cpm, Clock_pclock)); 20.107 + printf(" APB source frequency: %d\n", jz4780_cpm_get_source_frequency(cpm, Clock_pclock)); 20.108 + printf(" Slow peripheral (APB) frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_pclock)); 20.109 + printf("AHB2 source: %d\n", jz4780_cpm_get_source(cpm, Clock_hclock2)); 20.110 + printf(" AHB2 source frequency: %d\n", jz4780_cpm_get_source_frequency(cpm, Clock_hclock2)); 20.111 + printf(" Fast peripheral (AHB2) frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_hclock2)); 20.112 20.113 return 0; 20.114 }
21.1 --- a/pkg/landfall-examples/ci20_hdmi_i2c/ci20_hdmi_i2c.c Tue Oct 24 18:52:06 2023 +0200 21.2 +++ b/pkg/landfall-examples/ci20_hdmi_i2c/ci20_hdmi_i2c.c Fri Oct 27 18:02:49 2023 +0200 21.3 @@ -272,14 +272,12 @@ 21.4 21.5 cpm = jz4780_cpm_init(cpm_base); 21.6 21.7 - printf("VPLL frequency: %d\n", jz4780_cpm_get_vpll_frequency(cpm)); 21.8 - printf("HDMI divider: %d\n", jz4780_cpm_get_hdmi_divider(cpm)); 21.9 + printf("VPLL frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_pll_V)); 21.10 printf("HDMI frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_hdmi)); 21.11 21.12 jz4780_cpm_stop_clock(cpm, Clock_hdmi); 21.13 jz4780_cpm_set_frequency(cpm, Clock_hdmi, 27000000); 21.14 21.15 - printf("HDMI divider: %d\n", jz4780_cpm_get_hdmi_divider(cpm)); 21.16 printf("HDMI frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_hdmi)); 21.17 21.18 jz4780_cpm_start_clock(cpm, Clock_hdmi); 21.19 @@ -340,25 +338,22 @@ 21.20 21.21 /* Test initialisation with a frequency appropriate for the test panel. */ 21.22 21.23 - printf("LCD source: %d\n", jz4780_cpm_get_lcd_source(cpm)); 21.24 - printf("LCD divider: %d\n", jz4780_cpm_get_lcd_pixel_divider(cpm)); 21.25 - printf("LCD frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel)); 21.26 + printf("LCD source: %d\n", jz4780_cpm_get_source(cpm, Clock_lcd)); 21.27 + printf("LCD frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel0)); 21.28 printf("Desired frequency: %d\n", jz4740_lcd_get_pixel_clock(lcd)); 21.29 21.30 jz4780_cpm_stop_clock(cpm, Clock_lcd); 21.31 jz4780_cpm_set_frequency(cpm, Clock_lcd, jz4740_lcd_get_pixel_clock(lcd) * 3); 21.32 - jz4780_cpm_set_frequency(cpm, Clock_lcd_pixel, jz4740_lcd_get_pixel_clock(lcd)); 21.33 + jz4780_cpm_set_frequency(cpm, Clock_lcd_pixel0, jz4740_lcd_get_pixel_clock(lcd)); 21.34 21.35 - printf("LCD source: %d\n", jz4780_cpm_get_lcd_source(cpm)); 21.36 - printf("LCD divider: %d\n", jz4780_cpm_get_lcd_pixel_divider(cpm)); 21.37 - printf("LCD frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel)); 21.38 - printf("AHB0 frequency: %d\n", jz4780_cpm_get_hclock0_frequency(cpm)); 21.39 + printf("LCD source: %d\n", jz4780_cpm_get_source(cpm, Clock_lcd)); 21.40 + printf("LCD frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel0)); 21.41 21.42 /* With the LCD pixel clock set up, bring up the HDMI. */ 21.43 21.44 printf("Enable HDMI output...\n"); 21.45 21.46 - jz4780_hdmi_enable(hdmi, jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel)); 21.47 + jz4780_hdmi_enable(hdmi, jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel0)); 21.48 21.49 /* Create the DMA space. */ 21.50
22.1 --- a/pkg/landfall-examples/ci20_i2c/ci20_i2c.c Tue Oct 24 18:52:06 2023 +0200 22.2 +++ b/pkg/landfall-examples/ci20_i2c/ci20_i2c.c Fri Oct 27 18:02:49 2023 +0200 22.3 @@ -1,7 +1,7 @@ 22.4 /* 22.5 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de> 22.6 * economic rights: Technische Universität Dresden (Germany) 22.7 - * Copyright (C) 2017, 2018, 2019, 2020 Paul Boddie <paul@boddie.org.uk> 22.8 + * Copyright (C) 2017, 2018, 2019, 2020, 2023 Paul Boddie <paul@boddie.org.uk> 22.9 * 22.10 * This file is part of TUD:OS and distributed under the terms of the 22.11 * GNU General Public License 2. 22.12 @@ -403,8 +403,8 @@ 22.13 22.14 /* Attempt to set the PCLK source to SCLK_A. */ 22.15 22.16 - jz4780_cpm_set_pclock_source(cpm, 1); 22.17 - printf("Peripheral clock: %d\n", jz4780_cpm_get_pclock_frequency(cpm)); 22.18 + jz4780_cpm_set_source_clock(cpm, Clock_pclock, Clock_main); 22.19 + printf("Peripheral clock: %d\n", jz4780_cpm_get_frequency(cpm, Clock_pclock)); 22.20 22.21 /* Obtain I2C reference. */ 22.22
23.1 --- a/pkg/landfall-examples/qi_lb60_lcd/qi_lb60_lcd.c Tue Oct 24 18:52:06 2023 +0200 23.2 +++ b/pkg/landfall-examples/qi_lb60_lcd/qi_lb60_lcd.c Fri Oct 27 18:02:49 2023 +0200 23.3 @@ -188,7 +188,7 @@ 23.4 23.5 jz4740_cpm_stop_clock(cpm, Clock_lcd); 23.6 jz4740_cpm_set_frequency(cpm, Clock_lcd, jz4740_lcd_get_pixel_clock(lcd) * 3); 23.7 - jz4740_cpm_set_frequency(cpm, Clock_lcd_pixel, jz4740_lcd_get_pixel_clock(lcd)); 23.8 + jz4740_cpm_set_frequency(cpm, Clock_lcd_pixel0, jz4740_lcd_get_pixel_clock(lcd)); 23.9 23.10 /* Create the DMA space. */ 23.11
24.1 --- a/tools/install.sh Tue Oct 24 18:52:06 2023 +0200 24.2 +++ b/tools/install.sh Fri Oct 27 18:02:49 2023 +0200 24.3 @@ -25,7 +25,7 @@ 24.4 24.5 if [ "$1" = '--help' ]; then 24.6 cat 1>&2 <<EOF 24.7 -Usage: $PROGNAME <l4-directory> [ --clean ] 24.8 +Usage: $PROGNAME <l4-directory> [ --clean | --preserve ] 24.9 24.10 Copy the distributed packages into the "pkg" hierarchy found within the 24.11 specified directory. Also copy the distributed configuration examples into the 24.12 @@ -35,6 +35,9 @@ 24.13 "conf" directory and a "pkg" directory inside it. 24.14 24.15 Specifying --clean removes copied objects. 24.16 + 24.17 +Specifying --preserve preserves files and directories in locations used by this 24.18 +distribution that are not (or are no longer) part of this distribution. 24.19 EOF 24.20 exit 1 24.21 fi 24.22 @@ -58,13 +61,15 @@ 24.23 fi 24.24 24.25 L4DIR=$1 24.26 +CLEAN= 24.27 +PRESERVE= 24.28 24.29 # Determine the mode. 24.30 24.31 if [ "$2" = '--clean' ] ; then 24.32 CLEAN=$2 24.33 -else 24.34 - CLEAN= 24.35 +elif [ "$2" = '--preserve' ] ; then 24.36 + PRESERVE=$2 24.37 fi 24.38 24.39 # Check the configuration, if possible. 24.40 @@ -140,6 +145,10 @@ 24.41 24.42 # Remove obsolete files. 24.43 24.44 + if [ "$PRESERVE" ] ; then 24.45 + continue 24.46 + fi 24.47 + 24.48 for OBJECT in "$SOURCEDIR/"* ; do 24.49 OBJNAME=$(basename "$OBJECT") 24.50 ORIGIN=$(readlink -f "$OBJECT")