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