1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <ddk/debug.h>
6 #include <ddk/device.h>
7 #include <ddk/metadata.h>
8 #include <ddk/platform-defs.h>
9 #include <ddk/protocol/platform/bus.h>
10 #include <soc/aml-s912/s912-gpio.h>
11 #include <soc/aml-s912/s912-hw.h>
12 #include <soc/aml-common/aml-thermal.h>
13 #include "vim.h"
14
15 static const pbus_mmio_t mailbox_mmios[] = {
16 // Mailbox
17 {
18 .base = S912_HIU_MAILBOX_BASE,
19 .length = S912_HIU_MAILBOX_LENGTH,
20 },
21 // Mailbox Payload
22 {
23 .base = S912_MAILBOX_PAYLOAD_BASE,
24 .length = S912_MAILBOX_PAYLOAD_LENGTH,
25 },
26 };
27
28 // IRQ for Mailbox
29 static const pbus_irq_t mailbox_irqs[] = {
30 {
31 .irq = S912_MBOX_IRQ_RECEIV0,
32 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
33 },
34 {
35 .irq = S912_MBOX_IRQ_RECEIV1,
36 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
37 },
38 {
39 .irq = S912_MBOX_IRQ_RECEIV2,
40 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
41 },
42 {
43 .irq = S912_MBOX_IRQ_SEND3,
44 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
45 },
46 {
47 .irq = S912_MBOX_IRQ_SEND4,
48 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
49 },
50 {
51 .irq = S912_MBOX_IRQ_SEND5,
52 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH
53 },
54 };
55
56 static const pbus_gpio_t fanctl_gpios[] = {
57 {
58 .gpio = S912_GPIODV(14),
59 },
60 {
61 .gpio = S912_GPIODV(15),
62 }
63 };
64
65 /* ACTIVE COOLING - For VIM2, we assume that all devices
66 * are connected with a GPIO-controlled fan.
67 * The GPIO controlled fan has 3 levels of speed (1-3)
68 *
69 * PASSIVE COOLING - For VIM2, we have DVFS support added
70 * Below is the operating point information for Big cluster
71 * Operating point 0 - Freq 0.1000 Ghz Voltage 0.9100 V
72 * Operating point 1 - Freq 0.2500 Ghz Voltage 0.9100 V
73 * Operating point 2 - Freq 0.5000 Ghz Voltage 0.9100 V
74 * Operating point 3 - Freq 0.6670 Ghz Voltage 0.9500 V
75 * Operating point 4 - Freq 1.0000 Ghz Voltage 0.9900 V
76 * Operating point 5 - Freq 1.2000 Ghz Voltage 1.0700 V
77 * Operating point 6 - Freq 1.2960 Ghz Voltage 1.1000 V
78 *
79 * Below is the operating point information for Little cluster
80 * Operating point 0 - Freq 0.1000 Ghz Voltage 0.9100 V
81 * Operating point 1 - Freq 0.2500 Ghz Voltage 0.9100 V
82 * Operating point 2 - Freq 0.5000 Ghz Voltage 0.9100 V
83 * Operating point 3 - Freq 0.6670 Ghz Voltage 0.9500 V
84 * Operating point 4 - Freq 1.0000 Ghz Voltage 0.9900 V
85 *
86 * GPU_CLK_FREQUENCY_SOURCE - For VIM2, we support GPU
87 * throttling. Currently we have pre-defined frequencies
88 * we can set the GPU clock to, but we can always add more
89 * One's we support now are below
90 * Operating point 0 - 285.7 MHz
91 * Operating point 1 - 400.0 MHz
92 * Operating point 2 - 500.0 MHz
93 * Operating point 3 - 666.0 MHz
94 * Operating point -1 - INVALID/No throttling needed
95 */
96
97 static thermal_device_info_t aml_vim2_config = {
98 .active_cooling = true,
99 .passive_cooling = true,
100 .gpu_throttling = true,
101 .big_little = true,
102 .num_trip_points = 8,
103 .critical_temp = 81,
104 .trip_point_info = {
105 {
106 // This is the initial thermal setup of the device
107 // Fan set to OFF
108 // CPU freq set to a known stable MAX
109 .fan_level = 0,
110 .big_cluster_dvfs_opp = 6,
111 .little_cluster_dvfs_opp = 4,
112 .gpu_clk_freq_source = 3,
113 },
114 {
115 .fan_level = 1,
116 .up_temp = 65,
117 .down_temp = 63,
118 .big_cluster_dvfs_opp = 6,
119 .little_cluster_dvfs_opp = 4,
120 .gpu_clk_freq_source = 3,
121 },
122 {
123 .fan_level = 2,
124 .up_temp = 70,
125 .down_temp = 68,
126 .big_cluster_dvfs_opp = 6,
127 .little_cluster_dvfs_opp = 4,
128 .gpu_clk_freq_source = 3,
129 },
130 {
131 .fan_level = 3,
132 .up_temp = 75,
133 .down_temp = 73,
134 .big_cluster_dvfs_opp = 6,
135 .little_cluster_dvfs_opp = 4,
136 .gpu_clk_freq_source = 3,
137 },
138 {
139 .fan_level = 3,
140 .up_temp = 82,
141 .down_temp = 79,
142 .big_cluster_dvfs_opp = 5,
143 .little_cluster_dvfs_opp = 4,
144 .gpu_clk_freq_source = 2,
145 },
146 {
147 .fan_level = 3,
148 .up_temp = 87,
149 .down_temp = 84,
150 .big_cluster_dvfs_opp = 4,
151 .little_cluster_dvfs_opp = 4,
152 .gpu_clk_freq_source = 2,
153 },
154 {
155 .fan_level = 3,
156 .up_temp = 92,
157 .down_temp = 89,
158 .big_cluster_dvfs_opp = 3,
159 .little_cluster_dvfs_opp = 3,
160 .gpu_clk_freq_source = 1,
161 },
162 {
163 .fan_level = 3,
164 .up_temp = 96,
165 .down_temp = 93,
166 .big_cluster_dvfs_opp = 2,
167 .little_cluster_dvfs_opp = 2,
168 .gpu_clk_freq_source = 0,
169 }
170 }
171 };
172
173 static const pbus_metadata_t vim_thermal_metadata[] = {
174 {
175 .type = DEVICE_METADATA_PRIVATE,
176 .data_buffer = &aml_vim2_config,
177 .data_size = sizeof(aml_vim2_config),
178 }
179 };
180
181 static const pbus_dev_t scpi_children[] = {
182 // VIM2 thermal driver
183 {
184 .gpio_list = fanctl_gpios,
185 .gpio_count = countof(fanctl_gpios),
186 .metadata_list = vim_thermal_metadata,
187 .metadata_count = countof(vim_thermal_metadata),
188 },
189 };
190
191 static const pbus_dev_t mailbox_children[] = {
192 // Amlogic SCPI driver
193 {
194 .child_list = scpi_children,
195 .child_count = countof(scpi_children),
196 },
197 };
198
199 static const pbus_dev_t mailbox_dev = {
200 .name = "mailbox",
201 .vid = PDEV_VID_KHADAS,
202 .pid = PDEV_PID_VIM2,
203 .did = PDEV_DID_AMLOGIC_MAILBOX,
204 .mmio_list = mailbox_mmios,
205 .mmio_count = countof(mailbox_mmios),
206 .irq_list = mailbox_irqs,
207 .irq_count = countof(mailbox_irqs),
208 .child_list = mailbox_children,
209 .child_count = countof(mailbox_children),
210 };
211
vim2_thermal_init(vim_bus_t * bus)212 zx_status_t vim2_thermal_init(vim_bus_t* bus) {
213 zx_status_t status = pbus_device_add(&bus->pbus, &mailbox_dev);
214 if (status != ZX_OK) {
215 zxlogf(ERROR, "vim2_thermal_init: pbus_device_add failed: %d\n", status);
216 return status;
217 }
218 return ZX_OK;
219 }
220