1 /* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2017-2021, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #ifndef MOD_PIK_CLOCK_H 9 #define MOD_PIK_CLOCK_H 10 11 #include <fwk_element.h> 12 13 #include <stdbool.h> 14 #include <stdint.h> 15 16 /*! 17 * \addtogroup GroupModules Modules 18 * \{ 19 */ 20 21 /*! 22 * \defgroup GroupPIKClock PIK Clock Driver 23 * 24 * \details A driver for clock devices that are part of a PIK. 25 * 26 * \{ 27 */ 28 29 /*! 30 * \brief APIs provided by the driver. 31 */ 32 enum mod_pik_clock_api_type { 33 /*! An implementation of the Clock HAL module's clock driver API */ 34 MOD_PIK_CLOCK_API_TYPE_CLOCK, 35 /*! A low-level API for direct control of CSS clocks */ 36 MOD_PIK_CLOCK_API_TYPE_CSS, 37 MOD_PIK_CLOCK_API_COUNT, 38 }; 39 40 /*! 41 * \brief Sub-types of PIK clock. 42 */ 43 enum mod_pik_clock_type { 44 /*! A clock with a fixed source. Only its divider can be changed. */ 45 MOD_PIK_CLOCK_TYPE_SINGLE_SOURCE, 46 /*! A clock with multiple, selectable sources and at least one divider. */ 47 MOD_PIK_CLOCK_TYPE_MULTI_SOURCE, 48 /*! 49 * A clock with multiple, selectable sources, at least one divider, and 50 * support for modulation. 51 */ 52 MOD_PIK_CLOCK_TYPE_CLUSTER, 53 }; 54 55 /*! 56 * \brief Divider register types. 57 */ 58 enum mod_pik_clock_msclock_divider { 59 /*! Divider affecting the system PLL clock source. */ 60 MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_SYS, 61 /*! Divider affecting the private or external PLL clock sources. */ 62 MOD_PIK_CLOCK_MSCLOCK_DIVIDER_DIV_EXT, 63 }; 64 65 /*! 66 * \brief Selectable clock sources for multi-source clocks. 67 */ 68 enum mod_pik_clock_msclock_source { 69 /*! The clock is gated */ 70 MOD_PIK_CLOCK_MSCLOCK_SOURCE_GATED = 0, 71 /*! The clock source is set to the system reference clock */ 72 MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSREFCLK = 1, 73 /*! The clock source is set to the system PLL clock */ 74 MOD_PIK_CLOCK_MSCLOCK_SOURCE_SYSPLLCLK = 2, 75 /*! The clock source is set to a private PLL */ 76 MOD_PIK_CLOCK_MSCLOCK_SOURCE_PRIVPLLCLK = 4, 77 /*! Number of valid clock sources */ 78 MOD_PIK_CLOCK_MSCLOCK_SOURCE_MAX 79 }; 80 81 /*! 82 * \brief Selectable clock sources for V8.2 cluster clocks. 83 */ 84 enum mod_clusclock_source { 85 /*! The clock is gated */ 86 MOD_PIK_CLOCK_CLUSCLK_SOURCE_GATED = 0, 87 /*! The clock source is set to the system reference clock */ 88 MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSREFCLK = 1, 89 /*! The clock source is set to a private cluster PLL */ 90 MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL0 = 2, 91 /*! The clock source is set to a private cluster PLL */ 92 MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL1 = 3, 93 /*! The clock source is set to a private cluster PLL */ 94 MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL2 = 4, 95 /*! The clock source is set to a private cluster PLL */ 96 MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL3 = 5, 97 /*! The clock source is set to a private cluster PLL */ 98 MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL4 = 6, 99 /*! The clock source is set to a private cluster PLL */ 100 MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL5 = 7, 101 /*! The clock source is set to a private cluster PLL */ 102 MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL6 = 8, 103 /*! The clock source is set to a private cluster PLL */ 104 MOD_PIK_CLOCK_CLUSCLK_SOURCE_PLL7 = 9, 105 /*! The clock source is set to the system PLL clock */ 106 MOD_PIK_CLOCK_CLUSCLK_SOURCE_SYSPLLCLK = 10, 107 /*! Number of valid clock sources */ 108 MOD_PIK_CLOCK_CLUSCLK_SOURCE_MAX 109 }; 110 111 /*! 112 * \brief Selectable clock sources for GPU clocks. 113 */ 114 enum mod_pik_clock_gpuclock_source { 115 /*! The clock is gated */ 116 MOD_PIK_CLOCK_GPUCLK_SOURCE_GATED = 0, 117 /*! The clock source is set to the system reference clock */ 118 MOD_PIK_CLOCK_GPUCLK_SOURCE_SYSREFCLK = 1, 119 /*! The clock source is set to the system PLL clock */ 120 MOD_PIK_CLOCK_GPUCLK_SOURCE_SYSPLLCLK = 2, 121 /*! The clock source is set to the dedicated GPU PLL */ 122 MOD_PIK_CLOCK_GPUCLK_SOURCE_GPUPLLCLK = 4, 123 /*! Number of valid clock sources */ 124 MOD_PIK_CLOCK_GPUCLK_SOURCE_MAX 125 }; 126 127 /*! 128 * \brief Selectable clock sources for DPU scaler clocks. 129 */ 130 enum mod_pik_clock_dpuclock_source { 131 /*! The clock is gated */ 132 MOD_PIK_CLOCK_DPUCLK_SOURCE_GATED = 0, 133 /*! The clock source is set to the system reference clock */ 134 MOD_PIK_CLOCK_DPUCLK_SOURCE_SYSREFCLK = 1, 135 /*! The clock source is set to the dedicated display PLL */ 136 MOD_PIK_CLOCK_DPUCLK_SOURCE_DISPLAYPLLCLK = 2, 137 /*! The clock source is set to a pixel clock PLL */ 138 MOD_PIK_CLOCK_DPUCLK_SOURCE_PIXELCLK = 4, 139 /*! Number of valid clock sources */ 140 MOD_PIK_CLOCK_DPUCLK_SOURCE_MAX 141 }; 142 143 /*! 144 * \brief Selectable clock sources for the DPU AXI clock. 145 */ 146 enum mod_pik_clock_aclkdpu_source { 147 /*! The clock is gated */ 148 MOD_PIK_CLOCK_ACLKDPU_SOURCE_GATED = 0, 149 /*! The clock source is set to the system reference clock */ 150 MOD_PIK_CLOCK_ACLKDPU_SOURCE_SYSREFCLK = 1, 151 /*! The clock source is set to the dedicated display PLL */ 152 MOD_PIK_CLOCK_ACLKDPU_SOURCE_DISPLAYPLLCLK = 2, 153 /*! The clock source is set to the system PLL clock */ 154 MOD_PIK_CLOCK_ACLKDPU_SOURCE_SYSPLLCLK = 4, 155 /*! Number of valid clock sources */ 156 MOD_PIK_CLOCK_ACLKDPU_SOURCE_MAX 157 }; 158 159 /*! 160 * \brief Selectable clock sources for the video processor clock. 161 */ 162 enum mod_pik_clock_vpuclk_source { 163 /*! The clock is gated */ 164 MOD_PIK_CLOCK_VPUCLK_SOURCE_GATED = 0, 165 /*! The clock source is set to the system reference clock */ 166 MOD_PIK_CLOCK_VPUCLK_SOURCE_SYSREFCLK = 1, 167 /*! The clock source is set to the system PLL clock */ 168 MOD_PIK_CLOCK_VPUCLK_SOURCE_SYSPLLCLK = 2, 169 /*! The clock source is set to the dedicated video PLL */ 170 MOD_PIK_CLOCK_VPUCLK_SOURCE_VIDEOPLLCLK = 4, 171 /*! Number of valid clock sources */ 172 MOD_PIK_CLOCK_VPUCLK_SOURCE_MAX 173 }; 174 175 /*! 176 * \brief Selectable clock sources for interconnect clock. 177 */ 178 enum mod_pik_clock_intclk_source { 179 /*! The clock is gated */ 180 MOD_PIK_CLOCK_INTCLK_SOURCE_GATED = 0, 181 /*! The clock source is set to the system reference clock */ 182 MOD_PIK_CLOCK_INTCLK_SOURCE_SYSREFCLK = 1, 183 /*! The clock source is set to a private PLL */ 184 MOD_PIK_CLOCK_INTCLK_SOURCE_INTPLL = 2, 185 }; 186 187 /*! 188 * \brief Selectable clock sources for DMC clock. 189 */ 190 enum mod_pik_clock_dmcclk_source { 191 /*! The clock is gated */ 192 MOD_PIK_CLOCK_DMCCLK_SOURCE_GATED = 0, 193 /*! The clock source is set to the system reference clock */ 194 MOD_PIK_CLOCK_DMCCLK_SOURCE_REFCLK = 1, 195 /*! The clock source is set to a private PLL */ 196 MOD_PIK_CLOCK_DMCCLK_SOURCE_DDRPLL = 2, 197 }; 198 199 /*! 200 * \brief Divider bitfield width. 201 */ 202 enum mod_pik_clock_divider_bitfield_width { 203 /*! PIK clock with 4-bit divider. */ 204 MOD_PIK_CLOCK_DIVIDER_BITFIELD_WIDTH_4BITS = 4, 205 /*! PIK clock with 5-bit divider. */ 206 MOD_PIK_CLOCK_DIVIDER_BITFIELD_WIDTH_5BITS = 5, 207 }; 208 209 /*! 210 * \brief PIK clock module configuration. 211 */ 212 struct mod_pik_clock_module_config { 213 /*! The maximum divider value. */ 214 unsigned int divider_max; 215 }; 216 217 218 /*! 219 * \brief Rate lookup entry. 220 */ 221 struct mod_pik_clock_rate { 222 /*! Rate in Hertz. */ 223 uint64_t rate; 224 /*! Clock source used to obtain the rate (multi-source clocks only). */ 225 uint8_t source; 226 /*! The divider register to use (multi-source clocks only). */ 227 enum mod_pik_clock_msclock_divider divider_reg; 228 /*! Divider used to obtain the rate. */ 229 uint8_t divider; 230 }; 231 232 /*! 233 * \brief Subsystem clock device configuration. 234 */ 235 struct mod_pik_clock_dev_config { 236 /*! The type of the clock device. */ 237 enum mod_pik_clock_type type; 238 239 /*! 240 * \brief Indicates whether the clock is part of a CSS clock group (\c true) 241 * or operating as an independent clock (\c false). 242 * 243 * \details The value determines the API that the clock exposes during 244 * binding. If the clock is part of a group then the 245 * ::MOD_PIK_CLOCK_API_TYPE_CSS API is exposed for direct control via 246 * the CSS Clock module, otherwise the ::MOD_PIK_CLOCK_API_TYPE_CLOCK 247 * API, defined by the Clock HAL, is exposed. 248 */ 249 bool is_group_member; 250 251 /*! Pointer to the clock's control register. */ 252 volatile uint32_t * const control_reg; 253 254 /*! Pointer to the clock's modulator register, if any. */ 255 volatile uint32_t * const modulator_reg; 256 257 /*! Pointer to the clock's DIV_SYS divider register, if any. */ 258 volatile uint32_t * const divsys_reg; 259 260 /*! Pointer to the clock's DIV_EXT divider register, if any. */ 261 volatile uint32_t * const divext_reg; 262 263 /*! Pointer to the clock's rate lookup table. */ 264 const struct mod_pik_clock_rate *rate_table; 265 266 /*! The number of rates in the rate lookup table. */ 267 uint32_t rate_count; 268 269 /*! The rate, in Hz, to set during module initialization. */ 270 uint64_t initial_rate; 271 272 /*! 273 * If \c true, the driver will not attempt to set a default frequency, or to 274 * otherwise configure the PLL during the pre-runtime phase. The PLL is 275 * expected to be initialized later in response to a notification or other 276 * event. 277 */ 278 const bool defer_initialization; 279 }; 280 281 /*! 282 * \} 283 */ 284 285 /*! 286 * \} 287 */ 288 289 #endif /* MOD_PIK_CLOCK_H */ 290