1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 #include <acpi/acpigen.h>
4 #include <acpi/acpi_device.h>
8 #include "soc/intel/common/block/include/intelblocks/acpi.h"
9 #include "soc/intel/common/block/pcie/rtd3/chip.h"
11 /* FCPO# to RESET# delay time during WWAN ON */
12 #define FM350GL_TN2B 20
13 /* RESET# to PERST# delay time during WWAN ON */
14 #define FM350GL_TB2R 80
15 /* The delay between de-assertion of PERST# to change of PDS state from 0 to 1 during WWAN ON */
16 #define FM350GL_TR2P 0
17 /* RESET# to FCPO# delay time during WWAN OFF */
18 #define FM350GL_TB2F 10
19 /* Time to allow the WWAN module to fully discharge any residual voltages before FCPO# could be
21 #define FM350GL_TFDI 500
22 /* The delay between assertion and de-assertion RESET# during FLDR */
23 #define FM350GL_TBTG 10
24 /* The delay between de-assertion of RESET# and change of PDS state from 0 to 1 after FLDR */
25 #define FM350GL_TBTP 170
26 /* PERST# to RESET# delay time during WWAN OFF */
27 #define FM350GL_TR2B 10
28 /* 20s HW initialization needed after de-assertion of PERST#
29 However, it is not required and is not proper place to ensure HW initialization in ACPI. The
30 delay here is to ensure the following reset or RTD3 _OFF method won't be called immediately.
32 #define FM350GL_TIME_HW_INIT 100
40 * Returns the RTD3 PM methods requested and available to the device.
42 static enum acpi_pcie_rp_pm_emit
43 wwan_fm350gl_get_rtd3_method_support(const struct drivers_wwan_fm_config
*config
)
45 const struct soc_intel_common_block_pcie_rtd3_config
*rtd3_config
;
47 rtd3_config
= config_of(config
->rtd3dev
);
49 return rtd3_config
->ext_pm_support
;
53 * Generate first half reset flow (FHRF) method.
54 * Arg0 = 0; RESET_TYPE_WARM: warm reset
55 * Arg0 = 1; RESET_TYPE_COLD: cold reset
57 static void wwan_fm350gl_acpi_method_fhrf(const struct device
*parent_dev
,
58 const struct drivers_wwan_fm_config
*config
)
60 acpigen_write_method_serialized("FHRF", 1);
63 const struct soc_intel_common_block_pcie_rtd3_config
*rtd3_config
;
65 rtd3_config
= config_of(config
->rtd3dev
);
66 if (rtd3_config
->use_rp_mutex
) {
67 snprintf(mutex_path
, sizeof(mutex_path
), "%s",
68 acpi_device_path_join(parent_dev
, RP_MUTEX_NAME
));
69 /* Acquire root port mutex in case FHRF is called directly and not called from _RST */
70 acpigen_write_acquire(mutex_path
, ACPI_MUTEX_NO_TIMEOUT
);
74 acpigen_get_tx_gpio(&config
->perst_gpio
);
75 acpigen_write_if_lequal_op_int(LOCAL0_OP
, 0);
77 if (wwan_fm350gl_get_rtd3_method_support(config
) &
78 ACPI_PCIE_RP_EMIT_L23
) {
79 acpigen_emit_namestring(acpi_device_path_join(parent_dev
,
82 /* assert PERST# pin */
83 acpigen_enable_tx_gpio(&config
->perst_gpio
);
85 acpigen_write_if_end(); /* If */
86 acpigen_write_sleep(FM350GL_TR2B
);
87 /* assert RESET# pin */
88 acpigen_enable_tx_gpio(&config
->reset_gpio
);
90 acpigen_write_if_lequal_op_int(ARG0_OP
, RESET_TYPE_WARM
);
92 acpigen_write_sleep(FM350GL_TBTG
);
97 acpigen_write_if_lequal_op_int(ARG0_OP
, RESET_TYPE_COLD
);
99 /* disable source clock */
100 if (wwan_fm350gl_get_rtd3_method_support(config
) &
101 ACPI_PCIE_RP_EMIT_SRCK
) {
102 acpigen_emit_namestring(acpi_device_path_join(
103 parent_dev
, "SRCK"));
104 acpigen_emit_byte(ZERO_OP
);
106 acpigen_write_sleep(FM350GL_TB2F
);
107 /* assert FCPO# pin */
108 acpigen_enable_tx_gpio(&config
->fcpo_gpio
);
109 acpigen_write_sleep(FM350GL_TFDI
);
111 acpigen_write_if_end(); /* If */
113 acpigen_pop_len(); /* Else */
115 if (rtd3_config
->use_rp_mutex
)
116 acpigen_write_release(mutex_path
);
118 acpigen_write_method_end(); /* Method */
122 * Generate second half reset flow (SHRF) method.
124 static void wwan_fm350gl_acpi_method_shrf(const struct device
*parent_dev
,
125 const struct drivers_wwan_fm_config
*config
)
127 acpigen_write_method_serialized("SHRF", 0);
129 char mutex_path
[128];
130 const struct soc_intel_common_block_pcie_rtd3_config
*rtd3_config
;
132 rtd3_config
= config_of(config
->rtd3dev
);
133 if (rtd3_config
->use_rp_mutex
) {
134 snprintf(mutex_path
, sizeof(mutex_path
), "%s",
135 acpi_device_path_join(parent_dev
, RP_MUTEX_NAME
));
136 /* Acquire root port mutex */
137 acpigen_write_acquire(mutex_path
, ACPI_MUTEX_NO_TIMEOUT
);
140 /* call rtd3 method to Disable ModPHY Power Gating. */
141 if (wwan_fm350gl_get_rtd3_method_support(config
) &
142 ACPI_PCIE_RP_EMIT_PSD0
) {
143 acpigen_emit_namestring(acpi_device_path_join(parent_dev
,
146 /* call rtd3 method to Enable SRC Clock. */
147 if (wwan_fm350gl_get_rtd3_method_support(config
) &
148 ACPI_PCIE_RP_EMIT_SRCK
) {
149 acpigen_emit_namestring(acpi_device_path_join(parent_dev
,
151 acpigen_emit_byte(ONE_OP
);
153 /* De-assert FCPO# GPIO. */
154 acpigen_disable_tx_gpio(&config
->fcpo_gpio
);
155 acpigen_write_sleep(FM350GL_TN2B
);
156 /* De-assert RESET# GPIO. */
157 acpigen_disable_tx_gpio(&config
->reset_gpio
);
158 acpigen_write_sleep(FM350GL_TB2R
);
159 /* De-assert PERST# GPIO. */
160 acpigen_disable_tx_gpio(&config
->perst_gpio
);
161 /* Call rtd3 method to trigger L2/L3 ready exit flow in root port */
162 if (wwan_fm350gl_get_rtd3_method_support(config
) &
163 ACPI_PCIE_RP_EMIT_L23
) {
164 acpigen_emit_namestring(acpi_device_path_join(parent_dev
,
167 acpigen_write_sleep(FM350GL_TIME_HW_INIT
);
169 if (rtd3_config
->use_rp_mutex
)
170 acpigen_write_release(mutex_path
);
172 acpigen_write_method_end(); /* Method */
176 * Generate _RST method. This is to perform a soft reset. It is added under
177 * PXSX. This is called during device driver removal.
179 static void wwan_fm350gl_acpi_method_rst(const struct device
*parent_dev
,
180 const struct drivers_wwan_fm_config
*config
)
182 acpigen_write_method_serialized("_RST", 0);
184 char mutex_path
[128];
185 const struct soc_intel_common_block_pcie_rtd3_config
*rtd3_config
;
187 rtd3_config
= config_of(config
->rtd3dev
);
188 if (rtd3_config
->use_rp_mutex
) {
189 snprintf(mutex_path
, sizeof(mutex_path
), "%s",
190 acpi_device_path_join(parent_dev
, RP_MUTEX_NAME
));
191 /* Acquire root port mutex */
192 acpigen_write_acquire(mutex_path
, ACPI_MUTEX_NO_TIMEOUT
);
195 /* Perform 1st Half of FLDR Flow for soft reset: FHRF(0) */
196 acpigen_emit_namestring("FHRF");
197 acpigen_emit_byte(RESET_TYPE_WARM
);
198 /* Perform 2nd Half of FLDR Flow: SHRF() */
199 acpigen_emit_namestring("SHRF");
200 /* Indicates that the following _Off will be skipped. */
201 acpigen_emit_byte(INCREMENT_OP
);
202 acpigen_emit_namestring(acpi_device_path_join(parent_dev
, "RTD3.OFSK"));
204 if (rtd3_config
->use_rp_mutex
)
205 acpigen_write_release(mutex_path
);
207 acpigen_write_method_end(); /* Method */
211 * Generate _RST method. This is to perform a cold reset. This reset will be
212 * included under PXSX.MRST. This method is used during device firmware update.
214 static void wwan_fm350gl_acpi_method_mrst_rst(const struct device
*parent_dev
,
215 const struct drivers_wwan_fm_config
*config
)
217 acpigen_write_method_serialized("_RST", 0);
219 char mutex_path
[128];
220 const struct soc_intel_common_block_pcie_rtd3_config
*rtd3_config
;
222 rtd3_config
= config_of(config
->rtd3dev
);
223 if (rtd3_config
->use_rp_mutex
) {
224 snprintf(mutex_path
, sizeof(mutex_path
), "%s",
225 acpi_device_path_join(parent_dev
, RP_MUTEX_NAME
));
226 /* Acquire root port mutex */
227 acpigen_write_acquire(mutex_path
, ACPI_MUTEX_NO_TIMEOUT
);
230 /* Perform 1st Half of FLDR Flow for cold reset: FHRF (1) */
231 acpigen_emit_namestring("FHRF");
232 acpigen_emit_byte(RESET_TYPE_COLD
);
233 /* Perform 2nd Half of FLDR Flow: SHRF () */
234 acpigen_emit_namestring("SHRF");
235 /* Indicate kernel ACPI PM to skip _off RTD3 after reset at the end of
237 acpigen_emit_byte(INCREMENT_OP
);
238 acpigen_emit_namestring(acpi_device_path_join(parent_dev
, "RTD3.OFSK"));
240 if (rtd3_config
->use_rp_mutex
)
241 acpigen_write_release(mutex_path
);
243 acpigen_write_method_end(); /* Method */
247 * Generate DPTS (Device Prepare To Seep) Method. This is called in
250 static void wwan_fm350gl_acpi_method_dpts(const struct device
*parent_dev
,
251 const struct drivers_wwan_fm_config
*config
)
253 acpigen_write_method_serialized("DPTS", 1);
255 /* Perform 1st Half of FLDR Flow for cold reset: FHRF (1) */
256 acpigen_emit_namestring("FHRF");
257 acpigen_emit_byte(RESET_TYPE_COLD
);
259 acpigen_write_method_end(); /* Method */
262 static const char *wwan_fm350gl_acpi_name(const struct device
*dev
)
264 /* Attached device name must be "PXSX" for the Linux Kernel to recognize it. */
269 wwan_fm350gl_acpi_event_interrupts(const struct acpi_gpio
*wake_gpio
)
271 acpigen_write_name("_AEI");
272 acpigen_write_resourcetemplate_header();
273 acpi_device_write_gpio(wake_gpio
);
274 acpigen_write_resourcetemplate_footer();
278 wwan_fm350gl_acpi_event_method(const struct device
*dev
,
279 const struct acpi_gpio
*wake_gpio
)
284 pin
= wake_gpio
->pins
[0];
285 if (CONFIG(GENERIC_GPIO_LIB
))
286 pin
= gpio_acpi_pin(pin
);
289 printk(BIOS_ERR
, "%s: pins above 0xFF are unsupported (pin %u)\n",
294 snprintf(name
, sizeof(name
), "_%c%02X",
295 wake_gpio
->irq
.mode
== ACPI_IRQ_EDGE_TRIGGERED
? 'E' : 'L', pin
);
297 acpigen_write_method_serialized(name
, 0);
298 acpigen_notify(acpi_device_path(dev
), 0x02); /* NOTIFY_DEVICE_WAKE */
299 acpigen_write_method_end();
302 static void wwan_fm350gl_acpi_gpio_events(const struct device
*dev
)
304 const struct drivers_wwan_fm_config
*config
= config_of(dev
);
305 const struct acpi_gpio
*wake_gpio
= &config
->wake_gpio
;
307 /* Write into GPIO controller's scope */
308 if (CONFIG(GENERIC_GPIO_LIB
))
309 acpigen_write_scope(wake_gpio
->resource
? : gpio_acpi_path(wake_gpio
->pins
[0]));
311 acpigen_write_scope(wake_gpio
->resource
);
312 wwan_fm350gl_acpi_event_interrupts(wake_gpio
);
313 wwan_fm350gl_acpi_event_method(dev
, wake_gpio
);
314 acpigen_write_scope_end();
317 static void wwan_fm350gl_acpi_fill_ssdt(const struct device
*dev
)
319 const struct drivers_wwan_fm_config
*config
= config_of(dev
);
320 const struct device
*parent
= dev
->upstream
->dev
;
321 const char *scope
= acpi_device_path(parent
);
322 const struct soc_intel_common_block_pcie_rtd3_config
*rtd3_config
;
324 if (!is_dev_enabled(parent
)) {
325 printk(BIOS_ERR
, "%s: root port not enabled\n", __func__
);
329 printk(BIOS_ERR
, "%s: root port scope not found\n", __func__
);
332 if (!config
->fcpo_gpio
.pin_count
&& !config
->reset_gpio
.pin_count
&&
333 !config
->perst_gpio
.pin_count
) {
334 printk(BIOS_ERR
, "%s: FCPO, RESET, PERST GPIO required for %s.\n",
339 rtd3_config
= config_of(config
->rtd3dev
);
340 if (!rtd3_config
->use_rp_mutex
)
341 printk(BIOS_WARNING
, "%s: RTD3 must use root port mutex.\n",
344 printk(BIOS_INFO
, "%s: Enable WWAN for %s (%s)\n", scope
, dev_path(parent
),
345 config
->desc
?: dev
->chip_ops
->name
);
346 acpigen_write_scope(scope
);
348 acpigen_write_device(wwan_fm350gl_acpi_name(dev
));
350 acpigen_write_ADR(0);
352 acpigen_write_name_string("_DDN", config
->name
);
354 acpigen_write_name_unicode("_STR", config
->desc
);
355 wwan_fm350gl_acpi_method_fhrf(parent
, config
);
356 wwan_fm350gl_acpi_method_shrf(parent
, config
);
357 wwan_fm350gl_acpi_method_rst(parent
, config
);
358 wwan_fm350gl_acpi_method_dpts(parent
, config
);
360 if (config
->add_acpi_dma_property
)
361 acpi_device_add_dma_property(NULL
);
363 /* NOTE: the 5G driver will call MRST._RST to trigger a cold reset
364 * during firmware update.
366 acpigen_write_device("MRST");
368 acpigen_write_ADR(0);
369 wwan_fm350gl_acpi_method_mrst_rst(parent
, config
);
372 acpigen_write_device_end(); /* Device */
374 acpigen_write_device_end(); /* Device */
376 acpigen_write_scope_end(); /* Scope */
378 if (config
->wake_gpio
.pin_count
&& config
->wake_gpio
.type
== ACPI_GPIO_TYPE_INTERRUPT
)
379 wwan_fm350gl_acpi_gpio_events(dev
);
382 static struct device_operations wwan_fm350gl_ops
= {
383 .read_resources
= noop_read_resources
,
384 .set_resources
= noop_set_resources
,
385 .acpi_fill_ssdt
= wwan_fm350gl_acpi_fill_ssdt
,
386 .acpi_name
= wwan_fm350gl_acpi_name
389 static void wwan_fm350gl_acpi_enable(struct device
*dev
)
391 dev
->ops
= &wwan_fm350gl_ops
;
394 struct chip_operations drivers_wwan_fm_ops
= {
395 .name
= "Fibocom FM-350-GL",
396 .enable_dev
= wwan_fm350gl_acpi_enable