1 /* 2 * Copyright (C) 2015 Google, Inc 3 * Written by Simon Glass <sjg@chromium.org> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <clk.h> 10 #include <dm.h> 11 #include <errno.h> 12 #include <dm/lists.h> 13 #include <dm/root.h> 14 15 DECLARE_GLOBAL_DATA_PTR; 16 17 ulong clk_get_rate(struct udevice *dev) 18 { 19 struct clk_ops *ops = clk_get_ops(dev); 20 21 if (!ops->get_rate) 22 return -ENOSYS; 23 24 return ops->get_rate(dev); 25 } 26 27 ulong clk_set_rate(struct udevice *dev, ulong rate) 28 { 29 struct clk_ops *ops = clk_get_ops(dev); 30 31 if (!ops->set_rate) 32 return -ENOSYS; 33 34 return ops->set_rate(dev, rate); 35 } 36 37 int clk_enable(struct udevice *dev, int periph) 38 { 39 struct clk_ops *ops = clk_get_ops(dev); 40 41 if (!ops->enable) 42 return -ENOSYS; 43 44 return ops->enable(dev, periph); 45 } 46 47 ulong clk_get_periph_rate(struct udevice *dev, int periph) 48 { 49 struct clk_ops *ops = clk_get_ops(dev); 50 51 if (!ops->get_periph_rate) 52 return -ENOSYS; 53 54 return ops->get_periph_rate(dev, periph); 55 } 56 57 ulong clk_set_periph_rate(struct udevice *dev, int periph, ulong rate) 58 { 59 struct clk_ops *ops = clk_get_ops(dev); 60 61 if (!ops->set_periph_rate) 62 return -ENOSYS; 63 64 return ops->set_periph_rate(dev, periph, rate); 65 } 66 67 #if CONFIG_IS_ENABLED(OF_CONTROL) 68 int clk_get_by_index(struct udevice *dev, int index, struct udevice **clk_devp) 69 { 70 int ret; 71 #ifdef CONFIG_SPL_BUILD 72 u32 cell[2]; 73 74 if (index != 0) 75 return -ENOSYS; 76 assert(*clk_devp); 77 ret = uclass_get_device(UCLASS_CLK, 0, clk_devp); 78 if (ret) 79 return ret; 80 ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clocks", 81 cell, 2); 82 if (ret) 83 return ret; 84 return cell[1]; 85 #else 86 struct fdtdec_phandle_args args; 87 88 assert(*clk_devp); 89 ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset, 90 "clocks", "#clock-cells", 0, index, 91 &args); 92 if (ret) { 93 debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n", 94 __func__, ret); 95 return ret; 96 } 97 98 ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, clk_devp); 99 if (ret) { 100 debug("%s: uclass_get_device_by_of_offset failed: err=%d\n", 101 __func__, ret); 102 return ret; 103 } 104 return args.args_count > 0 ? args.args[0] : 0; 105 #endif 106 } 107 #endif 108 109 UCLASS_DRIVER(clk) = { 110 .id = UCLASS_CLK, 111 .name = "clk", 112 }; 113