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