2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <device/mmio.h>
16 #include <soc/addressmap.h>
17 #include <soc/flow_ctrl.h>
19 #define FLOW_CTRL_HALT_CPU0_EVENTS 0x0
20 #define FLOW_CTRL_WAITEVENT (2 << 29)
21 #define FLOW_CTRL_WAIT_FOR_INTERRUPT (4 << 29)
22 #define FLOW_CTRL_HALT_SCLK (1 << 27)
23 #define FLOW_CTRL_HALT_LIC_IRQ (1 << 11)
24 #define FLOW_CTRL_HALT_LIC_FIQ (1 << 10)
25 #define FLOW_CTRL_HALT_GIC_IRQ (1 << 9)
26 #define FLOW_CTRL_HALT_GIC_FIQ (1 << 8)
27 #define FLOW_CTRL_CPU0_CSR 0x8
28 #define FLOW_CTRL_CSR_INTR_FLAG (1 << 15)
29 #define FLOW_CTRL_CSR_EVENT_FLAG (1 << 14)
30 #define FLOW_CTRL_CSR_WFI_CPU0 (1 << 8)
31 #define FLOW_CTRL_CSR_WFI_BITMAP (0xF << 8)
32 #define FLOW_CTRL_CSR_WFE_BITMAP (0xF << 4)
33 #define FLOW_CTRL_CSR_ENABLE (1 << 0)
34 #define FLOW_CTRL_HALT_CPU1_EVENTS 0x14
35 #define FLOW_CTRL_CPU1_CSR 0x18
36 #define FLOW_CTRL_CC4_CORE0_CTRL 0x6c
38 static void *tegra_flowctrl_base
= (void *)TEGRA_FLOW_BASE
;
40 static const uint8_t flowctrl_offset_halt_cpu
[] = {
41 FLOW_CTRL_HALT_CPU0_EVENTS
,
42 FLOW_CTRL_HALT_CPU1_EVENTS
,
43 FLOW_CTRL_HALT_CPU1_EVENTS
+ 8,
44 FLOW_CTRL_HALT_CPU1_EVENTS
+ 16
47 static const uint8_t flowctrl_offset_cpu_csr
[] = {
50 FLOW_CTRL_CPU1_CSR
+ 8,
51 FLOW_CTRL_CPU1_CSR
+ 16
54 static const uint8_t flowctrl_offset_cc4_ctrl
[] = {
55 FLOW_CTRL_CC4_CORE0_CTRL
,
56 FLOW_CTRL_CC4_CORE0_CTRL
+ 4,
57 FLOW_CTRL_CC4_CORE0_CTRL
+ 8,
58 FLOW_CTRL_CC4_CORE0_CTRL
+ 12
61 void flowctrl_write_cpu_csr(int cpu
, uint32_t val
)
63 write32(tegra_flowctrl_base
+ flowctrl_offset_cpu_csr
[cpu
], val
);
64 val
= read32(tegra_flowctrl_base
+ flowctrl_offset_cpu_csr
[cpu
]);
67 void flowctrl_write_cpu_halt(int cpu
, uint32_t val
)
69 write32(tegra_flowctrl_base
+ flowctrl_offset_halt_cpu
[cpu
], val
);
70 val
= read32(tegra_flowctrl_base
+ flowctrl_offset_halt_cpu
[cpu
]);
73 void flowctrl_write_cc4_ctrl(int cpu
, uint32_t val
)
75 write32(tegra_flowctrl_base
+ flowctrl_offset_cc4_ctrl
[cpu
], val
);
76 val
= read32(tegra_flowctrl_base
+ flowctrl_offset_cc4_ctrl
[cpu
]);
79 void flowctrl_cpu_off(int cpu
)
81 uint32_t val
= FLOW_CTRL_CSR_INTR_FLAG
| FLOW_CTRL_CSR_EVENT_FLAG
|
82 FLOW_CTRL_CSR_ENABLE
| (FLOW_CTRL_CSR_WFI_CPU0
<< cpu
);
84 flowctrl_write_cpu_csr(cpu
, val
);
85 flowctrl_write_cpu_halt(cpu
, FLOW_CTRL_WAITEVENT
);
86 flowctrl_write_cc4_ctrl(cpu
, 0);
89 void flowctrl_cpu_on(int cpu
)
91 flowctrl_write_cpu_csr(cpu
, FLOW_CTRL_CSR_ENABLE
);
92 flowctrl_write_cpu_halt(cpu
, FLOW_CTRL_WAITEVENT
|
96 void flowctrl_cpu_suspend(int cpu
)
100 val
= FLOW_CTRL_HALT_GIC_IRQ
| FLOW_CTRL_HALT_GIC_FIQ
|
101 FLOW_CTRL_HALT_LIC_IRQ
| FLOW_CTRL_HALT_LIC_FIQ
|
103 flowctrl_write_cpu_halt(cpu
, val
);
105 val
= FLOW_CTRL_CSR_INTR_FLAG
| FLOW_CTRL_CSR_EVENT_FLAG
|
106 FLOW_CTRL_CSR_ENABLE
| (FLOW_CTRL_CSR_WFI_CPU0
<< cpu
);
107 flowctrl_write_cpu_csr(cpu
, val
);