diff options
author | Neela Chithirala <chithiralan@google.com> | 2022-01-17 04:41:54 +0000 |
---|---|---|
committer | Neela Chithirala <chithiralan@google.com> | 2022-02-03 06:27:20 +0000 |
commit | 3ccb2479717de3089dbbcb894ddd045b2ddc256c (patch) | |
tree | a577f284ff42d11b1fcfb7c338a7f0b59b10672a /gxp-firmware.c | |
parent | e14069f1739b05c7a7f60ae73c8ce14b91ef12e0 (diff) | |
download | gs201-3ccb2479717de3089dbbcb894ddd045b2ddc256c.tar.gz |
Merge branch 'gs201-release' to android13-gs-pixel-5.10
* gs201-release:
gxp: Fix multicore VDs not shutting down clean
Bug: 215303765
gxp: Rework VD locking and remove mailbox locking
Bug: 189018271
gxp: initial commit for thermal driver
Bug: 177217526
gxp: Add wakelock interface and make debugfs wakelock aware
Bug: 215192870
gxp: Hook-up pm ops for driver suspend/resume
Bug: 204924965
gxp: Dynamically power BLK_AUR on and off
Bug: 204924965
gxp: support GXP_PLATFORM=GEM5
Bug: 204942713
gxp: Remove delay waiting for FW mailbox init
Bug: 207037428
gxp: Fix infrequent crash during mailbox release
gxp: Release FW file on firmware loading errors
gxp: return GXP_RESP_CANCELLED if timeout occurs
Bug: 207432733
gxp: Remove initial 10ms delay when disabling telemetry
gxp: Cast telemetry buffer IOVAs to u32s before use
gxp: check sscoredump by CONFIG_SUBSYSTEM_COREDUMP
gxp: Fix double-lock hang in gxp_telemetry_vma_close
gxp: Log driver git commit hash on probe
Bug: 206744969
gxp: Add ioctl for reading the TOP global counter
gxp: Implement eventfd signalling for telemetry
gxp: Notify running cores of telemetry state changes
gxp: Add notification interface
Signed-off-by: Neela Chithirala <chithiralan@google.com>
Change-Id: Ic7cd7b81ee643371c600ac208ae33d6344ed7f1b
Diffstat (limited to 'gxp-firmware.c')
-rw-r--r-- | gxp-firmware.c | 64 |
1 files changed, 49 insertions, 15 deletions
diff --git a/gxp-firmware.c b/gxp-firmware.c index 89c0354..1557696 100644 --- a/gxp-firmware.c +++ b/gxp-firmware.c @@ -21,6 +21,9 @@ #include "gxp-internal.h" #include "gxp-lpm.h" #include "gxp-mailbox.h" +#include "gxp-notification.h" +#include "gxp-pm.h" +#include "gxp-telemetry.h" #include "gxp-tmp.h" /* TODO (b/176984045): Clean up gxp-firmware.c */ @@ -125,6 +128,9 @@ static int elf_load_segments(struct gxp_dev *gxp, const struct firmware *fw, return ret; } +/* Forward declaration for usage inside gxp_firmware_load(..). */ +static void gxp_firmware_unload(struct gxp_dev *gxp, uint core); + static int gxp_firmware_load(struct gxp_dev *gxp, uint core) { u32 reset_vec, offset; @@ -163,14 +169,15 @@ static int gxp_firmware_load(struct gxp_dev *gxp, uint core) gxp->fwbufs[core].size, MEMREMAP_WC); if (!(gxp->fwbufs[core].vaddr)) { dev_err(gxp->dev, "FW buf memremap failed\n"); - return -EINVAL; + ret = -EINVAL; + goto out_firmware_unload; } /* Load firmware to System RAM */ ret = elf_load_segments(gxp, fw[core], core); if (ret) { dev_err(gxp->dev, "Unable to load elf file\n"); - return ret; + goto out_firmware_unload; } memset(gxp->fwbufs[core].vaddr + AURORA_SCRATCHPAD_OFF, 0, @@ -203,6 +210,10 @@ static int gxp_firmware_load(struct gxp_dev *gxp, uint core) gxp_bpm_configure(gxp, core, DATA_BPM_OFFSET, BPM_EVENT_WRITE_XFER); return 0; + +out_firmware_unload: + gxp_firmware_unload(gxp, core); + return ret; } static int gxp_firmware_handshake(struct gxp_dev *gxp, uint core) @@ -270,6 +281,7 @@ static int gxp_firmware_handshake(struct gxp_dev *gxp, uint core) dev_notice(gxp->dev, "Core %u is alive!\n", core); } +#ifndef CONFIG_GXP_GEM5 /* * Currently, the hello_world FW reads the INT_MASK0 register * (written by the driver) to validate TOP access. The value @@ -277,6 +289,9 @@ static int gxp_firmware_handshake(struct gxp_dev *gxp, uint core) * the scratchpad space, which must be compared to the value * written in the INT_MASK0 register by the driver for * confirmation. + * On Gem5, FW will start early when lpm is up. This behavior will + * affect the order of reading/writing INT_MASK0, so ignore this + * handshaking in Gem5. */ /* TODO (b/182528386): Fix handshake for verifying TOP access */ offset = SCRATCHPAD_MSG_OFFSET(MSG_TOP_ACCESS_OK); @@ -291,6 +306,7 @@ static int gxp_firmware_handshake(struct gxp_dev *gxp, uint core) dev_notice(gxp->dev, "TOP access from core %u successful!\n", core); } +#endif // !CONFIG_GXP_GEM5 /* Stop bus performance monitors */ gxp_bpm_stop(gxp, core); @@ -324,6 +340,9 @@ int gxp_fw_init(struct gxp_dev *gxp) aurora_base = gxp->regs.vaddr; + /* Power on BLK_AUR to read the revision and processor ID registers */ + gxp_pm_blk_on(gxp); + ver = gxp_read_32(gxp, GXP_REG_AURORA_REVISION); dev_notice(gxp->dev, "Aurora version: 0x%x\n", ver); @@ -333,6 +352,9 @@ int gxp_fw_init(struct gxp_dev *gxp) core, proc_id); } + /* Shut BLK_AUR down again to avoid interfering with power management */ + gxp_pm_blk_off(gxp); + ret = gxp_acquire_rmem_resource(gxp, &r, "gxp-fw-region"); if (ret) { dev_err(gxp->dev, @@ -365,18 +387,23 @@ int gxp_fw_init(struct gxp_dev *gxp) */ gxp->firmware_running = 0; - gxp_lpm_init(gxp); return 0; } void gxp_fw_destroy(struct gxp_dev *gxp) { - gxp_lpm_destroy(gxp); + /* NO-OP for now. */ + /* + * TODO(b/214124218): Revisit if the firmware subsystem still needs a + * "destroy" method now that power management is decoupled from the + * firmware subsystem's lifecycle. + */ } int gxp_firmware_run(struct gxp_dev *gxp, uint core) { int ret = 0; + struct work_struct *work; if (gxp->firmware_running & BIT(core)) { dev_err(gxp->dev, "Firmware is already running on core %u\n", @@ -390,7 +417,8 @@ int gxp_firmware_run(struct gxp_dev *gxp, uint core) return ret; } - ret = gxp_lpm_up(gxp, core); + gxp_doorbell_set_listening_core(gxp, CORE_WAKEUP_DOORBELL, core); + ret = gxp_pm_core_on(gxp, core); if (ret) { dev_err(gxp->dev, "Failed to power up core %u\n", core); goto out_firmware_unload; @@ -400,7 +428,7 @@ int gxp_firmware_run(struct gxp_dev *gxp, uint core) if (ret) { dev_err(gxp->dev, "Firmware handshake failed on core %u\n", core); - /* TODO (b/176984045): Undo gxp_lpm_up() */ + gxp_pm_core_off(gxp, core); goto out_firmware_unload; } @@ -420,15 +448,16 @@ int gxp_firmware_run(struct gxp_dev *gxp, uint core) goto out_firmware_unload; } - gxp_mailbox_register_debug_handler(gxp->mailbox_mgr->mailboxes[core], - gxp_debug_dump_process_dump, - GXP_DEBUG_DUMP_INT_MASK); + work = gxp_debug_dump_get_notification_handler(gxp, core); + if (work) + gxp_notification_register_handler( + gxp, core, HOST_NOTIF_DEBUG_DUMP_READY, work); + + work = gxp_telemetry_get_notification_handler(gxp, core); + if (work) + gxp_notification_register_handler( + gxp, core, HOST_NOTIF_TELEMETRY_STATUS, work); - /* - * Wait until the FW consumes the new mailbox register values before - * allowing messages to be sent thus manipulating the mailbox pointers. - */ - msleep(25 * GXP_TIME_DELAY_FACTOR); gxp->firmware_running |= BIT(core); return ret; @@ -445,10 +474,15 @@ void gxp_firmware_stop(struct gxp_dev *gxp, uint core) gxp->firmware_running &= ~BIT(core); + gxp_notification_unregister_handler(gxp, core, + HOST_NOTIF_DEBUG_DUMP_READY); + gxp_notification_unregister_handler(gxp, core, + HOST_NOTIF_TELEMETRY_STATUS); + gxp_mailbox_release(gxp->mailbox_mgr, gxp->mailbox_mgr->mailboxes[core]); dev_notice(gxp->dev, "Mailbox %u released\n", core); - gxp_lpm_down(gxp, core); + gxp_pm_core_off(gxp, core); gxp_firmware_unload(gxp, core); } |