1 /* 2 * Copyright (c) 2016, NVIDIA CORPORATION. 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <misc.h> 10 #include <power-domain-uclass.h> 11 #include <asm/arch-tegra/bpmp_abi.h> 12 13 #define UPDATE BIT(0) 14 #define ON BIT(1) 15 16 static int tegra186_power_domain_request(struct power_domain *power_domain) 17 { 18 debug("%s(power_domain=%p) (dev=%p, id=%lu)\n", __func__, 19 power_domain, power_domain->dev, power_domain->id); 20 21 return 0; 22 } 23 24 static int tegra186_power_domain_free(struct power_domain *power_domain) 25 { 26 debug("%s(power_domain=%p) (dev=%p, id=%lu)\n", __func__, 27 power_domain, power_domain->dev, power_domain->id); 28 29 return 0; 30 } 31 32 static int tegra186_power_domain_common(struct power_domain *power_domain, 33 bool on) 34 { 35 struct mrq_pg_update_state_request req; 36 int on_state = on ? ON : 0; 37 int ret; 38 39 req.partition_id = power_domain->id; 40 req.logic_state = UPDATE | on_state; 41 req.sram_state = UPDATE | on_state; 42 /* 43 * Drivers manage their own clocks so they don't get out of sync, and 44 * since some power domains have many clocks, only a subset of which 45 * are actually needed depending on use-case. 46 */ 47 req.clock_state = UPDATE; 48 49 ret = misc_call(power_domain->dev->parent, MRQ_PG_UPDATE_STATE, &req, 50 sizeof(req), NULL, 0); 51 if (ret < 0) 52 return ret; 53 54 return 0; 55 } 56 57 static int tegra186_power_domain_on(struct power_domain *power_domain) 58 { 59 debug("%s(power_domain=%p) (dev=%p, id=%lu)\n", __func__, 60 power_domain, power_domain->dev, power_domain->id); 61 62 return tegra186_power_domain_common(power_domain, true); 63 } 64 65 static int tegra186_power_domain_off(struct power_domain *power_domain) 66 { 67 debug("%s(power_domain=%p) (dev=%p, id=%lu)\n", __func__, 68 power_domain, power_domain->dev, power_domain->id); 69 70 return tegra186_power_domain_common(power_domain, false); 71 } 72 73 struct power_domain_ops tegra186_power_domain_ops = { 74 .request = tegra186_power_domain_request, 75 .free = tegra186_power_domain_free, 76 .on = tegra186_power_domain_on, 77 .off = tegra186_power_domain_off, 78 }; 79 80 static int tegra186_power_domain_probe(struct udevice *dev) 81 { 82 debug("%s(dev=%p)\n", __func__, dev); 83 84 return 0; 85 } 86 87 U_BOOT_DRIVER(tegra186_power_domain) = { 88 .name = "tegra186_power_domain", 89 .id = UCLASS_POWER_DOMAIN, 90 .probe = tegra186_power_domain_probe, 91 .ops = &tegra186_power_domain_ops, 92 }; 93