Skip to content

Commit 1adf095

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 55dddcf commit 1adf095

File tree

2 files changed

+58
-29
lines changed

2 files changed

+58
-29
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: 57 additions & 29 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(int node)
@@ -297,6 +291,40 @@ static int hpm_for_each_in_i2c_bus(const char *i2c_path, hpm_callback_t *cb, voi
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+
int idx = hpm_index(node);
311+
if (idx < 0) continue;
312+
snprintf(hpm_path, sizeof(hpm_path), "%s/%s", spmi_path, name);
313+
314+
tps6598x_dev_t *tps = tps6598x_init_spmi(hpm_path, spmi);
315+
if (!tps) {
316+
printf("usb: tps6598x_init_spmi failed for %s.\n", hpm_path);
317+
continue;
318+
}
319+
cb(tps, idx, data);
320+
tps6598x_shutdown(tps);
321+
}
322+
323+
spmi_shutdown(spmi);
324+
325+
return 0;
326+
}
327+
300328
static void hpm_init_callback(tps6598x_dev_t *tps, u32 idx, void *data)
301329
{
302330
if (tps6598x_powerup(tps) < 0) {
@@ -331,15 +359,6 @@ void usb_init(void)
331359
if (usb_is_initialized)
332360
return;
333361

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-
343362
/*
344363
* A7-A11 uses a custom internal otg controller with the peripheral part
345364
* being dwc2.
@@ -350,11 +369,21 @@ void usb_init(void)
350369
return;
351370
}
352371

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

359388
for (int idx = 0; idx < USB_IODEV_COUNT; ++idx)
360389
usb_phy_bringup(idx); /* Fails on missing devices, just continue */
@@ -364,22 +393,21 @@ void usb_init(void)
364393

365394
void usb_hpm_restore_irqs(bool force)
366395
{
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-
373396
/*
374397
* Do not try to restore irqs on A7-A11 which don't use i2c
375398
*/
376399
if (adt_path_offset(adt, "/arm-io/otgphyctrl") > 0 &&
377400
adt_path_offset(adt, "/arm-io/usb-complex") > 0)
378401
return;
379402

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);
403+
if (adt_path_offset(adt, "/arm-io/nub-spmi-a0/hpm0") > 0) {
404+
hpm_for_each_in_spmi_bus("/arm-io/nub-spmi-a0", hpm_restore_irqs_callback, &force);
405+
hpm_for_each_in_spmi_bus("/arm-io/nub-spmi-a1", hpm_restore_irqs_callback, &force);
406+
} else {
407+
if (adt_is_compatible(adt, 0, "J180dAP"))
408+
hpm_for_each_in_i2c_bus("/arm-io/i2c3", hpm_restore_irqs_callback, &force);
409+
hpm_for_each_in_i2c_bus("/arm-io/i2c0", hpm_restore_irqs_callback, &force);
410+
}
383411
}
384412

385413
void usb_iodev_init(void)

0 commit comments

Comments
 (0)