Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp2767121imj; Mon, 11 Feb 2019 08:10:08 -0800 (PST) X-Google-Smtp-Source: AHgI3IbxdMIrs+PQh6oUdNDEO0g7bhmCJm3XUOFXODScuaPc1TXvS3ohv5kByMAaBm212LwsXpJG X-Received: by 2002:a17:902:7590:: with SMTP id j16mr37423664pll.231.1549901408435; Mon, 11 Feb 2019 08:10:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549901408; cv=none; d=google.com; s=arc-20160816; b=BrCCnJ/O7yFpXbkEAFk9UiARm/LuiiEg8D9swnoZ1UReZm+n7slxRIWVn6PXeGn9dh ADKc6bTw0cgrQJK1GaB4knmbjK6jvEDVEMVuhv3bWK7XrVZm1HOaK4SvQZn4HDgcfIcA VJMHyigs34hdNZb0Zwr3yEnD633Dzbfxd3HCedmFowL0wqJR5XPd6Wx6qgLeVgtrsqqy JPuacC2fF5AIoapJZc3TRS+9vksqElwvasPnIJZf2thdAIimxeOv2hRASxA3zf5wdl/4 Aq7GexemdZ/rGfKozOenAkURdCOCn8XsJuX2UBmTVHkalynIZq42cZfXE2CJ2CEeYuFj aWAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=TiWNPHwtd8aVZUDd+aHwqq8O2jNX7WQiBWhxYfsPtiY=; b=mQGW2JAU7b2eVUuG++BNRLtpUU0KBsTIr1GE7PMgKVaLN6N1xg+fmzt+rvM9kO/r1l Wg2g4laQ2uUSt84HqGtKX5t4qaAWuWe5Ux59F4WCypdV6BocEGMDi6L9uw86upKxyY55 N9UuPYpcRlq/hV75T8SeoXhegs9rgzoiBS3Lp6MWPqdjfr0RmLjY+SREcxIX2TsjQ332 hTA7bVg4iKUgfzUiiHI1v1VO9gOd8LMyVOIxfUDXY5A7t2zlB4+3q2fPNJ4swe6KVVyp kJtIDCuE1m/uEz6D8NhfOH5NK10h6ZmVCoF0tpy5iyANKEFyvtGibZSG5ec71vzPJxFR NpRw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=qWo5lHw8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n2si9123180pgp.30.2019.02.11.08.09.51; Mon, 11 Feb 2019 08:10:08 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=qWo5lHw8; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387627AbfBKQIu (ORCPT + 99 others); Mon, 11 Feb 2019 11:08:50 -0500 Received: from mail.kernel.org ([198.145.29.99]:59414 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729439AbfBKOZt (ORCPT ); Mon, 11 Feb 2019 09:25:49 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 0E9372075C; Mon, 11 Feb 2019 14:25:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1549895147; bh=Kh06wUfyOne3w8UomsLxv1FO+m58Zr7iOFMI7Udcu44=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qWo5lHw8Py5UWa6Sv+xamVOAMHvz15oENCTEoJyIKS3CMy40mRdEsUvRG7TlCTVl5 mVu3xnb6meJuOKHBfUlYNqSKs7/yCBriQgPRnIUKrykUHKQcGoN8J7ADz5Y0C5288O G0jX+ZjXDdYmB648YN0qYu6BWhTCdaVtgEy3r+5w= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Hans de Goede , Alan Cox , Andy Shevchenko , Darren Hart , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Sasha Levin Subject: [PATCH 4.20 107/352] platform/x86: Fix config space access for intel_atomisp2_pm Date: Mon, 11 Feb 2019 15:15:34 +0100 Message-Id: <20190211141852.600463874@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190211141846.543045703@linuxfoundation.org> References: <20190211141846.543045703@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.20-stable review patch. If anyone has any objections, please let me know. ------------------ [ Upstream commit 6a31061833a52a79c99221b6251db08cf377470e ] We lose even config space access when we power gate the ISP via the PUNIT. That makes lspci & co. produce gibberish. To fix that let's try to implement actual runtime pm hooks and inform the pci core that the device always goes to D3cold. That will cause the pci core to resume the device before attempting config space access. This introduces another annoyance though. We get the following error every time we try to resume the device: intel_atomisp2_pm 0000:00:03.0: Refused to change power state, currently in D3 The reason being that the pci core tries to put the device back into D0 via the standard PCI PM mechanism before calling the driver resume hook. To fix this properly we'd need to infiltrate the platform pm hooks (could turn ugly real fast), or use pm domains (which don't seem to exist on x86), or some extra early resume hook for the driver (which doesn't exist either). So maybe we just choose to live with the error? Cc: Hans de Goede Cc: Alan Cox Cc: Andy Shevchenko Cc: Darren Hart Signed-off-by: Ville Syrjälä Signed-off-by: Andy Shevchenko Reviewed-by: Hans de Goede Signed-off-by: Sasha Levin --- drivers/platform/x86/intel_atomisp2_pm.c | 68 +++++++++++++++++------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/drivers/platform/x86/intel_atomisp2_pm.c b/drivers/platform/x86/intel_atomisp2_pm.c index 9371603a0ac9..2a8c7a4cea35 100644 --- a/drivers/platform/x86/intel_atomisp2_pm.c +++ b/drivers/platform/x86/intel_atomisp2_pm.c @@ -33,46 +33,45 @@ #define ISPSSPM0_IUNIT_POWER_ON 0x0 #define ISPSSPM0_IUNIT_POWER_OFF 0x3 -static int isp_probe(struct pci_dev *dev, const struct pci_device_id *id) +static int isp_set_power(struct pci_dev *dev, bool enable) { unsigned long timeout; - u32 val; - - pci_write_config_dword(dev, PCI_INTERRUPT_CTRL, 0); - - /* - * MRFLD IUNIT DPHY is located in an always-power-on island - * MRFLD HW design need all CSI ports are disabled before - * powering down the IUNIT. - */ - pci_read_config_dword(dev, PCI_CSI_CONTROL, &val); - val |= PCI_CSI_CONTROL_PORTS_OFF_MASK; - pci_write_config_dword(dev, PCI_CSI_CONTROL, val); + u32 val = enable ? ISPSSPM0_IUNIT_POWER_ON : + ISPSSPM0_IUNIT_POWER_OFF; - /* Write 0x3 to ISPSSPM0 bit[1:0] to power off the IUNIT */ + /* Write to ISPSSPM0 bit[1:0] to power on/off the IUNIT */ iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM0, - ISPSSPM0_IUNIT_POWER_OFF, ISPSSPM0_ISPSSC_MASK); + val, ISPSSPM0_ISPSSC_MASK); /* * There should be no IUNIT access while power-down is * in progress HW sighting: 4567865 * Wait up to 50 ms for the IUNIT to shut down. + * And we do the same for power on. */ timeout = jiffies + msecs_to_jiffies(50); while (1) { - /* Wait until ISPSSPM0 bit[25:24] shows 0x3 */ - iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM0, &val); - val = (val & ISPSSPM0_ISPSSS_MASK) >> ISPSSPM0_ISPSSS_OFFSET; - if (val == ISPSSPM0_IUNIT_POWER_OFF) + u32 tmp; + + /* Wait until ISPSSPM0 bit[25:24] shows the right value */ + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_REG_READ, ISPSSPM0, &tmp); + tmp = (tmp & ISPSSPM0_ISPSSS_MASK) >> ISPSSPM0_ISPSSS_OFFSET; + if (tmp == val) break; if (time_after(jiffies, timeout)) { - dev_err(&dev->dev, "IUNIT power-off timeout.\n"); + dev_err(&dev->dev, "IUNIT power-%s timeout.\n", + enable ? "on" : "off"); return -EBUSY; } usleep_range(1000, 2000); } + return 0; +} + +static int isp_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ pm_runtime_allow(&dev->dev); pm_runtime_put_sync_suspend(&dev->dev); @@ -87,11 +86,40 @@ static void isp_remove(struct pci_dev *dev) static int isp_pci_suspend(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); + u32 val; + + pci_write_config_dword(pdev, PCI_INTERRUPT_CTRL, 0); + + /* + * MRFLD IUNIT DPHY is located in an always-power-on island + * MRFLD HW design need all CSI ports are disabled before + * powering down the IUNIT. + */ + pci_read_config_dword(pdev, PCI_CSI_CONTROL, &val); + val |= PCI_CSI_CONTROL_PORTS_OFF_MASK; + pci_write_config_dword(pdev, PCI_CSI_CONTROL, val); + + /* + * We lose config space access when punit power gates + * the ISP. Can't use pci_set_power_state() because + * pmcsr won't actually change when we write to it. + */ + pci_save_state(pdev); + pdev->current_state = PCI_D3cold; + isp_set_power(pdev, false); + return 0; } static int isp_pci_resume(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); + + isp_set_power(pdev, true); + pdev->current_state = PCI_D0; + pci_restore_state(pdev); + return 0; } -- 2.19.1