1 /* 2 * Copyright (c) 2016, NVIDIA CORPORATION. 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <clk-uclass.h> 9 #include <dm.h> 10 #include <asm/arch/clock.h> 11 #include <asm/arch-tegra/clk_rst.h> 12 13 static int tegra_car_clk_request(struct clk *clk) 14 { 15 debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, 16 clk->id); 17 18 /* 19 * Note that the first PERIPH_ID_COUNT clock IDs (where the value 20 * varies per SoC) are the peripheral clocks, which use a numbering 21 * scheme that matches HW registers 1:1. There are other clock IDs 22 * beyond this that are assigned arbitrarily by the Tegra CAR DT 23 * binding. Due to the implementation of this driver, it currently 24 * only supports the peripheral IDs. 25 */ 26 if (clk->id >= PERIPH_ID_COUNT) 27 return -EINVAL; 28 29 return 0; 30 } 31 32 static int tegra_car_clk_free(struct clk *clk) 33 { 34 debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, 35 clk->id); 36 37 return 0; 38 } 39 40 static ulong tegra_car_clk_get_rate(struct clk *clk) 41 { 42 enum clock_id parent; 43 44 debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, 45 clk->id); 46 47 parent = clock_get_periph_parent(clk->id); 48 return clock_get_periph_rate(clk->id, parent); 49 } 50 51 static ulong tegra_car_clk_set_rate(struct clk *clk, ulong rate) 52 { 53 enum clock_id parent; 54 55 debug("%s(clk=%p, rate=%lu) (dev=%p, id=%lu)\n", __func__, clk, rate, 56 clk->dev, clk->id); 57 58 parent = clock_get_periph_parent(clk->id); 59 return clock_adjust_periph_pll_div(clk->id, parent, rate, NULL); 60 } 61 62 static int tegra_car_clk_enable(struct clk *clk) 63 { 64 debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, 65 clk->id); 66 67 clock_enable(clk->id); 68 69 return 0; 70 } 71 72 static int tegra_car_clk_disable(struct clk *clk) 73 { 74 debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev, 75 clk->id); 76 77 clock_disable(clk->id); 78 79 return 0; 80 } 81 82 static struct clk_ops tegra_car_clk_ops = { 83 .request = tegra_car_clk_request, 84 .free = tegra_car_clk_free, 85 .get_rate = tegra_car_clk_get_rate, 86 .set_rate = tegra_car_clk_set_rate, 87 .enable = tegra_car_clk_enable, 88 .disable = tegra_car_clk_disable, 89 }; 90 91 static int tegra_car_clk_probe(struct udevice *dev) 92 { 93 debug("%s(dev=%p)\n", __func__, dev); 94 95 return 0; 96 } 97 98 U_BOOT_DRIVER(tegra_car_clk) = { 99 .name = "tegra_car_clk", 100 .id = UCLASS_CLK, 101 .probe = tegra_car_clk_probe, 102 .ops = &tegra_car_clk_ops, 103 }; 104