coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
acpi_fm350gl.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <acpi/acpigen.h>
4 #include <acpi/acpi_device.h>
5 #include "chip.h"
7 
8 /* FCPO# to RESET# delay time during WWAN ON */
9 #define FM350GL_TN2B 20
10 /* RESET# to PERST# delay time during WWAN ON */
11 #define FM350GL_TB2R 80
12 /* The delay between de-assertion of PERST# to change of PDS state from 0 to 1 during WWAN ON */
13 #define FM350GL_TR2P 0
14 /* RESET# to FCPO# delay time during WWAN OFF */
15 #define FM350GL_TB2F 10
16 /* Time to allow the WWAN module to fully discharge any residual voltages before FCPO# could be
17  de-asserted again. */
18 #define FM350GL_TFDI 500
19 /* The delay between assertion and de-assertion RESET# during FLDR */
20 #define FM350GL_TBTG 10
21 /* The delay between de-assertion of RESET# and change of PDS state from 0 to 1 after FLDR */
22 #define FM350GL_TBTP 170
23 /* PERST# to RESET# delay time during WWAN OFF */
24 #define FM350GL_TR2B 10
25 /* 20s HW initialization needed after de-assertion of PERST#
26  However, it is not required and is not proper place to ensure HW initialization in ACPI. The
27  delay here is to ensure the following reset or RTD3 _OFF method won't be called immediately.
28  */
29 #define FM350GL_TIME_HW_INIT 100
30 
31 enum reset_type {
33  RESET_TYPE_COLD = 1
34 };
35 
36 /*
37  * Returns the RTD3 PM methods requested and available to the device.
38  */
39 static enum acpi_pcie_rp_pm_emit
41 {
42  const struct soc_intel_common_block_pcie_rtd3_config *rtd3_config;
43 
44  rtd3_config = config_of(config->rtd3dev);
45 
46  return rtd3_config->ext_pm_support;
47 }
48 
49 /*
50  * Generate first half reset flow (FHRF) method.
51  * Arg0 = RESET_TYPE_WARM: warm reset
52  * Arg0 = 1RESET_TYPE_COLD: cold reset
53  */
54 static void wwan_fm350gl_acpi_method_fhrf(const struct device *parent_dev,
55  const struct drivers_wwan_fm_config *config)
56 {
58  {
59  /* LOCAL0 = PERST# */
60  acpigen_get_tx_gpio(&config->perst_gpio);
62  {
66  "DL23"));
67  }
68  /* assert PERST# pin */
69  acpigen_enable_tx_gpio(&config->perst_gpio);
70  }
71  acpigen_write_if_end(); /* If */
73  /* assert RESET# pin */
74  acpigen_enable_tx_gpio(&config->reset_gpio);
75  /* warm reset */
77  {
79  }
80  /* cold reset */
82  {
84  {
85  /* disable source clock */
89  parent_dev, "SRCK"));
91  }
93  /* assert FCPO# pin */
94  acpigen_enable_tx_gpio(&config->fcpo_gpio);
96  }
97  acpigen_write_if_end(); /* If */
98  }
99  acpigen_pop_len(); /* Else */
100  }
101  acpigen_write_method_end(); /* Method */
102 }
103 
104 /*
105  * Generate second half reset flow (SHRF) method.
106  */
107 static void wwan_fm350gl_acpi_method_shrf(const struct device *parent_dev,
108  const struct drivers_wwan_fm_config *config)
109 {
111  {
112  /* call rtd3 method to Disable ModPHY Power Gating. */
116  "PSD0"));
117  }
118  /* call rtd3 method to Enable SRC Clock. */
122  "SRCK"));
124  }
125  /* De-assert FCPO# GPIO. */
126  acpigen_disable_tx_gpio(&config->fcpo_gpio);
128  /* De-assert RESET# GPIO. */
129  acpigen_disable_tx_gpio(&config->reset_gpio);
131  /* De-assert PERST# GPIO. */
132  acpigen_disable_tx_gpio(&config->perst_gpio);
133  /* Call rtd3 method to trigger L2/L3 ready exit flow in root port */
137  "L23D"));
138  }
140  }
141  acpigen_write_method_end(); /* Method */
142 }
143 
144 /*
145  * Generate _RST method. This is to perform a soft reset. It is added under
146  * PXSX. This is called during device driver removal.
147  */
148 static void wwan_fm350gl_acpi_method_rst(const struct device *parent_dev,
149  const struct drivers_wwan_fm_config *config)
150 {
152  {
153  /* Perform 1st Half of FLDR Flow for soft reset: FHRF(0) */
154  acpigen_emit_namestring("FHRF");
156  /* Perform 2nd Half of FLDR Flow: SHRF() */
157  acpigen_emit_namestring("SHRF");
158  /* Indicates that the following _Off will be skipped. */
160  acpigen_emit_namestring(acpi_device_path_join(parent_dev, "RTD3.OFSK"));
161  }
162  acpigen_write_method_end(); /* Method */
163 }
164 
165 /*
166  * Generate _RST method. This is to perform a cold reset. This reset will be
167  * included under PXSX.MRST. This method is used during device firmware update.
168  */
169 static void wwan_fm350gl_acpi_method_mrst_rst(const struct device *parent_dev,
170  const struct drivers_wwan_fm_config *config)
171 {
173  {
174  /* Perform 1st Half of FLDR Flow for cold reset: FHRF (1) */
175  acpigen_emit_namestring("FHRF");
177  /* Perform 2nd Half of FLDR Flow: SHRF () */
178  acpigen_emit_namestring("SHRF");
179  /* Indicate kernel ACPI PM to skip _off RTD3 after reset at the end of
180  driver removal */
182  acpigen_emit_namestring(acpi_device_path_join(parent_dev, "RTD3.OFSK"));
183  }
184  acpigen_write_method_end(); /* Method */
185 }
186 
187 /*
188  * Generate DPTS (Device Prepare To Seep) Method. This is called in
189  * \.SB.MPTS Method.
190  */
191 static void wwan_fm350gl_acpi_method_dpts(const struct device *parent_dev,
192  const struct drivers_wwan_fm_config *config)
193 {
195  {
196  /* Perform 1st Half of FLDR Flow for cold reset: FHRF (1) */
197  acpigen_emit_namestring("FHRF");
199  }
200  acpigen_write_method_end(); /* Method */
201 }
202 
203 static const char *wwan_fm350gl_acpi_name(const struct device *dev)
204 {
205  /* Attached device name must be "PXSX" for the Linux Kernel to recognize it. */
206  return "PXSX";
207 }
208 
209 static void wwan_fm350gl_acpi_fill_ssdt(const struct device *dev)
210 {
211  const struct drivers_wwan_fm_config *config = config_of(dev);
212  const struct device *parent = dev->bus->dev;
213  const char *scope = acpi_device_path(parent);
214 
215  if (!is_dev_enabled(parent)) {
216  printk(BIOS_ERR, "%s: root port not enabled\n", __func__);
217  return;
218  }
219  if (!scope) {
220  printk(BIOS_ERR, "%s: root port scope not found\n", __func__);
221  return;
222  }
223  if (!config->fcpo_gpio.pin_count && !config->reset_gpio.pin_count &&
224  !config->perst_gpio.pin_count) {
225  printk(BIOS_ERR, "%s: FCPO, RESET, PERST GPIO required for %s.\n",
226  __func__, scope);
227  return;
228  }
229  printk(BIOS_INFO, "%s: Enable WWAN for %s (%s)\n", scope, dev_path(parent),
230  config->desc ?: dev->chip_ops->name);
231  acpigen_write_scope(scope);
232  {
234  {
236  if (config->name)
237  acpigen_write_name_string("_DDN", config->name);
238  if (config->desc)
239  acpigen_write_name_unicode("_STR", config->desc);
244 
245  if (config->add_acpi_dma_property) {
246  struct acpi_dp *dsd;
247  dsd = acpi_dp_new_table("_DSD");
248  acpi_dp_add_integer(dsd, "DmaProperty", 1);
249  acpi_dp_write(dsd);
250  }
251 
252  /* NOTE: the 5G driver will call MRST._RST to trigger a cold reset
253  * during firmware update.
254  */
255  acpigen_write_device("MRST");
256  {
259  }
260 
261  acpigen_write_device_end(); /* Device */
262  }
263  acpigen_write_device_end(); /* Device */
264  }
265  acpigen_write_scope_end(); /* Scope */
266 }
267 
268 static struct device_operations wwan_fm350gl_ops = {
270  .set_resources = noop_set_resources,
271  .acpi_fill_ssdt = wwan_fm350gl_acpi_fill_ssdt,
272  .acpi_name = wwan_fm350gl_acpi_name
273 };
274 
275 static void wwan_fm350gl_acpi_enable(struct device *dev)
276 {
277  dev->ops = &wwan_fm350gl_ops;
278 }
279 
281  CHIP_NAME("Fibocom FM-350-GL")
282  .enable_dev = wwan_fm350gl_acpi_enable
283 };
const char * acpi_device_path_join(const struct device *dev, const char *name)
Definition: device.c:172
const char * acpi_device_path(const struct device *dev)
Definition: device.c:144
struct acpi_dp * acpi_dp_add_integer(struct acpi_dp *dp, const char *name, uint64_t value)
Definition: device.c:977
void acpi_dp_write(struct acpi_dp *table)
Definition: device.c:898
struct acpi_dp * acpi_dp_new_table(const char *name)
Definition: device.c:930
static void wwan_fm350gl_acpi_method_rst(const struct device *parent_dev, const struct drivers_wwan_fm_config *config)
Definition: acpi_fm350gl.c:148
static void wwan_fm350gl_acpi_method_shrf(const struct device *parent_dev, const struct drivers_wwan_fm_config *config)
Definition: acpi_fm350gl.c:107
#define FM350GL_TR2B
Definition: acpi_fm350gl.c:24
reset_type
Definition: acpi_fm350gl.c:31
@ RESET_TYPE_COLD
Definition: acpi_fm350gl.c:33
@ RESET_TYPE_WARM
Definition: acpi_fm350gl.c:32
#define FM350GL_TN2B
Definition: acpi_fm350gl.c:9
#define FM350GL_TIME_HW_INIT
Definition: acpi_fm350gl.c:29
#define FM350GL_TFDI
Definition: acpi_fm350gl.c:18
static void wwan_fm350gl_acpi_enable(struct device *dev)
Definition: acpi_fm350gl.c:275
static void wwan_fm350gl_acpi_method_dpts(const struct device *parent_dev, const struct drivers_wwan_fm_config *config)
Definition: acpi_fm350gl.c:191
static enum acpi_pcie_rp_pm_emit wwan_fm350gl_get_rtd3_method_support(const struct drivers_wwan_fm_config *config)
Definition: acpi_fm350gl.c:40
struct chip_operations drivers_wwan_fm_ops
Definition: acpi_fm350gl.c:280
static void wwan_fm350gl_acpi_fill_ssdt(const struct device *dev)
Definition: acpi_fm350gl.c:209
#define FM350GL_TB2R
Definition: acpi_fm350gl.c:11
static const char * wwan_fm350gl_acpi_name(const struct device *dev)
Definition: acpi_fm350gl.c:203
static void wwan_fm350gl_acpi_method_fhrf(const struct device *parent_dev, const struct drivers_wwan_fm_config *config)
Definition: acpi_fm350gl.c:54
#define FM350GL_TBTG
Definition: acpi_fm350gl.c:20
static struct device_operations wwan_fm350gl_ops
Definition: acpi_fm350gl.c:268
#define FM350GL_TB2F
Definition: acpi_fm350gl.c:15
static void wwan_fm350gl_acpi_method_mrst_rst(const struct device *parent_dev, const struct drivers_wwan_fm_config *config)
Definition: acpi_fm350gl.c:169
void acpigen_write_ADR(uint64_t adr)
Definition: acpigen.c:2122
void acpigen_emit_namestring(const char *namepath)
Definition: acpigen.c:275
void acpigen_pop_len(void)
Definition: acpigen.c:37
void acpigen_write_scope(const char *name)
Definition: acpigen.c:326
int acpigen_disable_tx_gpio(const struct acpi_gpio *gpio)
Definition: acpigen.c:2023
void acpigen_write_if_lequal_op_int(uint8_t op, uint64_t val)
Definition: acpigen.c:1472
void acpigen_write_sleep(uint64_t sleep_ms)
Definition: acpigen.c:1327
void acpigen_write_method_serialized(const char *name, int nargs)
Definition: acpigen.c:764
void acpigen_emit_byte(unsigned char b)
Definition: acpigen.c:61
void acpigen_write_name_unicode(const char *name, const char *string)
Definition: acpigen.c:182
void acpigen_write_device(const char *name)
Definition: acpigen.c:769
int acpigen_enable_tx_gpio(const struct acpi_gpio *gpio)
Definition: acpigen.c:2015
void acpigen_write_else(void)
Definition: acpigen.c:1510
void acpigen_write_name_string(const char *name, const char *string)
Definition: acpigen.c:176
void acpigen_get_tx_gpio(const struct acpi_gpio *gpio)
Definition: acpigen.c:2039
#define printk(level,...)
Definition: stdlib.h:16
bool is_dev_enabled(const struct device *dev)
Definition: device_const.c:369
const char * dev_path(const struct device *dev)
Definition: device_util.c:149
@ ARG0_OP
Definition: acpigen.h:89
@ LOCAL0_OP
Definition: acpigen.h:81
@ ZERO_OP
Definition: acpigen.h:30
@ ONE_OP
Definition: acpigen.h:31
@ INCREMENT_OP
Definition: acpigen.h:101
void acpigen_write_device_end(void)
Definition: acpigen.h:354
void acpigen_write_method_end(void)
Definition: acpigen.h:349
void acpigen_write_scope_end(void)
Definition: acpigen.h:343
void acpigen_write_if_end(void)
Definition: acpigen.h:431
#define CHIP_NAME(X)
Definition: device.h:32
static void noop_read_resources(struct device *dev)
Standard device operations function pointers shims.
Definition: device.h:73
static void noop_set_resources(struct device *dev)
Definition: device.h:74
static DEVTREE_CONST void * config_of(const struct device *dev)
Definition: device.h:382
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
enum board_config config
Definition: memory.c:448
acpi_pcie_rp_pm_emit
Definition: chip.h:8
@ ACPI_PCIE_RP_EMIT_PSD0
Definition: chip.h:11
@ ACPI_PCIE_RP_EMIT_L23
Definition: chip.h:10
@ ACPI_PCIE_RP_EMIT_SRCK
Definition: chip.h:12
DEVTREE_CONST struct device * dev
Definition: device.h:78
const char * name
Definition: device.h:29
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107
struct chip_operations * chip_ops
Definition: device.h:144
struct device_operations * ops
Definition: device.h:143
DEVTREE_CONST struct bus * bus
Definition: device.h:108
enum acpi_pcie_rp_pm_emit ext_pm_support
Definition: chip.h:78