Furquan Shaikh | 08c524c | 2020-05-09 13:10:30 -0700 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Furquan Shaikh | 08c524c | 2020-05-09 13:10:30 -0700 | [diff] [blame] | 2 | |
Felix Held | 14e3432 | 2020-11-14 00:30:21 +0100 | [diff] [blame] | 3 | #ifndef AMD_BLOCK_SPI_H |
| 4 | #define AMD_BLOCK_SPI_H |
Furquan Shaikh | 08c524c | 2020-05-09 13:10:30 -0700 | [diff] [blame] | 5 | |
Raul E Rangel | 964eb67 | 2021-11-02 11:51:48 -0600 | [diff] [blame] | 6 | #include <thread.h> |
Elyes HAOUAS | 553a22e | 2020-07-22 11:43:47 +0200 | [diff] [blame] | 7 | #include <types.h> |
Martin Roth | f09b4b6 | 2020-07-06 23:35:40 -0600 | [diff] [blame] | 8 | |
Furquan Shaikh | 08c524c | 2020-05-09 13:10:30 -0700 | [diff] [blame] | 9 | #define SPI_CNTRL0 0x00 |
| 10 | #define SPI_BUSY BIT(31) |
| 11 | |
| 12 | enum spi_read_mode { |
| 13 | SPI_READ_MODE_NORMAL33M = 0, |
| 14 | /* 1 is reserved. */ |
| 15 | SPI_READ_MODE_DUAL112 = 2, |
| 16 | SPI_READ_MODE_QUAD114 = 3, |
| 17 | SPI_READ_MODE_DUAL122 = 4, |
| 18 | SPI_READ_MODE_QUAD144 = 5, |
| 19 | SPI_READ_MODE_NORMAL66M = 6, |
| 20 | SPI_READ_MODE_FAST_READ = 7, |
| 21 | }; |
| 22 | /* |
| 23 | * SPI read mode is split into bits 18, 29, 30 such that [30:29:18] correspond to bits [2:0] for |
| 24 | * SpiReadMode. |
| 25 | */ |
| 26 | #define SPI_READ_MODE_MASK (BIT(30) | BIT(29) | BIT(18)) |
| 27 | #define SPI_READ_MODE_UPPER_BITS(x) ((((x) >> 1) & 0x3) << 29) |
| 28 | #define SPI_READ_MODE_LOWER_BITS(x) (((x) & 0x1) << 18) |
| 29 | #define SPI_READ_MODE(x) (SPI_READ_MODE_UPPER_BITS(x) | \ |
| 30 | SPI_READ_MODE_LOWER_BITS(x)) |
| 31 | #define SPI_ACCESS_MAC_ROM_EN BIT(22) |
| 32 | |
| 33 | #define SPI100_ENABLE 0x20 |
| 34 | #define SPI_USE_SPI100 BIT(0) |
| 35 | |
Martin Roth | e582e71 | 2021-08-11 13:21:20 -0600 | [diff] [blame] | 36 | #define DECODE_SPI_MODE_BITS(x) ((x) & SPI_READ_MODE_MASK) |
| 37 | #define DECODE_SPI_MODE_UPPER_BITS(x) ((DECODE_SPI_MODE_BITS(x) >> 28) & 0x06) |
| 38 | #define DECODE_SPI_MODE_LOWER_BITS(x) ((DECODE_SPI_MODE_BITS(x) >> 18) & 0x01) |
| 39 | #define DECODE_SPI_READ_MODE(x) (DECODE_SPI_MODE_UPPER_BITS(x) | \ |
| 40 | DECODE_SPI_MODE_LOWER_BITS(x)) |
| 41 | |
Furquan Shaikh | 08c524c | 2020-05-09 13:10:30 -0700 | [diff] [blame] | 42 | /* Use SPI_SPEED_16M-SPI_SPEED_66M below for the southbridge */ |
| 43 | #define SPI100_SPEED_CONFIG 0x22 |
| 44 | enum spi100_speed { |
| 45 | SPI_SPEED_66M = 0, |
| 46 | SPI_SPEED_33M = 1, |
| 47 | SPI_SPEED_22M = 2, |
| 48 | SPI_SPEED_16M = 3, |
| 49 | SPI_SPEED_100M = 4, |
| 50 | SPI_SPEED_800K = 5, |
| 51 | }; |
| 52 | |
| 53 | #define SPI_SPEED_MASK 0xf |
| 54 | #define SPI_SPEED_MODE(x, shift) (((x) & SPI_SPEED_MASK) << shift) |
| 55 | #define SPI_NORM_SPEED(x) SPI_SPEED_MODE(x, 12) |
| 56 | #define SPI_FAST_SPEED(x) SPI_SPEED_MODE(x, 8) |
| 57 | #define SPI_ALT_SPEED(x) SPI_SPEED_MODE(x, 4) |
| 58 | #define SPI_TPM_SPEED(x) SPI_SPEED_MODE(x, 0) |
| 59 | |
| 60 | #define SPI_SPEED_CFG(n, f, a, t) (SPI_NORM_SPEED(n) | SPI_FAST_SPEED(f) | \ |
| 61 | SPI_ALT_SPEED(a) | SPI_TPM_SPEED(t)) |
| 62 | |
Martin Roth | e582e71 | 2021-08-11 13:21:20 -0600 | [diff] [blame] | 63 | #define DECODE_SPEED_MASK 0x07 |
| 64 | #define DECODE_SPEED_MODE(x, shift) (((x) >> shift) & DECODE_SPEED_MASK) |
| 65 | #define DECODE_SPI_NORMAL_SPEED(x) DECODE_SPEED_MODE(x, 12) |
| 66 | #define DECODE_SPI_FAST_SPEED(x) DECODE_SPEED_MODE(x, 8) |
| 67 | #define DECODE_SPI_ALT_SPEED(x) DECODE_SPEED_MODE(x, 4) |
| 68 | #define DECODE_SPI_TPM_SPEED(x) DECODE_SPEED_MODE(x, 0) |
| 69 | |
Furquan Shaikh | 08c524c | 2020-05-09 13:10:30 -0700 | [diff] [blame] | 70 | #define SPI100_HOST_PREF_CONFIG 0x2c |
| 71 | #define SPI_RD4DW_EN_HOST BIT(15) |
| 72 | |
Zheng Bao | 8cb14be | 2023-04-07 10:51:20 +0800 | [diff] [blame^] | 73 | #define SPI_ROM_PAGE 0x5c |
| 74 | |
Furquan Shaikh | 08c524c | 2020-05-09 13:10:30 -0700 | [diff] [blame] | 75 | #define SPI_FIFO 0x80 |
Felix Held | 6b0f451 | 2021-12-10 18:38:16 +0100 | [diff] [blame] | 76 | #define SPI_FIFO_LAST_BYTE 0xc6 /* 0xc7 for Cezanne */ |
Felix Held | 601a971 | 2021-12-08 16:13:01 +0100 | [diff] [blame] | 77 | #define SPI_FIFO_DEPTH (SPI_FIFO_LAST_BYTE - SPI_FIFO + 1) |
Furquan Shaikh | 08c524c | 2020-05-09 13:10:30 -0700 | [diff] [blame] | 78 | |
| 79 | struct spi_config { |
| 80 | /* |
| 81 | * Default values if not overridden by mainboard: |
| 82 | * Read mode - Normal 33MHz |
| 83 | * Normal speed - 66MHz |
| 84 | * Fast speed - 66MHz |
| 85 | * Alt speed - 66MHz |
| 86 | * TPM speed - 66MHz |
| 87 | */ |
| 88 | enum spi_read_mode read_mode; |
| 89 | enum spi100_speed normal_speed; |
| 90 | enum spi100_speed fast_speed; |
| 91 | enum spi100_speed altio_speed; |
| 92 | enum spi100_speed tpm_speed; |
| 93 | }; |
| 94 | |
| 95 | /* |
| 96 | * Perform early SPI initialization: |
| 97 | * 1. Sets SPI ROM base and enables SPI ROM |
| 98 | * 2. Enables SPI ROM prefetching |
Felix Held | 9bfbcd2 | 2021-11-29 21:17:19 +0100 | [diff] [blame] | 99 | * 3. Disables 4 DWORD burst if !SOC_AMD_COMMON_BLOCK_SPI_4DW_BURST |
Furquan Shaikh | 08c524c | 2020-05-09 13:10:30 -0700 | [diff] [blame] | 100 | * 4. Configures SPI speed and read mode. |
| 101 | * |
| 102 | * This function expects SoC to include soc_amd_common_config in chip SoC config and uses |
| 103 | * settings from mainboard devicetree to configure speed and read mode. |
| 104 | */ |
| 105 | void fch_spi_early_init(void); |
| 106 | |
Martin Roth | f09b4b6 | 2020-07-06 23:35:40 -0600 | [diff] [blame] | 107 | /* Set the SPI base address variable */ |
| 108 | void spi_set_base(void *base); |
| 109 | |
Martin Roth | e582e71 | 2021-08-11 13:21:20 -0600 | [diff] [blame] | 110 | /* Show the SPI settings */ |
| 111 | void show_spi_speeds_and_modes(void); |
| 112 | |
Martin Roth | f09b4b6 | 2020-07-06 23:35:40 -0600 | [diff] [blame] | 113 | /* Get the SPI base address variable's value */ |
| 114 | uintptr_t spi_get_bar(void); |
Martin Roth | 3b8b14d | 2020-07-23 13:50:11 -0600 | [diff] [blame] | 115 | uint8_t spi_read8(uint8_t reg); |
| 116 | uint16_t spi_read16(uint8_t reg); |
| 117 | uint32_t spi_read32(uint8_t reg); |
| 118 | void spi_write8(uint8_t reg, uint8_t val); |
| 119 | void spi_write16(uint8_t reg, uint16_t val); |
| 120 | void spi_write32(uint8_t reg, uint32_t val); |
Martin Roth | f09b4b6 | 2020-07-06 23:35:40 -0600 | [diff] [blame] | 121 | |
Karthikeyan Ramasubramanian | 5705b63 | 2021-10-05 14:11:13 -0600 | [diff] [blame] | 122 | void fch_spi_config_modes(void); |
Karthikeyan Ramasubramanian | 5717ce6 | 2022-10-28 10:23:39 -0600 | [diff] [blame] | 123 | void mainboard_spi_cfg_override(uint8_t *fast_speed, uint8_t *read_mode); |
Raul E Rangel | 964eb67 | 2021-11-02 11:51:48 -0600 | [diff] [blame] | 124 | |
| 125 | /* Ensure you hold the mutex when performing SPI transactions */ |
| 126 | extern struct thread_mutex spi_hw_mutex; |
| 127 | |
Felix Held | 14e3432 | 2020-11-14 00:30:21 +0100 | [diff] [blame] | 128 | #endif /* AMD_BLOCK_SPI_H */ |