Landfall

pkg/devices/lib/cpm/src/x1600.cc

243:c705336ff600
11 months ago Paul Boddie Introduced internal/chip-specific clock identifiers, starting with USB PHY source clocks. Replaced Clock_undefined with Clock_none, adjusting the clock identifier ordering. cpm-library-improvements
     1 /*     2  * Clock and power management. This exposes the combined functionality     3  * provided by the X1600 and related SoCs. The power management     4  * functionality could be exposed using a separate driver.     5  *     6  * Copyright (C) 2017, 2018, 2020, 2021, 2023 Paul Boddie <paul@boddie.org.uk>     7  *     8  * This program is free software; you can redistribute it and/or     9  * modify it under the terms of the GNU General Public License as    10  * published by the Free Software Foundation; either version 2 of    11  * the License, or (at your option) any later version.    12  *    13  * This program is distributed in the hope that it will be useful,    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    16  * GNU General Public License for more details.    17  *    18  * You should have received a copy of the GNU General Public License    19  * along with this program; if not, write to the Free Software    20  * Foundation, Inc., 51 Franklin Street, Fifth Floor,    21  * Boston, MA  02110-1301, USA    22  */    23     24 #include <l4/devices/hw_mmio_register_block.h>    25 #include "cpm-x1600.h"    26     27     28     29 // Register locations.    30     31 enum Regs : unsigned    32 {    33   Clock_control       = 0x000,  // CPCCR    34   Low_power_control   = 0x004,  // LCR    35   Clock_gate0         = 0x020,  // CLKGR0    36   Clock_gate1         = 0x028,  // CLKGR1    37   Sleep_control       = 0x024,  // OPCR (oscillator and power control)    38   Clock_status        = 0x0d4,  // CPCSR    39     40   Divider_can0        = 0x0a0,  // CAN0CDR    41   Divider_can1        = 0x0a8,  // CAN1CDR    42   Divider_cdbus       = 0x0ac,  // CDBUSCDR    43   Divider_cim         = 0x078,  // CIMCDR    44   Divider_ddr         = 0x02c,  // DDRCDR    45   Divider_mac         = 0x054,  // MACCDR    46   Divider0_i2s0       = 0x060,  // I2S0CDR    47   Divider1_i2s0       = 0x070,  // I2S0CDR1    48   Divider0_i2s1       = 0x07c,  // I2S1CDR (from X2000 manual)    49   Divider1_i2s1       = 0x080,  // I2S1CDR1 (from X2000 manual)    50   Divider_lcd         = 0x064,  // LPCDR    51   Divider_macphy0     = 0x0e4,  // MPHY0C    52   Divider_msc0        = 0x068,  // MSC0CDR    53   Divider_msc1        = 0x0a4,  // MSC1CDR    54   Divider_pwm         = 0x06c,  // PWMCDR    55   Divider_sfc         = 0x074,  // SFCCDR    56   Divider_ssi         = 0x05c,  // SSICDR    57     58   Cpm_interrupt       = 0x0b0,  // CPM_INTR    59   Cpm_interrupt_en    = 0x0b4,  // CPM_INTRE    60   Cpm_swi             = 0x0bc,  // CPM_SFTINT    61   Cpm_scratch         = 0x034,  // CPSPR    62   Cpm_scratch_prot    = 0x038,  // CPSPPR    63     64   Gate_ddr            = 0x0d0,  // DRCG    65     66   Usb_param_control0  = 0x03c,  // USBPCR    67   Usb_reset_detect    = 0x040,  // USBRDT    68   Usb_vbus_jitter     = 0x044,  // USBVBFIL    69   Usb_param_control1  = 0x048,  // USBPCR1    70     71   Pll_control         = 0x00c,  // CPPCR    72   Pll_control_A       = 0x010,  // CPAPCR    73   Pll_control_M       = 0x014,  // CPMPCR    74   Pll_control_E       = 0x018,  // CPEPCR    75   Pll_fraction_A      = 0x084,  // CPAPACR    76   Pll_fraction_M      = 0x088,  // CPMPACR    77   Pll_fraction_E      = 0x08c,  // CPEPACR    78 };    79     80     81     82 // Register field definitions.    83     84 static Field Clock_source_main         (Clock_control, 3, 30),       // SEL_SRC (output to SCLK_A)    85              Clock_source_cpu          (Clock_control, 3, 28),       // SEL_CPLL (output to CCLK)    86              Clock_source_hclock0      (Clock_control, 3, 26),       // SEL_H0PLL (output to AHB0)    87              Clock_source_hclock2      (Clock_control, 3, 24),       // SEL_H2PLL (output to AHB2)    88              Clock_source_can0         (Divider_can0, 3, 30),        // CA0CS    89              Clock_source_can1         (Divider_can1, 3, 30),        // CA1CS    90              Clock_source_cdbus        (Divider_cdbus, 3, 30),       // CDCS    91              Clock_source_cim          (Divider_cim, 3, 30),         // CIMPCS    92              Clock_source_ddr          (Divider_ddr, 3, 30),         // DCS    93              Clock_source_i2s0         (Divider0_i2s0, 1, 30),       // I2PCS    94              Clock_source_i2s1         (Divider0_i2s1, 1, 30),       // I2PCS    95              Clock_source_lcd          (Divider_lcd, 3, 30),         // LPCS    96              Clock_source_mac          (Divider_mac, 3, 30),         // MACPCS    97              Clock_source_msc0         (Divider_msc0, 3, 30),        // MPCS    98              Clock_source_msc1         (Divider_msc1, 3, 30),        // MPCS    99              Clock_source_pwm          (Divider_pwm, 3, 30),         // PWMPCS   100              Clock_source_rtc          (Sleep_control, 0x01, 2),     // ERCS   101              Clock_source_sfc          (Divider_sfc, 3, 30),         // SFCS   102              Clock_source_ssi          (Divider_ssi, 3, 30),         // SPCS   103    104              Clock_busy_cpu            (Clock_status, 1, 0),   105              Clock_busy_hclock0        (Clock_status, 1, 1),   106              Clock_busy_hclock2        (Clock_status, 1, 2),   107              Clock_busy_ddr            (Divider_ddr, 1, 28),   108              Clock_busy_mac            (Divider_mac, 1, 28),   109              Clock_busy_lcd            (Divider_lcd, 1, 28),   110              Clock_busy_msc0           (Divider_msc0, 1, 28),   111              Clock_busy_msc1           (Divider_msc1, 1, 28),   112              Clock_busy_sfc            (Divider_sfc, 1, 28),   113              Clock_busy_ssi            (Divider_ssi, 1, 28),   114              Clock_busy_cim            (Divider_cim, 1, 28),   115              Clock_busy_pwm            (Divider_pwm, 1, 28),   116              Clock_busy_can0           (Divider_can0, 1, 28),   117              Clock_busy_can1           (Divider_can1, 1, 28),   118              Clock_busy_cdbus          (Divider_cdbus, 1, 28),   119    120              Clock_change_enable_cpu   (Clock_control, 1, 22),   121              Clock_change_enable_ahb0  (Clock_control, 1, 21),   122              Clock_change_enable_ahb2  (Clock_control, 1, 20),   123              Clock_change_enable_ddr   (Divider_ddr, 1, 29),   124              Clock_change_enable_mac   (Divider_mac, 1, 29),   125              Clock_gate_i2s0           (Divider0_i2s0, 1, 29),       // CE_I2S is gate, not change enable   126              Clock_gate_i2s1           (Divider0_i2s1, 1, 29),       // CE_I2S is gate, not change enable   127              Clock_change_enable_lcd   (Divider_lcd, 1, 29),   128              Clock_change_enable_msc0  (Divider_msc0, 1, 29),   129              Clock_change_enable_msc1  (Divider_msc1, 1, 29),   130              Clock_change_enable_sfc   (Divider_sfc, 1, 29),   131              Clock_change_enable_ssi   (Divider_ssi, 1, 29),   132              Clock_change_enable_cim   (Divider_cim, 1, 29),   133              Clock_change_enable_pwm   (Divider_pwm, 1, 29),   134              Clock_change_enable_can0  (Divider_can0, 1, 29),   135              Clock_change_enable_can1  (Divider_can1, 1, 29),   136              Clock_change_enable_cdbus (Divider_cdbus, 1, 29),   137    138              Clock_divider_cpu         (Clock_control, 0x0f, 0),     // CDIV   139              Clock_divider_hclock0     (Clock_control, 0x0f, 8),     // H0DIV (fast AHB peripherals)   140              Clock_divider_hclock2     (Clock_control, 0x0f, 12),    // H2DIV (fast AHB peripherals)   141              Clock_divider_l2cache     (Clock_control, 0x0f, 4),     // L2CDIV   142              Clock_divider_pclock      (Clock_control, 0x0f, 16),    // PDIV (slow APB peripherals)   143              Clock_divider_can0        (Divider_can0, 0xff, 0),      // CAN0CDR   144              Clock_divider_can1        (Divider_can1, 0xff, 0),      // CAN1CDR   145              Clock_divider_cdbus       (Divider_cdbus, 0xff, 0),     // CDBUSCDR   146              Clock_divider_cim         (Divider_cim, 0xff, 0),       // CIMCDR   147              Clock_divider_ddr         (Divider_ddr, 0x0f, 0),       // DDRCDR   148              Clock_divider_i2s0_m      (Divider0_i2s0, 0x1ff, 20),   // I2SDIV_M   149              Clock_divider_i2s0_n      (Divider0_i2s0, 0xfffff, 0),  // I2SDIV_N   150              Clock_divider_i2s0_d      (Divider1_i2s0, 0xfffff, 0),  // I2SDIV_D   151              Clock_divider_i2s1_m      (Divider0_i2s1, 0x1ff, 20),   // I2SDIV_M   152              Clock_divider_i2s1_n      (Divider0_i2s1, 0xfffff, 0),  // I2SDIV_N   153              Clock_divider_i2s1_d      (Divider1_i2s1, 0xfffff, 0),  // I2SDIV_D   154              Clock_divider_lcd         (Divider_lcd, 0xff, 0),       // LPCDR   155              Clock_divider_mac         (Divider_mac, 0xff, 0),       // MACCDR   156              Clock_divider_msc0        (Divider_msc0, 0xff, 0),      // MSC0CDR   157              Clock_divider_msc1        (Divider_msc1, 0xff, 0),      // MSC1CDR   158              Clock_divider_pwm         (Divider_pwm, 0x0f, 0),       // PWMCDR   159              Clock_divider_sfc         (Divider_sfc, 0xff, 0),       // SFCCDR   160              Clock_divider_ssi         (Divider_ssi, 0xff, 0),       // SSICDR   161    162              Clock_divider_i2s0_n_auto (Divider1_i2s0, 1, 31),       // I2S_NEN   163              Clock_divider_i2s0_d_auto (Divider1_i2s0, 1, 30),       // I2S_DEN   164              Clock_divider_i2s1_n_auto (Divider1_i2s1, 1, 31),       // I2S_NEN   165              Clock_divider_i2s1_d_auto (Divider1_i2s1, 1, 30),       // I2S_DEN   166    167              Clock_gate_main           (Clock_control, 1, 23, true), // GATE_SCLKA   168              Clock_gate_ddr            (Clock_gate0, 1, 31, true),   // DDR   169              Clock_gate_ahb0           (Clock_gate0, 1, 29, true),   // AHB0   170              Clock_gate_apb0           (Clock_gate0, 1, 28, true),   // APB0   171              Clock_gate_rtc            (Clock_gate0, 1, 27, true),   // RTC   172              Clock_gate_aes            (Clock_gate0, 1, 24, true),   // AES   173              Clock_gate_lcd_pixel      (Clock_gate0, 1, 23, true),   // LCD   174              Clock_gate_cim            (Clock_gate0, 1, 22, true),   // CIM   175              Clock_gate_dma            (Clock_gate0, 1, 21, true),   // PDMA   176              Clock_gate_ost            (Clock_gate0, 1, 20, true),   // OST   177              Clock_gate_ssi0           (Clock_gate0, 1, 19, true),   // SSI0   178              Clock_gate_timer          (Clock_gate0, 1, 18, true),   // TCU   179              Clock_gate_dtrng          (Clock_gate0, 1, 17, true),   // DTRNG   180              Clock_gate_uart2          (Clock_gate0, 1, 16, true),   // UART2   181              Clock_gate_uart1          (Clock_gate0, 1, 15, true),   // UART1   182              Clock_gate_uart0          (Clock_gate0, 1, 14, true),   // UART0   183              Clock_gate_sadc           (Clock_gate0, 1, 13, true),   // SADC   184              Clock_gate_aic            (Clock_gate0, 1, 11, true),   // AUDIO   185              Clock_gate_ssi_slv        (Clock_gate0, 1, 10, true),   // SSI_SLV   186              Clock_gate_i2c1           (Clock_gate0, 1, 8, true),    // I2C1   187              Clock_gate_i2c0           (Clock_gate0, 1, 7, true),    // I2C0   188              Clock_gate_msc1           (Clock_gate0, 1, 5, true),    // MSC1   189              Clock_gate_msc0           (Clock_gate0, 1, 4, true),    // MSC0   190              Clock_gate_otg            (Clock_gate0, 1, 3, true),    // OTG   191              Clock_gate_sfc            (Clock_gate0, 1, 2, true),    // SFC   192              Clock_gate_efuse          (Clock_gate0, 1, 1, true),    // EFUSE   193              Clock_gate_nemc           (Clock_gate0, 1, 0, true),    // NEMC   194              Clock_gate_arb            (Clock_gate1, 1, 30, true),   // ARB   195              Clock_gate_mipi_csi       (Clock_gate1, 1, 28, true),   // MIPI_CSI   196              Clock_gate_intc           (Clock_gate1, 1, 26, true),   // INTC   197              Clock_gate_gmac0          (Clock_gate1, 1, 23, true),   // GMAC0   198              Clock_gate_uart3          (Clock_gate1, 1, 16, true),   // UART3   199              Clock_gate_i2s0_tx        (Clock_gate1, 1, 9, true),    // I2S0_dev_tclk   200              Clock_gate_i2s0_rx        (Clock_gate1, 1, 8, true),    // I2S0_dev_rclk   201              Clock_gate_hash           (Clock_gate1, 1, 6, true),    // HASH   202              Clock_gate_pwm            (Clock_gate1, 1, 5, true),    // PWM   203              Clock_gate_cdbus          (Clock_gate1, 1, 2, true),    // CDBUS   204              Clock_gate_can1           (Clock_gate1, 1, 1, true),    // CAN1   205              Clock_gate_can0           (Clock_gate1, 1, 0, true),    // CAN0   206              Clock_gate_usb_phy        (Sleep_control, 1, 23, true), // gate_usbphy_clk   207    208              Pll_enable_A              (Pll_control_A, 1, 0),        // APLLEN   209              Pll_enable_E              (Pll_control_E, 1, 0),        // EPLLEN   210              Pll_enable_M              (Pll_control_M, 1, 0),        // MPLLEN   211    212              Pll_stable_A              (Pll_control_A, 1, 3),        // APLL_ON   213              Pll_stable_E              (Pll_control_E, 1, 3),        // EPLL_ON   214              Pll_stable_M              (Pll_control_M, 1, 3),        // MPLL_ON   215    216              Pll_bypass_A              (Pll_control_A, 1, 30),       // APLL_BP   217              Pll_bypass_E              (Pll_control_E, 1, 26),       // EPLL_BP   218              Pll_bypass_M              (Pll_control_M, 1, 28),       // MPLL_BP   219    220              Pll_multiplier_A          (Pll_control_A, 0xfff, 20),   // APLLM   221              Pll_multiplier_E          (Pll_control_E, 0x3f, 20),    // EPLLM (observed)   222              Pll_multiplier_M          (Pll_control_M, 0xfff, 20),   // MPLLM   223    224              Pll_input_division_A      (Pll_control_A, 0x3f, 14),    // APLLN   225              Pll_input_division_E      (Pll_control_E, 0x3f, 14),    // EPLLN   226              Pll_input_division_M      (Pll_control_M, 0x3f, 14),    // MPLLN   227    228              Pll_output_division1_A    (Pll_control_A, 0x07, 11),    // APLLOD1   229              Pll_output_division1_E    (Pll_control_E, 0x07, 11),    // EPLLOD1   230              Pll_output_division1_M    (Pll_control_M, 0x07, 11),    // MPLLOD1   231    232              Pll_output_division0_A    (Pll_control_A, 0x07, 8),     // APLLOD0   233              Pll_output_division0_E    (Pll_control_E, 0x07, 8),     // EPLLOD0   234              Pll_output_division0_M    (Pll_control_M, 0x07, 8);     // MPLLOD0   235    236    237    238 // Multiplexer instances.   239    240 #define Clocks(...) ((enum Clock_identifiers []) {__VA_ARGS__})   241 #define Specific(CLOCK) ((enum Clock_identifiers) (CLOCK))   242    243 static Mux mux_external       (Clock_external),   244    245            // Clocks being propagated to others.   246    247            mux_hclock0        (Clock_hclock0),   248            mux_hclock2        (Clock_hclock2),   249            mux_pclock         (Clock_pclock),   250            mux_hclock2_pclock (Clock_hclock2_pclock),   251            mux_i2s0_rx        (Clock_i2s0),   252            mux_i2s0_tx        (Clock_i2s1),   253            mux_usb_phy        (Specific(Clock_usb_phy_12MHz)),   254    255            // Main peripheral and bus clock sources.   256    257            mux_bus      (4, Clocks(Clock_main, Clock_pll_M, Clock_pll_E, Clock_external)),   258            mux_core     (3, Clocks(Clock_none, Clock_main, Clock_pll_M)),   259            mux_dev      (3, Clocks(Clock_main, Clock_pll_M, Clock_pll_E)),   260            mux_main     (3, Clocks(Clock_none, Clock_external, Clock_pll_A)),   261            mux_i2s      (2, Clocks(Clock_main, Clock_pll_E)),   262            mux_rtc      (2, Clocks(Clock_external_div_512, Clock_rtc_external));   263    264    265    266 // Clock instances.   267    268 static Clock_null        clock_none;   269    270 static Clock_passive     clock_external(24000000),   271                          clock_rtc_external(32768),   272                          clock_usb_phy_12MHz(12000000);   273    274 // Note the use of extra parentheses due to the annoying C++ "most vexing parse"   275 // problem. See: https://en.wikipedia.org/wiki/Most_vexing_parse   276    277 static Clock clock_aic((Source(mux_hclock2)), (Control(Clock_gate_aic))),   278    279              clock_dma((Source(mux_hclock2)), (Control(Clock_gate_dma))),   280    281              clock_i2c0((Source(mux_pclock)), (Control(Clock_gate_i2c0))),   282    283              clock_i2c1((Source(mux_pclock)), (Control(Clock_gate_i2c1))),   284    285              clock_i2s0(Source(mux_i2s, Clock_source_i2s0), Control(Clock_gate_i2s0)),   286    287              clock_i2s1(Source(mux_i2s, Clock_source_i2s1), Control(Clock_gate_i2s1)),   288    289              clock_main(Source(mux_main, Clock_source_main), Control(Clock_gate_main)),   290    291              clock_mipi_csi((Source(mux_hclock0)), Control(Clock_gate_mipi_csi)),   292    293              clock_otg0((Source(mux_hclock2)), (Control(Clock_gate_otg))),   294    295              clock_rtc(Source(mux_rtc, Clock_source_rtc), (Control(Clock_gate_rtc))),   296    297              clock_timer((Source(mux_pclock)), (Control(Clock_gate_timer))),   298    299              clock_uart0((Source(mux_external)), (Control(Clock_gate_uart0))),   300    301              clock_uart1((Source(mux_external)), (Control(Clock_gate_uart1))),   302    303              clock_uart2((Source(mux_external)), (Control(Clock_gate_uart2))),   304    305              clock_uart3((Source(mux_external)), (Control(Clock_gate_uart3))),   306    307              clock_usb_phy((Source(mux_usb_phy)), (Control(Clock_gate_usb_phy))),   308    309              // Special parent clock for hclock2 and pclock.   310    311              clock_hclock2_pclock(Source(mux_core, Clock_source_hclock2),   312                            Control(Clock_gate_apb0, Clock_change_enable_ahb2));   313    314 static Clock_divided   315              clock_can0(Source(mux_bus, Clock_source_can0),   316                         Control(Clock_gate_can0, Clock_change_enable_can0, Clock_busy_can0),   317                         Divider(Clock_divider_can0)),   318    319              clock_can1(Source(mux_bus, Clock_source_can1),   320                         Control(Clock_gate_can1, Clock_change_enable_can1, Clock_busy_can1),   321                         Divider(Clock_divider_can1)),   322    323              clock_cdbus(Source(mux_dev, Clock_source_cdbus),   324                          Control(Clock_gate_cdbus, Clock_change_enable_cdbus, Clock_busy_cdbus),   325                          Divider(Clock_divider_cdbus)),   326    327              clock_cim(Source(mux_dev, Clock_source_cim),   328                        Control(Clock_gate_cim, Clock_change_enable_cim, Clock_busy_cim),   329                        Divider(Clock_divider_cim)),   330    331              clock_cpu(Source(mux_core, Clock_source_cpu),   332                        Control(Field::undefined, Clock_change_enable_cpu, Clock_busy_cpu),   333                        Divider(Clock_divider_cpu)),   334    335              clock_ddr(Source(mux_core, Clock_source_ddr),   336                        Control(Clock_gate_ddr, Clock_change_enable_ddr, Clock_busy_ddr),   337                        Divider(Clock_divider_ddr)),   338    339              clock_hclock0(Source(mux_core, Clock_source_hclock0),   340                            Control(Clock_gate_ahb0, Clock_change_enable_ahb0),   341                            Divider(Clock_divider_hclock0)),   342    343              clock_hclock2((Source(mux_hclock2_pclock)), (Divider(Clock_divider_hclock2))),   344    345              clock_l2cache(Source(mux_core, Clock_source_cpu),   346                            Control(Field::undefined, Clock_change_enable_cpu, Clock_busy_cpu),   347                            Divider(Clock_divider_l2cache)),   348    349              clock_lcd_pixel(Source(mux_dev, Clock_source_lcd),   350                              Control(Clock_gate_lcd_pixel, Clock_change_enable_lcd, Clock_busy_lcd),   351                              Divider(Clock_divider_lcd)),   352    353              clock_mac(Source(mux_dev, Clock_source_mac),   354                        Control(Clock_gate_gmac0, Clock_change_enable_mac, Clock_busy_mac),   355                        Divider(Clock_divider_mac)),   356    357              clock_msc0(Source(mux_dev, Clock_source_msc0),   358                         Control(Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0),   359                         Divider(Clock_divider_msc0)),   360    361              clock_msc1(Source(mux_dev, Clock_source_msc1),   362                         Control(Clock_gate_msc1, Clock_change_enable_msc1, Clock_busy_msc1),   363                         Divider(Clock_divider_msc1)),   364    365              clock_pclock((Source(mux_hclock2_pclock)), (Divider(Clock_divider_pclock))),   366    367              clock_pwm0(Source(mux_dev, Clock_source_pwm),   368                         Control(Clock_gate_pwm, Clock_change_enable_pwm, Clock_busy_pwm),   369                         Divider(Clock_divider_pwm)),   370    371              clock_sfc(Source(mux_dev, Clock_source_sfc),   372                        Control(Clock_gate_sfc, Clock_change_enable_sfc, Clock_busy_sfc),   373                        Divider(Clock_divider_sfc)),   374    375              clock_ssi0(Source(mux_dev, Clock_source_ssi),   376                         Control(Clock_gate_ssi0, Clock_change_enable_ssi, Clock_busy_ssi),   377                         Divider(Clock_divider_ssi));   378    379 static Clock_divided_fixed   380              clock_external_div_512((Source(mux_external)), (Divider_fixed(512)));   381    382 static Clock_divided_i2s   383              clock_i2s0_rx(Source(mux_i2s0_rx),   384                            Control(Clock_gate_i2s0_rx),   385                            Divider_i2s(Clock_divider_i2s0_m, Clock_divider_i2s0_n,   386                                        Clock_divider_i2s0_d, Clock_divider_i2s0_n_auto,   387                                        Clock_divider_i2s0_d_auto)),   388    389              clock_i2s0_tx(Source(mux_i2s0_tx),   390                            Control(Clock_gate_i2s0_tx),   391                            Divider_i2s(Clock_divider_i2s1_m, Clock_divider_i2s1_n,   392                                        Clock_divider_i2s1_d, Clock_divider_i2s1_n_auto,   393                                        Clock_divider_i2s1_d_auto));   394    395 const double x1600_pll_intermediate_min = 600000000,   396              x1600_pll_intermediate_max = 2400000000;   397    398 static Pll   clock_pll_A(Source(mux_external),   399                          Control_pll(Pll_enable_A, Pll_stable_A, Pll_bypass_A),   400                          Divider_pll(Pll_multiplier_A, Pll_input_division_A,   401                                      Pll_output_division0_A, Pll_output_division1_A,   402                                      x1600_pll_intermediate_min, x1600_pll_intermediate_max,   403                                      false)),   404    405              clock_pll_E(Source(mux_external),   406                          Control_pll(Pll_enable_E, Pll_stable_E, Pll_bypass_E),   407                          Divider_pll(Pll_multiplier_E, Pll_input_division_E,   408                                      Pll_output_division0_E, Pll_output_division1_E,   409                                      x1600_pll_intermediate_min, x1600_pll_intermediate_max,   410                                      false)),   411    412              clock_pll_M(Source(mux_external),   413                          Control_pll(Pll_enable_M, Pll_stable_M, Pll_bypass_M),   414                          Divider_pll(Pll_multiplier_M, Pll_input_division_M,   415                                      Pll_output_division0_M, Pll_output_division1_M,   416                                      x1600_pll_intermediate_min, x1600_pll_intermediate_max,   417                                      false));   418    419    420    421 // Clock register.   422    423 static Clock_base *clocks[Clock_x1600_identifier_count] = {   424   &clock_none,   425    426   &clock_aic,   427   &clock_none,            // Clock_aic_bitclk   428   &clock_none,            // Clock_aic_pclk   429   &clock_can0,   430   &clock_can1,   431   &clock_cdbus,   432   &clock_cim,   433   &clock_cpu,   434   &clock_ddr,   435   &clock_dma,   436   &clock_none,            // Clock_emac   437   &clock_external,   438   &clock_external_div_512,   439   &clock_hclock0,   440   &clock_hclock2,   441   &clock_hclock2_pclock,   442   &clock_none,            // Clock_hdmi   443   &clock_i2c0,   444   &clock_i2c1,   445   &clock_none,            // Clock_i2c2   446   &clock_none,            // Clock_i2c3   447   &clock_none,            // Clock_i2c4   448   &clock_i2s0,            // supplies i2s0_rx   449   &clock_i2s0_rx,   450   &clock_i2s0_tx,   451   &clock_i2s1,            // supplies i2s0_tx   452   &clock_none,            // Clock_i2s1_rx   453   &clock_none,            // Clock_i2s1_tx   454   &clock_none,            // Clock_kbc   455   &clock_l2cache,   456   &clock_none,            // Clock_lcd   457   &clock_lcd_pixel,   458   &clock_none,            // Clock_lcd_pixel1   459   &clock_mac,   460   &clock_main,   461   &clock_mipi_csi,   462   &clock_none,            // Clock_msc   463   &clock_msc0,   464   &clock_msc1,   465   &clock_none,            // Clock_msc2   466   &clock_otg0,   467   &clock_none,            // Clock_otg1   468   &clock_pclock,   469   &clock_none,            // Clock_pcm   470   &clock_pll_A,   471   &clock_pll_E,   472   &clock_pll_M,   473   &clock_none,            // Clock_pll_V   474   &clock_pwm0,   475   &clock_none,            // Clock_pwm1   476   &clock_rtc,   477   &clock_rtc_external,   478   &clock_none,            // Clock_scc   479   &clock_sfc,   480   &clock_none,            // Clock_ssi   481   &clock_ssi0,   482   &clock_none,            // Clock_ssi1   483   &clock_none,            // Clock_ssi2   484   &clock_timer,   485   &clock_uart0,   486   &clock_uart1,   487   &clock_uart2,   488   &clock_uart3,   489   &clock_none,            // Clock_uart4   490   &clock_none,            // Clock_udc   491   &clock_none,            // Clock_uhc   492   &clock_none,            // Clock_uprt   493   &clock_usb_phy,   494   &clock_none,            // Clock_vpu   495    496   /* X1600-specific clocks. */   497    498   &clock_usb_phy_12MHz,   499 };   500    501    502    503 // Peripheral abstraction.   504    505 Cpm_x1600_chip::Cpm_x1600_chip(l4_addr_t addr)   506 : Cpm_chip(addr, clocks)   507 {   508 }   509    510    511    512 // C language interface functions.   513    514 void   515 *x1600_cpm_init(l4_addr_t cpm_base)   516 {   517   return (void *) new Cpm_x1600_chip(cpm_base);   518 }   519    520 const char *   521 x1600_cpm_clock_type(void *cpm, enum Clock_identifiers clock)   522 {   523   return static_cast<Cpm_x1600_chip *>(cpm)->clock_type(clock);   524 }   525    526 int   527 x1600_cpm_have_clock(void *cpm, enum Clock_identifiers clock)   528 {   529   return static_cast<Cpm_x1600_chip *>(cpm)->have_clock(clock);   530 }   531    532 void   533 x1600_cpm_start_clock(void *cpm, enum Clock_identifiers clock)   534 {   535   static_cast<Cpm_x1600_chip *>(cpm)->start_clock(clock);   536 }   537    538 void   539 x1600_cpm_stop_clock(void *cpm, enum Clock_identifiers clock)   540 {   541   static_cast<Cpm_x1600_chip *>(cpm)->stop_clock(clock);   542 }   543    544 int   545 x1600_cpm_get_parameters(void *cpm, enum Clock_identifiers clock, uint32_t parameters[])   546 {   547   return static_cast<Cpm_x1600_chip *>(cpm)->get_parameters(clock, parameters);   548 }   549    550 int   551 x1600_cpm_set_parameters(void *cpm, enum Clock_identifiers clock, int num_parameters, uint32_t parameters[])   552 {   553   return static_cast<Cpm_x1600_chip *>(cpm)->set_parameters(clock, num_parameters, parameters);   554 }   555    556 uint8_t   557 x1600_cpm_get_source(void *cpm, enum Clock_identifiers clock)   558 {   559   return static_cast<Cpm_x1600_chip *>(cpm)->get_source(clock);   560 }   561    562 void   563 x1600_cpm_set_source(void *cpm, enum Clock_identifiers clock, uint8_t source)   564 {   565   static_cast<Cpm_x1600_chip *>(cpm)->set_source(clock, source);   566 }   567    568 enum Clock_identifiers   569 x1600_cpm_get_source_clock(void *cpm, enum Clock_identifiers clock)   570 {   571   return static_cast<Cpm_x1600_chip *>(cpm)->get_source_clock(clock);   572 }   573    574 void   575 x1600_cpm_set_source_clock(void *cpm, enum Clock_identifiers clock, enum Clock_identifiers source)   576 {   577   static_cast<Cpm_x1600_chip *>(cpm)->set_source_clock(clock, source);   578 }   579    580 uint64_t   581 x1600_cpm_get_source_frequency(void *cpm, enum Clock_identifiers clock)   582 {   583   return static_cast<Cpm_x1600_chip *>(cpm)->get_source_frequency(clock);   584 }   585    586 uint64_t   587 x1600_cpm_get_frequency(void *cpm, enum Clock_identifiers clock)   588 {   589   return static_cast<Cpm_x1600_chip *>(cpm)->get_frequency(clock);   590 }   591    592 int   593 x1600_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint64_t frequency)   594 {   595   return static_cast<Cpm_x1600_chip *>(cpm)->set_frequency(clock, frequency);   596 }