1.1 --- a/pkg/devices/cpm/src/jz4730/cpm-jz4730.cc Tue Sep 12 17:20:10 2023 +0200 1.2 +++ b/pkg/devices/cpm/src/jz4730/cpm-jz4730.cc Thu Sep 14 00:11:14 2023 +0200 1.3 @@ -58,7 +58,7 @@ 1.4 { 1.5 } 1.6 1.7 - long set_frequency(enum Clock_frequency_identifiers clock, uint32_t frequency) 1.8 + long set_frequency(enum Clock_identifiers clock, uint32_t frequency) 1.9 { 1.10 _chip->set_frequency(clock, frequency); 1.11 return L4_EOK; 1.12 @@ -81,12 +81,6 @@ 1.13 _chip->stop_clock(clock); 1.14 return L4_EOK; 1.15 } 1.16 - 1.17 - long update_output_frequency() 1.18 - { 1.19 - _chip->update_output_frequency(); 1.20 - return L4_EOK; 1.21 - } 1.22 }; 1.23 1.24
2.1 --- a/pkg/devices/cpm/src/jz4740/cpm-jz4740.cc Tue Sep 12 17:20:10 2023 +0200 2.2 +++ b/pkg/devices/cpm/src/jz4740/cpm-jz4740.cc Thu Sep 14 00:11:14 2023 +0200 2.3 @@ -58,7 +58,7 @@ 2.4 { 2.5 } 2.6 2.7 - long set_frequency(enum Clock_frequency_identifiers clock, uint32_t frequency) 2.8 + long set_frequency(enum Clock_identifiers clock, uint32_t frequency) 2.9 { 2.10 _chip->set_frequency(clock, frequency); 2.11 return L4_EOK; 2.12 @@ -81,12 +81,6 @@ 2.13 _chip->stop_clock(clock); 2.14 return L4_EOK; 2.15 } 2.16 - 2.17 - long update_output_frequency() 2.18 - { 2.19 - _chip->update_output_frequency(); 2.20 - return L4_EOK; 2.21 - } 2.22 }; 2.23 2.24
3.1 --- a/pkg/devices/cpm/src/jz4780/cpm-jz4780.cc Tue Sep 12 17:20:10 2023 +0200 3.2 +++ b/pkg/devices/cpm/src/jz4780/cpm-jz4780.cc Thu Sep 14 00:11:14 2023 +0200 3.3 @@ -58,13 +58,13 @@ 3.4 { 3.5 } 3.6 3.7 - long get_frequency(enum Clock_frequency_identifiers clock, uint32_t *frequency) 3.8 + long get_frequency(enum Clock_identifiers clock, uint32_t *frequency) 3.9 { 3.10 *frequency = _chip->get_frequency(clock); 3.11 return L4_EOK; 3.12 } 3.13 3.14 - long set_frequency(enum Clock_frequency_identifiers clock, uint32_t frequency) 3.15 + long set_frequency(enum Clock_identifiers clock, uint32_t frequency) 3.16 { 3.17 _chip->set_frequency(clock, frequency); 3.18 return L4_EOK; 3.19 @@ -87,12 +87,6 @@ 3.20 _chip->stop_clock(clock); 3.21 return L4_EOK; 3.22 } 3.23 - 3.24 - long update_output_frequency() 3.25 - { 3.26 - _chip->update_output_frequency(); 3.27 - return L4_EOK; 3.28 - } 3.29 }; 3.30 3.31
4.1 --- a/pkg/devices/display/src/ci20/display-ci20_hdmi.cc Tue Sep 12 17:20:10 2023 +0200 4.2 +++ b/pkg/devices/display/src/ci20/display-ci20_hdmi.cc Thu Sep 14 00:11:14 2023 +0200 4.3 @@ -68,7 +68,7 @@ 4.4 /* Start the HDMI peripheral. */ 4.5 4.6 cpm_device->stop_clock(Clock_hdmi); 4.7 - cpm_device->set_frequency(Clock_frequency_hdmi, 27000000); 4.8 + cpm_device->set_frequency(Clock_hdmi, 27000000); 4.9 cpm_device->start_clock(Clock_hdmi); 4.10 4.11 /* Load the panel data from the configured library. */ 4.12 @@ -122,7 +122,7 @@ 4.13 4.14 // NOTE: Should test to see if it is connected. 4.15 4.16 - if (!cpm_device->get_frequency(Clock_frequency_lcd_pixel, &frequency)) 4.17 + if (!cpm_device->get_frequency(Clock_lcd_pixel, &frequency)) 4.18 { 4.19 hdmi->enable(frequency); 4.20 }
5.1 --- a/pkg/devices/idl/cpm.idl Tue Sep 12 17:20:10 2023 +0200 5.2 +++ b/pkg/devices/idl/cpm.idl Thu Sep 14 00:11:14 2023 +0200 5.3 @@ -8,15 +8,13 @@ 5.4 [protocol(LANDFALL_CPM)] 5.5 interface CPM 5.6 { 5.7 - void get_frequency(in enum Clock_frequency_identifiers clock, out uint32_t frequency); 5.8 + void get_frequency(in enum Clock_identifiers clock, out uint32_t frequency); 5.9 5.10 - void set_frequency(in enum Clock_frequency_identifiers clock, in uint32_t frequency); 5.11 + void set_frequency(in enum Clock_identifiers clock, in uint32_t frequency); 5.12 5.13 void have_clock(in enum Clock_identifiers clock, out int enabled); 5.14 5.15 void start_clock(in enum Clock_identifiers clock); 5.16 5.17 void stop_clock(in enum Clock_identifiers clock); 5.18 - 5.19 - void update_output_frequency(); 5.20 };
6.1 --- a/pkg/devices/include/clocks.h Tue Sep 12 17:20:10 2023 +0200 6.2 +++ b/pkg/devices/include/clocks.h Thu Sep 14 00:11:14 2023 +0200 6.3 @@ -1,7 +1,7 @@ 6.4 /* 6.5 * Clock identifiers for clock and power management. 6.6 * 6.7 - * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk> 6.8 + * Copyright (C) 2021, 2023 Paul Boddie <paul@boddie.org.uk> 6.9 * 6.10 * This program is free software; you can redistribute it and/or 6.11 * modify it under the terms of the GNU General Public License as 6.12 @@ -29,17 +29,32 @@ 6.13 { 6.14 Clock_aic_bitclk, 6.15 Clock_aic_pclk, 6.16 + Clock_can0, 6.17 + Clock_can1, 6.18 + Clock_cdbus, 6.19 Clock_cim, 6.20 + Clock_ddr, 6.21 Clock_dma, 6.22 Clock_emac, 6.23 Clock_hdmi, 6.24 Clock_i2c, 6.25 + Clock_i2c0, 6.26 + Clock_i2c1, 6.27 + Clock_i2s, 6.28 + Clock_i2s0_rx, 6.29 + Clock_i2s0_tx, 6.30 Clock_kbc, 6.31 Clock_lcd, 6.32 + Clock_lcd_pixel, 6.33 + Clock_mac, 6.34 Clock_msc, 6.35 - Clock_pmw0, 6.36 + Clock_msc0, 6.37 + Clock_msc1, 6.38 + Clock_pwm, 6.39 + Clock_pwm0, 6.40 Clock_pwm1, 6.41 Clock_scc, 6.42 + Clock_sfc, 6.43 Clock_smb0, 6.44 Clock_smb1, 6.45 Clock_smb2, 6.46 @@ -54,15 +69,8 @@ 6.47 Clock_udc, 6.48 Clock_uhc, 6.49 Clock_uprt, 6.50 -}; 6.51 - 6.52 -/* Identifiers for clocks whose frequencies can be adjusted or inspected. */ 6.53 - 6.54 -enum Clock_frequency_identifiers 6.55 -{ 6.56 - Clock_frequency_lcd, 6.57 - Clock_frequency_lcd_pixel, 6.58 - Clock_frequency_hdmi, 6.59 + Clock_identifier_count, /* not a clock: limit for array definition */ 6.60 + Clock_identifier_any /* not a clock: indicates any clock */ 6.61 }; 6.62 6.63 // vim: tabstop=2 expandtab shiftwidth=2
7.1 --- a/pkg/devices/lcd/src/jz4740/lcd-jz4740-device.cc Tue Sep 12 17:20:10 2023 +0200 7.2 +++ b/pkg/devices/lcd/src/jz4740/lcd-jz4740-device.cc Thu Sep 14 00:11:14 2023 +0200 7.3 @@ -70,9 +70,8 @@ 7.4 // 1.5 times that of the pixel clock, and a STN panel needs a device clock 3 7.5 // times that of the pixel clock. 7.6 7.7 - cpm_device->set_frequency(Clock_frequency_lcd, pclk * 3); 7.8 - cpm_device->set_frequency(Clock_frequency_lcd_pixel, pclk); 7.9 - cpm_device->update_output_frequency(); 7.10 + cpm_device->set_frequency(Clock_lcd, pclk * 3); 7.11 + cpm_device->set_frequency(Clock_lcd_pixel, pclk); 7.12 cpm_device->start_clock(Clock_lcd); 7.13 7.14 l4_sleep(1); // 1ms == 1000us
8.1 --- a/pkg/devices/lib/cpm/include/cpm-jz4730.h Tue Sep 12 17:20:10 2023 +0200 8.2 +++ b/pkg/devices/lib/cpm/include/cpm-jz4730.h Thu Sep 14 00:11:14 2023 +0200 8.3 @@ -42,6 +42,13 @@ 8.4 Hw::Register_block<32> _regs; 8.5 uint32_t _exclk_freq; 8.6 8.7 + // Utility methods. 8.8 + 8.9 + uint8_t _get_divider(uint32_t reg, uint32_t mask, uint8_t shift); 8.10 + 8.11 + // PLL status. 8.12 + 8.13 + int have_pll(); 8.14 int pll_enabled(); 8.15 int pll_bypassed(); 8.16 8.17 @@ -52,39 +59,44 @@ 8.18 public: 8.19 Cpm_jz4730_chip(l4_addr_t addr, uint32_t exclk_freq); 8.20 8.21 - int have_pll(); 8.22 + // PLL configuration. 8.23 8.24 uint16_t get_multiplier(); 8.25 uint8_t get_input_division(); 8.26 uint8_t get_output_division(); 8.27 8.28 - uint8_t _get_divider(uint32_t reg, uint32_t mask, uint8_t shift); 8.29 + // Divider configuration. 8.30 + 8.31 uint8_t get_cpu_divider(); 8.32 uint8_t get_hclock_divider(); 8.33 uint8_t get_pclock_divider(); 8.34 uint8_t get_memory_divider(); 8.35 uint8_t get_source_divider(); 8.36 - 8.37 uint16_t get_lcd_pixel_divider(); 8.38 8.39 void set_lcd_device_divider(uint8_t division); 8.40 void set_lcd_pixel_divider(uint16_t division); 8.41 8.42 - uint32_t get_frequency(enum Clock_frequency_identifiers clock); 8.43 - void set_frequency(enum Clock_frequency_identifiers clock, uint32_t frequency); 8.44 - 8.45 - int have_clock(enum Clock_identifiers clock); 8.46 - void start_clock(enum Clock_identifiers clock); 8.47 - void stop_clock(enum Clock_identifiers clock); 8.48 + // PLL frequency status. 8.49 8.50 uint32_t get_pll_frequency(); 8.51 - uint32_t get_output_frequency(); 8.52 - void update_output_frequency(); 8.53 + uint32_t get_source_frequency(); 8.54 + 8.55 + // Clock frequency status. 8.56 8.57 uint32_t get_cpu_frequency(); 8.58 uint32_t get_hclock_frequency(); 8.59 uint32_t get_pclock_frequency(); 8.60 uint32_t get_memory_frequency(); 8.61 + 8.62 + // Clock configuration. 8.63 + 8.64 + uint32_t get_frequency(enum Clock_identifiers clock); 8.65 + void set_frequency(enum Clock_identifiers clock, uint32_t frequency); 8.66 + 8.67 + int have_clock(enum Clock_identifiers clock); 8.68 + void start_clock(enum Clock_identifiers clock); 8.69 + void stop_clock(enum Clock_identifiers clock); 8.70 }; 8.71 8.72 #endif /* __cplusplus */ 8.73 @@ -105,14 +117,12 @@ 8.74 8.75 uint16_t jz4730_cpm_get_lcd_pixel_divider(void *cpm); 8.76 8.77 -uint32_t jz4730_cpm_get_frequency(void *cpm, enum Clock_frequency_identifiers clock); 8.78 -void jz4730_cpm_set_frequency(void *cpm, enum Clock_frequency_identifiers clock, uint32_t frequency); 8.79 - 8.80 -void jz4730_cpm_update_output_frequency(void *cpm); 8.81 +uint32_t jz4730_cpm_get_frequency(void *cpm, enum Clock_identifiers clock); 8.82 +void jz4730_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency); 8.83 8.84 uint32_t jz4730_cpm_get_cpu_frequency(void *cpm); 8.85 uint32_t jz4730_cpm_get_hclock_frequency(void *cpm); 8.86 -uint32_t jz4730_cpm_get_output_frequency(void *cpm); 8.87 +uint32_t jz4730_cpm_get_source_frequency(void *cpm); 8.88 uint32_t jz4730_cpm_get_pclock_frequency(void *cpm); 8.89 uint32_t jz4730_cpm_get_memory_frequency(void *cpm); 8.90
9.1 --- a/pkg/devices/lib/cpm/include/cpm-jz4740.h Tue Sep 12 17:20:10 2023 +0200 9.2 +++ b/pkg/devices/lib/cpm/include/cpm-jz4740.h Thu Sep 14 00:11:14 2023 +0200 9.3 @@ -1,7 +1,7 @@ 9.4 /* 9.5 * CPM (clock and power management) support for the JZ4740. 9.6 * 9.7 - * Copyright (C) 2017, 2018, 2020, 2021 Paul Boddie <paul@boddie.org.uk> 9.8 + * Copyright (C) 2017, 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk> 9.9 * 9.10 * This program is free software; you can redistribute it and/or 9.11 * modify it under the terms of the GNU General Public License as 9.12 @@ -42,6 +42,13 @@ 9.13 Hw::Register_block<32> _regs; 9.14 uint32_t _exclk_freq; 9.15 9.16 + // Utility methods. 9.17 + 9.18 + uint8_t _get_divider(uint32_t reg, uint32_t mask, uint8_t shift); 9.19 + 9.20 + // PLL status. 9.21 + 9.22 + int have_pll(); 9.23 int pll_enabled(); 9.24 int pll_bypassed(); 9.25 9.26 @@ -52,39 +59,45 @@ 9.27 public: 9.28 Cpm_jz4740_chip(l4_addr_t addr, uint32_t exclk_freq); 9.29 9.30 - int have_clock(enum Clock_identifiers clock); 9.31 - void start_clock(enum Clock_identifiers clock); 9.32 - void stop_clock(enum Clock_identifiers clock); 9.33 - 9.34 - int have_pll(); 9.35 + // PLL configuration. 9.36 9.37 uint16_t get_multiplier(); 9.38 uint8_t get_input_division(); 9.39 uint8_t get_output_division(); 9.40 9.41 - uint8_t _get_divider(uint32_t reg, uint32_t mask, uint8_t shift); 9.42 + // Divider configuration. 9.43 + 9.44 uint8_t get_cpu_divider(); 9.45 uint8_t get_hclock_divider(); 9.46 uint8_t get_pclock_divider(); 9.47 uint8_t get_memory_divider(); 9.48 uint8_t get_source_divider(); 9.49 - 9.50 uint16_t get_lcd_pixel_divider(); 9.51 9.52 void set_lcd_device_divider(uint8_t division); 9.53 void set_lcd_pixel_divider(uint16_t division); 9.54 9.55 - uint32_t get_frequency(enum Clock_frequency_identifiers clock); 9.56 - void set_frequency(enum Clock_frequency_identifiers clock, uint32_t frequency); 9.57 + // PLL frequency status. 9.58 9.59 uint32_t get_pll_frequency(); 9.60 - uint32_t get_output_frequency(); 9.61 - void update_output_frequency(); 9.62 + uint32_t get_source_frequency(); 9.63 + 9.64 + // Clock frequency status. 9.65 9.66 uint32_t get_cpu_frequency(); 9.67 uint32_t get_hclock_frequency(); 9.68 uint32_t get_pclock_frequency(); 9.69 uint32_t get_memory_frequency(); 9.70 + 9.71 + // Clock configuration. 9.72 + 9.73 + uint32_t get_frequency(enum Clock_identifiers clock); 9.74 + void set_frequency(enum Clock_identifiers clock, uint32_t frequency); 9.75 + 9.76 + int have_clock(enum Clock_identifiers clock); 9.77 + void start_clock(enum Clock_identifiers clock); 9.78 + void stop_clock(enum Clock_identifiers clock); 9.79 + 9.80 }; 9.81 9.82 #endif /* __cplusplus */ 9.83 @@ -105,14 +118,12 @@ 9.84 9.85 uint16_t jz4740_cpm_get_lcd_pixel_divider(void *cpm); 9.86 9.87 -uint32_t jz4740_cpm_get_frequency(void *cpm, enum Clock_frequency_identifiers clock); 9.88 -void jz4740_cpm_set_frequency(void *cpm, enum Clock_frequency_identifiers clock, uint32_t frequency); 9.89 - 9.90 -void jz4740_cpm_update_output_frequency(void *cpm); 9.91 +uint32_t jz4740_cpm_get_frequency(void *cpm, enum Clock_identifiers clock); 9.92 +void jz4740_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency); 9.93 9.94 uint32_t jz4740_cpm_get_cpu_frequency(void *cpm); 9.95 uint32_t jz4740_cpm_get_hclock_frequency(void *cpm); 9.96 -uint32_t jz4740_cpm_get_output_frequency(void *cpm); 9.97 +uint32_t jz4740_cpm_get_source_frequency(void *cpm); 9.98 uint32_t jz4740_cpm_get_pclock_frequency(void *cpm); 9.99 uint32_t jz4740_cpm_get_memory_frequency(void *cpm); 9.100
10.1 --- a/pkg/devices/lib/cpm/include/cpm-jz4780.h Tue Sep 12 17:20:10 2023 +0200 10.2 +++ b/pkg/devices/lib/cpm/include/cpm-jz4780.h Thu Sep 14 00:11:14 2023 +0200 10.3 @@ -1,7 +1,7 @@ 10.4 /* 10.5 * CPM (clock and power management) support for the JZ4780. 10.6 * 10.7 - * Copyright (C) 2017, 2018, 2020, 2021 Paul Boddie <paul@boddie.org.uk> 10.8 + * Copyright (C) 2017, 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk> 10.9 * 10.10 * This program is free software; you can redistribute it and/or 10.11 * modify it under the terms of the GNU General Public License as 10.12 @@ -48,11 +48,14 @@ 10.13 void set_field(uint32_t reg, uint32_t mask, uint8_t shift, uint32_t value); 10.14 uint8_t _get_divider(uint32_t reg, uint32_t mask, uint8_t shift); 10.15 10.16 - // PLL control. 10.17 + // PLL status. 10.18 10.19 int have_pll(uint32_t pll_reg); 10.20 int pll_enabled(uint32_t pll_reg); 10.21 int pll_bypassed(uint32_t pll_reg); 10.22 + 10.23 + // PLL control. 10.24 + 10.25 void pll_disable(uint32_t pll_reg); 10.26 void pll_enable(uint32_t pll_reg); 10.27 10.28 @@ -89,10 +92,6 @@ 10.29 void set_pclock_source(uint8_t source); 10.30 Cpm_jz4780_chip(l4_addr_t addr, uint32_t exclk_freq, uint32_t rtclk_freq); 10.31 10.32 - int have_clock(enum Clock_identifiers clock); 10.33 - void start_clock(enum Clock_identifiers clock); 10.34 - void stop_clock(enum Clock_identifiers clock); 10.35 - 10.36 // Clock divider values. 10.37 10.38 uint8_t get_cpu_divider(); 10.39 @@ -103,13 +102,9 @@ 10.40 uint8_t get_lcd_pixel_divider(uint8_t controller = 0); 10.41 uint8_t get_memory_divider(); 10.42 10.43 - // Input frequencies. 10.44 + // Clock sources. 10.45 10.46 uint8_t get_main_source(); 10.47 - uint32_t get_main_frequency(); 10.48 - 10.49 - // Clock sources, providing the input frequency. 10.50 - 10.51 uint8_t get_cpu_source(); 10.52 uint8_t get_hclock0_source(); 10.53 uint8_t get_hclock2_source(); 10.54 @@ -119,6 +114,14 @@ 10.55 uint8_t get_memory_source(); 10.56 uint8_t get_pclock_source(); 10.57 10.58 + // PLL frequency status. 10.59 + 10.60 + uint32_t get_apll_frequency(); 10.61 + uint32_t get_epll_frequency(); 10.62 + uint32_t get_mpll_frequency(); 10.63 + uint32_t get_vpll_frequency(); 10.64 + 10.65 + uint32_t get_main_frequency(); 10.66 uint32_t get_cpu_source_frequency(); 10.67 uint32_t get_hclock0_source_frequency(); 10.68 uint32_t get_hclock2_source_frequency(); 10.69 @@ -128,7 +131,7 @@ 10.70 uint32_t get_memory_source_frequency(); 10.71 uint32_t get_pclock_source_frequency(); 10.72 10.73 - // Final, calculated frequencies. 10.74 + // Clock frequency status. 10.75 10.76 uint32_t get_cpu_frequency(); 10.77 uint32_t get_hclock0_frequency(); 10.78 @@ -136,17 +139,16 @@ 10.79 uint32_t get_memory_frequency(); 10.80 uint32_t get_pclock_frequency(); 10.81 10.82 - uint32_t get_apll_frequency(); 10.83 - uint32_t get_epll_frequency(); 10.84 - uint32_t get_mpll_frequency(); 10.85 - uint32_t get_vpll_frequency(); 10.86 - 10.87 void set_pll_parameters(uint32_t pll_reg, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider); 10.88 10.89 - uint32_t get_frequency(enum Clock_frequency_identifiers clock); 10.90 - void set_frequency(enum Clock_frequency_identifiers clock, uint32_t frequency); 10.91 + // Clock frequency configuration. 10.92 10.93 - void update_output_frequency(); 10.94 + uint32_t get_frequency(enum Clock_identifiers clock); 10.95 + void set_frequency(enum Clock_identifiers clock, uint32_t frequency); 10.96 + 10.97 + int have_clock(enum Clock_identifiers clock); 10.98 + void start_clock(enum Clock_identifiers clock); 10.99 + void stop_clock(enum Clock_identifiers clock); 10.100 }; 10.101 10.102 #endif /* __cplusplus */ 10.103 @@ -201,8 +203,8 @@ 10.104 uint32_t jz4780_cpm_get_mpll_frequency(void *cpm); 10.105 uint32_t jz4780_cpm_get_vpll_frequency(void *cpm); 10.106 10.107 -uint32_t jz4780_cpm_get_frequency(void *cpm, enum Clock_frequency_identifiers clock); 10.108 -void jz4780_cpm_set_frequency(void *cpm, enum Clock_frequency_identifiers clock, uint32_t frequency); 10.109 +uint32_t jz4780_cpm_get_frequency(void *cpm, enum Clock_identifiers clock); 10.110 +void jz4780_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency); 10.111 10.112 void jz4780_cpm_set_mpll_parameters(void *cpm, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider); 10.113
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/pkg/devices/lib/cpm/include/cpm-x1600.h Thu Sep 14 00:11:14 2023 +0200 11.3 @@ -0,0 +1,197 @@ 11.4 +/* 11.5 + * CPM (clock and power management) support for the X1600. 11.6 + * 11.7 + * Copyright (C) 2017, 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk> 11.8 + * 11.9 + * This program is free software; you can redistribute it and/or 11.10 + * modify it under the terms of the GNU General Public License as 11.11 + * published by the Free Software Foundation; either version 2 of 11.12 + * the License, or (at your option) any later version. 11.13 + * 11.14 + * This program is distributed in the hope that it will be useful, 11.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.17 + * GNU General Public License for more details. 11.18 + * 11.19 + * You should have received a copy of the GNU General Public License 11.20 + * along with this program; if not, write to the Free Software 11.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 11.22 + * Boston, MA 02110-1301, USA 11.23 + */ 11.24 + 11.25 +#pragma once 11.26 + 11.27 +#include <l4/devices/cpm.h> 11.28 + 11.29 +#include <l4/sys/types.h> 11.30 +#include <stdint.h> 11.31 + 11.32 + 11.33 + 11.34 +#ifdef __cplusplus 11.35 + 11.36 +#include <l4/devices/hw_register_block.h> 11.37 + 11.38 +/* A simple abstraction for accessing the CPM registers. 11.39 + * A proper device could inherit from Hw::Device and use an 11.40 + * Int_property for _exclk_freq. */ 11.41 + 11.42 +class Cpm_x1600_chip : public Cpm_chip 11.43 +{ 11.44 +private: 11.45 + Hw::Register_block<32> _regs; 11.46 + uint32_t _exclk_freq; 11.47 + 11.48 + // Utility methods. 11.49 + 11.50 + uint32_t get_field(uint32_t reg, uint32_t mask, uint8_t shift); 11.51 + void set_field(uint32_t reg, uint32_t mask, uint8_t shift, uint32_t value); 11.52 + uint8_t _get_divider(uint32_t reg, uint32_t mask, uint8_t shift); 11.53 + 11.54 + // PLL control. 11.55 + 11.56 + int have_pll(uint32_t pll_reg); 11.57 + int pll_enabled(uint32_t pll_reg); 11.58 + int pll_bypassed(uint32_t pll_reg); 11.59 + void pll_disable(uint32_t pll_reg); 11.60 + void pll_enable(uint32_t pll_reg); 11.61 + 11.62 + // General frequency modifiers. 11.63 + 11.64 + uint16_t get_multiplier(uint32_t pll_reg); 11.65 + void set_multiplier(uint32_t pll_reg, uint16_t multiplier); 11.66 + uint8_t get_input_division(uint32_t pll_reg); 11.67 + void set_input_division(uint32_t pll_reg, uint8_t divider); 11.68 + uint8_t get_output_division(uint32_t pll_reg); 11.69 + void set_output_division(uint32_t pll_reg, uint8_t divider); 11.70 + 11.71 + // Clock dividers. 11.72 + 11.73 + void set_lcd_pixel_divider(uint8_t controller, uint16_t division); 11.74 + 11.75 + // Input frequencies. 11.76 + 11.77 + uint32_t get_pll_frequency(uint32_t pll_reg); 11.78 + 11.79 + // Clock sources. 11.80 + 11.81 + void set_hclock2_source(uint8_t source); 11.82 + void set_lcd_source(uint8_t controller, uint8_t source); 11.83 + 11.84 + // Clock control. 11.85 + 11.86 + uint32_t get_clock_gate_register(enum Clock_identifiers clock); 11.87 + uint32_t get_clock_gate_value(enum Clock_identifiers clock); 11.88 + 11.89 +public: 11.90 + void set_pclock_source(uint8_t source); 11.91 + Cpm_x1600_chip(l4_addr_t addr, uint32_t exclk_freq); 11.92 + 11.93 + int have_clock(enum Clock_identifiers clock); 11.94 + void start_clock(enum Clock_identifiers clock); 11.95 + void stop_clock(enum Clock_identifiers clock); 11.96 + 11.97 + // Clock divider values. 11.98 + 11.99 + uint8_t get_cpu_divider(); 11.100 + uint8_t get_hclock0_divider(); 11.101 + uint8_t get_hclock2_divider(); 11.102 + uint8_t get_pclock_divider(); 11.103 + uint8_t get_lcd_pixel_divider(uint8_t controller = 0); 11.104 + uint8_t get_memory_divider(); 11.105 + 11.106 + // Input frequencies. 11.107 + 11.108 + uint8_t get_main_source(); 11.109 + uint32_t get_main_frequency(); 11.110 + 11.111 + // Clock sources, providing the input frequency. 11.112 + 11.113 + uint8_t get_cpu_source(); 11.114 + uint8_t get_hclock0_source(); 11.115 + uint8_t get_hclock2_source(); 11.116 + uint8_t get_lcd_source(uint8_t controller); 11.117 + uint8_t get_lcd_source() { return get_lcd_source(0); } 11.118 + uint8_t get_memory_source(); 11.119 + uint8_t get_pclock_source(); 11.120 + 11.121 + uint32_t get_cpu_source_frequency(); 11.122 + uint32_t get_hclock0_source_frequency(); 11.123 + uint32_t get_hclock2_source_frequency(); 11.124 + uint32_t get_lcd_source_frequency(uint8_t controller); 11.125 + uint32_t get_lcd_source_frequency() { return get_lcd_source_frequency(0); } 11.126 + uint32_t get_memory_source_frequency(); 11.127 + uint32_t get_pclock_source_frequency(); 11.128 + 11.129 + // Final, calculated frequencies. 11.130 + 11.131 + uint32_t get_cpu_frequency(); 11.132 + uint32_t get_hclock0_frequency(); 11.133 + uint32_t get_hclock2_frequency(); 11.134 + uint32_t get_memory_frequency(); 11.135 + uint32_t get_pclock_frequency(); 11.136 + 11.137 + uint32_t get_apll_frequency(); 11.138 + uint32_t get_epll_frequency(); 11.139 + uint32_t get_mpll_frequency(); 11.140 + 11.141 + void set_pll_parameters(uint32_t pll_reg, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider); 11.142 + 11.143 + uint32_t get_frequency(enum Clock_identifiers clock); 11.144 + void set_frequency(enum Clock_identifiers clock, uint32_t frequency); 11.145 +}; 11.146 + 11.147 +#endif /* __cplusplus */ 11.148 + 11.149 + 11.150 + 11.151 +/* C language interface. */ 11.152 + 11.153 +EXTERN_C_BEGIN 11.154 + 11.155 +void *x1600_cpm_init(l4_addr_t cpm_base); 11.156 + 11.157 +int x1600_cpm_have_clock(void *cpm, enum Clock_identifiers clock); 11.158 +void x1600_cpm_start_clock(void *cpm, enum Clock_identifiers clock); 11.159 +void x1600_cpm_stop_clock(void *cpm, enum Clock_identifiers clock); 11.160 + 11.161 +uint8_t x1600_cpm_get_cpu_divider(void *cpm); 11.162 +uint8_t x1600_cpm_get_hclock0_divider(void *cpm); 11.163 +uint8_t x1600_cpm_get_hclock2_divider(void *cpm); 11.164 +uint8_t x1600_cpm_get_lcd_pixel_divider(void *cpm); 11.165 +uint8_t x1600_cpm_get_memory_divider(void *cpm); 11.166 +uint8_t x1600_cpm_get_pclock_divider(void *cpm); 11.167 + 11.168 +uint8_t x1600_cpm_get_hclock0_source(void *cpm); 11.169 +uint8_t x1600_cpm_get_hclock2_source(void *cpm); 11.170 +uint8_t x1600_cpm_get_lcd_source(void *cpm); 11.171 +uint8_t x1600_cpm_get_memory_source(void *cpm); 11.172 +uint8_t x1600_cpm_get_pclock_source(void *cpm); 11.173 + 11.174 +uint32_t x1600_cpm_get_hclock0_source_frequency(void *cpm); 11.175 +uint32_t x1600_cpm_get_hclock2_source_frequency(void *cpm); 11.176 +uint32_t x1600_cpm_get_lcd_source_frequency(void *cpm); 11.177 +uint32_t x1600_cpm_get_memory_source_frequency(void *cpm); 11.178 +uint32_t x1600_cpm_get_pclock_source_frequency(void *cpm); 11.179 + 11.180 +void x1600_cpm_set_pclock_source(void *cpm, uint8_t source); 11.181 + 11.182 +uint8_t x1600_cpm_get_main_source(void *cpm); 11.183 +uint32_t x1600_cpm_get_main_frequency(void *cpm); 11.184 + 11.185 +uint32_t x1600_cpm_get_cpu_frequency(void *cpm); 11.186 +uint32_t x1600_cpm_get_hclock0_frequency(void *cpm); 11.187 +uint32_t x1600_cpm_get_hclock2_frequency(void *cpm); 11.188 +uint32_t x1600_cpm_get_memory_frequency(void *cpm); 11.189 +uint32_t x1600_cpm_get_pclock_frequency(void *cpm); 11.190 + 11.191 +uint32_t x1600_cpm_get_apll_frequency(void *cpm); 11.192 +uint32_t x1600_cpm_get_epll_frequency(void *cpm); 11.193 +uint32_t x1600_cpm_get_mpll_frequency(void *cpm); 11.194 + 11.195 +uint32_t x1600_cpm_get_frequency(void *cpm, enum Clock_identifiers clock); 11.196 +void x1600_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency); 11.197 + 11.198 +void x1600_cpm_set_mpll_parameters(void *cpm, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider); 11.199 + 11.200 +EXTERN_C_END
12.1 --- a/pkg/devices/lib/cpm/include/cpm.h Tue Sep 12 17:20:10 2023 +0200 12.2 +++ b/pkg/devices/lib/cpm/include/cpm.h Thu Sep 14 00:11:14 2023 +0200 12.3 @@ -1,7 +1,7 @@ 12.4 /* 12.5 * Clock and power management (CPM) abstractions. 12.6 * 12.7 - * Copyright (C) 2017, 2018, 2020, 2021 Paul Boddie <paul@boddie.org.uk> 12.8 + * Copyright (C) 2017, 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk> 12.9 * 12.10 * This program is free software; you can redistribute it and/or 12.11 * modify it under the terms of the GNU General Public License as 12.12 @@ -39,8 +39,6 @@ 12.13 virtual void start_clock(enum Clock_identifiers clock) = 0; 12.14 12.15 virtual void stop_clock(enum Clock_identifiers clock) = 0; 12.16 - 12.17 - virtual void update_output_frequency() = 0; 12.18 }; 12.19 12.20 #endif /* __cplusplus */
13.1 --- a/pkg/devices/lib/cpm/src/Makefile Tue Sep 12 17:20:10 2023 +0200 13.2 +++ b/pkg/devices/lib/cpm/src/Makefile Thu Sep 14 00:11:14 2023 +0200 13.3 @@ -4,7 +4,7 @@ 13.4 TARGET = libcpm.o.a libcpm.o.so 13.5 PC_FILENAME := libdrivers-cpm 13.6 13.7 -SRC_CC := jz4730.cc jz4740.cc jz4780.cc 13.8 +SRC_CC := jz4730.cc jz4740.cc jz4780.cc x1600.cc 13.9 13.10 PRIVATE_INCDIR += $(PKGDIR)/lib/cpm/include 13.11
14.1 --- a/pkg/devices/lib/cpm/src/jz4730.cc Tue Sep 12 17:20:10 2023 +0200 14.2 +++ b/pkg/devices/lib/cpm/src/jz4730.cc Thu Sep 14 00:11:14 2023 +0200 14.3 @@ -37,7 +37,7 @@ 14.4 14.5 enum Clock_bits : unsigned 14.6 { 14.7 - Clock_enable = 20, // UPE 14.8 + Clock_change_enable = 20, // UPE 14.9 Clock_memory_divider = 16, // MFR 14.10 Clock_lcd_divider = 12, // LFR 14.11 Clock_pclock_divider = 8, // PFR (slow APB peripherals) 14.12 @@ -68,7 +68,7 @@ 14.13 Clock_gate_msc = 13, 14.14 Clock_gate_ssi = 12, 14.15 Clock_gate_pwm1 = 11, 14.16 - Clock_gate_pmw0 = 10, 14.17 + Clock_gate_pwm0 = 10, 14.18 Clock_gate_aic_pclk = 9, 14.19 Clock_gate_i2c = 8, 14.20 Clock_gate_lcd = 7, 14.21 @@ -119,7 +119,7 @@ 14.22 case Clock_msc: return (1 << Clock_gate_msc); 14.23 case Clock_ssi: return (1 << Clock_gate_ssi); 14.24 case Clock_pwm1: return (1 << Clock_gate_pwm1); 14.25 - case Clock_pmw0: return (1 << Clock_gate_pmw0); 14.26 + case Clock_pwm0: return (1 << Clock_gate_pwm0); 14.27 case Clock_aic_pclk: return (1 << Clock_gate_aic_pclk); 14.28 case Clock_i2c: return (1 << Clock_gate_i2c); 14.29 case Clock_lcd: return (1 << Clock_gate_lcd); 14.30 @@ -272,8 +272,12 @@ 14.31 for (i = 0; i < 10; i++) 14.32 if (cd[i] >= division) break; 14.33 14.34 + _regs[Clock_control] = _regs[Clock_control] | (1 << Clock_change_enable); 14.35 + 14.36 _regs[Clock_control] = (_regs[Clock_control] & ~(0xf << Clock_lcd_divider)) | 14.37 (cd[i] << Clock_lcd_divider); 14.38 + 14.39 + _regs[Clock_control] = _regs[Clock_control] & ~(1 << Clock_change_enable); 14.40 } 14.41 14.42 // LCD pixel clock divider. 14.43 @@ -292,38 +296,42 @@ 14.44 else if (division > 512) 14.45 division = 512; 14.46 14.47 + _regs[Clock_control] = _regs[Clock_control] | (1 << Clock_change_enable); 14.48 + 14.49 _regs[Lcd_divider] = (_regs[Lcd_divider] & ~(0x1ff << Lcd_divider_value)) | 14.50 ((division - 1) << Lcd_divider_value); 14.51 + 14.52 + _regs[Clock_control] = _regs[Clock_control] & ~(1 << Clock_change_enable); 14.53 } 14.54 14.55 14.56 14.57 uint32_t 14.58 -Cpm_jz4730_chip::get_frequency(enum Clock_frequency_identifiers clock) 14.59 +Cpm_jz4730_chip::get_frequency(enum Clock_identifiers clock) 14.60 { 14.61 - if (clock == Clock_frequency_lcd_pixel) 14.62 - return get_output_frequency() / get_lcd_pixel_divider(); 14.63 + if (clock == Clock_lcd_pixel) 14.64 + return get_source_frequency() / get_lcd_pixel_divider(); 14.65 14.66 // NOTE: Consider a better error result. 14.67 return 0; 14.68 } 14.69 14.70 void 14.71 -Cpm_jz4730_chip::set_frequency(enum Clock_frequency_identifiers clock, uint32_t frequency) 14.72 +Cpm_jz4730_chip::set_frequency(enum Clock_identifiers clock, uint32_t frequency) 14.73 { 14.74 - uint32_t out = get_output_frequency(); 14.75 + uint32_t out = get_source_frequency(); 14.76 14.77 switch (clock) 14.78 { 14.79 // Limit the device frequency to 150MHz. 14.80 14.81 - case Clock_frequency_lcd: 14.82 + case Clock_lcd: 14.83 if (frequency > 150000000) 14.84 frequency = 150000000; 14.85 set_lcd_device_divider(out / frequency); 14.86 break; 14.87 14.88 - case Clock_frequency_lcd_pixel: 14.89 + case Clock_lcd_pixel: 14.90 set_lcd_pixel_divider(out / frequency); 14.91 break; 14.92 14.93 @@ -349,17 +357,11 @@ 14.94 // Clock frequency for MSC, I2S, LCD and USB. 14.95 14.96 uint32_t 14.97 -Cpm_jz4730_chip::get_output_frequency() 14.98 +Cpm_jz4730_chip::get_source_frequency() 14.99 { 14.100 return get_pll_frequency() / get_source_divider(); 14.101 } 14.102 14.103 -void 14.104 -Cpm_jz4730_chip::update_output_frequency() 14.105 -{ 14.106 - _regs[Clock_control] = _regs[Clock_control] | (1 << Clock_enable); 14.107 -} 14.108 - 14.109 // Clock frequency for the CPU. 14.110 14.111 uint32_t Cpm_jz4730_chip::get_cpu_frequency() 14.112 @@ -447,9 +449,9 @@ 14.113 } 14.114 14.115 uint32_t 14.116 -jz4730_cpm_get_output_frequency(void *cpm) 14.117 +jz4730_cpm_get_source_frequency(void *cpm) 14.118 { 14.119 - return static_cast<Cpm_jz4730_chip *>(cpm)->get_output_frequency(); 14.120 + return static_cast<Cpm_jz4730_chip *>(cpm)->get_source_frequency(); 14.121 } 14.122 14.123 uint32_t 14.124 @@ -471,19 +473,13 @@ 14.125 } 14.126 14.127 uint32_t 14.128 -jz4730_cpm_get_frequency(void *cpm, enum Clock_frequency_identifiers clock) 14.129 +jz4730_cpm_get_frequency(void *cpm, enum Clock_identifiers clock) 14.130 { 14.131 return static_cast<Cpm_jz4730_chip *>(cpm)->get_frequency(clock); 14.132 } 14.133 14.134 void 14.135 -jz4730_cpm_set_frequency(void *cpm, enum Clock_frequency_identifiers clock, uint32_t frequency) 14.136 +jz4730_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency) 14.137 { 14.138 static_cast<Cpm_jz4730_chip *>(cpm)->set_frequency(clock, frequency); 14.139 } 14.140 - 14.141 -void 14.142 -jz4730_cpm_update_output_frequency(void *cpm) 14.143 -{ 14.144 - static_cast<Cpm_jz4730_chip *>(cpm)->update_output_frequency(); 14.145 -}
15.1 --- a/pkg/devices/lib/cpm/src/jz4740.cc Tue Sep 12 17:20:10 2023 +0200 15.2 +++ b/pkg/devices/lib/cpm/src/jz4740.cc Thu Sep 14 00:11:14 2023 +0200 15.3 @@ -42,7 +42,7 @@ 15.4 15.5 enum Clock_bits : unsigned 15.6 { 15.7 - Clock_enable = 22, // CE 15.8 + Clock_change_enable = 22, // CE 15.9 Clock_pllout_source = 21, // PCS 15.10 Clock_lcd_divider = 16, // LCD 15.11 Clock_memory_divider = 12, // MDIV 15.12 @@ -226,8 +226,12 @@ 15.13 else if (division > 32) 15.14 division = 32; 15.15 15.16 + _regs[Clock_control] = _regs[Clock_control] | (1 << Clock_change_enable); 15.17 + 15.18 _regs[Clock_control] = (_regs[Clock_control] & ~(0x1f << Clock_lcd_divider)) | 15.19 ((division - 1) << Clock_lcd_divider); 15.20 + 15.21 + _regs[Clock_control] = _regs[Clock_control] & ~(1 << Clock_change_enable); 15.22 } 15.23 15.24 // LCD pixel clock divider. 15.25 @@ -246,38 +250,42 @@ 15.26 else if (division > 2048) 15.27 division = 2048; 15.28 15.29 + _regs[Clock_control] = _regs[Clock_control] | (1 << Clock_change_enable); 15.30 + 15.31 _regs[Lcd_divider] = (_regs[Lcd_divider] & ~(0x7ff << Lcd_divider_value)) | 15.32 ((division - 1) << Lcd_divider_value); 15.33 + 15.34 + _regs[Clock_control] = _regs[Clock_control] & ~(1 << Clock_change_enable); 15.35 } 15.36 15.37 15.38 15.39 uint32_t 15.40 -Cpm_jz4740_chip::get_frequency(enum Clock_frequency_identifiers clock) 15.41 +Cpm_jz4740_chip::get_frequency(enum Clock_identifiers clock) 15.42 { 15.43 - if (clock == Clock_frequency_lcd_pixel) 15.44 - return get_output_frequency() / get_lcd_pixel_divider(); 15.45 + if (clock == Clock_lcd_pixel) 15.46 + return get_source_frequency() / get_lcd_pixel_divider(); 15.47 15.48 // NOTE: Consider a better error result. 15.49 return 0; 15.50 } 15.51 15.52 void 15.53 -Cpm_jz4740_chip::set_frequency(enum Clock_frequency_identifiers clock, uint32_t frequency) 15.54 +Cpm_jz4740_chip::set_frequency(enum Clock_identifiers clock, uint32_t frequency) 15.55 { 15.56 - uint32_t out = get_output_frequency(); 15.57 + uint32_t out = get_source_frequency(); 15.58 15.59 switch (clock) 15.60 { 15.61 // Limit the device frequency to 150MHz. 15.62 15.63 - case Clock_frequency_lcd: 15.64 + case Clock_lcd: 15.65 if (frequency > 150000000) 15.66 frequency = 150000000; 15.67 set_lcd_device_divider(out / frequency); 15.68 break; 15.69 15.70 - case Clock_frequency_lcd_pixel: 15.71 + case Clock_lcd_pixel: 15.72 set_lcd_pixel_divider(out / frequency); 15.73 break; 15.74 15.75 @@ -303,17 +311,11 @@ 15.76 // Clock frequency for MSC, I2S, LCD and USB. 15.77 15.78 uint32_t 15.79 -Cpm_jz4740_chip::get_output_frequency() 15.80 +Cpm_jz4740_chip::get_source_frequency() 15.81 { 15.82 return get_pll_frequency() / get_source_divider(); 15.83 } 15.84 15.85 -void 15.86 -Cpm_jz4740_chip::update_output_frequency() 15.87 -{ 15.88 - _regs[Clock_control] = _regs[Clock_control] | (1 << Clock_enable); 15.89 -} 15.90 - 15.91 // Clock frequency for the CPU. 15.92 15.93 uint32_t Cpm_jz4740_chip::get_cpu_frequency() 15.94 @@ -389,9 +391,9 @@ 15.95 } 15.96 15.97 uint32_t 15.98 -jz4740_cpm_get_output_frequency(void *cpm) 15.99 +jz4740_cpm_get_source_frequency(void *cpm) 15.100 { 15.101 - return static_cast<Cpm_jz4740_chip *>(cpm)->get_output_frequency(); 15.102 + return static_cast<Cpm_jz4740_chip *>(cpm)->get_source_frequency(); 15.103 } 15.104 15.105 uint32_t 15.106 @@ -413,19 +415,13 @@ 15.107 } 15.108 15.109 uint32_t 15.110 -jz4740_cpm_get_frequency(void *cpm, enum Clock_frequency_identifiers clock) 15.111 +jz4740_cpm_get_frequency(void *cpm, enum Clock_identifiers clock) 15.112 { 15.113 return static_cast<Cpm_jz4740_chip *>(cpm)->get_frequency(clock); 15.114 } 15.115 15.116 void 15.117 -jz4740_cpm_set_frequency(void *cpm, enum Clock_frequency_identifiers clock, uint32_t frequency) 15.118 +jz4740_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency) 15.119 { 15.120 static_cast<Cpm_jz4740_chip *>(cpm)->set_frequency(clock, frequency); 15.121 } 15.122 - 15.123 -void 15.124 -jz4740_cpm_update_output_frequency(void *cpm) 15.125 -{ 15.126 - static_cast<Cpm_jz4740_chip *>(cpm)->update_output_frequency(); 15.127 -}
16.1 --- a/pkg/devices/lib/cpm/src/jz4780.cc Tue Sep 12 17:20:10 2023 +0200 16.2 +++ b/pkg/devices/lib/cpm/src/jz4780.cc Thu Sep 14 00:11:14 2023 +0200 16.3 @@ -58,11 +58,11 @@ 16.4 16.5 enum Clock_bits : unsigned 16.6 { 16.7 - Clock_enable = 22, // CE_CPU 16.8 - Clock_pclock_divider = 16, // PDIV (slow APB peripherals) 16.9 - Clock_hclock2_divider = 12, // H2DIV (fast AHB peripherals) 16.10 - Clock_hclock0_divider = 8, // H0DIV (fast AHB peripherals) 16.11 - Clock_cpu_divider = 0, // CDIV 16.12 + Clock_cpu_change_enable = 22, // CE_CPU 16.13 + Clock_pclock_divider = 16, // PDIV (slow APB peripherals) 16.14 + Clock_hclock2_divider = 12, // H2DIV (fast AHB peripherals) 16.15 + Clock_hclock0_divider = 8, // H0DIV (fast AHB peripherals) 16.16 + Clock_cpu_divider = 0, // CDIV 16.17 }; 16.18 16.19 enum Pll_bits : unsigned 16.20 @@ -743,16 +743,16 @@ 16.21 16.22 16.23 uint32_t 16.24 -Cpm_jz4780_chip::get_frequency(enum Clock_frequency_identifiers clock) 16.25 +Cpm_jz4780_chip::get_frequency(enum Clock_identifiers clock) 16.26 { 16.27 switch (clock) 16.28 { 16.29 // NOTE: Returning only the frequency for controller 0. 16.30 16.31 - case Clock_frequency_lcd_pixel: 16.32 + case Clock_lcd_pixel: 16.33 return get_lcd_source_frequency(0) / get_lcd_pixel_divider(0); 16.34 16.35 - case Clock_frequency_hdmi: 16.36 + case Clock_hdmi: 16.37 return get_hdmi_source_frequency() / get_hdmi_divider(); 16.38 16.39 // NOTE: Consider a better error result. 16.40 @@ -763,7 +763,7 @@ 16.41 } 16.42 16.43 void 16.44 -Cpm_jz4780_chip::set_frequency(enum Clock_frequency_identifiers clock, uint32_t frequency) 16.45 +Cpm_jz4780_chip::set_frequency(enum Clock_identifiers clock, uint32_t frequency) 16.46 { 16.47 switch (clock) 16.48 { 16.49 @@ -771,7 +771,7 @@ 16.50 // NOTE: Here, the actual frequency value is ignored, but should at least be 16.51 // NOTE: tested. 16.52 16.53 - case Clock_frequency_lcd: 16.54 + case Clock_lcd: 16.55 set_lcd_source(0, Source_pll_V); 16.56 set_lcd_source(1, Source_pll_V); 16.57 pll_enable(Pll_control_V); 16.58 @@ -780,7 +780,7 @@ 16.59 // Unlike the JZ4740, HCLK/AHB0 is used as the device frequency, with the pixel 16.60 // frequency being based on the selected clock source (SCLK_A, MPLL or VPLL). 16.61 16.62 - case Clock_frequency_lcd_pixel: 16.63 + case Clock_lcd_pixel: 16.64 16.65 // Switch to the video PLL and attempt to set the divider. 16.66 16.67 @@ -788,7 +788,7 @@ 16.68 set_lcd_pixel_divider(1, get_lcd_source_frequency() / frequency); 16.69 break; 16.70 16.71 - case Clock_frequency_hdmi: 16.72 + case Clock_hdmi: 16.73 16.74 // Switch to the video PLL and attempt to set the divider. 16.75 16.76 @@ -802,13 +802,6 @@ 16.77 } 16.78 } 16.79 16.80 -// NOTE: Empty method for compatibility. 16.81 - 16.82 -void 16.83 -Cpm_jz4780_chip::update_output_frequency() 16.84 -{ 16.85 -} 16.86 - 16.87 16.88 16.89 // C language interface functions. 16.90 @@ -1037,13 +1030,13 @@ 16.91 16.92 16.93 uint32_t 16.94 -jz4780_cpm_get_frequency(void *cpm, enum Clock_frequency_identifiers clock) 16.95 +jz4780_cpm_get_frequency(void *cpm, enum Clock_identifiers clock) 16.96 { 16.97 return static_cast<Cpm_jz4780_chip *>(cpm)->get_frequency(clock); 16.98 } 16.99 16.100 void 16.101 -jz4780_cpm_set_frequency(void *cpm, enum Clock_frequency_identifiers clock, uint32_t frequency) 16.102 +jz4780_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency) 16.103 { 16.104 static_cast<Cpm_jz4780_chip *>(cpm)->set_frequency(clock, frequency); 16.105 }
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/pkg/devices/lib/cpm/src/x1600.cc Thu Sep 14 00:11:14 2023 +0200 17.3 @@ -0,0 +1,1117 @@ 17.4 +/* 17.5 + * Clock and power management. This exposes the combined functionality 17.6 + * provided by the X1600 and related SoCs. The power management 17.7 + * functionality could be exposed using a separate driver. 17.8 + * 17.9 + * Copyright (C) 2017, 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk> 17.10 + * 17.11 + * This program is free software; you can redistribute it and/or 17.12 + * modify it under the terms of the GNU General Public License as 17.13 + * published by the Free Software Foundation; either version 2 of 17.14 + * the License, or (at your option) any later version. 17.15 + * 17.16 + * This program is distributed in the hope that it will be useful, 17.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 17.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17.19 + * GNU General Public License for more details. 17.20 + * 17.21 + * You should have received a copy of the GNU General Public License 17.22 + * along with this program; if not, write to the Free Software 17.23 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, 17.24 + * Boston, MA 02110-1301, USA 17.25 + */ 17.26 + 17.27 +#include <l4/devices/hw_mmio_register_block.h> 17.28 +#include "cpm-x1600.h" 17.29 +#include <math.h> 17.30 + 17.31 + 17.32 + 17.33 +enum Regs : unsigned 17.34 +{ 17.35 + Clock_control = 0x000, // CPCCR 17.36 + Low_power_control = 0x004, // LCR 17.37 + Clock_gate0 = 0x020, // CLKGR0 17.38 + Clock_gate1 = 0x028, // CLKGR1 17.39 + Sleep_control = 0x024, // OPCR (oscillator and power control) 17.40 + Clock_status = 0x0d4, // CPCSR 17.41 + Ddr_divider = 0x02c, // DDRCDR 17.42 + Mac_divider = 0x054, // MACCDR 17.43 + I2s_divider0 = 0x060, // I2SCDR 17.44 + I2s_divider1 = 0x070, // I2S1CDR 17.45 + Lcd_divider = 0x064, // LPCDR 17.46 + Msc_divider0 = 0x068, // MSC0CDR 17.47 + Msc_divider1 = 0x0a4, // MSC1CDR 17.48 + Sfc_divider = 0x074, // SFCCDR 17.49 + Ssi_divider = 0x05c, // SSICDR 17.50 + Cim_divider = 0x078, // CIMCDR 17.51 + Pwm_divider = 0x06c, // PWMCDR 17.52 + Can_divider0 = 0x0a0, // CAN0CDR 17.53 + Can_divider1 = 0x0a8, // CAN1CDR 17.54 + Cdbus_divider = 0x0ac, // CDBUSCDR 17.55 + Macphy0_divider = 0x0e4, // MPHY0C 17.56 + Cpm_interrupt = 0x0b0, // CPM_INTR 17.57 + Cpm_interrupt_en = 0x0b4, // CPM_INTRE 17.58 + Cpm_swi = 0x0bc, // CPM_SFTINT 17.59 + Ddr_gate = 0x0d0, // DRCG 17.60 + Cpm_scratch_prot = 0x038, // CPSPPR 17.61 + Cpm_scratch = 0x034, // CPSPR 17.62 + Usb_param_control0 = 0x03c, // USBPCR 17.63 + Usb_reset_detect = 0x040, // USBRDT 17.64 + Usb_vbus_jitter = 0x044, // USBVBFIL 17.65 + Usb_param_control1 = 0x048, // USBPCR1 17.66 + Pll_control = 0x00c, // CPPCR 17.67 + Pll_control_A = 0x010, // CPAPCR 17.68 + Pll_control_M = 0x014, // CPMPCR 17.69 + Pll_control_E = 0x018, // CPEPCR 17.70 + Pll_fraction_A = 0x084, // CPAPACR 17.71 + Pll_fraction_M = 0x088, // CPMPACR 17.72 + Pll_fraction_E = 0x08c, // CPEPACR 17.73 +}; 17.74 + 17.75 +enum Clock_bits : unsigned 17.76 +{ 17.77 + // Clock_control 17.78 + 17.79 + Clock_gate_A = 23, // GATE_SCLKA 17.80 + Clock_cpu_change_enable = 22, // CE_CPU 17.81 + Clock_ahb0_change_enable = 21, // CE_AHB0 17.82 + Clock_ahb2_change_enable = 20, // CE_AHB2 17.83 + Clock_pclock_divider = 16, // PDIV (slow APB peripherals) 17.84 + Clock_hclock2_divider = 12, // H2DIV (fast AHB peripherals) 17.85 + Clock_hclock0_divider = 8, // H0DIV (fast AHB peripherals) 17.86 + Clock_l2cache_divider = 4, // L2CDIV 17.87 + Clock_cpu_divider = 0, // CDIV 17.88 +}; 17.89 + 17.90 +enum Clock_source_bits : unsigned 17.91 +{ 17.92 + // Clock_control 17.93 + 17.94 + Clock_source_main = 30, // SEL_SRC (output to SCLK_A) 17.95 + Clock_source_cpu = 28, // SEL_CPLL (output to CCLK) 17.96 + Clock_source_hclock0 = 26, // SEL_H0PLL (output to AHB0) 17.97 + Clock_source_hclock2 = 24, // SEL_H2PLL (output to AHB2) 17.98 + 17.99 + // Ddr_divider 17.100 + 17.101 + Clock_source_ddr = 30, // DCS 17.102 + 17.103 + // I2s_divider0 17.104 + 17.105 + Clock_source_i2s = 31, // I2PCS 17.106 + 17.107 + // Lcd_divider 17.108 + 17.109 + Clock_source_lcd = 30, // LPCS 17.110 + 17.111 + // Mac_divider 17.112 + 17.113 + Clock_source_mac = 30, // MACPCS 17.114 + 17.115 + // Msc_divider0, Msc_divider1 17.116 + 17.117 + Clock_source_msc0 = 30, // MPCS 17.118 + Clock_source_msc1 = 30, // MPCS 17.119 + 17.120 + // Sfc_divider 17.121 + 17.122 + Clock_source_sfc = 30, // SFCS 17.123 + 17.124 + // Ssi_divider 17.125 + 17.126 + Clock_source_ssi = 30, // SPCS 17.127 + 17.128 + // Cim_divider 17.129 + 17.130 + Clock_source_cim = 30, // CIMPCS 17.131 + 17.132 + // Pwm_divider 17.133 + 17.134 + Clock_source_pwm = 30, // PWMPCS 17.135 + 17.136 + // Can_divider0, Can_divider1 17.137 + 17.138 + Clock_source_can0 = 30, // CA0CS 17.139 + Clock_source_can1 = 30, // CA1CS 17.140 + 17.141 + // Cdbus_divider 17.142 + 17.143 + Clock_source_cdbus = 30, // CDCS 17.144 +}; 17.145 + 17.146 +enum Clock_sources : unsigned 17.147 +{ 17.148 + // Clock_source_main 17.149 + 17.150 + Source_external = 1, // EXCLK 17.151 + Source_pll_A = 2, // APLL 17.152 + 17.153 + // Stoppable clock sources: 17.154 + // Clock_source_cpu, Clock_source_hclock0, Clock_source_hclock2, 17.155 + // Clock_source_ddr 17.156 + 17.157 + Source_mux_stopped = 0, 17.158 + Source_mux_main = 1, // SCLK_A 17.159 + Source_mux_pll_M = 2, // MPLL 17.160 + 17.161 + // Unstoppable clock sources: 17.162 + // Clock_source_mac, Clock_source_i2s, Clock_source_lcd, Clock_source_msc0, 17.163 + // Clock_source_msc1, Clock_source_sfc, Clock_source_ssi, Clock_source_cim, 17.164 + // Clock_source_pwm, Clock_source_can0, Clock_source_can1, Clock_source_cdbus 17.165 + 17.166 + Source_main = 0, // SCLK_A 17.167 + Source_pll_M = 1, // MPLL 17.168 + Source_pll_E = 2, // EPLL 17.169 + 17.170 + Source_i2s_pll_E = 1, // EPLL 17.171 + 17.172 + Source_can_external = 3, // EXCLK 17.173 +}; 17.174 + 17.175 +enum Clock_gate_bits : unsigned 17.176 +{ 17.177 + // Clock_gate0 17.178 + 17.179 + Clock_gate_ddr = 31, // DDR 17.180 + Clock_gate_ahb0 = 29, // AHB0 17.181 + Clock_gate_apb0 = 28, // APB0 17.182 + Clock_gate_rtc = 27, // RTC 17.183 + Clock_gate_aes = 24, // AES 17.184 + Clock_gate_lcd_pixel = 23, // LCD 17.185 + Clock_gate_cim = 22, // CIM 17.186 + Clock_gate_dma = 21, // PDMA 17.187 + Clock_gate_ost = 20, // OST 17.188 + Clock_gate_ssi0 = 19, // SSI0 17.189 + Clock_gate_timer = 18, // TCU 17.190 + Clock_gate_dtrng = 17, // DTRNG 17.191 + Clock_gate_uart2 = 16, // UART2 17.192 + Clock_gate_uart1 = 15, // UART1 17.193 + Clock_gate_uart0 = 14, // UART0 17.194 + Clock_gate_sadc = 13, // SADC 17.195 + Clock_gate_audio = 11, // AUDIO 17.196 + Clock_gate_ssi_slv = 10, // SSI_SLV 17.197 + Clock_gate_i2c1 = 8, // I2C1 17.198 + Clock_gate_i2c0 = 7, // I2C0 17.199 + Clock_gate_msc1 = 5, // MSC1 17.200 + Clock_gate_msc0 = 4, // MSC0 17.201 + Clock_gate_otg = 3, // OTG 17.202 + Clock_gate_sfc = 2, // SFC 17.203 + Clock_gate_efuse = 1, // EFUSE 17.204 + Clock_gate_nemc = 0, // NEMC 17.205 + 17.206 + // Clock_gate1 17.207 + 17.208 + Clock_gate_arb = 30, // ARB 17.209 + Clock_gate_mipi_csi = 28, // MIPI_CSI 17.210 + Clock_gate_intc = 26, // INTC 17.211 + Clock_gate_gmac0 = 23, // GMAC0 17.212 + Clock_gate_uart3 = 16, // UART3 17.213 + Clock_gate_i2s0_tx = 9, // I2S0_dev_tclk 17.214 + Clock_gate_i2s0_rx = 8, // I2S0_dev_rclk 17.215 + Clock_gate_hash = 6, // HASH 17.216 + Clock_gate_pwm = 5, // PWM 17.217 + Clock_gate_cdbus = 2, // CDBUS 17.218 + Clock_gate_can1 = 1, // CAN1 17.219 + Clock_gate_can0 = 0, // CAN0 17.220 + 17.221 + // Special value 17.222 + 17.223 + Clock_gate_undefined = 32, 17.224 +}; 17.225 + 17.226 +// Clock gate register correspondences. 17.227 + 17.228 +static uint32_t clock_gate_reg[Clock_identifier_count] = { 17.229 + /* Clock_aic_bitclk */ 0, 17.230 + /* Clock_aic_pclk */ 0, 17.231 + /* Clock_can0 */ Clock_gate1, 17.232 + /* Clock_can1 */ Clock_gate1, 17.233 + /* Clock_cdbus */ Clock_gate1, 17.234 + /* Clock_cim */ Clock_gate0, 17.235 + /* Clock_ddr */ Clock_gate0, 17.236 + /* Clock_dma */ Clock_gate0, 17.237 + /* Clock_emac */ 0, 17.238 + /* Clock_hdmi */ 0, 17.239 + /* Clock_i2c */ Clock_gate0, 17.240 + /* Clock_i2c0 */ Clock_gate0, 17.241 + /* Clock_i2c1 */ Clock_gate0, 17.242 + /* Clock_i2s */ 0, 17.243 + /* Clock_i2s0_rx */ Clock_gate1, 17.244 + /* Clock_i2s0_tx */ Clock_gate1, 17.245 + /* Clock_kbc */ 0, 17.246 + /* Clock_lcd */ 0, 17.247 + /* Clock_lcd_pixel */ Clock_gate0, 17.248 + /* Clock_mac */ Clock_gate1, 17.249 + /* Clock_msc */ Clock_gate0, 17.250 + /* Clock_msc0 */ Clock_gate0, 17.251 + /* Clock_msc1 */ Clock_gate0, 17.252 + /* Clock_pwm */ Clock_gate1, 17.253 + /* Clock_pwm0 */ Clock_gate1, 17.254 + /* Clock_pwm1 */ 0, 17.255 + /* Clock_scc */ 0, 17.256 + /* Clock_sfc */ Clock_gate0, 17.257 + /* Clock_smb0 */ 0, 17.258 + /* Clock_smb1 */ 0, 17.259 + /* Clock_smb2 */ 0, 17.260 + /* Clock_smb3 */ 0, 17.261 + /* Clock_smb4 */ 0, 17.262 + /* Clock_ssi */ Clock_gate0, 17.263 + /* Clock_timer */ Clock_gate0, 17.264 + /* Clock_uart0 */ Clock_gate0, 17.265 + /* Clock_uart1 */ Clock_gate0, 17.266 + /* Clock_uart2 */ Clock_gate0, 17.267 + /* Clock_uart3 */ Clock_gate1, 17.268 + /* Clock_udc */ 0, 17.269 + /* Clock_uhc */ 0, 17.270 + /* Clock_uprt */ 0, 17.271 +}; 17.272 + 17.273 +// Clock gate register bit correspondences. 17.274 + 17.275 +static enum Clock_gate_bits clock_gate_bit[Clock_identifier_count] = { 17.276 + /* Clock_aic_bitclk */ Clock_gate_undefined, 17.277 + /* Clock_aic_pclk */ Clock_gate_undefined, 17.278 + /* Clock_can0 */ Clock_gate_can0, 17.279 + /* Clock_can1 */ Clock_gate_can1, 17.280 + /* Clock_cdbus */ Clock_gate_cdbus, 17.281 + /* Clock_cim */ Clock_gate_cim, 17.282 + /* Clock_ddr */ Clock_gate_ddr, 17.283 + /* Clock_dma */ Clock_gate_dma, 17.284 + /* Clock_emac */ Clock_gate_undefined, 17.285 + /* Clock_hdmi */ Clock_gate_undefined, 17.286 + /* Clock_i2c */ Clock_gate_i2c0, 17.287 + /* Clock_i2c0 */ Clock_gate_i2c0, 17.288 + /* Clock_i2c1 */ Clock_gate_i2c1, 17.289 + /* Clock_i2s */ Clock_gate_undefined, 17.290 + /* Clock_i2s0_rx */ Clock_gate_i2s0_rx, 17.291 + /* Clock_i2s0_tx */ Clock_gate_i2s0_tx, 17.292 + /* Clock_kbc */ Clock_gate_undefined, 17.293 + /* Clock_lcd */ Clock_gate_undefined, 17.294 + /* Clock_lcd_pixel */ Clock_gate_lcd_pixel, 17.295 + /* Clock_mac */ Clock_gate_gmac0, 17.296 + /* Clock_msc */ Clock_gate_msc0, 17.297 + /* Clock_msc0 */ Clock_gate_msc0, 17.298 + /* Clock_msc1 */ Clock_gate_msc1, 17.299 + /* Clock_pwm */ Clock_gate_pwm, 17.300 + /* Clock_pwm0 */ Clock_gate_pwm, 17.301 + /* Clock_pwm1 */ Clock_gate_undefined, 17.302 + /* Clock_scc */ Clock_gate_undefined, 17.303 + /* Clock_sfc */ Clock_gate_sfc, 17.304 + /* Clock_smb0 */ Clock_gate_undefined, 17.305 + /* Clock_smb1 */ Clock_gate_undefined, 17.306 + /* Clock_smb2 */ Clock_gate_undefined, 17.307 + /* Clock_smb3 */ Clock_gate_undefined, 17.308 + /* Clock_smb4 */ Clock_gate_undefined, 17.309 + /* Clock_ssi */ Clock_gate_ssi0, 17.310 + /* Clock_timer */ Clock_gate_timer, 17.311 + /* Clock_uart0 */ Clock_gate_uart0, 17.312 + /* Clock_uart1 */ Clock_gate_uart1, 17.313 + /* Clock_uart2 */ Clock_gate_uart2, 17.314 + /* Clock_uart3 */ Clock_gate_uart3, 17.315 + /* Clock_udc */ Clock_gate_undefined, 17.316 + /* Clock_uhc */ Clock_gate_undefined, 17.317 + /* Clock_uprt */ Clock_gate_undefined, 17.318 +}; 17.319 + 17.320 +enum Divider_bits : unsigned 17.321 +{ 17.322 + Ddr_divider_value = 0, // DDRCDR 17.323 + Lcd_divider_value = 0, // LPCDR 17.324 +}; 17.325 + 17.326 +enum Clock_status_values : unsigned 17.327 +{ 17.328 + Lcd_change_enable = 0x20000000, // CE_LCD 17.329 + Lcd_change_busy = 0x10000000, // LCD_BUSY 17.330 + Lcd_clock_stop = 0x08000000, // LCD_STOP 17.331 +}; 17.332 + 17.333 +enum Pll_bits : unsigned 17.334 +{ 17.335 + // Pll_control_A, Pll_control_M, Pll_control_E 17.336 + 17.337 + Pll_multiplier = 20, // xPLLM 17.338 + Pll_input_division = 14, // xPLLN 17.339 + Pll_output_division1 = 11, // xPLLOD1 17.340 + Pll_output_division0 = 8, // xPLLOD0 17.341 + Pll_stable = 3, // xPLL_ON 17.342 + Pll_enabled = 0, // xPLLEN 17.343 +}; 17.344 + 17.345 +enum Pll_bypass_bits : unsigned 17.346 +{ 17.347 + Pll_bypass_A = 30, // APLL_BP 17.348 + Pll_bypass_M = 28, // MPLL_BP 17.349 + Pll_bypass_E = 26, // EPLL_BP 17.350 +}; 17.351 + 17.352 + 17.353 + 17.354 +// If implemented as a Hw::Device, various properties would be 17.355 +// initialised in the constructor and obtained from the device tree 17.356 +// definitions. 17.357 + 17.358 +Cpm_x1600_chip::Cpm_x1600_chip(l4_addr_t addr, uint32_t exclk_freq) 17.359 +: _exclk_freq(exclk_freq) 17.360 +{ 17.361 + _regs = new Hw::Mmio_register_block<32>(addr); 17.362 + 17.363 + // add_cid("cpm"); 17.364 + // add_cid("cpm-x1600"); 17.365 + // register_property("exclk_freq", &_exclk_freq); 17.366 +} 17.367 + 17.368 +// Clock/timer control. 17.369 + 17.370 +uint32_t 17.371 +Cpm_x1600_chip::get_clock_gate_register(enum Clock_identifiers clock) 17.372 +{ 17.373 + return clock_gate_reg[clock]; 17.374 +} 17.375 + 17.376 +uint32_t 17.377 +Cpm_x1600_chip::get_clock_gate_value(enum Clock_identifiers clock) 17.378 +{ 17.379 + return 1 << clock_gate_bit[clock]; 17.380 +} 17.381 + 17.382 +int 17.383 +Cpm_x1600_chip::have_clock(enum Clock_identifiers clock) 17.384 +{ 17.385 + return !(_regs[get_clock_gate_register(clock)] & get_clock_gate_value(clock)); 17.386 +} 17.387 + 17.388 +void 17.389 +Cpm_x1600_chip::start_clock(enum Clock_identifiers clock) 17.390 +{ 17.391 + uint32_t gate = get_clock_gate_register(clock); 17.392 + 17.393 + _regs[gate] = _regs[gate] & ~get_clock_gate_value(clock); 17.394 +} 17.395 + 17.396 +void 17.397 +Cpm_x1600_chip::stop_clock(enum Clock_identifiers clock) 17.398 +{ 17.399 + uint32_t gate = get_clock_gate_register(clock); 17.400 + 17.401 + _regs[gate] = _regs[gate] | get_clock_gate_value(clock); 17.402 +} 17.403 + 17.404 + 17.405 + 17.406 +// Utility methods. 17.407 + 17.408 +uint32_t 17.409 +Cpm_x1600_chip::get_field(uint32_t reg, uint32_t mask, uint8_t shift) 17.410 +{ 17.411 + return (_regs[reg] & (mask << shift)) >> shift; 17.412 +} 17.413 + 17.414 +void 17.415 +Cpm_x1600_chip::set_field(uint32_t reg, uint32_t mask, uint8_t shift, uint32_t value) 17.416 +{ 17.417 + _regs[reg] = (_regs[reg] & (~(mask << shift))) | ((mask & value) << shift); 17.418 +} 17.419 + 17.420 +// General clock divider access. 17.421 + 17.422 +uint8_t 17.423 +Cpm_x1600_chip::_get_divider(uint32_t reg, uint32_t mask, uint8_t shift) 17.424 +{ 17.425 + return get_field(reg, mask, shift) + 1; 17.426 +} 17.427 + 17.428 + 17.429 + 17.430 +// PLL control. 17.431 + 17.432 +// Return whether the PLL is stable. 17.433 + 17.434 +int 17.435 +Cpm_x1600_chip::have_pll(uint32_t pll_reg) 17.436 +{ 17.437 + return _regs[pll_reg] & (1 << Pll_stable); 17.438 +} 17.439 + 17.440 +int 17.441 +Cpm_x1600_chip::pll_enabled(uint32_t pll_reg) 17.442 +{ 17.443 + return _regs[pll_reg] & (1 << Pll_enabled); 17.444 +} 17.445 + 17.446 +int 17.447 +Cpm_x1600_chip::pll_bypassed(uint32_t pll_reg) 17.448 +{ 17.449 + uint32_t mask; 17.450 + 17.451 + switch (pll_reg) 17.452 + { 17.453 + case Pll_control_A: mask = (1 << Pll_bypass_A); break; 17.454 + case Pll_control_M: mask = (1 << Pll_bypass_M); break; 17.455 + case Pll_control_E: mask = (1 << Pll_bypass_E); break; 17.456 + default: mask = 0; break; 17.457 + } 17.458 + 17.459 + return _regs[Pll_control] & mask; 17.460 +} 17.461 + 17.462 +void 17.463 +Cpm_x1600_chip::pll_enable(uint32_t pll_reg) 17.464 +{ 17.465 + _regs[pll_reg] = _regs[pll_reg] | (1 << Pll_enabled); 17.466 + while (!(_regs[pll_reg] & (1 << Pll_stable))); 17.467 +} 17.468 + 17.469 +void 17.470 +Cpm_x1600_chip::pll_disable(uint32_t pll_reg) 17.471 +{ 17.472 + _regs[pll_reg] = _regs[pll_reg] & ~(1 << Pll_enabled); 17.473 + while (_regs[pll_reg] & (1 << Pll_stable)); 17.474 +} 17.475 + 17.476 +// Feedback (13-bit) multiplier. 17.477 + 17.478 +uint16_t 17.479 +Cpm_x1600_chip::get_multiplier(uint32_t pll_reg) 17.480 +{ 17.481 + return get_field(pll_reg, 0x1fff, Pll_multiplier) + 1; 17.482 +} 17.483 + 17.484 +void 17.485 +Cpm_x1600_chip::set_multiplier(uint32_t pll_reg, uint16_t multiplier) 17.486 +{ 17.487 + set_field(pll_reg, 0x1fff, Pll_multiplier, multiplier - 1); 17.488 +} 17.489 + 17.490 +// Input (6-bit) divider. 17.491 + 17.492 +uint8_t 17.493 +Cpm_x1600_chip::get_input_division(uint32_t pll_reg) 17.494 +{ 17.495 + return get_field(pll_reg, 0x3f, Pll_input_division) + 1; 17.496 +} 17.497 + 17.498 +void 17.499 +Cpm_x1600_chip::set_input_division(uint32_t pll_reg, uint8_t divider) 17.500 +{ 17.501 + set_field(pll_reg, 0x3f, Pll_input_division, divider - 1); 17.502 +} 17.503 + 17.504 +// Output (dual 3-bit) dividers. 17.505 + 17.506 +uint8_t 17.507 +Cpm_x1600_chip::get_output_division(uint32_t pll_reg) 17.508 +{ 17.509 + uint8_t d0 = get_field(pll_reg, 0x07, Pll_output_division0); 17.510 + uint8_t d1 = get_field(pll_reg, 0x07, Pll_output_division1); 17.511 + 17.512 + return d0 * d1; 17.513 +} 17.514 + 17.515 +void 17.516 +Cpm_x1600_chip::set_output_division(uint32_t pll_reg, uint8_t divider) 17.517 +{ 17.518 + // Assert 1 as a minimum. 17.519 + // Divider 0 must be less than or equal to divider 1. 17.520 + 17.521 + uint8_t d0 = (uint8_t) floor(sqrt(divider ? divider : 1)); 17.522 + uint8_t d1 = divider / d0; 17.523 + 17.524 + set_field(pll_reg, 0x07, Pll_output_division0, d0); 17.525 + set_field(pll_reg, 0x07, Pll_output_division1, d1); 17.526 +} 17.527 + 17.528 +uint32_t 17.529 +Cpm_x1600_chip::get_pll_frequency(uint32_t pll_reg) 17.530 +{ 17.531 + // Test for PLL enable and not PLL bypass. 17.532 + 17.533 + if (pll_enabled(pll_reg) && !pll_bypassed(pll_reg)) 17.534 + return (_exclk_freq * get_multiplier(pll_reg)) / 17.535 + (get_input_division(pll_reg) * get_output_division(pll_reg)); 17.536 + else 17.537 + return _exclk_freq; 17.538 +} 17.539 + 17.540 +void 17.541 +Cpm_x1600_chip::set_pll_parameters(uint32_t pll_reg, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider) 17.542 +{ 17.543 + set_multiplier(pll_reg, multiplier); 17.544 + set_input_division(pll_reg, in_divider); 17.545 + set_output_division(pll_reg, out_divider); 17.546 + 17.547 + if (pll_enabled(pll_reg) && !pll_bypassed(pll_reg)) 17.548 + while (!have_pll(pll_reg)); 17.549 +} 17.550 + 17.551 + 17.552 + 17.553 +// CPU clock (CCLK) divider. 17.554 + 17.555 +uint8_t 17.556 +Cpm_x1600_chip::get_cpu_divider() 17.557 +{ 17.558 + return _get_divider(Clock_control, 0xf, Clock_cpu_divider); 17.559 +} 17.560 + 17.561 +// Fast peripheral clock (H0CLK) divider. 17.562 + 17.563 +uint8_t 17.564 +Cpm_x1600_chip::get_hclock0_divider() 17.565 +{ 17.566 + return _get_divider(Clock_control, 0xf, Clock_hclock0_divider); 17.567 +} 17.568 + 17.569 +// Fast peripheral clock (H2CLK) divider. 17.570 + 17.571 +uint8_t 17.572 +Cpm_x1600_chip::get_hclock2_divider() 17.573 +{ 17.574 + return _get_divider(Clock_control, 0xf, Clock_hclock2_divider); 17.575 +} 17.576 + 17.577 +// Slow peripheral clock (PCLK) divider. 17.578 + 17.579 +uint8_t 17.580 +Cpm_x1600_chip::get_pclock_divider() 17.581 +{ 17.582 + return _get_divider(Clock_control, 0xf, Clock_pclock_divider); 17.583 +} 17.584 + 17.585 +// LCD clock (LPCLK) divider for LCD pixel clock. 17.586 + 17.587 +uint8_t 17.588 +Cpm_x1600_chip::get_lcd_pixel_divider(uint8_t controller) 17.589 +{ 17.590 + (void) controller; 17.591 + return _get_divider(Lcd_divider, 0xff, Lcd_divider_value); 17.592 +} 17.593 + 17.594 +// Memory clock (DDR_CLK) divider. 17.595 + 17.596 +uint8_t 17.597 +Cpm_x1600_chip::get_memory_divider() 17.598 +{ 17.599 + return _get_divider(Ddr_divider, 0xf, Ddr_divider_value); 17.600 +} 17.601 + 17.602 +// LCD pixel clock divider. 17.603 + 17.604 +void 17.605 +Cpm_x1600_chip::set_lcd_pixel_divider(uint8_t controller, uint16_t division) 17.606 +{ 17.607 + if (controller > 0) 17.608 + return; 17.609 + 17.610 + if ((division < 1) || (division > 256)) 17.611 + return; 17.612 + 17.613 + // Enable change. 17.614 + 17.615 + _regs[Lcd_divider] = _regs[Lcd_divider] | Lcd_change_enable; 17.616 + 17.617 + // Set the divider. 17.618 + 17.619 + set_field(Lcd_divider, 0xff, Lcd_divider_value, division - 1); 17.620 + 17.621 + // Restart clock and disable change. 17.622 + 17.623 + while (_regs[Lcd_divider] & Lcd_change_busy); 17.624 + _regs[Lcd_divider] = _regs[Lcd_divider] & ~Lcd_change_enable; 17.625 +} 17.626 + 17.627 + 17.628 + 17.629 +// Clock sources. 17.630 + 17.631 +uint8_t 17.632 +Cpm_x1600_chip::get_memory_source() 17.633 +{ 17.634 + return get_field(Ddr_divider, 0x3, Clock_source_ddr); 17.635 +} 17.636 + 17.637 +uint32_t 17.638 +Cpm_x1600_chip::get_memory_source_frequency() 17.639 +{ 17.640 + switch (get_memory_source()) 17.641 + { 17.642 + case Source_mux_main: 17.643 + return get_main_frequency(); 17.644 + case Source_mux_pll_M: 17.645 + return get_pll_frequency(Pll_control_M); 17.646 + default: 17.647 + return 0; 17.648 + } 17.649 +} 17.650 + 17.651 +uint8_t 17.652 +Cpm_x1600_chip::get_cpu_source() 17.653 +{ 17.654 + return get_field(Clock_control, 0x3, Clock_source_cpu); 17.655 +} 17.656 + 17.657 +uint32_t 17.658 +Cpm_x1600_chip::get_cpu_source_frequency() 17.659 +{ 17.660 + switch (get_cpu_source()) 17.661 + { 17.662 + case Source_mux_main: 17.663 + return get_main_frequency(); 17.664 + case Source_mux_pll_M: 17.665 + return get_pll_frequency(Pll_control_M); 17.666 + default: 17.667 + return 0; 17.668 + } 17.669 +} 17.670 + 17.671 +uint8_t 17.672 +Cpm_x1600_chip::get_hclock0_source() 17.673 +{ 17.674 + return get_field(Clock_control, 0x3, Clock_source_hclock0); 17.675 +} 17.676 + 17.677 +uint32_t 17.678 +Cpm_x1600_chip::get_hclock0_source_frequency() 17.679 +{ 17.680 + switch (get_hclock0_source()) 17.681 + { 17.682 + case Source_mux_main: 17.683 + return get_main_frequency(); 17.684 + case Source_mux_pll_M: 17.685 + return get_pll_frequency(Pll_control_M); 17.686 + default: 17.687 + return 0; 17.688 + } 17.689 +} 17.690 + 17.691 +uint8_t 17.692 +Cpm_x1600_chip::get_hclock2_source() 17.693 +{ 17.694 + return get_field(Clock_control, 0x3, Clock_source_hclock2); 17.695 +} 17.696 + 17.697 +uint32_t 17.698 +Cpm_x1600_chip::get_hclock2_source_frequency() 17.699 +{ 17.700 + switch (get_hclock2_source()) 17.701 + { 17.702 + case Source_mux_main: 17.703 + return get_main_frequency(); 17.704 + case Source_mux_pll_M: 17.705 + return get_pll_frequency(Pll_control_M); 17.706 + default: 17.707 + return 0; 17.708 + } 17.709 +} 17.710 + 17.711 +void 17.712 +Cpm_x1600_chip::set_hclock2_source(uint8_t source) 17.713 +{ 17.714 + set_field(Clock_control, 0x3, Clock_source_hclock2, source); 17.715 +} 17.716 + 17.717 +uint8_t 17.718 +Cpm_x1600_chip::get_lcd_source(uint8_t controller) 17.719 +{ 17.720 + (void) controller; 17.721 + return get_field(Lcd_divider, 0x3, Clock_source_lcd); 17.722 +} 17.723 + 17.724 +uint32_t 17.725 +Cpm_x1600_chip::get_lcd_source_frequency(uint8_t controller) 17.726 +{ 17.727 + switch (get_lcd_source(controller)) 17.728 + { 17.729 + case Source_main: 17.730 + return get_main_frequency(); 17.731 + case Source_pll_M: 17.732 + return get_pll_frequency(Pll_control_M); 17.733 + case Source_pll_E: 17.734 + return get_pll_frequency(Pll_control_E); 17.735 + default: 17.736 + return 0; 17.737 + } 17.738 +} 17.739 + 17.740 +void 17.741 +Cpm_x1600_chip::set_lcd_source(uint8_t controller, uint8_t source) 17.742 +{ 17.743 + if (controller > 0) 17.744 + return; 17.745 + 17.746 + // Stop clock and enable change. 17.747 + 17.748 + _regs[Lcd_divider] = _regs[Lcd_divider] | Lcd_change_enable | Lcd_clock_stop; 17.749 + 17.750 + // Set the source. 17.751 + 17.752 + set_field(Lcd_divider, 0x03, Clock_source_lcd, source); 17.753 + 17.754 + // Restart clock and disable change. 17.755 + 17.756 + while (_regs[Lcd_divider] & Lcd_change_busy); 17.757 + _regs[Lcd_divider] = _regs[Lcd_divider] & ~(Lcd_change_enable | Lcd_clock_stop); 17.758 +} 17.759 + 17.760 +uint8_t 17.761 +Cpm_x1600_chip::get_pclock_source() 17.762 +{ 17.763 + return get_hclock2_source(); 17.764 +} 17.765 + 17.766 +uint32_t 17.767 +Cpm_x1600_chip::get_pclock_source_frequency() 17.768 +{ 17.769 + return get_hclock2_source_frequency(); 17.770 +} 17.771 + 17.772 +void 17.773 +Cpm_x1600_chip::set_pclock_source(uint8_t source) 17.774 +{ 17.775 + set_hclock2_source(source); 17.776 +} 17.777 + 17.778 + 17.779 + 17.780 +// Source frequency, used by various clock sources. 17.781 + 17.782 +uint8_t 17.783 +Cpm_x1600_chip::get_main_source() 17.784 +{ 17.785 + return get_field(Clock_control, 0x3, Clock_source_main); 17.786 +} 17.787 + 17.788 +uint32_t 17.789 +Cpm_x1600_chip::get_main_frequency() 17.790 +{ 17.791 + switch (get_main_source()) 17.792 + { 17.793 + case Source_pll_A: 17.794 + return get_pll_frequency(Pll_control_A); 17.795 + case Source_external: 17.796 + return _exclk_freq; 17.797 + default: 17.798 + return 0; 17.799 + } 17.800 +} 17.801 + 17.802 +// Clock frequency for the CPU. 17.803 + 17.804 +uint32_t 17.805 +Cpm_x1600_chip::get_cpu_frequency() 17.806 +{ 17.807 + return get_cpu_source_frequency() / get_cpu_divider(); 17.808 +} 17.809 + 17.810 +// Clock frequency for fast peripherals. 17.811 + 17.812 +uint32_t 17.813 +Cpm_x1600_chip::get_hclock0_frequency() 17.814 +{ 17.815 + return get_hclock0_source_frequency() / get_hclock0_divider(); 17.816 +} 17.817 + 17.818 +// Clock frequency for fast peripherals. 17.819 + 17.820 +uint32_t 17.821 +Cpm_x1600_chip::get_hclock2_frequency() 17.822 +{ 17.823 + return get_hclock2_source_frequency() / get_hclock2_divider(); 17.824 +} 17.825 + 17.826 +// Clock frequency for slow peripherals. 17.827 + 17.828 +uint32_t 17.829 +Cpm_x1600_chip::get_pclock_frequency() 17.830 +{ 17.831 + return get_pclock_source_frequency() / get_pclock_divider(); 17.832 +} 17.833 + 17.834 +// Clock frequency for the memory. 17.835 + 17.836 +uint32_t 17.837 +Cpm_x1600_chip::get_memory_frequency() 17.838 +{ 17.839 + return get_memory_source_frequency() / get_memory_divider(); 17.840 +} 17.841 + 17.842 +uint32_t 17.843 +Cpm_x1600_chip::get_apll_frequency() 17.844 +{ 17.845 + return get_pll_frequency(Pll_control_A); 17.846 +} 17.847 + 17.848 +uint32_t 17.849 +Cpm_x1600_chip::get_epll_frequency() 17.850 +{ 17.851 + return get_pll_frequency(Pll_control_E); 17.852 +} 17.853 + 17.854 +uint32_t 17.855 +Cpm_x1600_chip::get_mpll_frequency() 17.856 +{ 17.857 + return get_pll_frequency(Pll_control_M); 17.858 +} 17.859 + 17.860 + 17.861 + 17.862 +uint32_t 17.863 +Cpm_x1600_chip::get_frequency(enum Clock_identifiers clock) 17.864 +{ 17.865 + switch (clock) 17.866 + { 17.867 + // NOTE: Returning only the frequency for controller 0. 17.868 + 17.869 + case Clock_lcd_pixel: 17.870 + return get_lcd_source_frequency(0) / get_lcd_pixel_divider(0); 17.871 + 17.872 + // NOTE: Consider a better error result. 17.873 + 17.874 + default: 17.875 + return 0; 17.876 + } 17.877 +} 17.878 + 17.879 +void 17.880 +Cpm_x1600_chip::set_frequency(enum Clock_identifiers clock, uint32_t frequency) 17.881 +{ 17.882 + switch (clock) 17.883 + { 17.884 + // The pixel frequency is based on the selected clock source (SCLK_A, MPLL or 17.885 + // EPLL). 17.886 + 17.887 + case Clock_lcd_pixel: 17.888 + 17.889 + // Switch to the MPLL and attempt to set the divider. 17.890 + 17.891 + set_lcd_source(0, Source_pll_M); 17.892 + pll_enable(Pll_control_M); 17.893 + set_lcd_pixel_divider(0, get_lcd_source_frequency() / frequency); 17.894 + break; 17.895 + 17.896 + default: 17.897 + break; 17.898 + } 17.899 +} 17.900 + 17.901 + 17.902 + 17.903 +// C language interface functions. 17.904 + 17.905 +void 17.906 +*x1600_cpm_init(l4_addr_t cpm_base) 17.907 +{ 17.908 + /* Initialise the clock and power management peripheral with the 17.909 + register memory region and a 24MHz EXCLK frequency. */ 17.910 + 17.911 + return (void *) new Cpm_x1600_chip(cpm_base, 24000000); 17.912 +} 17.913 + 17.914 +int 17.915 +x1600_cpm_have_clock(void *cpm, enum Clock_identifiers clock) 17.916 +{ 17.917 + return static_cast<Cpm_x1600_chip *>(cpm)->have_clock(clock); 17.918 +} 17.919 + 17.920 +void 17.921 +x1600_cpm_start_clock(void *cpm, enum Clock_identifiers clock) 17.922 +{ 17.923 + static_cast<Cpm_x1600_chip *>(cpm)->start_clock(clock); 17.924 +} 17.925 + 17.926 +void 17.927 +x1600_cpm_stop_clock(void *cpm, enum Clock_identifiers clock) 17.928 +{ 17.929 + static_cast<Cpm_x1600_chip *>(cpm)->stop_clock(clock); 17.930 +} 17.931 + 17.932 + 17.933 + 17.934 +uint8_t 17.935 +x1600_cpm_get_cpu_divider(void *cpm) 17.936 +{ 17.937 + return static_cast<Cpm_x1600_chip *>(cpm)->get_cpu_divider(); 17.938 +} 17.939 + 17.940 +uint8_t 17.941 +x1600_cpm_get_hclock0_divider(void *cpm) 17.942 +{ 17.943 + return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_divider(); 17.944 +} 17.945 + 17.946 +uint8_t 17.947 +x1600_cpm_get_hclock2_divider(void *cpm) 17.948 +{ 17.949 + return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_divider(); 17.950 +} 17.951 + 17.952 +uint8_t 17.953 +x1600_cpm_get_lcd_pixel_divider(void *cpm) 17.954 +{ 17.955 + return static_cast<Cpm_x1600_chip *>(cpm)->get_lcd_pixel_divider(); 17.956 +} 17.957 + 17.958 +uint8_t 17.959 +x1600_cpm_get_memory_divider(void *cpm) 17.960 +{ 17.961 + return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_divider(); 17.962 +} 17.963 + 17.964 +uint8_t 17.965 +x1600_cpm_get_pclock_divider(void *cpm) 17.966 +{ 17.967 + return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_divider(); 17.968 +} 17.969 + 17.970 + 17.971 + 17.972 +uint8_t 17.973 +x1600_cpm_get_hclock0_source(void *cpm) 17.974 +{ 17.975 + return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_source(); 17.976 +} 17.977 + 17.978 +uint8_t 17.979 +x1600_cpm_get_hclock2_source(void *cpm) 17.980 +{ 17.981 + return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_source(); 17.982 +} 17.983 + 17.984 +uint8_t 17.985 +x1600_cpm_get_lcd_source(void *cpm) 17.986 +{ 17.987 + return static_cast<Cpm_x1600_chip *>(cpm)->get_lcd_source(); 17.988 +} 17.989 + 17.990 +uint8_t 17.991 +x1600_cpm_get_memory_source(void *cpm) 17.992 +{ 17.993 + return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_source(); 17.994 +} 17.995 + 17.996 +uint8_t 17.997 +x1600_cpm_get_pclock_source(void *cpm) 17.998 +{ 17.999 + return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_source(); 17.1000 +} 17.1001 + 17.1002 +void 17.1003 +x1600_cpm_set_pclock_source(void *cpm, uint8_t source) 17.1004 +{ 17.1005 + static_cast<Cpm_x1600_chip *>(cpm)->set_pclock_source(source); 17.1006 +} 17.1007 + 17.1008 + 17.1009 + 17.1010 +uint32_t 17.1011 +x1600_cpm_get_hclock0_source_frequency(void *cpm) 17.1012 +{ 17.1013 + return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_source_frequency(); 17.1014 +} 17.1015 + 17.1016 +uint32_t 17.1017 +x1600_cpm_get_hclock2_source_frequency(void *cpm) 17.1018 +{ 17.1019 + return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_source_frequency(); 17.1020 +} 17.1021 + 17.1022 +uint32_t 17.1023 +x1600_cpm_get_lcd_source_frequency(void *cpm) 17.1024 +{ 17.1025 + return static_cast<Cpm_x1600_chip *>(cpm)->get_lcd_source_frequency(); 17.1026 +} 17.1027 + 17.1028 +uint32_t 17.1029 +x1600_cpm_get_memory_source_frequency(void *cpm) 17.1030 +{ 17.1031 + return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_source_frequency(); 17.1032 +} 17.1033 + 17.1034 +uint32_t 17.1035 +x1600_cpm_get_pclock_source_frequency(void *cpm) 17.1036 +{ 17.1037 + return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_source_frequency(); 17.1038 +} 17.1039 + 17.1040 + 17.1041 + 17.1042 +uint8_t 17.1043 +x1600_cpm_get_main_source(void *cpm) 17.1044 +{ 17.1045 + return static_cast<Cpm_x1600_chip *>(cpm)->get_main_source(); 17.1046 +} 17.1047 + 17.1048 +uint32_t 17.1049 +x1600_cpm_get_main_frequency(void *cpm) 17.1050 +{ 17.1051 + return static_cast<Cpm_x1600_chip *>(cpm)->get_main_frequency(); 17.1052 +} 17.1053 + 17.1054 +uint32_t 17.1055 +x1600_cpm_get_cpu_frequency(void *cpm) 17.1056 +{ 17.1057 + return static_cast<Cpm_x1600_chip *>(cpm)->get_cpu_frequency(); 17.1058 +} 17.1059 + 17.1060 +uint32_t 17.1061 +x1600_cpm_get_hclock0_frequency(void *cpm) 17.1062 +{ 17.1063 + return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_frequency(); 17.1064 +} 17.1065 + 17.1066 +uint32_t 17.1067 +x1600_cpm_get_hclock2_frequency(void *cpm) 17.1068 +{ 17.1069 + return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_frequency(); 17.1070 +} 17.1071 + 17.1072 +uint32_t 17.1073 +x1600_cpm_get_memory_frequency(void *cpm) 17.1074 +{ 17.1075 + return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_frequency(); 17.1076 +} 17.1077 + 17.1078 +uint32_t 17.1079 +x1600_cpm_get_pclock_frequency(void *cpm) 17.1080 +{ 17.1081 + return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_frequency(); 17.1082 +} 17.1083 + 17.1084 +uint32_t 17.1085 +x1600_cpm_get_apll_frequency(void *cpm) 17.1086 +{ 17.1087 + return static_cast<Cpm_x1600_chip *>(cpm)->get_apll_frequency(); 17.1088 +} 17.1089 + 17.1090 +uint32_t 17.1091 +x1600_cpm_get_epll_frequency(void *cpm) 17.1092 +{ 17.1093 + return static_cast<Cpm_x1600_chip *>(cpm)->get_epll_frequency(); 17.1094 +} 17.1095 + 17.1096 +uint32_t 17.1097 +x1600_cpm_get_mpll_frequency(void *cpm) 17.1098 +{ 17.1099 + return static_cast<Cpm_x1600_chip *>(cpm)->get_mpll_frequency(); 17.1100 +} 17.1101 + 17.1102 + 17.1103 + 17.1104 +uint32_t 17.1105 +x1600_cpm_get_frequency(void *cpm, enum Clock_identifiers clock) 17.1106 +{ 17.1107 + return static_cast<Cpm_x1600_chip *>(cpm)->get_frequency(clock); 17.1108 +} 17.1109 + 17.1110 +void 17.1111 +x1600_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint32_t frequency) 17.1112 +{ 17.1113 + static_cast<Cpm_x1600_chip *>(cpm)->set_frequency(clock, frequency); 17.1114 +} 17.1115 + 17.1116 +void 17.1117 +x1600_cpm_set_mpll_parameters(void *cpm, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider) 17.1118 +{ 17.1119 + static_cast<Cpm_x1600_chip *>(cpm)->set_pll_parameters(Pll_control_M, multiplier, in_divider, out_divider); 17.1120 +}
18.1 --- a/pkg/landfall-examples/ci20_cpm/ci20_cpm.c Tue Sep 12 17:20:10 2023 +0200 18.2 +++ b/pkg/landfall-examples/ci20_cpm/ci20_cpm.c Thu Sep 14 00:11:14 2023 +0200 18.3 @@ -156,16 +156,16 @@ 18.4 printf("LCD source: %d\n", jz4780_cpm_get_lcd_source(cpm)); 18.5 printf(" LCD source frequency: %d\n", jz4780_cpm_get_lcd_source_frequency(cpm)); 18.6 printf(" LCD pixel clock divider: %d\n", jz4780_cpm_get_lcd_pixel_divider(cpm)); 18.7 - printf(" LCD pixel clock frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_frequency_lcd_pixel)); 18.8 + printf(" LCD pixel clock frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel)); 18.9 18.10 /* Attempt to set the pixel clock frequency. */ 18.11 18.12 - jz4780_cpm_set_frequency(cpm, Clock_frequency_lcd_pixel, 108000000); 18.13 + jz4780_cpm_set_frequency(cpm, Clock_lcd_pixel, 108000000); 18.14 18.15 printf("LCD source: %d\n", jz4780_cpm_get_lcd_source(cpm)); 18.16 printf(" LCD source frequency: %d\n", jz4780_cpm_get_lcd_source_frequency(cpm)); 18.17 printf(" LCD pixel clock divider: %d\n", jz4780_cpm_get_lcd_pixel_divider(cpm)); 18.18 - printf(" LCD pixel clock frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_frequency_lcd_pixel)); 18.19 + printf(" LCD pixel clock frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel)); 18.20 18.21 /* Attempt to set the peripheral clock frequency. */ 18.22
19.1 --- a/pkg/landfall-examples/ci20_hdmi_i2c/ci20_hdmi_i2c.c Tue Sep 12 17:20:10 2023 +0200 19.2 +++ b/pkg/landfall-examples/ci20_hdmi_i2c/ci20_hdmi_i2c.c Thu Sep 14 00:11:14 2023 +0200 19.3 @@ -274,13 +274,13 @@ 19.4 19.5 printf("VPLL frequency: %d\n", jz4780_cpm_get_vpll_frequency(cpm)); 19.6 printf("HDMI divider: %d\n", jz4780_cpm_get_hdmi_divider(cpm)); 19.7 - printf("HDMI frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_frequency_hdmi)); 19.8 + printf("HDMI frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_hdmi)); 19.9 19.10 jz4780_cpm_stop_clock(cpm, Clock_hdmi); 19.11 - jz4780_cpm_set_frequency(cpm, Clock_frequency_hdmi, 27000000); 19.12 + jz4780_cpm_set_frequency(cpm, Clock_hdmi, 27000000); 19.13 19.14 printf("HDMI divider: %d\n", jz4780_cpm_get_hdmi_divider(cpm)); 19.15 - printf("HDMI frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_frequency_hdmi)); 19.16 + printf("HDMI frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_hdmi)); 19.17 19.18 jz4780_cpm_start_clock(cpm, Clock_hdmi); 19.19 19.20 @@ -342,23 +342,23 @@ 19.21 19.22 printf("LCD source: %d\n", jz4780_cpm_get_lcd_source(cpm)); 19.23 printf("LCD divider: %d\n", jz4780_cpm_get_lcd_pixel_divider(cpm)); 19.24 - printf("LCD frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_frequency_lcd_pixel)); 19.25 + printf("LCD frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel)); 19.26 printf("Desired frequency: %d\n", jz4740_lcd_get_pixel_clock(lcd)); 19.27 19.28 jz4780_cpm_stop_clock(cpm, Clock_lcd); 19.29 - jz4780_cpm_set_frequency(cpm, Clock_frequency_lcd, jz4740_lcd_get_pixel_clock(lcd) * 3); 19.30 - jz4780_cpm_set_frequency(cpm, Clock_frequency_lcd_pixel, jz4740_lcd_get_pixel_clock(lcd)); 19.31 + jz4780_cpm_set_frequency(cpm, Clock_lcd, jz4740_lcd_get_pixel_clock(lcd) * 3); 19.32 + jz4780_cpm_set_frequency(cpm, Clock_lcd_pixel, jz4740_lcd_get_pixel_clock(lcd)); 19.33 19.34 printf("LCD source: %d\n", jz4780_cpm_get_lcd_source(cpm)); 19.35 printf("LCD divider: %d\n", jz4780_cpm_get_lcd_pixel_divider(cpm)); 19.36 - printf("LCD frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_frequency_lcd_pixel)); 19.37 + printf("LCD frequency: %d\n", jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel)); 19.38 printf("AHB0 frequency: %d\n", jz4780_cpm_get_hclock0_frequency(cpm)); 19.39 19.40 /* With the LCD pixel clock set up, bring up the HDMI. */ 19.41 19.42 printf("Enable HDMI output...\n"); 19.43 19.44 - jz4780_hdmi_enable(hdmi, jz4780_cpm_get_frequency(cpm, Clock_frequency_lcd_pixel)); 19.45 + jz4780_hdmi_enable(hdmi, jz4780_cpm_get_frequency(cpm, Clock_lcd_pixel)); 19.46 19.47 /* Create the DMA space. */ 19.48 19.49 @@ -469,7 +469,7 @@ 19.50 jz4740_lcd_set_irq(lcd, lcd_irq, Lcd_irq_frame_end); 19.51 19.52 jz4740_lcd_config(lcd, (struct Jz4740_lcd_descriptor *) desc_addr, 19.53 - (struct Jz4740_lcd_descriptor *) desc_paddr, 19.54 + (struct Jz4740_lcd_descriptor *) (l4_addr_t) desc_paddr, 19.55 fb_paddr); 19.56 19.57 jz4740_lcd_enable(lcd);
20.1 --- a/pkg/landfall-examples/qi_lb60_lcd/qi_lb60_lcd.c Tue Sep 12 17:20:10 2023 +0200 20.2 +++ b/pkg/landfall-examples/qi_lb60_lcd/qi_lb60_lcd.c Thu Sep 14 00:11:14 2023 +0200 20.3 @@ -187,9 +187,8 @@ 20.4 /* Test initialisation with a frequency appropriate for the test panel. */ 20.5 20.6 jz4740_cpm_stop_clock(cpm, Clock_lcd); 20.7 - jz4740_cpm_set_frequency(cpm, Clock_frequency_lcd, jz4740_lcd_get_pixel_clock(lcd) * 3); 20.8 - jz4740_cpm_set_frequency(cpm, Clock_frequency_lcd_pixel, jz4740_lcd_get_pixel_clock(lcd)); 20.9 - jz4740_cpm_update_output_frequency(cpm); 20.10 + jz4740_cpm_set_frequency(cpm, Clock_lcd, jz4740_lcd_get_pixel_clock(lcd) * 3); 20.11 + jz4740_cpm_set_frequency(cpm, Clock_lcd_pixel, jz4740_lcd_get_pixel_clock(lcd)); 20.12 20.13 /* Create the DMA space. */ 20.14 20.15 @@ -300,7 +299,7 @@ 20.16 jz4740_lcd_set_irq(lcd, lcd_irq, Lcd_irq_frame_end); 20.17 20.18 jz4740_lcd_config(lcd, (struct Jz4740_lcd_descriptor *) desc_addr, 20.19 - (struct Jz4740_lcd_descriptor *) desc_paddr, 20.20 + (struct Jz4740_lcd_descriptor *) (l4_addr_t) desc_paddr, 20.21 fb_paddr); 20.22 20.23 jz4740_lcd_enable(lcd);