coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
power.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <console/console.h>
5 #include <soc/addressmap.h>
6 #include <soc/clock.h>
7 #include <soc/flow.h>
8 #include <soc/pmc.h>
9 #include <soc/power.h>
10 
11 static struct tegra_pmc_regs * const pmc = (void *)TEGRA_PMC_BASE;
12 static struct flow_ctlr * const flow = (void *)TEGRA_FLOW_BASE;
13 
14 static int partition_powered(int id)
15 {
16  return read32(&pmc->pwrgate_status) & (0x1 << id);
17 }
18 
19 static int partition_clamp_on(int id)
20 {
21  return read32(&pmc->clamp_status) & (0x1 << id);
22 }
23 
25 {
26  printk(BIOS_INFO, "Ungating power partition %d.\n", id);
27 
28  if (!partition_powered(id)) {
29  uint32_t pwrgate_toggle = read32(&pmc->pwrgate_toggle);
30  pwrgate_toggle &= ~(PMC_PWRGATE_TOGGLE_PARTID_MASK);
31  pwrgate_toggle |= (id << PMC_PWRGATE_TOGGLE_PARTID_SHIFT);
32  pwrgate_toggle |= PMC_PWRGATE_TOGGLE_START;
33  write32(&pmc->pwrgate_toggle, pwrgate_toggle);
34 
35  // Wait for the request to be accepted.
37  ;
38  printk(BIOS_DEBUG, "Power gate toggle request accepted.\n");
39 
40  // Wait for the partition to be powered.
41  while (!partition_powered(id))
42  ;
43 
44  // Wait for clamp off.
45  while (partition_clamp_on(id))
46  ;
47  }
48 
49  printk(BIOS_INFO, "Ungated power partition %d.\n", id);
50 }
51 
53 {
54  /*
55  * Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (150MHz),
56  * set it for 5ms as per SysEng (5ms * PCLK_KHZ * 1000 / 1s).
57  */
59 
60  uint32_t cntrl = read32(&pmc->cntrl);
62  cntrl |= PMC_CNTRL_CPUPWRREQ_OE;
63  write32(&pmc->cntrl, cntrl);
64 
66 
67  // Ungate power to the non-core parts of the fast cluster.
69 
70  // Ungate power to CPU0 in the fast cluster.
72 }
73 
75 {
76  return read32(&pmc->rst_status) & 0x7;
77 }
78 
79 void ram_repair(void)
80 {
81  // Request RAM repair for cluster 0
83  // Poll for completion
84  while (!(read32(&flow->ram_repair) & RAM_REPAIR_STS))
85  ;
86  // Request RAM repair for cluster 1
88  // Poll for completion
90  ;
91 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define printk(level,...)
Definition: stdlib.h:16
#define setbits32(addr, set)
Definition: mmio.h:21
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
@ PMC_PWRGATE_TOGGLE_PARTID_SHIFT
Definition: pmc.h:306
@ PMC_PWRGATE_TOGGLE_START
Definition: pmc.h:307
@ PMC_PWRGATE_TOGGLE_PARTID_MASK
Definition: pmc.h:305
@ PMC_CNTRL_CPUPWRREQ_OE
Definition: pmc.h:327
@ PMC_CNTRL_CPUPWRREQ_POLARITY
Definition: pmc.h:326
@ POWER_PARTID_CE0
Definition: pmc.h:20
@ POWER_PARTID_C0NC
Definition: pmc.h:21
@ POWER_PARTID_CRAIL
Definition: pmc.h:9
int power_reset_status(void)
Definition: power.c:74
static void power_ungate_partition(uint32_t id)
Definition: power.c:24
static struct tegra_pmc_regs *const pmc
Definition: power.c:11
void power_enable_and_ungate_cpu(void)
Definition: power.c:52
static int partition_powered(int id)
Definition: power.c:14
static struct flow_ctlr *const flow
Definition: power.c:12
void ram_repair(void)
Definition: power.c:79
static int partition_clamp_on(int id)
Definition: power.c:19
@ TEGRA_FLOW_BASE
Definition: addressmap.h:22
@ TEGRA_PMC_BASE
Definition: addressmap.h:51
#define TEGRA_PCLK_KHZ
Definition: clock.h:268
unsigned int uint32_t
Definition: stdint.h:14
Definition: flow.h:6
u32 ram_repair_cluster1
Definition: flow.h:29
u32 ram_repair
Definition: flow.h:23
u32 cpupwrgood_timer
Definition: pmc.h:81
u32 rst_status
Definition: pmc.h:132
u32 clamp_status
Definition: pmc.h:42
u32 pwrgate_toggle
Definition: pmc.h:43
u32 pwrgate_status
Definition: pmc.h:45
u32 cntrl
Definition: pmc.h:31
@ RAM_REPAIR_REQ
Definition: flow.h:73
@ RAM_REPAIR_STS
Definition: flow.h:74