1e331f79eSHavard Skinnemoen /* 2*4e67d50dSHao Wu * Nuvoton NPCM7xx/8xx 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 */ 16c8283b0fSHao Wu #ifndef NPCM_CLK_H 17c8283b0fSHao Wu #define NPCM_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 #define NPCM7XX_CLK_NR_REGS (0x70 / sizeof(uint32_t)) 24*4e67d50dSHao Wu #define NPCM8XX_CLK_NR_REGS (0xc4 / sizeof(uint32_t)) 25ca6d6a94SHao Wu /* 26ca6d6a94SHao Wu * Number of maximum registers in NPCM device state structure. Don't change 27ca6d6a94SHao Wu * this without incrementing the version_id in the vmstate. 28ca6d6a94SHao Wu */ 29*4e67d50dSHao Wu #define NPCM_CLK_MAX_NR_REGS NPCM8XX_CLK_NR_REGS 30e331f79eSHavard Skinnemoen 317d378ed6SHao Wu #define NPCM7XX_WATCHDOG_RESET_GPIO_IN "npcm7xx-clk-watchdog-reset-gpio-in" 327d378ed6SHao Wu 33bcda710fSHao Wu /* Maximum amount of clock inputs in a SEL module. */ 34bcda710fSHao Wu #define NPCM7XX_CLK_SEL_MAX_INPUT 5 35bcda710fSHao Wu 36bcda710fSHao Wu /* PLLs in CLK module. */ 37bcda710fSHao Wu typedef enum NPCM7xxClockPLL { 38bcda710fSHao Wu NPCM7XX_CLOCK_PLL0, 39bcda710fSHao Wu NPCM7XX_CLOCK_PLL1, 40bcda710fSHao Wu NPCM7XX_CLOCK_PLL2, 41bcda710fSHao Wu NPCM7XX_CLOCK_PLLG, 42bcda710fSHao Wu NPCM7XX_CLOCK_NR_PLLS, 43bcda710fSHao Wu } NPCM7xxClockPLL; 44bcda710fSHao Wu 45bcda710fSHao Wu /* SEL/MUX in CLK module. */ 46bcda710fSHao Wu typedef enum NPCM7xxClockSEL { 47bcda710fSHao Wu NPCM7XX_CLOCK_PIXCKSEL, 48bcda710fSHao Wu NPCM7XX_CLOCK_MCCKSEL, 49bcda710fSHao Wu NPCM7XX_CLOCK_CPUCKSEL, 50bcda710fSHao Wu NPCM7XX_CLOCK_CLKOUTSEL, 51bcda710fSHao Wu NPCM7XX_CLOCK_UARTCKSEL, 52bcda710fSHao Wu NPCM7XX_CLOCK_TIMCKSEL, 53bcda710fSHao Wu NPCM7XX_CLOCK_SDCKSEL, 54bcda710fSHao Wu NPCM7XX_CLOCK_GFXMSEL, 55bcda710fSHao Wu NPCM7XX_CLOCK_SUCKSEL, 56bcda710fSHao Wu NPCM7XX_CLOCK_NR_SELS, 57bcda710fSHao Wu } NPCM7xxClockSEL; 58bcda710fSHao Wu 59bcda710fSHao Wu /* Dividers in CLK module. */ 60bcda710fSHao Wu typedef enum NPCM7xxClockDivider { 61bcda710fSHao Wu NPCM7XX_CLOCK_PLL1D2, /* PLL1/2 */ 62bcda710fSHao Wu NPCM7XX_CLOCK_PLL2D2, /* PLL2/2 */ 63bcda710fSHao Wu NPCM7XX_CLOCK_MC_DIVIDER, 64bcda710fSHao Wu NPCM7XX_CLOCK_AXI_DIVIDER, 65bcda710fSHao Wu NPCM7XX_CLOCK_AHB_DIVIDER, 66bcda710fSHao Wu NPCM7XX_CLOCK_AHB3_DIVIDER, 67bcda710fSHao Wu NPCM7XX_CLOCK_SPI0_DIVIDER, 68bcda710fSHao Wu NPCM7XX_CLOCK_SPIX_DIVIDER, 69bcda710fSHao Wu NPCM7XX_CLOCK_APB1_DIVIDER, 70bcda710fSHao Wu NPCM7XX_CLOCK_APB2_DIVIDER, 71bcda710fSHao Wu NPCM7XX_CLOCK_APB3_DIVIDER, 72bcda710fSHao Wu NPCM7XX_CLOCK_APB4_DIVIDER, 73bcda710fSHao Wu NPCM7XX_CLOCK_APB5_DIVIDER, 74bcda710fSHao Wu NPCM7XX_CLOCK_CLKOUT_DIVIDER, 75bcda710fSHao Wu NPCM7XX_CLOCK_UART_DIVIDER, 76bcda710fSHao Wu NPCM7XX_CLOCK_TIMER_DIVIDER, 77bcda710fSHao Wu NPCM7XX_CLOCK_ADC_DIVIDER, 78bcda710fSHao Wu NPCM7XX_CLOCK_MMC_DIVIDER, 79bcda710fSHao Wu NPCM7XX_CLOCK_SDHC_DIVIDER, 80bcda710fSHao Wu NPCM7XX_CLOCK_GFXM_DIVIDER, /* divide by 3 */ 81bcda710fSHao Wu NPCM7XX_CLOCK_UTMI_DIVIDER, 82bcda710fSHao Wu NPCM7XX_CLOCK_NR_DIVIDERS, 83bcda710fSHao Wu } NPCM7xxClockConverter; 84bcda710fSHao Wu 85ca6d6a94SHao Wu typedef struct NPCMCLKState NPCMCLKState; 86bcda710fSHao Wu 87bcda710fSHao Wu /** 88bcda710fSHao Wu * struct NPCM7xxClockPLLState - A PLL module in CLK module. 89bcda710fSHao Wu * @name: The name of the module. 90bcda710fSHao Wu * @clk: The CLK module that owns this module. 91bcda710fSHao Wu * @clock_in: The input clock of this module. 92bcda710fSHao Wu * @clock_out: The output clock of this module. 93bcda710fSHao Wu * @reg: The control registers for this PLL module. 94bcda710fSHao Wu */ 95bcda710fSHao Wu typedef struct NPCM7xxClockPLLState { 96bcda710fSHao Wu DeviceState parent; 97bcda710fSHao Wu 98bcda710fSHao Wu const char *name; 99ca6d6a94SHao Wu NPCMCLKState *clk; 100bcda710fSHao Wu Clock *clock_in; 101bcda710fSHao Wu Clock *clock_out; 102bcda710fSHao Wu 103bcda710fSHao Wu int reg; 104bcda710fSHao Wu } NPCM7xxClockPLLState; 105bcda710fSHao Wu 106bcda710fSHao Wu /** 107bcda710fSHao Wu * struct NPCM7xxClockSELState - A SEL module in CLK module. 108bcda710fSHao Wu * @name: The name of the module. 109bcda710fSHao Wu * @clk: The CLK module that owns this module. 110bcda710fSHao Wu * @input_size: The size of inputs of this module. 111bcda710fSHao Wu * @clock_in: The input clocks of this module. 112bcda710fSHao Wu * @clock_out: The output clocks of this module. 113bcda710fSHao Wu * @offset: The offset of this module in the control register. 114bcda710fSHao Wu * @len: The length of this module in the control register. 115bcda710fSHao Wu */ 116bcda710fSHao Wu typedef struct NPCM7xxClockSELState { 117bcda710fSHao Wu DeviceState parent; 118bcda710fSHao Wu 119bcda710fSHao Wu const char *name; 120ca6d6a94SHao Wu NPCMCLKState *clk; 121bcda710fSHao Wu uint8_t input_size; 122bcda710fSHao Wu Clock *clock_in[NPCM7XX_CLK_SEL_MAX_INPUT]; 123bcda710fSHao Wu Clock *clock_out; 124bcda710fSHao Wu 125bcda710fSHao Wu int offset; 126bcda710fSHao Wu int len; 127bcda710fSHao Wu } NPCM7xxClockSELState; 128bcda710fSHao Wu 129bcda710fSHao Wu /** 130bcda710fSHao Wu * struct NPCM7xxClockDividerState - A Divider module in CLK module. 131bcda710fSHao Wu * @name: The name of the module. 132bcda710fSHao Wu * @clk: The CLK module that owns this module. 133bcda710fSHao Wu * @clock_in: The input clock of this module. 134bcda710fSHao Wu * @clock_out: The output clock of this module. 135bcda710fSHao Wu * @divide: The function the divider uses to divide the input. 136bcda710fSHao Wu * @reg: The index of the control register that contains the divisor. 137bcda710fSHao Wu * @offset: The offset of the divisor in the control register. 138bcda710fSHao Wu * @len: The length of the divisor in the control register. 139bcda710fSHao Wu * @divisor: The divisor for a constant divisor 140bcda710fSHao Wu */ 141bcda710fSHao Wu typedef struct NPCM7xxClockDividerState { 142bcda710fSHao Wu DeviceState parent; 143bcda710fSHao Wu 144bcda710fSHao Wu const char *name; 145ca6d6a94SHao Wu NPCMCLKState *clk; 146bcda710fSHao Wu Clock *clock_in; 147bcda710fSHao Wu Clock *clock_out; 148bcda710fSHao Wu 149bcda710fSHao Wu uint32_t (*divide)(struct NPCM7xxClockDividerState *s); 150bcda710fSHao Wu union { 151bcda710fSHao Wu struct { 152bcda710fSHao Wu int reg; 153bcda710fSHao Wu int offset; 154bcda710fSHao Wu int len; 155bcda710fSHao Wu }; 156bcda710fSHao Wu int divisor; 157bcda710fSHao Wu }; 158bcda710fSHao Wu } NPCM7xxClockDividerState; 159bcda710fSHao Wu 160ca6d6a94SHao Wu struct NPCMCLKState { 161e331f79eSHavard Skinnemoen SysBusDevice parent; 162e331f79eSHavard Skinnemoen 163e331f79eSHavard Skinnemoen MemoryRegion iomem; 164e331f79eSHavard Skinnemoen 165bcda710fSHao Wu /* Clock converters */ 166*4e67d50dSHao Wu /* 167*4e67d50dSHao Wu * TODO: Implement unique clock converters for NPCM8xx. 168*4e67d50dSHao Wu * NPCM8xx adds a few more clock outputs. 169*4e67d50dSHao Wu */ 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 174ca6d6a94SHao Wu uint32_t regs[NPCM_CLK_MAX_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 183cf76c4e1SHao Wu typedef struct NPCMCLKClass { 184cf76c4e1SHao Wu SysBusDeviceClass parent; 185cf76c4e1SHao Wu 186cf76c4e1SHao Wu size_t nr_regs; 187cf76c4e1SHao Wu const uint32_t *cold_reset_values; 188cf76c4e1SHao Wu } NPCMCLKClass; 189cf76c4e1SHao Wu 190ca6d6a94SHao Wu #define TYPE_NPCM_CLK "npcm-clk" 191cf76c4e1SHao Wu OBJECT_DECLARE_TYPE(NPCMCLKState, NPCMCLKClass, NPCM_CLK) 192e331f79eSHavard Skinnemoen #define TYPE_NPCM7XX_CLK "npcm7xx-clk" 193*4e67d50dSHao Wu #define TYPE_NPCM8XX_CLK "npcm8xx-clk" 194e331f79eSHavard Skinnemoen 195c8283b0fSHao Wu #endif /* NPCM_CLK_H */ 196