Received: by 2002:a05:6358:4e97:b0:b3:742d:4702 with SMTP id ce23csp1611923rwb; Fri, 19 Aug 2022 06:39:17 -0700 (PDT) X-Google-Smtp-Source: AA6agR6GITRC3V/2Xt/VZKNUstDGyrVmcK/f5lx7xHcfcvK1X8pErNfKIIZJG40kmf7wrNxcrHN+ X-Received: by 2002:a17:906:8a78:b0:730:7a4f:fb36 with SMTP id hy24-20020a1709068a7800b007307a4ffb36mr5005403ejc.624.1660916357458; Fri, 19 Aug 2022 06:39:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660916357; cv=none; d=google.com; s=arc-20160816; b=dPBOyNKh72uyz1qFvr4zbYPKiF98/7GCJD6bwrS1PihesqWHgtJXNKztHBhgXIpfcE lLtbISZwCq85c+z4CVAAMWag+s6ZwiO/NtAzH59MaEqI3FJQRV4vDzeNdnxhglzCMkRr kx9BAcZVuqDWDawDpN78qcFjUMm1NxCf1JyZTzVLKhnzPpHcO/Y75DOBDqeNBecZczM6 aEePrOfgUUM3qyzKNWnPMWA61lQHsB7VgzovlZaFAoBZ3TyUpy8MfPJYONdDVMpdtPly Dxgr36SySmXNISHKQTdMW7V1J/fGY1uEIGm8iUM2GqqeL/9aoeIhwEhx63q2ndBXeyTY qQTQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=awM1h80DanAD01UKtdxZfyYBGMiowDYbkn+8qzZyNwM=; b=TTes3uloPS0dVgt4GnV6L1GrObZhGKtosQNRHR7756bJKpoYj5xF6GB3oaqu2nF4Bz dKAQkyTWjHxjmVXMAtfS2JwcfB7MO5BRG9wMe5TAh/6BDzVLEqL9FcrGxBQx9/dxHtQz JD/dDfVb4hUoIYUZoUp582rQg3xJ497NBwdGZ6wK8oQJpgQaRv+94irNk0eUP66vRpr7 VBhi11jpHlKZqSDrjQU4kRYtZZ33hdJ/dK7rdPhszaWVKMbwFhY8QJANYJNkWh+QBT3l vvbNeE2Btml1KtmpURyI+9FC7jnBSKvarkY+O5W1/xC8AC8UkwPh54HwFbIKt5AdLoGk 7Pqw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=XcANuo0Y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g10-20020a056402428a00b0043d127622b2si2915739edc.157.2022.08.19.06.38.51; Fri, 19 Aug 2022 06:39:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@collabora.com header.s=mail header.b=XcANuo0Y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348519AbiHSMhF (ORCPT + 99 others); Fri, 19 Aug 2022 08:37:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44554 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235596AbiHSMhD (ORCPT ); Fri, 19 Aug 2022 08:37:03 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A2F3A1015AE; Fri, 19 Aug 2022 05:37:01 -0700 (PDT) Received: from localhost.localdomain (unknown [IPv6:2405:201:10:389d:42df:ae4c:c047:294c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: shreeya) by madras.collabora.co.uk (Postfix) with ESMTPSA id 03D5D66015B2; Fri, 19 Aug 2022 13:36:57 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1660912620; bh=pObIoX59I+FSuduhBxmScU7R5MECVMxXywkg0t+LhWI=; h=From:To:Cc:Subject:Date:From; b=XcANuo0YHb1cRL3zdQAOt+ISxZy5XoMleqtMNJwGCpTmlCkKGRyDqNS/SVkqYTusI gvN7BoWm0u6C1yL77N4lW9ncUriHTJbb/fYVXprUyJebNMSiSrr9cwcKW0RLda5Ne5 o3Ejy1qu16f5Xy2/28NLynnyDsSznBpQOnF5lqYvzFYTSUXjNviPsmcG/FiLg9yNEZ hFbwY/NMpm5GOI69x9NfM02TeH3QHSvqeGlXGD+/a6WTHsMJEaTqBFvvyRduAU7RSI GKduVBNEg0t9I0uGsxa+3GPuU14nZgfpMvDLxu7oJJgMsQcBdvigW0NbUq1oLtW1G6 vYfBqgJvBiMNQ== From: Shreeya Patel To: sanju.mehta@amd.com, broonie@kernel.org Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, kernel@collabora.com, krisman@collabora.com, alvaro.soliverez@collabora.com, Shreeya Patel , Lucas Tanure Subject: [PATCH v2] spi: amd: Configure device speed Date: Fri, 19 Aug 2022 18:06:30 +0530 Message-Id: <20220819123630.368462-1-shreeya.patel@collabora.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lucas Tanure Number of clock frequencies are supported by AMD controller which are mentioned in the amd_spi_freq structure table. Create mechanism to configure device clock frequency such that it is strictly less than the requested frequency. Give priority to the device transfer speed and in case it is not set then use the max clock speed supported by the device. Co-developed-by: Shreeya Patel Signed-off-by: Shreeya Patel Signed-off-by: Lucas Tanure --- Changes in v2 - Improve the commit message. drivers/spi/spi-amd.c | 98 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c index 08df4f8d0531..0cc9fd908f4f 100644 --- a/drivers/spi/spi-amd.c +++ b/drivers/spi/spi-amd.c @@ -36,6 +36,18 @@ #define AMD_SPI_FIFO_SIZE 70 #define AMD_SPI_MEM_SIZE 200 +#define AMD_SPI_ENA_REG 0x20 +#define AMD_SPI_ALT_SPD_SHIFT 20 +#define AMD_SPI_ALT_SPD_MASK GENMASK(23, AMD_SPI_ALT_SPD_SHIFT) +#define AMD_SPI_SPI100_SHIFT 0 +#define AMD_SPI_SPI100_MASK GENMASK(AMD_SPI_SPI100_SHIFT, AMD_SPI_SPI100_SHIFT) +#define AMD_SPI_SPEED_REG 0x6C +#define AMD_SPI_SPD7_SHIFT 8 +#define AMD_SPI_SPD7_MASK GENMASK(13, AMD_SPI_SPD7_SHIFT) + +#define AMD_SPI_MAX_HZ 100000000 +#define AMD_SPI_MIN_HZ 800000 + /* M_CMD OP codes for SPI */ #define AMD_SPI_XFER_TX 1 #define AMD_SPI_XFER_RX 2 @@ -50,14 +62,41 @@ enum amd_spi_versions { AMD_SPI_V2, }; +enum amd_spi_speed { + F_66_66MHz, + F_33_33MHz, + F_22_22MHz, + F_16_66MHz, + F_100MHz, + F_800KHz, + SPI_SPD7, + F_50MHz = 0x4, + F_4MHz = 0x32, + F_3_17MHz = 0x3F +}; + +/** + * struct amd_spi_freq - Matches device speed with values to write in regs + * @speed_hz: Device frequency + * @enable_val: Value to be written to "enable register" + * @spd7_val: Some frequencies requires to have a value written at SPISPEED register + */ +struct amd_spi_freq { + u32 speed_hz; + u32 enable_val; + u32 spd7_val; +}; + /** * struct amd_spi - SPI driver instance * @io_remap_addr: Start address of the SPI controller registers * @version: SPI controller hardware version + * @speed_hz: Device frequency */ struct amd_spi { void __iomem *io_remap_addr; enum amd_spi_versions version; + unsigned int speed_hz; }; static inline u8 amd_spi_readreg8(struct amd_spi *amd_spi, int idx) @@ -189,10 +228,61 @@ static int amd_spi_master_setup(struct spi_device *spi) return 0; } +static const struct amd_spi_freq amd_spi_freq[] = { + { AMD_SPI_MAX_HZ, F_100MHz, 0}, + { 66660000, F_66_66MHz, 0}, + { 50000000, SPI_SPD7, F_50MHz}, + { 33330000, F_33_33MHz, 0}, + { 22220000, F_22_22MHz, 0}, + { 16660000, F_16_66MHz, 0}, + { 4000000, SPI_SPD7, F_4MHz}, + { 3170000, SPI_SPD7, F_3_17MHz}, + { AMD_SPI_MIN_HZ, F_800KHz, 0}, +}; + +static int amd_set_spi_freq(struct amd_spi *amd_spi, u32 speed_hz) +{ + unsigned int i, spd7_val, alt_spd; + + if (speed_hz == amd_spi->speed_hz) + return 0; + + if (speed_hz < AMD_SPI_MIN_HZ) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(amd_spi_freq); i++) + if (speed_hz >= amd_spi_freq[i].speed_hz) + break; + + if (speed_hz == amd_spi_freq[i].speed_hz) + return 0; + + amd_spi->speed_hz = amd_spi_freq[i].speed_hz; + + alt_spd = (amd_spi_freq[i].enable_val << AMD_SPI_ALT_SPD_SHIFT) + & AMD_SPI_ALT_SPD_MASK; + amd_spi_setclear_reg32(amd_spi, AMD_SPI_ENA_REG, alt_spd, + AMD_SPI_ALT_SPD_MASK); + + if (amd_spi->speed_hz == AMD_SPI_MAX_HZ) + amd_spi_setclear_reg32(amd_spi, AMD_SPI_ENA_REG, 1, + AMD_SPI_SPI100_MASK); + + if (amd_spi_freq[i].spd7_val) { + spd7_val = (amd_spi_freq[i].spd7_val << AMD_SPI_SPD7_SHIFT) + & AMD_SPI_SPD7_MASK; + amd_spi_setclear_reg32(amd_spi, AMD_SPI_SPEED_REG, spd7_val, + AMD_SPI_SPD7_MASK); + } + + return 0; +} + static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi, struct spi_master *master, struct spi_message *message) { + struct spi_device *spi = message->spi; struct spi_transfer *xfer = NULL; u8 cmd_opcode; u8 *buf = NULL; @@ -202,6 +292,12 @@ static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi, list_for_each_entry(xfer, &message->transfers, transfer_list) { + + if (xfer->speed_hz) + amd_set_spi_freq(amd_spi, xfer->speed_hz); + else + amd_set_spi_freq(amd_spi, spi->max_speed_hz); + if (xfer->rx_buf) m_cmd = AMD_SPI_XFER_RX; if (xfer->tx_buf) @@ -312,6 +408,8 @@ static int amd_spi_probe(struct platform_device *pdev) master->num_chipselect = 4; master->mode_bits = 0; master->flags = SPI_MASTER_HALF_DUPLEX; + master->max_speed_hz = AMD_SPI_MAX_HZ; + master->min_speed_hz = AMD_SPI_MIN_HZ; master->setup = amd_spi_master_setup; master->transfer_one_message = amd_spi_master_transfer; master->max_transfer_size = amd_spi_max_transfer_size; -- 2.30.2