1 /* 2 * Clock and power management. This exposes the combined functionality 3 * provided by the jz4780 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-jz4780.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_bch = 0x0ac, // BCHCDR 42 Divider_cim = 0x07c, // CIMCDR 43 Divider_ddr = 0x02c, // DDRCDR 44 Divider_gpu = 0x088, // GPUCDR 45 Divider_hdmi = 0x08c, // HDMICDR 46 Divider_i2s0 = 0x060, // I2SCDR 47 Divider_i2s1 = 0x0a0, // I2S1CDR 48 Divider_lcd0 = 0x054, // LP0CDR 49 Divider_lcd1 = 0x064, // LP1CDR 50 Divider_msc0 = 0x068, // MSC0CDR 51 Divider_msc1 = 0x0a4, // MSC1CDR 52 Divider_msc2 = 0x0a8, // MSC2CDR 53 Divider_pcm = 0x084, // PCMCDR 54 Divider_ssi = 0x074, // SSICDR 55 Divider_uhc = 0x06c, // UHCCDR 56 Divider_vpu = 0x030, // VPUCDR 57 58 Cpm_interrupt = 0x0b0, // CPM_INTR 59 Cpm_interrupt_en = 0x0b4, // CPM_INTRE 60 Cpm_scratch = 0x034, // CPSPR 61 Cpm_scratch_prot = 0x038, // CPSPPR 62 63 Usb_param_control0 = 0x03c, // USBPCR 64 Usb_reset_detect = 0x040, // USBRDT 65 Usb_vbus_jitter = 0x044, // USBVBFIL 66 Usb_param_control1 = 0x048, // USBPCR1 67 68 Pll_control = 0x00c, // CPPCR 69 Pll_control_A = 0x010, // CPAPCR 70 Pll_control_M = 0x014, // CPMPCR 71 Pll_control_E = 0x018, // CPEPCR 72 Pll_control_V = 0x01c, // CPVPCR 73 }; 74 75 76 77 // Register field definitions. 78 79 static Field Clock_source_main (Clock_control, 3, 30), // SEL_SRC (output to SCLK_A) 80 Clock_source_cpu (Clock_control, 3, 28), // SEL_CPLL (output to CCLK) 81 Clock_source_hclock0 (Clock_control, 3, 26), // SEL_H0PLL (output to AHB0) 82 Clock_source_hclock2 (Clock_control, 3, 24), // SEL_H2PLL (output to AHB2) 83 Clock_source_bch (Divider_bch, 3, 30), // BPCS 84 Clock_source_cim (Divider_cim, 1, 31), // CIMPCS 85 Clock_source_ddr (Divider_ddr, 3, 30), // DCS 86 Clock_source_gpu (Divider_gpu, 3, 30), // GPCS 87 Clock_source_hdmi (Divider_hdmi, 3, 30), // HPCS 88 Clock_source_i2s0 (Divider_i2s0, 3, 30), // I2CS, I2PCS 89 Clock_source_i2s1 (Divider_i2s1, 3, 30), // I2CS, I2PCS 90 Clock_source_lcd0 (Divider_lcd0, 3, 30), // LPCS 91 Clock_source_lcd1 (Divider_lcd1, 3, 30), // LPCS 92 Clock_source_msc (Divider_msc0, 3, 30), // MPCS 93 Clock_source_pcm (Divider_pcm, 7, 29), // PCMS, PCMPCS 94 Clock_source_rtc (Sleep_control, 0x01, 2), // ERCS 95 Clock_source_ssi (Divider_ssi, 3, 30), // SCS, SPCS 96 Clock_source_uhc (Divider_uhc, 3, 30), // UHCS 97 Clock_source_usb_phy (Usb_param_control1, 3, 24), // REFCLKDIV 98 Clock_source_vpu (Divider_vpu, 3, 30), // VCS 99 100 Clock_busy_cpu (Clock_status, 1, 0), 101 Clock_busy_hclock0 (Clock_status, 1, 1), 102 Clock_busy_hclock2 (Clock_status, 1, 2), 103 Clock_busy_bch (Divider_bch, 1, 28), 104 Clock_busy_cim (Divider_cim, 1, 29), 105 Clock_busy_ddr (Divider_ddr, 1, 28), 106 Clock_busy_gpu (Divider_gpu, 1, 28), 107 Clock_busy_hdmi (Divider_hdmi, 1, 28), 108 Clock_busy_i2s0 (Divider_i2s0, 1, 28), 109 Clock_busy_i2s1 (Divider_i2s1, 1, 28), 110 Clock_busy_lcd0 (Divider_lcd0, 1, 27), 111 Clock_busy_lcd1 (Divider_lcd1, 1, 27), 112 Clock_busy_msc0 (Divider_msc0, 1, 28), 113 Clock_busy_msc1 (Divider_msc1, 1, 28), 114 Clock_busy_msc2 (Divider_msc2, 1, 28), 115 Clock_busy_pcm (Divider_pcm, 1, 27), 116 Clock_busy_ssi (Divider_ssi, 1, 28), 117 Clock_busy_uhc (Divider_uhc, 1, 28), 118 Clock_busy_vpu (Divider_vpu, 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_bch (Divider_bch, 1, 29), 124 Clock_change_enable_cim (Divider_cim, 1, 30), 125 Clock_change_enable_ddr (Divider_ddr, 1, 29), 126 Clock_change_enable_gpu (Divider_gpu, 1, 29), 127 Clock_change_enable_hdmi (Divider_hdmi, 1, 29), 128 Clock_change_enable_i2s0 (Divider_i2s0, 1, 29), 129 Clock_change_enable_i2s1 (Divider_i2s1, 1, 29), 130 Clock_change_enable_lcd0 (Divider_lcd0, 1, 28), 131 Clock_change_enable_lcd1 (Divider_lcd1, 1, 28), 132 Clock_change_enable_msc0 (Divider_msc0, 1, 29), 133 Clock_change_enable_msc1 (Divider_msc1, 1, 29), 134 Clock_change_enable_msc2 (Divider_msc2, 1, 29), 135 Clock_change_enable_pcm (Divider_pcm, 1, 28), 136 Clock_change_enable_ssi (Divider_ssi, 1, 29), 137 Clock_change_enable_uhc (Divider_uhc, 1, 29), 138 Clock_change_enable_vpu (Divider_vpu, 1, 29), 139 140 Clock_divider_cpu (Clock_control, 0x0f, 0), // CDIV 141 Clock_divider_hclock0 (Clock_control, 0x0f, 8), // H0DIV (fast AHB peripherals) 142 Clock_divider_hclock2 (Clock_control, 0x0f, 12), // H2DIV (fast AHB peripherals) 143 Clock_divider_l2cache (Clock_control, 0x0f, 4), // L2CDIV 144 Clock_divider_pclock (Clock_control, 0x0f, 16), // PDIV (slow APB peripherals) 145 Clock_divider_bch (Divider_bch, 0x0f, 0), // BCHCDR 146 Clock_divider_cim (Divider_cim, 0xff, 0), // CIMCDR 147 Clock_divider_ddr (Divider_ddr, 0x0f, 0), // DDRCDR 148 Clock_divider_gpu (Divider_gpu, 0x0f, 0), // GPUCDR 149 Clock_divider_hdmi (Divider_hdmi, 0xff, 0), // HDMICDR 150 Clock_divider_i2s0 (Divider_i2s0, 0xff, 0), // I2SCDR 151 Clock_divider_i2s1 (Divider_i2s1, 0xff, 0), // I2SCDR 152 Clock_divider_lcd0 (Divider_lcd0, 0xff, 0), // LPCDR 153 Clock_divider_lcd1 (Divider_lcd1, 0xff, 0), // LPCDR 154 Clock_divider_msc0 (Divider_msc0, 0xff, 0), // MSC0CDR 155 Clock_divider_msc1 (Divider_msc1, 0xff, 0), // MSC1CDR 156 Clock_divider_msc2 (Divider_msc2, 0xff, 0), // MSC2CDR 157 Clock_divider_pcm (Divider_pcm, 0xff, 0), // PCMCDR 158 Clock_divider_ssi (Divider_ssi, 0xff, 0), // SSICDR 159 Clock_divider_uhc (Divider_uhc, 0xff, 0), // UHCCDR 160 Clock_divider_vpu (Divider_vpu, 0x0f, 0), // VPUCDR 161 162 Clock_gate_main (Clock_control, 1, 23, true), // GATE_SCLKA 163 Clock_gate_ddr (Clock_gate0, 3, 30, true), // DDR1, DDR0 164 Clock_gate_ipu (Clock_gate0, 1, 29, true), // IPU 165 Clock_gate_lcd (Clock_gate0, 3, 27, true), // LCD, TVE 166 Clock_gate_cim (Clock_gate0, 1, 26, true), // CIM 167 Clock_gate_i2c2 (Clock_gate0, 1, 25, true), // SMB2 168 Clock_gate_uhc (Clock_gate0, 1, 24, true), // UHC 169 Clock_gate_mac (Clock_gate0, 1, 23, true), // MAC 170 Clock_gate_gps (Clock_gate0, 1, 22, true), // GPS 171 Clock_gate_dma (Clock_gate0, 1, 21, true), // PDMA 172 //Clock_gate_ssi2 (Clock_gate0, 1, 20, true), // SSI2 173 Clock_gate_ssi1 (Clock_gate0, 1, 19, true), // SSI1 174 Clock_gate_uart3 (Clock_gate0, 1, 18, true), // UART3 175 Clock_gate_uart2 (Clock_gate0, 1, 17, true), // UART2 176 Clock_gate_uart1 (Clock_gate0, 1, 16, true), // UART1 177 Clock_gate_uart0 (Clock_gate0, 1, 15, true), // UART0 178 Clock_gate_sadc (Clock_gate0, 1, 14, true), // SADC 179 Clock_gate_kbc (Clock_gate0, 1, 13, true), // KBC 180 Clock_gate_msc2 (Clock_gate0, 1, 12, true), // MSC2 181 Clock_gate_msc1 (Clock_gate0, 1, 11, true), // MSC1 182 Clock_gate_owi (Clock_gate0, 1, 10, true), // OWI 183 Clock_gate_tssi0 (Clock_gate0, 1, 9, true), // TSSI0 184 Clock_gate_aic0 (Clock_gate0, 1, 8, true), // AIC0 185 Clock_gate_scc (Clock_gate0, 1, 7, true), // SCC 186 Clock_gate_i2c1 (Clock_gate0, 1, 6, true), // SMB1 187 Clock_gate_i2c0 (Clock_gate0, 1, 5, true), // SMB0 188 Clock_gate_ssi0 (Clock_gate0, 1, 4, true), // SSI0 189 Clock_gate_msc0 (Clock_gate0, 1, 3, true), // MSC0 190 Clock_gate_otg0 (Clock_gate0, 1, 2, true), // OTG0 191 Clock_gate_bch (Clock_gate0, 1, 1, true), // BCH 192 Clock_gate_nemc (Clock_gate0, 1, 0, true), // NEMC 193 Clock_gate_cpu1 (Clock_gate1, 1, 15, true), // P1 194 Clock_gate_x2d (Clock_gate1, 1, 14, true), // X2D 195 Clock_gate_des (Clock_gate1, 1, 13, true), // DES 196 Clock_gate_i2c4 (Clock_gate1, 1, 12, true), // SMB4 197 Clock_gate_ahb_mon (Clock_gate1, 1, 11, true), // AHB_MON 198 Clock_gate_uart4 (Clock_gate1, 1, 10, true), // UART4 199 Clock_gate_hdmi (Clock_gate1, 1, 9, true), // HDMI 200 Clock_gate_otg1 (Clock_gate1, 1, 8, true), // OTG1 201 Clock_gate_gpvlc (Clock_gate1, 1, 7, true), // GPVLC 202 Clock_gate_aic1 (Clock_gate1, 1, 6, true), // AIC1 203 Clock_gate_compress (Clock_gate1, 1, 5, true), // COMPRESS 204 Clock_gate_gpu (Clock_gate1, 1, 4, true), // GPU 205 Clock_gate_pcm (Clock_gate1, 1, 3, true), // PCM 206 Clock_gate_vpu (Clock_gate1, 1, 2, true), // VPU 207 Clock_gate_tssi1 (Clock_gate1, 1, 1, true), // TSSI1 208 Clock_gate_i2c3 (Clock_gate1, 1, 0, true), // I2C3 209 210 Pll_enable_A (Pll_control_A, 1, 0), // APLLEN 211 Pll_enable_E (Pll_control_E, 1, 0), // EPLLEN 212 Pll_enable_M (Pll_control_M, 1, 0), // MPLLEN 213 Pll_enable_V (Pll_control_V, 1, 0), // VPLLEN 214 215 Pll_stable_A (Pll_control_A, 1, 4), // APLL_ON 216 Pll_stable_E (Pll_control_E, 1, 4), // EPLL_ON 217 Pll_stable_M (Pll_control_M, 1, 4), // MPLL_ON 218 Pll_stable_V (Pll_control_V, 1, 4), // VPLL_ON 219 220 Pll_bypass_A (Pll_control_A, 1, 1), // APLL_BP 221 Pll_bypass_E (Pll_control_E, 1, 1), // EPLL_BP 222 Pll_bypass_M (Pll_control_M, 1, 1), // MPLL_BP 223 Pll_bypass_V (Pll_control_V, 1, 1), // VPLL_BP 224 225 // Multipliers and dividers yield 1-based values. 226 227 Pll_multiplier_A (Pll_control_A, 0x1fff, 19, false, 1), // APLLM 228 Pll_multiplier_E (Pll_control_E, 0x1fff, 19, false, 1), // EPLLM 229 Pll_multiplier_M (Pll_control_M, 0x1fff, 19, false, 1), // MPLLM 230 Pll_multiplier_V (Pll_control_V, 0x1fff, 19, false, 1), // VPLLM 231 232 Pll_input_division_A (Pll_control_A, 0x3f, 13, false, 1), // APLLN 233 Pll_input_division_E (Pll_control_E, 0x3f, 13, false, 1), // EPLLN 234 Pll_input_division_M (Pll_control_M, 0x3f, 13, false, 1), // MPLLN 235 Pll_input_division_V (Pll_control_V, 0x3f, 13, false, 1), // VPLLN 236 237 Pll_output_division_A (Pll_control_A, 0x0f, 9, false, 1), // APLLOD 238 Pll_output_division_E (Pll_control_E, 0x0f, 9, false, 1), // EPLLOD 239 Pll_output_division_M (Pll_control_M, 0x0f, 9, false, 1), // MPLLOD 240 Pll_output_division_V (Pll_control_V, 0x0f, 9, false, 1); // VPLLOD 241 242 243 244 // Multiplexer instances. 245 246 #define Clocks(...) ((enum Clock_identifiers []) {__VA_ARGS__}) 247 #define Specific(CLOCK) ((enum Clock_identifiers) (CLOCK)) 248 249 static Mux mux_external (Clock_external), 250 251 // Clocks being propagated to others. 252 253 mux_clock_ssi (Clock_ssi), 254 mux_clock_msc (Clock_msc), 255 mux_hclock2 (Clock_hclock2), 256 mux_hclock2_pclock (Clock_hclock2_pclock), 257 mux_pclock (Clock_pclock), 258 259 // Main bus and peripheral clock sources. 260 261 mux_ahb2 (4, Clocks(Clock_none, Clock_main, Clock_pll_M, Clock_rtc_external)), 262 mux_core (4, Clocks(Clock_none, Clock_main, Clock_pll_M, Clock_pll_E)), 263 mux_main (4, Clocks(Clock_none, Clock_pll_A, Clock_external, Clock_rtc_external)), 264 265 // Memory and device clock sources. 266 267 mux_cim (2, Clocks(Clock_main, Clock_pll_M)), 268 mux_dev (3, Clocks(Clock_none, Clock_main, Clock_pll_M)), 269 mux_lcd (3, Clocks(Clock_main, Clock_pll_M, Clock_pll_V)), 270 mux_usb (3, Clocks(Clock_main, Clock_pll_M, Clock_pll_E /* , OTG PHY */)), 271 mux_usb_phy (4, Clocks(Specific(Clock_usb_phy_12MHz), Specific(Clock_usb_phy_24MHz), 272 Specific(Clock_usb_phy_48MHz), Specific(Clock_usb_phy_19_2MHz))), 273 274 // Clock selectors involving the external clock. 275 276 mux_i2s (4, Clocks(Clock_external, Clock_external, Clock_main, Clock_pll_E)), 277 mux_pcm (8, Clocks(Clock_external, Clock_external, Clock_external, Clock_external, 278 Clock_main, Clock_pll_M, Clock_pll_E, Clock_pll_V)), 279 mux_rtc (2, Clocks(Clock_external_div, Clock_rtc_external)), 280 mux_ssi (4, Clocks(Clock_external, Clock_external, Clock_main, Clock_pll_M)); 281 282 283 284 // Clock instances. 285 286 static Clock_null clock_none; 287 288 static Clock_passive clock_external(48000000), 289 clock_rtc_external(32768), 290 clock_usb_phy_12MHz(12000000), 291 clock_usb_phy_19_2MHz(19200000), 292 clock_usb_phy_24MHz(24000000), 293 clock_usb_phy_48MHz(48000000); 294 295 296 297 // Note the use of extra parentheses due to the annoying C++ "most vexing parse" 298 // problem. See: https://en.wikipedia.org/wiki/Most_vexing_parse 299 300 static Clock clock_ahb_mon((Source(mux_external)), (Control(Clock_gate_ahb_mon))), 301 302 clock_compress((Source(mux_external)), (Control(Clock_gate_compress))), 303 304 clock_des((Source(mux_external)), (Control(Clock_gate_des))), 305 306 clock_dma((Source(mux_external)), (Control(Clock_gate_dma))), 307 308 clock_gps((Source(mux_external)), (Control(Clock_gate_gps))), 309 310 clock_gpvlc((Source(mux_external)), (Control(Clock_gate_gpvlc))), 311 312 clock_i2c0((Source(mux_pclock)), (Control(Clock_gate_i2c0))), 313 314 clock_i2c1((Source(mux_pclock)), (Control(Clock_gate_i2c1))), 315 316 clock_i2c2((Source(mux_pclock)), (Control(Clock_gate_i2c2))), 317 318 clock_i2c3((Source(mux_pclock)), (Control(Clock_gate_i2c3))), 319 320 clock_i2c4((Source(mux_pclock)), (Control(Clock_gate_i2c4))), 321 322 clock_i2s0(Source(mux_i2s, Clock_source_i2s0), Control(Clock_gate_aic0)), 323 324 clock_i2s1(Source(mux_i2s, Clock_source_i2s1), Control(Clock_gate_aic1)), 325 326 clock_ipu((Source(mux_external)), (Control(Clock_gate_ipu))), 327 328 clock_kbc((Source(mux_external)), (Control(Clock_gate_kbc))), 329 330 clock_lcd((Source(mux_external)), (Control(Clock_gate_lcd))), 331 332 clock_main(Source(mux_main, Clock_source_main), Control(Clock_gate_main)), 333 334 clock_mac((Source(mux_external)), (Control(Clock_gate_mac))), 335 336 clock_msc((Source(mux_dev, Clock_source_msc))), 337 338 clock_nemc((Source(mux_hclock2)), (Control(Clock_gate_nemc))), 339 340 clock_otg0((Source(mux_external)), (Control(Clock_gate_otg0))), 341 342 clock_otg1((Source(mux_external)), (Control(Clock_gate_otg1))), 343 344 clock_owi((Source(mux_external)), (Control(Clock_gate_owi))), 345 346 clock_rtc(Source(mux_rtc, Clock_source_rtc)), 347 348 clock_sadc((Source(mux_external)), (Control(Clock_gate_sadc))), 349 350 clock_scc((Source(mux_external)), (Control(Clock_gate_scc))), 351 352 clock_tssi0((Source(mux_external)), (Control(Clock_gate_tssi0))), 353 354 clock_tssi1((Source(mux_external)), (Control(Clock_gate_tssi1))), 355 356 clock_uart0((Source(mux_external)), (Control(Clock_gate_uart0))), 357 358 clock_uart1((Source(mux_external)), (Control(Clock_gate_uart1))), 359 360 clock_uart2((Source(mux_external)), (Control(Clock_gate_uart2))), 361 362 clock_uart3((Source(mux_external)), (Control(Clock_gate_uart3))), 363 364 clock_uart4((Source(mux_external)), (Control(Clock_gate_uart4))), 365 366 clock_usb_phy(Source(mux_usb_phy, Clock_source_usb_phy)), 367 368 clock_x2d((Source(mux_external)), (Control(Clock_gate_x2d))), 369 370 // Special parent clock for hclock2 and pclock. 371 372 clock_hclock2_pclock(Source(mux_ahb2, Clock_source_hclock2)), 373 374 // SSI channel clocks depending on a common parent divider. 375 376 clock_ssi0((Source(mux_clock_ssi)), Control(Clock_gate_ssi0)), 377 378 clock_ssi1((Source(mux_clock_ssi)), Control(Clock_gate_ssi1)); 379 380 static Clock_divided 381 clock_bch(Source(mux_core, Clock_source_bch), 382 Control(Clock_gate_bch, Clock_change_enable_bch, Clock_busy_bch), 383 Divider(Clock_divider_bch)), 384 385 clock_cim(Source(mux_cim, Clock_source_cim), 386 Control(Clock_gate_cim, Clock_change_enable_cim, Clock_busy_cim), 387 Divider(Clock_divider_cim)), 388 389 clock_cpu(Source(mux_core, Clock_source_cpu), 390 Control(Field::undefined, Clock_change_enable_cpu, Clock_busy_cpu), 391 Divider(Clock_divider_cpu)), 392 393 clock_ddr(Source(mux_dev, Clock_source_ddr), 394 Control(Clock_gate_ddr, Clock_change_enable_ddr, Clock_busy_ddr), 395 Divider(Clock_divider_ddr)), 396 397 clock_gpu(Source(mux_core, Clock_source_gpu), 398 Control(Clock_gate_gpu, Clock_change_enable_gpu, Clock_busy_gpu), 399 Divider(Clock_divider_gpu)), 400 401 clock_hclock0(Source(mux_core, Clock_source_hclock0), 402 Control(Field::undefined, Clock_change_enable_ahb0), 403 Divider(Clock_divider_hclock0)), 404 405 clock_hclock2(Source(mux_hclock2_pclock), 406 Control(Field::undefined, Clock_change_enable_ahb2), 407 Divider(Clock_divider_hclock2)), 408 409 clock_hdmi(Source(mux_lcd, Clock_source_hdmi), 410 Control(Clock_gate_hdmi, Clock_change_enable_hdmi, Clock_busy_hdmi), 411 Divider(Clock_divider_hdmi)), 412 413 clock_l2cache(Source(mux_core, Clock_source_cpu), 414 Control(Field::undefined, Clock_change_enable_cpu, Clock_busy_cpu), 415 Divider(Clock_divider_l2cache)), 416 417 clock_lcd_pixel0(Source(mux_lcd, Clock_source_lcd0), 418 Control(Clock_gate_lcd, Clock_change_enable_lcd0, Clock_busy_lcd0), 419 Divider(Clock_divider_lcd0)), 420 421 clock_lcd_pixel1(Source(mux_lcd, Clock_source_lcd1), 422 Control(Clock_gate_lcd, Clock_change_enable_lcd1, Clock_busy_lcd1), 423 Divider(Clock_divider_lcd1)), 424 425 clock_msc0(Source(mux_clock_msc), 426 Control(Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0), 427 Divider(Clock_divider_msc0, 2)), 428 429 clock_msc1(Source(mux_clock_msc), 430 Control(Clock_gate_msc1, Clock_change_enable_msc1, Clock_busy_msc1), 431 Divider(Clock_divider_msc1, 2)), 432 433 clock_msc2(Source(mux_clock_msc), 434 Control(Clock_gate_msc2, Clock_change_enable_msc2, Clock_busy_msc2), 435 Divider(Clock_divider_msc2, 2)), 436 437 clock_pcm(Source(mux_pcm, Clock_source_pcm), 438 Control(Clock_gate_pcm, Clock_change_enable_pcm, Clock_busy_pcm), 439 Divider(Clock_divider_pcm)), 440 441 clock_pclock(Source(mux_hclock2_pclock), 442 Control(Field::undefined, Clock_change_enable_ahb2), 443 Divider(Clock_divider_pclock)), 444 445 clock_ssi(Source(mux_ssi, Clock_source_ssi), 446 Control(Field::undefined, Clock_change_enable_ssi, Clock_busy_ssi), 447 Divider(Clock_divider_ssi)), 448 449 clock_uhc(Source(mux_usb, Clock_source_uhc), 450 Control(Clock_gate_uhc, Clock_change_enable_uhc, Clock_busy_uhc), 451 Divider(Clock_divider_uhc)), 452 453 clock_vpu(Source(mux_core, Clock_source_vpu), 454 Control(Clock_gate_vpu, Clock_change_enable_vpu, Clock_busy_vpu), 455 Divider(Clock_divider_vpu)); 456 457 static Clock_divided_fixed 458 clock_external_div((Source(mux_external)), (Divider_fixed(512))); 459 460 const double jz4780_pll_intermediate_min = 300000000, 461 jz4780_pll_intermediate_max = 1500000000; 462 463 static Pll clock_pll_A(Source(mux_external), 464 Control_pll(Pll_enable_A, Pll_stable_A, Pll_bypass_A), 465 Divider_pll(Pll_multiplier_A, Pll_input_division_A, 466 Pll_output_division_A, 467 jz4780_pll_intermediate_min, jz4780_pll_intermediate_max)), 468 469 clock_pll_E(Source(mux_external), 470 Control_pll(Pll_enable_E, Pll_stable_E, Pll_bypass_E), 471 Divider_pll(Pll_multiplier_E, Pll_input_division_E, 472 Pll_output_division_E, 473 jz4780_pll_intermediate_min, jz4780_pll_intermediate_max)), 474 475 clock_pll_M(Source(mux_external), 476 Control_pll(Pll_enable_M, Pll_stable_M, Pll_bypass_M), 477 Divider_pll(Pll_multiplier_M, Pll_input_division_M, 478 Pll_output_division_M, 479 jz4780_pll_intermediate_min, jz4780_pll_intermediate_max)), 480 481 clock_pll_V(Source(mux_external), 482 Control_pll(Pll_enable_V, Pll_stable_V, Pll_bypass_V), 483 Divider_pll(Pll_multiplier_V, Pll_input_division_V, 484 Pll_output_division_V, 485 jz4780_pll_intermediate_min, jz4780_pll_intermediate_max)); 486 487 488 489 // Clock register. 490 491 static Clock_base *clocks[Clock_jz4780_identifier_count] = { 492 &clock_none, 493 494 &clock_none, // Clock_aic 495 &clock_none, // Clock_aic_bitclk 496 &clock_none, // Clock_aic_pclk 497 &clock_none, // Clock_can0 498 &clock_none, // Clock_can1 499 &clock_none, // Clock_cdbus 500 &clock_cim, 501 &clock_cpu, 502 &clock_ddr, 503 &clock_dma, 504 &clock_none, // Clock_emac 505 &clock_external, 506 &clock_external_div, 507 &clock_hclock0, 508 &clock_hclock2, 509 &clock_hclock2_pclock, 510 &clock_hdmi, 511 &clock_i2c0, 512 &clock_i2c1, 513 &clock_i2c2, 514 &clock_i2c3, 515 &clock_i2c4, 516 &clock_i2s0, 517 &clock_none, // Clock_i2s0_rx 518 &clock_none, // Clock_i2s0_tx 519 &clock_i2s1, 520 &clock_none, // Clock_i2s1_rx 521 &clock_none, // Clock_i2s1_tx 522 &clock_none, // Clock_kbc 523 &clock_l2cache, 524 &clock_lcd, 525 &clock_lcd_pixel0, 526 &clock_lcd_pixel1, 527 &clock_mac, 528 &clock_main, 529 &clock_none, // Clock_mclock 530 &clock_none, // Clock_mipi_csi 531 &clock_msc, 532 &clock_msc0, 533 &clock_msc1, 534 &clock_msc2, 535 &clock_nemc, 536 &clock_otg0, 537 &clock_otg1, 538 &clock_pclock, 539 &clock_pcm, 540 &clock_none, // Clock_pll 541 &clock_pll_A, 542 &clock_pll_E, 543 &clock_pll_M, 544 &clock_pll_V, 545 &clock_none, // Clock_pwm0 546 &clock_none, // Clock_pwm1 547 &clock_rtc, 548 &clock_rtc_external, 549 &clock_sadc, 550 &clock_scc, 551 &clock_none, // Clock_sfc 552 &clock_ssi, 553 &clock_ssi0, 554 &clock_ssi1, 555 &clock_none, // Clock_ssi2 556 &clock_none, // Clock_timer 557 &clock_uart0, 558 &clock_uart1, 559 &clock_uart2, 560 &clock_uart3, 561 &clock_uart4, 562 &clock_none, // Clock_udc 563 &clock_uhc, 564 &clock_none, // Clock_uprt 565 &clock_usb_phy, 566 &clock_vpu, 567 568 /* JZ4780-specific clocks. */ 569 570 &clock_usb_phy_12MHz, 571 &clock_usb_phy_19_2MHz, 572 &clock_usb_phy_24MHz, 573 &clock_usb_phy_48MHz, 574 }; 575 576 577 578 // Peripheral abstraction. 579 580 Cpm_jz4780_chip::Cpm_jz4780_chip(l4_addr_t addr) 581 : Cpm_chip(addr, clocks) 582 { 583 } 584 585 Cpm_chip * 586 jz4780_cpm_chip(l4_addr_t cpm_base) 587 { 588 return new Cpm_jz4780_chip(cpm_base); 589 } 590 591 592 593 // C language interface functions. 594 595 void * 596 jz4780_cpm_init(l4_addr_t cpm_base) 597 { 598 return (void *) jz4780_cpm_chip(cpm_base); 599 } 600 601 const char * 602 jz4780_cpm_clock_type(void *cpm, enum Clock_identifiers clock) 603 { 604 return static_cast<Cpm_chip *>(cpm)->clock_type(clock); 605 } 606 607 int 608 jz4780_cpm_have_clock(void *cpm, enum Clock_identifiers clock) 609 { 610 return static_cast<Cpm_chip *>(cpm)->have_clock(clock); 611 } 612 613 void 614 jz4780_cpm_start_clock(void *cpm, enum Clock_identifiers clock) 615 { 616 static_cast<Cpm_chip *>(cpm)->start_clock(clock); 617 } 618 619 void 620 jz4780_cpm_stop_clock(void *cpm, enum Clock_identifiers clock) 621 { 622 static_cast<Cpm_chip *>(cpm)->stop_clock(clock); 623 } 624 625 int 626 jz4780_cpm_get_parameters(void *cpm, enum Clock_identifiers clock, uint32_t parameters[]) 627 { 628 return static_cast<Cpm_chip *>(cpm)->get_parameters(clock, parameters); 629 } 630 631 int 632 jz4780_cpm_set_parameters(void *cpm, enum Clock_identifiers clock, int num_parameters, uint32_t parameters[]) 633 { 634 return static_cast<Cpm_chip *>(cpm)->set_parameters(clock, num_parameters, parameters); 635 } 636 637 uint8_t 638 jz4780_cpm_get_source(void *cpm, enum Clock_identifiers clock) 639 { 640 return static_cast<Cpm_chip *>(cpm)->get_source(clock); 641 } 642 643 void 644 jz4780_cpm_set_source(void *cpm, enum Clock_identifiers clock, uint8_t source) 645 { 646 static_cast<Cpm_chip *>(cpm)->set_source(clock, source); 647 } 648 649 enum Clock_identifiers 650 jz4780_cpm_get_source_clock(void *cpm, enum Clock_identifiers clock) 651 { 652 return static_cast<Cpm_chip *>(cpm)->get_source_clock(clock); 653 } 654 655 void 656 jz4780_cpm_set_source_clock(void *cpm, enum Clock_identifiers clock, enum Clock_identifiers source) 657 { 658 static_cast<Cpm_chip *>(cpm)->set_source_clock(clock, source); 659 } 660 661 uint64_t 662 jz4780_cpm_get_source_frequency(void *cpm, enum Clock_identifiers clock) 663 { 664 return static_cast<Cpm_chip *>(cpm)->get_source_frequency(clock); 665 } 666 667 uint64_t 668 jz4780_cpm_get_frequency(void *cpm, enum Clock_identifiers clock) 669 { 670 return static_cast<Cpm_chip *>(cpm)->get_frequency(clock); 671 } 672 673 int 674 jz4780_cpm_set_frequency(void *cpm, enum Clock_identifiers clock, uint64_t frequency) 675 { 676 return static_cast<Cpm_chip *>(cpm)->set_frequency(clock, frequency); 677 }