#ifndef _PLATFORM_CLOCK_H #define _PLATFORM_CLOCK_H #include #include /* Clocking and reset is managed by the PRCI (Power Reset Clocking Interrupt) * block (Figure 24) [77] * * FU740-C000 generates all internal clocks from 26 MHz hfclk driven from an * external oscillator (HFCLKIN) or crystal (HFOSCIN) input, selected by input * HFXSEL. All harts operate in a single clock domain (coreclk) supplied by * either corepll or dvfscorepll, which can be selected using the corepllsel * register. These PLLs step 26 MHz hfclk up to higher frequencies. * The recommended frequency of coreclk is 1.0GHz, however operation at up to * 1.5GHz is possible. * tlclk is a divided version of the coreclk and generates the clock for the L2 * cache. * The hfpclkpll generates the clock for peripherals such as SPI, UART, GPIO, * I2C, and PWM. * dvfs_core_pll enables the user to change the CPU frequency without dropping * down to the lower frequency hfclk. * The DDR, Ethernet and PCIe Subsystems operate asynchronously. * The PRCI contains two dedicated PLLs used to step 26 MHz hfclk up to the DDR * and Ethernet operating frequencies. * The PCIe Subsystem contains its own clock generation. * The PRCI contains memory-mapped registers that control the clock selection * and configuration of the PLLs. * On power-on, the default PRCI register settings start the harts running * directly from hfclk. * All additional clock management, for instance initializing the DDR PLL or * stepping the coreclk frequency, is performed through software reads and * writes to the memory-mapped PRCI control registers. * The CPU real time clock (rtcclk) runs at 1 MHz and is driven from input pin * RTCCLKIN. This should be connected to an external oscillator. * JTAG debug logic runs off of JTAG TCK as described in Chapter 26. * * Reset * The FU740-C000 has two external reset pins. * PORESET_N is an asynchonous active low power-on reset that should be * connected to an external power sequencing/supervisory circuit. ERESET_N is * an asynchonous active low reset that can be connected to a reset button. * There is internal debounce and stretch logic. The PRCI also contains hardware * to generate internal synchronous resets for coreclk, tlclk, and hfpclk * domains and handle reset to and from the debug module. Resets for the DDR, * Eth- ernet and PCIE Subsystems are performed through software reads and * writes to memory-mapped PRCI control registers. These registers are outlined * in Table 34 below. */ /* Table 21: PRCI Memory Map * Offset Name Description * 0x00 hfxosccfg Crystal Oscillator Configuration and Status * 0x04 core_pllcfg PLL Configuration and Status * 0x08 core_plloutdiv PLL Final Divide Configuration * 0x0C ddr_pllcfg PLL Configuration and Status * 0x10 ddr_plloutdiv PLL Final Divide Configuration * 0x1C gemgxl_pllcfg PLL Configuration and Status * 0x20 gemgxl_plloutdiv PLL Final Divide Configuration * 0x24 core_clk_sel_reg Select core clock source. 0: coreclkpll 1: external hfclk * 0x28 devices_reset_n Software controlled resets (active low) * 0x2C clk_mux_status Current selection of each clock mux * 0x38 dvfs_core_pllcfg PLL Configuration and Status * 0x3C dvfs_core_plloutdiv PLL Final Divide Configuration * 0x40 corepllsel Select which PLL output to use for core clock. 0: corepll 1: dvfscorepll * 0x50 hfpclk_pllcfg PLL Configuration and Status * 0x54 hfpclk_plloutdiv PLL Final Divide Configuration * 0x58 hfpclkpllsel Select source for Periphery Clock (pclk). 0: hfpclkpll 1: external hfclk * 0x5C hfpclk_div_reg HFPCLK PLL divider value * 0xE0 prci_plls Indicates presence of each PLL */ #define HFCLK_FREQ_HZ 26000000L #define PRCI_MEMORY_BLOCK 0x10000000L struct S_PACKED prci_pllcfg { uint32_t pllr:6; // [RW, 0x1] PLL R Value uint32_t pllf:9; // [RW, 0x1F] PLL F Value uint32_t pllq:3; // [RW, 0x3] PLL Q Value uint32_t pllrange:3; // [RW, 0x0] PLL Range Value uint32_t reserved0:3; uint32_t pllbypass:1; // [RW, 0x1] PLL Bypass uint32_t pllfsebypass:1; // [RW, 0x1] PLL FSE Bypass uint32_t reserved1:5; uint32_t plllock:1; // [RO, X] PLL Lock }; struct S_PACKED prci_plloutdiv { uint32_t reserved:31; uint32_t pllcke:1; // [RW, 0x0] PLL Clock Enable }; struct S_PACKED prci_mem_map { // Offset 0x0 struct prci_hfxosccfg { uint32_t reserved:30; uint32_t hfxoscen:1; // [RW, 0x1] Crystal Oscillator Enable uint32_t hfxoscrdy:1; // [RO, X] Crystal Oscillator Ready } hfxosccfg; // Offset 0x4 struct prci_pllcfg core_pllcfg; // Offset 0x8 struct { uint32_t reserved; } core_plloutdiv; // Offset 0xC struct prci_pllcfg ddr_pllcfg; // Offset 0x10 struct prci_plloutdiv ddr_plloutdiv; uint8_t off0[8]; // Offset 0x1C struct prci_pllcfg gemgxl_pllcfg; // Offset 0x20 struct prci_plloutdiv gemgxl_plloutdiv; // Offset 0x24 uint32_t core_clk_sel_reg; // Offset 0x28 struct prci_devices_reset_n { uint32_t ddrctrl_reset_n:1; // [RW, 0x0] Active-Low ddrctrl reset uint32_t ddraxi_reset_n:1; // [RW, 0x0] Active-Low ddraxi reset uint32_t ddrahb_reset_n:1; // [RW, 0x0] Active-Low ddrahb reset uint32_t ddrphy_reset_n:1; // [RW, 0x0] Active-Low ddrphy reset uint32_t pcieaux_reset_n:1; // [RW, 0x0] Active-Low pcieaux reset uint32_t gemgxl_reset_n:1; // [RW, 0x0] Active-Low gemgxl reset uint32_t reserved:26; } devices_reset_n; // Offset 0x2C struct prci_clk_mux_status { uint32_t coreclkpllsel:1; // [RO, X] Current setting of coreclkpllsel mux uint32_t tlclksel:1; // [RO, X] Current setting of tlclksel mux uint32_t rtcxsel:1; // [RO, X] Current setting of rtcxsel mux uint32_t ddrctrlclksel:1; // [RO, X] Current setting of ddrctrlclksel mux uint32_t ddrphyclksel:1; // [RO, X] Current setting of ddrphyclksel mux uint32_t reserved0:1; // [RO, X] Current setting of reserved0 mux uint32_t gemgxlclksel:1; // [RO, X] Current setting of gemgxlclksel mux uint32_t mainmemclksel:1; // [RO, X] Current setting of mainmemclksel mux uint32_t reserved:24; } clk_mux_status; uint8_t off1[8]; // Offset 0x38 struct prci_pllcfg dvfs_core_pllcfg; // Offset 0x3C struct prci_plloutdiv dvfs_core_plloutdiv; // Offset 0x40 uint32_t corepllsel; uint8_t off2[12]; // Offset 0x50 struct prci_pllcfg hfpclk_pllcfg; // Offset 0x54 struct prci_plloutdiv hfpclk_plloutdiv; // Offset 0x58 uint32_t hfpclkpllsel; // Offset 0x5C uint32_t hfpclk_div_reg; // [RW, 0x0] HFPCLK PLL divider value uint8_t off3[128]; // Offset 0xE0 struct prci_prci_plls { uint32_t cltxpll:1; // [RO, X] Indicates presence of cltxpll uint32_t gemgxlpll:1; // [RO, X] Indicates presence of gemgxlpll uint32_t ddrpll:1; // [RO, X] Indicates presence of ddrpll uint32_t hfpclkpll:1; // [RO, X] Indicates presence of hfpclkpll uint32_t dvfscorepll:1; // [RO, X] Indicates presence of dvfscorepll uint32_t corepll:1; // [RO, X] Indicates presence of corepll uint32_t reserved:26; } prci_plls; }; static_assert((sizeof(struct prci_mem_map) == 0xE4), "prci_mem_map is not the right size"); #endif