RISC-V operating system
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
rovo/kernel/clock.h

190 lines
7.1 KiB

#ifndef _PLATFORM_CLOCK_H
#define _PLATFORM_CLOCK_H
#include <stdint.h>
#include <macro.h>
/* 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