2022-08-17 13:29:16

by Shreeya Patel

[permalink] [raw]
Subject: [PATCH] spi: amd: Configure device speed

From: Lucas Tanure <[email protected]>

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 the closest frequency supported by the
AMD controller.

Give priority to the device transfer speed and in case
it is not set then use the max clock frequency supported
by the device.

Co-developed-by: Shreeya Patel <[email protected]>
Signed-off-by: Shreeya Patel <[email protected]>
Signed-off-by: Lucas Tanure <[email protected]>
---
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


2022-08-17 14:01:22

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH] spi: amd: Configure device speed

On Wed, Aug 17, 2022 at 06:48:09PM +0530, Shreeya Patel wrote:

> Create mechanism to configure device clock frequency such
> that it is the closest frequency supported by the
> AMD controller.

You shouldn't use the closest, you should use a frequency which is
strictly less than the requested one - driving things too fast will
generally break but too slow is pretty much always fine.


Attachments:
(No filename) (396.00 B)
signature.asc (499.00 B)
Download all attachments

2022-08-17 14:34:50

by Shreeya Patel

[permalink] [raw]
Subject: Re: [PATCH] spi: amd: Configure device speed


On 17/08/22 19:14, Mark Brown wrote:
> On Wed, Aug 17, 2022 at 06:48:09PM +0530, Shreeya Patel wrote:
>
>> Create mechanism to configure device clock frequency such
>> that it is the closest frequency supported by the
>> AMD controller.
> You shouldn't use the closest, you should use a frequency which is
> strictly less than the requested one - driving things too fast will
> generally break but too slow is pretty much always fine.
Hi Mark,

yes, the code is actually configuring it to use the frequency which is
strictly less than the requested one.
I just didn't use the correct words. I will make the change in commit
message for v2 once you review the patch.


Thanks
Shreeya Patel

2022-08-18 13:31:40

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH] spi: amd: Configure device speed

On Wed, Aug 17, 2022 at 07:40:31PM +0530, Shreeya Patel wrote:

> yes, the code is actually configuring it to use the frequency which is
> strictly less than the requested one.
> I just didn't use the correct words. I will make the change in commit
> message for v2 once you review the patch.

Please just resend with a fixed commit message, I'll only have to review
it again anyway when you resend.


Attachments:
(No filename) (409.00 B)
signature.asc (499.00 B)
Download all attachments