From patchwork Mon Mar 8 06:27:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Winkler, Tomas" X-Patchwork-Id: 12121561 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7D80CC433E6 for ; Mon, 8 Mar 2021 06:28:07 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 13C4F651EB for ; Mon, 8 Mar 2021 06:28:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 13C4F651EB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 970DE6E51D; Mon, 8 Mar 2021 06:28:06 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6E35E6E51D for ; Mon, 8 Mar 2021 06:28:05 +0000 (UTC) IronPort-SDR: R0dOeTm8dlCu8qmF2TZZIAVOicD5mHbGA2yv6k4mLEDuZaIsgzFcojoxIf1bAbVKtZOwo3U3GN IqT5gTJNRo5Q== X-IronPort-AV: E=McAfee;i="6000,8403,9916"; a="249354804" X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="249354804" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:05 -0800 IronPort-SDR: KQs3aCQlzK1iwXW7swPP7kUMANTwB3lBtsP2SOeF0qtbiUruJB7WyBc+sjQoU57nNRL0wLbxTR I6r34H/k8m2A== X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="409181902" Received: from twinkler-lnx.jer.intel.com ([10.12.91.138]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:01 -0800 From: Tomas Winkler To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi Date: Mon, 8 Mar 2021 08:27:39 +0200 Message-Id: <20210308062748.208017-2-tomas.winkler@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210308062748.208017-1-tomas.winkler@intel.com> References: <20210308062748.208017-1-tomas.winkler@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 01/10 v2] drm/i915/spi: add spi device for discrete graphics X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexander Usyskin , intel-gfx@lists.freedesktop.org, Lucas De Marchi , linux-mtd@lists.infradead.org, Tomas Winkler , Vitaly Lubart Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Enable access to internal spi on descrete devices via a child device. The spi child device is exposed via MFD framework. Cc: Rodrigo Vivi Cc: Lucas De Marchi # v3 Signed-off-by: Tomas Winkler --- V2: 1. Fix header include guards name to match the file name 2. Drop intel_spi_fini() it was noop drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/i915/Makefile | 3 +++ drivers/gpu/drm/i915/i915_drv.c | 7 +++++ drivers/gpu/drm/i915/i915_drv.h | 4 +++ drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/spi/intel_spi.c | 40 ++++++++++++++++++++++++++++ drivers/gpu/drm/i915/spi/intel_spi.h | 17 ++++++++++++ 7 files changed, 73 insertions(+) create mode 100644 drivers/gpu/drm/i915/spi/intel_spi.c create mode 100644 drivers/gpu/drm/i915/spi/intel_spi.h diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 1e1cb245fca7..abcaa8da45ac 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -26,6 +26,7 @@ config DRM_I915 select SND_HDA_I915 if SND_HDA_CORE select CEC_CORE if CEC_NOTIFIER select VMAP_PFN + select MFD_CORE help Choose this option if you have a system that has "Intel Graphics Media Accelerator" or "HD Graphics" integrated graphics, diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index bc6138880c67..7f504475fde7 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -190,6 +190,9 @@ i915-y += gt/uc/intel_uc.o \ gt/uc/intel_huc_debugfs.o \ gt/uc/intel_huc_fw.o +# graphics spi device (DGFX) support +i915-y += spi/intel_spi.o + # modesetting core code i915-y += \ display/intel_atomic.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3edd5e47ad68..2719a92a8dd9 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -67,6 +68,8 @@ #include "gt/intel_gt_pm.h" #include "gt/intel_rc6.h" +#include "spi/intel_spi.h" + #include "i915_debugfs.h" #include "i915_drm_client.h" #include "i915_drv.h" @@ -684,6 +687,8 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) intel_gt_driver_register(&dev_priv->gt); + intel_spi_init(&dev_priv->spi, dev_priv); + intel_display_driver_register(dev_priv); intel_power_domains_enable(dev_priv); @@ -710,6 +715,8 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) intel_display_driver_unregister(dev_priv); + mfd_remove_devices(&dev_priv->drm.pdev->dev); + intel_gt_driver_unregister(&dev_priv->gt); i915_perf_unregister(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1d45d7492d10..1a1803a84432 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -85,6 +85,8 @@ #include "gt/intel_workarounds.h" #include "gt/uc/intel_uc.h" +#include "spi/intel_spi.h" + #include "intel_device_info.h" #include "intel_pch.h" #include "intel_runtime_pm.h" @@ -1117,6 +1119,8 @@ struct drm_i915_private { struct i915_perf perf; + struct intel_spi spi; + /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */ struct intel_gt gt; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e5dd0203991b..9e314393c593 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2510,6 +2510,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define VEBOX_RING_BASE 0x1a000 #define GEN11_VEBOX_RING_BASE 0x1c8000 #define GEN11_VEBOX2_RING_BASE 0x1d8000 +#define GEN12_GUNIT_SPI_BASE 0x00102040 #define BLT_RING_BASE 0x22000 #define RING_TAIL(base) _MMIO((base) + 0x30) #define RING_HEAD(base) _MMIO((base) + 0x34) diff --git a/drivers/gpu/drm/i915/spi/intel_spi.c b/drivers/gpu/drm/i915/spi/intel_spi.c new file mode 100644 index 000000000000..932221dff1c1 --- /dev/null +++ b/drivers/gpu/drm/i915/spi/intel_spi.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright(c) 2019-2021, Intel Corporation. All rights reserved. + */ + +#include +#include +#include "i915_reg.h" +#include "i915_drv.h" +#include "gt/intel_gt.h" +#include "spi/intel_spi.h" + +static const struct resource spi_resources[] = { + DEFINE_RES_MEM_NAMED(GEN12_GUNIT_SPI_BASE, 0x80, "i915-spi-mmio"), +}; + +static const struct mfd_cell intel_spi_cell = { + .id = 2, + .name = "i915-spi", + .num_resources = ARRAY_SIZE(spi_resources), + .resources = spi_resources, +}; + +void intel_spi_init(struct intel_spi *spi, struct drm_i915_private *dev_priv) +{ + struct pci_dev *pdev = dev_priv->drm.pdev; + int ret; + + /* Only the DGFX devices have internal SPI */ + if (!IS_DGFX(dev_priv)) + return; + + ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, + &intel_spi_cell, 1, + &pdev->resource[0], -1, NULL); + if (ret) + dev_err(&pdev->dev, "creating i915-spi cell failed\n"); + + spi->i915 = dev_priv; +} diff --git a/drivers/gpu/drm/i915/spi/intel_spi.h b/drivers/gpu/drm/i915/spi/intel_spi.h new file mode 100644 index 000000000000..237724fe9d50 --- /dev/null +++ b/drivers/gpu/drm/i915/spi/intel_spi.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright(c) 2019-2021, Intel Corporation. All rights reserved. + */ + +#ifndef __INTEL_SPI_H__ +#define __INTEL_SPI_H__ + +struct drm_i915_private; + +struct intel_spi { + struct drm_i915_private *i915; +}; + +void intel_spi_init(struct intel_spi *spi, struct drm_i915_private *i915); + +#endif /* __INTEL_SPI_H__ */ From patchwork Mon Mar 8 06:27:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Winkler, Tomas" X-Patchwork-Id: 12121563 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A39ADC433DB for ; Mon, 8 Mar 2021 06:28:11 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2675B651EB for ; Mon, 8 Mar 2021 06:28:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2675B651EB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A2F196E58A; Mon, 8 Mar 2021 06:28:10 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id D9AEF6E58A for ; Mon, 8 Mar 2021 06:28:08 +0000 (UTC) IronPort-SDR: xuVt1c7SV4Z9COGOBCv32Zfs5VYEKNmgoSDJfizHXTbfH4bQRDIXW4FU3HzmPviW+Qbnrat6Ge oSq+60/sVKOw== X-IronPort-AV: E=McAfee;i="6000,8403,9916"; a="249354810" X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="249354810" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:08 -0800 IronPort-SDR: zZ9UK6moBNTswwaFmapDV6oShOfztmBsdZUioPHE48ZNTDiPOtctXnfByaKBCjFJhQ576xHQqV PstsX5/Inu+w== X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="409181912" Received: from twinkler-lnx.jer.intel.com ([10.12.91.138]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:05 -0800 From: Tomas Winkler To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi Date: Mon, 8 Mar 2021 08:27:40 +0200 Message-Id: <20210308062748.208017-3-tomas.winkler@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210308062748.208017-1-tomas.winkler@intel.com> References: <20210308062748.208017-1-tomas.winkler@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 02/10 v2] drm/i915/spi: intel_spi_region map X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexander Usyskin , intel-gfx@lists.freedesktop.org, Lucas De Marchi , linux-mtd@lists.infradead.org, Tomas Winkler , Vitaly Lubart Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Add the dGFX spi region map and convey it via mfd cell platform data to the spi child device. Cc: Rodrigo Vivi Cc: Lucas De Marchi Signed-off-by: Tomas Winkler --- V2: Rebase drivers/gpu/drm/i915/spi/intel_spi.c | 9 +++++++++ drivers/gpu/drm/i915/spi/intel_spi.h | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/spi/intel_spi.c b/drivers/gpu/drm/i915/spi/intel_spi.c index 932221dff1c1..8eb09366124e 100644 --- a/drivers/gpu/drm/i915/spi/intel_spi.c +++ b/drivers/gpu/drm/i915/spi/intel_spi.c @@ -14,11 +14,20 @@ static const struct resource spi_resources[] = { DEFINE_RES_MEM_NAMED(GEN12_GUNIT_SPI_BASE, 0x80, "i915-spi-mmio"), }; +static const struct i915_spi_region regions[I915_SPI_REGIONS] = { + [0] = { .name = "DESCRIPTOR", }, + [2] = { .name = "GSC", }, + [11] = { .name = "OptionROM", }, + [12] = { .name = "DAM", }, +}; + static const struct mfd_cell intel_spi_cell = { .id = 2, .name = "i915-spi", .num_resources = ARRAY_SIZE(spi_resources), .resources = spi_resources, + .platform_data = (void *)regions, + .pdata_size = sizeof(regions), }; void intel_spi_init(struct intel_spi *spi, struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/spi/intel_spi.h b/drivers/gpu/drm/i915/spi/intel_spi.h index 237724fe9d50..37f6771ddbf6 100644 --- a/drivers/gpu/drm/i915/spi/intel_spi.h +++ b/drivers/gpu/drm/i915/spi/intel_spi.h @@ -8,6 +8,11 @@ struct drm_i915_private; +#define I915_SPI_REGIONS 13 +struct i915_spi_region { + const char *name; +}; + struct intel_spi { struct drm_i915_private *i915; }; From patchwork Mon Mar 8 06:27:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Winkler, Tomas" X-Patchwork-Id: 12121565 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CE30DC433E0 for ; Mon, 8 Mar 2021 06:28:14 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 33A59651EB for ; Mon, 8 Mar 2021 06:28:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 33A59651EB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B56126E7F5; Mon, 8 Mar 2021 06:28:13 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6AA266E7F5 for ; Mon, 8 Mar 2021 06:28:12 +0000 (UTC) IronPort-SDR: SyCeOcUH7rmk9BKFXFOCx7YSbceq2vgXX34SzcMHdV9OM6L2uZ+XqyD/bwE1oaeJMC98eEP13z NNCPKaFA6Oag== X-IronPort-AV: E=McAfee;i="6000,8403,9916"; a="249354823" X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="249354823" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:12 -0800 IronPort-SDR: B4CF5Iefunq3yJXZu0+lDtkFaUCiArcd58Uw/Q+9JuNwnzdRe4DQ0+/+o2WXMq0wrtdAsF71cn 84YFiiKQmbmw== X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="409181924" Received: from twinkler-lnx.jer.intel.com ([10.12.91.138]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:08 -0800 From: Tomas Winkler To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi Date: Mon, 8 Mar 2021 08:27:41 +0200 Message-Id: <20210308062748.208017-4-tomas.winkler@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210308062748.208017-1-tomas.winkler@intel.com> References: <20210308062748.208017-1-tomas.winkler@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 03/10 v2] drm/i915/spi: add driver for on-die spi device X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexander Usyskin , intel-gfx@lists.freedesktop.org, Lucas De Marchi , linux-mtd@lists.infradead.org, Tomas Winkler , Vitaly Lubart Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Add the platform driver for i915 on-die spi device, exposed via mfd framework. Cc: Rodrigo Vivi Cc: Lucas De Marchi Signed-off-by: Tomas Winkler --- V2: 1. Add own Kconfig and Makefile 2. Rename intel_spi_drv.c to i915_spi.c drivers/gpu/drm/i915/Kconfig | 2 + drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/spi/Kconfig | 17 ++++ drivers/gpu/drm/i915/spi/Makefile | 7 ++ drivers/gpu/drm/i915/spi/i915_spi.c | 116 ++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+) create mode 100644 drivers/gpu/drm/i915/spi/Kconfig create mode 100644 drivers/gpu/drm/i915/spi/Makefile create mode 100644 drivers/gpu/drm/i915/spi/i915_spi.c diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index abcaa8da45ac..d5062fbb6d25 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -131,6 +131,8 @@ config DRM_I915_GVT_KVMGT Choose this option if you want to enable KVMGT support for Intel GVT-g. +source "drivers/gpu/drm/i915/spi/Kconfig" + menu "drm/i915 Debugging" depends on DRM_I915 depends on EXPERT diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 7f504475fde7..9377a593364f 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -297,6 +297,7 @@ endif obj-$(CONFIG_DRM_I915) += i915.o obj-$(CONFIG_DRM_I915_GVT_KVMGT) += gvt/kvmgt.o +obj-$(CONFIG_DRM_I915_SPI) += spi/ # header test diff --git a/drivers/gpu/drm/i915/spi/Kconfig b/drivers/gpu/drm/i915/spi/Kconfig new file mode 100644 index 000000000000..7e6b82f8a59b --- /dev/null +++ b/drivers/gpu/drm/i915/spi/Kconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2021, Intel Corporation. All rights reserved. +# +config DRM_I915_SPI + tristate "I915 SPI driver for discrete devices" + select MTD + select MTD_PARTITIONED_MASTER + depends on DRM_I915 + help + I915 SPI driver for i915 discrete devices. + + This enables support for the SPI devices present on some + discrete i915 cards. This driver makes possible to + flush firmware during manufacturing process directly from + the operating system, and can be used by device health check + applications. + diff --git a/drivers/gpu/drm/i915/spi/Makefile b/drivers/gpu/drm/i915/spi/Makefile new file mode 100644 index 000000000000..0a2dab0aba03 --- /dev/null +++ b/drivers/gpu/drm/i915/spi/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2021, Intel Corporation. All rights reserved. +# +# Makefile - I915 SPI driver + +obj-$(CONFIG_DRM_I915_SPI) += i915_spi.o diff --git a/drivers/gpu/drm/i915/spi/i915_spi.c b/drivers/gpu/drm/i915/spi/i915_spi.c new file mode 100644 index 000000000000..23261f35b71f --- /dev/null +++ b/drivers/gpu/drm/i915/spi/i915_spi.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright(c) 2019-2021, Intel Corporation. All rights reserved. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct i915_spi { + void __iomem *base; + size_t size; + unsigned int nregions; + struct { + const char *name; + u8 id; + u64 offset; + u64 size; + } regions[]; +}; + +static int i915_spi_probe(struct platform_device *platdev) +{ + struct resource *bar; + struct device *device; + struct i915_spi *spi; + struct i915_spi_region *regions; + unsigned int nregions; + unsigned int i, n; + size_t size; + char *name; + size_t name_size; + + device = &platdev->dev; + + regions = dev_get_platdata(&platdev->dev); + if (!regions) { + dev_err(device, "no regions defined\n"); + return -ENODEV; + } + + /* count available regions */ + for (nregions = 0, i = 0; i < I915_SPI_REGIONS; i++) { + if (regions[i].name) + nregions++; + } + + if (!nregions) { + dev_err(device, "no regions defined\n"); + return -ENODEV; + } + + size = sizeof(*spi) + sizeof(spi->regions[0]) * nregions; + spi = devm_kzalloc(device, size, GFP_KERNEL); + if (!spi) + return -ENOMEM; + + spi->nregions = nregions; + for (n = 0, i = 0; i < I915_SPI_REGIONS; i++) { + if (regions[i].name) { + name_size = strlen(dev_name(&platdev->dev)) + + strlen(regions[i].name) + 2; /* for point */ + name = devm_kzalloc(device, name_size, GFP_KERNEL); + if (!name) + continue; + snprintf(name, name_size, "%s.%s", + dev_name(&platdev->dev), regions[i].name); + spi->regions[n].name = name; + spi->regions[n].id = i; + n++; + } + } + + bar = platform_get_resource(platdev, IORESOURCE_MEM, 0); + if (!bar) + return -ENODEV; + + spi->base = devm_ioremap_resource(device, bar); + if (IS_ERR(spi->base)) { + dev_err(device, "mmio not mapped\n"); + return PTR_ERR(spi->base); + } + + platform_set_drvdata(platdev, spi); + + dev_dbg(device, "i915-spi is bound\n"); + + return 0; +} + +static int i915_spi_remove(struct platform_device *platdev) +{ + platform_set_drvdata(platdev, NULL); + + return 0; +} + +MODULE_ALIAS("platform:i915-spi"); +static struct platform_driver i915_spi_driver = { + .probe = i915_spi_probe, + .remove = i915_spi_remove, + .driver = { + .name = "i915-spi", + }, +}; + +module_platform_driver(i915_spi_driver); + +MODULE_LICENSE("GPL and additional rights"); +MODULE_AUTHOR("Intel Corporation"); +MODULE_DESCRIPTION("Intel DGFX SPI driver"); From patchwork Mon Mar 8 06:27:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Winkler, Tomas" X-Patchwork-Id: 12121567 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1AD82C433DB for ; Mon, 8 Mar 2021 06:28:18 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9D533651EF for ; Mon, 8 Mar 2021 06:28:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9D533651EF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 37A946E7FE; Mon, 8 Mar 2021 06:28:17 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id C27896E7FE for ; Mon, 8 Mar 2021 06:28:16 +0000 (UTC) IronPort-SDR: SvCuUercfFXm9c6voadw6b/1/26pAwKZaa+rP64Wg0Iz+h+/j/BadYIXUqtkwTm89oUnHqs8wz YKM9jlL3e0Og== X-IronPort-AV: E=McAfee;i="6000,8403,9916"; a="249354828" X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="249354828" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:15 -0800 IronPort-SDR: b1DYI3j7iV+3NE6LvInSeATASjVm4Rr7FpjMol7lRfpYZNGnU9IiIBPXKmaET0IAoD21aM/ZT/ kKbWNe30qq8g== X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="409181934" Received: from twinkler-lnx.jer.intel.com ([10.12.91.138]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:12 -0800 From: Tomas Winkler To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi Date: Mon, 8 Mar 2021 08:27:42 +0200 Message-Id: <20210308062748.208017-5-tomas.winkler@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210308062748.208017-1-tomas.winkler@intel.com> References: <20210308062748.208017-1-tomas.winkler@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 04/10 v2] drm/i915/spi: implement regions enumeration X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexander Usyskin , intel-gfx@lists.freedesktop.org, Lucas De Marchi , linux-mtd@lists.infradead.org, Tomas Winkler , Vitaly Lubart Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Implement SPI device regions enumeration, as there is no access to the spi controller, all the information has to be extracted form the descriptor region. Cc: Rodrigo Vivi Cc: Lucas De Marchi Signed-off-by: Tomas Winkler --- V2: Update the commit message. drivers/gpu/drm/i915/spi/i915_spi.c | 190 ++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) diff --git a/drivers/gpu/drm/i915/spi/i915_spi.c b/drivers/gpu/drm/i915/spi/i915_spi.c index 23261f35b71f..a1e7171d05db 100644 --- a/drivers/gpu/drm/i915/spi/i915_spi.c +++ b/drivers/gpu/drm/i915/spi/i915_spi.c @@ -16,14 +16,197 @@ struct i915_spi { void __iomem *base; size_t size; unsigned int nregions; + u32 access_map; struct { const char *name; u8 id; u64 offset; u64 size; + unsigned int is_readable:1; + unsigned int is_writable:1; } regions[]; }; +#define SPI_TRIGGER_REG 0x00000000 +#define SPI_VALSIG_REG 0x00000010 +#define SPI_ADDRESS_REG 0x00000040 +#define SPI_REGION_ID_REG 0x00000044 +/* + * [15:0]-Erase size = 0x0010 4K 0x0080 32K 0x0100 64K + * [23:16]-Reserved + * [31:24]-Erase SPI RegionID + */ +#define SPI_ERASE_REG 0x00000048 +#define SPI_ACCESS_ERROR_REG 0x00000070 +#define SPI_ADDRESS_ERROR_REG 0x00000074 + +/* Flash Valid Signature */ +#define SPI_FLVALSIG 0x0FF0A55A + +#define SPI_MAP_ADDR_MASK 0x000000FF +#define SPI_MAP_ADDR_SHIFT 0x00000004 + +#define REGION_ID_DESCRIPTOR 0 +/* Flash Region Base Address */ +#define FRBA 0x40 +/* Flash Region __n - Flash Descriptor Record */ +#define FLREG(__n) (FRBA + ((__n) * 4)) +/* Flash Map 1 Register */ +#define FLMAP1_REG 0x18 +#define FLMSTR4_OFFSET 0x00C + +#define SPI_ACCESS_ERROR_PCIE_MASK 0x7 + +static inline void spi_set_region_id(struct i915_spi *spi, u8 region) +{ + iowrite32((u32)region, spi->base + SPI_REGION_ID_REG); +} + +static inline u32 spi_error(struct i915_spi *spi) +{ + u32 reg = ioread32(spi->base + SPI_ACCESS_ERROR_REG) & + SPI_ACCESS_ERROR_PCIE_MASK; + + /* reset error bits */ + if (reg) + iowrite32(reg, spi->base + SPI_ACCESS_ERROR_REG); + + return reg; +} + +static inline u32 spi_read32(struct i915_spi *spi, u32 address) +{ + void __iomem *base = spi->base; + + iowrite32(address, base + SPI_ADDRESS_REG); + + return ioread32(base + SPI_TRIGGER_REG); +} + +static int spi_get_access_map(struct i915_spi *spi) +{ + u32 flmap1; + u32 fmba; + u32 fmstr4; + u32 fmstr4_addr; + + spi_set_region_id(spi, REGION_ID_DESCRIPTOR); + + flmap1 = spi_read32(spi, FLMAP1_REG); + if (spi_error(spi)) + return -EIO; + /* Get Flash Master Baser Address (FMBA) */ + fmba = ((flmap1 & SPI_MAP_ADDR_MASK) << SPI_MAP_ADDR_SHIFT); + fmstr4_addr = fmba + FLMSTR4_OFFSET; + + fmstr4 = spi_read32(spi, fmstr4_addr); + if (spi_error(spi)) + return -EIO; + + spi->access_map = fmstr4; + return 0; +} + +static bool spi_region_readable(struct i915_spi *spi, u8 region) +{ + if (region < 12) + return spi->access_map & (1 << (region + 8)); /* [19:8] */ + else + return spi->access_map & (1 << (region - 12)); /* [3:0] */ +} + +static bool spi_region_writeable(struct i915_spi *spi, u8 region) +{ + if (region < 12) + return spi->access_map & (1 << (region + 20)); /* [31:20] */ + else + return spi->access_map & (1 << (region - 8)); /* [7:4] */ +} + +static int i915_spi_is_valid(struct i915_spi *spi) +{ + u32 is_valid; + + spi_set_region_id(spi, REGION_ID_DESCRIPTOR); + + is_valid = spi_read32(spi, SPI_VALSIG_REG); + if (spi_error(spi)) + return -EIO; + + if (is_valid != SPI_FLVALSIG) + return -ENODEV; + + return 0; +} + +static int i915_spi_init(struct i915_spi *spi, struct device *device) +{ + int ret; + unsigned int i, n; + + /* clean error register, previous errors are ignored */ + spi_error(spi); + + ret = i915_spi_is_valid(spi); + if (ret) { + dev_err(device, "The SPI is not valid %d\n", ret); + return ret; + } + + if (spi_get_access_map(spi)) + return -EIO; + + for (i = 0, n = 0; i < spi->nregions; i++) { + u32 address, base, limit, region; + u8 id = spi->regions[i].id; + + address = FLREG(id); + region = spi_read32(spi, address); + + base = (region & 0x0000FFFF) << 12; + limit = (((region & 0xFFFF0000) >> 16) << 12) | 0xFFF; + + dev_dbg(device, "[%d] %s: region: 0x%08X base: 0x%08x limit: 0x%08x\n", + id, spi->regions[i].name, region, base, limit); + + if (base >= limit || (i > 0 && limit == 0)) { + dev_dbg(device, "[%d] %s: disabled\n", + id, spi->regions[i].name); + spi->regions[i].is_readable = 0; + continue; + } + + if (spi->size < limit) + spi->size = limit; + + spi->regions[i].offset = base; + spi->regions[i].size = limit - base + 1; + /* No write access to descriptor; mask it out*/ + spi->regions[i].is_writable = spi_region_writeable(spi, id); + + spi->regions[i].is_readable = spi_region_readable(spi, id); + dev_dbg(device, "Registered, %s id=%d offset=%lld size=%lld rd=%d wr=%d\n", + spi->regions[i].name, + spi->regions[i].id, + spi->regions[i].offset, + spi->regions[i].size, + spi->regions[i].is_readable, + spi->regions[i].is_writable); + + if (spi->regions[i].is_readable) + n++; + } + + dev_dbg(device, "Registered %d regions\n", n); + + /* Need to add 1 to the amount of memory + * so it is reported as an even block + */ + spi->size += 1; + + return n; +} + static int i915_spi_probe(struct platform_device *platdev) { struct resource *bar; @@ -35,6 +218,7 @@ static int i915_spi_probe(struct platform_device *platdev) size_t size; char *name; size_t name_size; + int ret; device = &platdev->dev; @@ -86,6 +270,12 @@ static int i915_spi_probe(struct platform_device *platdev) return PTR_ERR(spi->base); } + ret = i915_spi_init(spi, device); + if (ret < 0) { + dev_err(device, "cannot initialize spi\n"); + return -ENODEV; + } + platform_set_drvdata(platdev, spi); dev_dbg(device, "i915-spi is bound\n"); From patchwork Mon Mar 8 06:27:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Winkler, Tomas" X-Patchwork-Id: 12121571 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2E68CC433DB for ; Mon, 8 Mar 2021 06:28:28 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D0CD1651EB for ; Mon, 8 Mar 2021 06:28:27 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D0CD1651EB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 42D896E80B; Mon, 8 Mar 2021 06:28:27 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id 72A966E811 for ; Mon, 8 Mar 2021 06:28:25 +0000 (UTC) IronPort-SDR: m9nx5mzpTCY+2qQlV+C3/UcnkZlBIYTb0Hi4Aj90lJQ2r6MwrRq8RTL066q0DlxsjEWxDmicWz QC3Zf0gjwhtg== X-IronPort-AV: E=McAfee;i="6000,8403,9916"; a="249354838" X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="249354838" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:19 -0800 IronPort-SDR: sRnFPwk1gbxDBaqBE17h22KiFsq+QEDcDfEQboZp0Ln+qUDtQScNalSzH5OaP3IBuI8ofyjqIX edJbLKDFsuuQ== X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="409181953" Received: from twinkler-lnx.jer.intel.com ([10.12.91.138]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:16 -0800 From: Tomas Winkler To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi Date: Mon, 8 Mar 2021 08:27:43 +0200 Message-Id: <20210308062748.208017-6-tomas.winkler@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210308062748.208017-1-tomas.winkler@intel.com> References: <20210308062748.208017-1-tomas.winkler@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 05/10 v2] drm/i915/spi: implement spi access functions X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexander Usyskin , intel-gfx@lists.freedesktop.org, Lucas De Marchi , linux-mtd@lists.infradead.org, Tomas Winkler , Vitaly Lubart Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Implement spi_read() spi_erase() spi_write() functions. Cc: Lucas De Marchi Cc: Rodrigo Vivi Signed-off-by: Tomas Winkler Co-developed-by: Alexander Usyskin Signed-off-by: Alexander Usyskin Co-developed-by: Vitaly Lubart Signed-off-by: Vitaly Lubart --- V2: 1. Rebase drivers/gpu/drm/i915/spi/i915_spi.c | 137 ++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/drivers/gpu/drm/i915/spi/i915_spi.c b/drivers/gpu/drm/i915/spi/i915_spi.c index a1e7171d05db..df6a461d520d 100644 --- a/drivers/gpu/drm/i915/spi/i915_spi.c +++ b/drivers/gpu/drm/i915/spi/i915_spi.c @@ -9,7 +9,10 @@ #include #include #include +#include +#include #include +#include #include struct i915_spi { @@ -83,6 +86,33 @@ static inline u32 spi_read32(struct i915_spi *spi, u32 address) return ioread32(base + SPI_TRIGGER_REG); } +static inline u64 spi_read64(struct i915_spi *spi, u32 address) +{ + void __iomem *base = spi->base; + + iowrite32(address, base + SPI_ADDRESS_REG); + + return readq(base + SPI_TRIGGER_REG); +} + +static void spi_write32(struct i915_spi *spi, u32 address, u32 data) +{ + void __iomem *base = spi->base; + + iowrite32(address, base + SPI_ADDRESS_REG); + + iowrite32(data, base + SPI_TRIGGER_REG); +} + +static void spi_write64(struct i915_spi *spi, u32 address, u64 data) +{ + void __iomem *base = spi->base; + + iowrite32(address, base + SPI_ADDRESS_REG); + + writeq(data, base + SPI_TRIGGER_REG); +} + static int spi_get_access_map(struct i915_spi *spi) { u32 flmap1; @@ -139,6 +169,113 @@ static int i915_spi_is_valid(struct i915_spi *spi) return 0; } +__maybe_unused +static unsigned int spi_get_region(const struct i915_spi *spi, loff_t from) +{ + unsigned int i; + + for (i = 0; i < spi->nregions; i++) { + if ((spi->regions[i].offset + spi->regions[i].size - 1) > from && + spi->regions[i].offset <= from && + spi->regions[i].size != 0) + break; + } + + return i; +} + +__maybe_unused +static ssize_t spi_write(struct i915_spi *spi, u8 region, + loff_t to, size_t len, const unsigned char *buf) +{ + size_t i; + size_t len8; + + spi_set_region_id(spi, region); + + len8 = ALIGN_DOWN(len, sizeof(u64)); + for (i = 0; i < len8; i += sizeof(u64)) { + u64 data; + + memcpy(&data, &buf[i], sizeof(u64)); + spi_write64(spi, to + i, data); + if (spi_error(spi)) + return -EIO; + } + + if (len8 != len) { /* caller ensure that write size is at least u32 */ + u32 data; + + memcpy(&data, &buf[i], sizeof(u32)); + spi_write32(spi, to + len8, data); + if (spi_error(spi)) + return -EIO; + } + + return len; +} + +__maybe_unused +static ssize_t spi_read(struct i915_spi *spi, u8 region, + loff_t from, size_t len, unsigned char *buf) +{ + size_t i; + size_t len8; + size_t len4; + + spi_set_region_id(spi, region); + + len8 = ALIGN_DOWN(len, sizeof(u64)); + for (i = 0; i < len8; i += sizeof(u64)) { + u64 data = spi_read64(spi, from + i); + + if (spi_error(spi)) + return -EIO; + + memcpy(&buf[i], &data, sizeof(data)); + } + + len4 = len - len8; + if (len4 >= sizeof(u32)) { + u32 data = spi_read32(spi, from + i); + + if (spi_error(spi)) + return -EIO; + memcpy(&buf[i], &data, sizeof(data)); + i += sizeof(u32); + len4 -= sizeof(u32); + } + + if (len4 > 0) { + u32 data = spi_read32(spi, from + i); + + if (spi_error(spi)) + return -EIO; + memcpy(&buf[i], &data, len4); + } + + return len; +} + +__maybe_unused +static ssize_t +spi_erase(struct i915_spi *spi, u8 region, loff_t from, u64 len, u64 *fail_addr) +{ + u64 i; + const u32 block = 0x10; + void __iomem *base = spi->base; + + for (i = 0; i < len; i += SZ_4K) { + iowrite32(from + i, base + SPI_ADDRESS_REG); + iowrite32(region << 24 | block, base + SPI_ERASE_REG); + /* Since the writes are via sguint + * we cannot do back to back erases. + */ + msleep(50); + } + return len; +} + static int i915_spi_init(struct i915_spi *spi, struct device *device) { int ret; From patchwork Mon Mar 8 06:27:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Winkler, Tomas" X-Patchwork-Id: 12121569 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7C20C433E6 for ; Mon, 8 Mar 2021 06:28:26 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 90765651EF for ; Mon, 8 Mar 2021 06:28:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 90765651EF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2B5AF6E811; Mon, 8 Mar 2021 06:28:26 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id 478A26E80B for ; Mon, 8 Mar 2021 06:28:25 +0000 (UTC) IronPort-SDR: 0V0ircQ2wI9WB8/B95dXXh3Upp43WFgFtRBQXZtfgwpS9ZhZ456DEwQqNhZB8HVZIymEANCe+7 Hm3YxKubqsng== X-IronPort-AV: E=McAfee;i="6000,8403,9916"; a="249354845" X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="249354845" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:22 -0800 IronPort-SDR: MY/0A5iLYhes/kzY16EZbxFIKWfti/TuB6njLQbEI+a8mq9vYJO1W+nhRwDDQxx3jZIRCNel89 mpJX/+h/8WrA== X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="409181981" Received: from twinkler-lnx.jer.intel.com ([10.12.91.138]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:19 -0800 From: Tomas Winkler To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi Date: Mon, 8 Mar 2021 08:27:44 +0200 Message-Id: <20210308062748.208017-7-tomas.winkler@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210308062748.208017-1-tomas.winkler@intel.com> References: <20210308062748.208017-1-tomas.winkler@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 06/10 v2] drm/i915/spi: spi register with mtd X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexander Usyskin , intel-gfx@lists.freedesktop.org, Lucas De Marchi , linux-mtd@lists.infradead.org, Tomas Winkler , Vitaly Lubart Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Register the on-die spi device with the mtd subsystem. Add mtd access stub functions. Cc: Rodrigo Vivi Cc: Lucas De Marchi Signed-off-by: Tomas Winkler --- V2: 1. Rebase drivers/gpu/drm/i915/spi/i915_spi.c | 86 ++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/spi/i915_spi.c b/drivers/gpu/drm/i915/spi/i915_spi.c index df6a461d520d..bdf58e14fd6b 100644 --- a/drivers/gpu/drm/i915/spi/i915_spi.c +++ b/drivers/gpu/drm/i915/spi/i915_spi.c @@ -15,7 +15,11 @@ #include #include +#include +#include + struct i915_spi { + struct mtd_info mtd; void __iomem *base; size_t size; unsigned int nregions; @@ -344,6 +348,73 @@ static int i915_spi_init(struct i915_spi *spi, struct device *device) return n; } +static int i915_spi_erase(struct mtd_info *mtd, struct erase_info *info) +{ + dev_err(&mtd->dev, "erasing %lld %lld\n", info->addr, info->len); + + return 0; +} + +static int i915_spi_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) +{ + dev_err(&mtd->dev, "read %lld %zd\n", from, len); + + return 0; +} + +static int i915_spi_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) +{ + dev_err(&mtd->dev, "writing %lld %zd\n", to, len); + + return 0; +} + +static int i915_spi_init_mtd(struct i915_spi *spi, struct device *device, + unsigned int nparts) +{ + unsigned int i; + unsigned int n; + struct mtd_partition *parts = NULL; + int ret; + + dev_dbg(device, "registering with mtd\n"); + + spi->mtd.owner = THIS_MODULE; + spi->mtd.dev.parent = device; + spi->mtd.flags = MTD_CAP_NORFLASH | MTD_WRITEABLE; + spi->mtd.type = MTD_DATAFLASH; + spi->mtd.priv = spi; + spi->mtd._write = i915_spi_write; + spi->mtd._read = i915_spi_read; + spi->mtd._erase = i915_spi_erase; + spi->mtd.writesize = SZ_4; /* 4 bytes granularity */ + spi->mtd.erasesize = SZ_4K; /* 4K bytes granularity */ + spi->mtd.size = spi->size; + + parts = kcalloc(spi->nregions, sizeof(*parts), GFP_KERNEL); + if (!parts) + return -ENOMEM; + + for (i = 0, n = 0; i < spi->nregions && n < nparts; i++) { + if (!spi->regions[i].is_readable) + continue; + parts[n].name = spi->regions[i].name; + parts[n].offset = spi->regions[i].offset; + parts[n].size = spi->regions[i].size; + if (!spi->regions[i].is_writable) + parts[n].mask_flags = MTD_WRITEABLE; + n++; + } + + ret = mtd_device_register(&spi->mtd, parts, n); + + kfree(parts); + + return ret; +} + static int i915_spi_probe(struct platform_device *platdev) { struct resource *bar; @@ -413,15 +484,28 @@ static int i915_spi_probe(struct platform_device *platdev) return -ENODEV; } + ret = i915_spi_init_mtd(spi, device, ret); + if (ret) { + dev_err(device, "i915-spi failed init mtd %d\n", ret); + return ret; + } + platform_set_drvdata(platdev, spi); dev_dbg(device, "i915-spi is bound\n"); - return 0; + return ret; } static int i915_spi_remove(struct platform_device *platdev) { + struct i915_spi *spi = platform_get_drvdata(platdev); + + if (!spi) + return 0; + + mtd_device_unregister(&spi->mtd); + platform_set_drvdata(platdev, NULL); return 0; From patchwork Mon Mar 8 06:27:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Winkler, Tomas" X-Patchwork-Id: 12121573 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EE908C433E6 for ; Mon, 8 Mar 2021 06:28:29 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A2BDE651EF for ; Mon, 8 Mar 2021 06:28:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A2BDE651EF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3584D6E804; Mon, 8 Mar 2021 06:28:29 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id BBDEB6E81A for ; Mon, 8 Mar 2021 06:28:27 +0000 (UTC) IronPort-SDR: sz2DfoeABRruntOG2uYE/eNQgCuGCvp/1JeaY6VcJKUQErpOar4PKq/DygPkWQEfe5JTGP6g/Z FYUrd4k5b8mQ== X-IronPort-AV: E=McAfee;i="6000,8403,9916"; a="249354852" X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="249354852" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:27 -0800 IronPort-SDR: YaG8UgBBFu3NnNGKqnVf1pXZTiJ2qyM1F5GI6CRelJS0GMi0M8bsrHPqJ3LUv0VRLKKCePaqrN j2DsjElyoiHA== X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="409181995" Received: from twinkler-lnx.jer.intel.com ([10.12.91.138]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:23 -0800 From: Tomas Winkler To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi Date: Mon, 8 Mar 2021 08:27:45 +0200 Message-Id: <20210308062748.208017-8-tomas.winkler@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210308062748.208017-1-tomas.winkler@intel.com> References: <20210308062748.208017-1-tomas.winkler@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 07/10 v2] drm/i915/spi: mtd: implement access handlers X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexander Usyskin , intel-gfx@lists.freedesktop.org, Lucas De Marchi , linux-mtd@lists.infradead.org, Tomas Winkler , Vitaly Lubart Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Implement mtd read, erase, and write handlers. For erase operation address and size should be 4K aligned. For write operation address and size has to be 4bytes aligned. Cc: Rodrigo Vivi Cc: Lucas De Marchi Signed-off-by: Tomas Winkler Signed-off-by: Vitaly Lubart --- V2: 1. Rebase drivers/gpu/drm/i915/spi/i915_spi.c | 138 ++++++++++++++++++++++++++-- 1 file changed, 131 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/spi/i915_spi.c b/drivers/gpu/drm/i915/spi/i915_spi.c index bdf58e14fd6b..1e8a40339e6d 100644 --- a/drivers/gpu/drm/i915/spi/i915_spi.c +++ b/drivers/gpu/drm/i915/spi/i915_spi.c @@ -173,7 +173,6 @@ static int i915_spi_is_valid(struct i915_spi *spi) return 0; } -__maybe_unused static unsigned int spi_get_region(const struct i915_spi *spi, loff_t from) { unsigned int i; @@ -188,7 +187,6 @@ static unsigned int spi_get_region(const struct i915_spi *spi, loff_t from) return i; } -__maybe_unused static ssize_t spi_write(struct i915_spi *spi, u8 region, loff_t to, size_t len, const unsigned char *buf) { @@ -219,7 +217,6 @@ static ssize_t spi_write(struct i915_spi *spi, u8 region, return len; } -__maybe_unused static ssize_t spi_read(struct i915_spi *spi, u8 region, loff_t from, size_t len, unsigned char *buf) { @@ -261,7 +258,6 @@ static ssize_t spi_read(struct i915_spi *spi, u8 region, return len; } -__maybe_unused static ssize_t spi_erase(struct i915_spi *spi, u8 region, loff_t from, u64 len, u64 *fail_addr) { @@ -350,7 +346,63 @@ static int i915_spi_init(struct i915_spi *spi, struct device *device) static int i915_spi_erase(struct mtd_info *mtd, struct erase_info *info) { - dev_err(&mtd->dev, "erasing %lld %lld\n", info->addr, info->len); + struct i915_spi *spi; + unsigned int idx; + u8 region; + u64 addr; + ssize_t bytes; + loff_t from; + size_t len; + size_t total_len; + + if (!mtd || !info) + return -EINVAL; + + spi = mtd->priv; + + if (!IS_ALIGNED(info->addr, SZ_4K) || !IS_ALIGNED(info->len, SZ_4K)) { + dev_err(&mtd->dev, "unaligned erase %llx %llx\n", + info->addr, info->len); + info->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + return -EINVAL; + } + + total_len = info->len; + addr = info->addr; + + while (total_len > 0) { + if (!IS_ALIGNED(addr, SZ_4K) || !IS_ALIGNED(total_len, SZ_4K)) { + dev_err(&mtd->dev, "unaligned erase %llx %zx\n", addr, total_len); + info->fail_addr = addr; + return -ERANGE; + } + + idx = spi_get_region(spi, addr); + if (idx >= spi->nregions) { + dev_err(&mtd->dev, "out of range"); + info->fail_addr = MTD_FAIL_ADDR_UNKNOWN; + return -ERANGE; + } + + from = addr - spi->regions[idx].offset; + region = spi->regions[idx].id; + len = total_len; + if (len > spi->regions[idx].size - from) + len = spi->regions[idx].size - from; + + dev_dbg(&mtd->dev, "erasing region[%d] %s from %llx len %zx\n", + region, spi->regions[idx].name, from, len); + + bytes = spi_erase(spi, region, from, len, &info->fail_addr); + if (bytes < 0) { + dev_dbg(&mtd->dev, "erase failed with %zd\n", bytes); + info->fail_addr += spi->regions[idx].offset; + return bytes; + } + + addr += len; + total_len -= len; + } return 0; } @@ -358,7 +410,43 @@ static int i915_spi_erase(struct mtd_info *mtd, struct erase_info *info) static int i915_spi_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { - dev_err(&mtd->dev, "read %lld %zd\n", from, len); + struct i915_spi *spi; + ssize_t ret; + unsigned int idx; + u8 region; + + if (!mtd) + return -EINVAL; + + spi = mtd->priv; + + if (!IS_ALIGNED(from, sizeof(u32))) { + dev_err(&mtd->dev, "unaligned read %lld %zd\n", from, len); + return -EINVAL; + } + + idx = spi_get_region(spi, from); + + dev_dbg(&mtd->dev, "reading region[%d] %s from %lld len %zd\n", + spi->regions[idx].id, spi->regions[idx].name, from, len); + + if (idx >= spi->nregions) { + dev_err(&mtd->dev, "out of ragnge"); + return -ERANGE; + } + + from -= spi->regions[idx].offset; + region = spi->regions[idx].id; + if (len > spi->regions[idx].size - from) + len = spi->regions[idx].size - from; + + ret = spi_read(spi, region, from, len, buf); + if (ret < 0) { + dev_dbg(&mtd->dev, "read failed with %zd\n", ret); + return ret; + } + + *retlen = ret; return 0; } @@ -366,7 +454,43 @@ static int i915_spi_read(struct mtd_info *mtd, loff_t from, size_t len, static int i915_spi_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { - dev_err(&mtd->dev, "writing %lld %zd\n", to, len); + struct i915_spi *spi; + ssize_t ret; + unsigned int idx; + u8 region; + + if (!mtd) + return -EINVAL; + + spi = mtd->priv; + + if (!(IS_ALIGNED(len, 4) && IS_ALIGNED(to, 4))) { + dev_err(&mtd->dev, "unaligned write %lld %zd\n", to, len); + return -EINVAL; + } + + idx = spi_get_region(spi, to); + + dev_dbg(&mtd->dev, "writing region[%d] %s to %lld len %zd\n", + spi->regions[idx].id, spi->regions[idx].name, to, len); + + if (idx >= spi->nregions) { + dev_err(&mtd->dev, "out of range"); + return -ERANGE; + } + + to -= spi->regions[idx].offset; + region = spi->regions[idx].id; + if (len > spi->regions[idx].size - to) + len = spi->regions[idx].size - to; + + ret = spi_write(spi, region, to, len, buf); + if (ret < 0) { + dev_dbg(&mtd->dev, "write failed with %zd\n", ret); + return ret; + } + + *retlen = ret; return 0; } From patchwork Mon Mar 8 06:27:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Winkler, Tomas" X-Patchwork-Id: 12121575 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 93246C433DB for ; Mon, 8 Mar 2021 06:28:33 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3A9A7651EB for ; Mon, 8 Mar 2021 06:28:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3A9A7651EB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B37896E819; Mon, 8 Mar 2021 06:28:32 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id 56BAF6E819 for ; Mon, 8 Mar 2021 06:28:31 +0000 (UTC) IronPort-SDR: xsHR+MrUSmDKa8NVV/daElTmXiqRm5fi13rMMiuswd3i1EQKZxp1Npla2boM+D2EBnihW3A4wP gANtPUuh5FxA== X-IronPort-AV: E=McAfee;i="6000,8403,9916"; a="249354858" X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="249354858" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:31 -0800 IronPort-SDR: 8E03uU3hoRk/FMR7EIEWVr2GexCm2Wo3DkfMWWZviADTLzAgaqdIoBAHoFzSFzDNkzQj0y8KgF TtxFZZsX1Beg== X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="409182018" Received: from twinkler-lnx.jer.intel.com ([10.12.91.138]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:27 -0800 From: Tomas Winkler To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi Date: Mon, 8 Mar 2021 08:27:46 +0200 Message-Id: <20210308062748.208017-9-tomas.winkler@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210308062748.208017-1-tomas.winkler@intel.com> References: <20210308062748.208017-1-tomas.winkler@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 08/10 v2] drm/i915/spi: serialize spi access X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexander Usyskin , intel-gfx@lists.freedesktop.org, Lucas De Marchi , linux-mtd@lists.infradead.org, Tomas Winkler , Vitaly Lubart Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" The SPI regions cannot be accessed in parallel because for each region the region selector has to be set. Add a mutex to prevent parallel access. Cc: Rodrigo Vivi Cc: Lucas De Marchi Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler --- V2: 1. Rebase drivers/gpu/drm/i915/spi/i915_spi.c | 32 +++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/spi/i915_spi.c b/drivers/gpu/drm/i915/spi/i915_spi.c index 1e8a40339e6d..9de49d00297d 100644 --- a/drivers/gpu/drm/i915/spi/i915_spi.c +++ b/drivers/gpu/drm/i915/spi/i915_spi.c @@ -20,6 +20,7 @@ struct i915_spi { struct mtd_info mtd; + struct mutex lock; /* region access lock */ void __iomem *base; size_t size; unsigned int nregions; @@ -354,6 +355,7 @@ static int i915_spi_erase(struct mtd_info *mtd, struct erase_info *info) loff_t from; size_t len; size_t total_len; + int ret = 0; if (!mtd || !info) return -EINVAL; @@ -370,18 +372,23 @@ static int i915_spi_erase(struct mtd_info *mtd, struct erase_info *info) total_len = info->len; addr = info->addr; + if (!mutex_trylock(&spi->lock)) + return -EBUSY; + while (total_len > 0) { if (!IS_ALIGNED(addr, SZ_4K) || !IS_ALIGNED(total_len, SZ_4K)) { dev_err(&mtd->dev, "unaligned erase %llx %zx\n", addr, total_len); info->fail_addr = addr; - return -ERANGE; + ret = -ERANGE; + goto out; } idx = spi_get_region(spi, addr); if (idx >= spi->nregions) { dev_err(&mtd->dev, "out of range"); info->fail_addr = MTD_FAIL_ADDR_UNKNOWN; - return -ERANGE; + ret = -ERANGE; + goto out; } from = addr - spi->regions[idx].offset; @@ -397,14 +404,17 @@ static int i915_spi_erase(struct mtd_info *mtd, struct erase_info *info) if (bytes < 0) { dev_dbg(&mtd->dev, "erase failed with %zd\n", bytes); info->fail_addr += spi->regions[idx].offset; - return bytes; + ret = bytes; + goto out; } addr += len; total_len -= len; } - return 0; +out: + mutex_unlock(&spi->lock); + return ret; } static int i915_spi_read(struct mtd_info *mtd, loff_t from, size_t len, @@ -440,14 +450,19 @@ static int i915_spi_read(struct mtd_info *mtd, loff_t from, size_t len, if (len > spi->regions[idx].size - from) len = spi->regions[idx].size - from; + if (!mutex_trylock(&spi->lock)) + return -EBUSY; + ret = spi_read(spi, region, from, len, buf); if (ret < 0) { dev_dbg(&mtd->dev, "read failed with %zd\n", ret); + mutex_unlock(&spi->lock); return ret; } *retlen = ret; + mutex_unlock(&spi->lock); return 0; } @@ -484,14 +499,19 @@ static int i915_spi_write(struct mtd_info *mtd, loff_t to, size_t len, if (len > spi->regions[idx].size - to) len = spi->regions[idx].size - to; + if (!mutex_trylock(&spi->lock)) + return -EBUSY; + ret = spi_write(spi, region, to, len, buf); if (ret < 0) { dev_dbg(&mtd->dev, "write failed with %zd\n", ret); + mutex_unlock(&spi->lock); return ret; } *retlen = ret; + mutex_unlock(&spi->lock); return 0; } @@ -505,6 +525,8 @@ static int i915_spi_init_mtd(struct i915_spi *spi, struct device *device, dev_dbg(device, "registering with mtd\n"); + mutex_init(&spi->lock); + spi->mtd.owner = THIS_MODULE; spi->mtd.dev.parent = device; spi->mtd.flags = MTD_CAP_NORFLASH | MTD_WRITEABLE; @@ -630,6 +652,8 @@ static int i915_spi_remove(struct platform_device *platdev) mtd_device_unregister(&spi->mtd); + mutex_destroy(&spi->lock); + platform_set_drvdata(platdev, NULL); return 0; From patchwork Mon Mar 8 06:27:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Winkler, Tomas" X-Patchwork-Id: 12121577 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.9 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,SPF_HELO_NONE,SPF_PASS, UNWANTED_LANGUAGE_BODY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D36E6C433DB for ; Mon, 8 Mar 2021 06:28:47 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8F18C64DE5 for ; Mon, 8 Mar 2021 06:28:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8F18C64DE5 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 262D46E817; Mon, 8 Mar 2021 06:28:47 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id E6B276E817 for ; Mon, 8 Mar 2021 06:28:45 +0000 (UTC) IronPort-SDR: qIFP0JvVpfsgaS6Wr+nJ6QqLdtvOWvagWHA0vUOmGPVjwqow4wTTd6nzRnOB2vxvAK2x1vS9/i cd4WLkKj8HGw== X-IronPort-AV: E=McAfee;i="6000,8403,9916"; a="249354870" X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="249354870" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:35 -0800 IronPort-SDR: Z+T8H/+nt6auK0aiH5DmMiNNG5QJqF/6TBXwMiiTcPDEghr1OO/lrpFSWg7ozgEpJ4lR6q7SiT bv7qzC2pGVNw== X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="409182028" Received: from twinkler-lnx.jer.intel.com ([10.12.91.138]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:31 -0800 From: Tomas Winkler To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi Date: Mon, 8 Mar 2021 08:27:47 +0200 Message-Id: <20210308062748.208017-10-tomas.winkler@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210308062748.208017-1-tomas.winkler@intel.com> References: <20210308062748.208017-1-tomas.winkler@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 09/10 v2] MAINTAINERS: add Intel i915 spi driver entry X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-mtd@lists.infradead.org, intel-gfx@lists.freedesktop.org, Tomas Winkler , Alexander Usyskin , Vitaly Lubart Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Add entry for Intel i915 spi driver. Signed-off-by: Tomas Winkler --- V2: 1. New in the series. MAINTAINERS | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 23f3c02493a8..dfe46844bbef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8992,6 +8992,17 @@ L: platform-driver-x86@vger.kernel.org S: Maintained F: drivers/platform/x86/intel-hid.c +INTEL I915 SPI DRIVER +M: Tomas Winkler +L: intel-gfx@lists.freedesktop.org +S: Supported +W: https://01.org/linuxgraphics/ +Q: http://patchwork.freedesktop.org/project/intel-gfx/ +B: https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs +C: irc://chat.freenode.net/intel-gfx +T: git git://anongit.freedesktop.org/drm-intel +F: drivers/gpu/drm/i915/spi/* + INTEL I/OAT DMA DRIVER M: Dave Jiang R: Dan Williams From patchwork Mon Mar 8 06:27:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Winkler, Tomas" X-Patchwork-Id: 12121579 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70D28C433E0 for ; Mon, 8 Mar 2021 06:28:48 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 301FD64DE5 for ; Mon, 8 Mar 2021 06:28:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 301FD64DE5 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A4B5D6E81B; Mon, 8 Mar 2021 06:28:47 +0000 (UTC) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4F8D76E817 for ; Mon, 8 Mar 2021 06:28:46 +0000 (UTC) IronPort-SDR: dof4xCgWUlghuDzjAzAk0dljmH7Icfio/ke3Z60yMhg0VZ2kkUObveVb3bzpFwowCa+ES8LT81 3GnNDEilDPrA== X-IronPort-AV: E=McAfee;i="6000,8403,9916"; a="249354875" X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="249354875" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:38 -0800 IronPort-SDR: dw16VgBnX99MAH347jLFNexdMxpQvor4XEEavslsTbxRWXr/M7CUNpy3JVaGAL8dE+SIAYUq4R 96cgUwoBY47w== X-IronPort-AV: E=Sophos;i="5.81,231,1610438400"; d="scan'208";a="409182040" Received: from twinkler-lnx.jer.intel.com ([10.12.91.138]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Mar 2021 22:28:35 -0800 From: Tomas Winkler To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi Date: Mon, 8 Mar 2021 08:27:48 +0200 Message-Id: <20210308062748.208017-11-tomas.winkler@intel.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210308062748.208017-1-tomas.winkler@intel.com> References: <20210308062748.208017-1-tomas.winkler@intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [RFC PATCH 10/10 v2] mtd: use refcount to prevent corruption X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-mtd@lists.infradead.org, intel-gfx@lists.freedesktop.org, Tomas Winkler , Alexander Usyskin , Vitaly Lubart Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" When underlying device is removed mtd core will crash in case user space is holding open handle. Need to use proper refcounting so device is release only when has no users. Signed-off-by: Tomas Winkler --- V2: 1. define pr_fmt macro drivers/mtd/mtdcore.c | 64 +++++++++++++++++++++++++---------------- drivers/mtd/mtdcore.h | 1 + drivers/mtd/mtdpart.c | 13 +++++---- include/linux/mtd/mtd.h | 2 +- 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 2d6423d89a17..152aba9822a0 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -7,6 +7,7 @@ * Copyright © 2006 Red Hat UK Limited */ +#define pr_fmt(fmt) "[" KBUILD_MODNAME ":%s:%d] " fmt, __func__, __LINE__ #include #include #include @@ -93,9 +94,31 @@ static void mtd_release(struct device *dev) dev_t index = MTD_DEVT(mtd->index); /* remove /dev/mtdXro node */ + if (mtd_is_partition(mtd)) + release_mtd_partition(mtd); + device_destroy(&mtd_class, index + 1); } +static void mtd_device_release(struct kref *kref) +{ + struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt); + + pr_debug("releasing %s\n", mtd->name); + + if (mtd->nvmem) { + nvmem_unregister(mtd->nvmem); + mtd->nvmem = NULL; + } + + idr_remove(&mtd_idr, mtd->index); + of_node_put(mtd_get_of_node(mtd)); + + device_unregister(&mtd->dev); + + module_put(THIS_MODULE); +} + static ssize_t mtd_type_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -619,7 +642,7 @@ int add_mtd_device(struct mtd_info *mtd) } mtd->index = i; - mtd->usecount = 0; + kref_init(&mtd->refcnt); /* default value if not set by driver */ if (mtd->bitflip_threshold == 0) @@ -719,6 +742,8 @@ int del_mtd_device(struct mtd_info *mtd) int ret; struct mtd_notifier *not; + pr_debug("%s %s\n", __func__, mtd->name); + mutex_lock(&mtd_table_mutex); debugfs_remove_recursive(mtd->dbg.dfs_dir); @@ -733,23 +758,8 @@ int del_mtd_device(struct mtd_info *mtd) list_for_each_entry(not, &mtd_notifiers, list) not->remove(mtd); - if (mtd->usecount) { - printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n", - mtd->index, mtd->name, mtd->usecount); - ret = -EBUSY; - } else { - /* Try to remove the NVMEM provider */ - if (mtd->nvmem) - nvmem_unregister(mtd->nvmem); - - device_unregister(&mtd->dev); - - idr_remove(&mtd_idr, mtd->index); - of_node_put(mtd_get_of_node(mtd)); - - module_put(THIS_MODULE); - ret = 0; - } + kref_put(&mtd->refcnt, mtd_device_release); + ret = 0; out_error: mutex_unlock(&mtd_table_mutex); @@ -984,20 +994,23 @@ int __get_mtd_device(struct mtd_info *mtd) if (!try_module_get(master->owner)) return -ENODEV; + kref_get(&mtd->refcnt); + pr_debug("get mtd %s %d\n", mtd->name, kref_read(&mtd->refcnt)); + if (master->_get_device) { err = master->_get_device(mtd); if (err) { + kref_put(&mtd->refcnt, mtd_device_release); module_put(master->owner); return err; } } - master->usecount++; - while (mtd->parent) { - mtd->usecount++; mtd = mtd->parent; + kref_get(&mtd->refcnt); + pr_debug("get mtd %s %d\n", mtd->name, kref_read(&mtd->refcnt)); } return 0; @@ -1055,14 +1068,15 @@ void __put_mtd_device(struct mtd_info *mtd) { struct mtd_info *master = mtd_get_master(mtd); + kref_put(&mtd->refcnt, mtd_device_release); + pr_debug("put mtd %s %d\n", mtd->name, kref_read(&mtd->refcnt)); + while (mtd->parent) { - --mtd->usecount; - BUG_ON(mtd->usecount < 0); mtd = mtd->parent; + kref_put(&mtd->refcnt, mtd_device_release); + pr_debug("put mtd %s %d\n", mtd->name, kref_read(&mtd->refcnt)); } - master->usecount--; - if (master->_put_device) master->_put_device(master); diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index b5eefeabf310..b014861a06a6 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h @@ -12,6 +12,7 @@ int __must_check add_mtd_device(struct mtd_info *mtd); int del_mtd_device(struct mtd_info *mtd); int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); int del_mtd_partitions(struct mtd_info *); +void release_mtd_partition(struct mtd_info *mtd); struct mtd_partitions; diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 12ca4f19cb14..6d70b5d0e663 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -27,10 +27,17 @@ static inline void free_partition(struct mtd_info *mtd) { + pr_err("free_partition \"%s\"\n", mtd->name); kfree(mtd->name); kfree(mtd); } +void release_mtd_partition(struct mtd_info *mtd) +{ + list_del_init(&mtd->part.node); + free_partition(mtd); +} + static struct mtd_info *allocate_partition(struct mtd_info *parent, const struct mtd_partition *part, int partno, uint64_t cur_offset) @@ -313,9 +320,6 @@ static int __mtd_del_partition(struct mtd_info *mtd) if (err) return err; - list_del(&child->part.node); - free_partition(mtd); - return 0; } @@ -341,9 +345,6 @@ static int __del_mtd_partitions(struct mtd_info *mtd) err = ret; continue; } - - list_del(&child->part.node); - free_partition(child); } return err; diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 157357ec1441..1217c9d8d69d 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -373,7 +373,7 @@ struct mtd_info { struct module *owner; struct device dev; - int usecount; + struct kref refcnt; struct mtd_debug_info dbg; struct nvmem_device *nvmem;