diff options
author | Rajan Vaja <rajanv@xilinx.com> | 2018-09-12 15:38:38 -0400 |
---|---|---|
committer | Michal Simek <michal.simek@xilinx.com> | 2018-09-26 02:47:34 -0400 |
commit | f9627312e20721681ea326bd2b7935bf8034b288 (patch) | |
tree | 02cebd0925084b4dd47e2ffa3746b8d229df7546 /drivers/firmware | |
parent | 59ecdd778879f171072b663f91de6c3a595e2ed4 (diff) |
firmware: xilinx: Add clock APIs
Add clock APIs to control clocks through firmware
interface.
Signed-off-by: Rajan Vaja <rajanv@xilinx.com>
Signed-off-by: Jolly Shah <jollys@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/xilinx/zynqmp.c | 186 |
1 files changed, 184 insertions, 2 deletions
diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index 2a333c04955b..697f4fa23a45 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c | |||
@@ -250,13 +250,195 @@ static int get_set_conduit_method(struct device_node *np) | |||
250 | */ | 250 | */ |
251 | static int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out) | 251 | static int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out) |
252 | { | 252 | { |
253 | return zynqmp_pm_invoke_fn(PM_QUERY_DATA, qdata.qid, qdata.arg1, | 253 | int ret; |
254 | qdata.arg2, qdata.arg3, out); | 254 | |
255 | ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, qdata.qid, qdata.arg1, | ||
256 | qdata.arg2, qdata.arg3, out); | ||
257 | |||
258 | /* | ||
259 | * For clock name query, all bytes in SMC response are clock name | ||
260 | * characters and return code is always success. For invalid clocks, | ||
261 | * clock name bytes would be zeros. | ||
262 | */ | ||
263 | return qdata.qid == PM_QID_CLOCK_GET_NAME ? 0 : ret; | ||
264 | } | ||
265 | |||
266 | /** | ||
267 | * zynqmp_pm_clock_enable() - Enable the clock for given id | ||
268 | * @clock_id: ID of the clock to be enabled | ||
269 | * | ||
270 | * This function is used by master to enable the clock | ||
271 | * including peripherals and PLL clocks. | ||
272 | * | ||
273 | * Return: Returns status, either success or error+reason | ||
274 | */ | ||
275 | static int zynqmp_pm_clock_enable(u32 clock_id) | ||
276 | { | ||
277 | return zynqmp_pm_invoke_fn(PM_CLOCK_ENABLE, clock_id, 0, 0, 0, NULL); | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * zynqmp_pm_clock_disable() - Disable the clock for given id | ||
282 | * @clock_id: ID of the clock to be disable | ||
283 | * | ||
284 | * This function is used by master to disable the clock | ||
285 | * including peripherals and PLL clocks. | ||
286 | * | ||
287 | * Return: Returns status, either success or error+reason | ||
288 | */ | ||
289 | static int zynqmp_pm_clock_disable(u32 clock_id) | ||
290 | { | ||
291 | return zynqmp_pm_invoke_fn(PM_CLOCK_DISABLE, clock_id, 0, 0, 0, NULL); | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * zynqmp_pm_clock_getstate() - Get the clock state for given id | ||
296 | * @clock_id: ID of the clock to be queried | ||
297 | * @state: 1/0 (Enabled/Disabled) | ||
298 | * | ||
299 | * This function is used by master to get the state of clock | ||
300 | * including peripherals and PLL clocks. | ||
301 | * | ||
302 | * Return: Returns status, either success or error+reason | ||
303 | */ | ||
304 | static int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state) | ||
305 | { | ||
306 | u32 ret_payload[PAYLOAD_ARG_CNT]; | ||
307 | int ret; | ||
308 | |||
309 | ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETSTATE, clock_id, 0, | ||
310 | 0, 0, ret_payload); | ||
311 | *state = ret_payload[1]; | ||
312 | |||
313 | return ret; | ||
314 | } | ||
315 | |||
316 | /** | ||
317 | * zynqmp_pm_clock_setdivider() - Set the clock divider for given id | ||
318 | * @clock_id: ID of the clock | ||
319 | * @divider: divider value | ||
320 | * | ||
321 | * This function is used by master to set divider for any clock | ||
322 | * to achieve desired rate. | ||
323 | * | ||
324 | * Return: Returns status, either success or error+reason | ||
325 | */ | ||
326 | static int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider) | ||
327 | { | ||
328 | return zynqmp_pm_invoke_fn(PM_CLOCK_SETDIVIDER, clock_id, divider, | ||
329 | 0, 0, NULL); | ||
330 | } | ||
331 | |||
332 | /** | ||
333 | * zynqmp_pm_clock_getdivider() - Get the clock divider for given id | ||
334 | * @clock_id: ID of the clock | ||
335 | * @divider: divider value | ||
336 | * | ||
337 | * This function is used by master to get divider values | ||
338 | * for any clock. | ||
339 | * | ||
340 | * Return: Returns status, either success or error+reason | ||
341 | */ | ||
342 | static int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider) | ||
343 | { | ||
344 | u32 ret_payload[PAYLOAD_ARG_CNT]; | ||
345 | int ret; | ||
346 | |||
347 | ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETDIVIDER, clock_id, 0, | ||
348 | 0, 0, ret_payload); | ||
349 | *divider = ret_payload[1]; | ||
350 | |||
351 | return ret; | ||
352 | } | ||
353 | |||
354 | /** | ||
355 | * zynqmp_pm_clock_setrate() - Set the clock rate for given id | ||
356 | * @clock_id: ID of the clock | ||
357 | * @rate: rate value in hz | ||
358 | * | ||
359 | * This function is used by master to set rate for any clock. | ||
360 | * | ||
361 | * Return: Returns status, either success or error+reason | ||
362 | */ | ||
363 | static int zynqmp_pm_clock_setrate(u32 clock_id, u64 rate) | ||
364 | { | ||
365 | return zynqmp_pm_invoke_fn(PM_CLOCK_SETRATE, clock_id, | ||
366 | lower_32_bits(rate), | ||
367 | upper_32_bits(rate), | ||
368 | 0, NULL); | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * zynqmp_pm_clock_getrate() - Get the clock rate for given id | ||
373 | * @clock_id: ID of the clock | ||
374 | * @rate: rate value in hz | ||
375 | * | ||
376 | * This function is used by master to get rate | ||
377 | * for any clock. | ||
378 | * | ||
379 | * Return: Returns status, either success or error+reason | ||
380 | */ | ||
381 | static int zynqmp_pm_clock_getrate(u32 clock_id, u64 *rate) | ||
382 | { | ||
383 | u32 ret_payload[PAYLOAD_ARG_CNT]; | ||
384 | int ret; | ||
385 | |||
386 | ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETRATE, clock_id, 0, | ||
387 | 0, 0, ret_payload); | ||
388 | *rate = ((u64)ret_payload[2] << 32) | ret_payload[1]; | ||
389 | |||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | /** | ||
394 | * zynqmp_pm_clock_setparent() - Set the clock parent for given id | ||
395 | * @clock_id: ID of the clock | ||
396 | * @parent_id: parent id | ||
397 | * | ||
398 | * This function is used by master to set parent for any clock. | ||
399 | * | ||
400 | * Return: Returns status, either success or error+reason | ||
401 | */ | ||
402 | static int zynqmp_pm_clock_setparent(u32 clock_id, u32 parent_id) | ||
403 | { | ||
404 | return zynqmp_pm_invoke_fn(PM_CLOCK_SETPARENT, clock_id, | ||
405 | parent_id, 0, 0, NULL); | ||
406 | } | ||
407 | |||
408 | /** | ||
409 | * zynqmp_pm_clock_getparent() - Get the clock parent for given id | ||
410 | * @clock_id: ID of the clock | ||
411 | * @parent_id: parent id | ||
412 | * | ||
413 | * This function is used by master to get parent index | ||
414 | * for any clock. | ||
415 | * | ||
416 | * Return: Returns status, either success or error+reason | ||
417 | */ | ||
418 | static int zynqmp_pm_clock_getparent(u32 clock_id, u32 *parent_id) | ||
419 | { | ||
420 | u32 ret_payload[PAYLOAD_ARG_CNT]; | ||
421 | int ret; | ||
422 | |||
423 | ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETPARENT, clock_id, 0, | ||
424 | 0, 0, ret_payload); | ||
425 | *parent_id = ret_payload[1]; | ||
426 | |||
427 | return ret; | ||
255 | } | 428 | } |
256 | 429 | ||
257 | static const struct zynqmp_eemi_ops eemi_ops = { | 430 | static const struct zynqmp_eemi_ops eemi_ops = { |
258 | .get_api_version = zynqmp_pm_get_api_version, | 431 | .get_api_version = zynqmp_pm_get_api_version, |
259 | .query_data = zynqmp_pm_query_data, | 432 | .query_data = zynqmp_pm_query_data, |
433 | .clock_enable = zynqmp_pm_clock_enable, | ||
434 | .clock_disable = zynqmp_pm_clock_disable, | ||
435 | .clock_getstate = zynqmp_pm_clock_getstate, | ||
436 | .clock_setdivider = zynqmp_pm_clock_setdivider, | ||
437 | .clock_getdivider = zynqmp_pm_clock_getdivider, | ||
438 | .clock_setrate = zynqmp_pm_clock_setrate, | ||
439 | .clock_getrate = zynqmp_pm_clock_getrate, | ||
440 | .clock_setparent = zynqmp_pm_clock_setparent, | ||
441 | .clock_getparent = zynqmp_pm_clock_getparent, | ||
260 | }; | 442 | }; |
261 | 443 | ||
262 | /** | 444 | /** |