Skip to content

Commit 0704464

Browse files
committed
[TAINTED] usb: use HPM SPMI transport when needed
revert AsahiLinux#365 (+ part of AsahiLinux#508) and instead use the appropriate transport as necessary
1 parent 01a668b commit 0704464

File tree

2 files changed

+60
-30
lines changed

2 files changed

+60
-30
lines changed

proxyclient/m1n1/hv/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,7 @@ def setup_adt(self):
16301630
"/arm-io/i2c0/hpmBusManager1/hpm%d",
16311631
"/arm-io/i2c3/hpmBusManager0/hpm%d",
16321632
"/arm-io/nub-spmi-a0/hpm%d",
1633+
"/arm-io/nub-spmi-a1/hpm%d",
16331634
"/arm-io/atc%d-dpxbar",
16341635
"/arm-io/atc%d-dpphy",
16351636
"/arm-io/atc%d-dpin0",

src/usb.c

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "adt.h"
55
#include "dart.h"
66
#include "i2c.h"
7+
#include "spmi.h"
78
#include "iodev.h"
89
#include "malloc.h"
910
#include "pmgr.h"
@@ -33,6 +34,7 @@ struct usb_drd_regs {
3334
#define FMT_DRD_PATH "/arm-io/usb-drd%u"
3435
// HPM_PATH string is at most
3536
// "/arm-io/i2cX" (12) + "/" + hpmBusManagerX (14) + "/" + "hpmX" (4) + '\0'
37+
// "/arm-io/nub-spmi-aX" (19) + "/" + "hpmX" (4) + '\0'
3638
#define MAX_HPM_PATH_LEN 40
3739

3840
static tps6598x_irq_state_t tps6598x_irq_state[USB_IODEV_COUNT];
@@ -231,14 +233,6 @@ struct iodev iodev_usb_vuart = {
231233
.lock = SPINLOCK_INIT,
232234
};
233235

234-
void usb_spmi_init(void)
235-
{
236-
for (int idx = 0; idx < USB_IODEV_COUNT; ++idx)
237-
usb_phy_bringup(idx); /* Fails on missing devices, just continue */
238-
239-
usb_is_initialized = true;
240-
}
241-
242236
typedef void(*hpm_callback_t)(tps6598x_dev_t *tps, u32 idx, void *data);
243237

244238
static int hpm_index(const char *name)
@@ -297,6 +291,41 @@ static int hpm_for_each_in_i2c_bus(const char *i2c_path, hpm_callback_t cb, void
297291
return 0;
298292
}
299293

294+
static int hpm_for_each_in_spmi_bus(const char *spmi_path, hpm_callback_t cb, void *data)
295+
{
296+
char hpm_path[MAX_HPM_PATH_LEN];
297+
298+
int node = adt_path_offset(adt, spmi_path);
299+
if (node < 0)
300+
return 0;
301+
302+
spmi_dev_t *spmi = spmi_init(spmi_path);
303+
if (!spmi) {
304+
printf("usb: spmi init failed for %s\n", spmi_path);
305+
return -1;
306+
}
307+
308+
ADT_FOREACH_CHILD(adt, node)
309+
{
310+
const char *name = adt_get_name(adt, node);
311+
int idx = hpm_index(name);
312+
if (idx < 0) continue;
313+
snprintf(hpm_path, sizeof(hpm_path), "%s/%s", spmi_path, name);
314+
315+
tps6598x_dev_t *tps = tps6598x_init_spmi(hpm_path, spmi);
316+
if (!tps) {
317+
printf("usb: tps6598x_init_spmi failed for %s.\n", hpm_path);
318+
continue;
319+
}
320+
cb(tps, idx, data);
321+
tps6598x_shutdown(tps);
322+
}
323+
324+
spmi_shutdown(spmi);
325+
326+
return 0;
327+
}
328+
300329
static void hpm_init_callback(tps6598x_dev_t *tps, u32 idx, void *)
301330
{
302331
if (tps6598x_powerup(tps) < 0) {
@@ -331,15 +360,6 @@ void usb_init(void)
331360
if (usb_is_initialized)
332361
return;
333362

334-
/*
335-
* M3/M4 models do not use i2c, but instead SPMI with a new controller.
336-
* We can get USB going for now by just bringing up the phys.
337-
*/
338-
if (adt_path_offset(adt, "/arm-io/nub-spmi-a0/hpm0") > 0) {
339-
usb_spmi_init();
340-
return;
341-
}
342-
343363
/*
344364
* A7-A11 uses a custom internal otg controller with the peripheral part
345365
* being dwc2.
@@ -350,11 +370,21 @@ void usb_init(void)
350370
return;
351371
}
352372

353-
if (adt_is_compatible(adt, 0, "J180dAP"))
354-
if (hpm_for_each_in_i2c_bus("/arm-io/i2c3", hpm_init_callback, NULL) < 0)
373+
/*
374+
* M3/M4 models do not use i2c, but instead SPMI with a new controller.
375+
*/
376+
if (adt_path_offset(adt, "/arm-io/nub-spmi-a0/hpm0") > 0) {
377+
if (hpm_for_each_in_spmi_bus("/arm-io/nub-spmi-a0", hpm_init_callback, NULL) < 0)
355378
return;
356-
if (hpm_for_each_in_i2c_bus("/arm-io/i2c0", hpm_init_callback, NULL) < 0)
357-
return;
379+
if (hpm_for_each_in_spmi_bus("/arm-io/nub-spmi-a1", hpm_init_callback, NULL) < 0)
380+
return;
381+
} else {
382+
if (adt_is_compatible(adt, 0, "J180dAP"))
383+
if (hpm_for_each_in_i2c_bus("/arm-io/i2c3", hpm_init_callback, NULL) < 0)
384+
return;
385+
if (hpm_for_each_in_i2c_bus("/arm-io/i2c0", hpm_init_callback, NULL) < 0)
386+
return;
387+
}
358388

359389
for (int idx = 0; idx < USB_IODEV_COUNT; ++idx)
360390
usb_phy_bringup(idx); /* Fails on missing devices, just continue */
@@ -364,22 +394,21 @@ void usb_init(void)
364394

365395
void usb_hpm_restore_irqs(bool force)
366396
{
367-
/*
368-
* Do not try to restore irqs on M3/M4 which don't use i2c
369-
*/
370-
if (adt_path_offset(adt, "/arm-io/nub-spmi-a0/hpm0") > 0)
371-
return;
372-
373397
/*
374398
* Do not try to restore irqs on A7-A11 which don't use i2c
375399
*/
376400
if (adt_path_offset(adt, "/arm-io/otgphyctrl") > 0 &&
377401
adt_path_offset(adt, "/arm-io/usb-complex") > 0)
378402
return;
379403

380-
if (adt_is_compatible(adt, 0, "J180dAP"))
381-
hpm_for_each_in_i2c_bus("/arm-io/i2c3", hpm_restore_irqs_callback, &force);
382-
hpm_for_each_in_i2c_bus("/arm-io/i2c0", hpm_restore_irqs_callback, &force);
404+
if (adt_path_offset(adt, "/arm-io/nub-spmi-a0/hpm0") > 0) {
405+
hpm_for_each_in_spmi_bus("/arm-io/nub-spmi-a0", hpm_restore_irqs_callback, &force);
406+
hpm_for_each_in_spmi_bus("/arm-io/nub-spmi-a1", hpm_restore_irqs_callback, &force);
407+
} else {
408+
if (adt_is_compatible(adt, 0, "J180dAP"))
409+
hpm_for_each_in_i2c_bus("/arm-io/i2c3", hpm_restore_irqs_callback, &force);
410+
hpm_for_each_in_i2c_bus("/arm-io/i2c0", hpm_restore_irqs_callback, &force);
411+
}
383412
}
384413

385414
void usb_iodev_init(void)

0 commit comments

Comments
 (0)