diff options
author | Aurora pro automerger <aurora-pro-automerger@google.com> | 2022-04-28 17:59:17 +0800 |
---|---|---|
committer | John Scheible <johnscheible@google.com> | 2022-05-02 22:33:52 +0000 |
commit | 27bed782f3a828674c0f1584cf355bf592c382be (patch) | |
tree | 79f6f3410eece25889b3cfc80dcd156ec5b543c6 /gxp-firmware.c | |
parent | a96a198c9328b06866df39ebd420b0f3fd58ce51 (diff) | |
download | gs201-27bed782f3a828674c0f1584cf355bf592c382be.tar.gz |
[Copybara Auto Merge] Merge branch 'gs201-release' into 'android13-gs-pixel-5.10'
gxp: check BLK is on during power state transition
gxp: prepare more worker structures for async jobs
gxp: Cleanup virt<->phys core translation APIs
gxp: switch mux to make sure LPM works
gxp: init has_vd_lock field of gxp_client
gxp: Clean up variable names and update variable type
gxp: remove gxp-tmp.h
gxp: move scratchpad macros from tmp to firmware.h
gxp: remove no-iommu support
gxp: remove SYNC_ macros from tmp.h
gxp: remove DOORBELL macros
gxp: move PSM macros to lpm.h
gxp: Check for valid VD in mb_eventfd IOCTLs
gxp: Firmware startup and Core-On optimizations
gxp: Move ownership of user response queues
gxp: move macros from tmp.h to bpm.c
gxp: remove legacy software mailbox support
gxp: Add gxp-eventfd interface
gxp: remove unused macros from gxp-tmp.h
gxp: bind page tables per virtual device
Bug: 176979630
Bug: 207037425
Bug: 207038856
Bug: 209083969
Bug: 225059930
Bug: 226211187
Bug: 227145352
Bug: 227693917
Bug: 227694164
Bug: 228233514
Bug: 228921329
Bug: 229095276
Bug: 229584236
GitOrigin-RevId: d2c00e3ee2d71e551d41adfa5bcc6bec79379db3
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Change-Id: Ia92e12a2ab46eadc2876bcdb7ed3c04e223b3901
Diffstat (limited to 'gxp-firmware.c')
-rw-r--r-- | gxp-firmware.c | 93 |
1 files changed, 38 insertions, 55 deletions
diff --git a/gxp-firmware.c b/gxp-firmware.c index 2af783e..df4e192 100644 --- a/gxp-firmware.c +++ b/gxp-firmware.c @@ -26,7 +26,7 @@ #include "gxp-notification.h" #include "gxp-pm.h" #include "gxp-telemetry.h" -#include "gxp-tmp.h" +#include "gxp-vd.h" /* TODO (b/176984045): Clean up gxp-firmware.c */ @@ -303,10 +303,8 @@ out_firmware_unload: static int gxp_firmware_handshake(struct gxp_dev *gxp, uint core) { u32 offset; - u32 psm_status; u32 expected_top_value; - void __iomem *core_psm_base, *core_scratchpad_base, *addr; - uint state; + void __iomem *core_scratchpad_base; int ctr; /* Raise wakeup doorbell */ @@ -316,21 +314,12 @@ static int gxp_firmware_handshake(struct gxp_dev *gxp, uint core) gxp_doorbell_set(gxp, CORE_WAKEUP_DOORBELL); /* Wait for core to come up */ - dev_notice(gxp->dev, "Waiting for core %u to power up...\n", - core); - core_psm_base = - ((u8 *)gxp->regs.vaddr) + LPM_BLOCK + CORE_PSM_BASE(core); + dev_notice(gxp->dev, "Waiting for core %u to power up...\n", core); ctr = 1000; while (ctr) { - addr = core_psm_base + PSM_STATUS_OFFSET; - psm_status = (u32) readl(addr); /* 0x60041688 */ - if (psm_status & PSM_STATE_VALID_MASK) { - state = psm_status & PSM_CURR_STATE_MASK; - if ((state == PSM_STATE_ACTIVE) - || (state == PSM_STATE_CLK_GATED)) - break; - } - cpu_relax(); + if (gxp_lpm_is_powered(gxp, core)) + break; + udelay(1 * GXP_TIME_DELAY_FACTOR); ctr--; } @@ -346,18 +335,20 @@ static int gxp_firmware_handshake(struct gxp_dev *gxp, uint core) core_scratchpad_base = gxp->fwbufs[core].vaddr + AURORA_SCRATCHPAD_OFF; - ctr = 500; - offset = SCRATCHPAD_MSG_OFFSET(MSG_CORE_ALIVE); - while (ctr--) { - if (readl(core_scratchpad_base + offset) == Q7_ALIVE_MAGIC) - break; - msleep(1 * GXP_TIME_DELAY_FACTOR); - } /* * Currently, the hello_world FW writes a magic number * (Q7_ALIVE_MAGIC) to offset MSG_CORE_ALIVE in the scratchpad * space as an alive message */ + ctr = 5000; + offset = SCRATCHPAD_MSG_OFFSET(MSG_CORE_ALIVE); + usleep_range(500 * GXP_TIME_DELAY_FACTOR, 1000 * GXP_TIME_DELAY_FACTOR); + while (ctr--) { + if (readl(core_scratchpad_base + offset) == Q7_ALIVE_MAGIC) + break; + usleep_range(1 * GXP_TIME_DELAY_FACTOR, + 10 * GXP_TIME_DELAY_FACTOR); + } if (readl(core_scratchpad_base + offset) != Q7_ALIVE_MAGIC) { dev_err(gxp->dev, "Core %u did not respond!\n", core); return -EIO; @@ -377,11 +368,14 @@ static int gxp_firmware_handshake(struct gxp_dev *gxp, uint core) * handshaking in Gem5. */ /* TODO (b/182528386): Fix handshake for verifying TOP access */ + ctr = 1000; offset = SCRATCHPAD_MSG_OFFSET(MSG_TOP_ACCESS_OK); expected_top_value = BIT(0); -#ifdef CONFIG_GXP_USE_SW_MAILBOX - expected_top_value |= BIT(31 - core); -#endif // CONFIG_GXP_USE_SW_MAILBOX + while (ctr--) { + if (readl(core_scratchpad_base + offset) == expected_top_value) + break; + udelay(1 * GXP_TIME_DELAY_FACTOR); + } if (readl(core_scratchpad_base + offset) != expected_top_value) { dev_err(gxp->dev, "TOP access from core %u failed!\n", core); return -EIO; @@ -479,7 +473,8 @@ void gxp_fw_destroy(struct gxp_dev *gxp) */ } -int gxp_firmware_run(struct gxp_dev *gxp, uint core) +int gxp_firmware_run(struct gxp_dev *gxp, struct gxp_virtual_device *vd, + uint virt_core, uint core) { int ret = 0; struct work_struct *work; @@ -503,21 +498,24 @@ int gxp_firmware_run(struct gxp_dev *gxp, uint core) goto out_firmware_unload; } + /* Switch PLL_CON0_NOC_USER MUX to the normal state to guarantee LPM works */ + gxp_pm_force_cmu_noc_user_mux_normal(gxp); ret = gxp_firmware_handshake(gxp, core); if (ret) { dev_err(gxp->dev, "Firmware handshake failed on core %u\n", core); gxp_pm_core_off(gxp, core); - goto out_firmware_unload; + goto out_check_noc_user_mux; } - - /* Initialize ioctl response queues */ - INIT_LIST_HEAD(&(gxp->mailbox_resp_queues[core])); - init_waitqueue_head(&(gxp->mailbox_resp_waitqs[core])); + /* + * Check if we need to set PLL_CON0_NOC_USER MUX to low state for + * AUR_READY requested state. + */ + gxp_pm_check_cmu_noc_user_mux(gxp); /* Initialize mailbox */ - gxp->mailbox_mgr->mailboxes[core] = gxp_mailbox_alloc(gxp->mailbox_mgr, - core); + gxp->mailbox_mgr->mailboxes[core] = + gxp_mailbox_alloc(gxp->mailbox_mgr, vd, virt_core, core); if (IS_ERR(gxp->mailbox_mgr->mailboxes[core])) { dev_err(gxp->dev, "Unable to allocate mailbox (core=%u, ret=%ld)\n", core, @@ -541,16 +539,16 @@ int gxp_firmware_run(struct gxp_dev *gxp, uint core) return ret; +out_check_noc_user_mux: + gxp_pm_check_cmu_noc_user_mux(gxp); out_firmware_unload: gxp_firmware_unload(gxp, core); return ret; } -void gxp_firmware_stop(struct gxp_dev *gxp, uint core) +void gxp_firmware_stop(struct gxp_dev *gxp, struct gxp_virtual_device *vd, + uint virt_core, uint core) { - struct gxp_async_response *cur, *nxt; - unsigned long flags; - if (!(gxp->firmware_running & BIT(core))) dev_err(gxp->dev, "Firmware is not running on core %u\n", core); @@ -561,25 +559,10 @@ void gxp_firmware_stop(struct gxp_dev *gxp, uint core) gxp_notification_unregister_handler(gxp, core, HOST_NOTIF_TELEMETRY_STATUS); - gxp_mailbox_release(gxp->mailbox_mgr, + gxp_mailbox_release(gxp->mailbox_mgr, vd, virt_core, gxp->mailbox_mgr->mailboxes[core]); dev_notice(gxp->dev, "Mailbox %u released\n", core); - /* - * TODO(b/226211187) response queues should be owned by VDs - * This step should not be necessary until a VD is destroyed once the - * queues are owned directly by the VD and not shared by all users of - * a physical core. - */ - /* Flush and free any abandoned responses left in the queue */ - spin_lock_irqsave(&gxp->mailbox_resps_lock, flags); - list_for_each_entry_safe(cur, nxt, &gxp->mailbox_resp_queues[core], - list_entry) { - list_del(&cur->list_entry); - kfree(cur); - } - spin_unlock_irqrestore(&gxp->mailbox_resps_lock, flags); - gxp_pm_core_off(gxp, core); gxp_firmware_unload(gxp, core); } |