11/* SPDX-License-Identifier: GPL-2.0-only */
22
3- #include "chip.h"
43#include <acpi/acpigen.h>
54#include <console/console.h>
65#include <delay.h>
98#include <device/pciexp.h>
109#include <device/pci_ids.h>
1110#include <timer.h>
11+ #include "chip.h"
12+ #include "dtbt.h"
13+
1214
13- #define PCIE2TBT 0x54C
14- #define PCIE2TBT_VALID BIT(0)
15- #define PCIE2TBT_GO2SX 2
16- #define PCIE2TBT_GO2SX_NO_WAKE 3
17- #define PCIE2TBT_SX_EXIT_TBT_CONNECTED 4
18- #define PCIE2TBT_OS_UP 6
19- #define PCIE2TBT_SET_SECURITY_LEVEL 8
20- #define PCIE2TBT_GET_SECURITY_LEVEL 9
21- #define PCIE2TBT_BOOT_ON 24
22- #define PCIE2TBT_USB_ON 25
23- #define PCIE2TBT_GET_ENUMERATION_METHOD 26
24- #define PCIE2TBT_SET_ENUMERATION_METHOD 27
25- #define PCIE2TBT_POWER_CYCLE 28
26- #define PCIE2TBT_SX_START 29
27- #define PCIE2TBT_ACL_BOOT 30
28- #define PCIE2TBT_CONNECT_TOPOLOGY 31
29-
30- #define TBT2PCIE 0x548
31- #define TBT2PCIE_DONE BIT(0)
32-
33- // Default timeout for mailbox commands unless otherwise specified.
34- #define TIMEOUT_MS 1000
35- // Default timeout for controller to ack GO2SX/GO2SX_NO_WAKE mailbox command.
36- #define GO2SX_TIMEOUT_MS 600
15+ /*
16+ * We only want to enable the first/primary bridge device,
17+ * as sending mailbox commands to secondary ones will fail,
18+ * and we only want to create a single ACPI device in the SSDT.
19+ */
20+ static bool enable_done ;
21+ static bool ssdt_done ;
3722
3823static void dtbt_cmd (struct device * dev , u32 command , u32 data , u32 timeout )
3924{
4025 u32 reg = (data << 8 ) | (command << 1 ) | PCIE2TBT_VALID ;
4126 u32 status ;
4227
43- printk (BIOS_DEBUG , "dTBT send command %08x\n" , command );
28+ printk (BIOS_SPEW , "dTBT send command 0x%x\n" , command );
29+ /* Send command */
4430 pci_write_config32 (dev , PCIE2TBT , reg );
45-
46- if (!wait_ms (timeout , (status = pci_read_config32 (dev , TBT2PCIE )) & TBT2PCIE_DONE )) {
47- printk (BIOS_ERR , "dTBT command %08x send timeout %08x\n" , command , status );
48- }
49-
31+ /* Wait for done bit to be cleared */
32+ if (!wait_ms (timeout , (status = pci_read_config32 (dev , TBT2PCIE )) & TBT2PCIE_DONE ))
33+ printk (BIOS_ERR , "dTBT command 0x%x send timeout, status 0x%x\n" , command , status );
34+ /* Clear valid bit */
5035 pci_write_config32 (dev , PCIE2TBT , 0 );
51- if (! wait_ms ( timeout , !( pci_read_config32 ( dev , TBT2PCIE ) & TBT2PCIE_DONE ))) {
52- printk ( BIOS_ERR , "dTBT command %08x clear timeout\n" , command );
53- }
36+ /* Wait for done bit to be cleared */
37+ if (! wait_ms ( timeout , ( status = pci_read_config32 ( dev , TBT2PCIE )) & TBT2PCIE_DONE ))
38+ printk ( BIOS_ERR , "dTBT command 0x%x clear valid bit timeout, status 0x%x\n" , command , status );
5439}
5540
5641static void dtbt_write_dsd (void )
@@ -86,14 +71,17 @@ static void dtbt_fill_ssdt(const struct device *dev)
8671 const char * parent_scope ;
8772 const char * dev_name = acpi_device_name (dev );
8873
74+ if (ssdt_done )
75+ return ;
76+
8977 bus = dev -> upstream ;
9078 if (!bus ) {
9179 printk (BIOS_ERR , "dTBT bus invalid\n" );
9280 return ;
9381 }
9482
9583 parent = bus -> dev ;
96- if (!parent || parent -> path . type != DEVICE_PATH_PCI ) {
84+ if (!parent || ! is_pci ( parent ) ) {
9785 printk (BIOS_ERR , "dTBT parent invalid\n" );
9886 return ;
9987 }
@@ -113,7 +101,7 @@ static void dtbt_fill_ssdt(const struct device *dev)
113101 acpigen_write_name_integer ("_ADR" , 0 );
114102 dtbt_write_opregion (bus );
115103
116- /* Method */
104+ /* PTS Method */
117105 acpigen_write_method_serialized ("PTS" , 0 );
118106
119107 acpigen_write_debug_string ("dTBT prepare to sleep" );
@@ -129,26 +117,49 @@ static void dtbt_fill_ssdt(const struct device *dev)
129117 acpigen_write_device_end ();
130118 acpigen_write_scope_end ();
131119
132- printk (BIOS_DEBUG , "dTBT fill SSDT\n" );
133- printk (BIOS_DEBUG , " Dev %s\n" , dev_path (dev ));
134- //printk(BIOS_DEBUG, " Bus %s\n", bus_path(bus));
135- printk (BIOS_DEBUG , " Parent %s\n" , dev_path (parent ));
136- printk (BIOS_DEBUG , " Scope %s\n" , parent_scope );
137- printk (BIOS_DEBUG , " Device %s\n" , dev_name );
138-
139120 // \.TBTS Method
140121 acpigen_write_scope ("\\" );
141122 acpigen_write_method ("TBTS" , 0 );
142123 acpigen_emit_namestring (acpi_device_path_join (dev , "PTS" ));
143124 acpigen_write_method_end ();
144125 acpigen_write_scope_end ();
126+
127+ printk (BIOS_INFO , "%s.%s %s\n" , parent_scope , dev_name , dev_path (dev ));
128+ ssdt_done = true;
145129}
146130
147131static const char * dtbt_acpi_name (const struct device * dev )
148132{
149133 return "DTBT" ;
150134}
151135
136+ static void dtbt_enable (struct device * dev )
137+ {
138+ if (!is_dev_enabled (dev ) || enable_done )
139+ return ;
140+
141+ printk (BIOS_INFO , "dTBT controller found at %s\n" , dev_path (dev ));
142+
143+ // XXX: Recommendation is to set SL1 ("User Authorization")
144+ printk (BIOS_DEBUG , "dTBT set security level SL0\n" );
145+ /* Set security level */
146+ dtbt_cmd (dev , PCIE2TBT_SET_SECURITY_LEVEL , SEC_LEVEL_NONE , MBOX_TIMEOUT_MS );
147+
148+ if (acpi_is_wakeup_s3 ()) {
149+ printk (BIOS_DEBUG , "dTBT SX exit\n" );
150+ dtbt_cmd (dev , PCIE2TBT_SX_EXIT_TBT_CONNECTED , 0 , MBOX_TIMEOUT_MS );
151+ /* Read TBT2PCIE register, verify not invalid */
152+ if (pci_read_config32 (dev , TBT2PCIE ) == 0xffffffff )
153+ printk (BIOS_ERR , "dTBT S3 resume failure.\n" );
154+ } else {
155+ printk (BIOS_DEBUG , "dTBT set boot on\n" );
156+ dtbt_cmd (dev , PCIE2TBT_BOOT_ON , 0 , MBOX_TIMEOUT_MS );
157+ printk (BIOS_DEBUG , "dTBT set USB on\n" );
158+ dtbt_cmd (dev , PCIE2TBT_USB_ON , 0 , MBOX_TIMEOUT_MS );
159+ }
160+ enable_done = true;
161+ }
162+
152163static struct pci_operations dtbt_device_ops_pci = {
153164 .set_subsystem = 0 ,
154165};
@@ -162,38 +173,30 @@ static struct device_operations dtbt_device_ops = {
162173 .scan_bus = pciexp_scan_bridge ,
163174 .reset_bus = pci_bus_reset ,
164175 .ops_pci = & dtbt_device_ops_pci ,
176+ .enable = dtbt_enable
165177};
166178
167- static void dtbt_enable (struct device * dev )
168- {
169- if (!is_dev_enabled (dev ) || dev -> path .type != DEVICE_PATH_PCI )
170- return ;
171-
172- if (pci_read_config16 (dev , PCI_VENDOR_ID ) != PCI_VID_INTEL )
173- return ;
174-
175- // TODO: check device ID
176-
177- dev -> ops = & dtbt_device_ops ;
178-
179- printk (BIOS_INFO , "dTBT controller found at %s\n" , dev_path (dev ));
180-
181- // XXX: Recommendation is to set SL1 ("User Authorization")
182- printk (BIOS_DEBUG , "dTBT set security level SL0\n" );
183- dtbt_cmd (dev , PCIE2TBT_SET_SECURITY_LEVEL , 0 , TIMEOUT_MS );
184- // XXX: Must verify change or rollback all controllers
179+ /* We only want to match the (first) bridge device */
180+ static const unsigned short pci_device_ids [] = {
181+ AR_2C_BRG ,
182+ AR_4C_BRG ,
183+ AR_LP_BRG ,
184+ AR_4C_C0_BRG ,
185+ AR_2C_C0_BRG ,
186+ TR_2C_BRG ,
187+ TR_4C_BRG ,
188+ TR_4C_BRG ,
189+ MR_2C_BRG ,
190+ MR_4C_BRG ,
191+ 0
192+ };
185193
186- if (acpi_is_wakeup_s3 ()) {
187- printk (BIOS_DEBUG , "dTBT SX exit\n" );
188- dtbt_cmd (dev , PCIE2TBT_SX_EXIT_TBT_CONNECTED , 0 , TIMEOUT_MS );
189- // TODO: "wait for fast link bring-up" loop (timeout: 5s)
190- } else {
191- printk (BIOS_DEBUG , "dTBT boot on\n" );
192- dtbt_cmd (dev , PCIE2TBT_BOOT_ON , 0 , TIMEOUT_MS );
193- }
194- }
194+ static const struct pci_driver intel_dtbt_driver __pci_driver = {
195+ .ops = & dtbt_device_ops ,
196+ .vendor = PCI_VID_INTEL ,
197+ .devices = pci_device_ids ,
198+ };
195199
196200struct chip_operations drivers_intel_dtbt_ops = {
197201 .name = "Intel Discrete Thunderbolt" ,
198- .enable_dev = dtbt_enable ,
199202};
0 commit comments