From patchwork Fri Mar 29 19:48:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Witold Sadowski X-Patchwork-Id: 13610985 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9426413B58C; Fri, 29 Mar 2024 19:49:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711741752; cv=none; b=uuTtHzAhKl8XMRRtcSqgj9V+DR15diFix5PgFbnUaEQ4iKuVRLyPz026xEYt/y3BtolI39cqYTOaxj1TG/JStMmvV/9iu959+nCLC4kWDfi9kzh7LBSLR/5ekN8imhPMCNG3H5HTXLZDLZoXsMyAAUEYUgjIW93m/HzPAlsk/9s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711741752; c=relaxed/simple; bh=xTVALSbBbBWsl/l8dgpPJ/5/oohMl624HLHwodkoJRc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=X3siAJeLnhFvAQB3SUxxE8i1hc5Px3KUFUIFX8flbG6s3RbVItSU6/AdCDafazpFxAeDr9cANPnoK64mWqtHLuZdqWDq3nbrPkBxfvABJ0VlGfYNnCc7TtvCUdFc71H4LzAUTpSDaKmvgYA4gYuP9uSW5wLjgXnIpJwRXDHJtpU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=OYJO7EMh; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="OYJO7EMh" Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 42TCGnSb028424; Fri, 29 Mar 2024 12:49:04 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= pfpt0220; bh=LwDE4hVpVUsTgpgBUWnH7+VxfWI+SH+0P4tn4Puet80=; b=OYJ O7EMhu1TAlWlM10F2Oti/ZlmKc9EcfxMooUfDxvZfhjN/HgX44VwGHAZ+lJ4BWCe DHIAQWyA82HBfTj6P1Y3mEQj66Ib5nW2zGmrKFb/bX3jdgPB7WSy5vydkjsH5j9J Zm5Zvp+afjeOkV0fZCzvAS7kPtU4ZHLRqpTyMfHdMjoaX9il6lzjqullaHr7Mr4z VqwQY03PJNE+NfsFUGHpSHejllDqwxOgH+hdR76PsuSSYrGDZzz9o6psegrMQbSs SHyUEtZuSouKGBNb1ECgFxQufGkwmwtNHrPe6vlZHp6Ow0FIVl//6vcB0Rxuogxm DdRG9BKYwjejbWiwp/Q== Received: from dc6wp-exch02.marvell.com ([4.21.29.225]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3x5wgphd3s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 Mar 2024 12:49:04 -0700 (PDT) Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Fri, 29 Mar 2024 12:49:02 -0700 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.4 via Frontend Transport; Fri, 29 Mar 2024 12:49:02 -0700 Received: from localhost.localdomain (unknown [10.110.150.170]) by maili.marvell.com (Postfix) with ESMTP id 61F273F707B; Fri, 29 Mar 2024 12:49:02 -0700 (PDT) From: Witold Sadowski To: , , CC: , , , , , Witold Sadowski Subject: [PATCH 1/5] spi: cadence: Add new bindings documentation for Cadence XSPI Date: Fri, 29 Mar 2024 12:48:45 -0700 Message-ID: <20240329194849.25554-2-wsadowski@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240329194849.25554-1-wsadowski@marvell.com> References: <20240329194849.25554-1-wsadowski@marvell.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-GUID: x18rr20XsovfCrnsIYOlRkcn8RwavBHT X-Proofpoint-ORIG-GUID: x18rr20XsovfCrnsIYOlRkcn8RwavBHT X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-03-29_13,2024-03-28_01,2023-05-22_02 Add new bindings: - mrvl,xspi-nor compatible string Compatible string to enable Marvell XSPI modification - Multiple PHY configuration registers - base for xfer register set Signed-off-by: Witold Sadowski --- .../devicetree/bindings/spi/cdns,xspi.yaml | 84 ++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/cdns,xspi.yaml b/Documentation/devicetree/bindings/spi/cdns,xspi.yaml index eb0f92468185..d1fde8d4e9b8 100644 --- a/Documentation/devicetree/bindings/spi/cdns,xspi.yaml +++ b/Documentation/devicetree/bindings/spi/cdns,xspi.yaml @@ -20,23 +20,74 @@ allOf: properties: compatible: - const: cdns,xspi-nor + - const: cdns,xspi-nor + - const: mrvl,xspi-nor reg: items: - description: address and length of the controller register set - description: address and length of the Slave DMA data port - description: address and length of the auxiliary registers + - description: address and length of the xfer registers reg-names: items: - const: io - const: sdma - const: aux + - const: xferbase interrupts: maxItems: 1 + cdns,dll-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x707 + + cdns,rfile-phy-control: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x40000 + + cdns,rfile-phy-tsel: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + + cdns,phy-dq-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x101 + + cdns,phy-dqs-timing: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x700404 + + cdns,phy-gate-lpbk-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x200030 + + cdns,phy-dll-master-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x00800000 + + cdns,phy-dll-slave-ctrl: + description: | + PHY config register. Valid only for cdns,mrvl-xspi-nor + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0x0000ff01 + required: - compatible - reg @@ -68,6 +119,37 @@ examples: reg = <0>; }; + flash@1 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <75000000>; + reg = <1>; + }; + }; + }; + - | + #include + bus { + #address-cells = <2>; + #size-cells = <2>; + + xspi: spi@a0010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mrvl,xspi-nor"; + reg = <0x0 0xa0010000 0x0 0x1040>, + <0x0 0xb0000000 0x0 0x1000>, + <0x0 0xa0020000 0x0 0x100>; + <0x0 0xa0090000 0x0 0x100>; + reg-names = "io", "sdma", "aux", "xferbase"; + interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&gic>; + + flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <75000000>; + reg = <0>; + }; + flash@1 { compatible = "jedec,spi-nor"; spi-max-frequency = <75000000>; From patchwork Fri Mar 29 19:48:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Witold Sadowski X-Patchwork-Id: 13610986 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B49F813B58F; Fri, 29 Mar 2024 19:49:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711741752; cv=none; b=cYW1AIS3uQbKs30n423l6Oj+0qgTUMTf/VtRWRJWCJ4jyE+KHHjHmXd++KjKDPJNmclVBQA7PYikpyo4nzxS4G+eDXDAs1zlm6Npyklm9MV6mZSaVcPUreLERMRKJpybc6Lrj19Ac5nlCX7HE0o8Upfe2n6N7h1rJAUq02sxKmc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711741752; c=relaxed/simple; bh=RQfkxEbmUEursFfbk/NnyJASD3prRmM+bDbQdXUO1nM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=j0SLF6FF9NoUKH9FiyObx6239qxwHBkltrN76G10UFSKbSu5TcFY7CWxa3XyGq3W5q1p3M3LCNwBmJtruVCX4jSaFXoTD2ZwT/ITRspPXKAIVoQ1vUiy+BZRBznHSrbAWFbmKWa6cyOrcUoLXqEyN28tf4Q1Auy2RDvDvHDWs7k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=YpK+vCPh; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="YpK+vCPh" Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 42TCGnSc028424; Fri, 29 Mar 2024 12:49:05 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= pfpt0220; bh=N90THS7jWW4+Nwtm6d/5q6ZFs8Zl+YTdX/fB3Xm0y9Y=; b=YpK +vCPhQinuC7Iu4YoFPDjBmuhHSGQSwO1Vlwwp8LHqfMQsOdbN/XDw9CKT2Qdin15 JL/T3DimMigijwY2qzJPsaB1uBq3ktYd1G51vDeLjH6TGg6r0tfim1KpBwReml+X 4Iqg7cAw6tbSAIBR1kItL/JLbwW8g0ZA2Ee2MxxvfBazxQeo0FCP9Rjucz1XDbSy 59tcK8C9xgCQFNYVBC3CWbDgWrJK2WS9jKhyNk5fQMzEtFkkeboAFbB8Gh1cob13 phlIAtuSOBqCasWBNqmkOeRjRf7Rz4ojay5ru4H4j4DZUahuzH64jlX6ZPHMOSs9 0Q4xoJf3OnijLk9f7pA== Received: from dc5-exch05.marvell.com ([199.233.59.128]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3x5wgphd3v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 Mar 2024 12:49:05 -0700 (PDT) Received: from DC5-EXCH05.marvell.com (10.69.176.209) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Fri, 29 Mar 2024 12:49:04 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH05.marvell.com (10.69.176.209) with Microsoft SMTP Server id 15.2.1544.4 via Frontend Transport; Fri, 29 Mar 2024 12:49:04 -0700 Received: from localhost.localdomain (unknown [10.110.150.170]) by maili.marvell.com (Postfix) with ESMTP id 4FAED3F707C; Fri, 29 Mar 2024 12:49:04 -0700 (PDT) From: Witold Sadowski To: , , CC: , , , , , Witold Sadowski Subject: [PATCH 2/5] spi: cadence: Add Marvell IP modification changes Date: Fri, 29 Mar 2024 12:48:46 -0700 Message-ID: <20240329194849.25554-3-wsadowski@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240329194849.25554-1-wsadowski@marvell.com> References: <20240329194849.25554-1-wsadowski@marvell.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-GUID: PDCAkOAO3ZFqdtEAdYLWlcMClfIMJse3 X-Proofpoint-ORIG-GUID: PDCAkOAO3ZFqdtEAdYLWlcMClfIMJse3 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-03-29_13,2024-03-28_01,2023-05-22_02 Add support for Marvell IP modification - clock divider, and PHY config, and IRQ clearing. Clock divider block is build into Cadence XSPI controller and is connected directly to 800MHz clock. As PHY config is not set directly in IP block, driver can load custom PHY configuration values. To correctly clear interrupt in Marvell implementation MSI-X must be cleared too. Signed-off-by: Witold Sadowski --- drivers/spi/spi-cadence-xspi.c | 311 ++++++++++++++++++++++++++++++++- 1 file changed, 306 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c index 8648b8eb080d..f570b2920b18 100644 --- a/drivers/spi/spi-cadence-xspi.c +++ b/drivers/spi/spi-cadence-xspi.c @@ -189,6 +189,43 @@ ((op)->data.dir == SPI_MEM_DATA_IN) ? \ CDNS_XSPI_STIG_CMD_DIR_READ : CDNS_XSPI_STIG_CMD_DIR_WRITE)) +/*PHY default values*/ +#define REGS_DLL_PHY_CTRL 0x00000707 +#define CTB_RFILE_PHY_CTRL 0x00004000 +#define RFILE_PHY_TSEL 0x00000000 +#define RFILE_PHY_DQ_TIMING 0x00000101 +#define RFILE_PHY_DQS_TIMING 0x00700404 +#define RFILE_PHY_GATE_LPBK_CTRL 0x00200030 +#define RFILE_PHY_DLL_MASTER_CTRL 0x00800000 +#define RFILE_PHY_DLL_SLAVE_CTRL 0x0000ff01 + +/*PHY config rtegisters*/ +#define CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL 0x1034 +#define CDNS_XSPI_PHY_CTB_RFILE_PHY_CTRL 0x0080 +#define CDNS_XSPI_PHY_CTB_RFILE_PHY_TSEL 0x0084 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQ_TIMING 0x0000 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQS_TIMING 0x0004 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL 0x0008 +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_MASTER_CTRL 0x000c +#define CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_SLAVE_CTRL 0x0010 +#define CDNS_XSPI_DATASLICE_RFILE_PHY_DLL_OBS_REG_0 0x001c + +#define CDNS_XSPI_DLL_RST_N BIT(24) +#define CDNS_XSPI_DLL_LOCK BIT(0) + +/* Marvell clock config register */ +#define CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG 0x2020 +#define CDNS_MRVL_XSPI_CLK_ENABLE BIT(0) +#define CDNS_MRVL_XSPI_CLK_DIV GENMASK(4, 1) + +/* Marvell MSI-X clear interrupt register */ +#define CDNS_MRVL_XSPI_SPIX_INTR_AUX 0x2000 +#define CDNS_MRVL_MSIX_CLEAR_IRQ 0x01 + +/* Marvell clock macros */ +#define CDNS_MRVL_XSPI_CLOCK_IO_HZ 800000000 +#define CDNS_MRVL_XSPI_CLOCK_DIVIDED(div) ((CDNS_MRVL_XSPI_CLOCK_IO_HZ) / (div)) + enum cdns_xspi_stig_instr_type { CDNS_XSPI_STIG_INSTR_TYPE_0, CDNS_XSPI_STIG_INSTR_TYPE_1, @@ -208,6 +245,7 @@ enum cdns_xspi_stig_cmd_dir { struct cdns_xspi_dev { struct platform_device *pdev; struct device *dev; + bool mrvl_hw_overlay; void __iomem *iobase; void __iomem *auxbase; @@ -228,6 +266,157 @@ struct cdns_xspi_dev { u8 hw_num_banks; }; +#define MRVL_DEFAULT_CLK 25000000 + +const int cdns_mrvl_xspi_clk_div_list[] = { + 4, //0x0 = Divide by 4. SPI clock is 200 MHz. + 6, //0x1 = Divide by 6. SPI clock is 133.33 MHz. + 8, //0x2 = Divide by 8. SPI clock is 100 MHz. + 10, //0x3 = Divide by 10. SPI clock is 80 MHz. + 12, //0x4 = Divide by 12. SPI clock is 66.666 MHz. + 16, //0x5 = Divide by 16. SPI clock is 50 MHz. + 18, //0x6 = Divide by 18. SPI clock is 44.44 MHz. + 20, //0x7 = Divide by 20. SPI clock is 40 MHz. + 24, //0x8 = Divide by 24. SPI clock is 33.33 MHz. + 32, //0x9 = Divide by 32. SPI clock is 25 MHz. + 40, //0xA = Divide by 40. SPI clock is 20 MHz. + 50, //0xB = Divide by 50. SPI clock is 16 MHz. + 64, //0xC = Divide by 64. SPI clock is 12.5 MHz. + 128, //0xD = Divide by 128. SPI clock is 6.25 MHz. + -1 //End of list +}; + +static bool cdns_xspi_reset_dll(struct cdns_xspi_dev *cdns_xspi) +{ + u32 dll_cntrl = readl(cdns_xspi->iobase + + CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL); + u32 dll_lock; + + /*Reset DLL*/ + dll_cntrl |= CDNS_XSPI_DLL_RST_N; + writel(dll_cntrl, cdns_xspi->iobase + + CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL); + + /*Wait for DLL lock*/ + return readl_relaxed_poll_timeout(cdns_xspi->iobase + + CDNS_XSPI_INTR_STATUS_REG, + dll_lock, ((dll_lock & CDNS_XSPI_DLL_LOCK) == 1), 10, 10000); +} + +static void cdns_configure_phy_register_io(struct cdns_xspi_dev *cdns_xspi, + const char *prop_name, + u64 default_value, u64 offset) +{ + struct device_node *node_prop = cdns_xspi->pdev->dev.of_node; + u64 phy_cfg; + + if (of_property_read_u64(node_prop, prop_name, &phy_cfg)) + phy_cfg = default_value; + writel(phy_cfg, + cdns_xspi->iobase + offset); +} + +static void cdns_configure_phy_register_aux(struct cdns_xspi_dev *cdns_xspi, + const char *prop_name, + u64 default_value, u64 offset) +{ + struct device_node *node_prop = cdns_xspi->pdev->dev.of_node; + u64 phy_cfg; + + if (of_property_read_u64(node_prop, "cdns,dll-phy-control", &phy_cfg)) + phy_cfg = default_value; + writel(phy_cfg, + cdns_xspi->auxbase + offset); +} + +//Static confiuration of PHY +static bool cdns_xspi_configure_phy(struct cdns_xspi_dev *cdns_xspi) +{ + cdns_configure_phy_register_io(cdns_xspi, + "cdns,dll-phy-control", + REGS_DLL_PHY_CTRL, + CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL); + cdns_configure_phy_register_aux(cdns_xspi, + "cdns,rfile-phy-control", + CTB_RFILE_PHY_CTRL, + CDNS_XSPI_PHY_CTB_RFILE_PHY_CTRL); + cdns_configure_phy_register_aux(cdns_xspi, + "cdns,rfile-phy-tsel", + RFILE_PHY_TSEL, + CDNS_XSPI_PHY_CTB_RFILE_PHY_TSEL); + cdns_configure_phy_register_aux(cdns_xspi, + "cdns,phy-dq-timing", + RFILE_PHY_DQ_TIMING, + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQ_TIMING); + cdns_configure_phy_register_aux(cdns_xspi, + "cdns,phy-dqs-timing", + RFILE_PHY_DQS_TIMING, + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQS_TIMING); + cdns_configure_phy_register_aux(cdns_xspi, + "cdns,phy-gate-lpbk-ctrl", + RFILE_PHY_GATE_LPBK_CTRL, + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL); + cdns_configure_phy_register_aux(cdns_xspi, + "cdns,phy-dll-master-ctrl", + RFILE_PHY_DLL_MASTER_CTRL, + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL); + cdns_configure_phy_register_aux(cdns_xspi, + "cdns,phy-dll-slave-ctrl", + RFILE_PHY_DLL_SLAVE_CTRL, + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_SLAVE_CTRL); + + return cdns_xspi_reset_dll(cdns_xspi); +} + +// Find max avalible clock +static bool cdns_mrvl_xspi_setup_clock(struct cdns_xspi_dev *cdns_xspi, + int requested_clk) +{ + int i = 0; + int clk_val; + u32 clk_reg; + bool update_clk = false; + + while (cdns_mrvl_xspi_clk_div_list[i] > 0) { + clk_val = CDNS_MRVL_XSPI_CLOCK_DIVIDED( + cdns_mrvl_xspi_clk_div_list[i]); + if (clk_val <= requested_clk) + break; + i++; + } + + if (cdns_mrvl_xspi_clk_div_list[i] == -1) { + dev_info(cdns_xspi->dev, + "Unable to find clk div for CLK: %d - using 6.25MHz\n", + requested_clk); + i = 0x0D; + } else { + dev_dbg(cdns_xspi->dev, "Found clk div: %d, clk val: %d\n", + cdns_mrvl_xspi_clk_div_list[i], + CDNS_MRVL_XSPI_CLOCK_DIVIDED( + cdns_mrvl_xspi_clk_div_list[i])); + } + + clk_reg = readl(cdns_xspi->auxbase + CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG); + + if (FIELD_GET(CDNS_MRVL_XSPI_CLK_DIV, clk_reg) != i) { + clk_reg &= ~CDNS_MRVL_XSPI_CLK_ENABLE; + writel(clk_reg, + cdns_xspi->auxbase + CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG); + clk_reg = FIELD_PREP(CDNS_MRVL_XSPI_CLK_DIV, i); + clk_reg &= ~CDNS_MRVL_XSPI_CLK_DIV; + clk_reg |= FIELD_PREP(CDNS_MRVL_XSPI_CLK_DIV, i); + clk_reg |= CDNS_MRVL_XSPI_CLK_ENABLE; + update_clk = true; + } + + if (update_clk) + writel(clk_reg, + cdns_xspi->auxbase + CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG); + + return update_clk; +} + static int cdns_xspi_wait_for_controller_idle(struct cdns_xspi_dev *cdns_xspi) { u32 ctrl_stat; @@ -291,6 +480,10 @@ static void cdns_xspi_set_interrupts(struct cdns_xspi_dev *cdns_xspi, bool enabled) { u32 intr_enable; + u32 irq_status; + + irq_status = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG); + writel(irq_status, cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG); intr_enable = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG); if (enabled) @@ -315,6 +508,9 @@ static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi) return -EIO; } + writel(FIELD_PREP(CDNS_XSPI_CTRL_WORK_MODE, CDNS_XSPI_WORK_MODE_STIG), + cdns_xspi->iobase + CDNS_XSPI_CTRL_CONFIG_REG); + ctrl_features = readl(cdns_xspi->iobase + CDNS_XSPI_CTRL_FEATURES_REG); cdns_xspi->hw_num_banks = FIELD_GET(CDNS_XSPI_NUM_BANKS, ctrl_features); cdns_xspi_set_interrupts(cdns_xspi, false); @@ -322,6 +518,70 @@ static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi) return 0; } +static void mrvl_ioreadq(void __iomem *addr, void *buf, int len) +{ + int i = 0; + int rcount = len / 8; + int rcount_nf = len % 8; + uint64_t tmp; + uint64_t *buf64 = (uint64_t *)buf; + + if (((uint64_t)buf % 8) == 0) { + for (i = 0; i < rcount; i++) + *buf64++ = readq(addr); + } else { + for (i = 0; i < rcount; i++) { + tmp = readq(addr); + memcpy(buf+(i*8), &tmp, 8); + } + } + + if (rcount_nf != 0) { + tmp = readq(addr); + memcpy(buf+(i*8), &tmp, rcount_nf); + } +} + +static void mrvl_iowriteq(void __iomem *addr, const void *buf, int len) +{ + int i = 0; + int rcount = len / 8; + int rcount_nf = len % 8; + uint64_t tmp; + uint64_t *buf64 = (uint64_t *)buf; + + if (((uint64_t)buf % 8) == 0) { + for (i = 0; i < rcount; i++) + writeq(*buf64++, addr); + } else { + for (i = 0; i < rcount; i++) { + memcpy(&tmp, buf+(i*8), 8); + writeq(tmp, addr); + } + } + + if (rcount_nf != 0) { + memcpy(&tmp, buf+(i*8), rcount_nf); + writeq(tmp, addr); + } +} + +static void cdns_xspi_sdma_memread(struct cdns_xspi_dev *cdns_xspi, int len) +{ + if (cdns_xspi->mrvl_hw_overlay) + mrvl_ioreadq(cdns_xspi->sdmabase, cdns_xspi->in_buffer, len); + else + ioread8_rep(cdns_xspi->sdmabase, cdns_xspi->in_buffer, len); +} + +static void cdns_xspi_sdma_memwrite(struct cdns_xspi_dev *cdns_xspi, int len) +{ + if (cdns_xspi->mrvl_hw_overlay) + mrvl_iowriteq(cdns_xspi->sdmabase, cdns_xspi->out_buffer, len); + else + iowrite8_rep(cdns_xspi->sdmabase, cdns_xspi->out_buffer, len); +} + static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi) { u32 sdma_size, sdma_trd_info; @@ -333,13 +593,11 @@ static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi) switch (sdma_dir) { case CDNS_XSPI_SDMA_DIR_READ: - ioread8_rep(cdns_xspi->sdmabase, - cdns_xspi->in_buffer, sdma_size); + cdns_xspi_sdma_memread(cdns_xspi, sdma_size); break; case CDNS_XSPI_SDMA_DIR_WRITE: - iowrite8_rep(cdns_xspi->sdmabase, - cdns_xspi->out_buffer, sdma_size); + cdns_xspi_sdma_memwrite(cdns_xspi, sdma_size); break; } } @@ -411,6 +669,9 @@ static int cdns_xspi_mem_op(struct cdns_xspi_dev *cdns_xspi, if (cdns_xspi->cur_cs != spi_get_chipselect(mem->spi, 0)) cdns_xspi->cur_cs = spi_get_chipselect(mem->spi, 0); + if (cdns_xspi->mrvl_hw_overlay) + cdns_mrvl_xspi_setup_clock(cdns_xspi, mem->spi->max_speed_hz); + return cdns_xspi_send_stig_command(cdns_xspi, op, (dir != SPI_MEM_NO_DATA)); } @@ -451,6 +712,10 @@ static irqreturn_t cdns_xspi_irq_handler(int this_irq, void *dev) irq_status = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG); writel(irq_status, cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG); + if (cdns_xspi->mrvl_hw_overlay) + writel(CDNS_MRVL_MSIX_CLEAR_IRQ, + cdns_xspi->auxbase + CDNS_MRVL_XSPI_SPIX_INTR_AUX); + if (irq_status & (CDNS_XSPI_SDMA_ERROR | CDNS_XSPI_SDMA_TRIGGER | CDNS_XSPI_STIG_DONE)) { @@ -524,6 +789,27 @@ static void cdns_xspi_print_phy_config(struct cdns_xspi_dev *cdns_xspi) readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL)); } +static int cdns_xspi_setup(struct spi_device *spi_dev) +{ + struct cdns_xspi_dev *cdns_xspi = spi_master_get_devdata(spi_dev->master); + + if (cdns_xspi->mrvl_hw_overlay) + cdns_mrvl_xspi_setup_clock(cdns_xspi, spi_dev->max_speed_hz); + + return 0; +} + +static bool cdns_xspi_get_hw_overlay(struct platform_device *pdev) +{ + int err; + + err = device_property_match_string(&pdev->dev, + "compatible", "mrvl,xspi-nor"); + + + return (err >= 0); +} + static int cdns_xspi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -531,6 +817,7 @@ static int cdns_xspi_probe(struct platform_device *pdev) struct cdns_xspi_dev *cdns_xspi = NULL; struct resource *res; int ret; + bool hw_overlay; host = devm_spi_alloc_host(dev, sizeof(*cdns_xspi)); if (!host) @@ -540,10 +827,15 @@ static int cdns_xspi_probe(struct platform_device *pdev) SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_OCTAL | SPI_RX_OCTAL | SPI_MODE_0 | SPI_MODE_3; + hw_overlay = cdns_xspi_get_hw_overlay(pdev); + host->mem_ops = &cadence_xspi_mem_ops; host->dev.of_node = pdev->dev.of_node; host->bus_num = -1; + if (hw_overlay) + host->setup = cdns_xspi_setup; + platform_set_drvdata(pdev, host); cdns_xspi = spi_controller_get_devdata(host); @@ -555,6 +847,8 @@ static int cdns_xspi_probe(struct platform_device *pdev) init_completion(&cdns_xspi->auto_cmd_complete); init_completion(&cdns_xspi->sdma_complete); + cdns_xspi->mrvl_hw_overlay = hw_overlay; + ret = cdns_xspi_of_get_plat_data(pdev); if (ret) return -ENODEV; @@ -588,8 +882,12 @@ static int cdns_xspi_probe(struct platform_device *pdev) return ret; } - cdns_xspi_print_phy_config(cdns_xspi); + if (hw_overlay) { + cdns_mrvl_xspi_setup_clock(cdns_xspi, MRVL_DEFAULT_CLK); + cdns_xspi_configure_phy(cdns_xspi); + } + cdns_xspi_print_phy_config(cdns_xspi); ret = cdns_xspi_controller_init(cdns_xspi); if (ret) { dev_err(dev, "Failed to initialize controller\n"); @@ -613,6 +911,9 @@ static const struct of_device_id cdns_xspi_of_match[] = { { .compatible = "cdns,xspi-nor", }, + { + .compatible = "mrvl,xspi-nor", + }, { /* end of table */} }; MODULE_DEVICE_TABLE(of, cdns_xspi_of_match); From patchwork Fri Mar 29 19:48:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Witold Sadowski X-Patchwork-Id: 13610987 Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA5E813B5AC; Fri, 29 Mar 2024 19:49:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.156.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711741754; cv=none; b=HRq4cxA9BtPjv5DQeSUwDWP2ml+qWQpGxWtP3DAA1Sle+5KWO1i4g52qJR7NaNCOPLhZRvQliDNBcJbD+FA6ugacISp5fPcQ+CKWYAGLmFcGqIJYV905sTCZ3cy1jYf0O5fIYqQqdyuzhR5uiYHHD3rJmwLraHPTwAqYhgFjuXY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711741754; c=relaxed/simple; bh=47Oz1nPvAac9zh3peIwuv/tnQiJpEQqRqnRuiL+lSGQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=F7T8Ru36Fqw3yUtodJokTNb7EZz7F2Feo6Y4adHwlxL3fkoYTtOWMO2vkiGPmSrsO2UHa7/g+G2IUU2aOTTqtQlm/znrTujvY3RGaiDfeeaRHXY1ceHUhwlPoQQUAfkpdrLes29FHUP4heqF+3pkGPUlqZGnfid9wyNjwhYdZmw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=iICQQBo4; arc=none smtp.client-ip=67.231.156.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="iICQQBo4" Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 42TE0cl4014374; Fri, 29 Mar 2024 12:49:07 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= pfpt0220; bh=8fNMtZ9/pgFp6oVd4lQW8G2fv7HD8rCT8GxycTl6jyg=; b=iIC QQBo4S3Y5PyGsmjeT4dEpJMQ5C0hu1sy1ugTmMmIiB3zRdAZdgaxUrg0CGpGlyJt nqQVVQW2ChIzHLAr6I3PNONThdhKC9tsyZTWcnlexqpc6GJKekZ4B9EVL0GpPItK zkNFEUr8tlzyPl3BXPIxNctQ+OqSwBK7m92QeHf/b2eDq7zK8ZdhveUu9WNfip86 cE5o6XukTzEExupZM3FVlWsYaPBBexUhN3VH7Y8KQun9xiiFuqiEjWBZIu9L8+Vq mTCr5AoVH17Ngeh7iIHMLmvPQkGux9eR4TM4JTWIL7vJ8TbmJvowEx07V92LJh1L d0+16Y1MZ3YhQWBXiFQ== Received: from dc6wp-exch02.marvell.com ([4.21.29.225]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3x5gm3krq6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 Mar 2024 12:49:07 -0700 (PDT) Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Fri, 29 Mar 2024 12:49:06 -0700 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.4 via Frontend Transport; Fri, 29 Mar 2024 12:49:06 -0700 Received: from localhost.localdomain (unknown [10.110.150.170]) by maili.marvell.com (Postfix) with ESMTP id 02B983F707A; Fri, 29 Mar 2024 12:49:05 -0700 (PDT) From: Witold Sadowski To: , , CC: , , , , , Witold Sadowski Subject: [PATCH 3/5] spi: cadence: Force single modebyte Date: Fri, 29 Mar 2024 12:48:47 -0700 Message-ID: <20240329194849.25554-4-wsadowski@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240329194849.25554-1-wsadowski@marvell.com> References: <20240329194849.25554-1-wsadowski@marvell.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-GUID: sfyKqSIEWUN9qXI62K_B1BGNxxwymHOL X-Proofpoint-ORIG-GUID: sfyKqSIEWUN9qXI62K_B1BGNxxwymHOL X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-03-29_13,2024-03-28_01,2023-05-22_02 During dummy-cycles xSPI will switch GPIO into Hi-Z mode. To prevent unforeseen consequences of that behaviour, force send single modebyte(0x00). Modebyte will be send only if number of dummy-cycles is not equal to 0. Code must also reduce dummycycle byte count by one - as one byte is send as modebyte. Signed-off-by: Witold Sadowski --- drivers/spi/spi-cadence-xspi.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c index f570b2920b18..cce14473e88e 100644 --- a/drivers/spi/spi-cadence-xspi.c +++ b/drivers/spi/spi-cadence-xspi.c @@ -145,6 +145,9 @@ #define CDNS_XSPI_STIG_DONE_FLAG BIT(0) #define CDNS_XSPI_TRD_STATUS 0x0104 +#define MODE_NO_OF_BYTES GENMASK(25, 24) +#define MODEBYTES_COUNT 1 + /* Helper macros for filling command registers */ #define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1(op, data_phase) ( \ FIELD_PREP(CDNS_XSPI_CMD_INSTR_TYPE, (data_phase) ? \ @@ -157,9 +160,10 @@ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR3, ((op)->addr.val >> 24) & 0xFF) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR4, ((op)->addr.val >> 32) & 0xFF)) -#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op) ( \ +#define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op, modebytes) ( \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_ADDR5, ((op)->addr.val >> 40) & 0xFF) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_CMD, (op)->cmd.opcode) | \ + FIELD_PREP(MODE_NO_OF_BYTES, modebytes) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_NUM_ADDR_BYTES, (op)->addr.nbytes)) #define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4(op, chipsel) ( \ @@ -173,12 +177,12 @@ #define CDNS_XSPI_CMD_FLD_DSEQ_CMD_2(op) \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R2_DCNT_L, (op)->data.nbytes & 0xFFFF) -#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op) ( \ +#define CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op, dummybytes) ( \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_DCNT_H, \ ((op)->data.nbytes >> 16) & 0xffff) | \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_NUM_OF_DUMMY, \ (op)->dummy.buswidth != 0 ? \ - (((op)->dummy.nbytes * 8) / (op)->dummy.buswidth) : \ + (((dummybytes) * 8) / (op)->dummy.buswidth) : \ 0)) #define CDNS_XSPI_CMD_FLD_DSEQ_CMD_4(op, chipsel) ( \ @@ -609,6 +613,7 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi, u32 cmd_regs[6]; u32 cmd_status; int ret; + int dummybytes = op->dummy.nbytes; ret = cdns_xspi_wait_for_controller_idle(cdns_xspi); if (ret < 0) @@ -623,7 +628,12 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi, memset(cmd_regs, 0, sizeof(cmd_regs)); cmd_regs[1] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1(op, data_phase); cmd_regs[2] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_2(op); - cmd_regs[3] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op); + if (dummybytes != 0) { + cmd_regs[3] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op, 1); + dummybytes--; + } else { + cmd_regs[3] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op, 0); + } cmd_regs[4] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4(op, cdns_xspi->cur_cs); @@ -633,7 +643,7 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi, cmd_regs[0] = CDNS_XSPI_STIG_DONE_FLAG; cmd_regs[1] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_1(op); cmd_regs[2] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_2(op); - cmd_regs[3] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op); + cmd_regs[3] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op, dummybytes); cmd_regs[4] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_4(op, cdns_xspi->cur_cs); From patchwork Fri Mar 29 19:48:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Witold Sadowski X-Patchwork-Id: 13610988 Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2DD9313B7AC; Fri, 29 Mar 2024 19:49:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.148.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711741755; cv=none; b=OOTSOx4az0bC8kFFYiv9dWCrf5lEE7T4b3CNwfF5AjO8uqbU1+T6Ey5DLrpDSjWRZaDK1LtQdSpzzG4Z8h3ou9/2dp79DfjsqNPqAc5Ew2ny1aWIh1pJ7psXcM8NpT4b0DGjtVbYV81SOPJ6gxQWEYPyUyuysv9ECc1EIOyORMs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711741755; c=relaxed/simple; bh=1cEjig1GJt5yrW2/AZBvoJSGTO8Opdw4rdIQOqEsoRU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DARIhlLnfjqxrLKbQ+aQMXtWLmhZqY2leGZtBl2nr94A1SW6hNmrTqJWFTk/nmaD1xXQpfH3wbVaDIPDKucKrOMGeUPA1dgUzPDT2Vcxq9T/B4tpzropsOqkKuUsO49lzM0NF8RmIe+pl2bsUL/d7omN7PjYJmDF3V7hoNbatns= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=gZW9OegW; arc=none smtp.client-ip=67.231.148.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="gZW9OegW" Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 42TCGUx1027498; Fri, 29 Mar 2024 12:49:09 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= pfpt0220; bh=dhYmB03bw+WmHVytL0gPyN8XFol0C1gLpAhy8ykuUjY=; b=gZW 9OegWrhpm6o3pvMgvafWqIuOya/KSuf99IqoyD8vcCvNWariEo19Im9ke3T4IXFb h2+hggwpcuDW1AkHqwH+uIpr1aFwLlr2n/O6qi0DP7gXiqJrLmunUjzzW7JFQmht t+KAOIqFzwwNgp5hA1uPCOQ7VKkgjSWO1RvliW3Ek4gt65hnYZ4JXfMDZZuv3N8r JnSemB1sq6NQ7wMeog+9v1cAktCSIHfqn2blyDavNUyfQRznZkFn3m9e11X8yeBu MHeCxHXyVy2QACd1czK/geD5aMg4zM/zoapRufCFGN2cmiW376A6L4pryYw7oyaw BmPylgUjJMohCeWvteA== Received: from dc6wp-exch02.marvell.com ([4.21.29.225]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3x5wgphd40-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 Mar 2024 12:49:09 -0700 (PDT) Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Fri, 29 Mar 2024 12:49:08 -0700 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.4 via Frontend Transport; Fri, 29 Mar 2024 12:49:08 -0700 Received: from localhost.localdomain (unknown [10.110.150.170]) by maili.marvell.com (Postfix) with ESMTP id BA81F3F707A; Fri, 29 Mar 2024 12:49:07 -0700 (PDT) From: Witold Sadowski To: , , CC: , , , , , Piyush Malgujar , "Witold Sadowski" Subject: [PATCH 4/5] driver: spi: cadence: Add ACPI support Date: Fri, 29 Mar 2024 12:48:48 -0700 Message-ID: <20240329194849.25554-5-wsadowski@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240329194849.25554-1-wsadowski@marvell.com> References: <20240329194849.25554-1-wsadowski@marvell.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-GUID: CzJ6PpnvbTlkYBqy0ssT-tWNxl2wwUgB X-Proofpoint-ORIG-GUID: CzJ6PpnvbTlkYBqy0ssT-tWNxl2wwUgB X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-03-29_13,2024-03-28_01,2023-05-22_02 From: Piyush Malgujar These changes enables to read the configs from ACPI tables as required for successful probing in ACPI uefi environment. In case of ACPI disabled/dts based environment, it will continue to read configs from dts as before. Signed-off-by: Piyush Malgujar Signed-off-by: Witold Sadowski --- drivers/spi/spi-cadence-xspi.c | 97 ++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c index cce14473e88e..01e81d40f04c 100644 --- a/drivers/spi/spi-cadence-xspi.c +++ b/drivers/spi/spi-cadence-xspi.c @@ -2,6 +2,7 @@ // Cadence XSPI flash controller driver // Copyright (C) 2020-21 Cadence +#include #include #include #include @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -686,6 +688,67 @@ static int cdns_xspi_mem_op(struct cdns_xspi_dev *cdns_xspi, (dir != SPI_MEM_NO_DATA)); } +#ifdef CONFIG_ACPI +static bool cdns_xspi_supports_op(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + struct spi_device *spi = mem->spi; + const union acpi_object *obj; + struct acpi_device *adev; + + adev = ACPI_COMPANION(&spi->dev); + + if (!acpi_dev_get_property(adev, "spi-tx-bus-width", ACPI_TYPE_INTEGER, + &obj)) { + switch (obj->integer.value) { + case 1: + break; + case 2: + spi->mode |= SPI_TX_DUAL; + break; + case 4: + spi->mode |= SPI_TX_QUAD; + break; + case 8: + spi->mode |= SPI_TX_OCTAL; + break; + default: + dev_warn(&spi->dev, + "spi-tx-bus-width %lld not supported\n", + obj->integer.value); + break; + } + } + + if (!acpi_dev_get_property(adev, "spi-rx-bus-width", ACPI_TYPE_INTEGER, + &obj)) { + switch (obj->integer.value) { + case 1: + break; + case 2: + spi->mode |= SPI_RX_DUAL; + break; + case 4: + spi->mode |= SPI_RX_QUAD; + break; + case 8: + spi->mode |= SPI_RX_OCTAL; + break; + default: + dev_warn(&spi->dev, + "spi-rx-bus-width %lld not supported\n", + obj->integer.value); + break; + } + } + + if (!spi_mem_default_supports_op(mem, op)) + return false; + + return true; +} +#endif + static int cdns_xspi_mem_op_execute(struct spi_mem *mem, const struct spi_mem_op *op) { @@ -709,6 +772,9 @@ static int cdns_xspi_adjust_mem_op_size(struct spi_mem *mem, struct spi_mem_op * } static const struct spi_controller_mem_ops cadence_xspi_mem_ops = { +#ifdef CONFIG_ACPI + .supports_op = cdns_xspi_supports_op, +#endif .exec_op = cdns_xspi_mem_op_execute, .adjust_op_size = cdns_xspi_adjust_mem_op_size, }; @@ -760,21 +826,20 @@ static irqreturn_t cdns_xspi_irq_handler(int this_irq, void *dev) static int cdns_xspi_of_get_plat_data(struct platform_device *pdev) { - struct device_node *node_prop = pdev->dev.of_node; - struct device_node *node_child; + struct fwnode_handle *fwnode_child; unsigned int cs; - for_each_child_of_node(node_prop, node_child) { - if (!of_device_is_available(node_child)) + device_for_each_child_node(&pdev->dev, fwnode_child) { + if (!fwnode_device_is_available(fwnode_child)) continue; - if (of_property_read_u32(node_child, "reg", &cs)) { + if (fwnode_property_read_u32(fwnode_child, "reg", &cs)) { dev_err(&pdev->dev, "Couldn't get memory chip select\n"); - of_node_put(node_child); + fwnode_handle_put(fwnode_child); return -ENXIO; } else if (cs >= CDNS_XSPI_MAX_BANKS) { dev_err(&pdev->dev, "reg (cs) parameter value too large\n"); - of_node_put(node_child); + fwnode_handle_put(fwnode_child); return -ENXIO; } } @@ -816,7 +881,6 @@ static bool cdns_xspi_get_hw_overlay(struct platform_device *pdev) err = device_property_match_string(&pdev->dev, "compatible", "mrvl,xspi-nor"); - return (err >= 0); } @@ -841,6 +905,7 @@ static int cdns_xspi_probe(struct platform_device *pdev) host->mem_ops = &cadence_xspi_mem_ops; host->dev.of_node = pdev->dev.of_node; + host->dev.fwnode = pdev->dev.fwnode; host->bus_num = -1; if (hw_overlay) @@ -863,19 +928,21 @@ static int cdns_xspi_probe(struct platform_device *pdev) if (ret) return -ENODEV; - cdns_xspi->iobase = devm_platform_ioremap_resource_byname(pdev, "io"); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + cdns_xspi->iobase = devm_ioremap_resource(dev, res); if (IS_ERR(cdns_xspi->iobase)) { dev_err(dev, "Failed to remap controller base address\n"); return PTR_ERR(cdns_xspi->iobase); } - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sdma"); + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); cdns_xspi->sdmabase = devm_ioremap_resource(dev, res); if (IS_ERR(cdns_xspi->sdmabase)) return PTR_ERR(cdns_xspi->sdmabase); cdns_xspi->sdmasize = resource_size(res); - cdns_xspi->auxbase = devm_platform_ioremap_resource_byname(pdev, "aux"); + res = platform_get_resource(pdev, IORESOURCE_MEM, 2); + cdns_xspi->auxbase = devm_ioremap_resource(dev, res); if (IS_ERR(cdns_xspi->auxbase)) { dev_err(dev, "Failed to remap AUX address\n"); return PTR_ERR(cdns_xspi->auxbase); @@ -917,6 +984,13 @@ static int cdns_xspi_probe(struct platform_device *pdev) return 0; } +static const struct acpi_device_id cdns_xspi_acpi_match[] = { + {"cdns,xspi-nor", 0}, + {"mrvl,xspi-nor", 0}, + {}, +}; +MODULE_DEVICE_TABLE(acpi, cdns_xspi_acpi_match); +#ifdef CONFIG_OF static const struct of_device_id cdns_xspi_of_match[] = { { .compatible = "cdns,xspi-nor", @@ -933,6 +1007,7 @@ static struct platform_driver cdns_xspi_platform_driver = { .driver = { .name = CDNS_XSPI_NAME, .of_match_table = cdns_xspi_of_match, + .acpi_match_table = cdns_xspi_acpi_match, }, }; From patchwork Fri Mar 29 19:48:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Witold Sadowski X-Patchwork-Id: 13610989 Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 89EF313BC03; Fri, 29 Mar 2024 19:49:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=67.231.156.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711741757; cv=none; b=cjtehenVixvmNeHrgJU0vG6Oh0acYHRImhZEpbxhl+DJUIswbyC9R+tt65BKBwmM5eMTUOr6h+I02crApKSPRyp/df8chw6YSPRDKOdXSYBP/hGKUM97HrHSQy/7uuodDjkWSvcgTzqbP031nPi1F0yV0/aYNjpvbs+p2yIskFk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1711741757; c=relaxed/simple; bh=6OcVgjmbBH1TsNTeoHZG6CyiWyHGDstqZcpYmztn6FE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=IxYHdG83bEtICEWDLADT50IV7dvoNpfnD2Xqbsc4ZaY9+u0i440rhK2N/C2jlkc6ANtRgtYtIDlOOL3bnkDxWrl1sjRY6xfPs/uUQzqUD1IDm07y7CcXwCJqAUDkv4oLzuo5jVjaMLQRXhp6py6SCxkLIZGjxOGza4IvFXzg16Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com; spf=pass smtp.mailfrom=marvell.com; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b=BsaEc4id; arc=none smtp.client-ip=67.231.156.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=marvell.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=marvell.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=marvell.com header.i=@marvell.com header.b="BsaEc4id" Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 42TE0ThA014430; Fri, 29 Mar 2024 12:49:10 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= pfpt0220; bh=O3VwhaSMo1SbWKCSCLMX6Xq/pTDeQg1rQmmunEWwB0A=; b=Bsa Ec4idmY8+0kbBCKP2/R1VzZgBPAhIe0gmKSU3hAJ96fuM3E5qh8gd3fsf21SmNsF 1yUsBC9lrjyl2hisKXbBszMR52dNEMB9I1h/uQ8UGlGl7Y9qn8SfPNAwrfQacevC Kiu5FB1GaD8avwQrw7rUxkIKsJrZNQPpscO1rrqqKTE5S1RS3O2HKURj368UmmQh uLjfFhwDuZ/tdYWINOTuqVon/DrFec19fYLuhERg9o0/EZ5YFKjdGRGTl+lx1ao0 s1KJhJC9xv7diWIXegNR9QShpHYloiL6Si75RS16Zbu3V9jdIqRL+vmzG7SXUbSM U3gs1s21fJSvH3LDyAg== Received: from dc6wp-exch02.marvell.com ([4.21.29.225]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3x5gm3krqe-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 Mar 2024 12:49:10 -0700 (PDT) Received: from DC6WP-EXCH02.marvell.com (10.76.176.209) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.4; Fri, 29 Mar 2024 12:49:09 -0700 Received: from maili.marvell.com (10.69.176.80) by DC6WP-EXCH02.marvell.com (10.76.176.209) with Microsoft SMTP Server id 15.2.1544.4 via Frontend Transport; Fri, 29 Mar 2024 12:49:09 -0700 Received: from localhost.localdomain (unknown [10.110.150.170]) by maili.marvell.com (Postfix) with ESMTP id 403573F707A; Fri, 29 Mar 2024 12:49:09 -0700 (PDT) From: Witold Sadowski To: , , CC: , , , , , Witold Sadowski Subject: [PATCH 5/5] cadence-xspi: Add xfer capabilities Date: Fri, 29 Mar 2024 12:48:49 -0700 Message-ID: <20240329194849.25554-6-wsadowski@marvell.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240329194849.25554-1-wsadowski@marvell.com> References: <20240329194849.25554-1-wsadowski@marvell.com> Precedence: bulk X-Mailing-List: linux-spi@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Proofpoint-GUID: UCUA4KG5NQmrDiPPzCz6nPm-Is-msg-d X-Proofpoint-ORIG-GUID: UCUA4KG5NQmrDiPPzCz6nPm-Is-msg-d X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-03-29_13,2024-03-28_01,2023-05-22_02 Add support for iMRVL xfer hw_overlay of Cadence xSPI block. MRVL Xfer overlay extend xSPI capabilities, to support non-memory SPI operations. With generic xSPI command it allows to create any required SPI transaction Signed-off-by: Witold Sadowski --- drivers/spi/spi-cadence-xspi.c | 249 +++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c index 01e81d40f04c..451f83d53898 100644 --- a/drivers/spi/spi-cadence-xspi.c +++ b/drivers/spi/spi-cadence-xspi.c @@ -219,19 +219,38 @@ #define CDNS_XSPI_DLL_RST_N BIT(24) #define CDNS_XSPI_DLL_LOCK BIT(0) +#define CDNS_XSPI_POLL_TIMEOUT_US 1000 +#define CDNS_XSPI_POLL_DELAY_US 10 + /* Marvell clock config register */ #define CDNS_MRVL_XSPI_CLK_CTRL_AUX_REG 0x2020 #define CDNS_MRVL_XSPI_CLK_ENABLE BIT(0) #define CDNS_MRVL_XSPI_CLK_DIV GENMASK(4, 1) + /* Marvell MSI-X clear interrupt register */ #define CDNS_MRVL_XSPI_SPIX_INTR_AUX 0x2000 #define CDNS_MRVL_MSIX_CLEAR_IRQ 0x01 +#define SPIX_XFER_FUNC_CTRL 0x210 +#define SPIX_XFER_FUNC_CTRL_READ_DATA(i) (0x000 + 8 * (i)) + /* Marvell clock macros */ #define CDNS_MRVL_XSPI_CLOCK_IO_HZ 800000000 #define CDNS_MRVL_XSPI_CLOCK_DIVIDED(div) ((CDNS_MRVL_XSPI_CLOCK_IO_HZ) / (div)) +/* Marvell XFER registers */ +#define XFER_SOFT_RESET BIT(11) +#define XFER_CS_N_HOLD GENMASK(9, 6) +#define XFER_RECEIVE_ENABLE BIT(4) +#define XFER_FUNC_ENABLE BIT(3) +#define XFER_CLK_CAPTURE_POL BIT(2) +#define XFER_CLK_DRIVE_POL BIT(1) +#define XFER_FUNC_START BIT(0) + +#define XFER_QWORD_COUNT 32 +#define XFER_QWORD_BYTECOUNT 8 + enum cdns_xspi_stig_instr_type { CDNS_XSPI_STIG_INSTR_TYPE_0, CDNS_XSPI_STIG_INSTR_TYPE_1, @@ -256,6 +275,7 @@ struct cdns_xspi_dev { void __iomem *iobase; void __iomem *auxbase; void __iomem *sdmabase; + void __iomem *xferbase; int irq; int cur_cs; @@ -270,6 +290,9 @@ struct cdns_xspi_dev { const void *out_buffer; u8 hw_num_banks; + + bool xfer_in_progress; + int current_xfer_qword; }; #define MRVL_DEFAULT_CLK 25000000 @@ -884,6 +907,221 @@ static bool cdns_xspi_get_hw_overlay(struct platform_device *pdev) return (err >= 0); } + +static int cdns_xspi_prepare_generic(int cs, const void *dout, int len, int glue, u32 *cmd_regs) +{ + u8 *data = (u8 *)dout; + int i; + int data_counter = 0; + + memset(cmd_regs, 0x00, 6*4); + + if (len > 7) { + for (i = (len >= 10 ? 2 : len - 8); i >= 0 ; i--) + cmd_regs[3] |= data[data_counter++] << (8*i); + } + if (len > 3) { + for (i = (len >= 7 ? 3 : len - 4); i >= 0; i--) + cmd_regs[2] |= data[data_counter++] << (8*i); + } + for (i = (len >= 3 ? 2 : len - 1); i >= 0 ; i--) + cmd_regs[1] |= data[data_counter++] << (8 + 8*i); + + cmd_regs[1] |= 96; + cmd_regs[3] |= len << 24; + cmd_regs[4] |= cs << 12; + + if (glue == 1) + cmd_regs[4] |= 1 << 28; + + return 0; +} + +unsigned char reverse_bits(unsigned char num) +{ + unsigned int count = sizeof(num) * 8 - 1; + unsigned int reverse_num = num; + + num >>= 1; + while (num) { + reverse_num <<= 1; + reverse_num |= num & 1; + num >>= 1; + count--; + } + reverse_num <<= count; + return reverse_num; +} + +static void cdns_xspi_read_single_qword(struct cdns_xspi_dev *cdns_xspi, u8 **buffer) +{ + u64 d = readq(cdns_xspi->xferbase + + SPIX_XFER_FUNC_CTRL_READ_DATA(cdns_xspi->current_xfer_qword)); + u8 *ptr = (u8 *)&d; + int k; + + for (k = 0; k < 8; k++) { + u8 val = reverse_bits((ptr[k])); + **buffer = val; + *buffer = *buffer + 1; + } + + cdns_xspi->current_xfer_qword++; + cdns_xspi->current_xfer_qword %= XFER_QWORD_COUNT; +} + +static void cdns_xspi_finish_read(struct cdns_xspi_dev *cdns_xspi, u8 **buffer, u32 data_count) +{ + u64 d = readq(cdns_xspi->xferbase + + SPIX_XFER_FUNC_CTRL_READ_DATA(cdns_xspi->current_xfer_qword)); + u8 *ptr = (u8 *)&d; + int k; + + for (k = 0; k < data_count % XFER_QWORD_BYTECOUNT; k++) { + u8 val = reverse_bits((ptr[k])); + **buffer = val; + *buffer = *buffer + 1; + } + + cdns_xspi->current_xfer_qword++; + cdns_xspi->current_xfer_qword %= XFER_QWORD_COUNT; +} + +static int cdns_xspi_prepare_transfer(int cs, int dir, int len, u32 *cmd_regs) +{ + memset(cmd_regs, 0x00, 6*4); + + cmd_regs[1] |= 127; + cmd_regs[2] |= len << 16; + cmd_regs[4] |= dir << 4; //dir = 0 read, dir =1 write + cmd_regs[4] |= cs << 12; + + return 0; +} + +bool cdns_xspi_stig_ready(struct cdns_xspi_dev *cdns_xspi, bool sleep) +{ + u32 ctrl_stat; + + return readl_relaxed_poll_timeout + (cdns_xspi->iobase + CDNS_XSPI_CTRL_STATUS_REG, + ctrl_stat, + ((ctrl_stat & BIT(3)) == 0), + sleep ? CDNS_XSPI_POLL_DELAY_US : 0, + sleep ? CDNS_XSPI_POLL_TIMEOUT_US : 0); +} + +bool cdns_xspi_sdma_ready(struct cdns_xspi_dev *cdns_xspi, bool sleep) +{ + u32 ctrl_stat; + + return readl_relaxed_poll_timeout + (cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG, + ctrl_stat, + (ctrl_stat & CDNS_XSPI_SDMA_TRIGGER), + sleep ? CDNS_XSPI_POLL_DELAY_US : 0, + sleep ? CDNS_XSPI_POLL_TIMEOUT_US : 0); +} + +int cdns_xspi_transfer_one_message_b0(struct spi_controller *master, + struct spi_message *m) +{ + struct cdns_xspi_dev *cdns_xspi = spi_master_get_devdata(master); + struct spi_device *spi = m->spi; + struct spi_transfer *t = NULL; + + const int max_len = XFER_QWORD_BYTECOUNT * XFER_QWORD_COUNT; + int current_cycle_count; + int cs = spi->chip_select; + int cs_change = 0; + + /* Enable xfer state machine */ + if (!cdns_xspi->xfer_in_progress) { + u32 xfer_control = readl(cdns_xspi->xferbase + SPIX_XFER_FUNC_CTRL); + + cdns_xspi->current_xfer_qword = 0; + cdns_xspi->xfer_in_progress = true; + xfer_control |= (XFER_RECEIVE_ENABLE | + XFER_CLK_CAPTURE_POL | + XFER_FUNC_START | + XFER_SOFT_RESET | + FIELD_PREP(XFER_CS_N_HOLD, (1 << cs))); + xfer_control &= ~(XFER_FUNC_ENABLE | XFER_CLK_DRIVE_POL); + writel(xfer_control, cdns_xspi->xferbase + SPIX_XFER_FUNC_CTRL); + } + + list_for_each_entry(t, &m->transfers, transfer_list) { + u8 *txd = (u8 *) t->tx_buf; + u8 *rxd = (u8 *) t->rx_buf; + u8 data[10]; + u32 cmd_regs[6]; + + if (!txd) + txd = data; + + cdns_xspi->in_buffer = txd + 1; + cdns_xspi->out_buffer = txd + 1; + + while (t->len) { + + current_cycle_count = t->len > max_len ? max_len : t->len; + + if (current_cycle_count < 10) { + cdns_xspi_prepare_generic(cs, txd, current_cycle_count, + false, cmd_regs); + cdns_xspi_trigger_command(cdns_xspi, cmd_regs); + if (cdns_xspi_stig_ready(cdns_xspi, true)) + return -EIO; + } else { + cdns_xspi_prepare_generic(cs, txd, 1, true, cmd_regs); + cdns_xspi_trigger_command(cdns_xspi, cmd_regs); + cdns_xspi_prepare_transfer(cs, 1, current_cycle_count - 1, + cmd_regs); + cdns_xspi_trigger_command(cdns_xspi, cmd_regs); + if (cdns_xspi_sdma_ready(cdns_xspi, true)) + return -EIO; + cdns_xspi_sdma_handle(cdns_xspi); + if (cdns_xspi_stig_ready(cdns_xspi, true)) + return -EIO; + + cdns_xspi->in_buffer += current_cycle_count; + cdns_xspi->out_buffer += current_cycle_count; + } + + if (rxd) { + int j; + + for (j = 0; j < current_cycle_count / 8; j++) + cdns_xspi_read_single_qword(cdns_xspi, &rxd); + cdns_xspi_finish_read(cdns_xspi, &rxd, current_cycle_count); + } else { + cdns_xspi->current_xfer_qword += current_cycle_count / + XFER_QWORD_BYTECOUNT; + if (current_cycle_count % XFER_QWORD_BYTECOUNT) + cdns_xspi->current_xfer_qword++; + + cdns_xspi->current_xfer_qword %= XFER_QWORD_COUNT; + } + cs_change = t->cs_change; + t->len -= current_cycle_count; + } + } + + if (!cs_change) { + u32 xfer_control = readl(cdns_xspi->xferbase + SPIX_XFER_FUNC_CTRL); + + xfer_control &= ~(XFER_RECEIVE_ENABLE | + XFER_SOFT_RESET); + writel(xfer_control, cdns_xspi->xferbase + SPIX_XFER_FUNC_CTRL); + cdns_xspi->xfer_in_progress = false; + } + + m->status = 0; + spi_finalize_current_message(master); + + return 0; +} + static int cdns_xspi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -948,6 +1186,16 @@ static int cdns_xspi_probe(struct platform_device *pdev) return PTR_ERR(cdns_xspi->auxbase); } + if (hw_overlay) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 3); + cdns_xspi->xferbase = devm_ioremap_resource(dev, res); + if (IS_ERR(cdns_xspi->xferbase)) { + dev_info(dev, "XFER register base not found, set it\n"); + // For compatibility with older firmware + cdns_xspi->xferbase = cdns_xspi->iobase + 0x8000; + } + } + cdns_xspi->irq = platform_get_irq(pdev, 0); if (cdns_xspi->irq < 0) return -ENXIO; @@ -962,6 +1210,7 @@ static int cdns_xspi_probe(struct platform_device *pdev) if (hw_overlay) { cdns_mrvl_xspi_setup_clock(cdns_xspi, MRVL_DEFAULT_CLK); cdns_xspi_configure_phy(cdns_xspi); + host->transfer_one_message = cdns_xspi_transfer_one_message_b0; } cdns_xspi_print_phy_config(cdns_xspi);