From 27bed782f3a828674c0f1584cf355bf592c382be Mon Sep 17 00:00:00 2001 From: Aurora pro automerger Date: Thu, 28 Apr 2022 17:59:17 +0800 Subject: [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 Change-Id: Ia92e12a2ab46eadc2876bcdb7ed3c04e223b3901 --- gxp-firmware.c | 93 ++++++++++++++++++++++++---------------------------------- 1 file changed, 38 insertions(+), 55 deletions(-) (limited to 'gxp-firmware.c') 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); } -- cgit v1.2.3