blob: 46da541b75a887ee82d882dfe276c45777c5d8dd [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Stephen Warren24cdf1a2016-08-08 11:28:26 -06002/*
3 * Copyright (c) 2016, NVIDIA CORPORATION.
Stephen Warren24cdf1a2016-08-08 11:28:26 -06004 */
5
6#include <common.h>
7#include <dm.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -06008#include <log.h>
Simon Glass336d4612020-02-03 07:36:16 -07009#include <malloc.h>
Stephen Warren24cdf1a2016-08-08 11:28:26 -060010#include <misc.h>
11#include <power-domain-uclass.h>
12#include <asm/arch-tegra/bpmp_abi.h>
Simon Glasscd93d622020-05-10 11:40:13 -060013#include <linux/bitops.h>
Stephen Warren24cdf1a2016-08-08 11:28:26 -060014
15#define UPDATE BIT(0)
16#define ON BIT(1)
17
Stephen Warren24cdf1a2016-08-08 11:28:26 -060018static int tegra186_power_domain_common(struct power_domain *power_domain,
19 bool on)
20{
21 struct mrq_pg_update_state_request req;
22 int on_state = on ? ON : 0;
23 int ret;
24
25 req.partition_id = power_domain->id;
26 req.logic_state = UPDATE | on_state;
27 req.sram_state = UPDATE | on_state;
28 /*
29 * Drivers manage their own clocks so they don't get out of sync, and
30 * since some power domains have many clocks, only a subset of which
31 * are actually needed depending on use-case.
32 */
33 req.clock_state = UPDATE;
34
35 ret = misc_call(power_domain->dev->parent, MRQ_PG_UPDATE_STATE, &req,
36 sizeof(req), NULL, 0);
37 if (ret < 0)
38 return ret;
39
40 return 0;
41}
42
43static int tegra186_power_domain_on(struct power_domain *power_domain)
44{
45 debug("%s(power_domain=%p) (dev=%p, id=%lu)\n", __func__,
46 power_domain, power_domain->dev, power_domain->id);
47
48 return tegra186_power_domain_common(power_domain, true);
49}
50
51static int tegra186_power_domain_off(struct power_domain *power_domain)
52{
53 debug("%s(power_domain=%p) (dev=%p, id=%lu)\n", __func__,
54 power_domain, power_domain->dev, power_domain->id);
55
56 return tegra186_power_domain_common(power_domain, false);
57}
58
59struct power_domain_ops tegra186_power_domain_ops = {
Stephen Warren24cdf1a2016-08-08 11:28:26 -060060 .on = tegra186_power_domain_on,
61 .off = tegra186_power_domain_off,
62};
63
Stephen Warren24cdf1a2016-08-08 11:28:26 -060064U_BOOT_DRIVER(tegra186_power_domain) = {
65 .name = "tegra186_power_domain",
66 .id = UCLASS_POWER_DOMAIN,
Stephen Warren24cdf1a2016-08-08 11:28:26 -060067 .ops = &tegra186_power_domain_ops,
68};