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