1e331f79eSHavard Skinnemoen /* 2e331f79eSHavard Skinnemoen * Nuvoton NPCM7xx Clock Control Registers. 3e331f79eSHavard Skinnemoen * 4e331f79eSHavard Skinnemoen * Copyright 2020 Google LLC 5e331f79eSHavard Skinnemoen * 6e331f79eSHavard Skinnemoen * This program is free software; you can redistribute it and/or modify it 7e331f79eSHavard Skinnemoen * under the terms of the GNU General Public License as published by the 8e331f79eSHavard Skinnemoen * Free Software Foundation; either version 2 of the License, or 9e331f79eSHavard Skinnemoen * (at your option) any later version. 10e331f79eSHavard Skinnemoen * 11e331f79eSHavard Skinnemoen * This program is distributed in the hope that it will be useful, but WITHOUT 12e331f79eSHavard Skinnemoen * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13e331f79eSHavard Skinnemoen * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14e331f79eSHavard Skinnemoen * for more details. 15e331f79eSHavard Skinnemoen */ 16e331f79eSHavard Skinnemoen #ifndef NPCM7XX_CLK_H 17e331f79eSHavard Skinnemoen #define NPCM7XX_CLK_H 18e331f79eSHavard Skinnemoen 19e331f79eSHavard Skinnemoen #include "exec/memory.h" 20bcda710fSHao Wu #include "hw/clock.h" 21e331f79eSHavard Skinnemoen #include "hw/sysbus.h" 22e331f79eSHavard Skinnemoen 23e331f79eSHavard Skinnemoen /* 24e331f79eSHavard Skinnemoen * The reference clock frequency for the timer modules, and the SECCNT and 25e331f79eSHavard Skinnemoen * CNTR25M registers in this module, is always 25 MHz. 26e331f79eSHavard Skinnemoen */ 27e331f79eSHavard Skinnemoen #define NPCM7XX_TIMER_REF_HZ (25000000) 28e331f79eSHavard Skinnemoen 29e331f79eSHavard Skinnemoen /* 30e331f79eSHavard Skinnemoen * Number of registers in our device state structure. Don't change this without 31e331f79eSHavard Skinnemoen * incrementing the version_id in the vmstate. 32e331f79eSHavard Skinnemoen */ 33e331f79eSHavard Skinnemoen #define NPCM7XX_CLK_NR_REGS (0x70 / sizeof(uint32_t)) 34e331f79eSHavard Skinnemoen 357d378ed6SHao Wu #define NPCM7XX_WATCHDOG_RESET_GPIO_IN "npcm7xx-clk-watchdog-reset-gpio-in" 367d378ed6SHao Wu 37bcda710fSHao Wu /* Maximum amount of clock inputs in a SEL module. */ 38bcda710fSHao Wu #define NPCM7XX_CLK_SEL_MAX_INPUT 5 39bcda710fSHao Wu 40bcda710fSHao Wu /* PLLs in CLK module. */ 41bcda710fSHao Wu typedef enum NPCM7xxClockPLL { 42bcda710fSHao Wu NPCM7XX_CLOCK_PLL0, 43bcda710fSHao Wu NPCM7XX_CLOCK_PLL1, 44bcda710fSHao Wu NPCM7XX_CLOCK_PLL2, 45bcda710fSHao Wu NPCM7XX_CLOCK_PLLG, 46bcda710fSHao Wu NPCM7XX_CLOCK_NR_PLLS, 47bcda710fSHao Wu } NPCM7xxClockPLL; 48bcda710fSHao Wu 49bcda710fSHao Wu /* SEL/MUX in CLK module. */ 50bcda710fSHao Wu typedef enum NPCM7xxClockSEL { 51bcda710fSHao Wu NPCM7XX_CLOCK_PIXCKSEL, 52bcda710fSHao Wu NPCM7XX_CLOCK_MCCKSEL, 53bcda710fSHao Wu NPCM7XX_CLOCK_CPUCKSEL, 54bcda710fSHao Wu NPCM7XX_CLOCK_CLKOUTSEL, 55bcda710fSHao Wu NPCM7XX_CLOCK_UARTCKSEL, 56bcda710fSHao Wu NPCM7XX_CLOCK_TIMCKSEL, 57bcda710fSHao Wu NPCM7XX_CLOCK_SDCKSEL, 58bcda710fSHao Wu NPCM7XX_CLOCK_GFXMSEL, 59bcda710fSHao Wu NPCM7XX_CLOCK_SUCKSEL, 60bcda710fSHao Wu NPCM7XX_CLOCK_NR_SELS, 61bcda710fSHao Wu } NPCM7xxClockSEL; 62bcda710fSHao Wu 63bcda710fSHao Wu /* Dividers in CLK module. */ 64bcda710fSHao Wu typedef enum NPCM7xxClockDivider { 65bcda710fSHao Wu NPCM7XX_CLOCK_PLL1D2, /* PLL1/2 */ 66bcda710fSHao Wu NPCM7XX_CLOCK_PLL2D2, /* PLL2/2 */ 67bcda710fSHao Wu NPCM7XX_CLOCK_MC_DIVIDER, 68bcda710fSHao Wu NPCM7XX_CLOCK_AXI_DIVIDER, 69bcda710fSHao Wu NPCM7XX_CLOCK_AHB_DIVIDER, 70bcda710fSHao Wu NPCM7XX_CLOCK_AHB3_DIVIDER, 71bcda710fSHao Wu NPCM7XX_CLOCK_SPI0_DIVIDER, 72bcda710fSHao Wu NPCM7XX_CLOCK_SPIX_DIVIDER, 73bcda710fSHao Wu NPCM7XX_CLOCK_APB1_DIVIDER, 74bcda710fSHao Wu NPCM7XX_CLOCK_APB2_DIVIDER, 75bcda710fSHao Wu NPCM7XX_CLOCK_APB3_DIVIDER, 76bcda710fSHao Wu NPCM7XX_CLOCK_APB4_DIVIDER, 77bcda710fSHao Wu NPCM7XX_CLOCK_APB5_DIVIDER, 78bcda710fSHao Wu NPCM7XX_CLOCK_CLKOUT_DIVIDER, 79bcda710fSHao Wu NPCM7XX_CLOCK_UART_DIVIDER, 80bcda710fSHao Wu NPCM7XX_CLOCK_TIMER_DIVIDER, 81bcda710fSHao Wu NPCM7XX_CLOCK_ADC_DIVIDER, 82bcda710fSHao Wu NPCM7XX_CLOCK_MMC_DIVIDER, 83bcda710fSHao Wu NPCM7XX_CLOCK_SDHC_DIVIDER, 84bcda710fSHao Wu NPCM7XX_CLOCK_GFXM_DIVIDER, /* divide by 3 */ 85bcda710fSHao Wu NPCM7XX_CLOCK_UTMI_DIVIDER, 86bcda710fSHao Wu NPCM7XX_CLOCK_NR_DIVIDERS, 87bcda710fSHao Wu } NPCM7xxClockConverter; 88bcda710fSHao Wu 89bcda710fSHao Wu typedef struct NPCM7xxCLKState NPCM7xxCLKState; 90bcda710fSHao Wu 91bcda710fSHao Wu /** 92bcda710fSHao Wu * struct NPCM7xxClockPLLState - A PLL module in CLK module. 93bcda710fSHao Wu * @name: The name of the module. 94bcda710fSHao Wu * @clk: The CLK module that owns this module. 95bcda710fSHao Wu * @clock_in: The input clock of this module. 96bcda710fSHao Wu * @clock_out: The output clock of this module. 97bcda710fSHao Wu * @reg: The control registers for this PLL module. 98bcda710fSHao Wu */ 99bcda710fSHao Wu typedef struct NPCM7xxClockPLLState { 100bcda710fSHao Wu DeviceState parent; 101bcda710fSHao Wu 102bcda710fSHao Wu const char *name; 103bcda710fSHao Wu NPCM7xxCLKState *clk; 104bcda710fSHao Wu Clock *clock_in; 105bcda710fSHao Wu Clock *clock_out; 106bcda710fSHao Wu 107bcda710fSHao Wu int reg; 108bcda710fSHao Wu } NPCM7xxClockPLLState; 109bcda710fSHao Wu 110bcda710fSHao Wu /** 111bcda710fSHao Wu * struct NPCM7xxClockSELState - A SEL module in CLK module. 112bcda710fSHao Wu * @name: The name of the module. 113bcda710fSHao Wu * @clk: The CLK module that owns this module. 114bcda710fSHao Wu * @input_size: The size of inputs of this module. 115bcda710fSHao Wu * @clock_in: The input clocks of this module. 116bcda710fSHao Wu * @clock_out: The output clocks of this module. 117bcda710fSHao Wu * @offset: The offset of this module in the control register. 118bcda710fSHao Wu * @len: The length of this module in the control register. 119bcda710fSHao Wu */ 120bcda710fSHao Wu typedef struct NPCM7xxClockSELState { 121bcda710fSHao Wu DeviceState parent; 122bcda710fSHao Wu 123bcda710fSHao Wu const char *name; 124bcda710fSHao Wu NPCM7xxCLKState *clk; 125bcda710fSHao Wu uint8_t input_size; 126bcda710fSHao Wu Clock *clock_in[NPCM7XX_CLK_SEL_MAX_INPUT]; 127bcda710fSHao Wu Clock *clock_out; 128bcda710fSHao Wu 129bcda710fSHao Wu int offset; 130bcda710fSHao Wu int len; 131bcda710fSHao Wu } NPCM7xxClockSELState; 132bcda710fSHao Wu 133bcda710fSHao Wu /** 134bcda710fSHao Wu * struct NPCM7xxClockDividerState - A Divider module in CLK module. 135bcda710fSHao Wu * @name: The name of the module. 136bcda710fSHao Wu * @clk: The CLK module that owns this module. 137bcda710fSHao Wu * @clock_in: The input clock of this module. 138bcda710fSHao Wu * @clock_out: The output clock of this module. 139bcda710fSHao Wu * @divide: The function the divider uses to divide the input. 140bcda710fSHao Wu * @reg: The index of the control register that contains the divisor. 141bcda710fSHao Wu * @offset: The offset of the divisor in the control register. 142bcda710fSHao Wu * @len: The length of the divisor in the control register. 143bcda710fSHao Wu * @divisor: The divisor for a constant divisor 144bcda710fSHao Wu */ 145bcda710fSHao Wu typedef struct NPCM7xxClockDividerState { 146bcda710fSHao Wu DeviceState parent; 147bcda710fSHao Wu 148bcda710fSHao Wu const char *name; 149bcda710fSHao Wu NPCM7xxCLKState *clk; 150bcda710fSHao Wu Clock *clock_in; 151bcda710fSHao Wu Clock *clock_out; 152bcda710fSHao Wu 153bcda710fSHao Wu uint32_t (*divide)(struct NPCM7xxClockDividerState *s); 154bcda710fSHao Wu union { 155bcda710fSHao Wu struct { 156bcda710fSHao Wu int reg; 157bcda710fSHao Wu int offset; 158bcda710fSHao Wu int len; 159bcda710fSHao Wu }; 160bcda710fSHao Wu int divisor; 161bcda710fSHao Wu }; 162bcda710fSHao Wu } NPCM7xxClockDividerState; 163bcda710fSHao Wu 164bcda710fSHao Wu struct NPCM7xxCLKState { 165e331f79eSHavard Skinnemoen SysBusDevice parent; 166e331f79eSHavard Skinnemoen 167e331f79eSHavard Skinnemoen MemoryRegion iomem; 168e331f79eSHavard Skinnemoen 169bcda710fSHao Wu /* Clock converters */ 170bcda710fSHao Wu NPCM7xxClockPLLState plls[NPCM7XX_CLOCK_NR_PLLS]; 171bcda710fSHao Wu NPCM7xxClockSELState sels[NPCM7XX_CLOCK_NR_SELS]; 172bcda710fSHao Wu NPCM7xxClockDividerState dividers[NPCM7XX_CLOCK_NR_DIVIDERS]; 173bcda710fSHao Wu 174e331f79eSHavard Skinnemoen uint32_t regs[NPCM7XX_CLK_NR_REGS]; 175e331f79eSHavard Skinnemoen 176e331f79eSHavard Skinnemoen /* Time reference for SECCNT and CNTR25M, initialized by power on reset */ 177e331f79eSHavard Skinnemoen int64_t ref_ns; 178bcda710fSHao Wu 179bcda710fSHao Wu /* The incoming reference clock. */ 180bcda710fSHao Wu Clock *clkref; 181bcda710fSHao Wu }; 182e331f79eSHavard Skinnemoen 183e331f79eSHavard Skinnemoen #define TYPE_NPCM7XX_CLK "npcm7xx-clk" 184e331f79eSHavard Skinnemoen #define NPCM7XX_CLK(obj) OBJECT_CHECK(NPCM7xxCLKState, (obj), TYPE_NPCM7XX_CLK) 185e331f79eSHavard Skinnemoen 186e331f79eSHavard Skinnemoen #endif /* NPCM7XX_CLK_H */ 187