1 /* 2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /* 8 * ZynqMP system level PM-API functions for clock control. 9 */ 10 11 #include <arch_helpers.h> 12 #include <mmio.h> 13 #include <platform.h> 14 #include <string.h> 15 #include "pm_api_clock.h" 16 #include "pm_api_sys.h" 17 #include "pm_client.h" 18 #include "pm_common.h" 19 #include "pm_ipi.h" 20 21 #define CLK_NODE_MAX 6 22 23 /** 24 * struct pm_clock_node - Clock topology node information 25 * @type: Topology type (mux/div1/div2/gate/pll/fixed factor) 26 * @offset: Offset in control register 27 * @width: Width of the specific type in control register 28 * @clkflags: Clk specific flags 29 * @typeflags: Type specific flags 30 * @mult: Multiplier for fixed factor 31 * @div: Divisor for fixed factor 32 */ 33 struct pm_clock_node { 34 uint16_t clkflags; 35 uint16_t typeflags; 36 uint8_t type; 37 uint8_t offset; 38 uint8_t width; 39 uint8_t mult:4; 40 uint8_t div:4; 41 }; 42 43 /** 44 * struct pm_clock - Clock structure 45 * @name: Clock name 46 * @control_reg: Control register address 47 * @status_reg: Status register address 48 * @parents: Parents for first clock node. Lower byte indicates parent 49 * clock id and upper byte indicate flags for that id. 50 * pm_clock_node: Clock nodes 51 */ 52 struct pm_clock { 53 char name[CLK_NAME_LEN]; 54 uint8_t num_nodes; 55 unsigned int control_reg; 56 unsigned int status_reg; 57 int32_t (*parents)[]; 58 struct pm_clock_node(*nodes)[]; 59 }; 60 61 /* Clock array containing clock informaton */ 62 struct pm_clock clocks[] = {0}; 63 64 /** 65 * pm_api_clock_get_name() - PM call to request a clock's name 66 * @clock_id Clock ID 67 * @name Name of clock (max 16 bytes) 68 * 69 * This function is used by master to get nmae of clock specified 70 * by given clock ID. 71 * 72 * @return Returns success. In case of error, name data is 0. 73 */ 74 enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name) 75 { 76 return PM_RET_ERROR_NOTSUPPORTED; 77 } 78 79 /** 80 * pm_api_clock_get_topology() - PM call to request a clock's topology 81 * @clock_id Clock ID 82 * @index Topology index for next toplogy node 83 * @topology Buffer to store nodes in topology and flags 84 * 85 * This function is used by master to get topology information for the 86 * clock specified by given clock ID. Each response would return 3 87 * topology nodes. To get next nodes, caller needs to call this API with 88 * index of next node. Index starts from 0. 89 * 90 * @return Returns status, either success or error+reason 91 */ 92 enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id, 93 unsigned int index, 94 uint32_t *topology) 95 { 96 return PM_RET_ERROR_NOTSUPPORTED; 97 } 98 99 /** 100 * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed 101 * factor parameters for fixed clock 102 * @clock_id Clock ID 103 * @mul Multiplication value 104 * @div Divisor value 105 * 106 * This function is used by master to get fixed factor parameers for the 107 * fixed clock. This API is application only for the fixed clock. 108 * 109 * @return Returns status, either success or error+reason 110 */ 111 enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id, 112 uint32_t *mul, 113 uint32_t *div) 114 { 115 return PM_RET_ERROR_NOTSUPPORTED; 116 } 117 118 /** 119 * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents 120 * @clock_id Clock ID 121 * @index Index of next parent 122 * @parents Parents of the given clock 123 * 124 * This function is used by master to get clock's parents information. 125 * This API will return 3 parents with a single response. To get other 126 * parents, master should call same API in loop with new parent index 127 * till error is returned. 128 * 129 * E.g First call should have index 0 which will return parents 0, 1 and 130 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and 131 * so on. 132 * 133 * @return Returns status, either success or error+reason 134 */ 135 enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id, 136 unsigned int index, 137 uint32_t *parents) 138 { 139 return PM_RET_ERROR_NOTSUPPORTED; 140 } 141 142 /** 143 * pm_api_clock_get_attributes() - PM call to request a clock's attributes 144 * @clock_id Clock ID 145 * @attr Clock attributes 146 * 147 * This function is used by master to get clock's attributes 148 * (e.g. valid, clock type, etc). 149 * 150 * @return Returns status, either success or error+reason 151 */ 152 enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id, 153 uint32_t *attr) 154 { 155 return PM_RET_ERROR_NOTSUPPORTED; 156 } 157 158 /** 159 * pm_api_clock_enable() - Enable the clock for given id 160 * @clock_id: Id of the clock to be enabled 161 * 162 * This function is used by master to enable the clock 163 * including peripherals and PLL clocks. 164 * 165 * Return: Returns status, either success or error+reason. 166 */ 167 enum pm_ret_status pm_api_clock_enable(unsigned int clock_id) 168 { 169 return PM_RET_ERROR_NOTSUPPORTED; 170 } 171 172 /** 173 * pm_api_clock_disable - Disable the clock for given id 174 * @clock_id Id of the clock to be disable 175 * 176 * This function is used by master to disable the clock 177 * including peripherals and PLL clocks. 178 * 179 * Return: Returns status, either success or error+reason. 180 */ 181 182 enum pm_ret_status pm_api_clock_disable(unsigned int clock_id) 183 { 184 return PM_RET_ERROR_NOTSUPPORTED; 185 } 186 187 /** 188 * pm_api_clock_getstate - Get the clock state for given id 189 * @clock_id Id of the clock to be queried 190 * @state 1/0 (Enabled/Disabled) 191 * 192 * This function is used by master to get the state of clock 193 * including peripherals and PLL clocks. 194 * 195 * Return: Returns status, either success or error+reason. 196 */ 197 enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id, 198 unsigned int *state) 199 { 200 return PM_RET_ERROR_NOTSUPPORTED; 201 } 202 203 /** 204 * pm_api_clock_setdivider - Set the clock divider for given id 205 * @clock_id Id of the clock 206 * @divider Divider value 207 * 208 * This function is used by master to set divider for any clock 209 * to achieve desired rate. 210 * 211 * Return: Returns status, either success or error+reason. 212 */ 213 enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id, 214 unsigned int divider) 215 { 216 return PM_RET_ERROR_NOTSUPPORTED; 217 } 218 219 /** 220 * pm_api_clock_getdivider - Get the clock divider for given id 221 * @clock_id Id of the clock 222 * @divider Divider value 223 * 224 * This function is used by master to get divider values 225 * for any clock. 226 * 227 * Return: Returns status, either success or error+reason. 228 */ 229 enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id, 230 unsigned int *divider) 231 { 232 return PM_RET_ERROR_NOTSUPPORTED; 233 } 234 235 /** 236 * pm_api_clock_setrate - Set the clock rate for given id 237 * @clock_id Id of the clock 238 * @rate Rate value in hz 239 * 240 * This function is used by master to set rate for any clock. 241 * 242 * Return: Returns status, either success or error+reason. 243 */ 244 enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id, 245 uint64_t rate) 246 { 247 return PM_RET_ERROR_NOTSUPPORTED; 248 } 249 250 /** 251 * pm_api_clock_getrate - Get the clock rate for given id 252 * @clock_id Id of the clock 253 * @rate rate value in hz 254 * 255 * This function is used by master to get rate 256 * for any clock. 257 * 258 * Return: Returns status, either success or error+reason. 259 */ 260 enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id, 261 uint64_t *rate) 262 { 263 return PM_RET_ERROR_NOTSUPPORTED; 264 } 265 266 /** 267 * pm_api_clock_setparent - Set the clock parent for given id 268 * @clock_id Id of the clock 269 * @parent_id parent id 270 * 271 * This function is used by master to set parent for any clock. 272 * 273 * Return: Returns status, either success or error+reason. 274 */ 275 enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id, 276 unsigned int parent_idx) 277 { 278 return PM_RET_ERROR_NOTSUPPORTED; 279 } 280 281 /** 282 * pm_api_clock_getparent - Get the clock parent for given id 283 * @clock_id Id of the clock 284 * @parent_id parent id 285 * 286 * This function is used by master to get parent index 287 * for any clock. 288 * 289 * Return: Returns status, either success or error+reason. 290 */ 291 enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id, 292 unsigned int *parent_idx) 293 { 294 return PM_RET_ERROR_NOTSUPPORTED; 295 } 296 297 /** 298 * pm_api_clk_set_pll_mode() - Set PLL mode 299 * @pll PLL id 300 * @mode Mode fraction/integar 301 * 302 * This function sets PLL mode. 303 * 304 * @return Returns status, either success or error+reason 305 */ 306 enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll, 307 unsigned int mode) 308 { 309 return PM_RET_ERROR_NOTSUPPORTED; 310 } 311 312 /** 313 * pm_ioctl_get_pll_mode() - Get PLL mode 314 * @pll PLL id 315 * @mode Mode fraction/integar 316 * 317 * This function returns current PLL mode. 318 * 319 * @return Returns status, either success or error+reason 320 */ 321 enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll, 322 unsigned int *mode) 323 { 324 return PM_RET_ERROR_NOTSUPPORTED; 325 } 326 327 /** 328 * pm_api_clk_set_pll_frac_data() - Set PLL fraction data 329 * @pll PLL id 330 * @data fraction data 331 * 332 * This function sets fraction data. It is valid for fraction 333 * mode only. 334 * 335 * @return Returns status, either success or error+reason 336 */ 337 enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll, 338 unsigned int data) 339 { 340 return PM_RET_ERROR_NOTSUPPORTED; 341 } 342 343 /** 344 * pm_api_clk_get_pll_frac_data() - Get PLL fraction data 345 * @pll PLL id 346 * @data fraction data 347 * 348 * This function returns fraction data value. 349 * 350 * @return Returns status, either success or error+reason 351 */ 352 enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll, 353 unsigned int *data) 354 { 355 return PM_RET_ERROR_NOTSUPPORTED; 356 } 357